Merge tag 'refs/tags/sync-piper' into sync-stage
diff --git a/benchmarks/README.md b/benchmarks/README.md index 7678817..9c25c78 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md
@@ -19,10 +19,8 @@ benchmark tool for testing cpp. This will be automatically made during build the cpp benchmark. -The cpp protobuf performance can be improved by linking with [tcmalloc library]( -https://gperftools.github.io/gperftools/tcmalloc.html). For using tcmalloc, you -need to build [gpertools](https://github.com/gperftools/gperftools) to generate -libtcmallc.so library. +The cpp protobuf performance can be improved by linking with +[TCMalloc](https://google.github.io/tcmalloc). ### Java We're using maven to build the java benchmarks, which is the same as to build
diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index d2ab2de..990a57f 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in
@@ -58,6 +58,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\implicit_weak_message.h" include\google\protobuf\implicit_weak_message.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\inlined_string_field.h" include\google\protobuf\inlined_string_field.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h" include\google\protobuf\io\coded_stream.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\gzip_stream.h" include\google\protobuf\io\gzip_stream.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\io_win32.h" include\google\protobuf\io\io_win32.h @@ -87,6 +88,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field.h" include\google\protobuf\repeated_field.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\service.h" include\google\protobuf\service.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\source_context.pb.h" include\google\protobuf\source_context.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\string_member_robber.h" include\google\protobuf\string_member_robber.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\struct.pb.h" include\google\protobuf\struct.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\bytestream.h" include\google\protobuf\stubs\bytestream.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h" include\google\protobuf\stubs\callback.h
diff --git a/cmake/tests.cmake b/cmake/tests.cmake index 4a54b70..225db93 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake
@@ -114,6 +114,7 @@ set(common_test_files ${protobuf_source_dir}/src/google/protobuf/arena_test_util.cc ${protobuf_source_dir}/src/google/protobuf/map_test_util.inc + ${protobuf_source_dir}/src/google/protobuf/reflection_tester.cc ${protobuf_source_dir}/src/google/protobuf/test_util.cc ${protobuf_source_dir}/src/google/protobuf/test_util.inc ${protobuf_source_dir}/src/google/protobuf/testing/file.cc @@ -199,6 +200,7 @@ ${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util_test.cc ${protobuf_source_dir}/src/google/protobuf/well_known_types_unittest.cc ${protobuf_source_dir}/src/google/protobuf/wire_format_unittest.cc + ${protobuf_source_dir}/src/google/protobuf/wire_format_unittest.inc ) set(non_msvc_tests_files
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs index 48f9b80..8a52209 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs
@@ -198,12 +198,13 @@ "cHRpb25hbGdyb3VwGOwHIAEoCjJCLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMu", "cHJvdG8yLlVua25vd25Ub1Rlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwEhYK", "DW9wdGlvbmFsX2Jvb2wY7gcgASgIEhcKDnJlcGVhdGVkX2ludDMyGPMHIAMo", - "BRoaCg1PcHRpb25hbEdyb3VwEgkKAWEYASABKAUqRgoRRm9yZWlnbkVudW1Q", - "cm90bzISDwoLRk9SRUlHTl9GT08QABIPCgtGT1JFSUdOX0JBUhABEg8KC0ZP", - "UkVJR05fQkFaEAI6SgoPZXh0ZW5zaW9uX2ludDMyEjEucHJvdG9idWZfdGVz", - "dF9tZXNzYWdlcy5wcm90bzIuVGVzdEFsbFR5cGVzUHJvdG8yGHggASgFQi8K", - "KGNvbS5nb29nbGUucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5wcm90bzJIAfgB", - "AQ==")); + "BRoaCg1PcHRpb25hbEdyb3VwEgkKAWEYASABKAUiFgoUTnVsbEh5cG90aGVz", + "aXNQcm90bzIiLwoORW51bU9ubHlQcm90bzIiHQoEQm9vbBIKCgZrRmFsc2UQ", + "ABIJCgVrVHJ1ZRABKkYKEUZvcmVpZ25FbnVtUHJvdG8yEg8KC0ZPUkVJR05f", + "Rk9PEAASDwoLRk9SRUlHTl9CQVIQARIPCgtGT1JFSUdOX0JBWhACOkoKD2V4", + "dGVuc2lvbl9pbnQzMhIxLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8y", + "LlRlc3RBbGxUeXBlc1Byb3RvMhh4IAEoBUIvCihjb20uZ29vZ2xlLnByb3Rv", + "YnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8ySAH4AQE=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::ProtobufTestMessages.Proto2.ForeignEnumProto2), }, new pb::Extension[] { TestMessagesProto2Extensions.ExtensionInt32 }, new pbr::GeneratedClrTypeInfo[] { @@ -213,7 +214,9 @@ new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension1), global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension1.Parser, new[]{ "Str" }, null, null, new pb::Extension[] { global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension1.Extensions.MessageSetExtension }, null), new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension2), global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension2.Parser, new[]{ "I" }, null, null, new pb::Extension[] { global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension2.Extensions.MessageSetExtension }, null)}), new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.ForeignMessageProto2), global::ProtobufTestMessages.Proto2.ForeignMessageProto2.Parser, new[]{ "C" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes), global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Parser, new[]{ "OptionalInt32", "OptionalString", "NestedMessage", "OptionalGroup", "OptionalBool", "RepeatedInt32" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Types.OptionalGroup), global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Types.OptionalGroup.Parser, new[]{ "A" }, null, null, null, null)}) + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes), global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Parser, new[]{ "OptionalInt32", "OptionalString", "NestedMessage", "OptionalGroup", "OptionalBool", "RepeatedInt32" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Types.OptionalGroup), global::ProtobufTestMessages.Proto2.UnknownToTestAllTypes.Types.OptionalGroup.Parser, new[]{ "A" }, null, null, null, null)}), + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.NullHypothesisProto2), global::ProtobufTestMessages.Proto2.NullHypothesisProto2.Parser, null, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto2.EnumOnlyProto2), global::ProtobufTestMessages.Proto2.EnumOnlyProto2.Parser, null, null, new[]{ typeof(global::ProtobufTestMessages.Proto2.EnumOnlyProto2.Types.Bool) }, null, null) })); } #endregion @@ -6981,6 +6984,323 @@ } + public sealed partial class NullHypothesisProto2 : pb::IMessage<NullHypothesisProto2> + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser<NullHypothesisProto2> _parser = new pb::MessageParser<NullHypothesisProto2>(() => new NullHypothesisProto2()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser<NullHypothesisProto2> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::ProtobufTestMessages.Proto2.TestMessagesProto2Reflection.Descriptor.MessageTypes[3]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public NullHypothesisProto2() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public NullHypothesisProto2(NullHypothesisProto2 other) : this() { + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public NullHypothesisProto2 Clone() { + return new NullHypothesisProto2(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as NullHypothesisProto2); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(NullHypothesisProto2 other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(NullHypothesisProto2 other) { + if (other == null) { + return; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } + } + #endif + + } + + public sealed partial class EnumOnlyProto2 : pb::IMessage<EnumOnlyProto2> + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser<EnumOnlyProto2> _parser = new pb::MessageParser<EnumOnlyProto2>(() => new EnumOnlyProto2()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser<EnumOnlyProto2> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::ProtobufTestMessages.Proto2.TestMessagesProto2Reflection.Descriptor.MessageTypes[4]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public EnumOnlyProto2() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public EnumOnlyProto2(EnumOnlyProto2 other) : this() { + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public EnumOnlyProto2 Clone() { + return new EnumOnlyProto2(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as EnumOnlyProto2); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(EnumOnlyProto2 other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(EnumOnlyProto2 other) { + if (other == null) { + return; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } + } + #endif + + #region Nested types + /// <summary>Container for nested types declared in the EnumOnlyProto2 message type.</summary> + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static partial class Types { + public enum Bool { + [pbr::OriginalName("kFalse")] KFalse = 0, + [pbr::OriginalName("kTrue")] KTrue = 1, + } + + } + #endregion + + } + #endregion }
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs index 0e00150..71e803c 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs
@@ -227,16 +227,20 @@ "A0JBUhABEgcKA0JBWhACEhAKA05FRxD///////////8BIlkKC0FsaWFzZWRF", "bnVtEg0KCUFMSUFTX0ZPTxAAEg0KCUFMSUFTX0JBUhABEg0KCUFMSUFTX0JB", "WhACEgcKA1FVWBACEgcKA3F1eBACEgcKA2JBehACGgIQAUINCgtvbmVvZl9m", - "aWVsZEoGCPUDEP8DIhsKDkZvcmVpZ25NZXNzYWdlEgkKAWMYASABKAUqQAoL", - "Rm9yZWlnbkVudW0SDwoLRk9SRUlHTl9GT08QABIPCgtGT1JFSUdOX0JBUhAB", - "Eg8KC0ZPUkVJR05fQkFaEAJCOAooY29tLmdvb2dsZS5wcm90b2J1Zl90ZXN0", - "X21lc3NhZ2VzLnByb3RvM0gB+AEBogIGUHJvdG8zYgZwcm90bzM=")); + "aWVsZEoGCPUDEP8DIhsKDkZvcmVpZ25NZXNzYWdlEgkKAWMYASABKAUiFgoU", + "TnVsbEh5cG90aGVzaXNQcm90bzMiLwoORW51bU9ubHlQcm90bzMiHQoEQm9v", + "bBIKCgZrRmFsc2UQABIJCgVrVHJ1ZRABKkAKC0ZvcmVpZ25FbnVtEg8KC0ZP", + "UkVJR05fRk9PEAASDwoLRk9SRUlHTl9CQVIQARIPCgtGT1JFSUdOX0JBWhAC", + "QjgKKGNvbS5nb29nbGUucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5wcm90bzNI", + "AfgBAaICBlByb3RvM2IGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::ProtobufTestMessages.Proto3.ForeignEnum), }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalAliasedEnum", "OptionalStringPiece", "OptionalCord", "RecursiveMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "PackedInt32", "PackedInt64", "PackedUint32", "PackedUint64", "PackedSint32", "PackedSint64", "PackedFixed32", "PackedFixed64", "PackedSfixed32", "PackedSfixed64", "PackedFloat", "PackedDouble", "PackedBool", "PackedNestedEnum", "UnpackedInt32", "UnpackedInt64", "UnpackedUint32", "UnpackedUint64", "UnpackedSint32", "UnpackedSint64", "UnpackedFixed32", "UnpackedFixed64", "UnpackedSfixed32", "UnpackedSfixed64", "UnpackedFloat", "UnpackedDouble", "UnpackedBool", "UnpackedNestedEnum", "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapStringBytes", "MapStringNestedMessage", "MapStringForeignMessage", "MapStringNestedEnum", "MapStringForeignEnum", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes", "OneofBool", "OneofUint64", "OneofFloat", "OneofDouble", "OneofEnum", "OneofNullValue", "OptionalBoolWrapper", "OptionalInt32Wrapper", "OptionalInt64Wrapper", "OptionalUint32Wrapper", "OptionalUint64Wrapper", "OptionalFloatWrapper", "OptionalDoubleWrapper", "OptionalStringWrapper", "OptionalBytesWrapper", "RepeatedBoolWrapper", "RepeatedInt32Wrapper", "RepeatedInt64Wrapper", "RepeatedUint32Wrapper", "RepeatedUint64Wrapper", "RepeatedFloatWrapper", "RepeatedDoubleWrapper", "RepeatedStringWrapper", "RepeatedBytesWrapper", "OptionalDuration", "OptionalTimestamp", "OptionalFieldMask", "OptionalStruct", "OptionalAny", "OptionalValue", "OptionalNullValue", "RepeatedDuration", "RepeatedTimestamp", "RepeatedFieldmask", "RepeatedStruct", "RepeatedAny", "RepeatedValue", "RepeatedListValue", "Fieldname1", "FieldName2", "FieldName3", "FieldName4", "Field0Name5", "Field0Name6", "FieldName7", "FieldName8", "FieldName9", "FieldName10", "FIELDNAME11", "FIELDName12", "FieldName13", "FieldName14", "FieldName15", "FieldName16", "FieldName17", "FieldName18" }, new[]{ "OneofField" }, new[]{ typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum), typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage.Parser, new[]{ "A", "Corecursive" }, null, null, null, null), null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }), - new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.ForeignMessage), global::ProtobufTestMessages.Proto3.ForeignMessage.Parser, new[]{ "C" }, null, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.ForeignMessage), global::ProtobufTestMessages.Proto3.ForeignMessage.Parser, new[]{ "C" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.NullHypothesisProto3), global::ProtobufTestMessages.Proto3.NullHypothesisProto3.Parser, null, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.EnumOnlyProto3), global::ProtobufTestMessages.Proto3.EnumOnlyProto3.Parser, null, null, new[]{ typeof(global::ProtobufTestMessages.Proto3.EnumOnlyProto3.Types.Bool) }, null, null) })); } #endregion @@ -5862,6 +5866,323 @@ } + public sealed partial class NullHypothesisProto3 : pb::IMessage<NullHypothesisProto3> + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser<NullHypothesisProto3> _parser = new pb::MessageParser<NullHypothesisProto3>(() => new NullHypothesisProto3()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser<NullHypothesisProto3> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::ProtobufTestMessages.Proto3.TestMessagesProto3Reflection.Descriptor.MessageTypes[2]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public NullHypothesisProto3() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public NullHypothesisProto3(NullHypothesisProto3 other) : this() { + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public NullHypothesisProto3 Clone() { + return new NullHypothesisProto3(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as NullHypothesisProto3); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(NullHypothesisProto3 other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(NullHypothesisProto3 other) { + if (other == null) { + return; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } + } + #endif + + } + + public sealed partial class EnumOnlyProto3 : pb::IMessage<EnumOnlyProto3> + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser<EnumOnlyProto3> _parser = new pb::MessageParser<EnumOnlyProto3>(() => new EnumOnlyProto3()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser<EnumOnlyProto3> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::ProtobufTestMessages.Proto3.TestMessagesProto3Reflection.Descriptor.MessageTypes[3]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public EnumOnlyProto3() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public EnumOnlyProto3(EnumOnlyProto3 other) : this() { + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public EnumOnlyProto3 Clone() { + return new EnumOnlyProto3(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as EnumOnlyProto3); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(EnumOnlyProto3 other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(EnumOnlyProto3 other) { + if (other == null) { + return; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } + } + #endif + + #region Nested types + /// <summary>Container for nested types declared in the EnumOnlyProto3 message type.</summary> + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static partial class Types { + public enum Bool { + [pbr::OriginalName("kFalse")] KFalse = 0, + [pbr::OriginalName("kTrue")] KTrue = 1, + } + + } + #endregion + + } + #endregion }
diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb index 42ecd3a..caf5164 100644 --- a/csharp/src/Google.Protobuf.Test/testprotos.pb +++ b/csharp/src/Google.Protobuf.Test/testprotos.pb Binary files differ
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 1060c5a..8717f9e 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -61,14 +61,14 @@ */ public abstract class CodedInputStream { private static final int DEFAULT_BUFFER_SIZE = 4096; - private static final int DEFAULT_RECURSION_LIMIT = 100; // Integer.MAX_VALUE == 0x7FFFFFF == INT_MAX from limits.h private static final int DEFAULT_SIZE_LIMIT = Integer.MAX_VALUE; + private static volatile int defaultRecursionLimit = 100; /** Visible for subclasses. See setRecursionLimit() */ int recursionDepth; - int recursionLimit = DEFAULT_RECURSION_LIMIT; + int recursionLimit = defaultRecursionLimit; /** Visible for subclasses. See setSizeLimit() */ int sizeLimit = DEFAULT_SIZE_LIMIT; @@ -195,6 +195,11 @@ return newInstance(buffer, 0, buffer.length, true); } + public void checkRecursionLimit() throws InvalidProtocolBufferException { + if (recursionDepth >= recursionLimit) { + throw InvalidProtocolBufferException.recursionLimitExceeded(); + } + } /** Disable construction/inheritance outside of this class. */ private CodedInputStream() {} @@ -827,9 +832,7 @@ final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry) throws IOException { - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); ++recursionDepth; builder.mergeFrom(this, extensionRegistry); checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); @@ -843,9 +846,7 @@ final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException { - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); ++recursionDepth; T result = parser.parsePartialFrom(this, extensionRegistry); checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); @@ -865,9 +866,7 @@ final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry) throws IOException { final int length = readRawVarint32(); - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); final int oldLimit = pushLimit(length); ++recursionDepth; builder.mergeFrom(this, extensionRegistry); @@ -884,9 +883,7 @@ public <T extends MessageLite> T readMessage( final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException { int length = readRawVarint32(); - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); final int oldLimit = pushLimit(length); ++recursionDepth; T result = parser.parsePartialFrom(this, extensionRegistry); @@ -1555,9 +1552,7 @@ final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry) throws IOException { - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); ++recursionDepth; builder.mergeFrom(this, extensionRegistry); checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); @@ -1571,9 +1566,7 @@ final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException { - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); ++recursionDepth; T result = parser.parsePartialFrom(this, extensionRegistry); checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); @@ -1593,9 +1586,7 @@ final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry) throws IOException { final int length = readRawVarint32(); - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); final int oldLimit = pushLimit(length); ++recursionDepth; builder.mergeFrom(this, extensionRegistry); @@ -1612,9 +1603,7 @@ public <T extends MessageLite> T readMessage( final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException { int length = readRawVarint32(); - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); final int oldLimit = pushLimit(length); ++recursionDepth; T result = parser.parsePartialFrom(this, extensionRegistry); @@ -2358,9 +2347,7 @@ final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry) throws IOException { - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); ++recursionDepth; builder.mergeFrom(this, extensionRegistry); checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); @@ -2374,9 +2361,7 @@ final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException { - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); ++recursionDepth; T result = parser.parsePartialFrom(this, extensionRegistry); checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); @@ -2396,9 +2381,7 @@ final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry) throws IOException { final int length = readRawVarint32(); - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); final int oldLimit = pushLimit(length); ++recursionDepth; builder.mergeFrom(this, extensionRegistry); @@ -2415,9 +2398,7 @@ public <T extends MessageLite> T readMessage( final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException { int length = readRawVarint32(); - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); final int oldLimit = pushLimit(length); ++recursionDepth; T result = parser.parsePartialFrom(this, extensionRegistry); @@ -3461,9 +3442,7 @@ final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry) throws IOException { - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); ++recursionDepth; builder.mergeFrom(this, extensionRegistry); checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); @@ -3477,9 +3456,7 @@ final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException { - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); ++recursionDepth; T result = parser.parsePartialFrom(this, extensionRegistry); checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); @@ -3499,9 +3476,7 @@ final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry) throws IOException { final int length = readRawVarint32(); - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); final int oldLimit = pushLimit(length); ++recursionDepth; builder.mergeFrom(this, extensionRegistry); @@ -3518,9 +3493,7 @@ public <T extends MessageLite> T readMessage( final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException { int length = readRawVarint32(); - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } + checkRecursionLimit(); final int oldLimit = pushLimit(length); ++recursionDepth; T result = parser.parsePartialFrom(this, extensionRegistry);
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 e56a18e..7b14584 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java
@@ -1309,11 +1309,14 @@ SINT32(JavaType.INT), SINT64(JavaType.LONG); - Type(final JavaType javaType) { + // Private copy to avoid repeated allocations from calls to values() in valueOf(). + private static final Type[] types = values(); + + Type(JavaType javaType) { this.javaType = javaType; } - private JavaType javaType; + private final JavaType javaType; public FieldDescriptorProto.Type toProto() { return FieldDescriptorProto.Type.forNumber(ordinal() + 1); @@ -1324,13 +1327,13 @@ } public static Type valueOf(final FieldDescriptorProto.Type type) { - return values()[type.getNumber() - 1]; + return types[type.getNumber() - 1]; } } static { // Refuse to init if someone added a new declared type. - if (Type.values().length != FieldDescriptorProto.Type.values().length) { + if (Type.types.length != FieldDescriptorProto.Type.values().length) { throw new RuntimeException( "descriptor.proto has a new declared type but Descriptors.java wasn't updated."); }
diff --git a/java/core/src/main/java/com/google/protobuf/LazyField.java b/java/core/src/main/java/com/google/protobuf/LazyField.java index 891171d..035ea60 100644 --- a/java/core/src/main/java/com/google/protobuf/LazyField.java +++ b/java/core/src/main/java/com/google/protobuf/LazyField.java
@@ -35,10 +35,10 @@ /** * LazyField encapsulates the logic of lazily parsing message fields. It stores the message in a - * ByteString initially and then parse it on-demand. + * ByteString initially and then parses it on-demand. * - * <p>Most of key methods are implemented in {@link LazyFieldLite} but this class can contain - * default instance of the message to provide {@code hashCode()}, {@code euqals()} and {@code + * <p>Most methods are implemented in {@link LazyFieldLite} but this class can contain a + * default instance of the message to provide {@code hashCode()}, {@code equals()}, and {@code * toString()}. * * @author xiangl@google.com (Xiang Li) @@ -46,7 +46,7 @@ public class LazyField extends LazyFieldLite { /** - * Carry a message's default instance which is used by {@code hashCode()}, {@code euqals()} and + * Carry a message's default instance which is used by {@code hashCode()}, {@code equals()}, and * {@code toString()}. */ private final MessageLite defaultInstance;
diff --git a/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java b/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java index d66f5c4..1735a08 100644 --- a/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java +++ b/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java
@@ -181,32 +181,8 @@ this.defaultInstance = defaultInstance; this.info = info; this.objects = objects; - int value; - try { - value = (int) info.charAt(0); - } catch (StringIndexOutOfBoundsException e) { - // This is a fix for issues - // that error out on a subset of phones on charAt(0) with an index out of bounds exception. - char[] infoChars = info.toCharArray(); - info = new String(infoChars); - try { - value = (int) info.charAt(0); - } catch (StringIndexOutOfBoundsException e2) { - try { - char[] infoChars2 = new char[info.length()]; - info.getChars(0, info.length(), infoChars2, 0); - info = new String(infoChars2); - value = (int) info.charAt(0); - } catch (StringIndexOutOfBoundsException | ArrayIndexOutOfBoundsException e3) { - throw new IllegalStateException( - String.format( - "Failed parsing '%s' with charArray.length of %d", info, infoChars.length), - e3); - } - } - } - int position = 1; - + int position = 0; + int value = (int) info.charAt(position++); if (value < 0xD800) { flags = value; } else {
diff --git a/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java b/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java index 4bc8d10..5588b06 100644 --- a/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java +++ b/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
@@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static com.google.protobuf.TestUtil.TEST_REQUIRED_INITIALIZED; import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED; @@ -44,14 +46,13 @@ import protobuf_unittest.UnittestProto.TestRequiredForeign; import protobuf_unittest.UnittestProto.TestUnpackedTypes; import java.util.Map; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Unit test for {@link AbstractMessage}. - * - * @author kenton@google.com Kenton Varda - */ -public class AbstractMessageTest extends TestCase { +/** Unit test for {@link AbstractMessage}. */ +@RunWith(JUnit4.class) +public class AbstractMessageTest { /** * Extends AbstractMessage and wraps some other message object. The methods of the Message * interface which aren't explicitly implemented by AbstractMessage are forwarded to the wrapped @@ -238,6 +239,7 @@ new TestUtil.ReflectionTester( TestAllExtensions.getDescriptor(), TestUtil.getFullExtensionRegistry()); + @Test public void testClear() throws Exception { AbstractMessageWrapper message = new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder(TestUtil.getAllSet())) @@ -246,6 +248,7 @@ TestUtil.assertClear((TestAllTypes) message.wrappedMessage); } + @Test public void testCopy() throws Exception { AbstractMessageWrapper message = new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder()) @@ -254,28 +257,35 @@ TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage); } + @Test public void testSerializedSize() throws Exception { TestAllTypes message = TestUtil.getAllSet(); Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet()); - - assertEquals(message.getSerializedSize(), abstractMessage.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(abstractMessage.getSerializedSize()); } + @Test public void testSerialization() throws Exception { Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet()); - - TestUtil.assertAllFieldsSet(TestAllTypes.parseFrom(abstractMessage.toByteString())); - - assertEquals(TestUtil.getAllSet().toByteString(), abstractMessage.toByteString()); + TestUtil.assertAllFieldsSet( + TestAllTypes.parseFrom( + abstractMessage.toByteString(), ExtensionRegistryLite.getEmptyRegistry())); + assertThat(TestUtil.getAllSet().toByteString()).isEqualTo(abstractMessage.toByteString()); } + @Test public void testParsing() throws Exception { AbstractMessageWrapper.Builder builder = new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder()); - AbstractMessageWrapper message = builder.mergeFrom(TestUtil.getAllSet().toByteString()).build(); + AbstractMessageWrapper message = + builder + .mergeFrom( + TestUtil.getAllSet().toByteString(), ExtensionRegistryLite.getEmptyRegistry()) + .build(); TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage); } + @Test public void testParsingUninitialized() throws Exception { TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder(); builder.getOptionalMessageBuilder().setDummy2(10); @@ -283,10 +293,13 @@ Message.Builder abstractMessageBuilder = new AbstractMessageWrapper.Builder(TestRequiredForeign.newBuilder()); // mergeFrom() should not throw initialization error. - Message unused1 = abstractMessageBuilder.mergeFrom(bytes).buildPartial(); + Message unused1 = + abstractMessageBuilder + .mergeFrom(bytes, ExtensionRegistryLite.getEmptyRegistry()) + .buildPartial(); try { - abstractMessageBuilder.mergeFrom(bytes).build(); - fail(); + abstractMessageBuilder.mergeFrom(bytes, ExtensionRegistryLite.getEmptyRegistry()).build(); + assertWithMessage("shouldn't pass").fail(); } catch (UninitializedMessageException ex) { // pass } @@ -295,115 +308,140 @@ Message.Builder dynamicMessageBuilder = DynamicMessage.newBuilder(TestRequiredForeign.getDescriptor()); // mergeFrom() should not throw initialization error. - Message unused2 = dynamicMessageBuilder.mergeFrom(bytes).buildPartial(); + Message unused2 = + dynamicMessageBuilder + .mergeFrom(bytes, ExtensionRegistryLite.getEmptyRegistry()) + .buildPartial(); try { - dynamicMessageBuilder.mergeFrom(bytes).build(); - fail(); + dynamicMessageBuilder.mergeFrom(bytes, ExtensionRegistryLite.getEmptyRegistry()).build(); + assertWithMessage("shouldn't pass").fail(); } catch (UninitializedMessageException ex) { // pass } } + @Test public void testPackedSerialization() throws Exception { Message abstractMessage = new AbstractMessageWrapper(TestUtil.getPackedSet()); - - TestUtil.assertPackedFieldsSet(TestPackedTypes.parseFrom(abstractMessage.toByteString())); - - assertEquals(TestUtil.getPackedSet().toByteString(), abstractMessage.toByteString()); + TestUtil.assertPackedFieldsSet( + TestPackedTypes.parseFrom( + abstractMessage.toByteString(), ExtensionRegistryLite.getEmptyRegistry())); + assertThat(TestUtil.getPackedSet().toByteString()).isEqualTo(abstractMessage.toByteString()); } + @Test public void testPackedParsing() throws Exception { AbstractMessageWrapper.Builder builder = new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder()); AbstractMessageWrapper message = - builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); + builder + .mergeFrom( + TestUtil.getPackedSet().toByteString(), ExtensionRegistryLite.getEmptyRegistry()) + .build(); TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage); } + @Test public void testUnpackedSerialization() throws Exception { Message abstractMessage = new AbstractMessageWrapper(TestUtil.getUnpackedSet()); - - TestUtil.assertUnpackedFieldsSet(TestUnpackedTypes.parseFrom(abstractMessage.toByteString())); - - assertEquals(TestUtil.getUnpackedSet().toByteString(), abstractMessage.toByteString()); + TestUtil.assertUnpackedFieldsSet( + TestUnpackedTypes.parseFrom( + abstractMessage.toByteString(), ExtensionRegistryLite.getEmptyRegistry())); + assertThat(TestUtil.getUnpackedSet().toByteString()).isEqualTo(abstractMessage.toByteString()); } + @Test public void testParsePackedToUnpacked() throws Exception { AbstractMessageWrapper.Builder builder = new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder()); AbstractMessageWrapper message = - builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); + builder + .mergeFrom( + TestUtil.getPackedSet().toByteString(), ExtensionRegistryLite.getEmptyRegistry()) + .build(); TestUtil.assertUnpackedFieldsSet((TestUnpackedTypes) message.wrappedMessage); } + @Test public void testParseUnpackedToPacked() throws Exception { AbstractMessageWrapper.Builder builder = new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder()); AbstractMessageWrapper message = - builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); + builder + .mergeFrom( + TestUtil.getUnpackedSet().toByteString(), ExtensionRegistryLite.getEmptyRegistry()) + .build(); TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage); } + @Test public void testUnpackedParsing() throws Exception { AbstractMessageWrapper.Builder builder = new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder()); AbstractMessageWrapper message = - builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); + builder + .mergeFrom( + TestUtil.getUnpackedSet().toByteString(), ExtensionRegistryLite.getEmptyRegistry()) + .build(); TestUtil.assertUnpackedFieldsSet((TestUnpackedTypes) message.wrappedMessage); } + @Test public void testOptimizedForSize() throws Exception { // We're mostly only checking that this class was compiled successfully. TestOptimizedForSize message = TestOptimizedForSize.newBuilder().setI(1).build(); - message = TestOptimizedForSize.parseFrom(message.toByteString()); - assertEquals(2, message.getSerializedSize()); + message = + TestOptimizedForSize.parseFrom( + message.toByteString(), ExtensionRegistryLite.getEmptyRegistry()); + assertThat(message.getSerializedSize()).isEqualTo(2); } // ----------------------------------------------------------------- // Tests for isInitialized(). + @Test public void testIsInitialized() throws Exception { TestRequired.Builder builder = TestRequired.newBuilder(); AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder); - assertFalse(abstractBuilder.isInitialized()); - assertEquals("a, b, c", abstractBuilder.getInitializationErrorString()); + assertThat(abstractBuilder.isInitialized()).isFalse(); + assertThat(abstractBuilder.getInitializationErrorString()).isEqualTo("a, b, c"); builder.setA(1); - assertFalse(abstractBuilder.isInitialized()); - assertEquals("b, c", abstractBuilder.getInitializationErrorString()); + assertThat(abstractBuilder.isInitialized()).isFalse(); + assertThat(abstractBuilder.getInitializationErrorString()).isEqualTo("b, c"); builder.setB(1); - assertFalse(abstractBuilder.isInitialized()); - assertEquals("c", abstractBuilder.getInitializationErrorString()); + assertThat(abstractBuilder.isInitialized()).isFalse(); + assertThat(abstractBuilder.getInitializationErrorString()).isEqualTo("c"); builder.setC(1); - assertTrue(abstractBuilder.isInitialized()); - assertEquals("", abstractBuilder.getInitializationErrorString()); + assertThat(abstractBuilder.isInitialized()).isTrue(); + assertThat(abstractBuilder.getInitializationErrorString()).isEmpty(); } + @Test public void testForeignIsInitialized() throws Exception { TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder(); AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder); - assertTrue(abstractBuilder.isInitialized()); - assertEquals("", abstractBuilder.getInitializationErrorString()); + assertThat(abstractBuilder.isInitialized()).isTrue(); + assertThat(abstractBuilder.getInitializationErrorString()).isEmpty(); builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED); - assertFalse(abstractBuilder.isInitialized()); - assertEquals( - "optional_message.b, optional_message.c", abstractBuilder.getInitializationErrorString()); + assertThat(abstractBuilder.isInitialized()).isFalse(); + assertThat(abstractBuilder.getInitializationErrorString()) + .isEqualTo("optional_message.b, optional_message.c"); builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED); - assertTrue(abstractBuilder.isInitialized()); - assertEquals("", abstractBuilder.getInitializationErrorString()); + assertThat(abstractBuilder.isInitialized()).isTrue(); + assertThat(abstractBuilder.getInitializationErrorString()).isEmpty(); builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED); - assertFalse(abstractBuilder.isInitialized()); - assertEquals( - "repeated_message[0].b, repeated_message[0].c", - abstractBuilder.getInitializationErrorString()); + assertThat(abstractBuilder.isInitialized()).isFalse(); + assertThat(abstractBuilder.getInitializationErrorString()) + .isEqualTo("repeated_message[0].b, repeated_message[0].c"); builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED); - assertTrue(abstractBuilder.isInitialized()); - assertEquals("", abstractBuilder.getInitializationErrorString()); + assertThat(abstractBuilder.isInitialized()).isTrue(); + assertThat(abstractBuilder.getInitializationErrorString()).isEmpty(); } // ----------------------------------------------------------------- @@ -436,21 +474,23 @@ + "repeated_string: \"qux\"\n" + "repeated_string: \"bar\"\n"; + @Test public void testMergeFrom() throws Exception { AbstractMessageWrapper result = new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder(MERGE_DEST)) .mergeFrom(MERGE_SOURCE) .build(); - assertEquals(MERGE_RESULT_TEXT, result.toString()); + assertThat(result.toString()).isEqualTo(MERGE_RESULT_TEXT); } // ----------------------------------------------------------------- // Tests for equals and hashCode + @Test public void testEqualsAndHashCode() throws Exception { TestAllTypes a = TestUtil.getAllSet(); - TestAllTypes b = TestAllTypes.newBuilder().build(); + TestAllTypes b = TestAllTypes.getDefaultInstance(); TestAllTypes c = TestAllTypes.newBuilder(b).addRepeatedString("x").build(); TestAllTypes d = TestAllTypes.newBuilder(c).addRepeatedString("y").build(); TestAllExtensions e = TestUtil.getAllExtensionsSet(); @@ -489,23 +529,26 @@ // Deserializing into the TestEmptyMessage such that every field // is an {@link UnknownFieldSet.Field}. UnittestProto.TestEmptyMessage eUnknownFields = - UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray()); + UnittestProto.TestEmptyMessage.parseFrom( + e.toByteArray(), ExtensionRegistryLite.getEmptyRegistry()); UnittestProto.TestEmptyMessage fUnknownFields = - UnittestProto.TestEmptyMessage.parseFrom(f.toByteArray()); + UnittestProto.TestEmptyMessage.parseFrom( + f.toByteArray(), ExtensionRegistryLite.getEmptyRegistry()); checkNotEqual(eUnknownFields, fUnknownFields); checkEqualsIsConsistent(eUnknownFields); checkEqualsIsConsistent(fUnknownFields); // Subsequent reconstitutions should be identical UnittestProto.TestEmptyMessage eUnknownFields2 = - UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray()); + UnittestProto.TestEmptyMessage.parseFrom( + e.toByteArray(), ExtensionRegistryLite.getEmptyRegistry()); checkEqualsIsConsistent(eUnknownFields, eUnknownFields2); } /** Asserts that the given proto has symmetric equals and hashCode methods. */ private void checkEqualsIsConsistent(Message message) { - // Object should be equal to itself. - assertEquals(message, message); + // Test equals explicitly. + assertThat(message.equals(message)).isTrue(); // Object should be equal to a dynamic copy of itself. DynamicMessage dynamic = DynamicMessage.newBuilder(message).build(); @@ -514,9 +557,9 @@ /** Asserts that the given protos are equal and have the same hash code. */ private void checkEqualsIsConsistent(Message message1, Message message2) { - assertEquals(message1, message2); - assertEquals(message2, message1); - assertEquals(message2.hashCode(), message1.hashCode()); + assertThat(message1).isEqualTo(message2); + assertThat(message2).isEqualTo(message1); + assertThat(message2.hashCode()).isEqualTo(message1.hashCode()); } /** @@ -527,28 +570,33 @@ */ private void checkNotEqual(Message m1, Message m2) { String equalsError = String.format("%s should not be equal to %s", m1, m2); - assertFalse(equalsError, m1.equals(m2)); - assertFalse(equalsError, m2.equals(m1)); + assertWithMessage(equalsError).that(m1.equals(m2)).isFalse(); + assertWithMessage(equalsError).that(m2.equals(m1)).isFalse(); - assertFalse( - String.format("%s should have a different hash code from %s", m1, m2), - m1.hashCode() == m2.hashCode()); + assertWithMessage(String.format("%s should have a different hash code from %s", m1, m2)) + .that(m1.hashCode()) + .isNotEqualTo(m2.hashCode()); } + @Test public void testCheckByteStringIsUtf8OnUtf8() { ByteString byteString = ByteString.copyFromUtf8("some text"); AbstractMessageLite.checkByteStringIsUtf8(byteString); // No exception thrown. } + @Test public void testCheckByteStringIsUtf8OnNonUtf8() { ByteString byteString = ByteString.copyFrom(new byte[] {(byte) 0x80}); // A lone continuation byte. try { AbstractMessageLite.checkByteStringIsUtf8(byteString); - fail("Expected AbstractMessageLite.checkByteStringIsUtf8 to throw IllegalArgumentException"); + assertWithMessage( + "Expected AbstractMessageLite.checkByteStringIsUtf8 to throw" + + " IllegalArgumentException") + .fail(); } catch (IllegalArgumentException exception) { - assertEquals("Byte string is not UTF-8.", exception.getMessage()); + assertThat(exception).hasMessageThat().isEqualTo("Byte string is not UTF-8."); } } }
diff --git a/java/core/src/test/java/com/google/protobuf/AbstractProto2LiteSchemaTest.java b/java/core/src/test/java/com/google/protobuf/AbstractProto2LiteSchemaTest.java index 5d3fd3b..7eb0ace 100644 --- a/java/core/src/test/java/com/google/protobuf/AbstractProto2LiteSchemaTest.java +++ b/java/core/src/test/java/com/google/protobuf/AbstractProto2LiteSchemaTest.java
@@ -30,9 +30,8 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import com.google.protobuf.testing.Proto2TestingLite.Proto2EmptyLite; import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite; @@ -73,8 +72,8 @@ Proto2MessageLite merged = ExperimentalSerializationUtil.fromByteArray(data, Proto2MessageLite.class); - assertEquals(789, merged.getFieldMessage10().getFieldInt643()); - assertEquals(456, merged.getFieldMessage10().getFieldInt325()); + assertThat(merged.getFieldMessage10().getFieldInt643()).isEqualTo(789); + assertThat(merged.getFieldMessage10().getFieldInt325()).isEqualTo(456); } @Test @@ -133,7 +132,7 @@ byte[] roundtripBytes = ExperimentalSerializationUtil.toByteArray(empty); Proto2MessageLite roundtripMessage = ExperimentalSerializationUtil.fromByteArray(roundtripBytes, Proto2MessageLite.class); - assertEquals(expectedMessage, roundtripMessage); + assertThat(roundtripMessage).isEqualTo(expectedMessage); } @Test @@ -141,7 +140,7 @@ // Use unknown fields to hold invalid enum values. UnknownFieldSetLite unknowns = UnknownFieldSetLite.newInstance(); final int outOfRange = 1000; - assertNull(TestEnum.forNumber(outOfRange)); + assertThat(TestEnum.forNumber(outOfRange)).isNull(); unknowns.storeField( WireFormat.makeTag( Proto2MessageLite.FIELD_ENUM_13_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT), @@ -184,16 +183,18 @@ Proto2MessageLite parsed = ExperimentalSerializationUtil.fromByteArray(output, Proto2MessageLite.class); - assertFalse("out-of-range singular enum should not be in message", parsed.hasFieldEnum13()); - assertEquals( - "out-of-range repeated enum should not be in message", 2, parsed.getFieldEnumList30Count()); - assertEquals(TestEnum.ONE, parsed.getFieldEnumList30(0)); - assertEquals(TestEnum.TWO, parsed.getFieldEnumList30(1)); - assertEquals( - "out-of-range packed repeated enum should not be in message", - 2, - parsed.getFieldEnumListPacked44Count()); - assertEquals(TestEnum.ONE, parsed.getFieldEnumListPacked44(0)); - assertEquals(TestEnum.TWO, parsed.getFieldEnumListPacked44(1)); + assertWithMessage("out-of-range singular enum should not be in message") + .that(parsed.hasFieldEnum13()) + .isFalse(); + assertWithMessage("out-of-range repeated enum should not be in message") + .that(parsed.getFieldEnumList30Count()) + .isEqualTo(2); + assertThat(parsed.getFieldEnumList30(0)).isEqualTo(TestEnum.ONE); + assertThat(parsed.getFieldEnumList30(1)).isEqualTo(TestEnum.TWO); + assertWithMessage("out-of-range packed repeated enum should not be in message") + .that(parsed.getFieldEnumListPacked44Count()) + .isEqualTo(2); + assertThat(parsed.getFieldEnumListPacked44(0)).isEqualTo(TestEnum.ONE); + assertThat(parsed.getFieldEnumListPacked44(1)).isEqualTo(TestEnum.TWO); } }
diff --git a/java/core/src/test/java/com/google/protobuf/AbstractProto2SchemaTest.java b/java/core/src/test/java/com/google/protobuf/AbstractProto2SchemaTest.java index 0c16818..39980a7 100644 --- a/java/core/src/test/java/com/google/protobuf/AbstractProto2SchemaTest.java +++ b/java/core/src/test/java/com/google/protobuf/AbstractProto2SchemaTest.java
@@ -30,9 +30,8 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import com.google.protobuf.testing.Proto2Testing.Proto2Empty; import com.google.protobuf.testing.Proto2Testing.Proto2Message; @@ -72,8 +71,8 @@ byte[] data = output.toByteArray(); Proto2Message merged = ExperimentalSerializationUtil.fromByteArray(data, Proto2Message.class); - assertEquals(789, merged.getFieldMessage10().getFieldInt643()); - assertEquals(456, merged.getFieldMessage10().getFieldInt325()); + assertThat(merged.getFieldMessage10().getFieldInt643()).isEqualTo(789); + assertThat(merged.getFieldMessage10().getFieldInt325()).isEqualTo(456); } @Test @@ -125,10 +124,10 @@ // Merge serialized bytes into an empty message, then reserialize and merge it to a new // Proto2Message. Make sure the two messages equal. byte[] roundtripBytes = ExperimentalSerializationUtil.toByteArray(empty); - assertEquals(serializedBytes.length, roundtripBytes.length); + assertThat(serializedBytes).hasLength(roundtripBytes.length); Proto2Message roundtripMessage = ExperimentalSerializationUtil.fromByteArray(roundtripBytes, Proto2Message.class); - assertEquals(expectedMessage, roundtripMessage); + assertThat(roundtripMessage).isEqualTo(expectedMessage); } @Test @@ -136,7 +135,7 @@ // Use unknown fields to hold invalid enum values. UnknownFieldSetLite unknowns = UnknownFieldSetLite.newInstance(); final int outOfRange = 1000; - assertNull(TestEnum.forNumber(outOfRange)); + assertThat(TestEnum.forNumber(outOfRange)).isNull(); unknowns.storeField( WireFormat.makeTag(Proto2Message.FIELD_ENUM_13_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT), (long) outOfRange); @@ -177,15 +176,17 @@ codedOutput.flush(); Proto2Message parsed = ExperimentalSerializationUtil.fromByteArray(output, Proto2Message.class); - assertFalse("out-of-range singular enum should not be in message", parsed.hasFieldEnum13()); + assertWithMessage("out-of-range singular enum should not be in message") + .that(parsed.hasFieldEnum13()) + .isFalse(); { List<Long> singularEnum = parsed .getUnknownFields() .getField(Proto2Message.FIELD_ENUM_13_FIELD_NUMBER) .getVarintList(); - assertEquals(1, singularEnum.size()); - assertEquals((Long) (long) outOfRange, singularEnum.get(0)); + assertThat(singularEnum).hasSize(1); + assertThat((Long) (long) outOfRange).isEqualTo(singularEnum.get(0)); } { List<Long> repeatedEnum = @@ -193,8 +194,8 @@ .getUnknownFields() .getField(Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER) .getVarintList(); - assertEquals(1, repeatedEnum.size()); - assertEquals((Long) (long) outOfRange, repeatedEnum.get(0)); + assertThat(repeatedEnum).hasSize(1); + assertThat((Long) (long) outOfRange).isEqualTo(repeatedEnum.get(0)); } { List<Long> packedRepeatedEnum = @@ -202,19 +203,19 @@ .getUnknownFields() .getField(Proto2Message.FIELD_ENUM_LIST_PACKED_44_FIELD_NUMBER) .getVarintList(); - assertEquals(1, packedRepeatedEnum.size()); - assertEquals((Long) (long) outOfRange, packedRepeatedEnum.get(0)); + assertThat(packedRepeatedEnum).hasSize(1); + assertThat((Long) (long) outOfRange).isEqualTo(packedRepeatedEnum.get(0)); } - assertEquals( - "out-of-range repeated enum should not be in message", 2, parsed.getFieldEnumList30Count()); - assertEquals(TestEnum.ONE, parsed.getFieldEnumList30(0)); - assertEquals(TestEnum.TWO, parsed.getFieldEnumList30(1)); - assertEquals( - "out-of-range packed repeated enum should not be in message", - 2, - parsed.getFieldEnumListPacked44Count()); - assertEquals(TestEnum.ONE, parsed.getFieldEnumListPacked44(0)); - assertEquals(TestEnum.TWO, parsed.getFieldEnumListPacked44(1)); + assertWithMessage("out-of-range repeated enum should not be in message") + .that(parsed.getFieldEnumList30Count()) + .isEqualTo(2); + assertThat(parsed.getFieldEnumList30(0)).isEqualTo(TestEnum.ONE); + assertThat(parsed.getFieldEnumList30(1)).isEqualTo(TestEnum.TWO); + assertWithMessage("out-of-range packed repeated enum should not be in message") + .that(parsed.getFieldEnumListPacked44Count()) + .isEqualTo(2); + assertThat(parsed.getFieldEnumListPacked44(0)).isEqualTo(TestEnum.ONE); + assertThat(parsed.getFieldEnumListPacked44(1)).isEqualTo(TestEnum.TWO); } @Override
diff --git a/java/core/src/test/java/com/google/protobuf/AbstractProto3LiteSchemaTest.java b/java/core/src/test/java/com/google/protobuf/AbstractProto3LiteSchemaTest.java index 9cc04ec..ea53a17 100644 --- a/java/core/src/test/java/com/google/protobuf/AbstractProto3LiteSchemaTest.java +++ b/java/core/src/test/java/com/google/protobuf/AbstractProto3LiteSchemaTest.java
@@ -30,7 +30,7 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; +import static com.google.common.truth.Truth.assertThat; import com.google.protobuf.testing.Proto3TestingLite.Proto3EmptyLite; import com.google.protobuf.testing.Proto3TestingLite.Proto3MessageLite; @@ -94,8 +94,8 @@ Proto3MessageLite merged = ExperimentalSerializationUtil.fromByteArray(data, Proto3MessageLite.class); - assertEquals(789, merged.getFieldMessage10().getFieldInt643()); - assertEquals(456, merged.getFieldMessage10().getFieldInt325()); + assertThat(merged.getFieldMessage10().getFieldInt643()).isEqualTo(789); + assertThat(merged.getFieldMessage10().getFieldInt325()).isEqualTo(456); } @Test @@ -126,7 +126,7 @@ Proto3EmptyLite empty = ExperimentalSerializationUtil.fromByteArray( expectedMessage.toByteArray(), Proto3EmptyLite.class); - assertEquals(expectedMessage.getSerializedSize(), empty.getSerializedSize()); + assertThat(empty.getSerializedSize()).isEqualTo(expectedMessage.getSerializedSize()); } @Test
diff --git a/java/core/src/test/java/com/google/protobuf/AbstractProto3SchemaTest.java b/java/core/src/test/java/com/google/protobuf/AbstractProto3SchemaTest.java index 358f1e3..5d9883f 100644 --- a/java/core/src/test/java/com/google/protobuf/AbstractProto3SchemaTest.java +++ b/java/core/src/test/java/com/google/protobuf/AbstractProto3SchemaTest.java
@@ -30,7 +30,7 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; +import static com.google.common.truth.Truth.assertThat; import com.google.protobuf.testing.Proto3Testing.Proto3Empty; import com.google.protobuf.testing.Proto3Testing.Proto3Message; @@ -93,8 +93,8 @@ byte[] data = output.toByteArray(); Proto3Message merged = ExperimentalSerializationUtil.fromByteArray(data, Proto3Message.class); - assertEquals(789, merged.getFieldMessage10().getFieldInt643()); - assertEquals(456, merged.getFieldMessage10().getFieldInt325()); + assertThat(merged.getFieldMessage10().getFieldInt643()).isEqualTo(789); + assertThat(merged.getFieldMessage10().getFieldInt325()).isEqualTo(456); } @Test @@ -124,8 +124,8 @@ Proto3Empty empty = ExperimentalSerializationUtil.fromByteArray( expectedMessage.toByteArray(), Proto3Empty.class); - assertEquals(expectedMessage.getSerializedSize(), empty.getSerializedSize()); - assertEquals(expectedMessage.toByteString(), empty.toByteString()); + assertThat(empty.getSerializedSize()).isEqualTo(expectedMessage.getSerializedSize()); + assertThat(empty.toByteString()).isEqualTo(expectedMessage.toByteString()); } @Test @@ -134,7 +134,7 @@ // supported in proto3, e.g. groups. byte[] payload = new Proto2MessageFactory(10, 20, 2, 2).newMessage().toByteArray(); Proto3Empty empty = ExperimentalSerializationUtil.fromByteArray(payload, Proto3Empty.class); - assertEquals(payload.length, empty.getSerializedSize()); + assertThat(empty.getSerializedSize()).isEqualTo(payload.length); } @Test
diff --git a/java/core/src/test/java/com/google/protobuf/AbstractSchemaTest.java b/java/core/src/test/java/com/google/protobuf/AbstractSchemaTest.java index c69a4fd..7ca5e03 100644 --- a/java/core/src/test/java/com/google/protobuf/AbstractSchemaTest.java +++ b/java/core/src/test/java/com/google/protobuf/AbstractSchemaTest.java
@@ -30,10 +30,8 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.fail; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import java.io.IOException; import java.nio.ByteBuffer; @@ -80,7 +78,7 @@ T newMsg = schema.newInstance(); try { schema.mergeFrom(newMsg, reader, ExtensionRegistryLite.getEmptyRegistry()); - fail("should throw invalid "); + assertWithMessage("should throw invalid").fail(); } catch (InvalidProtocolBufferException expected) { } } @@ -106,13 +104,15 @@ exceptionCount += 1; } } - assertNotEquals(0, exceptionCount); + assertThat(exceptionCount).isNotEqualTo(0); } protected static final <M extends MessageLite> void roundtrip( String failureMessage, M msg, Schema<M> schema) throws IOException { byte[] serializedBytes = ExperimentalSerializationUtil.toByteArray(msg, schema); - assertEquals(failureMessage, msg.getSerializedSize(), serializedBytes.length); + assertWithMessage(failureMessage) + .that(serializedBytes.length) + .isEqualTo(msg.getSerializedSize()); // Now read it back in and verify it matches the original. if (Android.isOnAndroidDevice()) { @@ -121,14 +121,14 @@ schema.mergeFrom( newMsg, serializedBytes, 0, serializedBytes.length, new ArrayDecoders.Registers()); schema.makeImmutable(newMsg); - assertEquals(failureMessage, msg, newMsg); + assertWithMessage(failureMessage).that(newMsg).isEqualTo(msg); } M newMsg = schema.newInstance(); Reader reader = BinaryReader.newInstance(ByteBuffer.wrap(serializedBytes), true); schema.mergeFrom(newMsg, reader, ExtensionRegistryLite.getEmptyRegistry()); schema.makeImmutable(newMsg); - assertEquals(failureMessage, msg, newMsg); + assertWithMessage(failureMessage).that(newMsg).isEqualTo(msg); } protected final void roundtrip(String failureMessage, T msg) throws IOException { @@ -148,10 +148,10 @@ public void testRequiredFields() throws Exception { for (T msg : newMessagesMissingRequiredFields()) { if (schema.isInitialized(msg)) { - assertEquals("", msg.toString()); + assertThat(msg.toString()).isEmpty(); msg = (T) msg.toBuilder().build(); } - assertFalse(schema.isInitialized(msg)); + assertThat(schema.isInitialized(msg)).isFalse(); } } }
diff --git a/java/core/src/test/java/com/google/protobuf/AnyTest.java b/java/core/src/test/java/com/google/protobuf/AnyTest.java index d660ca7..ee13ef1 100644 --- a/java/core/src/test/java/com/google/protobuf/AnyTest.java +++ b/java/core/src/test/java/com/google/protobuf/AnyTest.java
@@ -30,13 +30,21 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import any_test.AnyTestProto.TestAny; import protobuf_unittest.UnittestProto.TestAllTypes; import java.util.Objects; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Unit tests for Any message. */ -public class AnyTest extends TestCase { +@RunWith(JUnit4.class) +public class AnyTest { + + @Test public void testAnyGeneratedApi() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); @@ -44,8 +52,8 @@ TestAny container = TestAny.newBuilder().setValue(Any.pack(message)).build(); - assertTrue(container.getValue().is(TestAllTypes.class)); - assertFalse(container.getValue().is(TestAny.class)); + assertThat(container.getValue().is(TestAllTypes.class)).isTrue(); + assertThat(container.getValue().is(TestAny.class)).isFalse(); TestAllTypes result = container.getValue().unpack(TestAllTypes.class); TestUtil.assertAllFieldsSet(result); @@ -54,7 +62,7 @@ // Unpacking to a wrong type will throw an exception. try { container.getValue().unpack(TestAny.class); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (InvalidProtocolBufferException e) { // expected. } @@ -65,12 +73,13 @@ container = containerBuilder.build(); try { container.getValue().unpack(TestAllTypes.class); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (InvalidProtocolBufferException e) { // expected. } } + @Test public void testCustomTypeUrls() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); @@ -78,38 +87,39 @@ TestAny container = TestAny.newBuilder().setValue(Any.pack(message, "xxx.com")).build(); - assertEquals( - "xxx.com/" + TestAllTypes.getDescriptor().getFullName(), container.getValue().getTypeUrl()); + assertThat(container.getValue().getTypeUrl()) + .isEqualTo("xxx.com/" + TestAllTypes.getDescriptor().getFullName()); - assertTrue(container.getValue().is(TestAllTypes.class)); - assertFalse(container.getValue().is(TestAny.class)); + assertThat(container.getValue().is(TestAllTypes.class)).isTrue(); + assertThat(container.getValue().is(TestAny.class)).isFalse(); TestAllTypes result = container.getValue().unpack(TestAllTypes.class); TestUtil.assertAllFieldsSet(result); container = TestAny.newBuilder().setValue(Any.pack(message, "yyy.com/")).build(); - assertEquals( - "yyy.com/" + TestAllTypes.getDescriptor().getFullName(), container.getValue().getTypeUrl()); + assertThat(container.getValue().getTypeUrl()) + .isEqualTo("yyy.com/" + TestAllTypes.getDescriptor().getFullName()); - assertTrue(container.getValue().is(TestAllTypes.class)); - assertFalse(container.getValue().is(TestAny.class)); + assertThat(container.getValue().is(TestAllTypes.class)).isTrue(); + assertThat(container.getValue().is(TestAny.class)).isFalse(); result = container.getValue().unpack(TestAllTypes.class); TestUtil.assertAllFieldsSet(result); container = TestAny.newBuilder().setValue(Any.pack(message, "")).build(); - assertEquals( - "/" + TestAllTypes.getDescriptor().getFullName(), container.getValue().getTypeUrl()); + assertThat(container.getValue().getTypeUrl()) + .isEqualTo("/" + TestAllTypes.getDescriptor().getFullName()); - assertTrue(container.getValue().is(TestAllTypes.class)); - assertFalse(container.getValue().is(TestAny.class)); + assertThat(container.getValue().is(TestAllTypes.class)).isTrue(); + assertThat(container.getValue().is(TestAny.class)).isFalse(); result = container.getValue().unpack(TestAllTypes.class); TestUtil.assertAllFieldsSet(result); } + @Test public void testCachedUnpackResult() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); @@ -117,10 +127,10 @@ TestAny container = TestAny.newBuilder().setValue(Any.pack(message)).build(); - assertTrue(container.getValue().is(TestAllTypes.class)); + assertThat(container.getValue().is(TestAllTypes.class)).isTrue(); TestAllTypes result1 = container.getValue().unpack(TestAllTypes.class); TestAllTypes result2 = container.getValue().unpack(TestAllTypes.class); - assertTrue(Objects.equals(result1, result2)); + assertThat(Objects.equals(result1, result2)).isTrue(); } }
diff --git a/java/core/src/test/java/com/google/protobuf/ArrayDecodersTest.java b/java/core/src/test/java/com/google/protobuf/ArrayDecodersTest.java index 037173b..895c9bd 100644 --- a/java/core/src/test/java/com/google/protobuf/ArrayDecodersTest.java +++ b/java/core/src/test/java/com/google/protobuf/ArrayDecodersTest.java
@@ -30,11 +30,17 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertWithMessage; + import com.google.protobuf.ArrayDecoders.Registers; import java.io.IOException; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -public class ArrayDecodersTest extends TestCase { +@RunWith(JUnit4.class) +public class ArrayDecodersTest { private static final int TAG = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); private static final ByteString NEGATIVE_SIZE_0 = generateNegativeLength(0); @@ -42,36 +48,40 @@ private Registers registers; - @Override + @Before public void setUp() { registers = new Registers(); registers.int1 = TAG; } + @Test public void testException_decodeString() { try { ArrayDecoders.decodeString(NEGATIVE_SIZE_0.toByteArray(), 0, registers); - fail(); + assertWithMessage("should throw exception").fail(); } catch (InvalidProtocolBufferException expected) { } } + @Test public void testException_decodeStringRequireUtf8() { try { ArrayDecoders.decodeStringRequireUtf8(NEGATIVE_SIZE_0.toByteArray(), 0, registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } } + @Test public void testException_decodeBytes() { try { ArrayDecoders.decodeBytes(NEGATIVE_SIZE_0.toByteArray(), 0, registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } } + @Test public void testException_decodeStringList_first() { try { ArrayDecoders.decodeStringList( @@ -81,11 +91,12 @@ NEGATIVE_SIZE_0.size(), new ProtobufArrayList<Object>(), registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } } + @Test public void testException_decodeStringList_second() { try { ArrayDecoders.decodeStringList( @@ -95,11 +106,12 @@ NEGATIVE_SIZE_1.size(), new ProtobufArrayList<Object>(), registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } } + @Test public void testException_decodeStringListRequireUtf8_first() { try { ArrayDecoders.decodeStringListRequireUtf8( @@ -109,11 +121,12 @@ NEGATIVE_SIZE_0.size(), new ProtobufArrayList<Object>(), registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } } + @Test public void testException_decodeStringListRequireUtf8_second() { try { ArrayDecoders.decodeStringListRequireUtf8( @@ -123,11 +136,12 @@ NEGATIVE_SIZE_1.size(), new ProtobufArrayList<Object>(), registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } } + @Test public void testException_decodeBytesList_first() { try { ArrayDecoders.decodeBytesList( @@ -137,11 +151,12 @@ NEGATIVE_SIZE_0.size(), new ProtobufArrayList<Object>(), registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } } + @Test public void testException_decodeBytesList_second() { try { ArrayDecoders.decodeBytesList( @@ -151,11 +166,12 @@ NEGATIVE_SIZE_1.size(), new ProtobufArrayList<Object>(), registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } } + @Test public void testException_decodeUnknownField() { try { ArrayDecoders.decodeUnknownField( @@ -165,11 +181,12 @@ NEGATIVE_SIZE_0.size(), UnknownFieldSetLite.newInstance(), registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } } + @Test public void testException_decodeHugeField() { byte[] badBytes = new byte[] { @@ -178,13 +195,13 @@ try { ArrayDecoders.decodeUnknownField( TAG, badBytes, 0, badBytes.length, UnknownFieldSetLite.newInstance(), registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } try { ArrayDecoders.decodeBytes(badBytes, 0, registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } @@ -206,7 +223,7 @@ try { ArrayDecoders.decodeBytesList( TAG, badBytesList, 0, badBytes.length, new ProtobufArrayList<>(), registers); - fail(); + assertWithMessage("should throw an exception").fail(); } catch (InvalidProtocolBufferException expected) { } }
diff --git a/java/core/src/test/java/com/google/protobuf/BinaryProtocolTest.java b/java/core/src/test/java/com/google/protobuf/BinaryProtocolTest.java index cda2998..0853b9a 100644 --- a/java/core/src/test/java/com/google/protobuf/BinaryProtocolTest.java +++ b/java/core/src/test/java/com/google/protobuf/BinaryProtocolTest.java
@@ -30,11 +30,10 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; +import static com.google.common.truth.Truth.assertThat; import com.google.protobuf.testing.Proto2Testing.Proto2Message; import com.google.protobuf.testing.Proto3Testing.Proto3Message; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -58,15 +57,15 @@ // Deserialize with BinaryReader and verify that the message matches the original. Proto3Message result = ExperimentalSerializationUtil.fromByteArray(expectedBytes, Proto3Message.class); - assertEquals(expected, result); + assertThat(result).isEqualTo(expected); // Now write it back out using BinaryWriter and verify the output length. byte[] actualBytes = ExperimentalSerializationUtil.toByteArray(result); - Assert.assertEquals(expectedBytes.length, actualBytes.length); + assertThat(actualBytes).hasLength(expectedBytes.length); // Read back in the bytes and verify that it matches the original message. Proto3Message actual = Proto3Message.parseFrom(actualBytes); - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -77,14 +76,14 @@ // Deserialize with BinaryReader and verify that the message matches the original. Proto2Message result = ExperimentalSerializationUtil.fromByteArray(expectedBytes, Proto2Message.class); - assertEquals(expected, result); + assertThat(result).isEqualTo(expected); // Now write it back out using BinaryWriter and verify the output length. byte[] actualBytes = ExperimentalSerializationUtil.toByteArray(result); - Assert.assertEquals(expectedBytes.length, actualBytes.length); + assertThat(actualBytes).hasLength(expectedBytes.length); // Read back in the bytes and verify that it matches the original message. Proto2Message actual = Proto2Message.parseFrom(actualBytes); - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } }
diff --git a/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java b/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java index 805b7b0..2050507 100644 --- a/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java
@@ -30,20 +30,22 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static java.util.Arrays.asList; import com.google.protobuf.Internal.BooleanList; import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.Iterator; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Tests for {@link BooleanArrayList}. - * - * @author dweis@google.com (Daniel Weis) - */ -public class BooleanArrayListTest extends TestCase { +/** Tests for {@link BooleanArrayList}. */ +@RunWith(JUnit4.class) +public class BooleanArrayListTest { private static final BooleanArrayList UNARY_LIST = newImmutableBooleanArrayList(true); private static final BooleanArrayList TERTIARY_LIST = @@ -51,19 +53,22 @@ private BooleanArrayList list; - @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { list = new BooleanArrayList(); } + @Test public void testEmptyListReturnsSameInstance() { - assertSame(BooleanArrayList.emptyList(), BooleanArrayList.emptyList()); + assertThat(BooleanArrayList.emptyList()).isSameInstanceAs(BooleanArrayList.emptyList()); } + @Test public void testEmptyListIsImmutable() { assertImmutable(BooleanArrayList.emptyList()); } + @Test public void testMakeImmutable() { list.addBoolean(true); list.addBoolean(false); @@ -73,19 +78,20 @@ assertImmutable(list); } + @Test public void testModificationWithIteration() { list.addAll(asList(true, false, true, false)); Iterator<Boolean> iterator = list.iterator(); - assertEquals(4, list.size()); - assertEquals(true, (boolean) list.get(0)); - assertEquals(true, (boolean) iterator.next()); + assertThat(list).hasSize(4); + assertThat((boolean) list.get(0)).isEqualTo(true); + assertThat((boolean) iterator.next()).isEqualTo(true); list.set(0, true); - assertEquals(false, (boolean) iterator.next()); + assertThat((boolean) iterator.next()).isEqualTo(false); list.remove(0); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail(); } catch (ConcurrentModificationException e) { // expected } @@ -94,191 +100,211 @@ list.add(0, false); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail(); } catch (ConcurrentModificationException e) { // expected } } + @Test public void testGet() { - assertEquals(true, (boolean) TERTIARY_LIST.get(0)); - assertEquals(false, (boolean) TERTIARY_LIST.get(1)); - assertEquals(true, (boolean) TERTIARY_LIST.get(2)); + assertThat((boolean) TERTIARY_LIST.get(0)).isEqualTo(true); + assertThat((boolean) TERTIARY_LIST.get(1)).isEqualTo(false); + assertThat((boolean) TERTIARY_LIST.get(2)).isEqualTo(true); try { TERTIARY_LIST.get(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { TERTIARY_LIST.get(3); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testGetBoolean() { - assertEquals(true, TERTIARY_LIST.getBoolean(0)); - assertEquals(false, TERTIARY_LIST.getBoolean(1)); - assertEquals(true, TERTIARY_LIST.getBoolean(2)); + assertThat(TERTIARY_LIST.getBoolean(0)).isEqualTo(true); + assertThat(TERTIARY_LIST.getBoolean(1)).isEqualTo(false); + assertThat(TERTIARY_LIST.getBoolean(2)).isEqualTo(true); try { TERTIARY_LIST.get(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { TERTIARY_LIST.get(3); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testIndexOf_nullElement() { - assertEquals(-1, TERTIARY_LIST.indexOf(null)); + assertThat(TERTIARY_LIST.indexOf(null)).isEqualTo(-1); } + @Test public void testIndexOf_incompatibleElementType() { - assertEquals(-1, TERTIARY_LIST.indexOf(new Object())); + assertThat(TERTIARY_LIST.indexOf(new Object())).isEqualTo(-1); } + @Test public void testIndexOf_notInList() { - assertEquals(-1, UNARY_LIST.indexOf(false)); + assertThat(UNARY_LIST.indexOf(false)).isEqualTo(-1); } + @Test public void testIndexOf_notInListWithDuplicates() { BooleanArrayList listWithDupes = newImmutableBooleanArrayList(true, true); - assertEquals(-1, listWithDupes.indexOf(false)); + assertThat(listWithDupes.indexOf(false)).isEqualTo(-1); } + @Test public void testIndexOf_inList() { - assertEquals(1, TERTIARY_LIST.indexOf(false)); + assertThat(TERTIARY_LIST.indexOf(false)).isEqualTo(1); } + @Test public void testIndexOf_inListWithDuplicates_matchAtHead() { BooleanArrayList listWithDupes = newImmutableBooleanArrayList(true, true, false); - assertEquals(0, listWithDupes.indexOf(true)); + assertThat(listWithDupes.indexOf(true)).isEqualTo(0); } + @Test public void testIndexOf_inListWithDuplicates_matchMidList() { BooleanArrayList listWithDupes = newImmutableBooleanArrayList(false, true, true, false); - assertEquals(1, listWithDupes.indexOf(true)); + assertThat(listWithDupes.indexOf(true)).isEqualTo(1); } + @Test public void testContains_nullElement() { - assertEquals(false, TERTIARY_LIST.contains(null)); + assertThat(TERTIARY_LIST).doesNotContain(null); } + @Test public void testContains_incompatibleElementType() { - assertEquals(false, TERTIARY_LIST.contains(new Object())); + assertThat(TERTIARY_LIST).doesNotContain(new Object()); } + @Test public void testContains_notInList() { - assertEquals(false, UNARY_LIST.contains(false)); + assertThat(UNARY_LIST).doesNotContain(false); } + @Test public void testContains_notInListWithDuplicates() { BooleanArrayList listWithDupes = newImmutableBooleanArrayList(true, true); - assertEquals(false, listWithDupes.contains(false)); + assertThat(listWithDupes).doesNotContain(false); } + @Test public void testContains_inList() { - assertEquals(true, TERTIARY_LIST.contains(false)); + assertThat(TERTIARY_LIST).contains(false); } + @Test public void testContains_inListWithDuplicates_matchAtHead() { BooleanArrayList listWithDupes = newImmutableBooleanArrayList(true, true, false); - assertEquals(true, listWithDupes.contains(true)); + assertThat(listWithDupes).contains(true); } + @Test public void testContains_inListWithDuplicates_matchMidList() { BooleanArrayList listWithDupes = newImmutableBooleanArrayList(false, true, true, false); - assertEquals(true, listWithDupes.contains(true)); + assertThat(listWithDupes).contains(true); } + @Test public void testSize() { - assertEquals(0, BooleanArrayList.emptyList().size()); - assertEquals(1, UNARY_LIST.size()); - assertEquals(3, TERTIARY_LIST.size()); + assertThat(BooleanArrayList.emptyList()).isEmpty(); + assertThat(UNARY_LIST).hasSize(1); + assertThat(TERTIARY_LIST).hasSize(3); list.addBoolean(true); list.addBoolean(false); list.addBoolean(false); list.addBoolean(false); - assertEquals(4, list.size()); + assertThat(list).hasSize(4); list.remove(0); - assertEquals(3, list.size()); + assertThat(list).hasSize(3); list.add(true); - assertEquals(4, list.size()); + assertThat(list).hasSize(4); } + @Test public void testSet() { list.addBoolean(false); list.addBoolean(false); - assertEquals(false, (boolean) list.set(0, true)); - assertEquals(true, list.getBoolean(0)); + assertThat((boolean) list.set(0, true)).isEqualTo(false); + assertThat(list.getBoolean(0)).isEqualTo(true); - assertEquals(false, (boolean) list.set(1, false)); - assertEquals(false, list.getBoolean(1)); + assertThat((boolean) list.set(1, false)).isEqualTo(false); + assertThat(list.getBoolean(1)).isEqualTo(false); try { list.set(-1, false); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.set(2, false); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testSetBoolean() { list.addBoolean(true); list.addBoolean(true); - assertEquals(true, list.setBoolean(0, false)); - assertEquals(false, list.getBoolean(0)); + assertThat(list.setBoolean(0, false)).isEqualTo(true); + assertThat(list.getBoolean(0)).isEqualTo(false); - assertEquals(true, list.setBoolean(1, false)); - assertEquals(false, list.getBoolean(1)); + assertThat(list.setBoolean(1, false)).isEqualTo(true); + assertThat(list.getBoolean(1)).isEqualTo(false); try { list.setBoolean(-1, false); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.setBoolean(2, false); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testAdd() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); - assertTrue(list.add(false)); - assertEquals(asList(false), list); + assertThat(list.add(false)).isTrue(); + assertThat(list).containsExactly(false); - assertTrue(list.add(true)); + assertThat(list.add(true)).isTrue(); list.add(0, false); - assertEquals(asList(false, false, true), list); + assertThat(list).containsExactly(false, false, true).inOrder(); list.add(0, true); list.add(0, false); @@ -286,8 +312,9 @@ for (int i = 0; i < 6; i++) { list.add(i % 2 == 0); } - assertEquals( - asList(false, true, false, false, true, true, false, true, false, true, false), list); + assertThat(list) + .containsExactly(false, true, false, false, true, true, false, true, false, true, false) + .inOrder(); try { list.add(-1, true); @@ -302,237 +329,247 @@ } } + @Test public void testAddBoolean() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); list.addBoolean(false); - assertEquals(asList(false), list); + assertThat(list).containsExactly(false); list.addBoolean(true); - assertEquals(asList(false, true), list); + assertThat(list).containsExactly(false, true).inOrder(); } + @Test public void testAddAll() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); - assertTrue(list.addAll(Collections.singleton(true))); - assertEquals(1, list.size()); - assertEquals(true, (boolean) list.get(0)); - assertEquals(true, list.getBoolean(0)); + assertThat(list.addAll(Collections.singleton(true))).isTrue(); + assertThat(list).hasSize(1); + assertThat((boolean) list.get(0)).isEqualTo(true); + assertThat(list.getBoolean(0)).isEqualTo(true); - assertTrue(list.addAll(asList(false, true, false, true, false))); - assertEquals(asList(true, false, true, false, true, false), list); + assertThat(list.addAll(asList(false, true, false, true, false))).isTrue(); + assertThat(list).containsExactly(true, false, true, false, true, false).inOrder(); - assertTrue(list.addAll(TERTIARY_LIST)); - assertEquals(asList(true, false, true, false, true, false, true, false, true), list); + assertThat(list.addAll(TERTIARY_LIST)).isTrue(); + assertThat(list) + .containsExactly(true, false, true, false, true, false, true, false, true) + .inOrder(); - assertFalse(list.addAll(Collections.<Boolean>emptyList())); - assertFalse(list.addAll(BooleanArrayList.emptyList())); + assertThat(list.addAll(Collections.<Boolean>emptyList())).isFalse(); + assertThat(list.addAll(BooleanArrayList.emptyList())).isFalse(); } + @Test public void testEquals() { BooleanArrayList list1 = new BooleanArrayList(); BooleanArrayList list2 = new BooleanArrayList(); - assertEquals(list1, list2); + assertThat(list1).isEqualTo(list2); } + @Test public void testRemove() { list.addAll(TERTIARY_LIST); - assertEquals(true, (boolean) list.remove(0)); - assertEquals(asList(false, true), list); + assertThat((boolean) list.remove(0)).isEqualTo(true); + assertThat(list).containsExactly(false, true).inOrder(); - assertTrue(list.remove(Boolean.TRUE)); - assertEquals(asList(false), list); + assertThat(list.remove(Boolean.TRUE)).isTrue(); + assertThat(list).containsExactly(false); - assertFalse(list.remove(Boolean.TRUE)); - assertEquals(asList(false), list); + assertThat(list.remove(Boolean.TRUE)).isFalse(); + assertThat(list).containsExactly(false); - assertEquals(false, (boolean) list.remove(0)); - assertEquals(asList(), list); + assertThat((boolean) list.remove(0)).isEqualTo(false); + assertThat(list).isEmpty(); try { list.remove(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.remove(0); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testRemoveEnd_listAtCapacity() { BooleanList toRemove = BooleanArrayList.emptyList().mutableCopyWithCapacity(1); toRemove.addBoolean(true); toRemove.remove(0); - assertEquals(0, toRemove.size()); + assertThat(toRemove).isEmpty(); } + @Test public void testRemove_listAtCapacity() { BooleanList toRemove = BooleanArrayList.emptyList().mutableCopyWithCapacity(2); toRemove.addBoolean(true); toRemove.addBoolean(false); toRemove.remove(0); - assertEquals(1, toRemove.size()); - assertEquals(false, (boolean) toRemove.get(0)); + assertThat(toRemove).hasSize(1); + assertThat((boolean) toRemove.get(0)).isEqualTo(false); } + @Test public void testSublistRemoveEndOfCapacity() { BooleanList toRemove = BooleanArrayList.emptyList().mutableCopyWithCapacity(1); toRemove.addBoolean(true); toRemove.subList(0, 1).clear(); - assertEquals(0, toRemove.size()); + assertThat(toRemove).isEmpty(); } private void assertImmutable(BooleanList list) { try { list.add(true); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.add(0, true); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(Collections.<Boolean>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(Collections.singletonList(true)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(new BooleanArrayList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, Collections.singleton(true)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, Collections.<Boolean>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addBoolean(false); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.clear(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.remove(1); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.remove(new Object()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(Collections.<Boolean>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(Collections.singleton(Boolean.TRUE)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(Collections.<Boolean>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(Collections.singleton(Boolean.TRUE)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.set(0, false); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.setBoolean(0, false); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected }
diff --git a/java/core/src/test/java/com/google/protobuf/BoundedByteStringTest.java b/java/core/src/test/java/com/google/protobuf/BoundedByteStringTest.java index 654d62b..656d2c3 100644 --- a/java/core/src/test/java/com/google/protobuf/BoundedByteStringTest.java +++ b/java/core/src/test/java/com/google/protobuf/BoundedByteStringTest.java
@@ -30,24 +30,30 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertWithMessage; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.UnsupportedEncodingException; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * This class tests {@link BoundedByteString}, which extends {@link LiteralByteString}, by * inheriting the tests from {@link LiteralByteStringTest}. The only method which is strange enough * that it needs to be overridden here is {@link #testToString()}. - * - * @author carlanton@google.com (Carl Haverl) */ +@RunWith(JUnit4.class) public class BoundedByteStringTest extends LiteralByteStringTest { @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { classUnderTest = "BoundedByteString"; byte[] sourceBytes = ByteStringTest.getTestBytes(2341, 11337766L); int from = 100; @@ -59,40 +65,39 @@ } @Override + @Test public void testToString() throws UnsupportedEncodingException { String testString = "I love unicode \u1234\u5678 characters"; ByteString unicode = ByteString.wrap(testString.getBytes(Internal.UTF_8)); ByteString chopped = unicode.substring(2, unicode.size() - 6); - assertEquals( - classUnderTest + ".substring() must have the expected type", - classUnderTest, - getActualClassName(chopped)); + assertWithMessage("%s.substring() must have the expected type", classUnderTest) + .that(classUnderTest) + .isEqualTo(getActualClassName(chopped)); String roundTripString = chopped.toString(UTF_8); - assertEquals( - classUnderTest + " unicode bytes must match", - testString.substring(2, testString.length() - 6), - roundTripString); + assertWithMessage("%s unicode bytes must match", classUnderTest) + .that(testString.substring(2, testString.length() - 6)) + .isEqualTo(roundTripString); } @Override + @Test public void testCharsetToString() { String testString = "I love unicode \u1234\u5678 characters"; ByteString unicode = ByteString.wrap(testString.getBytes(Internal.UTF_8)); ByteString chopped = unicode.substring(2, unicode.size() - 6); - assertEquals( - classUnderTest + ".substring() must have the expected type", - classUnderTest, - getActualClassName(chopped)); + assertWithMessage("%s.substring() must have the expected type", classUnderTest) + .that(classUnderTest) + .isEqualTo(getActualClassName(chopped)); String roundTripString = chopped.toString(Internal.UTF_8); - assertEquals( - classUnderTest + " unicode bytes must match", - testString.substring(2, testString.length() - 6), - roundTripString); + assertWithMessage("%s unicode bytes must match", classUnderTest) + .that(testString.substring(2, testString.length() - 6)) + .isEqualTo(roundTripString); } @Override + @Test public void testJavaSerialization() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); @@ -102,7 +107,7 @@ InputStream in = new ByteArrayInputStream(pickled); ObjectInputStream ois = new ObjectInputStream(in); Object o = ois.readObject(); - assertTrue("Didn't get a ByteString back", o instanceof ByteString); - assertEquals("Should get an equal ByteString back", stringUnderTest, o); + assertWithMessage("Didn't get a ByteString back").that(o).isInstanceOf(ByteString.class); + assertWithMessage("Should get an equal ByteString back").that(stringUnderTest).isEqualTo(o); } }
diff --git a/java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java b/java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java index 5f0ef62..11cdb02 100644 --- a/java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java +++ b/java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java
@@ -30,22 +30,29 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Random; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Tests for {@link ByteBufferWriter}. */ -public class ByteBufferWriterTest extends TestCase { +@RunWith(JUnit4.class) +public class ByteBufferWriterTest { + @Test public void testHeapBuffer() throws IOException { // Test a small and large buffer. testWrite(ByteBuffer.allocate(100)); testWrite(ByteBuffer.allocate(1024 * 100)); } + @Test public void testDirectBuffer() throws IOException { // Test a small and large buffer. testWrite(ByteBuffer.allocateDirect(100)); @@ -56,8 +63,8 @@ fillRandom(buffer); ByteArrayOutputStream os = new ByteArrayOutputStream(buffer.remaining()); ByteBufferWriter.write(buffer, os); - assertEquals(0, buffer.position()); - assertTrue(Arrays.equals(toArray(buffer), os.toByteArray())); + assertThat(buffer.position()).isEqualTo(0); + assertThat(Arrays.equals(toArray(buffer), os.toByteArray())).isTrue(); } private void fillRandom(ByteBuffer buf) {
diff --git a/java/core/src/test/java/com/google/protobuf/ByteStringTest.java b/java/core/src/test/java/com/google/protobuf/ByteStringTest.java index 1b1a786..3f97e31 100644 --- a/java/core/src/test/java/com/google/protobuf/ByteStringTest.java +++ b/java/core/src/test/java/com/google/protobuf/ByteStringTest.java
@@ -30,6 +30,9 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import com.google.protobuf.ByteString.Output; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -46,15 +49,16 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.Random; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Test methods with implementations in {@link ByteString}, plus do some top-level "integration" * tests. - * - * @author carlanton@google.com (Carl Haverl) */ -public class ByteStringTest extends TestCase { +@RunWith(JUnit4.class) +public class ByteStringTest { private static final Charset UTF_16 = Charset.forName("UTF-16"); @@ -87,17 +91,18 @@ return left.length == right.length && isArrayRange(left, right, 0, left.length); } + @Test public void testCompare_equalByteStrings_compareEqual() throws Exception { byte[] referenceBytes = getTestBytes(); ByteString string1 = ByteString.copyFrom(referenceBytes); ByteString string2 = ByteString.copyFrom(referenceBytes); - assertEquals( - "ByteString instances containing the same data must compare equal.", - 0, - ByteString.unsignedLexicographicalComparator().compare(string1, string2)); + assertWithMessage("ByteString instances containing the same data must compare equal.") + .that(ByteString.unsignedLexicographicalComparator().compare(string1, string2)) + .isEqualTo(0); } + @Test public void testCompare_byteStringsSortLexicographically() throws Exception { ByteString app = ByteString.copyFromUtf8("app"); ByteString apple = ByteString.copyFromUtf8("apple"); @@ -105,93 +110,109 @@ Comparator<ByteString> comparator = ByteString.unsignedLexicographicalComparator(); - assertTrue("ByteString(app) < ByteString(apple)", comparator.compare(app, apple) < 0); - assertTrue("ByteString(app) < ByteString(banana)", comparator.compare(app, banana) < 0); - assertTrue("ByteString(apple) < ByteString(banana)", comparator.compare(apple, banana) < 0); + assertWithMessage("ByteString(app) < ByteString(apple)") + .that(comparator.compare(app, apple) < 0) + .isTrue(); + assertWithMessage("ByteString(app) < ByteString(banana)") + .that(comparator.compare(app, banana) < 0) + .isTrue(); + assertWithMessage("ByteString(apple) < ByteString(banana)") + .that(comparator.compare(apple, banana) < 0) + .isTrue(); } + @Test public void testCompare_interpretsByteValuesAsUnsigned() throws Exception { // Two's compliment of `-1` == 0b11111111 == 255 ByteString twoHundredFiftyFive = ByteString.copyFrom(new byte[] {-1}); // 0b00000001 == 1 ByteString one = ByteString.copyFrom(new byte[] {1}); - assertTrue( - "ByteString comparison treats bytes as unsigned values", - ByteString.unsignedLexicographicalComparator().compare(one, twoHundredFiftyFive) < 0); + assertWithMessage("ByteString comparison treats bytes as unsigned values") + .that(ByteString.unsignedLexicographicalComparator().compare(one, twoHundredFiftyFive) < 0) + .isTrue(); } + @Test public void testSubstring_BeginIndex() { byte[] bytes = getTestBytes(); ByteString substring = ByteString.copyFrom(bytes).substring(500); - assertTrue( - "substring must contain the tail of the string", - isArrayRange(substring.toByteArray(), bytes, 500, bytes.length - 500)); + assertWithMessage("substring must contain the tail of the string") + .that(isArrayRange(substring.toByteArray(), bytes, 500, bytes.length - 500)) + .isTrue(); } + @Test public void testCopyFrom_BytesOffsetSize() { byte[] bytes = getTestBytes(); ByteString byteString = ByteString.copyFrom(bytes, 500, 200); - assertTrue( - "copyFrom sub-range must contain the expected bytes", - isArrayRange(byteString.toByteArray(), bytes, 500, 200)); + assertWithMessage("copyFrom sub-range must contain the expected bytes") + .that(isArrayRange(byteString.toByteArray(), bytes, 500, 200)) + .isTrue(); } + @Test public void testCopyFrom_Bytes() { byte[] bytes = getTestBytes(); ByteString byteString = ByteString.copyFrom(bytes); - assertTrue( - "copyFrom must contain the expected bytes", isArray(byteString.toByteArray(), bytes)); + assertWithMessage("copyFrom must contain the expected bytes") + .that(isArray(byteString.toByteArray(), bytes)) + .isTrue(); } + @Test public void testCopyFrom_ByteBufferSize() { byte[] bytes = getTestBytes(); ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length); byteBuffer.put(bytes); byteBuffer.position(500); ByteString byteString = ByteString.copyFrom(byteBuffer, 200); - assertTrue( - "copyFrom byteBuffer sub-range must contain the expected bytes", - isArrayRange(byteString.toByteArray(), bytes, 500, 200)); + assertWithMessage("copyFrom byteBuffer sub-range must contain the expected bytes") + .that(isArrayRange(byteString.toByteArray(), bytes, 500, 200)) + .isTrue(); } + @Test public void testCopyFrom_ByteBuffer() { byte[] bytes = getTestBytes(); ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length); byteBuffer.put(bytes); byteBuffer.position(500); ByteString byteString = ByteString.copyFrom(byteBuffer); - assertTrue( - "copyFrom byteBuffer sub-range must contain the expected bytes", - isArrayRange(byteString.toByteArray(), bytes, 500, bytes.length - 500)); + assertWithMessage("copyFrom byteBuffer sub-range must contain the expected bytes") + .that(isArrayRange(byteString.toByteArray(), bytes, 500, bytes.length - 500)) + .isTrue(); } + @Test public void testCopyFrom_StringEncoding() { String testString = "I love unicode \u1234\u5678 characters"; ByteString byteString = ByteString.copyFrom(testString, UTF_16); byte[] testBytes = testString.getBytes(UTF_16); - assertTrue( - "copyFrom string must respect the charset", - isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length)); + assertWithMessage("copyFrom string must respect the charset") + .that(isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length)) + .isTrue(); } + @Test public void testCopyFrom_Utf8() { String testString = "I love unicode \u1234\u5678 characters"; ByteString byteString = ByteString.copyFromUtf8(testString); byte[] testBytes = testString.getBytes(Internal.UTF_8); - assertTrue( - "copyFromUtf8 string must respect the charset", - isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length)); + assertWithMessage("copyFromUtf8 string must respect the charset") + .that(isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length)) + .isTrue(); } + @Test public void testCopyFrom_Iterable() { byte[] testBytes = getTestBytes(77777, 113344L); final List<ByteString> pieces = makeConcretePieces(testBytes); // Call copyFrom() on a Collection ByteString byteString = ByteString.copyFrom(pieces); - assertTrue( - "copyFrom a List must contain the expected bytes", - isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length)); + assertWithMessage("copyFrom a List must contain the expected bytes") + .that(isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length)) + .isTrue(); // Call copyFrom on an iteration that's not a collection ByteString byteStringAlt = ByteString.copyFrom( @@ -201,60 +222,65 @@ return pieces.iterator(); } }); - assertEquals( - "copyFrom from an Iteration must contain the expected bytes", byteString, byteStringAlt); + assertWithMessage("copyFrom from an Iteration must contain the expected bytes") + .that(byteString) + .isEqualTo(byteStringAlt); } + @Test public void testCopyFrom_LengthTooBig() { byte[] testBytes = getTestBytes(100); try { ByteString.copyFrom(testBytes, 0, 200); - fail("Should throw"); + assertWithMessage("Should throw").fail(); } catch (IndexOutOfBoundsException expected) { } try { ByteString.copyFrom(testBytes, 99, 2); - fail(); + assertWithMessage("Should throw").fail(); } catch (IndexOutOfBoundsException expected) { } ByteBuffer buf = ByteBuffer.wrap(testBytes); try { ByteString.copyFrom(buf, 101); - fail(); + assertWithMessage("Should throw").fail(); } catch (IndexOutOfBoundsException expected) { } try { ByteString.copyFrom(testBytes, -1, 10); - fail("Should throw"); + assertWithMessage("Should throw").fail(); } catch (IndexOutOfBoundsException expected) { } } + @Test public void testCopyTo_TargetOffset() { byte[] bytes = getTestBytes(); ByteString byteString = ByteString.copyFrom(bytes); byte[] target = new byte[bytes.length + 1000]; byteString.copyTo(target, 400); - assertTrue( - "copyFrom byteBuffer sub-range must contain the expected bytes", - isArrayRange(bytes, target, 400, bytes.length)); + assertWithMessage("copyFrom byteBuffer sub-range must contain the expected bytes") + .that(isArrayRange(bytes, target, 400, bytes.length)) + .isTrue(); } + @Test public void testReadFrom_emptyStream() throws IOException { ByteString byteString = ByteString.readFrom(new ByteArrayInputStream(new byte[0])); - assertSame( - "reading an empty stream must result in the EMPTY constant byte string", - ByteString.EMPTY, - byteString); + assertWithMessage("reading an empty stream must result in the EMPTY constant byte string") + .that(ByteString.EMPTY) + .isSameInstanceAs(byteString); } + @Test public void testReadFrom_smallStream() throws IOException { assertReadFrom(getTestBytes(10)); } + @Test public void testReadFrom_mutating() throws IOException { EvilInputStream eis = new EvilInputStream(); ByteString byteString = ByteString.readFrom(eis); @@ -266,12 +292,13 @@ } byte[] newValue = byteString.toByteArray(); - assertTrue( - "copyFrom byteBuffer must not grant access to underlying array", - Arrays.equals(originalValue, newValue)); + assertWithMessage("copyFrom byteBuffer must not grant access to underlying array") + .that(Arrays.equals(originalValue, newValue)) + .isTrue(); } // Tests sizes that are near the rope copy-out threshold. + @Test public void testReadFrom_mediumStream() throws IOException { assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE - 1)); assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE)); @@ -280,6 +307,7 @@ } // Tests sizes that are over multi-segment rope threshold. + @Test public void testReadFrom_largeStream() throws IOException { assertReadFrom(getTestBytes(0x100)); assertReadFrom(getTestBytes(0x101)); @@ -293,6 +321,7 @@ } // Tests sizes that are near the read buffer size. + @Test public void testReadFrom_byteBoundaries() throws IOException { final int min = ByteString.MIN_READ_FROM_CHUNK_SIZE; final int max = ByteString.MAX_READ_FROM_CHUNK_SIZE; @@ -323,26 +352,30 @@ } // Tests that IOExceptions propagate through ByteString.readFrom(). + @Test public void testReadFrom_IOExceptions() { try { ByteString.readFrom(new FailStream()); - fail("readFrom must throw the underlying IOException"); + assertWithMessage("readFrom must throw the underlying IOException").fail(); } catch (IOException e) { - assertEquals( - "readFrom must throw the expected exception", "synthetic failure", e.getMessage()); + assertWithMessage("readFrom must throw the expected exception") + .that(e) + .hasMessageThat() + .isEqualTo("synthetic failure"); } } // Tests that ByteString.readFrom works with streams that don't // always fill their buffers. + @Test public void testReadFrom_reluctantStream() throws IOException { final byte[] data = getTestBytes(0x1000); ByteString byteString = ByteString.readFrom(new ReluctantStream(data)); - assertTrue( - "readFrom byte stream must contain the expected bytes", - isArray(byteString.toByteArray(), data)); + assertWithMessage("readFrom byte stream must contain the expected bytes") + .that(isArray(byteString.toByteArray(), data)) + .isTrue(); // Same test as above, but with some specific chunk sizes. assertReadFromReluctantStream(data, 100); @@ -358,27 +391,29 @@ // reluctant stream with the given chunkSize parameter. private void assertReadFromReluctantStream(byte[] bytes, int chunkSize) throws IOException { ByteString b = ByteString.readFrom(new ReluctantStream(bytes), chunkSize); - assertTrue( - "readFrom byte stream must contain the expected bytes", isArray(b.toByteArray(), bytes)); + assertWithMessage("readFrom byte stream must contain the expected bytes") + .that(isArray(b.toByteArray(), bytes)) + .isTrue(); } // Tests that ByteString.readFrom works with streams that implement // available(). + @Test public void testReadFrom_available() throws IOException { final byte[] data = getTestBytes(0x1001); ByteString byteString = ByteString.readFrom(new AvailableStream(data)); - assertTrue( - "readFrom byte stream must contain the expected bytes", - isArray(byteString.toByteArray(), data)); + assertWithMessage("readFrom byte stream must contain the expected bytes") + .that(isArray(byteString.toByteArray(), data)) + .isTrue(); } // Fails unless ByteString.readFrom reads the bytes correctly. private void assertReadFrom(byte[] bytes) throws IOException { ByteString byteString = ByteString.readFrom(new ByteArrayInputStream(bytes)); - assertTrue( - "readFrom byte stream must contain the expected bytes", - isArray(byteString.toByteArray(), bytes)); + assertWithMessage("readFrom byte stream must contain the expected bytes") + .that(isArray(byteString.toByteArray(), bytes)) + .isTrue(); } // A stream that fails when read. @@ -478,45 +513,53 @@ } } + @Test public void testToStringUtf8() { String testString = "I love unicode \u1234\u5678 characters"; byte[] testBytes = testString.getBytes(Internal.UTF_8); ByteString byteString = ByteString.copyFrom(testBytes); - assertEquals( - "copyToStringUtf8 must respect the charset", testString, byteString.toStringUtf8()); + assertWithMessage("copyToStringUtf8 must respect the charset") + .that(testString) + .isEqualTo(byteString.toStringUtf8()); } + @Test public void testToString() { String toString = ByteString.copyFrom("Here are some bytes: \t\u00a1".getBytes(Internal.UTF_8)).toString(); - assertTrue(toString, toString.contains("size=24")); - assertTrue(toString, toString.contains("contents=\"Here are some bytes: \\t\\302\\241\"")); + assertWithMessage(toString).that(toString.contains("size=24")).isTrue(); + assertWithMessage(toString) + .that(toString.contains("contents=\"Here are some bytes: \\t\\302\\241\"")) + .isTrue(); } + @Test public void testToString_long() { String toString = ByteString.copyFrom( "123456789012345678901234567890123456789012345678901234567890" .getBytes(Internal.UTF_8)) .toString(); - assertTrue(toString, toString.contains("size=60")); - assertTrue( - toString, - toString.contains("contents=\"12345678901234567890123456789012345678901234567...\"")); + assertWithMessage(toString).that(toString.contains("size=60")).isTrue(); + assertWithMessage(toString) + .that(toString.contains("contents=\"12345678901234567890123456789012345678901234567...\"")) + .isTrue(); } + @Test public void testNewOutput_InitialCapacity() throws IOException { byte[] bytes = getTestBytes(); ByteString.Output output = ByteString.newOutput(bytes.length + 100); output.write(bytes); ByteString byteString = output.toByteString(); - assertTrue( - "String built from newOutput(int) must contain the expected bytes", - isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)); + assertWithMessage("String built from newOutput(int) must contain the expected bytes") + .that(isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)) + .isTrue(); } // Test newOutput() using a variety of buffer sizes and a variety of (fixed) // write sizes + @Test public void testNewOutput_ArrayWrite() { byte[] bytes = getTestBytes(); int length = bytes.length; @@ -533,15 +576,16 @@ output.write(bytes, i, Math.min(writeSize, length - i)); } ByteString byteString = output.toByteString(); - assertTrue( - "String built from newOutput() must contain the expected bytes", - isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)); + assertWithMessage("String built from newOutput() must contain the expected bytes") + .that(isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)) + .isTrue(); } } } // Test newOutput() using a variety of buffer sizes, but writing all the // characters using write(byte); + @Test public void testNewOutput_WriteChar() { byte[] bytes = getTestBytes(); int length = bytes.length; @@ -554,14 +598,15 @@ output.write(byteValue); } ByteString byteString = output.toByteString(); - assertTrue( - "String built from newOutput() must contain the expected bytes", - isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)); + assertWithMessage("String built from newOutput() must contain the expected bytes") + .that(isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)) + .isTrue(); } } // Test newOutput() in which we write the bytes using a variety of methods // and sizes, and in which we repeatedly call toByteString() in the middle. + @Test public void testNewOutput_Mixed() { Random rng = new Random(1); byte[] bytes = getTestBytes(); @@ -584,24 +629,26 @@ output.write(bytes[position]); position++; } - assertEquals("size() returns the right value", position, output.size()); - assertTrue( - "newOutput() substring must have correct bytes", - isArrayRange(output.toByteString().toByteArray(), bytes, 0, position)); + assertWithMessage("size() returns the right value").that(position).isEqualTo(output.size()); + assertWithMessage("newOutput() substring must have correct bytes") + .that(isArrayRange(output.toByteString().toByteArray(), bytes, 0, position)) + .isTrue(); } ByteString byteString = output.toByteString(); - assertTrue( - "String built from newOutput() must contain the expected bytes", - isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)); + assertWithMessage("String built from newOutput() must contain the expected bytes") + .that(isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)) + .isTrue(); } } + @Test public void testNewOutputEmpty() { // Make sure newOutput() correctly builds empty byte strings ByteString byteString = ByteString.newOutput().toByteString(); - assertEquals(ByteString.EMPTY, byteString); + assertThat(ByteString.EMPTY).isEqualTo(byteString); } + @Test public void testNewOutput_Mutating() throws IOException { Output os = ByteString.newOutput(5); os.write(new byte[] {1, 2, 3, 4, 5}); @@ -612,21 +659,23 @@ byte[] oldValue = byteString.toByteArray(); Arrays.fill(capturedArray, (byte) 0); byte[] newValue = byteString.toByteArray(); - assertTrue( - "Output must not provide access to the underlying byte array", - Arrays.equals(oldValue, newValue)); + assertWithMessage("Output must not provide access to the underlying byte array") + .that(Arrays.equals(oldValue, newValue)) + .isTrue(); } + @Test public void testNewCodedBuilder() throws IOException { byte[] bytes = getTestBytes(); ByteString.CodedBuilder builder = ByteString.newCodedBuilder(bytes.length); builder.getCodedOutput().writeRawBytes(bytes); ByteString byteString = builder.build(); - assertTrue( - "String built from newCodedBuilder() must contain the expected bytes", - isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)); + assertWithMessage("String built from newCodedBuilder() must contain the expected bytes") + .that(isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length)) + .isTrue(); } + @Test public void testSubstringParity() { byte[] bigBytes = getTestBytes(2048 * 1024, 113344L); int start = 512 * 1024 - 3333; @@ -636,16 +685,18 @@ for (int i = start; ok && i < end; ++i) { ok = (bigBytes[i] == concreteSubstring.byteAt(i - start)); } - assertTrue("Concrete substring didn't capture the right bytes", ok); + assertWithMessage("Concrete substring didn't capture the right bytes").that(ok).isTrue(); ByteString literalString = ByteString.copyFrom(bigBytes, start, end - start); - assertEquals("Substring must be equal to literal string", literalString, concreteSubstring); - assertEquals( - "Substring must have same hashcode as literal string", - literalString.hashCode(), - concreteSubstring.hashCode()); + assertWithMessage("Substring must be equal to literal string") + .that(literalString) + .isEqualTo(concreteSubstring); + assertWithMessage("Substring must have same hashcode as literal string") + .that(literalString.hashCode()) + .isEqualTo(concreteSubstring.hashCode()); } + @Test public void testCompositeSubstring() { byte[] referenceBytes = getTestBytes(77748, 113344L); @@ -660,34 +711,32 @@ for (int i = 0; stillEqual && i < to - from; ++i) { stillEqual = referenceBytes[from + i] == substringBytes[i]; } - assertTrue("Substring must return correct bytes", stillEqual); + assertWithMessage("Substring must return correct bytes").that(stillEqual).isTrue(); stillEqual = true; for (int i = 0; stillEqual && i < to - from; ++i) { stillEqual = referenceBytes[from + i] == compositeSubstring.byteAt(i); } - assertTrue("Substring must support byteAt() correctly", stillEqual); + assertWithMessage("Substring must support byteAt() correctly").that(stillEqual).isTrue(); ByteString literalSubstring = ByteString.copyFrom(referenceBytes, from, to - from); - assertEquals( - "Composite substring must equal a literal substring over the same bytes", - literalSubstring, - compositeSubstring); - assertEquals( - "Literal substring must equal a composite substring over the same bytes", - compositeSubstring, - literalSubstring); + assertWithMessage("Composite substring must equal a literal substring over the same bytes") + .that(literalSubstring) + .isEqualTo(compositeSubstring); + assertWithMessage("Literal substring must equal a composite substring over the same bytes") + .that(compositeSubstring) + .isEqualTo(literalSubstring); - assertEquals( - "We must get the same hashcodes for composite and literal substrings", - literalSubstring.hashCode(), - compositeSubstring.hashCode()); + assertWithMessage("We must get the same hashcodes for composite and literal substrings") + .that(literalSubstring.hashCode()) + .isEqualTo(compositeSubstring.hashCode()); - assertFalse( - "We can't be equal to a proper substring", - compositeSubstring.equals(literalSubstring.substring(0, literalSubstring.size() - 1))); + assertWithMessage("We can't be equal to a proper substring") + .that(compositeSubstring.equals(literalSubstring.substring(0, literalSubstring.size() - 1))) + .isFalse(); } + @Test public void testCopyFromList() { byte[] referenceBytes = getTestBytes(77748, 113344L); ByteString literalString = ByteString.copyFrom(referenceBytes); @@ -695,13 +744,15 @@ List<ByteString> pieces = makeConcretePieces(referenceBytes); ByteString listString = ByteString.copyFrom(pieces); - assertEquals("Composite string must be equal to literal string", literalString, listString); - assertEquals( - "Composite string must have same hashcode as literal string", - literalString.hashCode(), - listString.hashCode()); + assertWithMessage("Composite string must be equal to literal string") + .that(literalString) + .isEqualTo(listString); + assertWithMessage("Composite string must have same hashcode as literal string") + .that(literalString.hashCode()) + .isEqualTo(listString.hashCode()); } + @Test public void testConcat() { byte[] referenceBytes = getTestBytes(77748, 113344L); ByteString literalString = ByteString.copyFrom(referenceBytes); @@ -714,18 +765,19 @@ concatenatedString = concatenatedString.concat(iter.next()); } - assertEquals( - "Concatenated string must be equal to literal string", literalString, concatenatedString); - assertEquals( - "Concatenated string must have same hashcode as literal string", - literalString.hashCode(), - concatenatedString.hashCode()); + assertWithMessage("Concatenated string must be equal to literal string") + .that(literalString) + .isEqualTo(concatenatedString); + assertWithMessage("Concatenated string must have same hashcode as literal string") + .that(literalString.hashCode()) + .isEqualTo(concatenatedString.hashCode()); } /** * Test the Rope implementation can deal with Empty nodes, even though we guard against them. See * also {@link LiteralByteStringTest#testConcat_empty()}. */ + @Test public void testConcat_empty() { byte[] referenceBytes = getTestBytes(7748, 113344L); ByteString literalString = ByteString.copyFrom(referenceBytes); @@ -737,11 +789,12 @@ RopeByteString.newInstanceForTest(ByteString.EMPTY, literalString)); ByteString quintet = RopeByteString.newInstanceForTest(temp, ByteString.EMPTY); - assertEquals("String with concatenated nulls must equal simple concatenate", quintet, duo); - assertEquals( - "String with concatenated nulls have same hashcode as simple concatenate", - duo.hashCode(), - quintet.hashCode()); + assertWithMessage("String with concatenated nulls must equal simple concatenate") + .that(quintet) + .isEqualTo(duo); + assertWithMessage("String with concatenated nulls have same hashcode as simple concatenate") + .that(duo.hashCode()) + .isEqualTo(quintet.hashCode()); ByteString.ByteIterator duoIter = duo.iterator(); ByteString.ByteIterator quintetIter = quintet.iterator(); @@ -749,17 +802,17 @@ while (stillEqual && quintetIter.hasNext()) { stillEqual = (duoIter.nextByte() == quintetIter.nextByte()); } - assertTrue("We must get the same characters by iterating", stillEqual); - assertFalse("Iterator must be exhausted", duoIter.hasNext()); + assertWithMessage("We must get the same characters by iterating").that(stillEqual).isTrue(); + assertWithMessage("Iterator must be exhausted").that(duoIter.hasNext()).isFalse(); try { duoIter.nextByte(); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NoSuchElementException e) { // This is success } try { quintetIter.nextByte(); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NoSuchElementException e) { // This is success } @@ -771,45 +824,47 @@ // It is possible, using the testing factory method to create deeply nested // trees of empty leaves, to make a string that will fail this test. for (int i = 1; i < duo.size(); ++i) { - assertTrue( - "Substrings of size() < 2 must not be RopeByteStrings", - duo.substring(i - 1, i) instanceof ByteString.LeafByteString); + assertWithMessage("Substrings of size() < 2 must not be RopeByteStrings") + .that(duo.substring(i - 1, i) instanceof ByteString.LeafByteString) + .isTrue(); } for (int i = 1; i < quintet.size(); ++i) { - assertTrue( - "Substrings of size() < 2 must not be RopeByteStrings", - quintet.substring(i - 1, i) instanceof ByteString.LeafByteString); + assertWithMessage("Substrings of size() < 2 must not be RopeByteStrings") + .that(quintet.substring(i - 1, i) instanceof ByteString.LeafByteString) + .isTrue(); } } + @Test public void testStartsWith() { byte[] bytes = getTestBytes(1000, 1234L); ByteString string = ByteString.copyFrom(bytes); ByteString prefix = ByteString.copyFrom(bytes, 0, 500); ByteString suffix = ByteString.copyFrom(bytes, 400, 600); - assertTrue(string.startsWith(ByteString.EMPTY)); - assertTrue(string.startsWith(string)); - assertTrue(string.startsWith(prefix)); - assertFalse(string.startsWith(suffix)); - assertFalse(prefix.startsWith(suffix)); - assertFalse(suffix.startsWith(prefix)); - assertFalse(ByteString.EMPTY.startsWith(prefix)); - assertTrue(ByteString.EMPTY.startsWith(ByteString.EMPTY)); + assertThat(string.startsWith(ByteString.EMPTY)).isTrue(); + assertThat(string.startsWith(string)).isTrue(); + assertThat(string.startsWith(prefix)).isTrue(); + assertThat(string.startsWith(suffix)).isFalse(); + assertThat(prefix.startsWith(suffix)).isFalse(); + assertThat(suffix.startsWith(prefix)).isFalse(); + assertThat(ByteString.EMPTY.startsWith(prefix)).isFalse(); + assertThat(ByteString.EMPTY.startsWith(ByteString.EMPTY)).isTrue(); } + @Test public void testEndsWith() { byte[] bytes = getTestBytes(1000, 1234L); ByteString string = ByteString.copyFrom(bytes); ByteString prefix = ByteString.copyFrom(bytes, 0, 500); ByteString suffix = ByteString.copyFrom(bytes, 400, 600); - assertTrue(string.endsWith(ByteString.EMPTY)); - assertTrue(string.endsWith(string)); - assertTrue(string.endsWith(suffix)); - assertFalse(string.endsWith(prefix)); - assertFalse(suffix.endsWith(prefix)); - assertFalse(prefix.endsWith(suffix)); - assertFalse(ByteString.EMPTY.endsWith(suffix)); - assertTrue(ByteString.EMPTY.endsWith(ByteString.EMPTY)); + assertThat(string.endsWith(ByteString.EMPTY)).isTrue(); + assertThat(string.endsWith(string)).isTrue(); + assertThat(string.endsWith(suffix)).isTrue(); + assertThat(string.endsWith(prefix)).isFalse(); + assertThat(suffix.endsWith(prefix)).isFalse(); + assertThat(prefix.endsWith(suffix)).isFalse(); + assertThat(ByteString.EMPTY.endsWith(suffix)).isFalse(); + assertThat(ByteString.EMPTY.endsWith(ByteString.EMPTY)).isTrue(); } static List<ByteString> makeConcretePieces(byte[] referenceBytes) { @@ -832,6 +887,7 @@ return output.toByteArray(); } + @Test public void testWriteToOutputStream() throws Exception { // Choose a size large enough so when two ByteStrings are concatenated they // won't be merged into one byte array due to some optimizations. @@ -842,8 +898,8 @@ // Test LiteralByteString.writeTo(OutputStream,int,int) ByteString left = ByteString.wrap(data1); byte[] result = substringUsingWriteTo(left, 1, 1); - assertEquals(1, result.length); - assertEquals((byte) 11, result[0]); + assertThat(result).hasLength(1); + assertThat(result[0]).isEqualTo((byte) 11); byte[] data2 = new byte[dataSize]; Arrays.fill(data2, 0, data1.length, (byte) 2); @@ -852,27 +908,28 @@ ByteString root = left.concat(right); // Make sure we are actually testing a RopeByteString with a simple tree // structure. - assertEquals(1, root.getTreeDepth()); + assertThat(root.getTreeDepth()).isEqualTo(1); // Write parts of the left node. result = substringUsingWriteTo(root, 0, dataSize); - assertEquals(dataSize, result.length); - assertEquals((byte) 1, result[0]); - assertEquals((byte) 1, result[dataSize - 1]); + assertThat(result).hasLength(dataSize); + assertThat(result[0]).isEqualTo((byte) 1); + assertThat(result[dataSize - 1]).isEqualTo((byte) 1); // Write parts of the right node. result = substringUsingWriteTo(root, dataSize, dataSize); - assertEquals(dataSize, result.length); - assertEquals((byte) 2, result[0]); - assertEquals((byte) 2, result[dataSize - 1]); + assertThat(result).hasLength(dataSize); + assertThat(result[0]).isEqualTo((byte) 2); + assertThat(result[dataSize - 1]).isEqualTo((byte) 2); // Write a segment of bytes that runs across both nodes. result = substringUsingWriteTo(root, dataSize / 2, dataSize); - assertEquals(dataSize, result.length); - assertEquals((byte) 1, result[0]); - assertEquals((byte) 1, result[dataSize - dataSize / 2 - 1]); - assertEquals((byte) 2, result[dataSize - dataSize / 2]); - assertEquals((byte) 2, result[dataSize - 1]); + assertThat(result).hasLength(dataSize); + assertThat(result[0]).isEqualTo((byte) 1); + assertThat(result[dataSize - dataSize / 2 - 1]).isEqualTo((byte) 1); + assertThat(result[dataSize - dataSize / 2]).isEqualTo((byte) 2); + assertThat(result[dataSize - 1]).isEqualTo((byte) 2); } /** Tests ByteString uses Arrays based byte copier when running under Hotstop VM. */ + @Test public void testByteArrayCopier() throws Exception { if (Android.isOnAndroidDevice()) { return; @@ -880,9 +937,9 @@ Field field = ByteString.class.getDeclaredField("byteArrayCopier"); field.setAccessible(true); Object byteArrayCopier = field.get(null); - assertNotNull(byteArrayCopier); - assertTrue( - byteArrayCopier.toString(), - byteArrayCopier.getClass().getSimpleName().endsWith("ArraysByteArrayCopier")); + assertThat(byteArrayCopier).isNotNull(); + assertWithMessage(byteArrayCopier.toString()) + .that(byteArrayCopier.getClass().getSimpleName().endsWith("ArraysByteArrayCopier")) + .isTrue(); } }
diff --git a/java/core/src/test/java/com/google/protobuf/CachedFieldSizeTest.java b/java/core/src/test/java/com/google/protobuf/CachedFieldSizeTest.java index 96319d9..dc0ceb6 100644 --- a/java/core/src/test/java/com/google/protobuf/CachedFieldSizeTest.java +++ b/java/core/src/test/java/com/google/protobuf/CachedFieldSizeTest.java
@@ -30,7 +30,7 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; +import static com.google.common.truth.Truth.assertThat; import protobuf_unittest.UnittestProto.TestPackedTypes; import proto3_unittest.UnittestProto3; @@ -59,7 +59,7 @@ byte[] data3 = message.getProto3Child().toByteArray(); // Make sure the serialized data is correct. - assertEquals(message.getProto2Child(), TestPackedTypes.parseFrom(data2)); - assertEquals(message.getProto3Child(), UnittestProto3.TestPackedTypes.parseFrom(data3)); + assertThat(TestPackedTypes.parseFrom(data2)).isEqualTo(message.getProto2Child()); + assertThat(UnittestProto3.TestPackedTypes.parseFrom(data3)).isEqualTo(message.getProto3Child()); } }
diff --git a/java/core/src/test/java/com/google/protobuf/CheckUtf8Test.java b/java/core/src/test/java/com/google/protobuf/CheckUtf8Test.java index e276225..458529c 100644 --- a/java/core/src/test/java/com/google/protobuf/CheckUtf8Test.java +++ b/java/core/src/test/java/com/google/protobuf/CheckUtf8Test.java
@@ -30,97 +30,112 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import proto2_test_check_utf8.TestCheckUtf8.BytesWrapper; import proto2_test_check_utf8.TestCheckUtf8.StringWrapper; import proto2_test_check_utf8_size.TestCheckUtf8Size.BytesWrapperSize; import proto2_test_check_utf8_size.TestCheckUtf8Size.StringWrapperSize; import java.io.ByteArrayInputStream; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Test that protos generated with file option java_string_check_utf8 do in fact perform appropriate * UTF-8 checks. - * - * @author jbaum@google.com (Jacob Butcher) */ -public class CheckUtf8Test extends TestCase { +@RunWith(JUnit4.class) +public class CheckUtf8Test { private static final String UTF8_BYTE_STRING_TEXT = "some text"; private static final ByteString UTF8_BYTE_STRING = ByteString.copyFromUtf8(UTF8_BYTE_STRING_TEXT); private static final ByteString NON_UTF8_BYTE_STRING = ByteString.copyFrom(new byte[] {(byte) 0x80}); // A lone continuation byte. + @Test public void testBuildRequiredStringWithGoodUtf8() throws Exception { - assertEquals( - UTF8_BYTE_STRING_TEXT, StringWrapper.newBuilder().setReqBytes(UTF8_BYTE_STRING).getReq()); + assertThat(StringWrapper.newBuilder().setReqBytes(UTF8_BYTE_STRING).getReq()) + .isEqualTo(UTF8_BYTE_STRING_TEXT); } + @Test public void testParseRequiredStringWithGoodUtf8() throws Exception { ByteString serialized = BytesWrapper.newBuilder().setReq(UTF8_BYTE_STRING).build().toByteString(); - assertEquals(UTF8_BYTE_STRING_TEXT, StringWrapper.parser().parseFrom(serialized).getReq()); + assertThat(StringWrapper.parser().parseFrom(serialized).getReq()) + .isEqualTo(UTF8_BYTE_STRING_TEXT); } + @Test public void testBuildRequiredStringWithBadUtf8() throws Exception { try { StringWrapper.newBuilder().setReqBytes(NON_UTF8_BYTE_STRING); - fail("Expected IllegalArgumentException for non UTF-8 byte string."); + assertWithMessage("Expected IllegalArgumentException for non UTF-8 byte string.").fail(); } catch (IllegalArgumentException exception) { - assertEquals("Byte string is not UTF-8.", exception.getMessage()); + assertThat(exception).hasMessageThat().isEqualTo("Byte string is not UTF-8."); } } + @Test public void testBuildOptionalStringWithBadUtf8() throws Exception { try { StringWrapper.newBuilder().setOptBytes(NON_UTF8_BYTE_STRING); - fail("Expected IllegalArgumentException for non UTF-8 byte string."); + assertWithMessage("Expected IllegalArgumentException for non UTF-8 byte string.").fail(); } catch (IllegalArgumentException exception) { - assertEquals("Byte string is not UTF-8.", exception.getMessage()); + assertThat(exception).hasMessageThat().isEqualTo("Byte string is not UTF-8."); } } + @Test public void testBuildRepeatedStringWithBadUtf8() throws Exception { try { StringWrapper.newBuilder().addRepBytes(NON_UTF8_BYTE_STRING); - fail("Expected IllegalArgumentException for non UTF-8 byte string."); + assertWithMessage("Expected IllegalArgumentException for non UTF-8 byte string.").fail(); } catch (IllegalArgumentException exception) { - assertEquals("Byte string is not UTF-8.", exception.getMessage()); + assertThat(exception).hasMessageThat().isEqualTo("Byte string is not UTF-8."); } } + @Test public void testParseRequiredStringWithBadUtf8() throws Exception { byte[] serialized = BytesWrapper.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteArray(); assertParseBadUtf8(StringWrapper.getDefaultInstance(), serialized); } + @Test public void testBuildRequiredStringWithBadUtf8Size() throws Exception { try { StringWrapperSize.newBuilder().setReqBytes(NON_UTF8_BYTE_STRING); - fail("Expected IllegalArgumentException for non UTF-8 byte string."); + assertWithMessage("Expected IllegalArgumentException for non UTF-8 byte string.").fail(); } catch (IllegalArgumentException exception) { - assertEquals("Byte string is not UTF-8.", exception.getMessage()); + assertThat(exception).hasMessageThat().isEqualTo("Byte string is not UTF-8."); } } + @Test public void testBuildOptionalStringWithBadUtf8Size() throws Exception { try { StringWrapperSize.newBuilder().setOptBytes(NON_UTF8_BYTE_STRING); - fail("Expected IllegalArgumentException for non UTF-8 byte string."); + assertWithMessage("Expected IllegalArgumentException for non UTF-8 byte string.").fail(); } catch (IllegalArgumentException exception) { - assertEquals("Byte string is not UTF-8.", exception.getMessage()); + assertThat(exception).hasMessageThat().isEqualTo("Byte string is not UTF-8."); } } + @Test public void testBuildRepeatedStringWithBadUtf8Size() throws Exception { try { StringWrapperSize.newBuilder().addRepBytes(NON_UTF8_BYTE_STRING); - fail("Expected IllegalArgumentException for non UTF-8 byte string."); + assertWithMessage("Expected IllegalArgumentException for non UTF-8 byte string.").fail(); } catch (IllegalArgumentException exception) { - assertEquals("Byte string is not UTF-8.", exception.getMessage()); + assertThat(exception).hasMessageThat().isEqualTo("Byte string is not UTF-8."); } } + @Test public void testParseRequiredStringWithBadUtf8Size() throws Exception { byte[] serialized = BytesWrapperSize.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteArray(); @@ -131,27 +146,31 @@ // Check combinations of (parser vs. builder) x (byte[] vs. InputStream) try { defaultInstance.getParserForType().parseFrom(data); - fail("Expected InvalidProtocolBufferException for non UTF-8 byte string."); + assertWithMessage("Expected InvalidProtocolBufferException for non UTF-8 byte string.") + .fail(); } catch (InvalidProtocolBufferException exception) { - assertEquals("Protocol message had invalid UTF-8.", exception.getMessage()); + assertThat(exception).hasMessageThat().isEqualTo("Protocol message had invalid UTF-8."); } try { defaultInstance.newBuilderForType().mergeFrom(data); - fail("Expected InvalidProtocolBufferException for non UTF-8 byte string."); + assertWithMessage("Expected InvalidProtocolBufferException for non UTF-8 byte string.") + .fail(); } catch (InvalidProtocolBufferException exception) { - assertEquals("Protocol message had invalid UTF-8.", exception.getMessage()); + assertThat(exception).hasMessageThat().isEqualTo("Protocol message had invalid UTF-8."); } try { defaultInstance.getParserForType().parseFrom(new ByteArrayInputStream(data)); - fail("Expected InvalidProtocolBufferException for non UTF-8 byte string."); + assertWithMessage("Expected InvalidProtocolBufferException for non UTF-8 byte string.") + .fail(); } catch (InvalidProtocolBufferException exception) { - assertEquals("Protocol message had invalid UTF-8.", exception.getMessage()); + assertThat(exception).hasMessageThat().isEqualTo("Protocol message had invalid UTF-8."); } try { defaultInstance.newBuilderForType().mergeFrom(new ByteArrayInputStream(data)); - fail("Expected InvalidProtocolBufferException for non UTF-8 byte string."); + assertWithMessage("Expected InvalidProtocolBufferException for non UTF-8 byte string.") + .fail(); } catch (InvalidProtocolBufferException exception) { - assertEquals("Protocol message had invalid UTF-8.", exception.getMessage()); + assertThat(exception).hasMessageThat().isEqualTo("Protocol message had invalid UTF-8."); } } }
diff --git a/java/core/src/test/java/com/google/protobuf/CodedAdapterTest.java b/java/core/src/test/java/com/google/protobuf/CodedAdapterTest.java index a24b48b..6f5bf0c 100644 --- a/java/core/src/test/java/com/google/protobuf/CodedAdapterTest.java +++ b/java/core/src/test/java/com/google/protobuf/CodedAdapterTest.java
@@ -30,7 +30,7 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; +import static com.google.common.truth.Truth.assertThat; import com.google.protobuf.testing.Proto2Testing.Proto2Message; import com.google.protobuf.testing.Proto3Testing.Proto3Message; @@ -57,14 +57,14 @@ // Deserialize with BinaryReader and verify that the message matches the original. Proto3Message result = fromByteArray(expectedBytes, Proto3Message.class); - assertEquals(expected, result); + assertThat(result).isEqualTo(expected); // Now write it back out using BinaryWriter and verify the output length. byte[] actualBytes = toByteArray(result, expectedBytes.length); // Read back in the bytes and verify that it matches the original message. Proto3Message actual = Proto3Message.parseFrom(actualBytes); - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -74,14 +74,14 @@ // Deserialize with BinaryReader and verify that the message matches the original. Proto2Message result = fromByteArray(expectedBytes, Proto2Message.class); - assertEquals(expected, result); + assertThat(result).isEqualTo(expected); // Now write it back out using BinaryWriter and verify the output length. byte[] actualBytes = toByteArray(result, expectedBytes.length); // Read back in the bytes and verify that it matches the original message. Proto2Message actual = Proto2Message.parseFrom(actualBytes); - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } public static <T> byte[] toByteArray(T msg, int size) throws Exception { @@ -90,7 +90,7 @@ CodedOutputStreamWriter writer = CodedOutputStreamWriter.forCodedOutput(CodedOutputStream.newInstance(out)); schema.writeTo(msg, writer); - assertEquals(out.length, writer.getTotalBytesWritten()); + assertThat(writer.getTotalBytesWritten()).isEqualTo(out.length); return out; }
diff --git a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java index 10d156e..f5bb31f 100644 --- a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java +++ b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
@@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertArrayEquals; import protobuf_unittest.UnittestProto.BoolMessage; import protobuf_unittest.UnittestProto.Int32Message; @@ -45,14 +47,13 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Unit test for {@link CodedInputStream}. - * - * @author kenton@google.com Kenton Varda - */ -public class CodedInputStreamTest extends TestCase { +/** Unit test for {@link CodedInputStream}. */ +@RunWith(JUnit4.class) +public class CodedInputStreamTest { private static final int DEFAULT_BLOCK_SIZE = 4096; @@ -179,8 +180,8 @@ private void assertDataConsumed(String msg, byte[] data, CodedInputStream input) throws IOException { - assertEquals(msg, data.length, input.getTotalBytesRead()); - assertTrue(msg, input.isAtEnd()); + assertWithMessage(msg).that(data).hasLength(input.getTotalBytesRead()); + assertWithMessage(msg).that(input.isAtEnd()).isTrue(); } /** @@ -192,19 +193,21 @@ // Try different block sizes. for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { CodedInputStream input = inputType.newDecoder(data, blockSize); - assertEquals(inputType.name(), (int) value, input.readRawVarint32()); + assertWithMessage(inputType.name()).that(input.readRawVarint32()).isEqualTo((int) value); assertDataConsumed(inputType.name(), data, input); input = inputType.newDecoder(data, blockSize); - assertEquals(inputType.name(), value, input.readRawVarint64()); + assertWithMessage(inputType.name()).that(input.readRawVarint64()).isEqualTo(value); assertDataConsumed(inputType.name(), data, input); input = inputType.newDecoder(data, blockSize); - assertEquals(inputType.name(), value, input.readRawVarint64SlowPath()); + assertWithMessage(inputType.name()).that(input.readRawVarint64SlowPath()).isEqualTo(value); assertDataConsumed(inputType.name(), data, input); input = inputType.newDecoder(data, blockSize); - assertTrue(inputType.name(), input.skipField(WireFormat.WIRETYPE_VARINT)); + assertWithMessage(inputType.name()) + .that(input.skipField(WireFormat.WIRETYPE_VARINT)) + .isTrue(); assertDataConsumed(inputType.name(), data, input); } } @@ -215,8 +218,8 @@ byte[] longerData = new byte[data.length + 1]; System.arraycopy(data, 0, longerData, 0, data.length); InputStream rawInput = new ByteArrayInputStream(longerData); - assertEquals((int) value, CodedInputStream.readRawVarint32(rawInput)); - assertEquals(1, rawInput.available()); + assertThat(CodedInputStream.readRawVarint32(rawInput)).isEqualTo((int) value); + assertThat(rawInput.available()).isEqualTo(1); } /** @@ -229,29 +232,36 @@ try { CodedInputStream input = inputType.newDecoder(data); input.readRawVarint32(); - fail(inputType.name() + ": Should have thrown an exception."); + assertWithMessage("%s: Should have thrown an exception.", inputType.name()).fail(); } catch (InvalidProtocolBufferException e) { - assertEquals(inputType.name(), expected.getMessage(), e.getMessage()); + assertWithMessage(inputType.name()) + .that(e) + .hasMessageThat() + .isEqualTo(expected.getMessage()); } try { CodedInputStream input = inputType.newDecoder(data); input.readRawVarint64(); - fail(inputType.name() + ": Should have thrown an exception."); + assertWithMessage("%s: Should have thrown an exception.", inputType.name()).fail(); } catch (InvalidProtocolBufferException e) { - assertEquals(inputType.name(), expected.getMessage(), e.getMessage()); + assertWithMessage(inputType.name()) + .that(e) + .hasMessageThat() + .isEqualTo(expected.getMessage()); } } // Make sure we get the same error when reading direct from an InputStream. try { CodedInputStream.readRawVarint32(new ByteArrayInputStream(data)); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (InvalidProtocolBufferException e) { - assertEquals(expected.getMessage(), e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo(expected.getMessage()); } } /** Tests readRawVarint32() and readRawVarint64(). */ + @Test public void testReadVarint() throws Exception { assertReadVarint(bytes(0x00), 0); assertReadVarint(bytes(0x01), 1); @@ -309,8 +319,8 @@ // Try different block sizes. for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { CodedInputStream input = inputType.newDecoder(data, blockSize); - assertEquals(inputType.name(), value, input.readRawLittleEndian32()); - assertTrue(inputType.name(), input.isAtEnd()); + assertWithMessage(inputType.name()).that(input.readRawLittleEndian32()).isEqualTo(value); + assertWithMessage(inputType.name()).that(input.isAtEnd()).isTrue(); } } } @@ -324,13 +334,14 @@ // Try different block sizes. for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { CodedInputStream input = inputType.newDecoder(data, blockSize); - assertEquals(inputType.name(), value, input.readRawLittleEndian64()); - assertTrue(inputType.name(), input.isAtEnd()); + assertWithMessage(inputType.name()).that(input.readRawLittleEndian64()).isEqualTo(value); + assertWithMessage(inputType.name()).that(input.isAtEnd()).isTrue(); } } } /** Tests readRawLittleEndian32() and readRawLittleEndian64(). */ + @Test public void testReadLittleEndian() throws Exception { assertReadLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678); assertReadLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0); @@ -342,34 +353,36 @@ } /** Test decodeZigZag32() and decodeZigZag64(). */ + @Test public void testDecodeZigZag() throws Exception { - assertEquals(0, CodedInputStream.decodeZigZag32(0)); - assertEquals(-1, CodedInputStream.decodeZigZag32(1)); - assertEquals(1, CodedInputStream.decodeZigZag32(2)); - assertEquals(-2, CodedInputStream.decodeZigZag32(3)); - assertEquals(0x3FFFFFFF, CodedInputStream.decodeZigZag32(0x7FFFFFFE)); - assertEquals(0xC0000000, CodedInputStream.decodeZigZag32(0x7FFFFFFF)); - assertEquals(0x7FFFFFFF, CodedInputStream.decodeZigZag32(0xFFFFFFFE)); - assertEquals(0x80000000, CodedInputStream.decodeZigZag32(0xFFFFFFFF)); + assertThat(CodedInputStream.decodeZigZag32(0)).isEqualTo(0); + assertThat(CodedInputStream.decodeZigZag32(1)).isEqualTo(-1); + assertThat(CodedInputStream.decodeZigZag32(2)).isEqualTo(1); + assertThat(CodedInputStream.decodeZigZag32(3)).isEqualTo(-2); + assertThat(CodedInputStream.decodeZigZag32(0x7FFFFFFE)).isEqualTo(0x3FFFFFFF); + assertThat(CodedInputStream.decodeZigZag32(0x7FFFFFFF)).isEqualTo(0xC0000000); + assertThat(CodedInputStream.decodeZigZag32(0xFFFFFFFE)).isEqualTo(0x7FFFFFFF); + assertThat(CodedInputStream.decodeZigZag32(0xFFFFFFFF)).isEqualTo(0x80000000); - assertEquals(0, CodedInputStream.decodeZigZag64(0)); - assertEquals(-1, CodedInputStream.decodeZigZag64(1)); - assertEquals(1, CodedInputStream.decodeZigZag64(2)); - assertEquals(-2, CodedInputStream.decodeZigZag64(3)); - assertEquals(0x000000003FFFFFFFL, CodedInputStream.decodeZigZag64(0x000000007FFFFFFEL)); - assertEquals(0xFFFFFFFFC0000000L, CodedInputStream.decodeZigZag64(0x000000007FFFFFFFL)); - assertEquals(0x000000007FFFFFFFL, CodedInputStream.decodeZigZag64(0x00000000FFFFFFFEL)); - assertEquals(0xFFFFFFFF80000000L, CodedInputStream.decodeZigZag64(0x00000000FFFFFFFFL)); - assertEquals(0x7FFFFFFFFFFFFFFFL, CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFEL)); - assertEquals(0x8000000000000000L, CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFFL)); + assertThat(CodedInputStream.decodeZigZag64(0)).isEqualTo(0); + assertThat(CodedInputStream.decodeZigZag64(1)).isEqualTo(-1); + assertThat(CodedInputStream.decodeZigZag64(2)).isEqualTo(1); + assertThat(CodedInputStream.decodeZigZag64(3)).isEqualTo(-2); + assertThat(CodedInputStream.decodeZigZag64(0x000000007FFFFFFEL)).isEqualTo(0x000000003FFFFFFFL); + assertThat(CodedInputStream.decodeZigZag64(0x000000007FFFFFFFL)).isEqualTo(0xFFFFFFFFC0000000L); + assertThat(CodedInputStream.decodeZigZag64(0x00000000FFFFFFFEL)).isEqualTo(0x000000007FFFFFFFL); + assertThat(CodedInputStream.decodeZigZag64(0x00000000FFFFFFFFL)).isEqualTo(0xFFFFFFFF80000000L); + assertThat(CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFEL)).isEqualTo(0x7FFFFFFFFFFFFFFFL); + assertThat(CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFFL)).isEqualTo(0x8000000000000000L); } /** Tests reading and parsing a whole message with every field type. */ + @Test public void testReadWholeMessage() throws Exception { TestAllTypes message = TestUtil.getAllSet(); byte[] rawBytes = message.toByteArray(); - assertEquals(rawBytes.length, message.getSerializedSize()); + assertThat(rawBytes).hasLength(message.getSerializedSize()); for (InputType inputType : InputType.values()) { // Try different block sizes. @@ -381,6 +394,7 @@ } /** Tests skipField(). */ + @Test public void testSkipWholeMessage() throws Exception { TestAllTypes message = TestUtil.getAllSet(); byte[] rawBytes = message.toByteArray(); @@ -397,7 +411,7 @@ int tag = input1.readTag(); // Ensure that the rest match. for (int i = 1; i < inputs.length; ++i) { - assertEquals(inputTypes[i].name(), tag, inputs[i].readTag()); + assertWithMessage(inputTypes[i].name()).that(inputs[i].readTag()).isEqualTo(tag); } if (tag == 0) { break; @@ -415,6 +429,7 @@ * Test that a bug in skipRawBytes() has been fixed: if the skip skips exactly up to a limit, this * should not break things. */ + @Test public void testSkipRawBytesBug() throws Exception { byte[] rawBytes = new byte[] {1, 2}; for (InputType inputType : InputType.values()) { @@ -422,7 +437,7 @@ int limit = input.pushLimit(1); input.skipRawBytes(1); input.popLimit(limit); - assertEquals(inputType.name(), 2, input.readRawByte()); + assertWithMessage(inputType.name()).that(input.readRawByte()).isEqualTo(2); } } @@ -430,6 +445,7 @@ * Test that a bug in skipRawBytes() has been fixed: if the skip skips past the end of a buffer * with a limit that has been set past the end of that buffer, this should not break things. */ + @Test public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception { byte[] rawBytes = new byte[] {1, 2, 3, 4, 5}; for (InputType inputType : InputType.values()) { @@ -437,12 +453,12 @@ int limit = input.pushLimit(4); // In order to expose the bug we need to read at least one byte to prime the // buffer inside the CodedInputStream. - assertEquals(inputType.name(), 1, input.readRawByte()); + assertWithMessage(inputType.name()).that(input.readRawByte()).isEqualTo(1); // Skip to the end of the limit. input.skipRawBytes(3); - assertTrue(inputType.name(), input.isAtEnd()); + assertWithMessage(inputType.name()).that(input.isAtEnd()).isTrue(); input.popLimit(limit); - assertEquals(inputType.name(), 5, input.readRawByte()); + assertWithMessage(inputType.name()).that(input.readRawByte()).isEqualTo(5); } } @@ -450,15 +466,17 @@ * Test that calling skipRawBytes (when not merging a message) actually skips from the underlying * inputstream, regardless of the buffer size used. */ + @Test public void testSkipRawBytesActuallySkips() throws Exception { SmallBlockInputStream bytes = new SmallBlockInputStream(new byte[] {1, 2, 3, 4, 5}, 3); CodedInputStream input = CodedInputStream.newInstance(bytes, 1); // Tiny buffer input.skipRawBytes(3); input.skipRawBytes(2); - assertEquals(2, bytes.skipCalls); - assertEquals(0, bytes.readCalls); + assertThat(bytes.skipCalls).isEqualTo(2); + assertThat(bytes.readCalls).isEqualTo(0); } + @Test public void testSkipHugeBlob() throws Exception { // Allocate and initialize a 1MB blob. int blobSize = 1 << 20; @@ -476,11 +494,13 @@ } /** Skipping a huge blob should not allocate excessive memory, so there should be no limit */ + @Test public void testSkipMaliciouslyHugeBlob() throws Exception { InputStream is = new RepeatingInputStream(new byte[]{1}, Integer.MAX_VALUE); CodedInputStream.newInstance(is).skipRawBytes(Integer.MAX_VALUE); } + @Test public void testReadHugeBlob() throws Exception { // Allocate and initialize a 1MB blob. byte[] blob = new byte[1 << 20]; @@ -501,7 +521,9 @@ // reading. TestAllTypes message2 = TestAllTypes.parseFrom(inputType.newDecoder(data)); - assertEquals(inputType.name(), message.getOptionalBytes(), message2.getOptionalBytes()); + assertWithMessage(inputType.name()) + .that(message.getOptionalBytes()) + .isEqualTo(message2.getOptionalBytes()); // Make sure all the other fields were parsed correctly. TestAllTypes message3 = @@ -512,6 +534,7 @@ } } + @Test public void testReadMaliciouslyLargeBlob() throws Exception { ByteString.Output rawOutput = ByteString.newOutput(); CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); @@ -525,10 +548,10 @@ byte[] data = rawOutput.toByteString().toByteArray(); for (InputType inputType : InputType.values()) { CodedInputStream input = inputType.newDecoder(data); - assertEquals(tag, input.readTag()); + assertThat(input.readTag()).isEqualTo(tag); try { input.readBytes(); - fail(inputType.name() + ": Should have thrown an exception!"); + assertWithMessage("%s: Should have thrown an exception!", inputType.name()).fail(); } catch (InvalidProtocolBufferException e) { // success. } @@ -541,6 +564,7 @@ * * @throws IOException */ + @Test public void testParseMessagesCloseTo2G() throws IOException { byte[] serializedMessage = getBigSerializedMessage(); // How many of these big messages do we need to take us near our 2G limit? @@ -558,6 +582,7 @@ * * @throws IOException */ + @Test public void testParseMessagesOver2G() throws IOException { byte[] serializedMessage = getBigSerializedMessage(); // How many of these big messages do we need to take us near our 2G limit? @@ -569,9 +594,9 @@ InputStream is = new RepeatingInputStream(serializedMessage, count); try { TestAllTypes.parseFrom(is); - fail("Should have thrown an exception!"); + assertWithMessage("Should have thrown an exception!").fail(); } catch (InvalidProtocolBufferException e) { - assertTrue(e.getMessage().contains("too large")); + assertThat(e).hasMessageThat().contains("too large"); } } @@ -623,14 +648,15 @@ private void assertMessageDepth(String msg, TestRecursiveMessage message, int depth) { if (depth == 0) { - assertFalse(msg, message.hasA()); - assertEquals(msg, 5, message.getI()); + assertWithMessage(msg).that(message.hasA()).isFalse(); + assertWithMessage(msg).that(message.getI()).isEqualTo(5); } else { - assertTrue(msg, message.hasA()); + assertWithMessage(msg).that(message.hasA()).isTrue(); assertMessageDepth(msg, message.getA(), depth - 1); } } + @Test public void testMaliciousRecursion() throws Exception { byte[] data100 = makeRecursiveMessage(100).toByteArray(); byte[] data101 = makeRecursiveMessage(101).toByteArray(); @@ -641,16 +667,17 @@ try { TestRecursiveMessage.parseFrom(inputType.newDecoder(data101)); - fail("Should have thrown an exception!"); + assertWithMessage("Should have thrown an exception!").fail(); } catch (InvalidProtocolBufferException e) { // success. } + CodedInputStream input = inputType.newDecoder(data100); input.setRecursionLimit(8); try { TestRecursiveMessage.parseFrom(input); - fail(inputType.name() + ": Should have thrown an exception!"); + assertWithMessage("%s: Should have thrown an exception!", inputType.name()).fail(); } catch (InvalidProtocolBufferException e) { // success. } @@ -658,9 +685,12 @@ } private void checkSizeLimitExceeded(InvalidProtocolBufferException e) { - assertEquals(InvalidProtocolBufferException.sizeLimitExceeded().getMessage(), e.getMessage()); + assertThat(e) + .hasMessageThat() + .isEqualTo(InvalidProtocolBufferException.sizeLimitExceeded().getMessage()); } + @Test public void testSizeLimit() throws Exception { // NOTE: Size limit only applies to the stream-backed CIS. CodedInputStream input = @@ -670,44 +700,46 @@ try { TestAllTypes.parseFrom(input); - fail("Should have thrown an exception!"); + assertWithMessage("Should have thrown an exception!").fail(); } catch (InvalidProtocolBufferException expected) { checkSizeLimitExceeded(expected); } } + @Test public void testResetSizeCounter() throws Exception { // NOTE: Size limit only applies to the stream-backed CIS. CodedInputStream input = CodedInputStream.newInstance(new SmallBlockInputStream(new byte[256], 8)); input.setSizeLimit(16); input.readRawBytes(16); - assertEquals(16, input.getTotalBytesRead()); + assertThat(input.getTotalBytesRead()).isEqualTo(16); try { input.readRawByte(); - fail("Should have thrown an exception!"); + assertWithMessage("Should have thrown an exception!").fail(); } catch (InvalidProtocolBufferException expected) { checkSizeLimitExceeded(expected); } input.resetSizeCounter(); - assertEquals(0, input.getTotalBytesRead()); + assertThat(input.getTotalBytesRead()).isEqualTo(0); input.readRawByte(); // No exception thrown. input.resetSizeCounter(); - assertEquals(0, input.getTotalBytesRead()); + assertThat(input.getTotalBytesRead()).isEqualTo(0); input.readRawBytes(16); - assertEquals(16, input.getTotalBytesRead()); + assertThat(input.getTotalBytesRead()).isEqualTo(16); input.resetSizeCounter(); try { input.readRawBytes(17); // Hits limit again. - fail("Should have thrown an exception!"); + assertWithMessage("Should have thrown an exception!").fail(); } catch (InvalidProtocolBufferException expected) { checkSizeLimitExceeded(expected); } } + @Test public void testRefillBufferWithCorrectSize() throws Exception { // NOTE: refillBuffer only applies to the stream-backed CIS. byte[] bytes = "123456789".getBytes("UTF-8"); @@ -736,26 +768,28 @@ input.readString(); try { input.readRawByte(); // Hits limit. - fail("Should have thrown an exception!"); + assertWithMessage("Should have thrown an exception!").fail(); } catch (InvalidProtocolBufferException expected) { checkSizeLimitExceeded(expected); } } } + @Test public void testIsAtEnd() throws Exception { CodedInputStream input = CodedInputStream.newInstance(new ByteArrayInputStream(new byte[5])); try { for (int i = 0; i < 5; i++) { - assertEquals(false, input.isAtEnd()); + assertThat(input.isAtEnd()).isFalse(); input.readRawByte(); } - assertEquals(true, input.isAtEnd()); + assertThat(input.isAtEnd()).isTrue(); } catch (Exception e) { throw new AssertionError("Catch exception in the testIsAtEnd", e); } } + @Test public void testCurrentLimitExceeded() throws Exception { byte[] bytes = "123456789".getBytes("UTF-8"); ByteArrayOutputStream rawOutput = new ByteArrayOutputStream(); @@ -776,13 +810,15 @@ input.pushLimit(5); try { input.readString(); - fail("Should have thrown an exception"); + assertWithMessage("Should have thrown an exception").fail(); } catch (InvalidProtocolBufferException expected) { - assertEquals( - expected.getMessage(), InvalidProtocolBufferException.truncatedMessage().getMessage()); + assertThat(expected) + .hasMessageThat() + .isEqualTo(InvalidProtocolBufferException.truncatedMessage().getMessage()); } } + @Test public void testSizeLimitMultipleMessages() throws Exception { // NOTE: Size limit only applies to the stream-backed CIS. byte[] bytes = new byte[256]; @@ -794,14 +830,15 @@ for (int i = 0; i < 256 / 16; i++) { byte[] message = input.readRawBytes(16); for (int j = 0; j < message.length; j++) { - assertEquals(i * 16 + j, message[j] & 0xff); + assertThat(message[j] & 0xff).isEqualTo(i * 16 + j); } - assertEquals(16, input.getTotalBytesRead()); + assertThat(input.getTotalBytesRead()).isEqualTo(16); input.resetSizeCounter(); - assertEquals(0, input.getTotalBytesRead()); + assertThat(input.getTotalBytesRead()).isEqualTo(0); } } + @Test public void testReadString() throws Exception { String lorem = "Lorem ipsum dolor sit amet "; StringBuilder builder = new StringBuilder(); @@ -822,12 +859,13 @@ byte[] rawInput = rawOutput.toByteString().toByteArray(); for (InputType inputType : InputType.values()) { CodedInputStream input = inputType.newDecoder(rawInput); - assertEquals(inputType.name(), tag, input.readTag()); + assertWithMessage(inputType.name()).that(tag).isEqualTo(input.readTag()); String text = input.readString(); - assertEquals(inputType.name(), lorem, text); + assertWithMessage(inputType.name()).that(lorem).isEqualTo(text); } } + @Test public void testReadStringRequireUtf8() throws Exception { String lorem = "Lorem ipsum dolor sit amet "; StringBuilder builder = new StringBuilder(); @@ -848,9 +886,9 @@ byte[] rawInput = rawOutput.toByteString().toByteArray(); for (InputType inputType : InputType.values()) { CodedInputStream input = inputType.newDecoder(rawInput); - assertEquals(inputType.name(), tag, input.readTag()); + assertWithMessage(inputType.name()).that(tag).isEqualTo(input.readTag()); String text = input.readStringRequireUtf8(); - assertEquals(inputType.name(), lorem, text); + assertWithMessage(inputType.name()).that(lorem).isEqualTo(text); } } @@ -858,6 +896,7 @@ * Tests that if we readString invalid UTF-8 bytes, no exception is thrown. Instead, the invalid * bytes are replaced with the Unicode "replacement character" U+FFFD. */ + @Test public void testReadStringInvalidUtf8() throws Exception { ByteString.Output rawOutput = ByteString.newOutput(); CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); @@ -871,9 +910,9 @@ byte[] rawInput = rawOutput.toByteString().toByteArray(); for (InputType inputType : InputType.values()) { CodedInputStream input = inputType.newDecoder(rawInput); - assertEquals(inputType.name(), tag, input.readTag()); + assertWithMessage(inputType.name()).that(input.readTag()).isEqualTo(tag); String text = input.readString(); - assertEquals(inputType.name(), 0xfffd, text.charAt(0)); + assertWithMessage(inputType.name()).that(text.charAt(0)).isEqualTo(0xfffd); } } @@ -881,6 +920,7 @@ * Tests that if we readStringRequireUtf8 invalid UTF-8 bytes, an InvalidProtocolBufferException * is thrown. */ + @Test public void testReadStringRequireUtf8InvalidUtf8() throws Exception { ByteString.Output rawOutput = ByteString.newOutput(); CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); @@ -894,30 +934,34 @@ byte[] rawInput = rawOutput.toByteString().toByteArray(); for (InputType inputType : InputType.values()) { CodedInputStream input = inputType.newDecoder(rawInput); - assertEquals(tag, input.readTag()); + assertThat(input.readTag()).isEqualTo(tag); try { input.readStringRequireUtf8(); - fail(inputType.name() + ": Expected invalid UTF-8 exception."); + assertWithMessage("%s: Expected invalid UTF-8 exception.", inputType.name()).fail(); } catch (InvalidProtocolBufferException exception) { - assertEquals( - inputType.name(), "Protocol message had invalid UTF-8.", exception.getMessage()); + assertWithMessage(inputType.name()) + .that(exception) + .hasMessageThat() + .isEqualTo("Protocol message had invalid UTF-8."); } } } + @Test public void testReadFromSlice() throws Exception { byte[] bytes = bytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); CodedInputStream in = CodedInputStream.newInstance(bytes, 3, 5); - assertEquals(0, in.getTotalBytesRead()); + assertThat(in.getTotalBytesRead()).isEqualTo(0); for (int i = 3; i < 8; i++) { - assertEquals(i, in.readRawByte()); - assertEquals(i - 2, in.getTotalBytesRead()); + assertThat(in.readRawByte()).isEqualTo(i); + assertThat(in.getTotalBytesRead()).isEqualTo(i - 2); } // eof - assertEquals(0, in.readTag()); - assertEquals(5, in.getTotalBytesRead()); + assertThat(in.readTag()).isEqualTo(0); + assertThat(in.getTotalBytesRead()).isEqualTo(5); } + @Test public void testInvalidTag() throws Exception { // Any tag number which corresponds to field number zero is invalid and // should throw InvalidProtocolBufferException. @@ -925,17 +969,18 @@ for (int i = 0; i < 8; i++) { try { inputType.newDecoder(bytes(i)).readTag(); - fail(inputType.name() + ": Should have thrown an exception."); + assertWithMessage("%s: Should have thrown an exception.", inputType.name()).fail(); } catch (InvalidProtocolBufferException e) { - assertEquals( - inputType.name(), - InvalidProtocolBufferException.invalidTag().getMessage(), - e.getMessage()); + assertWithMessage(inputType.name()) + .that(e) + .hasMessageThat() + .isEqualTo(InvalidProtocolBufferException.invalidTag().getMessage()); } } } } + @Test public void testReadByteArray() throws Exception { ByteString.Output rawOutput = ByteString.newOutput(); CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); @@ -962,20 +1007,21 @@ CodedInputStream inputStream = inputType.newDecoder(rawInput); byte[] result = inputStream.readByteArray(); - assertEquals(inputType.name(), 0, result.length); + assertWithMessage(inputType.name()).that(result).isEmpty(); result = inputStream.readByteArray(); - assertEquals(inputType.name(), 1, result.length); - assertEquals(inputType.name(), (byte) 23, result[0]); + assertWithMessage(inputType.name()).that(result).hasLength(1); + assertWithMessage(inputType.name()).that(result[0]).isEqualTo((byte) 23); result = inputStream.readByteArray(); - assertEquals(inputType.name(), 1, result.length); - assertEquals(inputType.name(), (byte) 45, result[0]); + assertWithMessage(inputType.name()).that(result).hasLength(1); + assertWithMessage(inputType.name()).that(result[0]).isEqualTo((byte) 45); result = inputStream.readByteArray(); - assertEquals(inputType.name(), bytesLength, result.length); - assertEquals(inputType.name(), (byte) 67, result[0]); - assertEquals(inputType.name(), (byte) 89, result[bytesLength - 1]); + assertWithMessage(inputType.name()).that(result).hasLength(bytesLength); + assertWithMessage(inputType.name()).that(result[0]).isEqualTo((byte) 67); + assertWithMessage(inputType.name()).that(result[bytesLength - 1]).isEqualTo((byte) 89); } } + @Test public void testReadLargeByteStringFromInputStream() throws Exception { byte[] bytes = new byte[1024 * 1024]; for (int i = 0; i < bytes.length; i++) { @@ -997,9 +1043,10 @@ } }); ByteString result = input.readBytes(); - assertEquals(ByteString.copyFrom(bytes), result); + assertThat(ByteString.copyFrom(bytes)).isEqualTo(result); } + @Test public void testReadLargeByteArrayFromInputStream() throws Exception { byte[] bytes = new byte[1024 * 1024]; for (int i = 0; i < bytes.length; i++) { @@ -1021,9 +1068,10 @@ } }); byte[] result = input.readByteArray(); - assertTrue(Arrays.equals(bytes, result)); + assertThat(Arrays.equals(bytes, result)).isTrue(); } + @Test public void testReadByteBuffer() throws Exception { ByteString.Output rawOutput = ByteString.newOutput(); CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); @@ -1050,21 +1098,22 @@ CodedInputStream inputStream = inputType.newDecoder(rawInput); ByteBuffer result = inputStream.readByteBuffer(); - assertEquals(inputType.name(), 0, result.capacity()); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(0); result = inputStream.readByteBuffer(); - assertEquals(inputType.name(), 1, result.capacity()); - assertEquals(inputType.name(), (byte) 23, result.get()); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(1); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 23); result = inputStream.readByteBuffer(); - assertEquals(inputType.name(), 1, result.capacity()); - assertEquals(inputType.name(), (byte) 45, result.get()); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(1); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 45); result = inputStream.readByteBuffer(); - assertEquals(inputType.name(), bytesLength, result.capacity()); - assertEquals(inputType.name(), (byte) 67, result.get()); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(bytesLength); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 67); result.position(bytesLength - 1); - assertEquals(inputType.name(), (byte) 89, result.get()); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 89); } } + @Test public void testReadByteBufferAliasing() throws Exception { ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream(); CodedOutputStream output = CodedOutputStream.newInstance(byteArrayStream); @@ -1098,50 +1147,51 @@ // Without aliasing CodedInputStream inputStream = inputType.newDecoder(data); ByteBuffer result = inputStream.readByteBuffer(); - assertEquals(inputType.name(), 0, result.capacity()); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(0); result = inputStream.readByteBuffer(); - assertTrue(inputType.name(), result.array() != data); - assertEquals(inputType.name(), 1, result.capacity()); - assertEquals(inputType.name(), (byte) 23, result.get()); + assertWithMessage(inputType.name()).that(result.array() != data).isTrue(); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(1); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 23); result = inputStream.readByteBuffer(); - assertTrue(inputType.name(), result.array() != data); - assertEquals(inputType.name(), 1, result.capacity()); - assertEquals(inputType.name(), (byte) 45, result.get()); + assertWithMessage(inputType.name()).that(result.array() != data).isTrue(); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(1); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 45); result = inputStream.readByteBuffer(); - assertTrue(inputType.name(), result.array() != data); - assertEquals(inputType.name(), bytesLength, result.capacity()); - assertEquals(inputType.name(), (byte) 67, result.get()); + assertWithMessage(inputType.name()).that(result.array() != data).isTrue(); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(bytesLength); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 67); result.position(bytesLength - 1); - assertEquals(inputType.name(), (byte) 89, result.get()); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 89); // Enable aliasing inputStream = inputType.newDecoder(data, data.length); inputStream.enableAliasing(true); result = inputStream.readByteBuffer(); - assertEquals(inputType.name(), 0, result.capacity()); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(0); result = inputStream.readByteBuffer(); if (result.hasArray()) { - assertTrue(inputType.name(), result.array() == data); + assertWithMessage(inputType.name()).that(result.array() == data).isTrue(); } - assertEquals(inputType.name(), 1, result.capacity()); - assertEquals(inputType.name(), (byte) 23, result.get()); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(1); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 23); result = inputStream.readByteBuffer(); if (result.hasArray()) { - assertTrue(inputType.name(), result.array() == data); + assertWithMessage(inputType.name()).that(result.array() == data).isTrue(); } - assertEquals(inputType.name(), 1, result.capacity()); - assertEquals(inputType.name(), (byte) 45, result.get()); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(1); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 45); result = inputStream.readByteBuffer(); if (result.hasArray()) { - assertTrue(inputType.name(), result.array() == data); + assertWithMessage(inputType.name()).that(result.array() == data).isTrue(); } - assertEquals(inputType.name(), bytesLength, result.capacity()); - assertEquals(inputType.name(), (byte) 67, result.get()); + assertWithMessage(inputType.name()).that(result.capacity()).isEqualTo(bytesLength); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 67); result.position(bytesLength - 1); - assertEquals(inputType.name(), (byte) 89, result.get()); + assertWithMessage(inputType.name()).that(result.get()).isEqualTo((byte) 89); } } + @Test public void testIterableByteBufferInputStreamReadBytesWithAlias() throws Exception { ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream(); CodedOutputStream output = CodedOutputStream.newInstance(byteArrayStream); @@ -1171,10 +1221,11 @@ ByteString result = inputStream.readBytes(); for (int i = 0; i < bytesLength; i++) { - assertEquals((byte) (i % 256), result.byteAt(i)); + assertThat(result.byteAt(i)).isEqualTo((byte) (i % 256)); } } + @Test public void testCompatibleTypes() throws Exception { long data = 0x100000000L; Int64Message message = Int64Message.newBuilder().setData(data).build(); @@ -1184,15 +1235,16 @@ // Test int64(long) is compatible with bool(boolean) BoolMessage msg2 = BoolMessage.parseFrom(inputStream); - assertTrue(msg2.getData()); + assertThat(msg2.getData()).isTrue(); // Test int64(long) is compatible with int32(int) inputStream = inputType.newDecoder(serialized); Int32Message msg3 = Int32Message.parseFrom(inputStream); - assertEquals((int) data, msg3.getData()); + assertThat(msg3.getData()).isEqualTo((int) data); } } + @Test public void testSkipInvalidVarint_FastPath() throws Exception { // Fast path: We have >= 10 bytes available. Ensure we properly recognize a non-ending varint. byte[] data = new byte[] {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0}; @@ -1200,13 +1252,14 @@ try { CodedInputStream input = inputType.newDecoder(data); input.skipField(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT)); - fail(inputType.name() + ": Should have thrown an exception."); + assertWithMessage("%s: Should have thrown an exception.", inputType.name()).fail(); } catch (InvalidProtocolBufferException e) { // Expected } } } + @Test public void testSkipInvalidVarint_SlowPath() throws Exception { // Slow path: < 10 bytes available. Ensure we properly recognize a non-ending varint. byte[] data = new byte[] {-1, -1, -1, -1, -1, -1, -1, -1, -1}; @@ -1214,22 +1267,24 @@ try { CodedInputStream input = inputType.newDecoder(data); input.skipField(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT)); - fail(inputType.name() + ": Should have thrown an exception."); + assertWithMessage("%s: Should have thrown an exception.", inputType.name()).fail(); } catch (InvalidProtocolBufferException e) { // Expected } } } + @Test public void testSkipPastEndOfByteArrayInput() throws Exception { try { CodedInputStream.newInstance(new ByteArrayInputStream(new byte[100])).skipRawBytes(101); - fail(); + assertWithMessage("Should have thrown an exception").fail(); } catch (InvalidProtocolBufferException e) { // Expected } } + @Test public void testMaliciousInputStream() throws Exception { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(outputStream); @@ -1248,9 +1303,9 @@ CodedInputStream codedInputStream = CodedInputStream.newInstance(inputStream, 1); ByteString byteString = codedInputStream.readBytes(); - assertEquals(0x0, byteString.byteAt(0)); + assertThat(byteString.byteAt(0)).isEqualTo(0x0); maliciousCapture.get(1)[0] = 0x9; - assertEquals(0x0, byteString.byteAt(0)); + assertThat(byteString.byteAt(0)).isEqualTo(0x0); // test ByteBuffer @@ -1258,10 +1313,9 @@ maliciousCapture.clear(); codedInputStream = CodedInputStream.newInstance(inputStream, 1); ByteBuffer byteBuffer = codedInputStream.readByteBuffer(); - assertEquals(0x0, byteBuffer.get(0)); + assertThat(byteBuffer.get(0)).isEqualTo(0x0); maliciousCapture.get(1)[0] = 0x9; - assertEquals(0x0, byteBuffer.get(0)); - + assertThat(byteBuffer.get(0)).isEqualTo(0x0); // test byte[] @@ -1269,9 +1323,9 @@ maliciousCapture.clear(); codedInputStream = CodedInputStream.newInstance(inputStream, 1); byte[] byteArray = codedInputStream.readByteArray(); - assertEquals(0x0, byteArray[0]); + assertThat(byteArray[0]).isEqualTo(0x0); maliciousCapture.get(1)[0] = 0x9; - assertEquals(0x9, byteArray[0]); // MODIFICATION! Should we fix? + assertThat(byteArray[0]).isEqualTo(0x9); // MODIFICATION! Should we fix? // test rawBytes @@ -1280,11 +1334,12 @@ codedInputStream = CodedInputStream.newInstance(inputStream, 1); int length = codedInputStream.readRawVarint32(); byteArray = codedInputStream.readRawBytes(length); - assertEquals(0x0, byteArray[0]); + assertThat(byteArray[0]).isEqualTo(0x0); maliciousCapture.get(1)[0] = 0x9; - assertEquals(0x9, byteArray[0]); // MODIFICATION! Should we fix? + assertThat(byteArray[0]).isEqualTo(0x9); // MODIFICATION! Should we fix? } + @Test public void testInvalidInputYieldsInvalidProtocolBufferException_readTag() throws Exception { byte[] input = new byte[] {0x0a, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x77}; CodedInputStream inputStream = CodedInputStream.newInstance(input); @@ -1293,12 +1348,13 @@ int size = inputStream.readRawVarint32(); inputStream.pushLimit(size); inputStream.readTag(); - fail(); + assertWithMessage("Should have thrown an exception").fail(); } catch (InvalidProtocolBufferException ex) { // Expected. } } + @Test public void testInvalidInputYieldsInvalidProtocolBufferException_readBytes() throws Exception { byte[] input = new byte[] {0x0a, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x67, 0x1a, 0x1a}; @@ -1308,7 +1364,7 @@ int size = inputStream.readRawVarint32(); inputStream.pushLimit(size); inputStream.readBytes(); - fail(); + assertWithMessage("Should have thrown an exception").fail(); } catch (InvalidProtocolBufferException ex) { // Expected. }
diff --git a/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java index 8dc3e4c..9934ca1 100644 --- a/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java +++ b/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
@@ -30,6 +30,9 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import com.google.protobuf.CodedOutputStream.OutOfSpaceException; import protobuf_unittest.UnittestProto.SparseEnumMessage; import protobuf_unittest.UnittestProto.TestAllTypes; @@ -41,14 +44,13 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Unit test for {@link CodedOutputStream}. - * - * @author kenton@google.com Kenton Varda - */ -public class CodedOutputStreamTest extends TestCase { +/** Unit test for {@link CodedOutputStream}. */ +@RunWith(JUnit4.class) +public class CodedOutputStreamTest { private interface Coder { CodedOutputStream stream(); @@ -224,6 +226,7 @@ } /** Checks that invariants are maintained for varint round trip input and output. */ + @Test public void testVarintRoundTrips() throws Exception { for (OutputType outputType : OutputType.values()) { assertVarintRoundTrip(outputType, 0L); @@ -238,6 +241,7 @@ } /** Tests writeRawVarint32() and writeRawVarint64(). */ + @Test public void testWriteVarint() throws Exception { assertWriteVarint(bytes(0x00), 0); assertWriteVarint(bytes(0x01), 1); @@ -281,6 +285,7 @@ } /** Tests writeRawLittleEndian32() and writeRawLittleEndian64(). */ + @Test public void testWriteLittleEndian() throws Exception { assertWriteLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678); assertWriteLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0); @@ -292,50 +297,61 @@ } /** Test encodeZigZag32() and encodeZigZag64(). */ + @Test public void testEncodeZigZag() throws Exception { - assertEquals(0, CodedOutputStream.encodeZigZag32(0)); - assertEquals(1, CodedOutputStream.encodeZigZag32(-1)); - assertEquals(2, CodedOutputStream.encodeZigZag32(1)); - assertEquals(3, CodedOutputStream.encodeZigZag32(-2)); - assertEquals(0x7FFFFFFE, CodedOutputStream.encodeZigZag32(0x3FFFFFFF)); - assertEquals(0x7FFFFFFF, CodedOutputStream.encodeZigZag32(0xC0000000)); - assertEquals(0xFFFFFFFE, CodedOutputStream.encodeZigZag32(0x7FFFFFFF)); - assertEquals(0xFFFFFFFF, CodedOutputStream.encodeZigZag32(0x80000000)); + assertThat(CodedOutputStream.encodeZigZag32(0)).isEqualTo(0); + assertThat(CodedOutputStream.encodeZigZag32(-1)).isEqualTo(1); + assertThat(CodedOutputStream.encodeZigZag32(1)).isEqualTo(2); + assertThat(CodedOutputStream.encodeZigZag32(-2)).isEqualTo(3); + assertThat(CodedOutputStream.encodeZigZag32(0x3FFFFFFF)).isEqualTo(0x7FFFFFFE); + assertThat(CodedOutputStream.encodeZigZag32(0xC0000000)).isEqualTo(0x7FFFFFFF); + assertThat(CodedOutputStream.encodeZigZag32(0x7FFFFFFF)).isEqualTo(0xFFFFFFFE); + assertThat(CodedOutputStream.encodeZigZag32(0x80000000)).isEqualTo(0xFFFFFFFF); - assertEquals(0, CodedOutputStream.encodeZigZag64(0)); - assertEquals(1, CodedOutputStream.encodeZigZag64(-1)); - assertEquals(2, CodedOutputStream.encodeZigZag64(1)); - assertEquals(3, CodedOutputStream.encodeZigZag64(-2)); - assertEquals(0x000000007FFFFFFEL, CodedOutputStream.encodeZigZag64(0x000000003FFFFFFFL)); - assertEquals(0x000000007FFFFFFFL, CodedOutputStream.encodeZigZag64(0xFFFFFFFFC0000000L)); - assertEquals(0x00000000FFFFFFFEL, CodedOutputStream.encodeZigZag64(0x000000007FFFFFFFL)); - assertEquals(0x00000000FFFFFFFFL, CodedOutputStream.encodeZigZag64(0xFFFFFFFF80000000L)); - assertEquals(0xFFFFFFFFFFFFFFFEL, CodedOutputStream.encodeZigZag64(0x7FFFFFFFFFFFFFFFL)); - assertEquals(0xFFFFFFFFFFFFFFFFL, CodedOutputStream.encodeZigZag64(0x8000000000000000L)); + assertThat(CodedOutputStream.encodeZigZag64(0)).isEqualTo(0); + assertThat(CodedOutputStream.encodeZigZag64(-1)).isEqualTo(1); + assertThat(CodedOutputStream.encodeZigZag64(1)).isEqualTo(2); + assertThat(CodedOutputStream.encodeZigZag64(-2)).isEqualTo(3); + assertThat(CodedOutputStream.encodeZigZag64(0x000000003FFFFFFFL)) + .isEqualTo(0x000000007FFFFFFEL); + assertThat(CodedOutputStream.encodeZigZag64(0xFFFFFFFFC0000000L)) + .isEqualTo(0x000000007FFFFFFFL); + assertThat(CodedOutputStream.encodeZigZag64(0x000000007FFFFFFFL)) + .isEqualTo(0x00000000FFFFFFFEL); + assertThat(CodedOutputStream.encodeZigZag64(0xFFFFFFFF80000000L)) + .isEqualTo(0x00000000FFFFFFFFL); + assertThat(CodedOutputStream.encodeZigZag64(0x7FFFFFFFFFFFFFFFL)) + .isEqualTo(0xFFFFFFFFFFFFFFFEL); + assertThat(CodedOutputStream.encodeZigZag64(0x8000000000000000L)) + .isEqualTo(0xFFFFFFFFFFFFFFFFL); // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1) // were chosen semi-randomly via keyboard bashing. - assertEquals(0, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(0))); - assertEquals(1, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(1))); - assertEquals(-1, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-1))); - assertEquals(14927, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(14927))); - assertEquals(-3612, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-3612))); + assertThat(CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(0))).isEqualTo(0); + assertThat(CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(1))).isEqualTo(1); + assertThat(CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-1))).isEqualTo(-1); + assertThat(CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(14927))) + .isEqualTo(14927); + assertThat(CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-3612))) + .isEqualTo(-3612); - assertEquals(0, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(0))); - assertEquals(1, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(1))); - assertEquals(-1, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-1))); - assertEquals(14927, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(14927))); - assertEquals(-3612, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-3612))); + assertThat(CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(0))).isEqualTo(0); + assertThat(CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(1))).isEqualTo(1); + assertThat(CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-1))).isEqualTo(-1); + assertThat(CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(14927))) + .isEqualTo(14927); + assertThat(CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-3612))) + .isEqualTo(-3612); - assertEquals( - 856912304801416L, - CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(856912304801416L))); - assertEquals( - -75123905439571256L, - CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-75123905439571256L))); + assertThat(CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(856912304801416L))) + .isEqualTo(856912304801416L); + assertThat( + CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-75123905439571256L))) + .isEqualTo(-75123905439571256L); } /** Tests writing a whole message with every field type. */ + @Test public void testWriteWholeMessage() throws Exception { final byte[] expectedBytes = TestUtil.getGoldenMessage().toByteArray(); TestAllTypes message = TestUtil.getAllSet(); @@ -361,6 +377,7 @@ * Tests writing a whole message with every packed field type. Ensures the wire format of packed * fields is compatible with C++. */ + @Test public void testWriteWholePackedFieldsMessage() throws Exception { byte[] expectedBytes = TestUtil.getGoldenPackedFieldsMessage().toByteArray(); TestPackedTypes message = TestUtil.getPackedSet(); @@ -378,21 +395,23 @@ * Test writing a message containing a negative enum value. This used to fail because the size was * not properly computed as a sign-extended varint. */ + @Test public void testWriteMessageWithNegativeEnumValue() throws Exception { SparseEnumMessage message = SparseEnumMessage.newBuilder().setSparseEnum(TestSparseEnum.SPARSE_E).build(); - assertTrue(message.getSparseEnum().getNumber() < 0); + assertThat(message.getSparseEnum().getNumber() < 0).isTrue(); for (OutputType outputType : OutputType.values()) { Coder coder = outputType.newCoder(message.getSerializedSize()); message.writeTo(coder.stream()); coder.stream().flush(); byte[] rawBytes = coder.toByteArray(); SparseEnumMessage message2 = SparseEnumMessage.parseFrom(rawBytes); - assertEquals(TestSparseEnum.SPARSE_E, message2.getSparseEnum()); + assertThat(message2.getSparseEnum()).isEqualTo(TestSparseEnum.SPARSE_E); } } /** Test getTotalBytesWritten() */ + @Test public void testGetTotalBytesWritten() throws Exception { Coder coder = OutputType.STREAM.newCoder(4 * 1024); @@ -402,26 +421,29 @@ for (int i = 0; i < 1024; ++i) { coder.stream().writeRawBytes(value, 0, value.length); } - assertEquals(value.length * 1024, coder.stream().getTotalBytesWritten()); + assertThat(coder.stream().getTotalBytesWritten()).isEqualTo(value.length * 1024); // Now write an encoded string. String string = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"; // Ensure we take the slower fast path. - assertTrue( - CodedOutputStream.computeUInt32SizeNoTag(string.length()) - != CodedOutputStream.computeUInt32SizeNoTag(string.length() * Utf8.MAX_BYTES_PER_CHAR)); + assertThat( + CodedOutputStream.computeUInt32SizeNoTag(string.length()) + != CodedOutputStream.computeUInt32SizeNoTag( + string.length() * Utf8.MAX_BYTES_PER_CHAR)) + .isTrue(); coder.stream().writeStringNoTag(string); coder.stream().flush(); int stringSize = CodedOutputStream.computeStringSizeNoTag(string); // Verify that the total bytes written is correct - assertEquals((value.length * 1024) + stringSize, coder.stream().getTotalBytesWritten()); + assertThat(coder.stream().getTotalBytesWritten()).isEqualTo((value.length * 1024) + stringSize); } // TODO(dweis): Write a comprehensive test suite for CodedOutputStream that covers more than just // this case. + @Test public void testWriteStringNoTag_fastpath() throws Exception { int bufferSize = 153; String threeBytesPer = "\u0981"; @@ -430,10 +452,10 @@ string += threeBytesPer; } // These checks ensure we will tickle the slower fast path. - assertEquals(1, CodedOutputStream.computeUInt32SizeNoTag(string.length())); - assertEquals( - 2, CodedOutputStream.computeUInt32SizeNoTag(string.length() * Utf8.MAX_BYTES_PER_CHAR)); - assertEquals(bufferSize, string.length() * Utf8.MAX_BYTES_PER_CHAR); + assertThat(CodedOutputStream.computeUInt32SizeNoTag(string.length())).isEqualTo(1); + assertThat(CodedOutputStream.computeUInt32SizeNoTag(string.length() * Utf8.MAX_BYTES_PER_CHAR)) + .isEqualTo(2); + assertThat(bufferSize).isEqualTo(string.length() * Utf8.MAX_BYTES_PER_CHAR); for (OutputType outputType : OutputType.values()) { Coder coder = outputType.newCoder(bufferSize + 2); @@ -442,6 +464,7 @@ } } + @Test public void testWriteToByteBuffer() throws Exception { final int bufferSize = 16 * 1024; ByteBuffer buffer = ByteBuffer.allocate(bufferSize); @@ -462,19 +485,20 @@ codedStream.flush(); // Check that data is correctly written to the ByteBuffer. - assertEquals(0, buffer.remaining()); + assertThat(buffer.remaining()).isEqualTo(0); buffer.flip(); for (int i = 0; i < length1; i++) { - assertEquals((byte) 1, buffer.get()); + assertThat(buffer.get()).isEqualTo((byte) 1); } for (int i = 0; i < length2; i++) { - assertEquals((byte) 2, buffer.get()); + assertThat(buffer.get()).isEqualTo((byte) 2); } for (int i = 0; i < length3; i++) { - assertEquals((byte) 3, buffer.get()); + assertThat(buffer.get()).isEqualTo((byte) 3); } } + @Test public void testWriteByteBuffer() throws Exception { byte[] value = "abcde".getBytes(Internal.UTF_8); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); @@ -484,31 +508,33 @@ // ByteBuffer's capacity() is 5. codedStream.writeRawBytes(byteBuffer); // The above call shouldn't affect the ByteBuffer's state. - assertEquals(0, byteBuffer.position()); - assertEquals(1, byteBuffer.limit()); + assertThat(byteBuffer.position()).isEqualTo(0); + assertThat(byteBuffer.limit()).isEqualTo(1); // The correct way to write part of an array using ByteBuffer. codedStream.writeRawBytes(ByteBuffer.wrap(value, 2, 1).slice()); codedStream.flush(); byte[] result = outputStream.toByteArray(); - assertEquals(6, result.length); + assertThat(result).hasLength(6); for (int i = 0; i < 5; i++) { - assertEquals(value[i], result[i]); + assertThat(value[i]).isEqualTo(result[i]); } - assertEquals(value[2], result[5]); + assertThat(value[2]).isEqualTo(result[5]); } + @Test public void testWriteByteArrayWithOffsets() throws Exception { byte[] fullArray = bytes(0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88); for (OutputType type : new OutputType[] {OutputType.ARRAY}) { Coder coder = type.newCoder(4); coder.stream().writeByteArrayNoTag(fullArray, 2, 2); assertEqualBytes(type, bytes(0x02, 0x33, 0x44), coder.toByteArray()); - assertEquals(3, coder.stream().getTotalBytesWritten()); + assertThat(coder.stream().getTotalBytesWritten()).isEqualTo(3); } } + @Test public void testSerializeUtf8_MultipleSmallWrites() throws Exception { final String source = "abcdefghijklmnopqrstuvwxyz"; @@ -533,6 +559,7 @@ } } + @Test public void testSerializeInvalidUtf8() throws Exception { String[] invalidStrings = new String[] { @@ -558,6 +585,7 @@ // TODO(nathanmittler): This test can be deleted once we properly throw IOException while // encoding invalid UTF-8 strings. + @Test public void testSerializeInvalidUtf8FollowedByOutOfSpace() throws Exception { final int notEnoughBytes = 4; CodedOutputStream outputWithArray = CodedOutputStream.newInstance(new byte[notEnoughBytes]); @@ -567,25 +595,25 @@ String invalidString = newString(Character.MIN_HIGH_SURROGATE, 'f', 'o', 'o', 'b', 'a', 'r'); try { outputWithArray.writeStringNoTag(invalidString); - fail("Expected OutOfSpaceException"); + assertWithMessage("Expected OutOfSpaceException").fail(); } catch (OutOfSpaceException e) { - assertTrue(e.getCause() instanceof IndexOutOfBoundsException); + assertThat(e).hasCauseThat().isInstanceOf(IndexOutOfBoundsException.class); } try { outputWithByteBuffer.writeStringNoTag(invalidString); - fail("Expected OutOfSpaceException"); + assertWithMessage("Expected OutOfSpaceException").fail(); } catch (OutOfSpaceException e) { - assertTrue(e.getCause() instanceof IndexOutOfBoundsException); + assertThat(e).hasCauseThat().isInstanceOf(IndexOutOfBoundsException.class); } } /** Regression test for https://github.com/protocolbuffers/protobuf/issues/292 */ + @Test public void testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace() throws Exception { String testCase = "Foooooooo"; - assertEquals( - CodedOutputStream.computeUInt32SizeNoTag(testCase.length()), - CodedOutputStream.computeUInt32SizeNoTag(testCase.length() * 3)); - assertEquals(11, CodedOutputStream.computeStringSize(1, testCase)); + assertThat(CodedOutputStream.computeUInt32SizeNoTag(testCase.length())) + .isEqualTo(CodedOutputStream.computeUInt32SizeNoTag(testCase.length() * 3)); + assertThat(CodedOutputStream.computeStringSize(1, testCase)).isEqualTo(11); // Tag is one byte, varint describing string length is 1 byte, string length is 9 bytes. // An array of size 1 will cause a failure when trying to write the varint. for (OutputType outputType : @@ -599,13 +627,14 @@ Coder coder = outputType.newCoder(i); try { coder.stream().writeString(1, testCase); - fail("Should have thrown an out of space exception"); + assertWithMessage("Should have thrown an out of space exception").fail(); } catch (CodedOutputStream.OutOfSpaceException expected) { } } } } + @Test public void testDifferentStringLengths() throws Exception { // Test string serialization roundtrip using strings of the following lengths, // with ASCII and Unicode characters requiring different UTF-8 byte counts per @@ -631,6 +660,7 @@ } } + @Test public void testNioEncodersWithInitialOffsets() throws Exception { String value = "abc"; for (Coder coder : @@ -696,10 +726,9 @@ Coder coder = outputType.newCoder(testAllTypes.getSerializedSize()); testAllTypes.writeTo(coder.stream()); coder.stream().flush(); - assertEquals( - "OuputType: " + outputType, - fullString, - TestAllTypes.parseFrom(coder.toByteArray()).getOptionalString()); + assertWithMessage("OuputType: " + outputType) + .that(fullString) + .isEqualTo(TestAllTypes.parseFrom(coder.toByteArray()).getOptionalString()); } private static String fullString(char c, int length) { @@ -730,7 +759,7 @@ } private static void assertEqualBytes(OutputType outputType, byte[] a, byte[] b) { - assertEquals(outputType.name(), toList(a), toList(b)); + assertWithMessage(outputType.name()).that(toList(a)).isEqualTo(toList(b)); } /** @@ -747,7 +776,7 @@ assertEqualBytes(outputType, data, coder.toByteArray()); // Also try computing size. - assertEquals(data.length, CodedOutputStream.computeUInt32SizeNoTag((int) value)); + assertThat(data).hasLength(CodedOutputStream.computeUInt32SizeNoTag((int) value)); } { @@ -757,7 +786,7 @@ assertEqualBytes(outputType, data, coder.toByteArray()); // Also try computing size. - assertEquals(data.length, CodedOutputStream.computeUInt64SizeNoTag(value)); + assertThat(data).hasLength(CodedOutputStream.computeUInt64SizeNoTag(value)); } } @@ -792,10 +821,11 @@ coder.stream().writeUInt64NoTag(value); coder.stream().flush(); byte[] bytes = coder.toByteArray(); - assertEquals( - outputType.name(), bytes.length, CodedOutputStream.computeUInt64SizeNoTag(value)); + assertWithMessage(outputType.name()) + .that(bytes) + .hasLength(CodedOutputStream.computeUInt64SizeNoTag(value)); CodedInputStream input = CodedInputStream.newInstance(new ByteArrayInputStream(bytes)); - assertEquals(outputType.name(), value, input.readRawVarint64()); + assertWithMessage(outputType.name()).that(input.readRawVarint64()).isEqualTo(value); } if (value == (int) value) { @@ -803,10 +833,11 @@ coder.stream().writeUInt32NoTag((int) value); coder.stream().flush(); byte[] bytes = coder.toByteArray(); - assertEquals( - outputType.name(), bytes.length, CodedOutputStream.computeUInt32SizeNoTag((int) value)); + assertWithMessage(outputType.name()) + .that(bytes) + .hasLength(CodedOutputStream.computeUInt32SizeNoTag((int) value)); CodedInputStream input = CodedInputStream.newInstance(new ByteArrayInputStream(bytes)); - assertEquals(outputType.name(), value, input.readRawVarint32()); + assertWithMessage(outputType.name()).that(input.readRawVarint32()).isEqualTo(value); } } }
diff --git a/java/core/src/test/java/com/google/protobuf/DeprecatedFieldTest.java b/java/core/src/test/java/com/google/protobuf/DeprecatedFieldTest.java index 2addde8..fac6949 100644 --- a/java/core/src/test/java/com/google/protobuf/DeprecatedFieldTest.java +++ b/java/core/src/test/java/com/google/protobuf/DeprecatedFieldTest.java
@@ -30,47 +30,52 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertWithMessage; + import protobuf_unittest.UnittestProto.TestDeprecatedFields; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Test field deprecation - * - * @author birdo@google.com (Roberto Scaramuzzi) - */ -public class DeprecatedFieldTest extends TestCase { - private String[] deprecatedGetterNames = {"hasDeprecatedInt32", "getDeprecatedInt32"}; +/** Test field deprecation. */ +@RunWith(JUnit4.class) +public class DeprecatedFieldTest { + private final String[] deprecatedGetterNames = {"hasDeprecatedInt32", "getDeprecatedInt32"}; - private String[] deprecatedBuilderGetterNames = { + private final String[] deprecatedBuilderGetterNames = { "hasDeprecatedInt32", "getDeprecatedInt32", "clearDeprecatedInt32" }; - private String[] deprecatedBuilderSetterNames = {"setDeprecatedInt32"}; + private final String[] deprecatedBuilderSetterNames = {"setDeprecatedInt32"}; + @Test public void testDeprecatedField() throws Exception { Class<?> deprecatedFields = TestDeprecatedFields.class; Class<?> deprecatedFieldsBuilder = TestDeprecatedFields.Builder.class; for (String name : deprecatedGetterNames) { Method method = deprecatedFields.getMethod(name); - assertTrue("Method " + name + " should be deprecated", isDeprecated(method)); + assertWithMessage("Method %s should be deprecated", name).that(isDeprecated(method)).isTrue(); } for (String name : deprecatedBuilderGetterNames) { Method method = deprecatedFieldsBuilder.getMethod(name); - assertTrue("Method " + name + " should be deprecated", isDeprecated(method)); + assertWithMessage("Method %s should be deprecated", name).that(isDeprecated(method)).isTrue(); } for (String name : deprecatedBuilderSetterNames) { Method method = deprecatedFieldsBuilder.getMethod(name, int.class); - assertTrue("Method " + name + " should be deprecated", isDeprecated(method)); + assertWithMessage("Method %s should be deprecated", name).that(isDeprecated(method)).isTrue(); } } + @Test public void testDeprecatedFieldInOneof() throws Exception { Class<?> oneofCase = TestDeprecatedFields.OneofFieldsCase.class; String name = "DEPRECATED_INT32_IN_ONEOF"; java.lang.reflect.Field enumValue = oneofCase.getField(name); - assertTrue("Enum value " + name + " should be deprecated.", isDeprecated(enumValue)); + assertWithMessage("Enum value %s should be deprecated.", name) + .that(isDeprecated(enumValue)) + .isTrue(); } private boolean isDeprecated(AnnotatedElement annotated) {
diff --git a/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java b/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java index b98b332..6cb0bae 100644 --- a/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java +++ b/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java
@@ -30,11 +30,9 @@ package com.google.protobuf; -import static junit.framework.TestCase.assertFalse; -import static junit.framework.TestCase.assertTrue; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; -import protobuf_unittest.NestedExtension; -import protobuf_unittest.NonNestedExtension; import com.google.protobuf.DescriptorProtos.DescriptorProto; import com.google.protobuf.DescriptorProtos.EnumDescriptorProto; import com.google.protobuf.DescriptorProtos.EnumValueDescriptorProto; @@ -65,17 +63,17 @@ import protobuf_unittest.UnittestProto.TestRequired; import protobuf_unittest.UnittestProto.TestReservedFields; import protobuf_unittest.UnittestProto.TestService; -import java.util.Arrays; import java.util.Collections; import java.util.List; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import protobuf_unittest.NestedExtension; +import protobuf_unittest.NonNestedExtension; -/** - * Unit test for {@link Descriptors}. - * - * @author kenton@google.com Kenton Varda - */ -public class DescriptorsTest extends TestCase { +/** Unit test for {@link Descriptors}. */ +@RunWith(JUnit4.class) +public class DescriptorsTest { // Regression test for bug where referencing a FieldDescriptor.Type value // before a FieldDescriptorProto.Type value would yield a @@ -83,110 +81,114 @@ @SuppressWarnings("unused") private static final Object STATIC_INIT_TEST = FieldDescriptor.Type.BOOL; + @Test public void testFieldTypeEnumMapping() throws Exception { - assertEquals(FieldDescriptor.Type.values().length, FieldDescriptorProto.Type.values().length); + assertThat(FieldDescriptor.Type.values()).hasLength(FieldDescriptorProto.Type.values().length); for (FieldDescriptor.Type type : FieldDescriptor.Type.values()) { FieldDescriptorProto.Type protoType = type.toProto(); - assertEquals("TYPE_" + type.name(), protoType.name()); - assertEquals(type, FieldDescriptor.Type.valueOf(protoType)); + assertThat(protoType.name()).isEqualTo("TYPE_" + type.name()); + assertThat(FieldDescriptor.Type.valueOf(protoType)).isEqualTo(type); } } + @Test public void testFileDescriptor() throws Exception { FileDescriptor file = UnittestProto.getDescriptor(); - assertEquals("google/protobuf/unittest.proto", file.getName()); - assertEquals("protobuf_unittest", file.getPackage()); + assertThat(file.getName()).isEqualTo("google/protobuf/unittest.proto"); + assertThat(file.getPackage()).isEqualTo("protobuf_unittest"); + assertThat(file.getOptions().getJavaOuterClassname()).isEqualTo("UnittestProto"); + assertThat(file.toProto().getName()).isEqualTo("google/protobuf/unittest.proto"); - assertEquals("UnittestProto", file.getOptions().getJavaOuterClassname()); - assertEquals("google/protobuf/unittest.proto", file.toProto().getName()); - - assertEquals(Arrays.asList(UnittestImport.getDescriptor()), file.getDependencies()); + assertThat(file.getDependencies()).containsExactly(UnittestImport.getDescriptor()); Descriptor messageType = TestAllTypes.getDescriptor(); - assertEquals(messageType, file.getMessageTypes().get(0)); - assertEquals(messageType, file.findMessageTypeByName("TestAllTypes")); - assertNull(file.findMessageTypeByName("NoSuchType")); - assertNull(file.findMessageTypeByName("protobuf_unittest.TestAllTypes")); + assertThat(file.getMessageTypes().get(0)).isEqualTo(messageType); + assertThat(file.findMessageTypeByName("TestAllTypes")).isEqualTo(messageType); + assertThat(file.findMessageTypeByName("NoSuchType")).isNull(); + assertThat(file.findMessageTypeByName("protobuf_unittest.TestAllTypes")).isNull(); for (int i = 0; i < file.getMessageTypes().size(); i++) { - assertEquals(i, file.getMessageTypes().get(i).getIndex()); + assertThat(file.getMessageTypes().get(i).getIndex()).isEqualTo(i); } EnumDescriptor enumType = ForeignEnum.getDescriptor(); - assertEquals(enumType, file.getEnumTypes().get(0)); - assertEquals(enumType, file.findEnumTypeByName("ForeignEnum")); - assertNull(file.findEnumTypeByName("NoSuchType")); - assertNull(file.findEnumTypeByName("protobuf_unittest.ForeignEnum")); - assertEquals( - Arrays.asList(ImportEnum.getDescriptor(), ImportEnumForMap.getDescriptor()), - UnittestImport.getDescriptor().getEnumTypes()); + assertThat(file.getEnumTypes().get(0)).isEqualTo(enumType); + assertThat(file.findEnumTypeByName("ForeignEnum")).isEqualTo(enumType); + assertThat(file.findEnumTypeByName("NoSuchType")).isNull(); + assertThat(file.findEnumTypeByName("protobuf_unittest.ForeignEnum")).isNull(); + assertThat(UnittestImport.getDescriptor().getEnumTypes()) + .containsExactly(ImportEnum.getDescriptor(), ImportEnumForMap.getDescriptor()) + .inOrder(); for (int i = 0; i < file.getEnumTypes().size(); i++) { - assertEquals(i, file.getEnumTypes().get(i).getIndex()); + assertThat(file.getEnumTypes().get(i).getIndex()).isEqualTo(i); } ServiceDescriptor service = TestService.getDescriptor(); - assertEquals(service, file.getServices().get(0)); - assertEquals(service, file.findServiceByName("TestService")); - assertNull(file.findServiceByName("NoSuchType")); - assertNull(file.findServiceByName("protobuf_unittest.TestService")); - assertEquals(Collections.emptyList(), UnittestImport.getDescriptor().getServices()); + assertThat(file.getServices().get(0)).isEqualTo(service); + assertThat(file.findServiceByName("TestService")).isEqualTo(service); + assertThat(file.findServiceByName("NoSuchType")).isNull(); + assertThat(file.findServiceByName("protobuf_unittest.TestService")).isNull(); + assertThat(UnittestImport.getDescriptor().getServices()).isEqualTo(Collections.emptyList()); for (int i = 0; i < file.getServices().size(); i++) { - assertEquals(i, file.getServices().get(i).getIndex()); + assertThat(file.getServices().get(i).getIndex()).isEqualTo(i); } FieldDescriptor extension = UnittestProto.optionalInt32Extension.getDescriptor(); - assertEquals(extension, file.getExtensions().get(0)); - assertEquals(extension, file.findExtensionByName("optional_int32_extension")); - assertNull(file.findExtensionByName("no_such_ext")); - assertNull(file.findExtensionByName("protobuf_unittest.optional_int32_extension")); - assertEquals(Collections.emptyList(), UnittestImport.getDescriptor().getExtensions()); + assertThat(file.getExtensions().get(0)).isEqualTo(extension); + assertThat(file.findExtensionByName("optional_int32_extension")).isEqualTo(extension); + assertThat(file.findExtensionByName("no_such_ext")).isNull(); + assertThat(file.findExtensionByName("protobuf_unittest.optional_int32_extension")).isNull(); + assertThat(UnittestImport.getDescriptor().getExtensions()).isEqualTo(Collections.emptyList()); for (int i = 0; i < file.getExtensions().size(); i++) { - assertEquals(i, file.getExtensions().get(i).getIndex()); + assertThat(file.getExtensions().get(i).getIndex()).isEqualTo(i); } } + @Test public void testDescriptor() throws Exception { Descriptor messageType = TestAllTypes.getDescriptor(); Descriptor nestedType = TestAllTypes.NestedMessage.getDescriptor(); - assertEquals("TestAllTypes", messageType.getName()); - assertEquals("protobuf_unittest.TestAllTypes", messageType.getFullName()); - assertEquals(UnittestProto.getDescriptor(), messageType.getFile()); - assertNull(messageType.getContainingType()); - assertEquals(DescriptorProtos.MessageOptions.getDefaultInstance(), messageType.getOptions()); - assertEquals("TestAllTypes", messageType.toProto().getName()); + assertThat(messageType.getName()).isEqualTo("TestAllTypes"); + assertThat(messageType.getFullName()).isEqualTo("protobuf_unittest.TestAllTypes"); + assertThat(messageType.getFile()).isEqualTo(UnittestProto.getDescriptor()); + assertThat(messageType.getContainingType()).isNull(); + assertThat(messageType.getOptions()) + .isEqualTo(DescriptorProtos.MessageOptions.getDefaultInstance()); + assertThat(messageType.toProto().getName()).isEqualTo("TestAllTypes"); - assertEquals("NestedMessage", nestedType.getName()); - assertEquals("protobuf_unittest.TestAllTypes.NestedMessage", nestedType.getFullName()); - assertEquals(UnittestProto.getDescriptor(), nestedType.getFile()); - assertEquals(messageType, nestedType.getContainingType()); + assertThat(nestedType.getName()).isEqualTo("NestedMessage"); + assertThat(nestedType.getFullName()).isEqualTo("protobuf_unittest.TestAllTypes.NestedMessage"); + assertThat(nestedType.getFile()).isEqualTo(UnittestProto.getDescriptor()); + assertThat(nestedType.getContainingType()).isEqualTo(messageType); FieldDescriptor field = messageType.getFields().get(0); - assertEquals("optional_int32", field.getName()); - assertEquals(field, messageType.findFieldByName("optional_int32")); - assertNull(messageType.findFieldByName("no_such_field")); - assertEquals(field, messageType.findFieldByNumber(1)); - assertNull(messageType.findFieldByNumber(571283)); + assertThat(field.getName()).isEqualTo("optional_int32"); + assertThat(messageType.findFieldByName("optional_int32")).isEqualTo(field); + assertThat(messageType.findFieldByName("no_such_field")).isNull(); + assertThat(messageType.findFieldByNumber(1)).isEqualTo(field); + assertThat(messageType.findFieldByNumber(571283)).isNull(); for (int i = 0; i < messageType.getFields().size(); i++) { - assertEquals(i, messageType.getFields().get(i).getIndex()); + assertThat(messageType.getFields().get(i).getIndex()).isEqualTo(i); } - assertEquals(nestedType, messageType.getNestedTypes().get(0)); - assertEquals(nestedType, messageType.findNestedTypeByName("NestedMessage")); - assertNull(messageType.findNestedTypeByName("NoSuchType")); + assertThat(messageType.getNestedTypes().get(0)).isEqualTo(nestedType); + assertThat(messageType.findNestedTypeByName("NestedMessage")).isEqualTo(nestedType); + assertThat(messageType.findNestedTypeByName("NoSuchType")).isNull(); for (int i = 0; i < messageType.getNestedTypes().size(); i++) { - assertEquals(i, messageType.getNestedTypes().get(i).getIndex()); + assertThat(messageType.getNestedTypes().get(i).getIndex()).isEqualTo(i); } EnumDescriptor enumType = TestAllTypes.NestedEnum.getDescriptor(); - assertEquals(enumType, messageType.getEnumTypes().get(0)); - assertEquals(enumType, messageType.findEnumTypeByName("NestedEnum")); - assertNull(messageType.findEnumTypeByName("NoSuchType")); + assertThat(messageType.getEnumTypes().get(0)).isEqualTo(enumType); + assertThat(messageType.findEnumTypeByName("NestedEnum")).isEqualTo(enumType); + assertThat(messageType.findEnumTypeByName("NoSuchType")).isNull(); for (int i = 0; i < messageType.getEnumTypes().size(); i++) { - assertEquals(i, messageType.getEnumTypes().get(i).getIndex()); + assertThat(messageType.getEnumTypes().get(i).getIndex()).isEqualTo(i); } } + @Test public void testFieldDescriptor() throws Exception { Descriptor messageType = TestAllTypes.getDescriptor(); FieldDescriptor primitiveField = messageType.findFieldByName("optional_int32"); @@ -196,143 +198,154 @@ FieldDescriptor extension = UnittestProto.optionalInt32Extension.getDescriptor(); FieldDescriptor nestedExtension = TestRequired.single.getDescriptor(); - assertEquals("optional_int32", primitiveField.getName()); - assertEquals("protobuf_unittest.TestAllTypes.optional_int32", primitiveField.getFullName()); - assertEquals(1, primitiveField.getNumber()); - assertEquals(messageType, primitiveField.getContainingType()); - assertEquals(UnittestProto.getDescriptor(), primitiveField.getFile()); - assertEquals(FieldDescriptor.Type.INT32, primitiveField.getType()); - assertEquals(FieldDescriptor.JavaType.INT, primitiveField.getJavaType()); - assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(), primitiveField.getOptions()); - assertFalse(primitiveField.isExtension()); - assertEquals("optional_int32", primitiveField.toProto().getName()); + assertThat(primitiveField.getName()).isEqualTo("optional_int32"); + assertThat(primitiveField.getFullName()) + .isEqualTo("protobuf_unittest.TestAllTypes.optional_int32"); + assertThat(primitiveField.getNumber()).isEqualTo(1); + assertThat(primitiveField.getContainingType()).isEqualTo(messageType); + assertThat(primitiveField.getFile()).isEqualTo(UnittestProto.getDescriptor()); + assertThat(primitiveField.getType()).isEqualTo(FieldDescriptor.Type.INT32); + assertThat(primitiveField.getJavaType()).isEqualTo(FieldDescriptor.JavaType.INT); + assertThat(primitiveField.getOptions()) + .isEqualTo(DescriptorProtos.FieldOptions.getDefaultInstance()); + assertThat(primitiveField.isExtension()).isFalse(); + assertThat(primitiveField.toProto().getName()).isEqualTo("optional_int32"); - assertEquals("optional_nested_enum", enumField.getName()); - assertEquals(FieldDescriptor.Type.ENUM, enumField.getType()); - assertEquals(FieldDescriptor.JavaType.ENUM, enumField.getJavaType()); - assertEquals(TestAllTypes.NestedEnum.getDescriptor(), enumField.getEnumType()); + assertThat(enumField.getName()).isEqualTo("optional_nested_enum"); + assertThat(enumField.getType()).isEqualTo(FieldDescriptor.Type.ENUM); + assertThat(enumField.getJavaType()).isEqualTo(FieldDescriptor.JavaType.ENUM); + assertThat(enumField.getEnumType()).isEqualTo(TestAllTypes.NestedEnum.getDescriptor()); - assertEquals("optional_foreign_message", messageField.getName()); - assertEquals(FieldDescriptor.Type.MESSAGE, messageField.getType()); - assertEquals(FieldDescriptor.JavaType.MESSAGE, messageField.getJavaType()); - assertEquals(ForeignMessage.getDescriptor(), messageField.getMessageType()); + assertThat(messageField.getName()).isEqualTo("optional_foreign_message"); + assertThat(messageField.getType()).isEqualTo(FieldDescriptor.Type.MESSAGE); + assertThat(messageField.getJavaType()).isEqualTo(FieldDescriptor.JavaType.MESSAGE); + assertThat(messageField.getMessageType()).isEqualTo(ForeignMessage.getDescriptor()); - assertEquals("optional_cord", cordField.getName()); - assertEquals(FieldDescriptor.Type.STRING, cordField.getType()); - assertEquals(FieldDescriptor.JavaType.STRING, cordField.getJavaType()); - assertEquals(DescriptorProtos.FieldOptions.CType.CORD, cordField.getOptions().getCtype()); + assertThat(cordField.getName()).isEqualTo("optional_cord"); + assertThat(cordField.getType()).isEqualTo(FieldDescriptor.Type.STRING); + assertThat(cordField.getJavaType()).isEqualTo(FieldDescriptor.JavaType.STRING); + assertThat(cordField.getOptions().getCtype()) + .isEqualTo(DescriptorProtos.FieldOptions.CType.CORD); - assertEquals("optional_int32_extension", extension.getName()); - assertEquals("protobuf_unittest.optional_int32_extension", extension.getFullName()); - assertEquals(1, extension.getNumber()); - assertEquals(TestAllExtensions.getDescriptor(), extension.getContainingType()); - assertEquals(UnittestProto.getDescriptor(), extension.getFile()); - assertEquals(FieldDescriptor.Type.INT32, extension.getType()); - assertEquals(FieldDescriptor.JavaType.INT, extension.getJavaType()); - assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(), extension.getOptions()); - assertTrue(extension.isExtension()); - assertEquals(null, extension.getExtensionScope()); - assertEquals("optional_int32_extension", extension.toProto().getName()); + assertThat(extension.getName()).isEqualTo("optional_int32_extension"); + assertThat(extension.getFullName()).isEqualTo("protobuf_unittest.optional_int32_extension"); + assertThat(extension.getNumber()).isEqualTo(1); + assertThat(extension.getContainingType()).isEqualTo(TestAllExtensions.getDescriptor()); + assertThat(extension.getFile()).isEqualTo(UnittestProto.getDescriptor()); + assertThat(extension.getType()).isEqualTo(FieldDescriptor.Type.INT32); + assertThat(extension.getJavaType()).isEqualTo(FieldDescriptor.JavaType.INT); + assertThat(extension.getOptions()) + .isEqualTo(DescriptorProtos.FieldOptions.getDefaultInstance()); + assertThat(extension.isExtension()).isTrue(); + assertThat(extension.getExtensionScope()).isNull(); + assertThat(extension.toProto().getName()).isEqualTo("optional_int32_extension"); - assertEquals("single", nestedExtension.getName()); - assertEquals("protobuf_unittest.TestRequired.single", nestedExtension.getFullName()); - assertEquals(TestRequired.getDescriptor(), nestedExtension.getExtensionScope()); + assertThat(nestedExtension.getName()).isEqualTo("single"); + assertThat(nestedExtension.getFullName()).isEqualTo("protobuf_unittest.TestRequired.single"); + assertThat(nestedExtension.getExtensionScope()).isEqualTo(TestRequired.getDescriptor()); } + @Test public void testFieldDescriptorLabel() throws Exception { FieldDescriptor requiredField = TestRequired.getDescriptor().findFieldByName("a"); FieldDescriptor optionalField = TestAllTypes.getDescriptor().findFieldByName("optional_int32"); FieldDescriptor repeatedField = TestAllTypes.getDescriptor().findFieldByName("repeated_int32"); - assertTrue(requiredField.isRequired()); - assertFalse(requiredField.isRepeated()); - assertFalse(optionalField.isRequired()); - assertFalse(optionalField.isRepeated()); - assertFalse(repeatedField.isRequired()); - assertTrue(repeatedField.isRepeated()); + assertThat(requiredField.isRequired()).isTrue(); + assertThat(requiredField.isRepeated()).isFalse(); + assertThat(optionalField.isRequired()).isFalse(); + assertThat(optionalField.isRepeated()).isFalse(); + assertThat(repeatedField.isRequired()).isFalse(); + assertThat(repeatedField.isRepeated()).isTrue(); } + @Test public void testFieldDescriptorJsonName() throws Exception { FieldDescriptor requiredField = TestRequired.getDescriptor().findFieldByName("a"); FieldDescriptor optionalField = TestAllTypes.getDescriptor().findFieldByName("optional_int32"); FieldDescriptor repeatedField = TestAllTypes.getDescriptor().findFieldByName("repeated_int32"); - assertEquals("a", requiredField.getJsonName()); - assertEquals("optionalInt32", optionalField.getJsonName()); - assertEquals("repeatedInt32", repeatedField.getJsonName()); + assertThat(requiredField.getJsonName()).isEqualTo("a"); + assertThat(optionalField.getJsonName()).isEqualTo("optionalInt32"); + assertThat(repeatedField.getJsonName()).isEqualTo("repeatedInt32"); } + @Test public void testFieldDescriptorDefault() throws Exception { Descriptor d = TestAllTypes.getDescriptor(); - assertFalse(d.findFieldByName("optional_int32").hasDefaultValue()); - assertEquals(0, d.findFieldByName("optional_int32").getDefaultValue()); - assertTrue(d.findFieldByName("default_int32").hasDefaultValue()); - assertEquals(41, d.findFieldByName("default_int32").getDefaultValue()); + assertThat(d.findFieldByName("optional_int32").hasDefaultValue()).isFalse(); + assertThat(d.findFieldByName("optional_int32").getDefaultValue()).isEqualTo(0); + assertThat(d.findFieldByName("default_int32").hasDefaultValue()).isTrue(); + assertThat(d.findFieldByName("default_int32").getDefaultValue()).isEqualTo(41); d = TestExtremeDefaultValues.getDescriptor(); - assertEquals( - ByteString.copyFrom("\0\001\007\b\f\n\r\t\013\\\'\"\u00fe".getBytes(Internal.ISO_8859_1)), - d.findFieldByName("escaped_bytes").getDefaultValue()); - assertEquals(-1, d.findFieldByName("large_uint32").getDefaultValue()); - assertEquals(-1L, d.findFieldByName("large_uint64").getDefaultValue()); + assertThat(d.findFieldByName("escaped_bytes").getDefaultValue()) + .isEqualTo( + ByteString.copyFrom( + "\0\001\007\b\f\n\r\t\013\\\'\"\u00fe".getBytes(Internal.ISO_8859_1))); + assertThat(d.findFieldByName("large_uint32").getDefaultValue()).isEqualTo(-1); + assertThat(d.findFieldByName("large_uint64").getDefaultValue()).isEqualTo(-1L); } + @Test public void testEnumDescriptor() throws Exception { EnumDescriptor enumType = ForeignEnum.getDescriptor(); EnumDescriptor nestedType = TestAllTypes.NestedEnum.getDescriptor(); - assertEquals("ForeignEnum", enumType.getName()); - assertEquals("protobuf_unittest.ForeignEnum", enumType.getFullName()); - assertEquals(UnittestProto.getDescriptor(), enumType.getFile()); - assertNull(enumType.getContainingType()); - assertEquals(DescriptorProtos.EnumOptions.getDefaultInstance(), enumType.getOptions()); + assertThat(enumType.getName()).isEqualTo("ForeignEnum"); + assertThat(enumType.getFullName()).isEqualTo("protobuf_unittest.ForeignEnum"); + assertThat(enumType.getFile()).isEqualTo(UnittestProto.getDescriptor()); + assertThat(enumType.getContainingType()).isNull(); + assertThat(enumType.getOptions()).isEqualTo(DescriptorProtos.EnumOptions.getDefaultInstance()); - assertEquals("NestedEnum", nestedType.getName()); - assertEquals("protobuf_unittest.TestAllTypes.NestedEnum", nestedType.getFullName()); - assertEquals(UnittestProto.getDescriptor(), nestedType.getFile()); - assertEquals(TestAllTypes.getDescriptor(), nestedType.getContainingType()); + assertThat(nestedType.getName()).isEqualTo("NestedEnum"); + assertThat(nestedType.getFullName()).isEqualTo("protobuf_unittest.TestAllTypes.NestedEnum"); + assertThat(nestedType.getFile()).isEqualTo(UnittestProto.getDescriptor()); + assertThat(nestedType.getContainingType()).isEqualTo(TestAllTypes.getDescriptor()); EnumValueDescriptor value = ForeignEnum.FOREIGN_FOO.getValueDescriptor(); - assertEquals(value, enumType.getValues().get(0)); - assertEquals("FOREIGN_FOO", value.getName()); - assertEquals("FOREIGN_FOO", value.toString()); - assertEquals(4, value.getNumber()); - assertEquals(value, enumType.findValueByName("FOREIGN_FOO")); - assertEquals(value, enumType.findValueByNumber(4)); - assertNull(enumType.findValueByName("NO_SUCH_VALUE")); + assertThat(enumType.getValues().get(0)).isEqualTo(value); + assertThat(value.getName()).isEqualTo("FOREIGN_FOO"); + assertThat(value.toString()).isEqualTo("FOREIGN_FOO"); + assertThat(value.getNumber()).isEqualTo(4); + assertThat(enumType.findValueByName("FOREIGN_FOO")).isEqualTo(value); + assertThat(enumType.findValueByNumber(4)).isEqualTo(value); + assertThat(enumType.findValueByName("NO_SUCH_VALUE")).isNull(); for (int i = 0; i < enumType.getValues().size(); i++) { - assertEquals(i, enumType.getValues().get(i).getIndex()); + assertThat(enumType.getValues().get(i).getIndex()).isEqualTo(i); } } + @Test public void testServiceDescriptor() throws Exception { ServiceDescriptor service = TestService.getDescriptor(); - assertEquals("TestService", service.getName()); - assertEquals("protobuf_unittest.TestService", service.getFullName()); - assertEquals(UnittestProto.getDescriptor(), service.getFile()); + assertThat(service.getName()).isEqualTo("TestService"); + assertThat(service.getFullName()).isEqualTo("protobuf_unittest.TestService"); + assertThat(service.getFile()).isEqualTo(UnittestProto.getDescriptor()); MethodDescriptor fooMethod = service.getMethods().get(0); - assertEquals("Foo", fooMethod.getName()); - assertEquals(UnittestProto.FooRequest.getDescriptor(), fooMethod.getInputType()); - assertEquals(UnittestProto.FooResponse.getDescriptor(), fooMethod.getOutputType()); - assertEquals(fooMethod, service.findMethodByName("Foo")); + assertThat(fooMethod.getName()).isEqualTo("Foo"); + assertThat(fooMethod.getInputType()).isEqualTo(UnittestProto.FooRequest.getDescriptor()); + assertThat(fooMethod.getOutputType()).isEqualTo(UnittestProto.FooResponse.getDescriptor()); + assertThat(service.findMethodByName("Foo")).isEqualTo(fooMethod); MethodDescriptor barMethod = service.getMethods().get(1); - assertEquals("Bar", barMethod.getName()); - assertEquals(UnittestProto.BarRequest.getDescriptor(), barMethod.getInputType()); - assertEquals(UnittestProto.BarResponse.getDescriptor(), barMethod.getOutputType()); - assertEquals(barMethod, service.findMethodByName("Bar")); + assertThat(barMethod.getName()).isEqualTo("Bar"); + assertThat(barMethod.getInputType()).isEqualTo(UnittestProto.BarRequest.getDescriptor()); + assertThat(barMethod.getOutputType()).isEqualTo(UnittestProto.BarResponse.getDescriptor()); + assertThat(service.findMethodByName("Bar")).isEqualTo(barMethod); - assertNull(service.findMethodByName("NoSuchMethod")); + assertThat(service.findMethodByName("NoSuchMethod")).isNull(); for (int i = 0; i < service.getMethods().size(); i++) { - assertEquals(i, service.getMethods().get(i).getIndex()); + assertThat(service.getMethods().get(i).getIndex()).isEqualTo(i); } } + @Test public void testCustomOptions() throws Exception { // Get the descriptor indirectly from a dependent proto class. This is to // ensure that when a proto class is loaded, custom options defined in its @@ -342,80 +355,81 @@ .findFieldByName("field") .getMessageType(); - assertTrue(descriptor.getOptions().hasExtension(UnittestCustomOptions.messageOpt1)); - assertEquals( - Integer.valueOf(-56), - descriptor.getOptions().getExtension(UnittestCustomOptions.messageOpt1)); + assertThat(descriptor.getOptions().hasExtension(UnittestCustomOptions.messageOpt1)).isTrue(); + assertThat(descriptor.getOptions().getExtension(UnittestCustomOptions.messageOpt1)) + .isEqualTo(Integer.valueOf(-56)); FieldDescriptor field = descriptor.findFieldByName("field1"); - assertNotNull(field); + assertThat(field).isNotNull(); - assertTrue(field.getOptions().hasExtension(UnittestCustomOptions.fieldOpt1)); - assertEquals( - Long.valueOf(8765432109L), - field.getOptions().getExtension(UnittestCustomOptions.fieldOpt1)); + assertThat(field.getOptions().hasExtension(UnittestCustomOptions.fieldOpt1)).isTrue(); + assertThat(field.getOptions().getExtension(UnittestCustomOptions.fieldOpt1)) + .isEqualTo(Long.valueOf(8765432109L)); OneofDescriptor oneof = descriptor.getOneofs().get(0); - assertNotNull(oneof); + assertThat(oneof).isNotNull(); - assertTrue(oneof.getOptions().hasExtension(UnittestCustomOptions.oneofOpt1)); - assertEquals( - Integer.valueOf(-99), oneof.getOptions().getExtension(UnittestCustomOptions.oneofOpt1)); + assertThat(oneof.getOptions().hasExtension(UnittestCustomOptions.oneofOpt1)).isTrue(); + assertThat(oneof.getOptions().getExtension(UnittestCustomOptions.oneofOpt1)) + .isEqualTo(Integer.valueOf(-99)); EnumDescriptor enumType = UnittestCustomOptions.TestMessageWithCustomOptions.AnEnum.getDescriptor(); - assertTrue(enumType.getOptions().hasExtension(UnittestCustomOptions.enumOpt1)); - assertEquals( - Integer.valueOf(-789), enumType.getOptions().getExtension(UnittestCustomOptions.enumOpt1)); + assertThat(enumType.getOptions().hasExtension(UnittestCustomOptions.enumOpt1)).isTrue(); + assertThat(enumType.getOptions().getExtension(UnittestCustomOptions.enumOpt1)) + .isEqualTo(Integer.valueOf(-789)); ServiceDescriptor service = UnittestCustomOptions.TestServiceWithCustomOptions.getDescriptor(); - assertTrue(service.getOptions().hasExtension(UnittestCustomOptions.serviceOpt1)); - assertEquals( - Long.valueOf(-9876543210L), - service.getOptions().getExtension(UnittestCustomOptions.serviceOpt1)); + assertThat(service.getOptions().hasExtension(UnittestCustomOptions.serviceOpt1)).isTrue(); + assertThat(service.getOptions().getExtension(UnittestCustomOptions.serviceOpt1)) + .isEqualTo(Long.valueOf(-9876543210L)); MethodDescriptor method = service.findMethodByName("Foo"); - assertNotNull(method); + assertThat(method).isNotNull(); - assertTrue(method.getOptions().hasExtension(UnittestCustomOptions.methodOpt1)); - assertEquals( - UnittestCustomOptions.MethodOpt1.METHODOPT1_VAL2, - method.getOptions().getExtension(UnittestCustomOptions.methodOpt1)); + assertThat(method.getOptions().hasExtension(UnittestCustomOptions.methodOpt1)).isTrue(); + assertThat(method.getOptions().getExtension(UnittestCustomOptions.methodOpt1)) + .isEqualTo(UnittestCustomOptions.MethodOpt1.METHODOPT1_VAL2); } /** Test that the FieldDescriptor.Type enum is the same as the WireFormat.FieldType enum. */ + @Test public void testFieldTypeTablesMatch() throws Exception { FieldDescriptor.Type[] values1 = FieldDescriptor.Type.values(); WireFormat.FieldType[] values2 = WireFormat.FieldType.values(); - assertEquals(values1.length, values2.length); + assertThat(values1).hasLength(values2.length); for (int i = 0; i < values1.length; i++) { - assertEquals(values1[i].toString(), values2[i].toString()); + assertThat(values1[i].toString()).isEqualTo(values2[i].toString()); } } /** Test that the FieldDescriptor.JavaType enum is the same as the WireFormat.JavaType enum. */ + @Test public void testJavaTypeTablesMatch() throws Exception { FieldDescriptor.JavaType[] values1 = FieldDescriptor.JavaType.values(); WireFormat.JavaType[] values2 = WireFormat.JavaType.values(); - assertEquals(values1.length, values2.length); + assertThat(values1).hasLength(values2.length); for (int i = 0; i < values1.length; i++) { - assertEquals(values1[i].toString(), values2[i].toString()); + assertThat(values1[i].toString()).isEqualTo(values2[i].toString()); } } + @Test public void testEnormousDescriptor() throws Exception { // The descriptor for this file is larger than 64k, yet it did not cause // a compiler error due to an over-long string literal. - assertTrue(UnittestEnormousDescriptor.getDescriptor().toProto().getSerializedSize() > 65536); + assertThat(UnittestEnormousDescriptor.getDescriptor().toProto().getSerializedSize()) + .isGreaterThan(65536); } /** Tests that the DescriptorValidationException works as intended. */ + @Test public void testDescriptorValidatorException() throws Exception { FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder() @@ -435,14 +449,14 @@ .build(); try { Descriptors.FileDescriptor.buildFrom(fileDescriptorProto, new FileDescriptor[0]); - fail("DescriptorValidationException expected"); + assertWithMessage("DescriptorValidationException expected").fail(); } catch (DescriptorValidationException e) { // Expected; check that the error message contains some useful hints - assertTrue(e.getMessage().indexOf("foo") != -1); - assertTrue(e.getMessage().indexOf("Foo") != -1); - assertTrue(e.getMessage().indexOf("invalid") != -1); - assertTrue(e.getCause() instanceof NumberFormatException); - assertTrue(e.getCause().getMessage().indexOf("invalid") != -1); + assertThat(e).hasMessageThat().contains("foo"); + assertThat(e).hasMessageThat().contains("Foo"); + assertThat(e).hasMessageThat().contains("invalid"); + assertThat(e).hasCauseThat().isInstanceOf(NumberFormatException.class); + assertThat(e).hasCauseThat().hasMessageThat().contains("invalid"); } } @@ -450,6 +464,7 @@ * Tests the translate/crosslink for an example where a message field's name and type name are the * same. */ + @Test public void testDescriptorComplexCrosslink() throws Exception { FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder() @@ -481,25 +496,26 @@ FileDescriptor file = Descriptors.FileDescriptor.buildFrom(fileDescriptorProto, new FileDescriptor[0]); // verify resulting descriptors - assertNotNull(file); + assertThat(file).isNotNull(); List<Descriptor> msglist = file.getMessageTypes(); - assertNotNull(msglist); - assertTrue(msglist.size() == 2); + assertThat(msglist).isNotNull(); + assertThat(msglist).hasSize(2); boolean barFound = false; for (Descriptor desc : msglist) { if (desc.getName().equals("Bar")) { barFound = true; - assertNotNull(desc.getFields()); + assertThat(desc.getFields()).isNotNull(); List<FieldDescriptor> fieldlist = desc.getFields(); - assertNotNull(fieldlist); - assertTrue(fieldlist.size() == 1); - assertTrue(fieldlist.get(0).getType() == FieldDescriptor.Type.MESSAGE); - assertTrue(fieldlist.get(0).getMessageType().getName().equals("Foo")); + assertThat(fieldlist).isNotNull(); + assertThat(fieldlist).hasSize(1); + assertThat(fieldlist.get(0).getType()).isSameInstanceAs(FieldDescriptor.Type.MESSAGE); + assertThat(fieldlist.get(0).getMessageType().getName().equals("Foo")).isTrue(); } } - assertTrue(barFound); + assertThat(barFound).isTrue(); } + @Test public void testDependencyOrder() throws Exception { FileDescriptorProto fooProto = FileDescriptorProto.newBuilder().setName("foo.proto").build(); FileDescriptorProto barProto = @@ -521,6 +537,7 @@ Descriptors.FileDescriptor.buildFrom(bazProto, new FileDescriptor[] {barFile, fooFile}); } + @Test public void testInvalidPublicDependency() throws Exception { FileDescriptorProto fooProto = FileDescriptorProto.newBuilder().setName("foo.proto").build(); FileDescriptorProto barProto = @@ -532,12 +549,13 @@ FileDescriptor fooFile = Descriptors.FileDescriptor.buildFrom(fooProto, new FileDescriptor[0]); try { Descriptors.FileDescriptor.buildFrom(barProto, new FileDescriptor[] {fooFile}); - fail("DescriptorValidationException expected"); + assertWithMessage("DescriptorValidationException expected").fail(); } catch (DescriptorValidationException e) { - assertTrue(e.getMessage().indexOf("Invalid public dependency index.") != -1); + assertThat(e).hasMessageThat().contains("Invalid public dependency index."); } } + @Test public void testUnknownFieldsDenied() throws Exception { FileDescriptorProto fooProto = FileDescriptorProto.newBuilder() @@ -555,13 +573,14 @@ try { Descriptors.FileDescriptor.buildFrom(fooProto, new FileDescriptor[0]); - fail("DescriptorValidationException expected"); + assertWithMessage("DescriptorValidationException expected").fail(); } catch (DescriptorValidationException e) { - assertTrue(e.getMessage().indexOf("Bar") != -1); - assertTrue(e.getMessage().indexOf("is not defined") != -1); + assertThat(e).hasMessageThat().contains("Bar"); + assertThat(e).hasMessageThat().contains("is not defined"); } } + @Test public void testUnknownFieldsAllowed() throws Exception { FileDescriptorProto fooProto = FileDescriptorProto.newBuilder() @@ -580,6 +599,7 @@ Descriptors.FileDescriptor.buildFrom(fooProto, new FileDescriptor[0], true); } + @Test public void testHiddenDependency() throws Exception { FileDescriptorProto barProto = FileDescriptorProto.newBuilder() @@ -611,13 +631,14 @@ try { Descriptors.FileDescriptor.buildFrom(fooProto, new FileDescriptor[] {forwardFile}); - fail("DescriptorValidationException expected"); + assertWithMessage("DescriptorValidationException expected").fail(); } catch (DescriptorValidationException e) { - assertTrue(e.getMessage().indexOf("Bar") != -1); - assertTrue(e.getMessage().indexOf("is not defined") != -1); + assertThat(e).hasMessageThat().contains("Bar"); + assertThat(e).hasMessageThat().contains("is not defined"); } } + @Test public void testPublicDependency() throws Exception { FileDescriptorProto barProto = FileDescriptorProto.newBuilder() @@ -651,6 +672,7 @@ } /** Tests the translate/crosslink for an example with a more complex namespace referencing. */ + @Test public void testComplexNamespacePublicDependency() throws Exception { FileDescriptorProto fooProto = FileDescriptorProto.newBuilder() @@ -681,73 +703,78 @@ FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom(barProto, new FileDescriptor[] {fooFile}); // verify resulting descriptors - assertNotNull(barFile); + assertThat(barFile).isNotNull(); List<Descriptor> msglist = barFile.getMessageTypes(); - assertNotNull(msglist); - assertTrue(msglist.size() == 1); + assertThat(msglist).isNotNull(); + assertThat(msglist).hasSize(1); Descriptor desc = msglist.get(0); if (desc.getName().equals("MyMessage")) { - assertNotNull(desc.getFields()); + assertThat(desc.getFields()).isNotNull(); List<FieldDescriptor> fieldlist = desc.getFields(); - assertNotNull(fieldlist); - assertTrue(fieldlist.size() == 1); + assertThat(fieldlist).isNotNull(); + assertThat(fieldlist).hasSize(1); FieldDescriptor field = fieldlist.get(0); - assertTrue(field.getType() == FieldDescriptor.Type.ENUM); - assertTrue(field.getEnumType().getName().equals("MyEnum")); - assertTrue(field.getEnumType().getFile().getName().equals("bar.proto")); - assertTrue(field.getEnumType().getFile().getPackage().equals("a.b.c.d.bar.shared")); + assertThat(field.getType()).isSameInstanceAs(FieldDescriptor.Type.ENUM); + assertThat(field.getEnumType().getName().equals("MyEnum")).isTrue(); + assertThat(field.getEnumType().getFile().getName().equals("bar.proto")).isTrue(); + assertThat(field.getEnumType().getFile().getPackage().equals("a.b.c.d.bar.shared")).isTrue(); } } + @Test public void testOneofDescriptor() throws Exception { Descriptor messageType = TestAllTypes.getDescriptor(); FieldDescriptor field = messageType.findFieldByName("oneof_nested_message"); OneofDescriptor oneofDescriptor = field.getContainingOneof(); - assertNotNull(oneofDescriptor); - assertSame(oneofDescriptor, messageType.getOneofs().get(0)); - assertEquals("oneof_field", oneofDescriptor.getName()); + assertThat(oneofDescriptor).isNotNull(); + assertThat(messageType.getOneofs().get(0)).isSameInstanceAs(oneofDescriptor); + assertThat(oneofDescriptor.getName()).isEqualTo("oneof_field"); - assertEquals(4, oneofDescriptor.getFieldCount()); - assertSame(oneofDescriptor.getField(1), field); + assertThat(oneofDescriptor.getFieldCount()).isEqualTo(4); + assertThat(field).isSameInstanceAs(oneofDescriptor.getField(1)); - assertEquals(4, oneofDescriptor.getFields().size()); - assertEquals(oneofDescriptor.getFields().get(1), field); + assertThat(oneofDescriptor.getFields()).hasSize(4); + assertThat(field).isEqualTo(oneofDescriptor.getFields().get(1)); } + @Test public void testMessageDescriptorExtensions() throws Exception { - assertFalse(TestAllTypes.getDescriptor().isExtendable()); - assertTrue(TestAllExtensions.getDescriptor().isExtendable()); - assertTrue(TestMultipleExtensionRanges.getDescriptor().isExtendable()); + assertThat(TestAllTypes.getDescriptor().isExtendable()).isFalse(); + assertThat(TestAllExtensions.getDescriptor().isExtendable()).isTrue(); + assertThat(TestMultipleExtensionRanges.getDescriptor().isExtendable()).isTrue(); - assertFalse(TestAllTypes.getDescriptor().isExtensionNumber(3)); - assertTrue(TestAllExtensions.getDescriptor().isExtensionNumber(3)); - assertTrue(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(42)); - assertFalse(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(43)); - assertFalse(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(4142)); - assertTrue(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(4143)); + assertThat(TestAllTypes.getDescriptor().isExtensionNumber(3)).isFalse(); + assertThat(TestAllExtensions.getDescriptor().isExtensionNumber(3)).isTrue(); + assertThat(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(42)).isTrue(); + assertThat(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(43)).isFalse(); + assertThat(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(4142)).isFalse(); + assertThat(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(4143)).isTrue(); } + @Test public void testReservedFields() { Descriptor d = TestReservedFields.getDescriptor(); - assertTrue(d.isReservedNumber(2)); - assertFalse(d.isReservedNumber(8)); - assertTrue(d.isReservedNumber(9)); - assertTrue(d.isReservedNumber(10)); - assertTrue(d.isReservedNumber(11)); - assertFalse(d.isReservedNumber(12)); - assertFalse(d.isReservedName("foo")); - assertTrue(d.isReservedName("bar")); - assertTrue(d.isReservedName("baz")); + assertThat(d.isReservedNumber(2)).isTrue(); + assertThat(d.isReservedNumber(8)).isFalse(); + assertThat(d.isReservedNumber(9)).isTrue(); + assertThat(d.isReservedNumber(10)).isTrue(); + assertThat(d.isReservedNumber(11)).isTrue(); + assertThat(d.isReservedNumber(12)).isFalse(); + assertThat(d.isReservedName("foo")).isFalse(); + assertThat(d.isReservedName("bar")).isTrue(); + assertThat(d.isReservedName("baz")).isTrue(); } + @Test public void testToString() { - assertEquals( - "protobuf_unittest.TestAllTypes.optional_uint64", - UnittestProto.TestAllTypes.getDescriptor() - .findFieldByNumber(UnittestProto.TestAllTypes.OPTIONAL_UINT64_FIELD_NUMBER) - .toString()); + assertThat( + UnittestProto.TestAllTypes.getDescriptor() + .findFieldByNumber(UnittestProto.TestAllTypes.OPTIONAL_UINT64_FIELD_NUMBER) + .toString()) + .isEqualTo("protobuf_unittest.TestAllTypes.optional_uint64"); } + @Test public void testPackedEnumField() throws Exception { FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder() @@ -775,37 +802,41 @@ Descriptors.FileDescriptor.buildFrom(fileDescriptorProto, new FileDescriptor[0]); } + @Test public void testFieldJsonName() throws Exception { Descriptor d = TestJsonName.getDescriptor(); - assertEquals(6, d.getFields().size()); - assertEquals("fieldName1", d.getFields().get(0).getJsonName()); - assertEquals("fieldName2", d.getFields().get(1).getJsonName()); - assertEquals("FieldName3", d.getFields().get(2).getJsonName()); - assertEquals("FieldName4", d.getFields().get(3).getJsonName()); - assertEquals("FIELDNAME5", d.getFields().get(4).getJsonName()); - assertEquals("@type", d.getFields().get(5).getJsonName()); + assertThat(d.getFields()).hasSize(7); + assertThat(d.getFields().get(0).getJsonName()).isEqualTo("fieldName1"); + assertThat(d.getFields().get(1).getJsonName()).isEqualTo("fieldName2"); + assertThat(d.getFields().get(2).getJsonName()).isEqualTo("FieldName3"); + assertThat(d.getFields().get(3).getJsonName()).isEqualTo("FieldName4"); + assertThat(d.getFields().get(4).getJsonName()).isEqualTo("FIELDNAME5"); + assertThat(d.getFields().get(5).getJsonName()).isEqualTo("@type"); + assertThat(d.getFields().get(6).getJsonName()).isEqualTo("fieldname7"); } + @Test public void testExtensionRenamesKeywords() { - assertTrue(NonNestedExtension.if_ instanceof GeneratedMessage.GeneratedExtension); - assertTrue( - NestedExtension.MyNestedExtension.default_ - instanceof GeneratedMessage.GeneratedExtension); + assertThat(NonNestedExtension.if_).isInstanceOf(GeneratedMessage.GeneratedExtension.class); + assertThat(NestedExtension.MyNestedExtension.default_) + .isInstanceOf(GeneratedMessage.GeneratedExtension.class); NonNestedExtension.MessageToBeExtended msg = NonNestedExtension.MessageToBeExtended.newBuilder() .setExtension(NonNestedExtension.if_, "!fi") .build(); - assertEquals("!fi", msg.getExtension(NonNestedExtension.if_)); + assertThat(msg.getExtension(NonNestedExtension.if_)).isEqualTo("!fi"); msg = NonNestedExtension.MessageToBeExtended.newBuilder() .setExtension(NestedExtension.MyNestedExtension.default_, 8) .build(); - assertEquals(8, msg.getExtension(NestedExtension.MyNestedExtension.default_).intValue()); + assertThat(msg.getExtension(NestedExtension.MyNestedExtension.default_).intValue()) + .isEqualTo(8); } + @Test public void testDefaultDescriptorExtensionRange() throws Exception { - assertTrue(new Descriptor("default").isExtensionNumber(1)); + assertThat(new Descriptor("default").isExtensionNumber(1)).isTrue(); } }
diff --git a/java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java b/java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java index 01a96ba..a130545 100644 --- a/java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java +++ b/java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java
@@ -30,7 +30,7 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; +import static com.google.common.truth.Truth.assertWithMessage; import protobuf_unittest.UnittestProto; import proto3_unittest.UnittestProto3; @@ -83,12 +83,12 @@ // Use DiscardUnknownFieldsParser to parse the first payload. int oldLimit = input.pushLimit(messageSize); Message parsed = DiscardUnknownFieldsParser.wrap(message.getParserForType()).parseFrom(input); - assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize()); + assertWithMessage(message.getClass().getName()).that(parsed.getSerializedSize()).isEqualTo(0); input.popLimit(oldLimit); // Use the normal parser to parse the remaining payload should have unknown fields preserved. parsed = message.getParserForType().parseFrom(input); - assertEquals(message.getClass().getName(), payload, parsed.toByteString()); + assertWithMessage(message.getClass().getName()).that(parsed.toByteString()).isEqualTo(payload); } /** @@ -99,20 +99,20 @@ throws Exception { UnknownFieldSet unknownFields = UnknownFieldSet.newBuilder().mergeFrom(payload).build(); Message built = message.newBuilderForType().setUnknownFields(unknownFields).build(); - assertEquals(message.getClass().getName(), payload, built.toByteString()); + assertWithMessage(message.getClass().getName()).that(built.toByteString()).isEqualTo(payload); } private static void assertUnknownFieldsPreserved(MessageLite message) throws Exception { MessageLite parsed = message.getParserForType().parseFrom(payload); - assertEquals(message.getClass().getName(), payload, parsed.toByteString()); + assertWithMessage(message.getClass().getName()).that(parsed.toByteString()).isEqualTo(payload); parsed = message.newBuilderForType().mergeFrom(payload).build(); - assertEquals(message.getClass().getName(), payload, parsed.toByteString()); + assertWithMessage(message.getClass().getName()).that(parsed.toByteString()).isEqualTo(payload); } private static void assertUnknownFieldsExplicitlyDiscarded(Message message) throws Exception { Message parsed = DiscardUnknownFieldsParser.wrap(message.getParserForType()).parseFrom(payload); - assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize()); + assertWithMessage(message.getClass().getName()).that(parsed.getSerializedSize()).isEqualTo(0); } private static final ByteString payload =
diff --git a/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java b/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java index 019b5a1..28c05a3 100644 --- a/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java
@@ -30,39 +30,44 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static java.util.Arrays.asList; import com.google.protobuf.Internal.DoubleList; import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.Iterator; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Tests for {@link DoubleArrayList}. - * - * @author dweis@google.com (Daniel Weis) - */ -public class DoubleArrayListTest extends TestCase { +/** Tests for {@link DoubleArrayList}. */ +@RunWith(JUnit4.class) +public class DoubleArrayListTest { private static final DoubleArrayList UNARY_LIST = newImmutableDoubleArrayList(1); private static final DoubleArrayList TERTIARY_LIST = newImmutableDoubleArrayList(1, 2, 3); private DoubleArrayList list; - @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { list = new DoubleArrayList(); } + @Test public void testEmptyListReturnsSameInstance() { - assertSame(DoubleArrayList.emptyList(), DoubleArrayList.emptyList()); + assertThat(DoubleArrayList.emptyList()).isSameInstanceAs(DoubleArrayList.emptyList()); } + @Test public void testEmptyListIsImmutable() { assertImmutable(DoubleArrayList.emptyList()); } + @Test public void testMakeImmutable() { list.addDouble(3); list.addDouble(4); @@ -72,19 +77,20 @@ assertImmutable(list); } + @Test public void testModificationWithIteration() { list.addAll(asList(1D, 2D, 3D, 4D)); Iterator<Double> iterator = list.iterator(); - assertEquals(4, list.size()); - assertEquals(1D, (double) list.get(0), 0.0); - assertEquals(1D, (double) iterator.next(), 0.0); + assertThat(list).hasSize(4); + assertThat((double) list.get(0)).isEqualTo(1D); + assertThat((double) iterator.next()).isEqualTo(1D); list.set(0, 1D); - assertEquals(2D, (double) iterator.next(), 0.0); + assertThat((double) iterator.next()).isEqualTo(2D); list.remove(0); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail(); } catch (ConcurrentModificationException e) { // expected } @@ -93,191 +99,211 @@ list.add(0, 0D); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail(); } catch (ConcurrentModificationException e) { // expected } } + @Test public void testGet() { - assertEquals(1D, (double) TERTIARY_LIST.get(0), 0.0); - assertEquals(2D, (double) TERTIARY_LIST.get(1), 0.0); - assertEquals(3D, (double) TERTIARY_LIST.get(2), 0.0); + assertThat((double) TERTIARY_LIST.get(0)).isEqualTo(1D); + assertThat((double) TERTIARY_LIST.get(1)).isEqualTo(2D); + assertThat((double) TERTIARY_LIST.get(2)).isEqualTo(3D); try { TERTIARY_LIST.get(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { TERTIARY_LIST.get(3); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testGetDouble() { - assertEquals(1D, TERTIARY_LIST.getDouble(0), 0.0); - assertEquals(2D, TERTIARY_LIST.getDouble(1), 0.0); - assertEquals(3D, TERTIARY_LIST.getDouble(2), 0.0); + assertThat(TERTIARY_LIST.getDouble(0)).isEqualTo(1D); + assertThat(TERTIARY_LIST.getDouble(1)).isEqualTo(2D); + assertThat(TERTIARY_LIST.getDouble(2)).isEqualTo(3D); try { TERTIARY_LIST.get(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { TERTIARY_LIST.get(3); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testIndexOf_nullElement() { - assertEquals(-1, TERTIARY_LIST.indexOf(null)); + assertThat(TERTIARY_LIST.indexOf(null)).isEqualTo(-1); } + @Test public void testIndexOf_incompatibleElementType() { - assertEquals(-1, TERTIARY_LIST.indexOf(new Object())); + assertThat(TERTIARY_LIST.indexOf(new Object())).isEqualTo(-1); } + @Test public void testIndexOf_notInList() { - assertEquals(-1, UNARY_LIST.indexOf(2D)); + assertThat(UNARY_LIST.indexOf(2D)).isEqualTo(-1); } + @Test public void testIndexOf_notInListWithDuplicates() { DoubleArrayList listWithDupes = newImmutableDoubleArrayList(1D, 1D); - assertEquals(-1, listWithDupes.indexOf(2D)); + assertThat(listWithDupes.indexOf(2D)).isEqualTo(-1); } + @Test public void testIndexOf_inList() { - assertEquals(1, TERTIARY_LIST.indexOf(2D)); + assertThat(TERTIARY_LIST.indexOf(2D)).isEqualTo(1); } + @Test public void testIndexOf_inListWithDuplicates_matchAtHead() { DoubleArrayList listWithDupes = newImmutableDoubleArrayList(1D, 1D, 2D); - assertEquals(0, listWithDupes.indexOf(1D)); + assertThat(listWithDupes.indexOf(1D)).isEqualTo(0); } + @Test public void testIndexOf_inListWithDuplicates_matchMidList() { DoubleArrayList listWithDupes = newImmutableDoubleArrayList(2D, 1D, 1D, 2D); - assertEquals(1, listWithDupes.indexOf(1D)); + assertThat(listWithDupes.indexOf(1D)).isEqualTo(1); } + @Test public void testContains_nullElement() { - assertEquals(false, TERTIARY_LIST.contains(null)); + assertThat(TERTIARY_LIST).doesNotContain(null); } + @Test public void testContains_incompatibleElementType() { - assertEquals(false, TERTIARY_LIST.contains(new Object())); + assertThat(TERTIARY_LIST).doesNotContain(new Object()); } + @Test public void testContains_notInList() { - assertEquals(false, UNARY_LIST.contains(2D)); + assertThat(UNARY_LIST).doesNotContain(2D); } + @Test public void testContains_notInListWithDuplicates() { DoubleArrayList listWithDupes = newImmutableDoubleArrayList(1D, 1D); - assertEquals(false, listWithDupes.contains(2D)); + assertThat(listWithDupes).doesNotContain(2D); } + @Test public void testContains_inList() { - assertEquals(true, TERTIARY_LIST.contains(2D)); + assertThat(TERTIARY_LIST).contains(2D); } + @Test public void testContains_inListWithDuplicates_matchAtHead() { DoubleArrayList listWithDupes = newImmutableDoubleArrayList(1D, 1D, 2D); - assertEquals(true, listWithDupes.contains(1D)); + assertThat(listWithDupes).contains(1D); } + @Test public void testContains_inListWithDuplicates_matchMidList() { DoubleArrayList listWithDupes = newImmutableDoubleArrayList(2D, 1D, 1D, 2D); - assertEquals(true, listWithDupes.contains(1D)); + assertThat(listWithDupes).contains(1D); } + @Test public void testSize() { - assertEquals(0, DoubleArrayList.emptyList().size()); - assertEquals(1, UNARY_LIST.size()); - assertEquals(3, TERTIARY_LIST.size()); + assertThat(DoubleArrayList.emptyList()).isEmpty(); + assertThat(UNARY_LIST).hasSize(1); + assertThat(TERTIARY_LIST).hasSize(3); list.addDouble(3); list.addDouble(4); list.addDouble(6); list.addDouble(8); - assertEquals(4, list.size()); + assertThat(list).hasSize(4); list.remove(0); - assertEquals(3, list.size()); + assertThat(list).hasSize(3); list.add(17D); - assertEquals(4, list.size()); + assertThat(list).hasSize(4); } + @Test public void testSet() { list.addDouble(2); list.addDouble(4); - assertEquals(2D, (double) list.set(0, 3D), 0.0); - assertEquals(3D, list.getDouble(0), 0.0); + assertThat((double) list.set(0, 3D)).isEqualTo(2D); + assertThat(list.getDouble(0)).isEqualTo(3D); - assertEquals(4D, (double) list.set(1, 0D), 0.0); - assertEquals(0D, list.getDouble(1), 0.0); + assertThat((double) list.set(1, 0D)).isEqualTo(4D); + assertThat(list.getDouble(1)).isEqualTo(0D); try { list.set(-1, 0D); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.set(2, 0D); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testSetDouble() { list.addDouble(1); list.addDouble(3); - assertEquals(1D, list.setDouble(0, 0), 0.0); - assertEquals(0D, list.getDouble(0), 0.0); + assertThat(list.setDouble(0, 0)).isEqualTo(1D); + assertThat(list.getDouble(0)).isEqualTo(0D); - assertEquals(3D, list.setDouble(1, 0), 0.0); - assertEquals(0D, list.getDouble(1), 0.0); + assertThat(list.setDouble(1, 0)).isEqualTo(3D); + assertThat(list.getDouble(1)).isEqualTo(0D); try { list.setDouble(-1, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.setDouble(2, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testAdd() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); - assertTrue(list.add(2D)); - assertEquals(asList(2D), list); + assertThat(list.add(2D)).isTrue(); + assertThat(list).containsExactly(2D); - assertTrue(list.add(3D)); + assertThat(list.add(3D)).isTrue(); list.add(0, 4D); - assertEquals(asList(4D, 2D, 3D), list); + assertThat(list).containsExactly(4D, 2D, 3D).inOrder(); list.add(0, 1D); list.add(0, 0D); @@ -285,7 +311,7 @@ for (int i = 0; i < 6; i++) { list.add(Double.valueOf(5 + i)); } - assertEquals(asList(0D, 1D, 4D, 2D, 3D, 5D, 6D, 7D, 8D, 9D, 10D), list); + assertThat(list).containsExactly(0D, 1D, 4D, 2D, 3D, 5D, 6D, 7D, 8D, 9D, 10D).inOrder(); try { list.add(-1, 5D); @@ -300,92 +326,100 @@ } } + @Test public void testAddDouble() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); list.addDouble(2); - assertEquals(asList(2D), list); + assertThat(list).containsExactly(2D); list.addDouble(3); - assertEquals(asList(2D, 3D), list); + assertThat(list).containsExactly(2D, 3D).inOrder(); } + @Test public void testAddAll() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); - assertTrue(list.addAll(Collections.singleton(1D))); - assertEquals(1, list.size()); - assertEquals(1D, (double) list.get(0), 0.0); - assertEquals(1D, list.getDouble(0), 0.0); + assertThat(list.addAll(Collections.singleton(1D))).isTrue(); + assertThat(list).hasSize(1); + assertThat((double) list.get(0)).isEqualTo(1D); + assertThat(list.getDouble(0)).isEqualTo(1D); - assertTrue(list.addAll(asList(2D, 3D, 4D, 5D, 6D))); - assertEquals(asList(1D, 2D, 3D, 4D, 5D, 6D), list); + assertThat(list.addAll(asList(2D, 3D, 4D, 5D, 6D))).isTrue(); + assertThat(list).containsExactly(1D, 2D, 3D, 4D, 5D, 6D).inOrder(); - assertTrue(list.addAll(TERTIARY_LIST)); - assertEquals(asList(1D, 2D, 3D, 4D, 5D, 6D, 1D, 2D, 3D), list); + assertThat(list.addAll(TERTIARY_LIST)).isTrue(); + assertThat(list).containsExactly(1D, 2D, 3D, 4D, 5D, 6D, 1D, 2D, 3D).inOrder(); - assertFalse(list.addAll(Collections.<Double>emptyList())); - assertFalse(list.addAll(DoubleArrayList.emptyList())); + assertThat(list.addAll(Collections.<Double>emptyList())).isFalse(); + assertThat(list.addAll(DoubleArrayList.emptyList())).isFalse(); } + @Test public void testEquals() { DoubleArrayList list1 = new DoubleArrayList(); DoubleArrayList list2 = new DoubleArrayList(); list1.addDouble(Double.longBitsToDouble(0x7ff0000000000001L)); list2.addDouble(Double.longBitsToDouble(0x7ff0000000000002L)); - assertEquals(list1, list2); + assertThat(list1).isEqualTo(list2); } + @Test public void testRemove() { list.addAll(TERTIARY_LIST); - assertEquals(1D, (double) list.remove(0), 0.0); - assertEquals(asList(2D, 3D), list); + assertThat((double) list.remove(0)).isEqualTo(1D); + assertThat(list).containsExactly(2D, 3D).inOrder(); - assertTrue(list.remove(Double.valueOf(3))); - assertEquals(asList(2D), list); + assertThat(list.remove(Double.valueOf(3))).isTrue(); + assertThat(list).containsExactly(2D); - assertFalse(list.remove(Double.valueOf(3))); - assertEquals(asList(2D), list); + assertThat(list.remove(Double.valueOf(3))).isFalse(); + assertThat(list).containsExactly(2D); - assertEquals(2D, (double) list.remove(0), 0.0); - assertEquals(asList(), list); + assertThat((double) list.remove(0)).isEqualTo(2D); + assertThat(list).isEmpty(); try { list.remove(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.remove(0); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testRemoveEnd_listAtCapacity() { DoubleList toRemove = DoubleArrayList.emptyList().mutableCopyWithCapacity(1); toRemove.addDouble(3); toRemove.remove(0); - assertEquals(0, toRemove.size()); + assertThat(toRemove).isEmpty(); } + @Test public void testRemove_listAtCapacity() { DoubleList toRemove = DoubleArrayList.emptyList().mutableCopyWithCapacity(2); toRemove.addDouble(3); toRemove.addDouble(4); toRemove.remove(0); - assertEquals(1, toRemove.size()); - assertEquals(4D, (double) toRemove.get(0)); + assertThat(toRemove).hasSize(1); + assertThat((double) toRemove.get(0)).isEqualTo(4D); } + @Test public void testSublistRemoveEndOfCapacity() { DoubleList toRemove = DoubleArrayList.emptyList().mutableCopyWithCapacity(1); toRemove.addDouble(3); toRemove.subList(0, 1).clear(); - assertEquals(0, toRemove.size()); + assertThat(toRemove).isEmpty(); } private void assertImmutable(DoubleList list) { @@ -395,147 +429,147 @@ try { list.add(1D); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.add(0, 1D); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(Collections.<Double>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(Collections.singletonList(1D)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(new DoubleArrayList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, Collections.singleton(1D)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, Collections.<Double>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addDouble(0); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.clear(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.remove(1); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.remove(new Object()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(Collections.<Double>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(Collections.singleton(1D)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(Collections.<Double>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(Collections.singleton(1D)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.set(0, 0D); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.setDouble(0, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected }
diff --git a/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java b/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java index cd40ffa..3aacdcc 100644 --- a/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java +++ b/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java
@@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.OneofDescriptor; @@ -39,16 +41,16 @@ import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage; import protobuf_unittest.UnittestProto.TestEmptyMessage; import protobuf_unittest.UnittestProto.TestPackedTypes; -import java.util.Arrays; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Unit test for {@link DynamicMessage}. See also {@link MessageTest}, which tests some {@link * DynamicMessage} functionality. - * - * @author kenton@google.com Kenton Varda */ -public class DynamicMessageTest extends TestCase { +@RunWith(JUnit4.class) +public class DynamicMessageTest { TestUtil.ReflectionTester reflectionTester = new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null); @@ -58,6 +60,7 @@ TestUtil.ReflectionTester packedReflectionTester = new TestUtil.ReflectionTester(TestPackedTypes.getDescriptor(), null); + @Test public void testDynamicMessageAccessors() throws Exception { Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); reflectionTester.setAllFieldsViaReflection(builder); @@ -65,6 +68,7 @@ reflectionTester.assertAllFieldsSetViaReflection(message); } + @Test public void testSettersAfterBuild() throws Exception { Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); Message firstMessage = builder.build(); @@ -84,6 +88,7 @@ reflectionTester.assertClearViaReflection(firstMessage); } + @Test public void testUnknownFields() throws Exception { Message.Builder builder = DynamicMessage.newBuilder(TestEmptyMessage.getDescriptor()); builder.setUnknownFields( @@ -92,23 +97,25 @@ .addField(2, UnknownFieldSet.Field.newBuilder().addFixed32(1).build()) .build()); Message message = builder.build(); - assertEquals(2, message.getUnknownFields().asMap().size()); + assertThat(builder.getUnknownFields().asMap()).hasSize(2); // clone() with unknown fields Message.Builder newBuilder = builder.clone(); - assertEquals(2, newBuilder.getUnknownFields().asMap().size()); + assertThat(newBuilder.getUnknownFields().asMap()).hasSize(2); // clear() with unknown fields newBuilder.clear(); - assertTrue(newBuilder.getUnknownFields().asMap().isEmpty()); + assertThat(newBuilder.getUnknownFields().asMap()).isEmpty(); // serialize/parse with unknown fields newBuilder.mergeFrom(message.toByteString()); - assertEquals(2, newBuilder.getUnknownFields().asMap().size()); + assertThat(newBuilder.getUnknownFields().asMap()).hasSize(2); } + @Test public void testDynamicMessageSettersRejectNull() throws Exception { Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); reflectionTester.assertReflectionSettersRejectNull(builder); } + @Test public void testDynamicMessageExtensionAccessors() throws Exception { // We don't need to extensively test DynamicMessage's handling of // extensions because, frankly, it doesn't do anything special with them. @@ -119,11 +126,13 @@ extensionsReflectionTester.assertAllFieldsSetViaReflection(message); } + @Test public void testDynamicMessageExtensionSettersRejectNull() throws Exception { Message.Builder builder = DynamicMessage.newBuilder(TestAllExtensions.getDescriptor()); extensionsReflectionTester.assertReflectionSettersRejectNull(builder); } + @Test public void testDynamicMessageRepeatedSetters() throws Exception { Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); reflectionTester.setAllFieldsViaReflection(builder); @@ -132,11 +141,13 @@ reflectionTester.assertRepeatedFieldsModifiedViaReflection(message); } + @Test public void testDynamicMessageRepeatedSettersRejectNull() throws Exception { Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); reflectionTester.assertReflectionRepeatedSettersRejectNull(builder); } + @Test public void testDynamicMessageDefaults() throws Exception { reflectionTester.assertClearViaReflection( DynamicMessage.getDefaultInstance(TestAllTypes.getDescriptor())); @@ -144,6 +155,7 @@ DynamicMessage.newBuilder(TestAllTypes.getDescriptor()).build()); } + @Test public void testDynamicMessageSerializedSize() throws Exception { TestAllTypes message = TestUtil.getAllSet(); @@ -151,9 +163,10 @@ reflectionTester.setAllFieldsViaReflection(dynamicBuilder); Message dynamicMessage = dynamicBuilder.build(); - assertEquals(message.getSerializedSize(), dynamicMessage.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(dynamicMessage.getSerializedSize()); } + @Test public void testDynamicMessageSerialization() throws Exception { Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); reflectionTester.setAllFieldsViaReflection(builder); @@ -165,9 +178,10 @@ TestUtil.assertAllFieldsSet(message2); // In fact, the serialized forms should be exactly the same, byte-for-byte. - assertEquals(TestUtil.getAllSet().toByteString(), rawBytes); + assertThat(rawBytes).isEqualTo(TestUtil.getAllSet().toByteString()); } + @Test public void testDynamicMessageParsing() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); @@ -183,6 +197,7 @@ reflectionTester.assertAllFieldsSetViaReflection(message3); } + @Test public void testDynamicMessageExtensionParsing() throws Exception { ByteString rawBytes = TestUtil.getAllExtensionsSet().toByteString(); Message message = @@ -196,6 +211,7 @@ extensionsReflectionTester.assertAllFieldsSetViaReflection(message2); } + @Test public void testDynamicMessagePackedSerialization() throws Exception { Message.Builder builder = DynamicMessage.newBuilder(TestPackedTypes.getDescriptor()); packedReflectionTester.setPackedFieldsViaReflection(builder); @@ -207,9 +223,10 @@ TestUtil.assertPackedFieldsSet(message2); // In fact, the serialized forms should be exactly the same, byte-for-byte. - assertEquals(TestUtil.getPackedSet().toByteString(), rawBytes); + assertThat(rawBytes).isEqualTo(TestUtil.getPackedSet().toByteString()); } + @Test public void testDynamicMessagePackedParsing() throws Exception { TestPackedTypes.Builder builder = TestPackedTypes.newBuilder(); TestUtil.setPackedFields(builder); @@ -225,6 +242,7 @@ packedReflectionTester.assertPackedFieldsSetViaReflection(message3); } + @Test public void testGetBuilderForExtensionField() { DynamicMessage.Builder builder = DynamicMessage.newBuilder(TestAllExtensions.getDescriptor()); Message.Builder fieldBuilder = @@ -233,9 +251,10 @@ FieldDescriptor field = NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); fieldBuilder.setField(field, expected); - assertEquals(expected, fieldBuilder.build().getField(field)); + assertThat(fieldBuilder.build().getField(field)).isEqualTo(expected); } + @Test public void testDynamicMessageCopy() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); @@ -247,14 +266,15 @@ // Test oneof behavior FieldDescriptor bytesField = TestAllTypes.getDescriptor().findFieldByName("oneof_bytes"); FieldDescriptor uint32Field = TestAllTypes.getDescriptor().findFieldByName("oneof_uint32"); - assertTrue(copy.hasField(bytesField)); - assertFalse(copy.hasField(uint32Field)); + assertThat(copy.hasField(bytesField)).isTrue(); + assertThat(copy.hasField(uint32Field)).isFalse(); DynamicMessage copy2 = DynamicMessage.newBuilder(message).setField(uint32Field, 123).build(); - assertFalse(copy2.hasField(bytesField)); - assertTrue(copy2.hasField(uint32Field)); - assertEquals(123, copy2.getField(uint32Field)); + assertThat(copy2.hasField(bytesField)).isFalse(); + assertThat(copy2.hasField(uint32Field)).isTrue(); + assertThat(copy2.getField(uint32Field)).isEqualTo(123); } + @Test public void testToBuilder() throws Exception { DynamicMessage.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); reflectionTester.setAllFieldsViaReflection(builder); @@ -270,41 +290,42 @@ DynamicMessage derived = message.toBuilder().build(); reflectionTester.assertAllFieldsSetViaReflection(derived); - assertEquals( - Arrays.asList(unknownFieldVal), - derived.getUnknownFields().getField(unknownFieldNum).getVarintList()); + assertThat(derived.getUnknownFields().getField(unknownFieldNum).getVarintList()) + .containsExactly(unknownFieldVal); } + @Test public void testDynamicOneofMessage() throws Exception { DynamicMessage.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); OneofDescriptor oneof = TestAllTypes.getDescriptor().getOneofs().get(0); - assertFalse(builder.hasOneof(oneof)); - assertSame(null, builder.getOneofFieldDescriptor(oneof)); + assertThat(builder.hasOneof(oneof)).isFalse(); + assertThat(builder.getOneofFieldDescriptor(oneof)).isNull(); reflectionTester.setAllFieldsViaReflection(builder); - assertTrue(builder.hasOneof(oneof)); + assertThat(builder.hasOneof(oneof)).isTrue(); FieldDescriptor field = oneof.getField(3); - assertSame(field, builder.getOneofFieldDescriptor(oneof)); + assertThat(builder.getOneofFieldDescriptor(oneof)).isSameInstanceAs(field); DynamicMessage message = builder.buildPartial(); - assertTrue(message.hasOneof(oneof)); + assertThat(message.hasOneof(oneof)).isTrue(); DynamicMessage.Builder mergedBuilder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); FieldDescriptor mergedField = oneof.getField(0); mergedBuilder.setField(mergedField, 123); - assertTrue(mergedBuilder.hasField(mergedField)); + assertThat(mergedBuilder.hasField(mergedField)).isTrue(); mergedBuilder.mergeFrom(message); - assertTrue(mergedBuilder.hasField(field)); - assertFalse(mergedBuilder.hasField(mergedField)); + assertThat(mergedBuilder.hasField(field)).isTrue(); + assertThat(mergedBuilder.hasField(mergedField)).isFalse(); builder.clearOneof(oneof); - assertSame(null, builder.getOneofFieldDescriptor(oneof)); + assertThat(builder.getOneofFieldDescriptor(oneof)).isNull(); message = builder.build(); - assertSame(null, message.getOneofFieldDescriptor(oneof)); + assertThat(message.getOneofFieldDescriptor(oneof)).isNull(); } // Regression test for a bug that makes setField() not work for repeated // enum fields. + @Test public void testSettersForRepeatedEnumField() throws Exception { DynamicMessage.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); FieldDescriptor repeatedEnumField = @@ -312,6 +333,6 @@ EnumDescriptor enumDescriptor = TestAllTypes.NestedEnum.getDescriptor(); builder.setField(repeatedEnumField, enumDescriptor.getValues()); DynamicMessage message = builder.build(); - assertEquals(enumDescriptor.getValues(), message.getField(repeatedEnumField)); + assertThat(message.getField(repeatedEnumField)).isEqualTo(enumDescriptor.getValues()); } }
diff --git a/java/core/src/test/java/com/google/protobuf/EnumTest.java b/java/core/src/test/java/com/google/protobuf/EnumTest.java index 80c176a..6287a23 100644 --- a/java/core/src/test/java/com/google/protobuf/EnumTest.java +++ b/java/core/src/test/java/com/google/protobuf/EnumTest.java
@@ -30,47 +30,56 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import com.google.protobuf.UnittestLite.ForeignEnumLite; import com.google.protobuf.UnittestLite.TestAllTypesLite; import protobuf_unittest.UnittestProto.ForeignEnum; import protobuf_unittest.UnittestProto.TestAllTypes; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -public class EnumTest extends TestCase { +@RunWith(JUnit4.class) +public class EnumTest { + @Test public void testForNumber() { ForeignEnum e = ForeignEnum.forNumber(ForeignEnum.FOREIGN_BAR.getNumber()); - assertEquals(ForeignEnum.FOREIGN_BAR, e); + assertThat(e).isEqualTo(ForeignEnum.FOREIGN_BAR); e = ForeignEnum.forNumber(1000); - assertNull(e); + assertThat(e).isNull(); } + @Test public void testForNumber_oneof() { TestAllTypes.OneofFieldCase e = TestAllTypes.OneofFieldCase.forNumber( TestAllTypes.OneofFieldCase.ONEOF_NESTED_MESSAGE.getNumber()); - assertEquals(TestAllTypes.OneofFieldCase.ONEOF_NESTED_MESSAGE, e); + assertThat(e).isEqualTo(TestAllTypes.OneofFieldCase.ONEOF_NESTED_MESSAGE); e = TestAllTypes.OneofFieldCase.forNumber(1000); - assertNull(e); + assertThat(e).isNull(); } + @Test public void testForNumberLite() { ForeignEnumLite e = ForeignEnumLite.forNumber(ForeignEnumLite.FOREIGN_LITE_BAR.getNumber()); - assertEquals(ForeignEnumLite.FOREIGN_LITE_BAR, e); + assertThat(e).isEqualTo(ForeignEnumLite.FOREIGN_LITE_BAR); e = ForeignEnumLite.forNumber(1000); - assertNull(e); + assertThat(e).isNull(); } + @Test public void testForNumberLite_oneof() { TestAllTypesLite.OneofFieldCase e = TestAllTypesLite.OneofFieldCase.forNumber( TestAllTypesLite.OneofFieldCase.ONEOF_NESTED_MESSAGE.getNumber()); - assertEquals(TestAllTypesLite.OneofFieldCase.ONEOF_NESTED_MESSAGE, e); + assertThat(e).isEqualTo(TestAllTypesLite.OneofFieldCase.ONEOF_NESTED_MESSAGE); e = TestAllTypesLite.OneofFieldCase.forNumber(1000); - assertNull(e); + assertThat(e).isNull(); } }
diff --git a/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java b/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java index 70466ba..a881ece 100644 --- a/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java +++ b/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java
@@ -30,18 +30,20 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.ClassPath; import protobuf_unittest.NonNestedExtension; import protobuf_unittest.NonNestedExtensionLite; +import java.io.IOException; import java.lang.reflect.Method; +import java.net.URL; import java.net.URLClassLoader; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.junit.Ignore; /** * Tests for {@link ExtensionRegistryFactory} and the {@link ExtensionRegistry} instances it @@ -53,13 +55,8 @@ * * <p>The test mechanism employed here is based on the pattern in {@code * com.google.common.util.concurrent.AbstractFutureFallbackAtomicHelperTest} - * - * <p> This test is temporarily disabled due to what appears to be a subtle change to class loading - * behavior in Java 11. That seems to have broken the way the test uses a custom ClassLoader to - * exercise Lite functionality. */ @SuppressWarnings("JUnit4ClassUsedInJUnit3") -@Ignore public class ExtensionRegistryFactoryTest extends TestCase { // A classloader which blacklists some non-Lite classes. @@ -85,21 +82,21 @@ public void testCreate() { ExtensionRegistryLite registry = ExtensionRegistryFactory.create(); - assertEquals(registry.getClass(), ExtensionRegistry.class); + assertThat(registry.getClass()).isEqualTo(ExtensionRegistry.class); } @Override public void testEmpty() { ExtensionRegistryLite emptyRegistry = ExtensionRegistryFactory.createEmpty(); - assertEquals(emptyRegistry.getClass(), ExtensionRegistry.class); - assertEquals(emptyRegistry, ExtensionRegistry.EMPTY_REGISTRY); + assertThat(emptyRegistry.getClass()).isEqualTo(ExtensionRegistry.class); + assertThat(emptyRegistry).isEqualTo(ExtensionRegistry.EMPTY_REGISTRY); } @Override public void testIsFullRegistry() { ExtensionRegistryLite registry = ExtensionRegistryFactory.create(); - assertTrue(ExtensionRegistryFactory.isFullRegistry(registry)); + assertThat(ExtensionRegistryFactory.isFullRegistry(registry)).isTrue(); } @Override @@ -115,25 +112,24 @@ ExtensionRegistry fullRegistry1 = (ExtensionRegistry) registry1; ExtensionRegistry fullRegistry2 = (ExtensionRegistry) registry2; - assertTrue( - "Test is using a non-lite extension", - GeneratedMessageLite.GeneratedExtension.class.isAssignableFrom( - NonNestedExtensionLite.nonNestedExtensionLite.getClass())); - assertNull( - "Extension is not registered in masqueraded full registry", - fullRegistry1.findImmutableExtensionByName("protobuf_unittest.nonNestedExtension")); + assertWithMessage("Test is using a non-lite extension") + .that(NonNestedExtensionLite.nonNestedExtensionLite.getClass()) + .isInstanceOf(GeneratedMessageLite.GeneratedExtension.class); + assertWithMessage("Extension is not registered in masqueraded full registry") + .that(fullRegistry1.findImmutableExtensionByName("protobuf_unittest.nonNestedExtension")) + .isNull(); GeneratedMessageLite.GeneratedExtension<NonNestedExtensionLite.MessageLiteToBeExtended, ?> extension = registry1.findLiteExtensionByNumber( NonNestedExtensionLite.MessageLiteToBeExtended.getDefaultInstance(), 1); - assertNotNull("Extension registered in lite registry", extension); + assertWithMessage("Extension registered in lite registry").that(extension).isNotNull(); - assertTrue( - "Test is using a non-lite extension", - Extension.class.isAssignableFrom(NonNestedExtension.nonNestedExtension.getClass())); - assertNotNull( - "Extension is registered in masqueraded full registry", - fullRegistry2.findImmutableExtensionByName("protobuf_unittest.nonNestedExtension")); + assertWithMessage("Test is using a non-lite extension") + .that(Extension.class.isAssignableFrom(NonNestedExtension.nonNestedExtension.getClass())) + .isTrue(); + assertWithMessage("Extension is registered in masqueraded full registry") + .that(fullRegistry2.findImmutableExtensionByName("protobuf_unittest.nonNestedExtension")) + .isNotNull(); } @Override @@ -141,24 +137,24 @@ ExtensionRegistryLite registry1 = ExtensionRegistryLite.newInstance().getUnmodifiable(); try { NonNestedExtensionLite.registerAllExtensions(registry1); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException expected) { } try { registry1.add(NonNestedExtensionLite.nonNestedExtensionLite); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException expected) { } ExtensionRegistryLite registry2 = ExtensionRegistryLite.newInstance().getUnmodifiable(); try { NonNestedExtension.registerAllExtensions((ExtensionRegistry) registry2); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException expected) { } try { registry2.add(NonNestedExtension.nonNestedExtension); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException expected) { } } @@ -171,21 +167,21 @@ public void testCreate() { ExtensionRegistryLite registry = ExtensionRegistryFactory.create(); - assertEquals(registry.getClass(), ExtensionRegistryLite.class); + assertThat(registry.getClass()).isEqualTo(ExtensionRegistryLite.class); } @Override public void testEmpty() { ExtensionRegistryLite emptyRegistry = ExtensionRegistryFactory.createEmpty(); - assertEquals(emptyRegistry.getClass(), ExtensionRegistryLite.class); - assertEquals(emptyRegistry, ExtensionRegistryLite.EMPTY_REGISTRY_LITE); + assertThat(emptyRegistry.getClass()).isEqualTo(ExtensionRegistryLite.class); + assertThat(emptyRegistry).isEqualTo(ExtensionRegistryLite.EMPTY_REGISTRY_LITE); } @Override public void testIsFullRegistry() { ExtensionRegistryLite registry = ExtensionRegistryFactory.create(); - assertFalse(ExtensionRegistryFactory.isFullRegistry(registry)); + assertThat(ExtensionRegistryFactory.isFullRegistry(registry)).isFalse(); } @Override @@ -196,7 +192,7 @@ extension = registry.findLiteExtensionByNumber( NonNestedExtensionLite.MessageLiteToBeExtended.getDefaultInstance(), 1); - assertNotNull("Extension is registered in Lite registry", extension); + assertWithMessage("Extension is registered in Lite registry").that(extension).isNotNull(); } @Override @@ -204,7 +200,7 @@ ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance().getUnmodifiable(); try { NonNestedExtensionLite.registerAllExtensions(registry); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException expected) { } } @@ -252,19 +248,27 @@ * determine the Lite/non-Lite runtime. */ private static ClassLoader getLiteOnlyClassLoader() { - ClassLoader testClassLoader = ExtensionRegistryFactoryTest.class.getClassLoader(); - final Set<String> classNamesNotInLite = - Collections.unmodifiableSet( - new HashSet<String>( - Arrays.asList( - ExtensionRegistryFactory.FULL_REGISTRY_CLASS_NAME, - ExtensionRegistry.EXTENSION_CLASS_NAME))); + + ImmutableSet<ClassPath.ClassInfo> classes = ImmutableSet.of(); + try { + classes = ClassPath.from(ExtensionRegistryFactoryTest.class.getClassLoader()).getAllClasses(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + URL[] urls = new URL[classes.size()]; + int i = 0; + for (ClassPath.ClassInfo classInfo : classes) { + urls[i++] = classInfo.url(); + } + final ImmutableSet<String> classNamesNotInLite = + ImmutableSet.of( + ExtensionRegistryFactory.FULL_REGISTRY_CLASS_NAME, + ExtensionRegistry.EXTENSION_CLASS_NAME); // Construct a URLClassLoader delegating to the system ClassLoader, and looking up classes // in jar files based on the URLs already configured for this test's UrlClassLoader. // Certain classes throw a ClassNotFoundException by design. - return new URLClassLoader( - ((URLClassLoader) testClassLoader).getURLs(), ClassLoader.getSystemClassLoader()) { + return new URLClassLoader(urls, ClassLoader.getSystemClassLoader()) { @Override public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { if (classNamesNotInLite.contains(name)) {
diff --git a/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java index 7266729..c4830af 100644 --- a/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java +++ b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java
@@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; @@ -40,12 +42,15 @@ import com.google.protobuf.FieldPresenceTestProto.TestRepeatedFieldsOnly; import com.google.protobuf.testing.proto.TestProto3Optional; import protobuf_unittest.UnittestProto; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Unit tests for protos that doesn't support field presence test for optional non-message fields. */ -public class FieldPresenceTest extends TestCase { +@RunWith(JUnit4.class) +public class FieldPresenceTest { private static boolean hasMethod(Class<?> clazz, String name) { try { if (clazz.getMethod(name) != null) { @@ -60,17 +65,18 @@ private static void assertHasMethodRemoved( Class<?> classWithFieldPresence, Class<?> classWithoutFieldPresence, String camelName) { - assertTrue(hasMethod(classWithFieldPresence, "get" + camelName)); - assertTrue(hasMethod(classWithFieldPresence, "has" + camelName)); - assertTrue(hasMethod(classWithoutFieldPresence, "get" + camelName)); - assertFalse(hasMethod(classWithoutFieldPresence, "has" + camelName)); + assertThat(hasMethod(classWithFieldPresence, "get" + camelName)).isTrue(); + assertThat(hasMethod(classWithFieldPresence, "has" + camelName)).isTrue(); + assertThat(hasMethod(classWithoutFieldPresence, "get" + camelName)).isTrue(); + assertThat(hasMethod(classWithoutFieldPresence, "has" + camelName)).isFalse(); } private static void assertHasMethodExisting(Class<?> clazz, String camelName) { - assertTrue(hasMethod(clazz, "get" + camelName)); - assertTrue(hasMethod(clazz, "has" + camelName)); + assertThat(hasMethod(clazz, "get" + camelName)).isTrue(); + assertThat(hasMethod(clazz, "has" + camelName)).isTrue(); } + @Test public void testHasMethod() { // Optional non-message fields don't have a hasFoo() method generated. assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OptionalInt32"); @@ -89,113 +95,120 @@ UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OptionalNestedEnum"); // message fields still have the hasFoo() method generated. - assertFalse(TestAllTypes.getDefaultInstance().hasOptionalNestedMessage()); - assertFalse(TestAllTypes.newBuilder().hasOptionalNestedMessage()); + assertThat(TestAllTypes.getDefaultInstance().hasOptionalNestedMessage()).isFalse(); + assertThat(TestAllTypes.newBuilder().hasOptionalNestedMessage()).isFalse(); // oneof fields support hasFoo() methods for non-message types. assertHasMethodExisting(TestAllTypes.class, "OneofUint32"); assertHasMethodExisting(TestAllTypes.class, "OneofString"); assertHasMethodExisting(TestAllTypes.class, "OneofBytes"); - assertFalse(TestAllTypes.getDefaultInstance().hasOneofNestedMessage()); - assertFalse(TestAllTypes.newBuilder().hasOneofNestedMessage()); + assertThat(TestAllTypes.getDefaultInstance().hasOneofNestedMessage()).isFalse(); + assertThat(TestAllTypes.newBuilder().hasOneofNestedMessage()).isFalse(); assertHasMethodExisting(TestAllTypes.Builder.class, "OneofUint32"); assertHasMethodExisting(TestAllTypes.Builder.class, "OneofString"); assertHasMethodExisting(TestAllTypes.Builder.class, "OneofBytes"); } + @Test public void testHasMethodForProto3Optional() throws Exception { - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalInt32()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalInt64()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalUint32()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalUint64()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalSint32()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalSint64()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalFixed32()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalFixed64()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalFloat()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalDouble()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalBool()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalString()); - assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalBytes()); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalInt32()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalInt64()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalUint32()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalUint64()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalSint32()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalSint64()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalFixed32()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalFixed64()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalFloat()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalDouble()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalBool()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalString()).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().hasOptionalBytes()).isFalse(); TestProto3Optional.Builder builder = TestProto3Optional.newBuilder().setOptionalInt32(0); - assertTrue(builder.hasOptionalInt32()); - assertTrue(builder.build().hasOptionalInt32()); + assertThat(builder.hasOptionalInt32()).isTrue(); + assertThat(builder.build().hasOptionalInt32()).isTrue(); TestProto3Optional.Builder otherBuilder = TestProto3Optional.newBuilder().setOptionalInt32(1); otherBuilder.mergeFrom(builder.build()); - assertTrue(otherBuilder.hasOptionalInt32()); - assertEquals(0, otherBuilder.getOptionalInt32()); + assertThat(otherBuilder.hasOptionalInt32()).isTrue(); + assertThat(otherBuilder.getOptionalInt32()).isEqualTo(0); TestProto3Optional.Builder builder3 = TestProto3Optional.newBuilder().setOptionalNestedEnumValue(5); - assertTrue(builder3.hasOptionalNestedEnum()); + assertThat(builder3.hasOptionalNestedEnum()).isTrue(); TestProto3Optional.Builder builder4 = TestProto3Optional.newBuilder().setOptionalNestedEnum(TestProto3Optional.NestedEnum.FOO); - assertTrue(builder4.hasOptionalNestedEnum()); + assertThat(builder4.hasOptionalNestedEnum()).isTrue(); TestProto3Optional proto = TestProto3Optional.parseFrom(builder.build().toByteArray()); - assertTrue(proto.hasOptionalInt32()); - assertTrue(proto.toBuilder().hasOptionalInt32()); + assertThat(proto.hasOptionalInt32()).isTrue(); + assertThat(proto.toBuilder().hasOptionalInt32()).isTrue(); } private static void assertProto3OptionalReflection(String name) throws Exception { FieldDescriptor fieldDescriptor = TestProto3Optional.getDescriptor().findFieldByName(name); OneofDescriptor oneofDescriptor = fieldDescriptor.getContainingOneof(); - assertNotNull(fieldDescriptor.getContainingOneof()); - assertTrue(fieldDescriptor.hasOptionalKeyword()); - assertTrue(fieldDescriptor.hasPresence()); + assertThat(fieldDescriptor.getContainingOneof()).isNotNull(); + assertThat(fieldDescriptor.hasOptionalKeyword()).isTrue(); + assertThat(fieldDescriptor.hasPresence()).isTrue(); - assertFalse(TestProto3Optional.getDefaultInstance().hasOneof(oneofDescriptor)); - assertNull(TestProto3Optional.getDefaultInstance().getOneofFieldDescriptor(oneofDescriptor)); + assertThat(TestProto3Optional.getDefaultInstance().hasOneof(oneofDescriptor)).isFalse(); + assertThat(TestProto3Optional.getDefaultInstance().getOneofFieldDescriptor(oneofDescriptor)) + .isNull(); TestProto3Optional.Builder builder = TestProto3Optional.newBuilder(); builder.setField(fieldDescriptor, fieldDescriptor.getDefaultValue()); - assertTrue(builder.hasField(fieldDescriptor)); - assertEquals(fieldDescriptor.getDefaultValue(), builder.getField(fieldDescriptor)); - assertTrue(builder.build().hasField(fieldDescriptor)); - assertEquals(fieldDescriptor.getDefaultValue(), builder.build().getField(fieldDescriptor)); - assertTrue(builder.hasOneof(oneofDescriptor)); - assertEquals(fieldDescriptor, builder.getOneofFieldDescriptor(oneofDescriptor)); - assertTrue(builder.build().hasOneof(oneofDescriptor)); - assertEquals(fieldDescriptor, builder.build().getOneofFieldDescriptor(oneofDescriptor)); + assertThat(builder.hasField(fieldDescriptor)).isTrue(); + assertThat(builder.getField(fieldDescriptor)).isEqualTo(fieldDescriptor.getDefaultValue()); + assertThat(builder.build().hasField(fieldDescriptor)).isTrue(); + assertThat(builder.build().getField(fieldDescriptor)) + .isEqualTo(fieldDescriptor.getDefaultValue()); + assertThat(builder.hasOneof(oneofDescriptor)).isTrue(); + assertThat(builder.getOneofFieldDescriptor(oneofDescriptor)).isEqualTo(fieldDescriptor); + assertThat(builder.build().hasOneof(oneofDescriptor)).isTrue(); + assertThat(builder.build().getOneofFieldDescriptor(oneofDescriptor)).isEqualTo(fieldDescriptor); TestProto3Optional.Builder otherBuilder = TestProto3Optional.newBuilder(); otherBuilder.mergeFrom(builder.build()); - assertTrue(otherBuilder.hasField(fieldDescriptor)); - assertEquals(fieldDescriptor.getDefaultValue(), otherBuilder.getField(fieldDescriptor)); + assertThat(otherBuilder.hasField(fieldDescriptor)).isTrue(); + assertThat(otherBuilder.getField(fieldDescriptor)).isEqualTo(fieldDescriptor.getDefaultValue()); TestProto3Optional proto = TestProto3Optional.parseFrom(builder.build().toByteArray()); - assertTrue(proto.hasField(fieldDescriptor)); - assertTrue(proto.toBuilder().hasField(fieldDescriptor)); + assertThat(proto.hasField(fieldDescriptor)).isTrue(); + assertThat(proto.toBuilder().hasField(fieldDescriptor)).isTrue(); DynamicMessage.Builder dynamicBuilder = DynamicMessage.newBuilder(TestProto3Optional.getDescriptor()); dynamicBuilder.setField(fieldDescriptor, fieldDescriptor.getDefaultValue()); - assertTrue(dynamicBuilder.hasField(fieldDescriptor)); - assertEquals(fieldDescriptor.getDefaultValue(), dynamicBuilder.getField(fieldDescriptor)); - assertTrue(dynamicBuilder.build().hasField(fieldDescriptor)); - assertEquals( - fieldDescriptor.getDefaultValue(), dynamicBuilder.build().getField(fieldDescriptor)); - assertTrue(dynamicBuilder.hasOneof(oneofDescriptor)); - assertEquals(fieldDescriptor, dynamicBuilder.getOneofFieldDescriptor(oneofDescriptor)); - assertTrue(dynamicBuilder.build().hasOneof(oneofDescriptor)); - assertEquals(fieldDescriptor, dynamicBuilder.build().getOneofFieldDescriptor(oneofDescriptor)); + assertThat(dynamicBuilder.hasField(fieldDescriptor)).isTrue(); + assertThat(dynamicBuilder.getField(fieldDescriptor)) + .isEqualTo(fieldDescriptor.getDefaultValue()); + assertThat(dynamicBuilder.build().hasField(fieldDescriptor)).isTrue(); + assertThat(dynamicBuilder.build().getField(fieldDescriptor)) + .isEqualTo(fieldDescriptor.getDefaultValue()); + assertThat(dynamicBuilder.hasOneof(oneofDescriptor)).isTrue(); + assertThat(dynamicBuilder.getOneofFieldDescriptor(oneofDescriptor)).isEqualTo(fieldDescriptor); + assertThat(dynamicBuilder.build().hasOneof(oneofDescriptor)).isTrue(); + assertThat(dynamicBuilder.build().getOneofFieldDescriptor(oneofDescriptor)) + .isEqualTo(fieldDescriptor); DynamicMessage.Builder otherDynamicBuilder = DynamicMessage.newBuilder(TestProto3Optional.getDescriptor()); otherDynamicBuilder.mergeFrom(dynamicBuilder.build()); - assertTrue(otherDynamicBuilder.hasField(fieldDescriptor)); - assertEquals(fieldDescriptor.getDefaultValue(), otherDynamicBuilder.getField(fieldDescriptor)); + assertThat(otherDynamicBuilder.hasField(fieldDescriptor)).isTrue(); + assertThat(otherDynamicBuilder.getField(fieldDescriptor)) + .isEqualTo(fieldDescriptor.getDefaultValue()); DynamicMessage dynamicProto = DynamicMessage.parseFrom(TestProto3Optional.getDescriptor(), builder.build().toByteArray()); - assertTrue(dynamicProto.hasField(fieldDescriptor)); - assertTrue(dynamicProto.toBuilder().hasField(fieldDescriptor)); + assertThat(dynamicProto.hasField(fieldDescriptor)).isTrue(); + assertThat(dynamicProto.toBuilder().hasField(fieldDescriptor)).isTrue(); } + @Test public void testProto3Optional_reflection() throws Exception { assertProto3OptionalReflection("optional_int32"); assertProto3OptionalReflection("optional_int64"); @@ -212,6 +225,7 @@ assertProto3OptionalReflection("optional_bytes"); } + @Test public void testOneofEquals() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestAllTypes message1 = builder.build(); @@ -219,29 +233,31 @@ // messages should be different when check with oneof case. builder.setOneofUint32(0); TestAllTypes message2 = builder.build(); - assertFalse(message1.equals(message2)); + assertThat(message1.equals(message2)).isFalse(); } + @Test public void testLazyField() throws Exception { // Test default constructed message. TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestAllTypes message = builder.build(); - assertFalse(message.hasOptionalLazyMessage()); - assertEquals(0, message.getSerializedSize()); - assertEquals(ByteString.EMPTY, message.toByteString()); + assertThat(message.hasOptionalLazyMessage()).isFalse(); + assertThat(message.getSerializedSize()).isEqualTo(0); + assertThat(message.toByteString()).isEqualTo(ByteString.EMPTY); // Set default instance to the field. builder.setOptionalLazyMessage(TestAllTypes.NestedMessage.getDefaultInstance()); message = builder.build(); - assertTrue(message.hasOptionalLazyMessage()); - assertEquals(2, message.getSerializedSize()); + assertThat(message.hasOptionalLazyMessage()).isTrue(); + assertThat(message.getSerializedSize()).isEqualTo(2); // Test parse zero-length from wire sets the presence. TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteString()); - assertTrue(parsed.hasOptionalLazyMessage()); - assertEquals(message.getOptionalLazyMessage(), parsed.getOptionalLazyMessage()); + assertThat(parsed.hasOptionalLazyMessage()).isTrue(); + assertThat(parsed.getOptionalLazyMessage()).isEqualTo(message.getOptionalLazyMessage()); } + @Test public void testFieldPresence() { // Optional non-message fields set to their default value are treated the // same way as not set. @@ -253,7 +269,7 @@ builder.setOptionalBytes(ByteString.EMPTY); builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.FOO); TestAllTypes message = builder.build(); - assertEquals(0, message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(0); // mergeFrom() will ignore such fields. TestAllTypes.Builder a = TestAllTypes.newBuilder(); @@ -268,19 +284,20 @@ b.setOptionalNestedEnum(TestAllTypes.NestedEnum.FOO); a.mergeFrom(b.build()); message = a.build(); - assertEquals(1, message.getOptionalInt32()); - assertEquals("x", message.getOptionalString()); - assertEquals(ByteString.copyFromUtf8("y"), message.getOptionalBytes()); - assertEquals(TestAllTypes.NestedEnum.BAR, message.getOptionalNestedEnum()); + assertThat(message.getOptionalInt32()).isEqualTo(1); + assertThat(message.getOptionalString()).isEqualTo("x"); + assertThat(message.getOptionalBytes()).isEqualTo(ByteString.copyFromUtf8("y")); + assertThat(message.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.BAR); // equals()/hashCode() should produce the same results. TestAllTypes empty = TestAllTypes.getDefaultInstance(); message = builder.build(); - assertEquals(message, empty); - assertEquals(empty, message); - assertEquals(empty.hashCode(), message.hashCode()); + assertThat(empty).isEqualTo(message); + assertThat(message).isEqualTo(empty); + assertThat(message.hashCode()).isEqualTo(empty.hashCode()); } + @Test public void testFieldPresenceByReflection() { Descriptor descriptor = TestAllTypes.getDescriptor(); FieldDescriptor optionalInt32Field = descriptor.findFieldByName("optional_int32"); @@ -290,11 +307,11 @@ // Field not present. TestAllTypes message = TestAllTypes.getDefaultInstance(); - assertFalse(message.hasField(optionalInt32Field)); - assertFalse(message.hasField(optionalStringField)); - assertFalse(message.hasField(optionalBytesField)); - assertFalse(message.hasField(optionalNestedEnumField)); - assertEquals(0, message.getAllFields().size()); + assertThat(message.hasField(optionalInt32Field)).isFalse(); + assertThat(message.hasField(optionalStringField)).isFalse(); + assertThat(message.hasField(optionalBytesField)).isFalse(); + assertThat(message.hasField(optionalNestedEnumField)).isFalse(); + assertThat(message.getAllFields()).isEmpty(); // Field set to default value is seen as not present. message = @@ -304,11 +321,11 @@ .setOptionalBytes(ByteString.EMPTY) .setOptionalNestedEnum(TestAllTypes.NestedEnum.FOO) .build(); - assertFalse(message.hasField(optionalInt32Field)); - assertFalse(message.hasField(optionalStringField)); - assertFalse(message.hasField(optionalBytesField)); - assertFalse(message.hasField(optionalNestedEnumField)); - assertEquals(0, message.getAllFields().size()); + assertThat(message.hasField(optionalInt32Field)).isFalse(); + assertThat(message.hasField(optionalStringField)).isFalse(); + assertThat(message.hasField(optionalBytesField)).isFalse(); + assertThat(message.hasField(optionalNestedEnumField)).isFalse(); + assertThat(message.getAllFields()).isEmpty(); // Field set to non-default value is seen as present. message = @@ -318,13 +335,14 @@ .setOptionalBytes(ByteString.copyFromUtf8("y")) .setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR) .build(); - assertTrue(message.hasField(optionalInt32Field)); - assertTrue(message.hasField(optionalStringField)); - assertTrue(message.hasField(optionalBytesField)); - assertTrue(message.hasField(optionalNestedEnumField)); - assertEquals(4, message.getAllFields().size()); + assertThat(message.hasField(optionalInt32Field)).isTrue(); + assertThat(message.hasField(optionalStringField)).isTrue(); + assertThat(message.hasField(optionalBytesField)).isTrue(); + assertThat(message.hasField(optionalNestedEnumField)).isTrue(); + assertThat(message.getAllFields()).hasSize(4); } + @Test public void testFieldPresenceDynamicMessage() { Descriptor descriptor = TestAllTypes.getDescriptor(); FieldDescriptor optionalInt32Field = descriptor.findFieldByName("optional_int32"); @@ -338,11 +356,11 @@ DynamicMessage defaultInstance = DynamicMessage.getDefaultInstance(descriptor); // Field not present. DynamicMessage message = defaultInstance.newBuilderForType().build(); - assertFalse(message.hasField(optionalInt32Field)); - assertFalse(message.hasField(optionalStringField)); - assertFalse(message.hasField(optionalBytesField)); - assertFalse(message.hasField(optionalNestedEnumField)); - assertEquals(0, message.getAllFields().size()); + assertThat(message.hasField(optionalInt32Field)).isFalse(); + assertThat(message.hasField(optionalStringField)).isFalse(); + assertThat(message.hasField(optionalBytesField)).isFalse(); + assertThat(message.hasField(optionalNestedEnumField)).isFalse(); + assertThat(message.getAllFields()).isEmpty(); // Field set to non-default value is seen as present. message = @@ -353,11 +371,11 @@ .setField(optionalBytesField, ByteString.copyFromUtf8("y")) .setField(optionalNestedEnumField, nonDefaultEnumValueDescriptor) .build(); - assertTrue(message.hasField(optionalInt32Field)); - assertTrue(message.hasField(optionalStringField)); - assertTrue(message.hasField(optionalBytesField)); - assertTrue(message.hasField(optionalNestedEnumField)); - assertEquals(4, message.getAllFields().size()); + assertThat(message.hasField(optionalInt32Field)).isTrue(); + assertThat(message.hasField(optionalStringField)).isTrue(); + assertThat(message.hasField(optionalBytesField)).isTrue(); + assertThat(message.hasField(optionalNestedEnumField)).isTrue(); + assertThat(message.getAllFields()).hasSize(4); // Field set to default value is seen as not present. message = @@ -368,36 +386,38 @@ .setField(optionalBytesField, ByteString.EMPTY) .setField(optionalNestedEnumField, defaultEnumValueDescriptor) .build(); - assertFalse(message.hasField(optionalInt32Field)); - assertFalse(message.hasField(optionalStringField)); - assertFalse(message.hasField(optionalBytesField)); - assertFalse(message.hasField(optionalNestedEnumField)); - assertEquals(0, message.getAllFields().size()); + assertThat(message.hasField(optionalInt32Field)).isFalse(); + assertThat(message.hasField(optionalStringField)).isFalse(); + assertThat(message.hasField(optionalBytesField)).isFalse(); + assertThat(message.hasField(optionalNestedEnumField)).isFalse(); + assertThat(message.getAllFields()).isEmpty(); } + @Test public void testMessageField() { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - assertFalse(builder.hasOptionalNestedMessage()); - assertFalse(builder.build().hasOptionalNestedMessage()); + assertThat(builder.hasOptionalNestedMessage()).isFalse(); + assertThat(builder.build().hasOptionalNestedMessage()).isFalse(); TestAllTypes.NestedMessage.Builder nestedBuilder = builder.getOptionalNestedMessageBuilder(); - assertTrue(builder.hasOptionalNestedMessage()); - assertTrue(builder.build().hasOptionalNestedMessage()); + assertThat(builder.hasOptionalNestedMessage()).isTrue(); + assertThat(builder.build().hasOptionalNestedMessage()).isTrue(); nestedBuilder.setValue(1); - assertEquals(1, builder.build().getOptionalNestedMessage().getValue()); + assertThat(builder.build().getOptionalNestedMessage().getValue()).isEqualTo(1); builder.clearOptionalNestedMessage(); - assertFalse(builder.hasOptionalNestedMessage()); - assertFalse(builder.build().hasOptionalNestedMessage()); + assertThat(builder.hasOptionalNestedMessage()).isFalse(); + assertThat(builder.build().hasOptionalNestedMessage()).isFalse(); // Unlike non-message fields, if we set a message field to its default value (i.e., // default instance), the field should be seen as present. builder.setOptionalNestedMessage(TestAllTypes.NestedMessage.getDefaultInstance()); - assertTrue(builder.hasOptionalNestedMessage()); - assertTrue(builder.build().hasOptionalNestedMessage()); + assertThat(builder.hasOptionalNestedMessage()).isTrue(); + assertThat(builder.build().hasOptionalNestedMessage()).isTrue(); } + @Test public void testSerializeAndParse() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); builder.setOptionalInt32(1234); @@ -409,20 +429,21 @@ ByteString data = builder.build().toByteString(); TestAllTypes message = TestAllTypes.parseFrom(data); - assertEquals(1234, message.getOptionalInt32()); - assertEquals("hello", message.getOptionalString()); + assertThat(message.getOptionalInt32()).isEqualTo(1234); + assertThat(message.getOptionalString()).isEqualTo("hello"); // Fields not set will have the default value. - assertEquals(ByteString.EMPTY, message.getOptionalBytes()); - assertEquals(TestAllTypes.NestedEnum.FOO, message.getOptionalNestedEnum()); + assertThat(message.getOptionalBytes()).isEqualTo(ByteString.EMPTY); + assertThat(message.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.FOO); // The message field is set despite that it's set with a default instance. - assertTrue(message.hasOptionalNestedMessage()); - assertEquals(0, message.getOptionalNestedMessage().getValue()); + assertThat(message.hasOptionalNestedMessage()).isTrue(); + assertThat(message.getOptionalNestedMessage().getValue()).isEqualTo(0); // The oneof field set to its default value is also present. - assertEquals(TestAllTypes.OneofFieldCase.ONEOF_INT32, message.getOneofFieldCase()); + assertThat(message.getOneofFieldCase()).isEqualTo(TestAllTypes.OneofFieldCase.ONEOF_INT32); } // Regression test for b/16173397 // Make sure we haven't screwed up the code generation for repeated fields. + @Test public void testRepeatedFields() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); builder.setOptionalInt32(1234); @@ -434,49 +455,50 @@ ByteString data = builder.build().toByteString(); TestOptionalFieldsOnly optionalOnlyMessage = TestOptionalFieldsOnly.parseFrom(data); - assertEquals(1234, optionalOnlyMessage.getOptionalInt32()); - assertEquals("hello", optionalOnlyMessage.getOptionalString()); - assertTrue(optionalOnlyMessage.hasOptionalNestedMessage()); - assertEquals(0, optionalOnlyMessage.getOptionalNestedMessage().getValue()); + assertThat(optionalOnlyMessage.getOptionalInt32()).isEqualTo(1234); + assertThat(optionalOnlyMessage.getOptionalString()).isEqualTo("hello"); + assertThat(optionalOnlyMessage.hasOptionalNestedMessage()).isTrue(); + assertThat(optionalOnlyMessage.getOptionalNestedMessage().getValue()).isEqualTo(0); TestRepeatedFieldsOnly repeatedOnlyMessage = TestRepeatedFieldsOnly.parseFrom(data); - assertEquals(1, repeatedOnlyMessage.getRepeatedInt32Count()); - assertEquals(4321, repeatedOnlyMessage.getRepeatedInt32(0)); - assertEquals(1, repeatedOnlyMessage.getRepeatedStringCount()); - assertEquals("world", repeatedOnlyMessage.getRepeatedString(0)); - assertEquals(1, repeatedOnlyMessage.getRepeatedNestedMessageCount()); - assertEquals(0, repeatedOnlyMessage.getRepeatedNestedMessage(0).getValue()); + assertThat(repeatedOnlyMessage.getRepeatedInt32Count()).isEqualTo(1); + assertThat(repeatedOnlyMessage.getRepeatedInt32(0)).isEqualTo(4321); + assertThat(repeatedOnlyMessage.getRepeatedStringCount()).isEqualTo(1); + assertThat(repeatedOnlyMessage.getRepeatedString(0)).isEqualTo("world"); + assertThat(repeatedOnlyMessage.getRepeatedNestedMessageCount()).isEqualTo(1); + assertThat(repeatedOnlyMessage.getRepeatedNestedMessage(0).getValue()).isEqualTo(0); } + @Test public void testIsInitialized() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); // Test optional proto2 message fields. UnittestProto.TestRequired.Builder proto2Builder = builder.getOptionalProto2MessageBuilder(); - assertFalse(builder.isInitialized()); - assertFalse(builder.buildPartial().isInitialized()); + assertThat(builder.isInitialized()).isFalse(); + assertThat(builder.buildPartial().isInitialized()).isFalse(); proto2Builder.setA(1).setB(2).setC(3); - assertTrue(builder.isInitialized()); - assertTrue(builder.buildPartial().isInitialized()); + assertThat(builder.isInitialized()).isTrue(); + assertThat(builder.buildPartial().isInitialized()).isTrue(); // Test oneof proto2 message fields. proto2Builder = builder.getOneofProto2MessageBuilder(); - assertFalse(builder.isInitialized()); - assertFalse(builder.buildPartial().isInitialized()); + assertThat(builder.isInitialized()).isFalse(); + assertThat(builder.buildPartial().isInitialized()).isFalse(); proto2Builder.setA(1).setB(2).setC(3); - assertTrue(builder.isInitialized()); - assertTrue(builder.buildPartial().isInitialized()); + assertThat(builder.isInitialized()).isTrue(); + assertThat(builder.buildPartial().isInitialized()).isTrue(); // Test repeated proto2 message fields. proto2Builder = builder.addRepeatedProto2MessageBuilder(); - assertFalse(builder.isInitialized()); - assertFalse(builder.buildPartial().isInitialized()); + assertThat(builder.isInitialized()).isFalse(); + assertThat(builder.buildPartial().isInitialized()).isFalse(); proto2Builder.setA(1).setB(2).setC(3); - assertTrue(builder.isInitialized()); - assertTrue(builder.buildPartial().isInitialized()); + assertThat(builder.isInitialized()).isTrue(); + assertThat(builder.buildPartial().isInitialized()).isTrue(); } }
diff --git a/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java b/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java index 091ac5b..8fe8508 100644 --- a/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java
@@ -30,39 +30,44 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static java.util.Arrays.asList; import com.google.protobuf.Internal.FloatList; import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.Iterator; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Tests for {@link FloatArrayList}. - * - * @author dweis@google.com (Daniel Weis) - */ -public class FloatArrayListTest extends TestCase { +/** Tests for {@link FloatArrayList}. */ +@RunWith(JUnit4.class) +public class FloatArrayListTest { private static final FloatArrayList UNARY_LIST = newImmutableFloatArrayList(1); private static final FloatArrayList TERTIARY_LIST = newImmutableFloatArrayList(1, 2, 3); private FloatArrayList list; - @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { list = new FloatArrayList(); } + @Test public void testEmptyListReturnsSameInstance() { - assertSame(FloatArrayList.emptyList(), FloatArrayList.emptyList()); + assertThat(FloatArrayList.emptyList()).isSameInstanceAs(FloatArrayList.emptyList()); } + @Test public void testEmptyListIsImmutable() { assertImmutable(FloatArrayList.emptyList()); } + @Test public void testMakeImmutable() { list.addFloat(3); list.addFloat(4); @@ -72,19 +77,20 @@ assertImmutable(list); } + @Test public void testModificationWithIteration() { list.addAll(asList(1F, 2F, 3F, 4F)); Iterator<Float> iterator = list.iterator(); - assertEquals(4, list.size()); - assertEquals(1F, (float) list.get(0), 0.0f); - assertEquals(1F, (float) iterator.next(), 0.0f); + assertThat(list).hasSize(4); + assertThat((float) list.get(0)).isEqualTo(1F); + assertThat((float) iterator.next()).isEqualTo(1F); list.set(0, 1F); - assertEquals(2F, (float) iterator.next(), 0.0f); + assertThat((float) iterator.next()).isEqualTo(2F); list.remove(0); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail(); } catch (ConcurrentModificationException e) { // expected } @@ -93,191 +99,211 @@ list.add(0, 0F); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail(); } catch (ConcurrentModificationException e) { // expected } } + @Test public void testGet() { - assertEquals(1F, (float) TERTIARY_LIST.get(0), 0.0f); - assertEquals(2F, (float) TERTIARY_LIST.get(1), 0.0f); - assertEquals(3F, (float) TERTIARY_LIST.get(2), 0.0f); + assertThat((float) TERTIARY_LIST.get(0)).isEqualTo(1F); + assertThat((float) TERTIARY_LIST.get(1)).isEqualTo(2F); + assertThat((float) TERTIARY_LIST.get(2)).isEqualTo(3F); try { TERTIARY_LIST.get(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { TERTIARY_LIST.get(3); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testGetFloat() { - assertEquals(1F, TERTIARY_LIST.getFloat(0), 0.0f); - assertEquals(2F, TERTIARY_LIST.getFloat(1), 0.0f); - assertEquals(3F, TERTIARY_LIST.getFloat(2), 0.0f); + assertThat(TERTIARY_LIST.getFloat(0)).isEqualTo(1F); + assertThat(TERTIARY_LIST.getFloat(1)).isEqualTo(2F); + assertThat(TERTIARY_LIST.getFloat(2)).isEqualTo(3F); try { TERTIARY_LIST.get(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { TERTIARY_LIST.get(3); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testIndexOf_nullElement() { - assertEquals(-1, TERTIARY_LIST.indexOf(null)); + assertThat(TERTIARY_LIST.indexOf(null)).isEqualTo(-1); } + @Test public void testIndexOf_incompatibleElementType() { - assertEquals(-1, TERTIARY_LIST.indexOf(new Object())); + assertThat(TERTIARY_LIST.indexOf(new Object())).isEqualTo(-1); } + @Test public void testIndexOf_notInList() { - assertEquals(-1, UNARY_LIST.indexOf(2F)); + assertThat(UNARY_LIST.indexOf(2F)).isEqualTo(-1); } + @Test public void testIndexOf_notInListWithDuplicates() { FloatArrayList listWithDupes = newImmutableFloatArrayList(1F, 1F); - assertEquals(-1, listWithDupes.indexOf(2F)); + assertThat(listWithDupes.indexOf(2F)).isEqualTo(-1); } + @Test public void testIndexOf_inList() { - assertEquals(1, TERTIARY_LIST.indexOf(2F)); + assertThat(TERTIARY_LIST.indexOf(2F)).isEqualTo(1); } + @Test public void testIndexOf_inListWithDuplicates_matchAtHead() { FloatArrayList listWithDupes = newImmutableFloatArrayList(1F, 1F, 2F); - assertEquals(0, listWithDupes.indexOf(1F)); + assertThat(listWithDupes.indexOf(1F)).isEqualTo(0); } + @Test public void testIndexOf_inListWithDuplicates_matchMidList() { FloatArrayList listWithDupes = newImmutableFloatArrayList(2F, 1F, 1F, 2F); - assertEquals(1, listWithDupes.indexOf(1F)); + assertThat(listWithDupes.indexOf(1F)).isEqualTo(1); } + @Test public void testContains_nullElement() { - assertEquals(false, TERTIARY_LIST.contains(null)); + assertThat(TERTIARY_LIST).doesNotContain(null); } + @Test public void testContains_incompatibleElementType() { - assertEquals(false, TERTIARY_LIST.contains(new Object())); + assertThat(TERTIARY_LIST).doesNotContain(new Object()); } + @Test public void testContains_notInList() { - assertEquals(false, UNARY_LIST.contains(2F)); + assertThat(UNARY_LIST).doesNotContain(2F); } + @Test public void testContains_notInListWithDuplicates() { FloatArrayList listWithDupes = newImmutableFloatArrayList(1F, 1F); - assertEquals(false, listWithDupes.contains(2F)); + assertThat(listWithDupes).doesNotContain(2F); } + @Test public void testContains_inList() { - assertEquals(true, TERTIARY_LIST.contains(2F)); + assertThat(TERTIARY_LIST).contains(2F); } + @Test public void testContains_inListWithDuplicates_matchAtHead() { FloatArrayList listWithDupes = newImmutableFloatArrayList(1F, 1F, 2F); - assertEquals(true, listWithDupes.contains(1F)); + assertThat(listWithDupes).contains(1F); } + @Test public void testContains_inListWithDuplicates_matchMidList() { FloatArrayList listWithDupes = newImmutableFloatArrayList(2F, 1F, 1F, 2F); - assertEquals(true, listWithDupes.contains(1F)); + assertThat(listWithDupes).contains(1F); } + @Test public void testSize() { - assertEquals(0, FloatArrayList.emptyList().size()); - assertEquals(1, UNARY_LIST.size()); - assertEquals(3, TERTIARY_LIST.size()); + assertThat(FloatArrayList.emptyList()).isEmpty(); + assertThat(UNARY_LIST).hasSize(1); + assertThat(TERTIARY_LIST).hasSize(3); list.addFloat(3); list.addFloat(4); list.addFloat(6); list.addFloat(8); - assertEquals(4, list.size()); + assertThat(list).hasSize(4); list.remove(0); - assertEquals(3, list.size()); + assertThat(list).hasSize(3); list.add(17F); - assertEquals(4, list.size()); + assertThat(list).hasSize(4); } + @Test public void testSet() { list.addFloat(2); list.addFloat(4); - assertEquals(2F, (float) list.set(0, 3F), 0.0f); - assertEquals(3F, list.getFloat(0), 0.0f); + assertThat((float) list.set(0, 3F)).isEqualTo(2F); + assertThat(list.getFloat(0)).isEqualTo(3F); - assertEquals(4F, (float) list.set(1, 0F), 0.0f); - assertEquals(0F, list.getFloat(1), 0.0f); + assertThat((float) list.set(1, 0F)).isEqualTo(4F); + assertThat(list.getFloat(1)).isEqualTo(0F); try { list.set(-1, 0F); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.set(2, 0F); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testSetFloat() { list.addFloat(1); list.addFloat(3); - assertEquals(1F, list.setFloat(0, 0), 0.0f); - assertEquals(0F, list.getFloat(0), 0.0f); + assertThat(list.setFloat(0, 0)).isEqualTo(1F); + assertThat(list.getFloat(0)).isEqualTo(0F); - assertEquals(3F, list.setFloat(1, 0), 0.0f); - assertEquals(0F, list.getFloat(1), 0.0f); + assertThat(list.setFloat(1, 0)).isEqualTo(3F); + assertThat(list.getFloat(1)).isEqualTo(0F); try { list.setFloat(-1, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.setFloat(2, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testAdd() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); - assertTrue(list.add(2F)); - assertEquals(asList(2F), list); + assertThat(list.add(2F)).isTrue(); + assertThat(list).containsExactly(2F); - assertTrue(list.add(3F)); + assertThat(list.add(3F)).isTrue(); list.add(0, 4F); - assertEquals(asList(4F, 2F, 3F), list); + assertThat(list).containsExactly(4F, 2F, 3F).inOrder(); list.add(0, 1F); list.add(0, 0F); @@ -285,7 +311,7 @@ for (int i = 0; i < 6; i++) { list.add(Float.valueOf(5 + i)); } - assertEquals(asList(0F, 1F, 4F, 2F, 3F, 5F, 6F, 7F, 8F, 9F, 10F), list); + assertThat(list).containsExactly(0F, 1F, 4F, 2F, 3F, 5F, 6F, 7F, 8F, 9F, 10F).inOrder(); try { list.add(-1, 5F); @@ -300,92 +326,100 @@ } } + @Test public void testAddFloat() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); list.addFloat(2); - assertEquals(asList(2F), list); + assertThat(list).containsExactly(2F); list.addFloat(3); - assertEquals(asList(2F, 3F), list); + assertThat(list).containsExactly(2F, 3F).inOrder(); } + @Test public void testAddAll() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); - assertTrue(list.addAll(Collections.singleton(1F))); - assertEquals(1, list.size()); - assertEquals(1F, (float) list.get(0), 0.0f); - assertEquals(1F, list.getFloat(0), 0.0f); + assertThat(list.addAll(Collections.singleton(1F))).isTrue(); + assertThat(list).hasSize(1); + assertThat((float) list.get(0)).isEqualTo(1F); + assertThat(list.getFloat(0)).isEqualTo(1F); - assertTrue(list.addAll(asList(2F, 3F, 4F, 5F, 6F))); - assertEquals(asList(1F, 2F, 3F, 4F, 5F, 6F), list); + assertThat(list.addAll(asList(2F, 3F, 4F, 5F, 6F))).isTrue(); + assertThat(list).containsExactly(1F, 2F, 3F, 4F, 5F, 6F).inOrder(); - assertTrue(list.addAll(TERTIARY_LIST)); - assertEquals(asList(1F, 2F, 3F, 4F, 5F, 6F, 1F, 2F, 3F), list); + assertThat(list.addAll(TERTIARY_LIST)).isTrue(); + assertThat(list).containsExactly(1F, 2F, 3F, 4F, 5F, 6F, 1F, 2F, 3F).inOrder(); - assertFalse(list.addAll(Collections.<Float>emptyList())); - assertFalse(list.addAll(FloatArrayList.emptyList())); + assertThat(list.addAll(Collections.<Float>emptyList())).isFalse(); + assertThat(list.addAll(FloatArrayList.emptyList())).isFalse(); } + @Test public void testEquals() { FloatArrayList list1 = new FloatArrayList(); FloatArrayList list2 = new FloatArrayList(); list1.addFloat(Float.intBitsToFloat(0xff800001)); list2.addFloat(Float.intBitsToFloat(0xff800002)); - assertEquals(list1, list2); + assertThat(list1).isEqualTo(list2); } + @Test public void testRemove() { list.addAll(TERTIARY_LIST); - assertEquals(1F, (float) list.remove(0), 0.0f); - assertEquals(asList(2F, 3F), list); + assertThat((float) list.remove(0)).isEqualTo(1F); + assertThat(list).containsExactly(2F, 3F).inOrder(); - assertTrue(list.remove(Float.valueOf(3))); - assertEquals(asList(2F), list); + assertThat(list.remove(Float.valueOf(3))).isTrue(); + assertThat(list).containsExactly(2F); - assertFalse(list.remove(Float.valueOf(3))); - assertEquals(asList(2F), list); + assertThat(list.remove(Float.valueOf(3))).isFalse(); + assertThat(list).containsExactly(2F); - assertEquals(2F, (float) list.remove(0), 0.0f); - assertEquals(asList(), list); + assertThat((float) list.remove(0)).isEqualTo(2F); + assertThat(list).isEmpty(); try { list.remove(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.remove(0); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testRemoveEnd_listAtCapacity() { FloatList toRemove = FloatArrayList.emptyList().mutableCopyWithCapacity(1); toRemove.addFloat(3); toRemove.remove(0); - assertEquals(0, toRemove.size()); + assertThat(toRemove).isEmpty(); } + @Test public void testRemove_listAtCapacity() { FloatList toRemove = FloatArrayList.emptyList().mutableCopyWithCapacity(2); toRemove.addFloat(3); toRemove.addFloat(4); toRemove.remove(0); - assertEquals(1, toRemove.size()); - assertEquals(4F, (float) toRemove.get(0)); + assertThat(toRemove).hasSize(1); + assertThat((float) toRemove.get(0)).isEqualTo(4F); } + @Test public void testSublistRemoveEndOfCapacity() { FloatList toRemove = FloatArrayList.emptyList().mutableCopyWithCapacity(1); toRemove.addFloat(3); toRemove.subList(0, 1).clear(); - assertEquals(0, toRemove.size()); + assertThat(toRemove).isEmpty(); } private void assertImmutable(FloatList list) { @@ -395,147 +429,147 @@ try { list.add(1F); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.add(0, 1F); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(Collections.<Float>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(Collections.singletonList(1F)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(new FloatArrayList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, Collections.singleton(1F)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, Collections.<Float>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addFloat(0); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.clear(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.remove(1); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.remove(new Object()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(Collections.<Float>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(Collections.singleton(1F)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(Collections.<Float>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(Collections.singleton(1F)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.set(0, 0F); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.setFloat(0, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected }
diff --git a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java index 840e13e..fbba612 100644 --- a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java +++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -30,6 +30,9 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.test.UnittestImport; @@ -68,24 +71,27 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -import junit.framework.TestCase; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Unit test for generated messages and generated code. See also {@link MessageTest}, which tests * some generated message functionality. - * - * @author kenton@google.com Kenton Varda */ @SuppressWarnings({"ProtoBuilderReturnValueIgnored", "ReturnValueIgnored"}) -public class GeneratedMessageTest extends TestCase { +@RunWith(JUnit4.class) +public class GeneratedMessageTest { TestUtil.ReflectionTester reflectionTester = new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null); - @Override + @After public void tearDown() { GeneratedMessageV3.setAlwaysUseFieldBuildersForTesting(false); } + @Test public void testGetFieldBuilderForExtensionField() { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); Message.Builder fieldBuilder = @@ -94,18 +100,17 @@ FieldDescriptor field = NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); fieldBuilder.setField(field, expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()); + assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) + .isEqualTo(expected); // fieldBuilder still updates the builder after builder build() has been called. expected += 100; fieldBuilder.setField(field, expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()); + assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) + .isEqualTo(expected); } + @Test public void testGetFieldBuilderWithExistingMessage() { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); builder.setExtension( @@ -117,18 +122,17 @@ FieldDescriptor field = NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); fieldBuilder.setField(field, expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()); + assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) + .isEqualTo(expected); // fieldBuilder still updates the builder after builder build() has been called. expected += 100; fieldBuilder.setField(field, expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()); + assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) + .isEqualTo(expected); } + @Test public void testGetFieldBuilderWithExistingBuilder() { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); NestedMessage.Builder nestedMessageBuilder = NestedMessage.newBuilder().setBb(123); @@ -140,25 +144,23 @@ FieldDescriptor field = NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); fieldBuilder.setField(field, expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()); + assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) + .isEqualTo(expected); // Existing nestedMessageBuilder will also update builder. expected += 100; nestedMessageBuilder.setBb(expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()); + assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) + .isEqualTo(expected); // fieldBuilder still updates the builder. expected += 100; fieldBuilder.setField(field, expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()); + assertThat(builder.build().getExtension(UnittestProto.optionalNestedMessageExtension).getBb()) + .isEqualTo(expected); } + @Test public void testGetRepeatedFieldBuilderForExtensionField() { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); builder.addExtension( @@ -171,18 +173,19 @@ FieldDescriptor field = NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); fieldBuilder.setField(field, expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()); + assertThat( + builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()) + .isEqualTo(expected); // fieldBuilder still updates the builder after builder build() has been called. expected += 100; fieldBuilder.setField(field, expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()); + assertThat( + builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()) + .isEqualTo(expected); } + @Test public void testGetRepeatedFieldBuilderForExistingBuilder() { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); NestedMessage.Builder nestedMessageBuilder = NestedMessage.newBuilder().setBb(123); @@ -195,59 +198,61 @@ FieldDescriptor field = NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); fieldBuilder.setField(field, expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()); + assertThat( + builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()) + .isEqualTo(expected); // Existing nestedMessageBuilder will also update builder. expected += 100; nestedMessageBuilder.setBb(expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()); + assertThat( + builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()) + .isEqualTo(expected); // fieldBuilder still updates the builder. expected += 100; fieldBuilder.setField(field, expected); - assertEquals( - expected, - builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()); + assertThat( + builder.build().getExtension(UnittestProto.repeatedNestedMessageExtension, 0).getBb()) + .isEqualTo(expected); } + @Test public void testGetExtensionFieldOutOfBound() { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); try { builder.getRepeatedField(UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0); - fail("Expected IndexOutOfBoundsException to be thrown"); + assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); } catch (IndexOutOfBoundsException expected) { } try { builder.getExtension(UnittestProto.repeatedNestedMessageExtension, 0); - fail("Expected IndexOutOfBoundsException to be thrown"); + assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); } catch (IndexOutOfBoundsException expected) { } TestAllExtensions extensionsMessage = builder.build(); try { extensionsMessage.getRepeatedField( UnittestProto.repeatedNestedMessageExtension.getDescriptor(), 0); - fail("Expected IndexOutOfBoundsException to be thrown"); + assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); } catch (IndexOutOfBoundsException expected) { } try { extensionsMessage.getExtension(UnittestProto.repeatedNestedMessageExtension, 0); - fail("Expected IndexOutOfBoundsException to be thrown"); + assertWithMessage("Expected IndexOutOfBoundsException to be thrown").fail(); } catch (IndexOutOfBoundsException expected) { } } + @Test public void testDefaultInstance() throws Exception { - assertSame( - TestAllTypes.getDefaultInstance(), - TestAllTypes.getDefaultInstance().getDefaultInstanceForType()); - assertSame( - TestAllTypes.getDefaultInstance(), TestAllTypes.newBuilder().getDefaultInstanceForType()); + assertThat(TestAllTypes.getDefaultInstance()) + .isSameInstanceAs(TestAllTypes.getDefaultInstance().getDefaultInstanceForType()); + assertThat(TestAllTypes.getDefaultInstance()) + .isSameInstanceAs(TestAllTypes.newBuilder().getDefaultInstanceForType()); } + @Test public void testMessageOrBuilder() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); @@ -255,6 +260,7 @@ TestUtil.assertAllFieldsSet(message); } + @Test public void testUsingBuilderMultipleTimes() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); // primitive field scalar and repeated @@ -269,12 +275,12 @@ TestAllTypes value1 = builder.build(); - assertEquals(100, value1.getOptionalSfixed64()); - assertEquals(100, value1.getRepeatedInt32(0)); - assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, value1.getOptionalImportEnum()); - assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, value1.getRepeatedImportEnum(0)); - assertEquals(1, value1.getOptionalForeignMessage().getC()); - assertEquals(1, value1.getRepeatedForeignMessage(0).getC()); + assertThat(value1.getOptionalSfixed64()).isEqualTo(100); + assertThat(value1.getRepeatedInt32(0)).isEqualTo(100); + assertThat(value1.getOptionalImportEnum()).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR); + assertThat(value1.getRepeatedImportEnum(0)).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR); + assertThat(value1.getOptionalForeignMessage().getC()).isEqualTo(1); + assertThat(value1.getRepeatedForeignMessage(0).getC()).isEqualTo(1); // Make sure that builder didn't update previously created values builder.setOptionalSfixed64(200); @@ -287,22 +293,23 @@ TestAllTypes value2 = builder.build(); // Make sure value1 didn't change. - assertEquals(100, value1.getOptionalSfixed64()); - assertEquals(100, value1.getRepeatedInt32(0)); - assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, value1.getOptionalImportEnum()); - assertEquals(UnittestImport.ImportEnum.IMPORT_BAR, value1.getRepeatedImportEnum(0)); - assertEquals(1, value1.getOptionalForeignMessage().getC()); - assertEquals(1, value1.getRepeatedForeignMessage(0).getC()); + assertThat(value1.getOptionalSfixed64()).isEqualTo(100); + assertThat(value1.getRepeatedInt32(0)).isEqualTo(100); + assertThat(value1.getOptionalImportEnum()).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR); + assertThat(value1.getRepeatedImportEnum(0)).isEqualTo(UnittestImport.ImportEnum.IMPORT_BAR); + assertThat(value1.getOptionalForeignMessage().getC()).isEqualTo(1); + assertThat(value1.getRepeatedForeignMessage(0).getC()).isEqualTo(1); // Make sure value2 is correct - assertEquals(200, value2.getOptionalSfixed64()); - assertEquals(200, value2.getRepeatedInt32(0)); - assertEquals(UnittestImport.ImportEnum.IMPORT_FOO, value2.getOptionalImportEnum()); - assertEquals(UnittestImport.ImportEnum.IMPORT_FOO, value2.getRepeatedImportEnum(0)); - assertEquals(2, value2.getOptionalForeignMessage().getC()); - assertEquals(2, value2.getRepeatedForeignMessage(0).getC()); + assertThat(value2.getOptionalSfixed64()).isEqualTo(200); + assertThat(value2.getRepeatedInt32(0)).isEqualTo(200); + assertThat(value2.getOptionalImportEnum()).isEqualTo(UnittestImport.ImportEnum.IMPORT_FOO); + assertThat(value2.getRepeatedImportEnum(0)).isEqualTo(UnittestImport.ImportEnum.IMPORT_FOO); + assertThat(value2.getOptionalForeignMessage().getC()).isEqualTo(2); + assertThat(value2.getRepeatedForeignMessage(0).getC()).isEqualTo(2); } + @Test public void testProtosShareRepeatedArraysIfDidntChange() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); builder.addRepeatedInt32(100); @@ -311,10 +318,12 @@ TestAllTypes value1 = builder.build(); TestAllTypes value2 = value1.toBuilder().build(); - assertSame(value1.getRepeatedInt32List(), value2.getRepeatedInt32List()); - assertSame(value1.getRepeatedForeignMessageList(), value2.getRepeatedForeignMessageList()); + assertThat(value1.getRepeatedInt32List()).isSameInstanceAs(value2.getRepeatedInt32List()); + assertThat(value1.getRepeatedForeignMessageList()) + .isSameInstanceAs(value2.getRepeatedForeignMessageList()); } + @Test public void testRepeatedArraysAreImmutable() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); builder.addRepeatedInt32(100); @@ -332,6 +341,7 @@ assertIsUnmodifiable(value.getRepeatedFloatList()); } + @Test public void testParsedMessagesAreImmutable() throws Exception { TestAllTypes value = TestAllTypes.parser().parseFrom(TestUtil.getAllSet().toByteString()); assertIsUnmodifiable(value.getRepeatedInt32List()); @@ -364,77 +374,79 @@ } else { try { list.clear(); - fail("List wasn't immutable"); + assertWithMessage("List wasn't immutable").fail(); } catch (UnsupportedOperationException e) { // good } } } + @Test public void testSettersRejectNull() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); try { builder.setOptionalString(null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.setOptionalBytes(null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.setOptionalNestedMessage((TestAllTypes.NestedMessage) null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.setOptionalNestedMessage((TestAllTypes.NestedMessage.Builder) null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.setOptionalNestedEnum(null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.addRepeatedString(null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.addRepeatedBytes(null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage) null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage.Builder) null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.addRepeatedNestedEnum(null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } } + @Test public void testRepeatedSetters() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); @@ -443,6 +455,7 @@ TestUtil.assertRepeatedFieldsModified(message); } + @Test public void testRepeatedSettersRejectNull() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); @@ -450,7 +463,7 @@ builder.addRepeatedString("two"); try { builder.setRepeatedString(1, null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } @@ -459,7 +472,7 @@ builder.addRepeatedBytes(TestUtil.toBytes("two")); try { builder.setRepeatedBytes(1, null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } @@ -468,13 +481,13 @@ builder.addRepeatedNestedMessage(TestAllTypes.NestedMessage.newBuilder().setBb(456).build()); try { builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage) null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage.Builder) null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } @@ -483,12 +496,13 @@ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR); try { builder.setRepeatedNestedEnum(1, null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } } + @Test public void testRepeatedAppend() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); @@ -499,45 +513,48 @@ builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage)); TestAllTypes message = builder.build(); - assertEquals(message.getRepeatedInt32List(), Arrays.asList(1, 2, 3, 4)); - assertEquals(message.getRepeatedForeignEnumList(), Arrays.asList(ForeignEnum.FOREIGN_BAZ)); - assertEquals(1, message.getRepeatedForeignMessageCount()); - assertEquals(12, message.getRepeatedForeignMessage(0).getC()); + assertThat(Arrays.asList(1, 2, 3, 4)).isEqualTo(message.getRepeatedInt32List()); + assertThat(Arrays.asList(ForeignEnum.FOREIGN_BAZ)) + .isEqualTo(message.getRepeatedForeignEnumList()); + assertThat(message.getRepeatedForeignMessageCount()).isEqualTo(1); + assertThat(message.getRepeatedForeignMessage(0).getC()).isEqualTo(12); } + @Test public void testRepeatedAppendRejectsNull() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); ForeignMessage foreignMessage = ForeignMessage.newBuilder().setC(12).build(); try { builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage, (ForeignMessage) null)); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ, null)); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.addAllRepeatedString(Arrays.asList("one", null)); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } try { builder.addAllRepeatedBytes(Arrays.asList(TestUtil.toBytes("one"), null)); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } } + @Test public void testRepeatedAppendIterateOnlyOnce() throws Exception { // Create a Iterable that can only be iterated once. Iterable<String> stringIterable = @@ -555,29 +572,31 @@ }; TestAllTypes.Builder builder = TestAllTypes.newBuilder(); builder.addAllRepeatedString(stringIterable); - assertEquals(3, builder.getRepeatedStringCount()); - assertEquals("one", builder.getRepeatedString(0)); - assertEquals("two", builder.getRepeatedString(1)); - assertEquals("three", builder.getRepeatedString(2)); + assertThat(builder.getRepeatedStringCount()).isEqualTo(3); + assertThat(builder.getRepeatedString(0)).isEqualTo("one"); + assertThat(builder.getRepeatedString(1)).isEqualTo("two"); + assertThat(builder.getRepeatedString(2)).isEqualTo("three"); try { builder.addAllRepeatedString(stringIterable); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (IllegalStateException e) { // We expect this exception. } } + @Test public void testMergeFromOtherRejectsNull() throws Exception { try { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); builder.mergeFrom((TestAllTypes) null); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (NullPointerException e) { // We expect this exception. } } + @Test public void testSettingForeignMessageUsingBuilder() throws Exception { TestAllTypes message = TestAllTypes.newBuilder() @@ -590,9 +609,10 @@ .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(123).build()) .build(); // TODO(ngd): Upgrade to using real #equals method once implemented - assertEquals(expectedMessage.toString(), message.toString()); + assertThat(message.toString()).isEqualTo(expectedMessage.toString()); } + @Test public void testSettingRepeatedForeignMessageUsingBuilder() throws Exception { TestAllTypes message = TestAllTypes.newBuilder() @@ -604,24 +624,26 @@ // Create expected version passing foreign message instance explicitly. .addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(456).build()) .build(); - assertEquals(expectedMessage.toString(), message.toString()); + assertThat(message.toString()).isEqualTo(expectedMessage.toString()); } + @Test public void testDefaults() throws Exception { TestUtil.assertClear(TestAllTypes.getDefaultInstance()); TestUtil.assertClear(TestAllTypes.newBuilder().build()); TestExtremeDefaultValues message = TestExtremeDefaultValues.getDefaultInstance(); - assertEquals("\u1234", message.getUtf8String()); - assertEquals(Double.POSITIVE_INFINITY, message.getInfDouble(), 0.0); - assertEquals(Double.NEGATIVE_INFINITY, message.getNegInfDouble(), 0.0); - assertTrue(Double.isNaN(message.getNanDouble())); - assertEquals(Float.POSITIVE_INFINITY, message.getInfFloat(), 0.0f); - assertEquals(Float.NEGATIVE_INFINITY, message.getNegInfFloat(), 0.0f); - assertTrue(Float.isNaN(message.getNanFloat())); - assertEquals("? ? ?? ?? ??? ??/ ??-", message.getCppTrigraph()); + assertThat(message.getUtf8String()).isEqualTo("\u1234"); + assertThat(message.getInfDouble()).isEqualTo(Double.POSITIVE_INFINITY); + assertThat(message.getNegInfDouble()).isEqualTo(Double.NEGATIVE_INFINITY); + assertThat(Double.isNaN(message.getNanDouble())).isTrue(); + assertThat(message.getInfFloat()).isEqualTo(Float.POSITIVE_INFINITY); + assertThat(message.getNegInfFloat()).isEqualTo(Float.NEGATIVE_INFINITY); + assertThat(Float.isNaN(message.getNanFloat())).isTrue(); + assertThat(message.getCppTrigraph()).isEqualTo("? ? ?? ?? ??? ??/ ??-"); } + @Test public void testClear() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.assertClear(builder); @@ -630,6 +652,7 @@ TestUtil.assertClear(builder); } + @Test public void testReflectionGetters() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); @@ -639,6 +662,7 @@ reflectionTester.assertAllFieldsSetViaReflection(message); } + @Test public void testReflectionSetters() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); reflectionTester.setAllFieldsViaReflection(builder); @@ -648,11 +672,13 @@ TestUtil.assertAllFieldsSet(message); } + @Test public void testReflectionSettersRejectNull() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); reflectionTester.assertReflectionSettersRejectNull(builder); } + @Test public void testReflectionRepeatedSetters() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); reflectionTester.setAllFieldsViaReflection(builder); @@ -663,61 +689,69 @@ TestUtil.assertRepeatedFieldsModified(message); } + @Test public void testReflectionRepeatedSettersRejectNull() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); reflectionTester.assertReflectionRepeatedSettersRejectNull(builder); } + @Test public void testReflectionDefaults() throws Exception { reflectionTester.assertClearViaReflection(TestAllTypes.getDefaultInstance()); reflectionTester.assertClearViaReflection(TestAllTypes.newBuilder().build()); } + @Test public void testReflectionGetOneof() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); reflectionTester.setAllFieldsViaReflection(builder); Descriptors.OneofDescriptor oneof = TestAllTypes.getDescriptor().getOneofs().get(0); Descriptors.FieldDescriptor field = TestAllTypes.getDescriptor().findFieldByName("oneof_bytes"); - assertSame(field, builder.getOneofFieldDescriptor(oneof)); + assertThat(field).isSameInstanceAs(builder.getOneofFieldDescriptor(oneof)); TestAllTypes message = builder.build(); - assertSame(field, message.getOneofFieldDescriptor(oneof)); + assertThat(field).isSameInstanceAs(message.getOneofFieldDescriptor(oneof)); } + @Test public void testReflectionClearOneof() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); reflectionTester.setAllFieldsViaReflection(builder); Descriptors.OneofDescriptor oneof = TestAllTypes.getDescriptor().getOneofs().get(0); Descriptors.FieldDescriptor field = TestAllTypes.getDescriptor().findFieldByName("oneof_bytes"); - assertTrue(builder.hasOneof(oneof)); - assertTrue(builder.hasField(field)); + assertThat(builder.hasOneof(oneof)).isTrue(); + assertThat(builder.hasField(field)).isTrue(); builder.clearOneof(oneof); - assertFalse(builder.hasOneof(oneof)); - assertFalse(builder.hasField(field)); + assertThat(builder.hasOneof(oneof)).isFalse(); + assertThat(builder.hasField(field)).isFalse(); } + @Test public void testEnumInterface() throws Exception { - assertTrue( - TestAllTypes.getDefaultInstance().getDefaultNestedEnum() instanceof ProtocolMessageEnum); + assertThat(TestAllTypes.getDefaultInstance().getDefaultNestedEnum()) + .isInstanceOf(ProtocolMessageEnum.class); } + @Test public void testEnumMap() throws Exception { Internal.EnumLiteMap<ForeignEnum> map = ForeignEnum.internalGetValueMap(); for (ForeignEnum value : ForeignEnum.values()) { - assertEquals(value, map.findValueByNumber(value.getNumber())); + assertThat(map.findValueByNumber(value.getNumber())).isEqualTo(value); } - assertTrue(map.findValueByNumber(12345) == null); + assertThat(map.findValueByNumber(12345) == null).isTrue(); } + @Test public void testParsePackedToUnpacked() throws Exception { TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder(); TestUnpackedTypes message = builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); TestUtil.assertUnpackedFieldsSet(message); } + @Test public void testParseUnpackedToPacked() throws Exception { TestPackedTypes.Builder builder = TestPackedTypes.newBuilder(); TestPackedTypes message = builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); @@ -731,6 +765,7 @@ new TestUtil.ReflectionTester( TestAllExtensions.getDescriptor(), TestUtil.getFullExtensionRegistry()); + @Test public void testExtensionMessageOrBuilder() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); TestUtil.setAllExtensions(builder); @@ -738,6 +773,7 @@ TestUtil.assertAllExtensionsSet(message); } + @Test public void testGetBuilderForExtensionField() { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); Message.Builder fieldBuilder = @@ -746,21 +782,23 @@ FieldDescriptor field = NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); fieldBuilder.setField(field, expected); - assertEquals(expected, fieldBuilder.build().getField(field)); + assertThat(fieldBuilder.build().getField(field)).isEqualTo(expected); } + @Test public void testGetBuilderForNonMessageExtensionField() { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); try { // This should throw an exception because the extension field is not a message. builder.newBuilderForField(UnittestProto.optionalInt32Extension.getDescriptor()); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (UnsupportedOperationException e) { // This exception is expected. } } + @Test public void testExtensionRepeatedSetters() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); TestUtil.setAllExtensions(builder); @@ -769,26 +807,29 @@ TestUtil.assertRepeatedExtensionsModified(message); } + @Test public void testExtensionDefaults() throws Exception { TestUtil.assertExtensionsClear(TestAllExtensions.getDefaultInstance()); TestUtil.assertExtensionsClear(TestAllExtensions.newBuilder().build()); } + @Test public void testUnsetRepeatedExtensionGetField() { TestAllExtensions message = TestAllExtensions.getDefaultInstance(); Object value; value = message.getField(UnittestProto.repeatedStringExtension.getDescriptor()); - assertTrue(value instanceof List); - assertTrue(((List<?>) value).isEmpty()); + assertThat(value instanceof List).isTrue(); + assertThat(((List<?>) value).isEmpty()).isTrue(); assertIsUnmodifiable((List<?>) value); value = message.getField(UnittestProto.repeatedNestedMessageExtension.getDescriptor()); - assertTrue(value instanceof List); - assertTrue(((List<?>) value).isEmpty()); + assertThat(value instanceof List).isTrue(); + assertThat(((List<?>) value).isEmpty()).isTrue(); assertIsUnmodifiable((List<?>) value); } + @Test public void testExtensionReflectionGetters() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); TestUtil.setAllExtensions(builder); @@ -798,6 +839,7 @@ extensionsReflectionTester.assertAllFieldsSetViaReflection(message); } + @Test public void testExtensionReflectionSetters() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); extensionsReflectionTester.setAllFieldsViaReflection(builder); @@ -807,11 +849,13 @@ TestUtil.assertAllExtensionsSet(message); } + @Test public void testExtensionReflectionSettersRejectNull() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); extensionsReflectionTester.assertReflectionSettersRejectNull(builder); } + @Test public void testExtensionReflectionRepeatedSetters() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); extensionsReflectionTester.setAllFieldsViaReflection(builder); @@ -822,45 +866,51 @@ TestUtil.assertRepeatedExtensionsModified(message); } + @Test public void testExtensionReflectionRepeatedSettersRejectNull() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); extensionsReflectionTester.assertReflectionRepeatedSettersRejectNull(builder); } + @Test public void testExtensionReflectionDefaults() throws Exception { extensionsReflectionTester.assertClearViaReflection(TestAllExtensions.getDefaultInstance()); extensionsReflectionTester.assertClearViaReflection(TestAllExtensions.newBuilder().build()); } + @Test public void testClearExtension() throws Exception { // clearExtension() is not actually used in TestUtil, so try it manually. - assertFalse( - TestAllExtensions.newBuilder() - .setExtension(UnittestProto.optionalInt32Extension, 1) - .clearExtension(UnittestProto.optionalInt32Extension) - .hasExtension(UnittestProto.optionalInt32Extension)); - assertEquals( - 0, - TestAllExtensions.newBuilder() - .addExtension(UnittestProto.repeatedInt32Extension, 1) - .clearExtension(UnittestProto.repeatedInt32Extension) - .getExtensionCount(UnittestProto.repeatedInt32Extension)); + assertThat( + TestAllExtensions.newBuilder() + .setExtension(UnittestProto.optionalInt32Extension, 1) + .clearExtension(UnittestProto.optionalInt32Extension) + .hasExtension(UnittestProto.optionalInt32Extension)) + .isFalse(); + assertThat( + TestAllExtensions.newBuilder() + .addExtension(UnittestProto.repeatedInt32Extension, 1) + .clearExtension(UnittestProto.repeatedInt32Extension) + .getExtensionCount(UnittestProto.repeatedInt32Extension)) + .isEqualTo(0); } + @Test public void testExtensionCopy() throws Exception { TestAllExtensions original = TestUtil.getAllExtensionsSet(); TestAllExtensions copy = TestAllExtensions.newBuilder(original).build(); TestUtil.assertAllExtensionsSet(copy); } + @Test public void testExtensionMergeFrom() throws Exception { TestAllExtensions original = TestAllExtensions.newBuilder() .setExtension(UnittestProto.optionalInt32Extension, 1) .build(); TestAllExtensions merged = TestAllExtensions.newBuilder().mergeFrom(original).build(); - assertTrue(merged.hasExtension(UnittestProto.optionalInt32Extension)); - assertEquals(1, (int) merged.getExtension(UnittestProto.optionalInt32Extension)); + assertThat(merged.hasExtension(UnittestProto.optionalInt32Extension)).isTrue(); + assertThat((int) merged.getExtension(UnittestProto.optionalInt32Extension)).isEqualTo(1); } // ================================================================= @@ -870,16 +920,18 @@ // This test needs to be put before any other access to MultipleFilesTestProto // or messages defined in multiple_files_test.proto because the class loading // order affects initialization process of custom options. + @Test public void testEnumValueOptionsInMultipleFilesMode() throws Exception { - assertEquals( - 12345, - EnumWithNoOuter.FOO - .getValueDescriptor() - .getOptions() - .getExtension(MultipleFilesTestProto.enumValueOption) - .intValue()); + assertThat( + EnumWithNoOuter.FOO + .getValueDescriptor() + .getOptions() + .getExtension(MultipleFilesTestProto.enumValueOption) + .intValue()) + .isEqualTo(12345); } + @Test public void testMultipleFilesOption() throws Exception { // We mostly just want to check that things compile. MessageWithNoOuter message = @@ -889,56 +941,60 @@ .setNestedEnum(MessageWithNoOuter.NestedEnum.BAZ) .setForeignEnum(EnumWithNoOuter.BAR) .build(); - assertEquals(message, MessageWithNoOuter.parseFrom(message.toByteString())); + assertThat(MessageWithNoOuter.parseFrom(message.toByteString())).isEqualTo(message); - assertEquals( - MultipleFilesTestProto.getDescriptor(), MessageWithNoOuter.getDescriptor().getFile()); + assertThat(MessageWithNoOuter.getDescriptor().getFile()) + .isEqualTo(MultipleFilesTestProto.getDescriptor()); Descriptors.FieldDescriptor field = MessageWithNoOuter.getDescriptor().findFieldByName("foreign_enum"); - assertEquals(EnumWithNoOuter.BAR.getValueDescriptor(), message.getField(field)); + assertThat(message.getField(field)).isEqualTo(EnumWithNoOuter.BAR.getValueDescriptor()); - assertEquals( - MultipleFilesTestProto.getDescriptor(), ServiceWithNoOuter.getDescriptor().getFile()); + assertThat(ServiceWithNoOuter.getDescriptor().getFile()) + .isEqualTo(MultipleFilesTestProto.getDescriptor()); - assertFalse( - TestAllExtensions.getDefaultInstance() - .hasExtension(MultipleFilesTestProto.extensionWithOuter)); + assertThat( + TestAllExtensions.getDefaultInstance() + .hasExtension(MultipleFilesTestProto.extensionWithOuter)) + .isFalse(); } + @Test public void testOptionalFieldWithRequiredSubfieldsOptimizedForSize() throws Exception { TestOptionalOptimizedForSize message = TestOptionalOptimizedForSize.getDefaultInstance(); - assertTrue(message.isInitialized()); + assertThat(message.isInitialized()).isTrue(); message = TestOptionalOptimizedForSize.newBuilder() .setO(TestRequiredOptimizedForSize.newBuilder().buildPartial()) .buildPartial(); - assertFalse(message.isInitialized()); + assertThat(message.isInitialized()).isFalse(); message = TestOptionalOptimizedForSize.newBuilder() .setO(TestRequiredOptimizedForSize.newBuilder().setX(5).buildPartial()) .buildPartial(); - assertTrue(message.isInitialized()); + assertThat(message.isInitialized()).isTrue(); } + @Test public void testUninitializedExtensionInOptimizedForSize() throws Exception { TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder(); builder.setExtension( TestOptimizedForSize.testExtension2, TestRequiredOptimizedForSize.newBuilder().buildPartial()); - assertFalse(builder.isInitialized()); - assertFalse(builder.buildPartial().isInitialized()); + assertThat(builder.isInitialized()).isFalse(); + assertThat(builder.buildPartial().isInitialized()).isFalse(); builder = TestOptimizedForSize.newBuilder(); builder.setExtension( TestOptimizedForSize.testExtension2, TestRequiredOptimizedForSize.newBuilder().setX(10).buildPartial()); - assertTrue(builder.isInitialized()); - assertTrue(builder.buildPartial().isInitialized()); + assertThat(builder.isInitialized()).isTrue(); + assertThat(builder.buildPartial().isInitialized()).isTrue(); } + @Test public void testToBuilder() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestUtil.setAllFields(builder); @@ -947,39 +1003,43 @@ TestUtil.assertAllFieldsSet(message.toBuilder().build()); } + @Test public void testFieldConstantValues() throws Exception { - assertEquals(TestAllTypes.NestedMessage.BB_FIELD_NUMBER, 1); - assertEquals(TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, 1); - assertEquals(TestAllTypes.OPTIONALGROUP_FIELD_NUMBER, 16); - assertEquals(TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER, 18); - assertEquals(TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER, 21); - assertEquals(TestAllTypes.REPEATED_INT32_FIELD_NUMBER, 31); - assertEquals(TestAllTypes.REPEATEDGROUP_FIELD_NUMBER, 46); - assertEquals(TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER, 48); - assertEquals(TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER, 51); + assertThat(TestAllTypes.NestedMessage.BB_FIELD_NUMBER).isEqualTo(1); + assertThat(TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER).isEqualTo(1); + assertThat(TestAllTypes.OPTIONALGROUP_FIELD_NUMBER).isEqualTo(16); + assertThat(TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER).isEqualTo(18); + assertThat(TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER).isEqualTo(21); + assertThat(TestAllTypes.REPEATED_INT32_FIELD_NUMBER).isEqualTo(31); + assertThat(TestAllTypes.REPEATEDGROUP_FIELD_NUMBER).isEqualTo(46); + assertThat(TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER).isEqualTo(48); + assertThat(TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER).isEqualTo(51); } + @Test public void testExtensionConstantValues() throws Exception { - assertEquals(UnittestProto.TestRequired.SINGLE_FIELD_NUMBER, 1000); - assertEquals(UnittestProto.TestRequired.MULTI_FIELD_NUMBER, 1001); - assertEquals(UnittestProto.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER, 1); - assertEquals(UnittestProto.OPTIONALGROUP_EXTENSION_FIELD_NUMBER, 16); - assertEquals(UnittestProto.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 18); - assertEquals(UnittestProto.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 21); - assertEquals(UnittestProto.REPEATED_INT32_EXTENSION_FIELD_NUMBER, 31); - assertEquals(UnittestProto.REPEATEDGROUP_EXTENSION_FIELD_NUMBER, 46); - assertEquals(UnittestProto.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48); - assertEquals(UnittestProto.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 51); + assertThat(UnittestProto.TestRequired.SINGLE_FIELD_NUMBER).isEqualTo(1000); + assertThat(UnittestProto.TestRequired.MULTI_FIELD_NUMBER).isEqualTo(1001); + assertThat(UnittestProto.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER).isEqualTo(1); + assertThat(UnittestProto.OPTIONALGROUP_EXTENSION_FIELD_NUMBER).isEqualTo(16); + assertThat(UnittestProto.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER).isEqualTo(18); + assertThat(UnittestProto.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER).isEqualTo(21); + assertThat(UnittestProto.REPEATED_INT32_EXTENSION_FIELD_NUMBER).isEqualTo(31); + assertThat(UnittestProto.REPEATEDGROUP_EXTENSION_FIELD_NUMBER).isEqualTo(46); + assertThat(UnittestProto.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER).isEqualTo(48); + assertThat(UnittestProto.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER).isEqualTo(51); } + @Test public void testRecursiveMessageDefaultInstance() throws Exception { UnittestProto.TestRecursiveMessage message = UnittestProto.TestRecursiveMessage.getDefaultInstance(); - assertTrue(message != null); - assertNotNull(message.getA()); - assertTrue(message.getA().equals(message)); + assertThat(message != null).isTrue(); + assertThat(message.getA()).isNotNull(); + assertThat(message.getA().equals(message)).isTrue(); } + @Test public void testSerialize() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); TestAllTypes.Builder builder = TestAllTypes.newBuilder(); @@ -994,9 +1054,10 @@ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bais); TestAllTypes actual = (TestAllTypes) in.readObject(); - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } + @Test public void testSerializePartial() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); TestAllTypes.Builder builder = TestAllTypes.newBuilder(); @@ -1010,9 +1071,10 @@ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bais); TestAllTypes actual = (TestAllTypes) in.readObject(); - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } + @Test public void testDeserializeWithoutClassField() throws Exception { // serialized form for version <=3.6.0 // just includes messageClassName and asBytes @@ -1035,9 +1097,10 @@ ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes); ObjectInputStream in = new ObjectInputStream(bais); Int32Value int32Value = (Int32Value) in.readObject(); - assertEquals(123, int32Value.getValue()); + assertThat(int32Value.getValue()).isEqualTo(123); } + @Test public void testDeserializeWithClassField() throws Exception { // serialized form for version > 3.6.0 // includes messageClass, messageClassName (for compatibility), and asBytes @@ -1071,31 +1134,36 @@ ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes); ObjectInputStream in = new ObjectInputStream(bais); Int32Value int32Value = (Int32Value) in.readObject(); - assertEquals(123, int32Value.getValue()); + assertThat(int32Value.getValue()).isEqualTo(123); } + @Test public void testEnumValues() { - assertEquals(TestAllTypes.NestedEnum.BAR_VALUE, TestAllTypes.NestedEnum.BAR.getNumber()); - assertEquals(TestAllTypes.NestedEnum.BAZ_VALUE, TestAllTypes.NestedEnum.BAZ.getNumber()); - assertEquals(TestAllTypes.NestedEnum.FOO_VALUE, TestAllTypes.NestedEnum.FOO.getNumber()); + assertThat(TestAllTypes.NestedEnum.BAR.getNumber()) + .isEqualTo(TestAllTypes.NestedEnum.BAR_VALUE); + assertThat(TestAllTypes.NestedEnum.BAZ.getNumber()) + .isEqualTo(TestAllTypes.NestedEnum.BAZ_VALUE); + assertThat(TestAllTypes.NestedEnum.FOO.getNumber()) + .isEqualTo(TestAllTypes.NestedEnum.FOO_VALUE); } + @Test public void testNonNestedExtensionInitialization() { - assertTrue( - NonNestedExtension.nonNestedExtension.getMessageDefaultInstance() - instanceof MyNonNestedExtension); - assertEquals( - "nonNestedExtension", NonNestedExtension.nonNestedExtension.getDescriptor().getName()); + assertThat(NonNestedExtension.nonNestedExtension.getMessageDefaultInstance()) + .isInstanceOf(MyNonNestedExtension.class); + assertThat(NonNestedExtension.nonNestedExtension.getDescriptor().getName()) + .isEqualTo("nonNestedExtension"); } + @Test public void testNestedExtensionInitialization() { - assertTrue( - MyNestedExtension.recursiveExtension.getMessageDefaultInstance() - instanceof MessageToBeExtended); - assertEquals( - "recursiveExtension", MyNestedExtension.recursiveExtension.getDescriptor().getName()); + assertThat(MyNestedExtension.recursiveExtension.getMessageDefaultInstance()) + .isInstanceOf(MessageToBeExtended.class); + assertThat(MyNestedExtension.recursiveExtension.getDescriptor().getName()) + .isEqualTo("recursiveExtension"); } + @Test public void testInvalidations() throws Exception { GeneratedMessageV3.setAlwaysUseFieldBuildersForTesting(true); TestAllTypes.NestedMessage nestedMessage1 = TestAllTypes.NestedMessage.newBuilder().build(); @@ -1114,7 +1182,7 @@ builder.addRepeatedInt32(1); builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR); builder.addRepeatedNestedMessage(nestedMessage1); - assertEquals(0, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(0); // Now tell it we want changes and make sure it's only fired once // And do this for each flavor @@ -1123,39 +1191,40 @@ builder.buildPartial(); builder.setOptionalInt32(2); builder.setOptionalInt32(3); - assertEquals(1, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(1); // enum single builder.buildPartial(); builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ); builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR); - assertEquals(2, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(2); // message single builder.buildPartial(); builder.setOptionalNestedMessage(nestedMessage2); builder.setOptionalNestedMessage(nestedMessage1); - assertEquals(3, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(3); // primitive repeated builder.buildPartial(); builder.addRepeatedInt32(2); builder.addRepeatedInt32(3); - assertEquals(4, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(4); // enum repeated builder.buildPartial(); builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ); builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ); - assertEquals(5, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(5); // message repeated builder.buildPartial(); builder.addRepeatedNestedMessage(nestedMessage2); builder.addRepeatedNestedMessage(nestedMessage1); - assertEquals(6, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(6); } + @Test public void testInvalidations_Extensions() throws Exception { TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); @@ -1167,43 +1236,46 @@ builder.addExtension(UnittestProto.repeatedInt32Extension, 1); builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 2); builder.clearExtension(UnittestProto.repeatedInt32Extension); - assertEquals(0, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(0); // Now tell it we want changes and make sure it's only fired once builder.buildPartial(); builder.addExtension(UnittestProto.repeatedInt32Extension, 2); builder.addExtension(UnittestProto.repeatedInt32Extension, 3); - assertEquals(1, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(1); builder.buildPartial(); builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 4); builder.setExtension(UnittestProto.repeatedInt32Extension, 1, 5); - assertEquals(2, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(2); builder.buildPartial(); builder.clearExtension(UnittestProto.repeatedInt32Extension); builder.clearExtension(UnittestProto.repeatedInt32Extension); - assertEquals(3, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(3); } + @Test public void testBaseMessageOrBuilder() { // Mostly just makes sure the base interface exists and has some methods. TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestAllTypes message = builder.buildPartial(); TestAllTypesOrBuilder messageAsInterface = (TestAllTypesOrBuilder) message; - assertEquals(messageAsInterface.getDefaultBool(), messageAsInterface.getDefaultBool()); - assertEquals( - messageAsInterface.getOptionalDouble(), messageAsInterface.getOptionalDouble(), 0.0); + assertThat(messageAsInterface.getDefaultBool()).isEqualTo(messageAsInterface.getDefaultBool()); + assertThat(messageAsInterface.getOptionalDouble()) + .isEqualTo(messageAsInterface.getOptionalDouble()); } + @Test public void testMessageOrBuilderGetters() { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); // single fields - assertSame(ForeignMessage.getDefaultInstance(), builder.getOptionalForeignMessageOrBuilder()); + assertThat(ForeignMessage.getDefaultInstance()) + .isSameInstanceAs(builder.getOptionalForeignMessageOrBuilder()); ForeignMessage.Builder subBuilder = builder.getOptionalForeignMessageBuilder(); - assertSame(subBuilder, builder.getOptionalForeignMessageOrBuilder()); + assertThat(subBuilder).isSameInstanceAs(builder.getOptionalForeignMessageOrBuilder()); // repeated fields ForeignMessage m0 = ForeignMessage.newBuilder().buildPartial(); @@ -1212,22 +1284,23 @@ builder.addRepeatedForeignMessage(m0); builder.addRepeatedForeignMessage(m1); builder.addRepeatedForeignMessage(m2); - assertSame(m0, builder.getRepeatedForeignMessageOrBuilder(0)); - assertSame(m1, builder.getRepeatedForeignMessageOrBuilder(1)); - assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2)); + assertThat(m0).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(0)); + assertThat(m1).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(1)); + assertThat(m2).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(2)); ForeignMessage.Builder b0 = builder.getRepeatedForeignMessageBuilder(0); ForeignMessage.Builder b1 = builder.getRepeatedForeignMessageBuilder(1); - assertSame(b0, builder.getRepeatedForeignMessageOrBuilder(0)); - assertSame(b1, builder.getRepeatedForeignMessageOrBuilder(1)); - assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2)); + assertThat(b0).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(0)); + assertThat(b1).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(1)); + assertThat(m2).isSameInstanceAs(builder.getRepeatedForeignMessageOrBuilder(2)); List<? extends ForeignMessageOrBuilder> messageOrBuilderList = builder.getRepeatedForeignMessageOrBuilderList(); - assertSame(b0, messageOrBuilderList.get(0)); - assertSame(b1, messageOrBuilderList.get(1)); - assertSame(m2, messageOrBuilderList.get(2)); + assertThat(b0).isSameInstanceAs(messageOrBuilderList.get(0)); + assertThat(b1).isSameInstanceAs(messageOrBuilderList.get(1)); + assertThat(m2).isSameInstanceAs(messageOrBuilderList.get(2)); } + @Test public void testGetFieldBuilder() { Descriptor descriptor = TestAllTypes.getDescriptor(); @@ -1301,9 +1374,10 @@ Message newMessage2 = builder2.build(); // These two messages should be equal. - assertEquals(newMessage1, newMessage2); + assertThat(newMessage1).isEqualTo(newMessage2); } + @Test public void testGetFieldBuilderWithInitializedValue() { Descriptor descriptor = TestAllTypes.getDescriptor(); FieldDescriptor fieldDescriptor = descriptor.findFieldByName("optional_nested_message"); @@ -1312,7 +1386,7 @@ TestAllTypes.Builder builder = TestAllTypes.newBuilder(); NestedMessage.Builder fieldBuilder = (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor); - assertEquals(0, fieldBuilder.getBb()); + assertThat(fieldBuilder.getBb()).isEqualTo(0); // Setting field value with new field builder instance. builder = TestAllTypes.newBuilder(); @@ -1321,41 +1395,42 @@ // Then get the field builder instance by getFieldBuilder(). fieldBuilder = (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor); // It should contain new value. - assertEquals(2, fieldBuilder.getBb()); + assertThat(fieldBuilder.getBb()).isEqualTo(2); // These two builder should be equal. - assertSame(fieldBuilder, newFieldBuilder); + assertThat(fieldBuilder).isSameInstanceAs(newFieldBuilder); } + @Test public void testGetFieldBuilderNotSupportedException() { Descriptor descriptor = TestAllTypes.getDescriptor(); TestAllTypes.Builder builder = TestAllTypes.newBuilder(); try { builder.getFieldBuilder(descriptor.findFieldByName("optional_int32")); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (UnsupportedOperationException e) { // We expect this exception. } try { builder.getFieldBuilder(descriptor.findFieldByName("optional_nested_enum")); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (UnsupportedOperationException e) { // We expect this exception. } try { builder.getFieldBuilder(descriptor.findFieldByName("repeated_int32")); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (UnsupportedOperationException e) { // We expect this exception. } try { builder.getFieldBuilder(descriptor.findFieldByName("repeated_nested_enum")); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (UnsupportedOperationException e) { // We expect this exception. } try { builder.getFieldBuilder(descriptor.findFieldByName("repeated_nested_message")); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (UnsupportedOperationException e) { // We expect this exception. } @@ -1364,217 +1439,223 @@ // Test that when the default outer class name conflicts with another type // defined in the proto the compiler will append a suffix to avoid the // conflict. + @Test public void testConflictingOuterClassName() { // We just need to make sure we can refer to the outer class with the // expected name. There is nothing else to test. OuterClassNameTestOuterClass.OuterClassNameTest message = OuterClassNameTestOuterClass.OuterClassNameTest.newBuilder().build(); - assertTrue( - message.getDescriptorForType() - == OuterClassNameTestOuterClass.OuterClassNameTest.getDescriptor()); + assertThat(message.getDescriptorForType()) + .isSameInstanceAs(OuterClassNameTestOuterClass.OuterClassNameTest.getDescriptor()); OuterClassNameTest2OuterClass.TestMessage2.NestedMessage.OuterClassNameTest2 message2 = OuterClassNameTest2OuterClass.TestMessage2.NestedMessage.OuterClassNameTest2.newBuilder() .build(); - assertEquals(0, message2.getSerializedSize()); + assertThat(message2.getSerializedSize()).isEqualTo(0); OuterClassNameTest3OuterClass.TestMessage3.NestedMessage.OuterClassNameTest3 enumValue = OuterClassNameTest3OuterClass.TestMessage3.NestedMessage.OuterClassNameTest3.DUMMY_VALUE; - assertEquals(1, enumValue.getNumber()); + assertThat(enumValue.getNumber()).isEqualTo(1); } // ================================================================= // oneof generated code test + @Test public void testOneofEnumCase() throws Exception { TestOneof2 message = TestOneof2.newBuilder().setFooInt(123).setFooString("foo").setFooCord("bar").build(); TestUtil.assertAtMostOneFieldSetOneof(message); } + @Test public void testClearOneof() throws Exception { TestOneof2.Builder builder = TestOneof2.newBuilder().setFooInt(123); - assertEquals(TestOneof2.FooCase.FOO_INT, builder.getFooCase()); + assertThat(builder.getFooCase()).isEqualTo(TestOneof2.FooCase.FOO_INT); builder.clearFoo(); - assertEquals(TestOneof2.FooCase.FOO_NOT_SET, builder.getFooCase()); + assertThat(builder.getFooCase()).isEqualTo(TestOneof2.FooCase.FOO_NOT_SET); } + @Test public void testSetOneofClearsOthers() throws Exception { TestOneof2.Builder builder = TestOneof2.newBuilder(); TestOneof2 message = builder.setFooInt(123).setFooString("foo").buildPartial(); - assertTrue(message.hasFooString()); + assertThat(message.hasFooString()).isTrue(); TestUtil.assertAtMostOneFieldSetOneof(message); message = builder.setFooCord("bar").buildPartial(); - assertTrue(message.hasFooCord()); + assertThat(message.hasFooCord()).isTrue(); TestUtil.assertAtMostOneFieldSetOneof(message); message = builder.setFooStringPiece("baz").buildPartial(); - assertTrue(message.hasFooStringPiece()); + assertThat(message.hasFooStringPiece()).isTrue(); TestUtil.assertAtMostOneFieldSetOneof(message); message = builder.setFooBytes(TestUtil.toBytes("qux")).buildPartial(); - assertTrue(message.hasFooBytes()); + assertThat(message.hasFooBytes()).isTrue(); TestUtil.assertAtMostOneFieldSetOneof(message); message = builder.setFooEnum(TestOneof2.NestedEnum.FOO).buildPartial(); - assertTrue(message.hasFooEnum()); + assertThat(message.hasFooEnum()).isTrue(); TestUtil.assertAtMostOneFieldSetOneof(message); message = builder .setFooMessage(TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()) .buildPartial(); - assertTrue(message.hasFooMessage()); + assertThat(message.hasFooMessage()).isTrue(); TestUtil.assertAtMostOneFieldSetOneof(message); message = builder.setFooInt(123).buildPartial(); - assertTrue(message.hasFooInt()); + assertThat(message.hasFooInt()).isTrue(); TestUtil.assertAtMostOneFieldSetOneof(message); } + @Test public void testOneofTypes() throws Exception { // Primitive { TestOneof2.Builder builder = TestOneof2.newBuilder(); - assertEquals(builder.getFooInt(), 0); - assertFalse(builder.hasFooInt()); - assertTrue(builder.setFooInt(123).hasFooInt()); - assertEquals(builder.getFooInt(), 123); + assertThat(builder.getFooInt()).isEqualTo(0); + assertThat(builder.hasFooInt()).isFalse(); + assertThat(builder.setFooInt(123).hasFooInt()).isTrue(); + assertThat(builder.getFooInt()).isEqualTo(123); TestOneof2 message = builder.buildPartial(); - assertTrue(message.hasFooInt()); - assertEquals(message.getFooInt(), 123); + assertThat(message.hasFooInt()).isTrue(); + assertThat(123).isEqualTo(message.getFooInt()); - assertFalse(builder.clearFooInt().hasFooInt()); + assertThat(builder.clearFooInt().hasFooInt()).isFalse(); TestOneof2 message2 = builder.build(); - assertFalse(message2.hasFooInt()); - assertEquals(0, message2.getFooInt()); + assertThat(message2.hasFooInt()).isFalse(); + assertThat(message2.getFooInt()).isEqualTo(0); } // Enum { TestOneof2.Builder builder = TestOneof2.newBuilder(); - assertEquals(TestOneof2.NestedEnum.FOO, builder.getFooEnum()); - assertTrue(builder.setFooEnum(TestOneof2.NestedEnum.BAR).hasFooEnum()); - assertEquals(TestOneof2.NestedEnum.BAR, builder.getFooEnum()); + assertThat(builder.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.FOO); + assertThat(builder.setFooEnum(TestOneof2.NestedEnum.BAR).hasFooEnum()).isTrue(); + assertThat(builder.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR); TestOneof2 message = builder.buildPartial(); - assertTrue(message.hasFooEnum()); - assertEquals(TestOneof2.NestedEnum.BAR, message.getFooEnum()); + assertThat(message.hasFooEnum()).isTrue(); + assertThat(message.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR); - assertFalse(builder.clearFooEnum().hasFooEnum()); + assertThat(builder.clearFooEnum().hasFooEnum()).isFalse(); TestOneof2 message2 = builder.build(); - assertFalse(message2.hasFooEnum()); - assertEquals(TestOneof2.NestedEnum.FOO, message2.getFooEnum()); + assertThat(message2.hasFooEnum()).isFalse(); + assertThat(message2.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.FOO); } // String { TestOneof2.Builder builder = TestOneof2.newBuilder(); - assertEquals("", builder.getFooString()); + assertThat(builder.getFooString()).isEmpty(); builder.setFooString("foo"); - assertTrue(builder.hasFooString()); - assertEquals("foo", builder.getFooString()); + assertThat(builder.hasFooString()).isTrue(); + assertThat(builder.getFooString()).isEqualTo("foo"); TestOneof2 message = builder.buildPartial(); - assertTrue(message.hasFooString()); - assertEquals("foo", message.getFooString()); - assertEquals(message.getFooStringBytes(), TestUtil.toBytes("foo")); + assertThat(message.hasFooString()).isTrue(); + assertThat(message.getFooString()).isEqualTo("foo"); + assertThat(TestUtil.toBytes("foo")).isEqualTo(message.getFooStringBytes()); - assertFalse(builder.clearFooString().hasFooString()); + assertThat(builder.clearFooString().hasFooString()).isFalse(); TestOneof2 message2 = builder.buildPartial(); - assertFalse(message2.hasFooString()); - assertEquals("", message2.getFooString()); - assertEquals(message2.getFooStringBytes(), TestUtil.toBytes("")); + assertThat(message2.hasFooString()).isFalse(); + assertThat(message2.getFooString()).isEmpty(); + assertThat(message2.getFooStringBytes()).isEqualTo(TestUtil.toBytes("")); // Get method should not change the oneof value. builder.setFooInt(123); - assertEquals("", builder.getFooString()); - assertEquals(builder.getFooStringBytes(), TestUtil.toBytes("")); - assertEquals(123, builder.getFooInt()); + assertThat(builder.getFooString()).isEmpty(); + assertThat(builder.getFooStringBytes()).isEqualTo(TestUtil.toBytes("")); + assertThat(builder.getFooInt()).isEqualTo(123); message = builder.build(); - assertEquals("", message.getFooString()); - assertEquals(message.getFooStringBytes(), TestUtil.toBytes("")); - assertEquals(123, message.getFooInt()); + assertThat(message.getFooString()).isEmpty(); + assertThat(TestUtil.toBytes("")).isEqualTo(message.getFooStringBytes()); + assertThat(message.getFooInt()).isEqualTo(123); } // Cord { TestOneof2.Builder builder = TestOneof2.newBuilder(); - assertEquals("", builder.getFooCord()); + assertThat(builder.getFooCord()).isEmpty(); builder.setFooCord("foo"); - assertTrue(builder.hasFooCord()); - assertEquals("foo", builder.getFooCord()); + assertThat(builder.hasFooCord()).isTrue(); + assertThat(builder.getFooCord()).isEqualTo("foo"); TestOneof2 message = builder.buildPartial(); - assertTrue(message.hasFooCord()); - assertEquals("foo", message.getFooCord()); - assertEquals(message.getFooCordBytes(), TestUtil.toBytes("foo")); + assertThat(message.hasFooCord()).isTrue(); + assertThat(message.getFooCord()).isEqualTo("foo"); + assertThat(TestUtil.toBytes("foo")).isEqualTo(message.getFooCordBytes()); - assertFalse(builder.clearFooCord().hasFooCord()); + assertThat(builder.clearFooCord().hasFooCord()).isFalse(); TestOneof2 message2 = builder.build(); - assertFalse(message2.hasFooCord()); - assertEquals("", message2.getFooCord()); - assertEquals(message2.getFooCordBytes(), TestUtil.toBytes("")); + assertThat(message2.hasFooCord()).isFalse(); + assertThat(message2.getFooCord()).isEmpty(); + assertThat(message2.getFooCordBytes()).isEqualTo(TestUtil.toBytes("")); } // StringPiece { TestOneof2.Builder builder = TestOneof2.newBuilder(); - assertEquals("", builder.getFooStringPiece()); + assertThat(builder.getFooStringPiece()).isEmpty(); builder.setFooStringPiece("foo"); - assertTrue(builder.hasFooStringPiece()); - assertEquals("foo", builder.getFooStringPiece()); + assertThat(builder.hasFooStringPiece()).isTrue(); + assertThat(builder.getFooStringPiece()).isEqualTo("foo"); TestOneof2 message = builder.buildPartial(); - assertTrue(message.hasFooStringPiece()); - assertEquals("foo", message.getFooStringPiece()); - assertEquals(message.getFooStringPieceBytes(), TestUtil.toBytes("foo")); + assertThat(message.hasFooStringPiece()).isTrue(); + assertThat(message.getFooStringPiece()).isEqualTo("foo"); + assertThat(TestUtil.toBytes("foo")).isEqualTo(message.getFooStringPieceBytes()); - assertFalse(builder.clearFooStringPiece().hasFooStringPiece()); + assertThat(builder.clearFooStringPiece().hasFooStringPiece()).isFalse(); TestOneof2 message2 = builder.build(); - assertFalse(message2.hasFooStringPiece()); - assertEquals("", message2.getFooStringPiece()); - assertEquals(message2.getFooStringPieceBytes(), TestUtil.toBytes("")); + assertThat(message2.hasFooStringPiece()).isFalse(); + assertThat(message2.getFooStringPiece()).isEmpty(); + assertThat(message2.getFooStringPieceBytes()).isEqualTo(TestUtil.toBytes("")); } // Message { // set TestOneof2.Builder builder = TestOneof2.newBuilder(); - assertEquals(0, builder.getFooMessage().getQuxInt()); + assertThat(builder.getFooMessage().getQuxInt()).isEqualTo(0); builder.setFooMessage(TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()); - assertTrue(builder.hasFooMessage()); - assertEquals(234, builder.getFooMessage().getQuxInt()); + assertThat(builder.hasFooMessage()).isTrue(); + assertThat(builder.getFooMessage().getQuxInt()).isEqualTo(234); TestOneof2 message = builder.buildPartial(); - assertTrue(message.hasFooMessage()); - assertEquals(234, message.getFooMessage().getQuxInt()); + assertThat(message.hasFooMessage()).isTrue(); + assertThat(message.getFooMessage().getQuxInt()).isEqualTo(234); // clear - assertFalse(builder.clearFooMessage().hasFooString()); + assertThat(builder.clearFooMessage().hasFooString()).isFalse(); message = builder.build(); - assertFalse(message.hasFooMessage()); - assertEquals(0, message.getFooMessage().getQuxInt()); + assertThat(message.hasFooMessage()).isFalse(); + assertThat(message.getFooMessage().getQuxInt()).isEqualTo(0); // nested builder builder = TestOneof2.newBuilder(); - assertSame(builder.getFooMessageOrBuilder(), TestOneof2.NestedMessage.getDefaultInstance()); - assertFalse(builder.hasFooMessage()); + assertThat(builder.getFooMessageOrBuilder()) + .isSameInstanceAs(TestOneof2.NestedMessage.getDefaultInstance()); + assertThat(builder.hasFooMessage()).isFalse(); builder.getFooMessageBuilder().setQuxInt(123); - assertTrue(builder.hasFooMessage()); - assertEquals(123, builder.getFooMessage().getQuxInt()); + assertThat(builder.hasFooMessage()).isTrue(); + assertThat(builder.getFooMessage().getQuxInt()).isEqualTo(123); message = builder.build(); - assertTrue(message.hasFooMessage()); - assertEquals(123, message.getFooMessage().getQuxInt()); + assertThat(message.hasFooMessage()).isTrue(); + assertThat(message.getFooMessage().getQuxInt()).isEqualTo(123); } // LazyMessage is tested in LazyMessageLiteTest.java } + @Test public void testOneofMerge() throws Exception { // Primitive Type { TestOneof2.Builder builder = TestOneof2.newBuilder(); TestOneof2 message = builder.setFooInt(123).build(); TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); - assertTrue(message2.hasFooInt()); - assertEquals(123, message2.getFooInt()); + assertThat(message2.hasFooInt()).isTrue(); + assertThat(message2.getFooInt()).isEqualTo(123); } // String @@ -1582,8 +1663,8 @@ TestOneof2.Builder builder = TestOneof2.newBuilder(); TestOneof2 message = builder.setFooString("foo").build(); TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); - assertTrue(message2.hasFooString()); - assertEquals("foo", message2.getFooString()); + assertThat(message2.hasFooString()).isTrue(); + assertThat(message2.getFooString()).isEqualTo("foo"); } // Enum @@ -1591,8 +1672,8 @@ TestOneof2.Builder builder = TestOneof2.newBuilder(); TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build(); TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); - assertTrue(message2.hasFooEnum()); - assertEquals(TestOneof2.NestedEnum.BAR, message2.getFooEnum()); + assertThat(message2.hasFooEnum()).isTrue(); + assertThat(message2.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR); } // Message @@ -1603,11 +1684,12 @@ .setFooMessage(TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()) .build(); TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); - assertTrue(message2.hasFooMessage()); - assertEquals(234, message2.getFooMessage().getQuxInt()); + assertThat(message2.hasFooMessage()).isTrue(); + assertThat(message2.getFooMessage().getQuxInt()).isEqualTo(234); } } + @Test public void testOneofSerialization() throws Exception { // Primitive Type { @@ -1615,8 +1697,8 @@ TestOneof2 message = builder.setFooInt(123).build(); ByteString serialized = message.toByteString(); TestOneof2 message2 = TestOneof2.parseFrom(serialized); - assertTrue(message2.hasFooInt()); - assertEquals(123, message2.getFooInt()); + assertThat(message2.hasFooInt()).isTrue(); + assertThat(message2.getFooInt()).isEqualTo(123); } // String @@ -1625,8 +1707,8 @@ TestOneof2 message = builder.setFooString("foo").build(); ByteString serialized = message.toByteString(); TestOneof2 message2 = TestOneof2.parseFrom(serialized); - assertTrue(message2.hasFooString()); - assertEquals("foo", message2.getFooString()); + assertThat(message2.hasFooString()).isTrue(); + assertThat(message2.getFooString()).isEqualTo("foo"); } // Enum @@ -1635,8 +1717,8 @@ TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build(); ByteString serialized = message.toByteString(); TestOneof2 message2 = TestOneof2.parseFrom(serialized); - assertTrue(message2.hasFooEnum()); - assertEquals(TestOneof2.NestedEnum.BAR, message2.getFooEnum()); + assertThat(message2.hasFooEnum()).isTrue(); + assertThat(message2.getFooEnum()).isEqualTo(TestOneof2.NestedEnum.BAR); } // Message @@ -1648,22 +1730,24 @@ .build(); ByteString serialized = message.toByteString(); TestOneof2 message2 = TestOneof2.parseFrom(serialized); - assertTrue(message2.hasFooMessage()); - assertEquals(234, message2.getFooMessage().getQuxInt()); + assertThat(message2.hasFooMessage()).isTrue(); + assertThat(message2.getFooMessage().getQuxInt()).isEqualTo(234); } } + @Test public void testOneofNestedBuilderOnChangePropagation() { NestedTestAllTypes.Builder parentBuilder = NestedTestAllTypes.newBuilder(); TestAllTypes.Builder builder = parentBuilder.getPayloadBuilder(); builder.getOneofNestedMessageBuilder(); - assertTrue(builder.hasOneofNestedMessage()); - assertTrue(parentBuilder.hasPayload()); + assertThat(builder.hasOneofNestedMessage()).isTrue(); + assertThat(parentBuilder.hasPayload()).isTrue(); NestedTestAllTypes message = parentBuilder.build(); - assertTrue(message.hasPayload()); - assertTrue(message.getPayload().hasOneofNestedMessage()); + assertThat(message.hasPayload()).isTrue(); + assertThat(message.getPayload().hasOneofNestedMessage()).isTrue(); } + @Test public void testGetRepeatedFieldBuilder() { Descriptor descriptor = TestAllTypes.getDescriptor(); @@ -1722,9 +1806,10 @@ Message newMessage2 = builder2.build(); // These two messages should be equal. - assertEquals(newMessage1, newMessage2); + assertThat(newMessage1).isEqualTo(newMessage2); } + @Test public void testGetRepeatedFieldBuilderWithInitializedValue() { Descriptor descriptor = TestAllTypes.getDescriptor(); FieldDescriptor fieldDescriptor = descriptor.findFieldByName("repeated_nested_message"); @@ -1734,7 +1819,7 @@ builder.addRepeatedNestedMessageBuilder(); NestedMessage.Builder fieldBuilder = (NestedMessage.Builder) builder.getRepeatedFieldBuilder(fieldDescriptor, 0); - assertEquals(0, fieldBuilder.getBb()); + assertThat(fieldBuilder.getBb()).isEqualTo(0); // Setting field value with new field builder instance. builder = TestAllTypes.newBuilder(); @@ -1743,41 +1828,42 @@ // Then get the field builder instance by getRepeatedFieldBuilder(). fieldBuilder = (NestedMessage.Builder) builder.getRepeatedFieldBuilder(fieldDescriptor, 0); // It should contain new value. - assertEquals(2, fieldBuilder.getBb()); + assertThat(fieldBuilder.getBb()).isEqualTo(2); // These two builder should be equal. - assertSame(fieldBuilder, newFieldBuilder); + assertThat(fieldBuilder).isSameInstanceAs(newFieldBuilder); } + @Test public void testGetRepeatedFieldBuilderNotSupportedException() { Descriptor descriptor = TestAllTypes.getDescriptor(); TestAllTypes.Builder builder = TestAllTypes.newBuilder(); try { builder.getRepeatedFieldBuilder(descriptor.findFieldByName("repeated_int32"), 0); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (UnsupportedOperationException e) { // We expect this exception. } try { builder.getRepeatedFieldBuilder(descriptor.findFieldByName("repeated_nested_enum"), 0); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (UnsupportedOperationException e) { // We expect this exception. } try { builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_int32"), 0); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (UnsupportedOperationException e) { // We expect this exception. } try { builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_nested_enum"), 0); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (UnsupportedOperationException e) { // We expect this exception. } try { builder.getRepeatedFieldBuilder(descriptor.findFieldByName("optional_nested_message"), 0); - fail("Exception was not thrown"); + assertWithMessage("Exception was not thrown").fail(); } catch (UnsupportedOperationException e) { // We expect this exception. }
diff --git a/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java b/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java index 2ad94f8..15bbda9 100644 --- a/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java
@@ -30,39 +30,44 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static java.util.Arrays.asList; import com.google.protobuf.Internal.IntList; import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.Iterator; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Tests for {@link IntArrayList}. - * - * @author dweis@google.com (Daniel Weis) - */ -public class IntArrayListTest extends TestCase { +/** Tests for {@link IntArrayList}. */ +@RunWith(JUnit4.class) +public class IntArrayListTest { private static final IntArrayList UNARY_LIST = newImmutableIntArrayList(1); private static final IntArrayList TERTIARY_LIST = newImmutableIntArrayList(1, 2, 3); private IntArrayList list; - @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { list = new IntArrayList(); } + @Test public void testEmptyListReturnsSameInstance() { - assertSame(IntArrayList.emptyList(), IntArrayList.emptyList()); + assertThat(IntArrayList.emptyList()).isSameInstanceAs(IntArrayList.emptyList()); } + @Test public void testEmptyListIsImmutable() { assertImmutable(IntArrayList.emptyList()); } + @Test public void testMakeImmutable() { list.addInt(3); list.addInt(4); @@ -72,19 +77,20 @@ assertImmutable(list); } + @Test public void testModificationWithIteration() { list.addAll(asList(1, 2, 3, 4)); Iterator<Integer> iterator = list.iterator(); - assertEquals(4, list.size()); - assertEquals(1, (int) list.get(0)); - assertEquals(1, (int) iterator.next()); + assertThat(list).hasSize(4); + assertThat((int) list.get(0)).isEqualTo(1); + assertThat((int) iterator.next()).isEqualTo(1); list.set(0, 1); - assertEquals(2, (int) iterator.next()); + assertThat((int) iterator.next()).isEqualTo(2); list.remove(0); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail(); } catch (ConcurrentModificationException e) { // expected } @@ -93,191 +99,211 @@ list.add(0, 0); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail(); } catch (ConcurrentModificationException e) { // expected } } + @Test public void testGet() { - assertEquals(1, (int) TERTIARY_LIST.get(0)); - assertEquals(2, (int) TERTIARY_LIST.get(1)); - assertEquals(3, (int) TERTIARY_LIST.get(2)); + assertThat((int) TERTIARY_LIST.get(0)).isEqualTo(1); + assertThat((int) TERTIARY_LIST.get(1)).isEqualTo(2); + assertThat((int) TERTIARY_LIST.get(2)).isEqualTo(3); try { TERTIARY_LIST.get(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { TERTIARY_LIST.get(3); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testGetInt() { - assertEquals(1, TERTIARY_LIST.getInt(0)); - assertEquals(2, TERTIARY_LIST.getInt(1)); - assertEquals(3, TERTIARY_LIST.getInt(2)); + assertThat(TERTIARY_LIST.getInt(0)).isEqualTo(1); + assertThat(TERTIARY_LIST.getInt(1)).isEqualTo(2); + assertThat(TERTIARY_LIST.getInt(2)).isEqualTo(3); try { TERTIARY_LIST.get(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { TERTIARY_LIST.get(3); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testIndexOf_nullElement() { - assertEquals(-1, TERTIARY_LIST.indexOf(null)); + assertThat(TERTIARY_LIST.indexOf(null)).isEqualTo(-1); } + @Test public void testIndexOf_incompatibleElementType() { - assertEquals(-1, TERTIARY_LIST.indexOf(new Object())); + assertThat(TERTIARY_LIST.indexOf(new Object())).isEqualTo(-1); } + @Test public void testIndexOf_notInList() { - assertEquals(-1, UNARY_LIST.indexOf(2)); + assertThat(UNARY_LIST.indexOf(2)).isEqualTo(-1); } + @Test public void testIndexOf_notInListWithDuplicates() { IntArrayList listWithDupes = newImmutableIntArrayList(1, 1); - assertEquals(-1, listWithDupes.indexOf(2)); + assertThat(listWithDupes.indexOf(2)).isEqualTo(-1); } + @Test public void testIndexOf_inList() { - assertEquals(1, TERTIARY_LIST.indexOf(2)); + assertThat(TERTIARY_LIST.indexOf(2)).isEqualTo(1); } + @Test public void testIndexOf_inListWithDuplicates_matchAtHead() { IntArrayList listWithDupes = newImmutableIntArrayList(1, 1, 2); - assertEquals(0, listWithDupes.indexOf(1)); + assertThat(listWithDupes.indexOf(1)).isEqualTo(0); } + @Test public void testIndexOf_inListWithDuplicates_matchMidList() { IntArrayList listWithDupes = newImmutableIntArrayList(2, 1, 1, 2); - assertEquals(1, listWithDupes.indexOf(1)); + assertThat(listWithDupes.indexOf(1)).isEqualTo(1); } + @Test public void testContains_nullElement() { - assertEquals(false, TERTIARY_LIST.contains(null)); + assertThat(TERTIARY_LIST).doesNotContain(null); } + @Test public void testContains_incompatibleElementType() { - assertEquals(false, TERTIARY_LIST.contains(new Object())); + assertThat(TERTIARY_LIST).doesNotContain(new Object()); } + @Test public void testContains_notInList() { - assertEquals(false, UNARY_LIST.contains(2)); + assertThat(UNARY_LIST).doesNotContain(2); } + @Test public void testContains_notInListWithDuplicates() { IntArrayList listWithDupes = newImmutableIntArrayList(1, 1); - assertEquals(false, listWithDupes.contains(2)); + assertThat(listWithDupes).doesNotContain(2); } + @Test public void testContains_inList() { - assertEquals(true, TERTIARY_LIST.contains(2)); + assertThat(TERTIARY_LIST).contains(2); } + @Test public void testContains_inListWithDuplicates_matchAtHead() { IntArrayList listWithDupes = newImmutableIntArrayList(1, 1, 2); - assertEquals(true, listWithDupes.contains(1)); + assertThat(listWithDupes).contains(1); } + @Test public void testContains_inListWithDuplicates_matchMidList() { IntArrayList listWithDupes = newImmutableIntArrayList(2, 1, 1, 2); - assertEquals(true, listWithDupes.contains(1)); + assertThat(listWithDupes).contains(1); } + @Test public void testSize() { - assertEquals(0, IntArrayList.emptyList().size()); - assertEquals(1, UNARY_LIST.size()); - assertEquals(3, TERTIARY_LIST.size()); + assertThat(IntArrayList.emptyList()).isEmpty(); + assertThat(UNARY_LIST).hasSize(1); + assertThat(TERTIARY_LIST).hasSize(3); list.addInt(3); list.addInt(4); list.addInt(6); list.addInt(8); - assertEquals(4, list.size()); + assertThat(list).hasSize(4); list.remove(0); - assertEquals(3, list.size()); + assertThat(list).hasSize(3); list.add(17); - assertEquals(4, list.size()); + assertThat(list).hasSize(4); } + @Test public void testSet() { list.addInt(2); list.addInt(4); - assertEquals(2, (int) list.set(0, 3)); - assertEquals(3, list.getInt(0)); + assertThat((int) list.set(0, 3)).isEqualTo(2); + assertThat(list.getInt(0)).isEqualTo(3); - assertEquals(4, (int) list.set(1, 0)); - assertEquals(0, list.getInt(1)); + assertThat((int) list.set(1, 0)).isEqualTo(4); + assertThat(list.getInt(1)).isEqualTo(0); try { list.set(-1, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.set(2, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testSetInt() { list.addInt(1); list.addInt(3); - assertEquals(1, list.setInt(0, 0)); - assertEquals(0, list.getInt(0)); + assertThat(list.setInt(0, 0)).isEqualTo(1); + assertThat(list.getInt(0)).isEqualTo(0); - assertEquals(3, list.setInt(1, 0)); - assertEquals(0, list.getInt(1)); + assertThat(list.setInt(1, 0)).isEqualTo(3); + assertThat(list.getInt(1)).isEqualTo(0); try { list.setInt(-1, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.setInt(2, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testAdd() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); - assertTrue(list.add(2)); - assertEquals(asList(2), list); + assertThat(list.add(2)).isTrue(); + assertThat(list).containsExactly(2); - assertTrue(list.add(3)); + assertThat(list.add(3)).isTrue(); list.add(0, 4); - assertEquals(asList(4, 2, 3), list); + assertThat(list).containsExactly(4, 2, 3).inOrder(); list.add(0, 1); list.add(0, 0); @@ -285,7 +311,7 @@ for (int i = 0; i < 6; i++) { list.add(Integer.valueOf(5 + i)); } - assertEquals(asList(0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10), list); + assertThat(list).containsExactly(0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10).inOrder(); try { list.add(-1, 5); @@ -300,90 +326,98 @@ } } + @Test public void testAddInt() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); list.addInt(2); - assertEquals(asList(2), list); + assertThat(list).containsExactly(2); list.addInt(3); - assertEquals(asList(2, 3), list); + assertThat(list).containsExactly(2, 3).inOrder(); } + @Test public void testAddAll() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); - assertTrue(list.addAll(Collections.singleton(1))); - assertEquals(1, list.size()); - assertEquals(1, (int) list.get(0)); - assertEquals(1, list.getInt(0)); + assertThat(list.addAll(Collections.singleton(1))).isTrue(); + assertThat(list).hasSize(1); + assertThat((int) list.get(0)).isEqualTo(1); + assertThat(list.getInt(0)).isEqualTo(1); - assertTrue(list.addAll(asList(2, 3, 4, 5, 6))); - assertEquals(asList(1, 2, 3, 4, 5, 6), list); + assertThat(list.addAll(asList(2, 3, 4, 5, 6))).isTrue(); + assertThat(list).containsExactly(1, 2, 3, 4, 5, 6).inOrder(); - assertTrue(list.addAll(TERTIARY_LIST)); - assertEquals(asList(1, 2, 3, 4, 5, 6, 1, 2, 3), list); + assertThat(list.addAll(TERTIARY_LIST)).isTrue(); + assertThat(list).containsExactly(1, 2, 3, 4, 5, 6, 1, 2, 3).inOrder(); - assertFalse(list.addAll(Collections.<Integer>emptyList())); - assertFalse(list.addAll(IntArrayList.emptyList())); + assertThat(list.addAll(Collections.<Integer>emptyList())).isFalse(); + assertThat(list.addAll(IntArrayList.emptyList())).isFalse(); } + @Test public void testEquals() { IntArrayList list1 = new IntArrayList(); IntArrayList list2 = new IntArrayList(); - assertEquals(list1, list2); + assertThat(list1).isEqualTo(list2); } + @Test public void testRemove() { list.addAll(TERTIARY_LIST); - assertEquals(1, (int) list.remove(0)); - assertEquals(asList(2, 3), list); + assertThat((int) list.remove(0)).isEqualTo(1); + assertThat(list).containsExactly(2, 3).inOrder(); - assertTrue(list.remove(Integer.valueOf(3))); - assertEquals(asList(2), list); + assertThat(list.remove(Integer.valueOf(3))).isTrue(); + assertThat(list).containsExactly(2); - assertFalse(list.remove(Integer.valueOf(3))); - assertEquals(asList(2), list); + assertThat(list.remove(Integer.valueOf(3))).isFalse(); + assertThat(list).containsExactly(2); - assertEquals(2, (int) list.remove(0)); - assertEquals(asList(), list); + assertThat((int) list.remove(0)).isEqualTo(2); + assertThat(list).isEmpty(); try { list.remove(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.remove(0); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testRemoveEnd_listAtCapacity() { IntList toRemove = IntArrayList.emptyList().mutableCopyWithCapacity(1); toRemove.addInt(3); toRemove.remove(0); - assertEquals(0, toRemove.size()); + assertThat(toRemove).isEmpty(); } + @Test public void testRemove_listAtCapacity() { IntList toRemove = IntArrayList.emptyList().mutableCopyWithCapacity(2); toRemove.addInt(3); toRemove.addInt(4); toRemove.remove(0); - assertEquals(1, toRemove.size()); - assertEquals(4, (int) toRemove.get(0)); + assertThat(toRemove).hasSize(1); + assertThat((int) toRemove.get(0)).isEqualTo(4); } + @Test public void testSublistRemoveEndOfCapacity() { IntList toRemove = IntArrayList.emptyList().mutableCopyWithCapacity(1); toRemove.addInt(3); toRemove.subList(0, 1).clear(); - assertEquals(0, toRemove.size()); + assertThat(toRemove).isEmpty(); } private void assertImmutable(IntList list) { @@ -393,147 +427,147 @@ try { list.add(1); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.add(0, 1); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(Collections.<Integer>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(Collections.singletonList(1)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(new IntArrayList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, Collections.singleton(1)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, Collections.<Integer>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addInt(0); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.clear(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.remove(1); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.remove(new Object()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(Collections.<Integer>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(Collections.singleton(1)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(Collections.<Integer>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(Collections.singleton(1)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.set(0, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.setInt(0, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected }
diff --git a/java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java b/java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java index 6a737f1..bbbe2cd 100644 --- a/java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java +++ b/java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java
@@ -30,6 +30,7 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; import static com.google.protobuf.IsValidUtf8TestUtil.DIRECT_NIO_FACTORY; import static com.google.protobuf.IsValidUtf8TestUtil.EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT; import static com.google.protobuf.IsValidUtf8TestUtil.EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT; @@ -39,7 +40,9 @@ import com.google.protobuf.IsValidUtf8TestUtil.ByteStringFactory; import com.google.protobuf.IsValidUtf8TestUtil.Shard; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Tests cases for {@link ByteString#isValidUtf8()}. This includes three brute force tests that @@ -49,12 +52,11 @@ * sequence that will round trip when converted to a String and then back to bytes and will return * false for any sequence that will not round trip. See also {@link IsValidUtf8FourByteTest}. It * also includes some other more targeted tests. - * - * @author jonp@google.com (Jon Perlow) - * @author martinrb@google.com (Martin Buchholz) */ -public class IsValidUtf8Test extends TestCase { +@RunWith(JUnit4.class) +public class IsValidUtf8Test { /** Tests that round tripping of all two byte permutations work. */ + @Test public void testIsValidUtf8_1Byte() { testBytes(LITERAL_FACTORY, 1, EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT); testBytes(HEAP_NIO_FACTORY, 1, EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT); @@ -62,6 +64,7 @@ } /** Tests that round tripping of all two byte permutations work. */ + @Test public void testIsValidUtf8_2Bytes() { testBytes(LITERAL_FACTORY, 2, IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT); testBytes(HEAP_NIO_FACTORY, 2, IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT); @@ -69,6 +72,7 @@ } /** Tests that round tripping of all three byte permutations work. */ + @Test public void testIsValidUtf8_3Bytes() { // Travis' OOM killer doesn't like this test if (System.getenv("TRAVIS") == null) { @@ -83,6 +87,7 @@ * prohibitively expensive to test for automated runs; {@link IsValidUtf8FourByteTest} is used for * full coverage. This method tests specific four-byte cases. */ + @Test public void testIsValidUtf8_4BytesSamples() { // Valid 4 byte. assertValidUtf8(0xF0, 0xA4, 0xAD, 0xA2); @@ -97,29 +102,40 @@ } /** Tests some hard-coded test cases. */ + @Test public void testSomeSequences() { // Empty - assertTrue(asBytes("").isValidUtf8()); + assertThat(asBytes("").isValidUtf8()).isTrue(); // One-byte characters, including control characters - assertTrue(asBytes("\u0000abc\u007f").isValidUtf8()); + assertThat(asBytes("\u0000abc\u007f").isValidUtf8()).isTrue(); // Two-byte characters - assertTrue(asBytes("\u00a2\u00a2").isValidUtf8()); + assertThat(asBytes("\u00a2\u00a2").isValidUtf8()).isTrue(); // Three-byte characters - assertTrue(asBytes("\u020ac\u020ac").isValidUtf8()); + assertThat(asBytes("\u020ac\u020ac").isValidUtf8()).isTrue(); // Four-byte characters - assertTrue(asBytes("\u024B62\u024B62").isValidUtf8()); + assertThat(asBytes("\u024B62\u024B62").isValidUtf8()).isTrue(); // Mixed string - assertTrue(asBytes("a\u020ac\u00a2b\\u024B62u020acc\u00a2de\u024B62").isValidUtf8()); + assertThat(asBytes("a\u020ac\u00a2b\\u024B62u020acc\u00a2de\u024B62").isValidUtf8()).isTrue(); // Not a valid string assertInvalidUtf8(-1, 0, -1, 0); } + @Test + public void testShardsHaveExpectedRoundTrippables() { + // A sanity check. + int actual = 0; + for (Shard shard : IsValidUtf8TestUtil.FOUR_BYTE_SHARDS) { + actual = (int) (actual + shard.expected); + } + assertThat(actual).isEqualTo(IsValidUtf8TestUtil.EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT); + } + private byte[] toByteArray(int... bytes) { byte[] realBytes = new byte[bytes.length]; for (int i = 0; i < bytes.length; i++) { @@ -130,12 +146,12 @@ private void assertValidUtf8(ByteStringFactory factory, int[] bytes, boolean not) { byte[] realBytes = toByteArray(bytes); - assertTrue(not ^ Utf8.isValidUtf8(realBytes)); - assertTrue(not ^ Utf8.isValidUtf8(realBytes, 0, bytes.length)); + assertThat(not ^ Utf8.isValidUtf8(realBytes)).isTrue(); + assertThat(not ^ Utf8.isValidUtf8(realBytes, 0, bytes.length)).isTrue(); ByteString leaf = factory.newByteString(realBytes); ByteString sub = leaf.substring(0, bytes.length); - assertTrue(not ^ leaf.isValidUtf8()); - assertTrue(not ^ sub.isValidUtf8()); + assertThat(not ^ leaf.isValidUtf8()).isTrue(); + assertThat(not ^ sub.isValidUtf8()).isTrue(); ByteString[] ropes = { RopeByteString.newInstanceForTest(ByteString.EMPTY, leaf), RopeByteString.newInstanceForTest(ByteString.EMPTY, sub), @@ -144,7 +160,7 @@ RopeByteString.newInstanceForTest(sub, leaf) }; for (ByteString rope : ropes) { - assertTrue(not ^ rope.isValidUtf8()); + assertThat(not ^ rope.isValidUtf8()).isTrue(); } } @@ -163,13 +179,4 @@ private static ByteString asBytes(String s) { return ByteString.copyFromUtf8(s); } - - public void testShardsHaveExpectedRoundTrippables() { - // A sanity check. - int actual = 0; - for (Shard shard : IsValidUtf8TestUtil.FOUR_BYTE_SHARDS) { - actual = (int) (actual + shard.expected); - } - assertEquals(IsValidUtf8TestUtil.EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT, actual); - } }
diff --git a/java/core/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java b/java/core/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java index 67d2f59..94a9ffb 100644 --- a/java/core/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java +++ b/java/core/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java
@@ -30,11 +30,8 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import java.lang.ref.SoftReference; import java.nio.ByteBuffer; @@ -56,7 +53,7 @@ * @author martinrb@google.com (Martin Buchholz) */ final class IsValidUtf8TestUtil { - private static Logger logger = Logger.getLogger(IsValidUtf8TestUtil.class.getName()); + private static final Logger logger = Logger.getLogger(IsValidUtf8TestUtil.class.getName()); private IsValidUtf8TestUtil() {} @@ -80,8 +77,7 @@ } }; - private static ThreadLocal<SoftReference<ByteBuffer>> directBuffer = - new ThreadLocal<SoftReference<ByteBuffer>>(); + private static final ThreadLocal<SoftReference<ByteBuffer>> directBuffer = new ThreadLocal<>(); /** * Factory for direct {@link ByteBuffer} instances. To reduce direct memory usage, this uses a @@ -171,7 +167,7 @@ final long expected; public Shard(long index, long start, long lim, long expected) { - assertTrue(start < lim); + assertThat(start).isLessThan(lim); this.index = index; this.start = start; this.lim = lim; @@ -216,11 +212,11 @@ generateFourByteShards(128, FOUR_BYTE_SHARDS_EXPECTED_ROUNTRIPPABLES); private static List<Shard> generateFourByteShards(int numShards, long[] expected) { - assertEquals(numShards, expected.length); - List<Shard> shards = new ArrayList<Shard>(numShards); + assertThat(expected).hasLength(numShards); + List<Shard> shards = new ArrayList<>(numShards); long lim = 1L << 32; long increment = lim / numShards; - assertTrue(lim % numShards == 0); + assertThat(lim % numShards).isEqualTo(0); for (int i = 0; i < numShards; i++) { shards.add(new Shard(i, increment * i, increment * (i + 1), expected[i])); } @@ -276,11 +272,11 @@ } // Check agreement with static Utf8 methods. - assertEquals(isRoundTrippable, Utf8.isValidUtf8(bytes)); - assertEquals(isRoundTrippable, Utf8.isValidUtf8(bytes, 0, numBytes)); + assertThat(Utf8.isValidUtf8(bytes)).isEqualTo(isRoundTrippable); + assertThat(Utf8.isValidUtf8(bytes, 0, numBytes)).isEqualTo(isRoundTrippable); try { - assertEquals(s, Utf8.decodeUtf8(bytes, 0, numBytes)); + assertThat(Utf8.decodeUtf8(bytes, 0, numBytes)).isEqualTo(s); } catch (InvalidProtocolBufferException e) { if (isRoundTrippable) { System.out.println("Could not decode utf-8"); @@ -304,31 +300,32 @@ System.out.printf("state=%04x %04x %04x i=%d j=%d%n", state1, state2, state3, i, j); outputFailure(byteChar, bytes, bytesReencoded); } - assertEquals(isRoundTrippable, (state3 == Utf8.COMPLETE)); + assertThat((state3 == Utf8.COMPLETE)).isEqualTo(isRoundTrippable); // Test ropes built out of small partial sequences ByteString rope = RopeByteString.newInstanceForTest( bs.substring(0, i), RopeByteString.newInstanceForTest(bs.substring(i, j), bs.substring(j, numBytes))); - assertSame(RopeByteString.class, rope.getClass()); + assertThat(rope.getClass()).isSameInstanceAs(RopeByteString.class); ByteString[] byteStrings = {bs, bs.substring(0, numBytes), rope}; for (ByteString x : byteStrings) { - assertEquals(isRoundTrippable, x.isValidUtf8()); - assertEquals(state3, x.partialIsValidUtf8(Utf8.COMPLETE, 0, numBytes)); + assertThat(x.isValidUtf8()).isEqualTo(isRoundTrippable); + assertThat(x.partialIsValidUtf8(Utf8.COMPLETE, 0, numBytes)).isEqualTo(state3); - assertEquals(state1, x.partialIsValidUtf8(Utf8.COMPLETE, 0, i)); - assertEquals(state1, x.substring(0, i).partialIsValidUtf8(Utf8.COMPLETE, 0, i)); - assertEquals(state2, x.partialIsValidUtf8(state1, i, j - i)); - assertEquals(state2, x.substring(i, j).partialIsValidUtf8(state1, 0, j - i)); - assertEquals(state3, x.partialIsValidUtf8(state2, j, numBytes - j)); - assertEquals(state3, x.substring(j, numBytes).partialIsValidUtf8(state2, 0, numBytes - j)); + assertThat(x.partialIsValidUtf8(Utf8.COMPLETE, 0, i)).isEqualTo(state1); + assertThat(x.substring(0, i).partialIsValidUtf8(Utf8.COMPLETE, 0, i)).isEqualTo(state1); + assertThat(x.partialIsValidUtf8(state1, i, j - i)).isEqualTo(state2); + assertThat(x.substring(i, j).partialIsValidUtf8(state1, 0, j - i)).isEqualTo(state2); + assertThat(x.partialIsValidUtf8(state2, j, numBytes - j)).isEqualTo(state3); + assertThat(x.substring(j, numBytes).partialIsValidUtf8(state2, 0, numBytes - j)) + .isEqualTo(state3); } // ByteString reduplication should not affect its UTF-8 validity. ByteString ropeADope = RopeByteString.newInstanceForTest(bs, bs.substring(0, numBytes)); - assertEquals(isRoundTrippable, ropeADope.isValidUtf8()); + assertThat(ropeADope.isValidUtf8()).isEqualTo(isRoundTrippable); if (isRoundTrippable) { countRoundTripped++; @@ -339,7 +336,7 @@ } } logger.info("Round tripped " + countRoundTripped + " of " + count); - assertEquals(expectedCount, countRoundTripped); + assertThat(countRoundTripped).isEqualTo(expectedCount); } /** @@ -397,17 +394,17 @@ } boolean isRoundTrippable = factory.newByteString(bytes).isValidUtf8(); CoderResult result = decoder.decode(bb, cb, true); - assertFalse(result.isError()); + assertThat(result.isError()).isFalse(); result = decoder.flush(cb); - assertFalse(result.isError()); + assertThat(result.isError()).isFalse(); int charLen = cb.position(); cb.rewind(); cb.limit(charLen); result = encoder.encode(cb, bbReencoded, true); - assertFalse(result.isError()); + assertThat(result.isError()).isFalse(); result = encoder.flush(bbReencoded); - assertFalse(result.isError()); + assertThat(result.isError()).isFalse(); boolean bytesEqual = true; int bytesLen = bbReencoded.position(); @@ -434,7 +431,7 @@ } } logger.info("Round tripped " + countRoundTripped + " of " + count); - assertEquals(expectedCount, countRoundTripped); + assertThat(countRoundTripped).isEqualTo(expectedCount); } private static void outputFailure(long byteChar, byte[] bytes, byte[] after) { @@ -442,10 +439,8 @@ } private static void outputFailure(long byteChar, byte[] bytes, byte[] after, int len) { - fail( - String.format( - "Failure: (%s) %s => %s", - Long.toHexString(byteChar), toHexString(bytes), toHexString(after, len))); + assertWithMessage("Failure: (%s) %s => %s", + Long.toHexString(byteChar), toHexString(bytes), toHexString(after, len)).fail(); } private static String toHexString(byte[] b) {
diff --git a/java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java b/java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java index 8c13aca..98cee80 100644 --- a/java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
@@ -30,36 +30,39 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; import static protobuf_unittest.UnittestProto.optionalInt32Extension; import protobuf_unittest.UnittestProto.TestAllExtensions; import protobuf_unittest.UnittestProto.TestAllTypes; import java.io.IOException; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Unit test for {@link LazyFieldLite}. - * - * @author xiangl@google.com (Xiang Li) - */ -public class LazyFieldLiteTest extends TestCase { +/** Unit test for {@link LazyFieldLite}. */ +@RunWith(JUnit4.class) +public class LazyFieldLiteTest { + @Test public void testGetValue() { MessageLite message = TestUtil.getAllSet(); LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); - assertEquals(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); + assertThat(message).isEqualTo(lazyField.getValue(TestAllTypes.getDefaultInstance())); changeValue(lazyField); assertNotEqual(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); } + @Test public void testGetValueEx() throws Exception { TestAllExtensions message = TestUtil.getAllExtensionsSet(); LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); - assertEquals(message, lazyField.getValue(TestAllExtensions.getDefaultInstance())); + assertThat(message).isEqualTo(lazyField.getValue(TestAllExtensions.getDefaultInstance())); changeValue(lazyField); assertNotEqual(message, lazyField.getValue(TestAllExtensions.getDefaultInstance())); } + @Test public void testSetValue() { MessageLite message = TestUtil.getAllSet(); LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); @@ -67,9 +70,10 @@ assertNotEqual(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); message = lazyField.getValue(TestAllTypes.getDefaultInstance()); changeValue(lazyField); - assertEquals(message, lazyField.getValue(TestAllTypes.getDefaultInstance())); + assertThat(message).isEqualTo(lazyField.getValue(TestAllTypes.getDefaultInstance())); } + @Test public void testSetValueEx() throws Exception { TestAllExtensions message = TestUtil.getAllExtensionsSet(); LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); @@ -77,41 +81,46 @@ assertNotEqual(message, lazyField.getValue(TestAllExtensions.getDefaultInstance())); MessageLite value = lazyField.getValue(TestAllExtensions.getDefaultInstance()); changeValue(lazyField); - assertEquals(value, lazyField.getValue(TestAllExtensions.getDefaultInstance())); + assertThat(value).isEqualTo(lazyField.getValue(TestAllExtensions.getDefaultInstance())); } + @Test public void testGetSerializedSize() { MessageLite message = TestUtil.getAllSet(); LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); - assertEquals(message.getSerializedSize(), lazyField.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(lazyField.getSerializedSize()); changeValue(lazyField); assertNotEqual(message.getSerializedSize(), lazyField.getSerializedSize()); } + @Test public void testGetSerializedSizeEx() throws Exception { TestAllExtensions message = TestUtil.getAllExtensionsSet(); LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); - assertEquals(message.getSerializedSize(), lazyField.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(lazyField.getSerializedSize()); changeValue(lazyField); assertNotEqual(message.getSerializedSize(), lazyField.getSerializedSize()); } + @Test public void testGetByteString() { MessageLite message = TestUtil.getAllSet(); LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); - assertEquals(message.toByteString(), lazyField.toByteString()); + assertThat(message.toByteString()).isEqualTo(lazyField.toByteString()); changeValue(lazyField); assertNotEqual(message.toByteString(), lazyField.toByteString()); } + @Test public void testGetByteStringEx() throws Exception { TestAllExtensions message = TestUtil.getAllExtensionsSet(); LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message); - assertEquals(message.toByteString(), lazyField.toByteString()); + assertThat(message.toByteString()).isEqualTo(lazyField.toByteString()); changeValue(lazyField); assertNotEqual(message.toByteString(), lazyField.toByteString()); } + @Test public void testMergeExtensions() throws Exception { TestAllExtensions message = TestUtil.getAllExtensionsSet(); LazyFieldLite original = createLazyFieldLiteFromMessage(message); @@ -119,25 +128,29 @@ merged.merge(original); TestAllExtensions value = (TestAllExtensions) merged.getValue(TestAllExtensions.getDefaultInstance()); - assertEquals(message, value); + assertThat(message).isEqualTo(value); } + @Test public void testEmptyLazyField() throws Exception { LazyFieldLite field = new LazyFieldLite(); - assertEquals(0, field.getSerializedSize()); - assertEquals(ByteString.EMPTY, field.toByteString()); + assertThat(field.getSerializedSize()).isEqualTo(0); + assertThat(field.toByteString()).isEqualTo(ByteString.EMPTY); } + @Test public void testInvalidProto() throws Exception { // Silently fails and uses the default instance. LazyFieldLite field = new LazyFieldLite(TestUtil.getExtensionRegistry(), ByteString.copyFromUtf8("invalid")); - assertEquals( - TestAllTypes.getDefaultInstance(), field.getValue(TestAllTypes.getDefaultInstance())); - assertEquals(0, field.getSerializedSize()); - assertEquals(ByteString.EMPTY, field.toByteString()); + assertThat( + field.getValue(TestAllTypes.getDefaultInstance())) + .isEqualTo(TestAllTypes.getDefaultInstance()); + assertThat(field.getSerializedSize()).isEqualTo(0); + assertThat(field.toByteString()).isEqualTo(ByteString.EMPTY); } + @Test public void testMergeBeforeParsing() throws Exception { TestAllTypes message1 = TestAllTypes.newBuilder().setOptionalInt32(1).build(); LazyFieldLite field1 = createLazyFieldLiteFromMessage(message1); @@ -147,9 +160,10 @@ field1.merge(field2); TestAllTypes expected = TestAllTypes.newBuilder().setOptionalInt32(1).setOptionalInt64(2).build(); - assertEquals(expected, field1.getValue(TestAllTypes.getDefaultInstance())); + assertThat(field1.getValue(TestAllTypes.getDefaultInstance())).isEqualTo(expected); } + @Test public void testMergeOneNotParsed() throws Exception { // Test a few different paths that involve one message that was not parsed. TestAllTypes message1 = TestAllTypes.newBuilder().setOptionalInt32(1).build(); @@ -161,16 +175,17 @@ field1.getValue(TestAllTypes.getDefaultInstance()); // Force parsing. LazyFieldLite field2 = createLazyFieldLiteFromMessage(message2); field1.merge(field2); - assertEquals(expected, field1.getValue(TestAllTypes.getDefaultInstance())); + assertThat(field1.getValue(TestAllTypes.getDefaultInstance())).isEqualTo(expected); // Now reverse which one is parsed first. field1 = LazyFieldLite.fromValue(message1); field2 = createLazyFieldLiteFromMessage(message2); field2.getValue(TestAllTypes.getDefaultInstance()); // Force parsing. field1.merge(field2); - assertEquals(expected, field1.getValue(TestAllTypes.getDefaultInstance())); + assertThat(field1.getValue(TestAllTypes.getDefaultInstance())).isEqualTo(expected); } + @Test public void testMergeInvalid() throws Exception { // Test a few different paths that involve one message that was not parsed. TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(1).build(); @@ -180,9 +195,10 @@ invalid.merge(valid); // We swallow the exception and just use the set field. - assertEquals(message, invalid.getValue(TestAllTypes.getDefaultInstance())); + assertThat(invalid.getValue(TestAllTypes.getDefaultInstance())).isEqualTo(message); } + @Test public void testMergeKeepsExtensionsWhenPossible() throws Exception { // In this test we attempt to only use the empty registry, which will strip out all extensions // when serializing and then parsing. We verify that each code path will attempt to not @@ -190,32 +206,36 @@ // extensionRegistry. TestAllExtensions messageWithExtensions = TestAllExtensions.newBuilder().setExtension(optionalInt32Extension, 42).build(); - TestAllExtensions emptyMessage = TestAllExtensions.newBuilder().build(); + TestAllExtensions emptyMessage = TestAllExtensions.getDefaultInstance(); ExtensionRegistryLite emptyRegistry = ExtensionRegistryLite.getEmptyRegistry(); LazyFieldLite field = LazyFieldLite.fromValue(messageWithExtensions); field.merge(createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage)); - assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance())); + assertThat(field.getValue(TestAllExtensions.getDefaultInstance())) + .isEqualTo(messageWithExtensions); // Now reverse the order of the merging. field = createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage); field.merge(LazyFieldLite.fromValue(messageWithExtensions)); - assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance())); + assertThat(field.getValue(TestAllExtensions.getDefaultInstance())) + .isEqualTo(messageWithExtensions); // Now try parsing the empty field first. field = LazyFieldLite.fromValue(messageWithExtensions); LazyFieldLite other = createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage); other.getValue(TestAllExtensions.getDefaultInstance()); // Force parsing. field.merge(other); - assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance())); + assertThat(field.getValue(TestAllExtensions.getDefaultInstance())) + .isEqualTo(messageWithExtensions); // And again reverse. field = createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage); field.getValue(TestAllExtensions.getDefaultInstance()); // Force parsing. other = LazyFieldLite.fromValue(messageWithExtensions); field.merge(other); - assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance())); + assertThat(field.getValue(TestAllExtensions.getDefaultInstance())) + .isEqualTo(messageWithExtensions); } @@ -239,7 +259,8 @@ } private void assertNotEqual(Object unexpected, Object actual) { - assertFalse(unexpected == actual || (unexpected != null && unexpected.equals(actual))); + assertThat(unexpected).isNotSameInstanceAs(actual); + assertThat((unexpected != null && unexpected.equals(actual))).isFalse(); } }
diff --git a/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java b/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java index a3901e9..dbda3bd 100644 --- a/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java
@@ -30,71 +30,79 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import protobuf_unittest.UnittestProto.TestAllExtensions; import protobuf_unittest.UnittestProto.TestAllTypes; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Unit test for {@link LazyField}. - * - * @author xiangl@google.com (Xiang Li) - */ -public class LazyFieldTest extends TestCase { +/** Unit test for {@link LazyField}. */ +@RunWith(JUnit4.class) +public class LazyFieldTest { + + @Test public void testHashCode() { MessageLite message = TestUtil.getAllSet(); LazyField lazyField = createLazyFieldFromMessage(message); - assertEquals(message.hashCode(), lazyField.hashCode()); + assertThat(message.hashCode()).isEqualTo(lazyField.hashCode()); lazyField.getValue(); - assertEquals(message.hashCode(), lazyField.hashCode()); + assertThat(message.hashCode()).isEqualTo(lazyField.hashCode()); changeValue(lazyField); // make sure two messages have different hash code assertNotEqual(message.hashCode(), lazyField.hashCode()); } + @Test public void testHashCodeEx() throws Exception { TestAllExtensions message = TestUtil.getAllExtensionsSet(); LazyField lazyField = createLazyFieldFromMessage(message); - assertEquals(message.hashCode(), lazyField.hashCode()); + assertThat(message.hashCode()).isEqualTo(lazyField.hashCode()); lazyField.getValue(); - assertEquals(message.hashCode(), lazyField.hashCode()); + assertThat(message.hashCode()).isEqualTo(lazyField.hashCode()); changeValue(lazyField); // make sure two messages have different hash code assertNotEqual(message.hashCode(), lazyField.hashCode()); } + @Test public void testGetValue() { MessageLite message = TestUtil.getAllSet(); LazyField lazyField = createLazyFieldFromMessage(message); - assertEquals(message, lazyField.getValue()); + assertThat(message).isEqualTo(lazyField.getValue()); changeValue(lazyField); assertNotEqual(message, lazyField.getValue()); } + @Test public void testGetValueEx() throws Exception { TestAllExtensions message = TestUtil.getAllExtensionsSet(); LazyField lazyField = createLazyFieldFromMessage(message); - assertEquals(message, lazyField.getValue()); + assertThat(message).isEqualTo(lazyField.getValue()); changeValue(lazyField); assertNotEqual(message, lazyField.getValue()); } + @Test public void testEqualsObject() { MessageLite message = TestUtil.getAllSet(); LazyField lazyField = createLazyFieldFromMessage(message); - assertTrue(lazyField.equals(message)); + assertThat(lazyField).isEqualTo(message); changeValue(lazyField); - assertFalse(lazyField.equals(message)); - assertFalse(message.equals(lazyField.getValue())); + assertThat(lazyField).isNotEqualTo(message); + assertThat(message).isNotEqualTo(lazyField.getValue()); } - @SuppressWarnings("EqualsIncompatibleType") // LazyField.equals() is not symmetric + @Test + @SuppressWarnings("TruthIncompatibleType") // LazyField.equals() is not symmetric public void testEqualsObjectEx() throws Exception { TestAllExtensions message = TestUtil.getAllExtensionsSet(); LazyField lazyField = createLazyFieldFromMessage(message); - assertTrue(lazyField.equals(message)); + assertThat(lazyField).isEqualTo(message); changeValue(lazyField); - assertFalse(lazyField.equals(message)); - assertFalse(message.equals(lazyField.getValue())); + assertThat(lazyField).isNotEqualTo(message); + assertThat(message).isNotEqualTo(lazyField.getValue()); } // Help methods. @@ -113,6 +121,7 @@ } private void assertNotEqual(Object unexpected, Object actual) { - assertFalse(unexpected == actual || (unexpected != null && unexpected.equals(actual))); + assertThat(unexpected).isNotSameInstanceAs(actual); + assertThat((unexpected != null && unexpected.equals(actual))).isFalse(); } }
diff --git a/java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java b/java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java index c5880d5..576feea 100644 --- a/java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
@@ -30,30 +30,23 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import protobuf_unittest.LazyFieldsLite.LazyExtension; import protobuf_unittest.LazyFieldsLite.LazyInnerMessageLite; import protobuf_unittest.LazyFieldsLite.LazyMessageLite; import protobuf_unittest.LazyFieldsLite.LazyNestedInnerMessageLite; import java.util.ArrayList; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Unit test for messages with lazy fields. - * - * @author niwasaki@google.com (Naoki Iwasaki) - */ -public class LazyMessageLiteTest extends TestCase { +/** Unit test for messages with lazy fields. */ +@RunWith(JUnit4.class) +public class LazyMessageLiteTest { - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - + @Test public void testSetValues() { LazyNestedInnerMessageLite nested = LazyNestedInnerMessageLite.newBuilder().setNum(3).build(); LazyInnerMessageLite inner = @@ -66,24 +59,28 @@ .setOneofInner(inner) .build(); - assertEquals(1, outer.getNum()); - assertEquals(421, outer.getNumWithDefault()); + assertThat(outer.getNum()).isEqualTo(1); + assertThat(outer.getNumWithDefault()).isEqualTo(421); - assertEquals(2, outer.getInner().getNum()); - assertEquals(42, outer.getInner().getNumWithDefault()); + assertThat(outer.getInner().getNum()).isEqualTo(2); + assertThat(outer.getInner().getNumWithDefault()).isEqualTo(42); - assertEquals(3, outer.getInner().getNested().getNum()); - assertEquals(4, outer.getInner().getNested().getNumWithDefault()); + assertThat(outer.getInner().getNum()).isEqualTo(2); + assertThat(outer.getInner().getNumWithDefault()).isEqualTo(42); - assertFalse(outer.hasOneofNum()); - assertTrue(outer.hasOneofInner()); + assertThat(outer.getInner().getNested().getNum()).isEqualTo(3); + assertThat(outer.getInner().getNested().getNumWithDefault()).isEqualTo(4); - assertEquals(2, outer.getOneofInner().getNum()); - assertEquals(42, outer.getOneofInner().getNumWithDefault()); - assertEquals(3, outer.getOneofInner().getNested().getNum()); - assertEquals(4, outer.getOneofInner().getNested().getNumWithDefault()); + assertThat(outer.hasOneofNum()).isFalse(); + assertThat(outer.hasOneofInner()).isTrue(); + + assertThat(outer.getOneofInner().getNum()).isEqualTo(2); + assertThat(outer.getOneofInner().getNumWithDefault()).isEqualTo(42); + assertThat(outer.getOneofInner().getNested().getNum()).isEqualTo(3); + assertThat(outer.getOneofInner().getNested().getNumWithDefault()).isEqualTo(4); } + @Test public void testSetRepeatedValues() { LazyMessageLite outer = LazyMessageLite.newBuilder() @@ -92,12 +89,13 @@ .addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(122)) .build(); - assertEquals(1, outer.getNum()); - assertEquals(2, outer.getRepeatedInnerCount()); - assertEquals(119, outer.getRepeatedInner(0).getNum()); - assertEquals(122, outer.getRepeatedInner(1).getNum()); + assertThat(outer.getNum()).isEqualTo(1); + assertThat(outer.getRepeatedInnerCount()).isEqualTo(2); + assertThat(outer.getRepeatedInner(0).getNum()).isEqualTo(119); + assertThat(outer.getRepeatedInner(1).getNum()).isEqualTo(122); } + @Test public void testRepeatedMutability() throws Exception { LazyMessageLite outer = LazyMessageLite.newBuilder() @@ -105,14 +103,17 @@ .addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(122)) .build(); - outer = LazyMessageLite.parseFrom(outer.toByteArray()); + outer = + LazyMessageLite.parseFrom(outer.toByteArray(), + ExtensionRegistryLite.getEmptyRegistry()); try { outer.getRepeatedInnerList().set(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException expected) { } } + @Test public void testAddAll() { ArrayList<LazyInnerMessageLite> inners = new ArrayList<>(); int count = 4; @@ -122,51 +123,53 @@ } LazyMessageLite outer = LazyMessageLite.newBuilder().addAllRepeatedInner(inners).build(); - assertEquals(count, outer.getRepeatedInnerCount()); + assertThat(outer.getRepeatedInnerCount()).isEqualTo(count); for (int i = 0; i < count; i++) { - assertEquals(i, outer.getRepeatedInner(i).getNum()); + assertThat(outer.getRepeatedInner(i).getNum()).isEqualTo(i); } } + @Test public void testGetDefaultValues() { LazyMessageLite outer = LazyMessageLite.getDefaultInstance(); - assertEquals(0, outer.getNum()); - assertEquals(421, outer.getNumWithDefault()); + assertThat(outer.getNum()).isEqualTo(0); + assertThat(outer.getNumWithDefault()).isEqualTo(421); - assertEquals(0, outer.getInner().getNum()); - assertEquals(42, outer.getInner().getNumWithDefault()); + assertThat(outer.getInner().getNum()).isEqualTo(0); + assertThat(outer.getInner().getNumWithDefault()).isEqualTo(42); - assertEquals(0, outer.getInner().getNested().getNum()); - assertEquals(4, outer.getInner().getNested().getNumWithDefault()); + assertThat(outer.getInner().getNested().getNum()).isEqualTo(0); + assertThat(outer.getInner().getNested().getNumWithDefault()).isEqualTo(4); - assertEquals(0, outer.getOneofNum()); + assertThat(outer.getOneofNum()).isEqualTo(0); - assertEquals(0, outer.getOneofInner().getNum()); - assertEquals(42, outer.getOneofInner().getNumWithDefault()); - assertEquals(0, outer.getOneofInner().getNested().getNum()); - assertEquals(4, outer.getOneofInner().getNested().getNumWithDefault()); + assertThat(outer.getOneofInner().getNum()).isEqualTo(0); + assertThat(outer.getOneofInner().getNumWithDefault()).isEqualTo(42); + assertThat(outer.getOneofInner().getNested().getNum()).isEqualTo(0); + assertThat(outer.getOneofInner().getNested().getNumWithDefault()).isEqualTo(4); } + @Test public void testClearValues() { LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder().setNum(115).build(); LazyMessageLite.Builder outerBuilder = LazyMessageLite.newBuilder(); - assertEquals(0, outerBuilder.build().getNum()); + assertThat(outerBuilder.build().getNum()).isEqualTo(0); // Set/Clear num outerBuilder.setNum(100); - assertEquals(100, outerBuilder.build().getNum()); - assertEquals(421, outerBuilder.build().getNumWithDefault()); - assertFalse(outerBuilder.build().hasInner()); + assertThat(outerBuilder.build().getNum()).isEqualTo(100); + assertThat(outerBuilder.build().getNumWithDefault()).isEqualTo(421); + assertThat(outerBuilder.build().hasInner()).isFalse(); outerBuilder.clearNum(); - assertEquals(0, outerBuilder.build().getNum()); - assertEquals(421, outerBuilder.build().getNumWithDefault()); - assertFalse(outerBuilder.build().hasInner()); + assertThat(outerBuilder.build().getNum()).isEqualTo(0); + assertThat(outerBuilder.build().getNumWithDefault()).isEqualTo(421); + assertThat(outerBuilder.build().hasInner()).isFalse(); // Set/Clear all outerBuilder @@ -177,28 +180,29 @@ .setOneofInner(LazyInnerMessageLite.newBuilder().setNum(123)); LazyMessageLite outer = outerBuilder.build(); - assertEquals(100, outer.getNum()); - assertEquals(421, outer.getNumWithDefault()); - assertTrue(outer.hasInner()); - assertEquals(115, outer.getInner().getNum()); - assertEquals(2, outer.getRepeatedInnerCount()); - assertEquals(119, outer.getRepeatedInner(0).getNum()); - assertEquals(122, outer.getRepeatedInner(1).getNum()); - assertTrue(outer.hasOneofInner()); - assertEquals(123, outer.getOneofInner().getNum()); + assertThat(outer.getNum()).isEqualTo(100); + assertThat(outer.getNumWithDefault()).isEqualTo(421); + assertThat(outer.hasInner()).isTrue(); + assertThat(outer.getInner().getNum()).isEqualTo(115); + assertThat(outer.getRepeatedInnerCount()).isEqualTo(2); + assertThat(outer.getRepeatedInner(0).getNum()).isEqualTo(119); + assertThat(outer.getRepeatedInner(1).getNum()).isEqualTo(122); + assertThat(outer.hasOneofInner()).isTrue(); + assertThat(outer.getOneofInner().getNum()).isEqualTo(123); outerBuilder.clear(); outer = outerBuilder.build(); - assertEquals(0, outer.getNum()); - assertEquals(421, outer.getNumWithDefault()); - assertFalse(outer.hasInner()); - assertEquals(0, outer.getRepeatedInnerCount()); - assertFalse(outer.hasOneofInner()); - assertEquals(0, outer.getOneofInner().getNum()); + assertThat(outer.getNum()).isEqualTo(0); + assertThat(outer.getNumWithDefault()).isEqualTo(421); + assertThat(outer.hasInner()).isFalse(); + assertThat(outer.getRepeatedInnerCount()).isEqualTo(0); + assertThat(outer.hasOneofInner()).isFalse(); + assertThat(outer.getOneofInner().getNum()).isEqualTo(0); } + @Test public void testMergeValues() { LazyMessageLite outerBase = LazyMessageLite.newBuilder().setNumWithDefault(122).build(); @@ -211,14 +215,15 @@ .build(); LazyMessageLite merged = LazyMessageLite.newBuilder(outerBase).mergeFrom(outerMerging).build(); - assertEquals(119, merged.getNum()); - assertEquals(122, merged.getNumWithDefault()); - assertEquals(115, merged.getInner().getNum()); - assertEquals(42, merged.getInner().getNumWithDefault()); - assertEquals(115, merged.getOneofInner().getNum()); - assertEquals(42, merged.getOneofInner().getNumWithDefault()); + assertThat(merged.getNum()).isEqualTo(119); + assertThat(merged.getNumWithDefault()).isEqualTo(122); + assertThat(merged.getInner().getNum()).isEqualTo(115); + assertThat(merged.getInner().getNumWithDefault()).isEqualTo(42); + assertThat(merged.getOneofInner().getNum()).isEqualTo(115); + assertThat(merged.getOneofInner().getNumWithDefault()).isEqualTo(42); } + @Test public void testMergeDefaultValues() { LazyInnerMessageLite innerBase = LazyInnerMessageLite.newBuilder().setNum(115).build(); LazyMessageLite outerBase = @@ -233,15 +238,16 @@ LazyMessageLite merged = LazyMessageLite.newBuilder(outerBase).mergeFrom(outerMerging).build(); // Merging default-instance shouldn't overwrite values in the base message. - assertEquals(119, merged.getNum()); - assertEquals(122, merged.getNumWithDefault()); - assertEquals(115, merged.getInner().getNum()); - assertEquals(42, merged.getInner().getNumWithDefault()); - assertEquals(115, merged.getOneofInner().getNum()); - assertEquals(42, merged.getOneofInner().getNumWithDefault()); + assertThat(merged.getNum()).isEqualTo(119); + assertThat(merged.getNumWithDefault()).isEqualTo(122); + assertThat(merged.getInner().getNum()).isEqualTo(115); + assertThat(merged.getInner().getNumWithDefault()).isEqualTo(42); + assertThat(merged.getOneofInner().getNum()).isEqualTo(115); + assertThat(merged.getOneofInner().getNumWithDefault()).isEqualTo(42); } // Regression test for b/28198805. + @Test public void testMergeOneofMessages() throws Exception { LazyInnerMessageLite inner = LazyInnerMessageLite.getDefaultInstance(); LazyMessageLite outer = LazyMessageLite.newBuilder().setOneofInner(inner).build(); @@ -254,10 +260,11 @@ // Check that the 'outer' stays the same. ByteString data2 = outer.toByteString(); - assertEquals(data1, data2); - assertEquals(0, outer.getOneofInner().getNum()); + assertThat(data1).isEqualTo(data2); + assertThat(outer.getOneofInner().getNum()).isEqualTo(0); } + @Test public void testSerialize() throws InvalidProtocolBufferException { LazyNestedInnerMessageLite nested = LazyNestedInnerMessageLite.newBuilder().setNum(3).build(); LazyInnerMessageLite inner = @@ -266,40 +273,42 @@ LazyMessageLite.newBuilder().setNum(1).setInner(inner).setOneofInner(inner).build(); ByteString bytes = outer.toByteString(); - assertEquals(bytes.size(), outer.getSerializedSize()); + assertThat(bytes.size()).isEqualTo(outer.getSerializedSize()); - LazyMessageLite deserialized = LazyMessageLite.parseFrom(bytes); + LazyMessageLite deserialized = + LazyMessageLite.parseFrom(bytes, ExtensionRegistryLite.getEmptyRegistry()); - assertEquals(1, deserialized.getNum()); - assertEquals(421, deserialized.getNumWithDefault()); + assertThat(deserialized.getNum()).isEqualTo(1); + assertThat(deserialized.getNumWithDefault()).isEqualTo(421); - assertEquals(2, deserialized.getInner().getNum()); - assertEquals(42, deserialized.getInner().getNumWithDefault()); + assertThat(deserialized.getInner().getNum()).isEqualTo(2); + assertThat(deserialized.getInner().getNumWithDefault()).isEqualTo(42); - assertEquals(3, deserialized.getInner().getNested().getNum()); - assertEquals(4, deserialized.getInner().getNested().getNumWithDefault()); + assertThat(deserialized.getInner().getNested().getNum()).isEqualTo(3); + assertThat(deserialized.getInner().getNested().getNumWithDefault()).isEqualTo(4); - assertEquals(2, deserialized.getOneofInner().getNum()); - assertEquals(42, deserialized.getOneofInner().getNumWithDefault()); - assertEquals(3, deserialized.getOneofInner().getNested().getNum()); - assertEquals(4, deserialized.getOneofInner().getNested().getNumWithDefault()); + assertThat(deserialized.getOneofInner().getNum()).isEqualTo(2); + assertThat(deserialized.getOneofInner().getNumWithDefault()).isEqualTo(42); + assertThat(deserialized.getOneofInner().getNested().getNum()).isEqualTo(3); + assertThat(deserialized.getOneofInner().getNested().getNumWithDefault()).isEqualTo(4); - assertEquals(bytes, deserialized.toByteString()); + assertThat(deserialized.toByteString()).isEqualTo(bytes); } + @Test public void testExtensions() throws Exception { LazyInnerMessageLite.Builder innerBuilder = LazyInnerMessageLite.newBuilder(); innerBuilder.setExtension( LazyExtension.extension, LazyExtension.newBuilder().setName("name").build()); - assertTrue(innerBuilder.hasExtension(LazyExtension.extension)); - assertEquals("name", innerBuilder.getExtension(LazyExtension.extension).getName()); + assertThat(innerBuilder.hasExtension(LazyExtension.extension)).isTrue(); + assertThat(innerBuilder.getExtension(LazyExtension.extension).getName()).isEqualTo("name"); LazyInnerMessageLite innerMessage = innerBuilder.build(); - assertTrue(innerMessage.hasExtension(LazyExtension.extension)); - assertEquals("name", innerMessage.getExtension(LazyExtension.extension).getName()); + assertThat(innerMessage.hasExtension(LazyExtension.extension)).isTrue(); + assertThat(innerMessage.getExtension(LazyExtension.extension).getName()).isEqualTo("name"); LazyMessageLite lite = LazyMessageLite.newBuilder().setInner(innerMessage).build(); - assertTrue(lite.getInner().hasExtension(LazyExtension.extension)); - assertEquals("name", lite.getInner().getExtension(LazyExtension.extension).getName()); + assertThat(lite.getInner().hasExtension(LazyExtension.extension)).isTrue(); + assertThat(lite.getInner().getExtension(LazyExtension.extension).getName()).isEqualTo("name"); } }
diff --git a/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java b/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java index 24d0038..1ef03ce 100644 --- a/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
@@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static java.util.Arrays.asList; import java.util.ArrayList; @@ -37,14 +39,13 @@ import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.List; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Tests for {@link LazyStringArrayList}. - * - * @author jonp@google.com (Jon Perlow) - */ -public class LazyStringArrayListTest extends TestCase { +/** Tests for {@link LazyStringArrayList}. */ +@RunWith(JUnit4.class) +public class LazyStringArrayListTest { private static final String STRING_A = "A"; private static final String STRING_B = "B"; @@ -54,53 +55,56 @@ private static final ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B"); private static final ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C"); + @Test public void testJustStrings() { LazyStringArrayList list = new LazyStringArrayList(); list.add(STRING_A); list.add(STRING_B); list.add(STRING_C); - assertEquals(3, list.size()); - assertSame(STRING_A, list.get(0)); - assertSame(STRING_B, list.get(1)); - assertSame(STRING_C, list.get(2)); + assertThat(list).hasSize(3); + assertThat(list.get(0)).isSameInstanceAs(STRING_A); + assertThat(list.get(1)).isSameInstanceAs(STRING_B); + assertThat(list.get(2)).isSameInstanceAs(STRING_C); list.set(1, STRING_C); - assertSame(STRING_C, list.get(1)); + assertThat(list.get(1)).isSameInstanceAs(STRING_C); list.remove(1); - assertSame(STRING_A, list.get(0)); - assertSame(STRING_C, list.get(1)); + assertThat(list.get(0)).isSameInstanceAs(STRING_A); + assertThat(list.get(1)).isSameInstanceAs(STRING_C); List<ByteString> byteStringList = list.asByteStringList(); - assertEquals(BYTE_STRING_A, byteStringList.get(0)); - assertEquals(BYTE_STRING_C, byteStringList.get(1)); + assertThat(byteStringList.get(0)).isEqualTo(BYTE_STRING_A); + assertThat(byteStringList.get(1)).isEqualTo(BYTE_STRING_C); // Underlying list should be transformed. - assertSame(byteStringList.get(0), list.getByteString(0)); - assertSame(byteStringList.get(1), list.getByteString(1)); + assertThat(byteStringList.get(0)).isSameInstanceAs(list.getByteString(0)); + assertThat(byteStringList.get(1)).isSameInstanceAs(list.getByteString(1)); } + @Test public void testJustByteString() { LazyStringArrayList list = new LazyStringArrayList(); list.add(BYTE_STRING_A); list.add(BYTE_STRING_B); list.add(BYTE_STRING_C); - assertEquals(3, list.size()); - assertSame(BYTE_STRING_A, list.getByteString(0)); - assertSame(BYTE_STRING_B, list.getByteString(1)); - assertSame(BYTE_STRING_C, list.getByteString(2)); + assertThat(list).hasSize(3); + assertThat(list.getByteString(0)).isSameInstanceAs(BYTE_STRING_A); + assertThat(list.getByteString(1)).isSameInstanceAs(BYTE_STRING_B); + assertThat(list.getByteString(2)).isSameInstanceAs(BYTE_STRING_C); list.remove(1); - assertSame(BYTE_STRING_A, list.getByteString(0)); - assertSame(BYTE_STRING_C, list.getByteString(1)); + assertThat(list.getByteString(0)).isSameInstanceAs(BYTE_STRING_A); + assertThat(list.getByteString(1)).isSameInstanceAs(BYTE_STRING_C); List<ByteString> byteStringList = list.asByteStringList(); - assertSame(BYTE_STRING_A, byteStringList.get(0)); - assertSame(BYTE_STRING_C, byteStringList.get(1)); + assertThat(byteStringList.get(0)).isSameInstanceAs(BYTE_STRING_A); + assertThat(byteStringList.get(1)).isSameInstanceAs(BYTE_STRING_C); } + @Test public void testConversionBackAndForth() { LazyStringArrayList list = new LazyStringArrayList(); list.add(STRING_A); @@ -108,33 +112,34 @@ list.add(BYTE_STRING_C); // String a should be the same because it was originally a string - assertSame(STRING_A, list.get(0)); + assertThat(list.get(0)).isSameInstanceAs(STRING_A); // String b and c should be different because the string has to be computed // from the ByteString String bPrime = list.get(1); - assertNotSame(STRING_B, bPrime); - assertEquals(STRING_B, bPrime); + assertThat(bPrime).isNotSameInstanceAs(STRING_B); + assertThat(bPrime).isEqualTo(STRING_B); String cPrime = list.get(2); - assertNotSame(STRING_C, cPrime); - assertEquals(STRING_C, cPrime); + assertThat(cPrime).isNotSameInstanceAs(STRING_C); + assertThat(cPrime).isEqualTo(STRING_C); // String c and c should stay the same once cached. - assertSame(bPrime, list.get(1)); - assertSame(cPrime, list.get(2)); + assertThat(list.get(1)).isSameInstanceAs(bPrime); + assertThat(list.get(2)).isSameInstanceAs(cPrime); // ByteString needs to be computed from string for both a and b ByteString aPrimeByteString = list.getByteString(0); - assertEquals(BYTE_STRING_A, aPrimeByteString); + assertThat(aPrimeByteString).isEqualTo(BYTE_STRING_A); ByteString bPrimeByteString = list.getByteString(1); - assertNotSame(BYTE_STRING_B, bPrimeByteString); - assertEquals(BYTE_STRING_B, list.getByteString(1)); + assertThat(bPrimeByteString).isNotSameInstanceAs(BYTE_STRING_B); + assertThat(list.getByteString(1)).isEqualTo(BYTE_STRING_B); // Once cached, ByteString should stay cached. - assertSame(aPrimeByteString, list.getByteString(0)); - assertSame(bPrimeByteString, list.getByteString(1)); + assertThat(list.getByteString(0)).isSameInstanceAs(aPrimeByteString); + assertThat(list.getByteString(1)).isSameInstanceAs(bPrimeByteString); } + @Test public void testCopyConstructorCopiesByReference() { LazyStringArrayList list1 = new LazyStringArrayList(); list1.add(STRING_A); @@ -142,25 +147,27 @@ list1.add(BYTE_STRING_C); LazyStringArrayList list2 = new LazyStringArrayList(list1); - assertEquals(3, list2.size()); - assertSame(STRING_A, list2.get(0)); - assertSame(BYTE_STRING_B, list2.getByteString(1)); - assertSame(BYTE_STRING_C, list2.getByteString(2)); + assertThat(list2).hasSize(3); + assertThat(list2.get(0)).isSameInstanceAs(STRING_A); + assertThat(list2.getByteString(1)).isSameInstanceAs(BYTE_STRING_B); + assertThat(list2.getByteString(2)).isSameInstanceAs(BYTE_STRING_C); } + @Test public void testListCopyConstructor() { - List<String> list1 = new ArrayList<String>(); + List<String> list1 = new ArrayList<>(); list1.add(STRING_A); list1.add(STRING_B); list1.add(STRING_C); LazyStringArrayList list2 = new LazyStringArrayList(list1); - assertEquals(3, list2.size()); - assertSame(STRING_A, list2.get(0)); - assertSame(STRING_B, list2.get(1)); - assertSame(STRING_C, list2.get(2)); + assertThat(list2).hasSize(3); + assertThat(list2.get(0)).isSameInstanceAs(STRING_A); + assertThat(list2.get(1)).isSameInstanceAs(STRING_B); + assertThat(list2.get(2)).isSameInstanceAs(STRING_C); } + @Test public void testAddAllCopiesByReferenceIfPossible() { LazyStringArrayList list1 = new LazyStringArrayList(); list1.add(STRING_A); @@ -170,19 +177,20 @@ LazyStringArrayList list2 = new LazyStringArrayList(); list2.addAll(list1); - assertEquals(3, list2.size()); - assertSame(STRING_A, list2.get(0)); - assertSame(BYTE_STRING_B, list2.getByteString(1)); - assertSame(BYTE_STRING_C, list2.getByteString(2)); + assertThat(list2).hasSize(3); + assertThat(list2.get(0)).isSameInstanceAs(STRING_A); + assertThat(list2.getByteString(1)).isSameInstanceAs(BYTE_STRING_B); + assertThat(list2.getByteString(2)).isSameInstanceAs(BYTE_STRING_C); } + @Test public void testModificationWithIteration() { LazyStringArrayList list = new LazyStringArrayList(); list.addAll(asList(STRING_A, STRING_B, STRING_C)); Iterator<String> iterator = list.iterator(); - assertEquals(3, list.size()); - assertEquals(STRING_A, list.get(0)); - assertEquals(STRING_A, iterator.next()); + assertThat(list).hasSize(3); + assertThat(list.get(0)).isEqualTo(STRING_A); + assertThat(iterator.next()).isSameInstanceAs(STRING_A); // Does not structurally modify. iterator = list.iterator(); @@ -192,7 +200,7 @@ list.remove(0); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail();; } catch (ConcurrentModificationException e) { // expected } @@ -201,12 +209,13 @@ list.add(0, STRING_C); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail();; } catch (ConcurrentModificationException e) { // expected } } + @Test public void testMakeImmutable() { LazyStringArrayList list = new LazyStringArrayList(); list.add(STRING_A); @@ -220,54 +229,55 @@ try { list.add(BYTE_STRING_A.toByteArray()); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.add(BYTE_STRING_A); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.addAllByteArray(Collections.singletonList(BYTE_STRING_A.toByteArray())); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.addAllByteString(asList(BYTE_STRING_A)); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.mergeFrom(new LazyStringArrayList()); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.set(0, BYTE_STRING_A.toByteArray()); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.set(0, BYTE_STRING_A); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } } + @Test public void testImmutabilityPropagation() { LazyStringArrayList list = new LazyStringArrayList(); list.add(STRING_A); @@ -281,81 +291,80 @@ assertGenericListImmutable(byteArrayList, byteArrayList.get(0)); } - @SuppressWarnings("unchecked") private static <T> void assertGenericListImmutable(List<T> list, T value) { try { list.add(value); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.add(0, value); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.addAll(asList(value)); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, asList(value)); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.clear(); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.remove(0); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.remove(value); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(asList(value)); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(asList()); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(asList()); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected } try { list.set(0, value); - fail(); + assertWithMessage("expected exception").fail();; } catch (UnsupportedOperationException e) { // expected }
diff --git a/java/core/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java b/java/core/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java index 18c9c74..006ba38 100644 --- a/java/core/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java
@@ -30,16 +30,21 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import protobuf_unittest.UnittestProto; import java.io.IOException; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** - * Tests to make sure the lazy conversion of UTF8-encoded byte arrays to strings works correctly. - * - * @author jonp@google.com (Jon Perlow) + * Tests to make sure the lazy conversion of UTF8-encoded byte arrays to strings works + * correctly. */ -public class LazyStringEndToEndTest extends TestCase { +@RunWith(JUnit4.class) +public class LazyStringEndToEndTest { private static final ByteString TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8 = ByteString.copyFrom( @@ -50,9 +55,8 @@ private ByteString encodedTestAllTypes; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { this.encodedTestAllTypes = UnittestProto.TestAllTypes.newBuilder() .setOptionalString("foo") @@ -63,27 +67,34 @@ } /** Tests that an invalid UTF8 string will roundtrip through a parse and serialization. */ + @Test public void testParseAndSerialize() throws InvalidProtocolBufferException { UnittestProto.TestAllTypes tV2 = - UnittestProto.TestAllTypes.parseFrom(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8); + UnittestProto.TestAllTypes.parseFrom( + TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, + ExtensionRegistryLite.getEmptyRegistry()); ByteString bytes = tV2.toByteString(); - assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes); + assertThat(bytes).isEqualTo(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8); tV2.getOptionalString(); bytes = tV2.toByteString(); - assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes); + assertThat(bytes).isEqualTo(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8); } + @Test public void testParseAndWrite() throws IOException { UnittestProto.TestAllTypes tV2 = - UnittestProto.TestAllTypes.parseFrom(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8); + UnittestProto.TestAllTypes.parseFrom( + TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, + ExtensionRegistryLite.getEmptyRegistry()); byte[] sink = new byte[TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8.size()]; CodedOutputStream outputStream = CodedOutputStream.newInstance(sink); tV2.writeTo(outputStream); outputStream.flush(); - assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, ByteString.copyFrom(sink)); + assertThat(ByteString.copyFrom(sink)).isEqualTo(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8); } + @Test public void testCaching() { String a = "a"; String b = "b"; @@ -96,30 +107,33 @@ .build(); // String should be the one we passed it. - assertSame(a, proto.getOptionalString()); - assertSame(b, proto.getRepeatedString(0)); - assertSame(c, proto.getRepeatedString(1)); + assertThat(proto.getOptionalString()).isSameInstanceAs(a); + assertThat(proto.getRepeatedString(0)).isSameInstanceAs(b); + assertThat(proto.getRepeatedString(1)).isSameInstanceAs(c); // Ensure serialization keeps strings cached. proto.toByteString(); // And now the string should stay cached. - assertSame(a, proto.getOptionalString()); - assertSame(b, proto.getRepeatedString(0)); - assertSame(c, proto.getRepeatedString(1)); + assertThat(proto.getOptionalString()).isSameInstanceAs(a); + assertThat(proto.getRepeatedString(0)).isSameInstanceAs(b); + assertThat(proto.getRepeatedString(1)).isSameInstanceAs(c); } + @Test public void testNoStringCachingIfOnlyBytesAccessed() throws Exception { - UnittestProto.TestAllTypes proto = UnittestProto.TestAllTypes.parseFrom(encodedTestAllTypes); + UnittestProto.TestAllTypes proto = + UnittestProto.TestAllTypes.parseFrom( + encodedTestAllTypes, ExtensionRegistryLite.getEmptyRegistry()); ByteString optional = proto.getOptionalStringBytes(); - assertSame(optional, proto.getOptionalStringBytes()); - assertSame(optional, proto.toBuilder().getOptionalStringBytes()); + assertThat(proto.getOptionalStringBytes()).isSameInstanceAs(optional); + assertThat(proto.toBuilder().getOptionalStringBytes()).isSameInstanceAs(optional); ByteString repeated0 = proto.getRepeatedStringBytes(0); ByteString repeated1 = proto.getRepeatedStringBytes(1); - assertSame(repeated0, proto.getRepeatedStringBytes(0)); - assertSame(repeated1, proto.getRepeatedStringBytes(1)); - assertSame(repeated0, proto.toBuilder().getRepeatedStringBytes(0)); - assertSame(repeated1, proto.toBuilder().getRepeatedStringBytes(1)); + assertThat(proto.getRepeatedStringBytes(0)).isSameInstanceAs(repeated0); + assertThat(proto.getRepeatedStringBytes(1)).isSameInstanceAs(repeated1); + assertThat(proto.toBuilder().getRepeatedStringBytes(0)).isSameInstanceAs(repeated0); + assertThat(proto.toBuilder().getRepeatedStringBytes(1)).isSameInstanceAs(repeated1); } }
diff --git a/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java b/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java index 4177a47..5ec4a93 100644 --- a/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java +++ b/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java
@@ -31,6 +31,7 @@ package com.google.protobuf; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -45,16 +46,18 @@ import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Test {@code LiteralByteString} by setting up a reference string in {@link #setUp()}. This class * is designed to be extended for testing extensions of {@code LiteralByteString} such as {@code * BoundedByteString}, see {@link BoundedByteStringTest}. - * - * @author carlanton@google.com (Carl Haverl) */ -public class LiteralByteStringTest extends TestCase { +@RunWith(JUnit4.class) +public class LiteralByteStringTest { protected static final String UTF_8 = "UTF-8"; protected String classUnderTest; @@ -62,48 +65,56 @@ protected ByteString stringUnderTest; protected int expectedHashCode; - @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { classUnderTest = "LiteralByteString"; referenceBytes = ByteStringTest.getTestBytes(1234, 11337766L); stringUnderTest = ByteString.copyFrom(referenceBytes); expectedHashCode = 331161852; } + @Test public void testExpectedType() { String actualClassName = getActualClassName(stringUnderTest); - assertEquals(classUnderTest + " should match type exactly", classUnderTest, actualClassName); + assertWithMessage("%s should match type exactly", classUnderTest) + .that(classUnderTest) + .isEqualTo(actualClassName); } protected String getActualClassName(Object object) { return object.getClass().getSimpleName(); } + @Test public void testByteAt() { boolean stillEqual = true; for (int i = 0; stillEqual && i < referenceBytes.length; ++i) { stillEqual = (referenceBytes[i] == stringUnderTest.byteAt(i)); } - assertTrue(classUnderTest + " must capture the right bytes", stillEqual); + assertWithMessage("%s must capture the right bytes", classUnderTest).that(stillEqual).isTrue(); } + @Test public void testByteIterator() { boolean stillEqual = true; ByteString.ByteIterator iter = stringUnderTest.iterator(); for (int i = 0; stillEqual && i < referenceBytes.length; ++i) { stillEqual = (iter.hasNext() && referenceBytes[i] == iter.nextByte()); } - assertTrue(classUnderTest + " must capture the right bytes", stillEqual); - assertFalse(classUnderTest + " must have exhausted the iterator", iter.hasNext()); + assertWithMessage("%s must capture the right bytes", classUnderTest).that(stillEqual).isTrue(); + assertWithMessage("%s must have exhausted the iterator", classUnderTest) + .that(iter.hasNext()) + .isFalse(); try { iter.nextByte(); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NoSuchElementException e) { // This is success } } + @Test public void testByteIterable() { boolean stillEqual = true; int j = 0; @@ -111,25 +122,36 @@ stillEqual = (referenceBytes[j] == quantum); ++j; } - assertTrue(classUnderTest + " must capture the right bytes as Bytes", stillEqual); - assertEquals(classUnderTest + " iterable character count", referenceBytes.length, j); + assertWithMessage("%s must capture the right bytes as Bytes", classUnderTest) + .that(stillEqual) + .isTrue(); + assertWithMessage("%s iterable character count", classUnderTest) + .that(referenceBytes) + .hasLength(j); } + @Test public void testSize() { - assertEquals( - classUnderTest + " must have the expected size", - referenceBytes.length, - stringUnderTest.size()); + assertWithMessage("%s must have the expected size", classUnderTest) + .that(referenceBytes.length) + .isEqualTo(stringUnderTest.size()); } + @Test public void testGetTreeDepth() { - assertEquals(classUnderTest + " must have depth 0", 0, stringUnderTest.getTreeDepth()); + assertWithMessage("%s must have depth 0", classUnderTest) + .that(stringUnderTest.getTreeDepth()) + .isEqualTo(0); } + @Test public void testIsBalanced() { - assertTrue(classUnderTest + " is technically balanced", stringUnderTest.isBalanced()); + assertWithMessage("%s is technically balanced", classUnderTest) + .that(stringUnderTest.isBalanced()) + .isTrue(); } + @Test public void testCopyTo_ByteArrayOffsetLength() { int destinationOffset = 50; int length = 100; @@ -140,9 +162,12 @@ for (int i = 0; stillEqual && i < length; ++i) { stillEqual = referenceBytes[i + sourceOffset] == destination[i + destinationOffset]; } - assertTrue(classUnderTest + ".copyTo(4 arg) must give the expected bytes", stillEqual); + assertWithMessage("%s.copyTo(4 arg) must give the expected bytes", classUnderTest) + .that(stillEqual) + .isTrue(); } + @Test public void testCopyTo_ByteArrayOffsetLengthErrors() { int destinationOffset = 50; int length = 100; @@ -152,7 +177,9 @@ // Copy one too many bytes stringUnderTest.copyTo( destination, stringUnderTest.size() + 1 - length, destinationOffset, length); - fail("Should have thrown an exception when copying too many bytes of a " + classUnderTest); + assertWithMessage( + "Should have thrown an exception when copying too many bytes of a %s", classUnderTest) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } @@ -160,9 +187,10 @@ try { // Copy with illegal negative sourceOffset stringUnderTest.copyTo(destination, -1, destinationOffset, length); - fail( - "Should have thrown an exception when given a negative sourceOffset in " - + classUnderTest); + assertWithMessage( + "Should have thrown an exception when given a negative sourceOffset in %s", + classUnderTest) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } @@ -170,9 +198,10 @@ try { // Copy with illegal negative destinationOffset stringUnderTest.copyTo(destination, 0, -1, length); - fail( - "Should have thrown an exception when given a negative destinationOffset in " - + classUnderTest); + assertWithMessage( + "Should have thrown an exception when given a negative destinationOffset in %s", + classUnderTest) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } @@ -180,7 +209,9 @@ try { // Copy with illegal negative size stringUnderTest.copyTo(destination, 0, 0, -1); - fail("Should have thrown an exception when given a negative size in " + classUnderTest); + assertWithMessage( + "Should have thrown an exception when given a negative size in %s", classUnderTest) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } @@ -188,9 +219,10 @@ try { // Copy with illegal too-large sourceOffset stringUnderTest.copyTo(destination, 2 * stringUnderTest.size(), 0, length); - fail( - "Should have thrown an exception when the destinationOffset is too large in " - + classUnderTest); + assertWithMessage( + "Should have thrown an exception when the destinationOffset is too large in %s", + classUnderTest) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } @@ -198,27 +230,33 @@ try { // Copy with illegal too-large destinationOffset stringUnderTest.copyTo(destination, 0, 2 * destination.length, length); - fail( - "Should have thrown an exception when the destinationOffset is too large in " - + classUnderTest); + assertWithMessage( + "Should have thrown an exception when the destinationOffset is too large in %s", + classUnderTest) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } } + @Test public void testCopyTo_ByteBuffer() { ByteBuffer myBuffer = ByteBuffer.allocate(referenceBytes.length); stringUnderTest.copyTo(myBuffer); - assertTrue( - classUnderTest + ".copyTo(ByteBuffer) must give back the same bytes", - Arrays.equals(referenceBytes, myBuffer.array())); + assertWithMessage("%s.copyTo(ByteBuffer) must give back the same bytes", classUnderTest) + .that(Arrays.equals(referenceBytes, myBuffer.array())) + .isTrue(); } + @Test public void testMarkSupported() { InputStream stream = stringUnderTest.newInput(); - assertTrue(classUnderTest + ".newInput() must support marking", stream.markSupported()); + assertWithMessage("%s.newInput() must support marking", classUnderTest) + .that(stream.markSupported()) + .isTrue(); } + @Test public void testMarkAndReset() throws IOException { int fraction = stringUnderTest.size() / 3; @@ -227,16 +265,17 @@ skipFully(stream, fraction); // Skip a large fraction, but not all. int available = stream.available(); - assertTrue( - classUnderTest + ": after skipping to the 'middle', half the bytes are available", - (stringUnderTest.size() - fraction) == available); + assertWithMessage( + "%s: after skipping to the 'middle', half the bytes are available", classUnderTest) + .that((stringUnderTest.size() - fraction) == available) + .isTrue(); stream.reset(); skipFully(stream, stringUnderTest.size()); // Skip to the end. available = stream.available(); - assertTrue( - classUnderTest + ": after skipping to the end, no more bytes are available", - 0 == available); + assertWithMessage("%s: after skipping to the end, no more bytes are available", classUnderTest) + .that(0 == available) + .isTrue(); } /** @@ -272,50 +311,55 @@ } } + @Test public void testAsReadOnlyByteBuffer() { ByteBuffer byteBuffer = stringUnderTest.asReadOnlyByteBuffer(); byte[] roundTripBytes = new byte[referenceBytes.length]; - assertTrue(byteBuffer.remaining() == referenceBytes.length); - assertTrue(byteBuffer.isReadOnly()); + assertThat(byteBuffer.remaining() == referenceBytes.length).isTrue(); + assertThat(byteBuffer.isReadOnly()).isTrue(); byteBuffer.get(roundTripBytes); - assertTrue( - classUnderTest + ".asReadOnlyByteBuffer() must give back the same bytes", - Arrays.equals(referenceBytes, roundTripBytes)); + assertWithMessage("%s.asReadOnlyByteBuffer() must give back the same bytes", classUnderTest) + .that(Arrays.equals(referenceBytes, roundTripBytes)) + .isTrue(); } + @Test public void testAsReadOnlyByteBufferList() { List<ByteBuffer> byteBuffers = stringUnderTest.asReadOnlyByteBufferList(); int bytesSeen = 0; byte[] roundTripBytes = new byte[referenceBytes.length]; for (ByteBuffer byteBuffer : byteBuffers) { int thisLength = byteBuffer.remaining(); - assertTrue(byteBuffer.isReadOnly()); - assertTrue(bytesSeen + thisLength <= referenceBytes.length); + assertThat(byteBuffer.isReadOnly()).isTrue(); + assertThat(bytesSeen + thisLength <= referenceBytes.length).isTrue(); byteBuffer.get(roundTripBytes, bytesSeen, thisLength); bytesSeen += thisLength; } - assertTrue(bytesSeen == referenceBytes.length); - assertTrue( - classUnderTest + ".asReadOnlyByteBufferTest() must give back the same bytes", - Arrays.equals(referenceBytes, roundTripBytes)); + assertThat(bytesSeen == referenceBytes.length).isTrue(); + assertWithMessage("%s.asReadOnlyByteBufferTest() must give back the same bytes", classUnderTest) + .that(Arrays.equals(referenceBytes, roundTripBytes)) + .isTrue(); } + @Test public void testToByteArray() { byte[] roundTripBytes = stringUnderTest.toByteArray(); - assertTrue( - classUnderTest + ".toByteArray() must give back the same bytes", - Arrays.equals(referenceBytes, roundTripBytes)); + assertWithMessage("%s.toByteArray() must give back the same bytes", classUnderTest) + .that(Arrays.equals(referenceBytes, roundTripBytes)) + .isTrue(); } + @Test public void testWriteTo() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); stringUnderTest.writeTo(bos); byte[] roundTripBytes = bos.toByteArray(); - assertTrue( - classUnderTest + ".writeTo() must give back the same bytes", - Arrays.equals(referenceBytes, roundTripBytes)); + assertWithMessage("%s.writeTo() must give back the same bytes", classUnderTest) + .that(Arrays.equals(referenceBytes, roundTripBytes)) + .isTrue(); } + @Test public void testWriteToShouldNotExposeInternalBufferToOutputStream() throws IOException { OutputStream os = new OutputStream() { @@ -331,11 +375,12 @@ }; stringUnderTest.writeTo(os); - assertTrue( - classUnderTest + ".writeTo() must not grant access to underlying array", - Arrays.equals(referenceBytes, stringUnderTest.toByteArray())); + assertWithMessage("%s.writeTo() must not grant access to underlying array", classUnderTest) + .that(Arrays.equals(referenceBytes, stringUnderTest.toByteArray())) + .isTrue(); } + @Test public void testWriteToInternalShouldExposeInternalBufferToOutputStream() throws IOException { OutputStream os = new OutputStream() { @@ -352,11 +397,12 @@ stringUnderTest.writeToInternal(os, 0, stringUnderTest.size()); byte[] allZeros = new byte[stringUnderTest.size()]; - assertTrue( - classUnderTest + ".writeToInternal() must grant access to underlying array", - Arrays.equals(allZeros, stringUnderTest.toByteArray())); + assertWithMessage("%s.writeToInternal() must grant access to underlying array", classUnderTest) + .that(Arrays.equals(allZeros, stringUnderTest.toByteArray())) + .isTrue(); } + @Test public void testWriteToShouldExposeInternalBufferToByteOutput() throws IOException { ByteOutput out = new ByteOutput() { @@ -388,197 +434,240 @@ stringUnderTest.writeTo(out); byte[] allZeros = new byte[stringUnderTest.size()]; - assertTrue( - classUnderTest + ".writeToInternal() must grant access to underlying array", - Arrays.equals(allZeros, stringUnderTest.toByteArray())); + assertWithMessage("%s.writeToInternal() must grant access to underlying array", classUnderTest) + .that(Arrays.equals(allZeros, stringUnderTest.toByteArray())) + .isTrue(); } + @Test public void testNewOutput() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteString.Output output = ByteString.newOutput(); stringUnderTest.writeTo(output); - assertEquals("Output Size returns correct result", output.size(), stringUnderTest.size()); + assertWithMessage("Output Size returns correct result") + .that(output.size()) + .isEqualTo(stringUnderTest.size()); output.writeTo(bos); - assertTrue( - "Output.writeTo() must give back the same bytes", - Arrays.equals(referenceBytes, bos.toByteArray())); + assertWithMessage("Output.writeTo() must give back the same bytes") + .that(Arrays.equals(referenceBytes, bos.toByteArray())) + .isTrue(); // write the output stream to itself! This should cause it to double output.writeTo(output); - assertEquals( - "Writing an output stream to itself is successful", - stringUnderTest.concat(stringUnderTest), - output.toByteString()); + assertWithMessage("Writing an output stream to itself is successful") + .that(stringUnderTest.concat(stringUnderTest)) + .isEqualTo(output.toByteString()); output.reset(); - assertEquals("Output.reset() resets the output", 0, output.size()); - assertEquals("Output.reset() resets the output", ByteString.EMPTY, output.toByteString()); + assertWithMessage("Output.reset() resets the output").that(output.size()).isEqualTo(0); + assertWithMessage("Output.reset() resets the output") + .that(output.toByteString()) + .isEqualTo(ByteString.EMPTY); } + @Test public void testToString() throws UnsupportedEncodingException { String testString = "I love unicode \u1234\u5678 characters"; ByteString unicode = ByteString.wrap(testString.getBytes(Internal.UTF_8)); String roundTripString = unicode.toString(UTF_8); - assertEquals(classUnderTest + " unicode must match", testString, roundTripString); + assertWithMessage("%s unicode must match", classUnderTest) + .that(testString) + .isEqualTo(roundTripString); } + @Test public void testCharsetToString() { String testString = "I love unicode \u1234\u5678 characters"; ByteString unicode = ByteString.wrap(testString.getBytes(Internal.UTF_8)); String roundTripString = unicode.toString(Internal.UTF_8); - assertEquals(classUnderTest + " unicode must match", testString, roundTripString); + assertWithMessage("%s unicode must match", classUnderTest) + .that(testString) + .isEqualTo(roundTripString); } + @Test public void testToString_returnsCanonicalEmptyString() { - assertSame( - classUnderTest + " must be the same string references", - ByteString.EMPTY.toString(Internal.UTF_8), - ByteString.wrap(new byte[] {}).toString(Internal.UTF_8)); + assertWithMessage("%s must be the same string references", classUnderTest) + .that(ByteString.EMPTY.toString(Internal.UTF_8)) + .isSameInstanceAs(ByteString.wrap(new byte[] {}).toString(Internal.UTF_8)); } + @Test public void testToString_raisesException() { try { ByteString.EMPTY.toString("invalid"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (UnsupportedEncodingException expected) { // This is success } try { ByteString.wrap(referenceBytes).toString("invalid"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (UnsupportedEncodingException expected) { // This is success } } + @Test + @SuppressWarnings("SelfEquals") public void testEquals() { - assertEquals(classUnderTest + " must not equal null", false, stringUnderTest.equals(null)); - assertEquals(classUnderTest + " must equal self", stringUnderTest, stringUnderTest); - assertFalse( - classUnderTest + " must not equal the empty string", - stringUnderTest.equals(ByteString.EMPTY)); - assertEquals( - classUnderTest + " empty strings must be equal", - ByteString.wrap(new byte[] {}), - stringUnderTest.substring(55, 55)); - assertEquals( - classUnderTest + " must equal another string with the same value", - stringUnderTest, - ByteString.wrap(referenceBytes)); + assertWithMessage("%s must not equal null", classUnderTest) + .that(stringUnderTest) + .isNotEqualTo(null); + assertWithMessage("%s must equal self", classUnderTest) + .that(stringUnderTest.equals(stringUnderTest)) + .isTrue(); + assertWithMessage("%s must not equal the empty string", classUnderTest) + .that(stringUnderTest) + .isNotEqualTo(ByteString.EMPTY); + assertWithMessage("%s empty strings must be equal", classUnderTest) + .that(ByteString.wrap(new byte[] {})) + .isEqualTo(stringUnderTest.substring(55, 55)); + assertWithMessage("%s must equal another string with the same value", classUnderTest) + .that(stringUnderTest) + .isEqualTo(ByteString.wrap(referenceBytes)); byte[] mungedBytes = new byte[referenceBytes.length]; System.arraycopy(referenceBytes, 0, mungedBytes, 0, referenceBytes.length); mungedBytes[mungedBytes.length - 5] = (byte) (mungedBytes[mungedBytes.length - 5] ^ 0xFF); - assertFalse( - classUnderTest + " must not equal every string with the same length", - stringUnderTest.equals(ByteString.wrap(mungedBytes))); + assertWithMessage("%s must not equal every string with the same length", classUnderTest) + .that(stringUnderTest) + .isNotEqualTo(ByteString.wrap(mungedBytes)); } + @Test public void testHashCode() { int hash = stringUnderTest.hashCode(); - assertEquals(classUnderTest + " must have expected hashCode", expectedHashCode, hash); + assertWithMessage("%s must have expected hashCode", classUnderTest) + .that(hash) + .isEqualTo(expectedHashCode); } + @Test public void testPeekCachedHashCode() { - assertEquals( - classUnderTest + ".peekCachedHashCode() should return zero at first", - 0, - stringUnderTest.peekCachedHashCode()); - stringUnderTest.hashCode(); - assertEquals( - classUnderTest + ".peekCachedHashCode should return zero at first", - expectedHashCode, - stringUnderTest.peekCachedHashCode()); + assertWithMessage("%s.peekCachedHashCode() should return zero at first", classUnderTest) + .that(stringUnderTest.peekCachedHashCode()) + .isEqualTo(0); + int unused = stringUnderTest.hashCode(); + assertWithMessage("%s.peekCachedHashCode should return zero at first", classUnderTest) + .that(stringUnderTest.peekCachedHashCode()) + .isEqualTo(expectedHashCode); } + @Test public void testPartialHash() { // partialHash() is more strenuously tested elsewhere by testing hashes of substrings. // This test would fail if the expected hash were 1. It's not. int hash = stringUnderTest.partialHash(stringUnderTest.size(), 0, stringUnderTest.size()); - assertEquals( - classUnderTest + ".partialHash() must yield expected hashCode", expectedHashCode, hash); + assertWithMessage("%s.partialHash() must yield expected hashCode", classUnderTest) + .that(hash) + .isEqualTo(expectedHashCode); } + @Test public void testNewInput() throws IOException { InputStream input = stringUnderTest.newInput(); - assertEquals( - "InputStream.available() returns correct value", stringUnderTest.size(), input.available()); + assertWithMessage("InputStream.available() returns correct value") + .that(stringUnderTest.size()) + .isEqualTo(input.available()); boolean stillEqual = true; for (byte referenceByte : referenceBytes) { int expectedInt = (referenceByte & 0xFF); stillEqual = (expectedInt == input.read()); } - assertEquals("InputStream.available() returns correct value", 0, input.available()); - assertTrue(classUnderTest + " must give the same bytes from the InputStream", stillEqual); - assertEquals(classUnderTest + " InputStream must now be exhausted", -1, input.read()); + assertWithMessage("InputStream.available() returns correct value") + .that(input.available()) + .isEqualTo(0); + assertWithMessage("%s must give the same bytes from the InputStream", classUnderTest) + .that(stillEqual) + .isTrue(); + assertWithMessage("%s InputStream must now be exhausted", classUnderTest) + .that(input.read()) + .isEqualTo(-1); } + @Test public void testNewInput_readZeroBytes() throws IOException { InputStream input = stringUnderTest.newInput(); - assertEquals( - classUnderTest + " InputStream.read() returns 0 when told to read 0 bytes and not at EOF", - 0, - input.read(new byte[0])); + assertWithMessage( + "%s InputStream.read() returns 0 when told to read 0 bytes and not at EOF", + classUnderTest) + .that(input.read(new byte[0])) + .isEqualTo(0); input.skip(input.available()); - assertEquals( - classUnderTest + " InputStream.read() returns -1 when told to read 0 bytes at EOF", - -1, - input.read(new byte[0])); + assertWithMessage( + "%s InputStream.read() returns -1 when told to read 0 bytes at EOF", classUnderTest) + .that(input.read(new byte[0])) + .isEqualTo(-1); } + @Test public void testNewInput_skip() throws IOException { InputStream input = stringUnderTest.newInput(); int stringSize = stringUnderTest.size(); int nearEndIndex = stringSize * 2 / 3; long skipped1 = input.skip(nearEndIndex); - assertEquals("InputStream.skip()", skipped1, nearEndIndex); - assertEquals("InputStream.available()", stringSize - skipped1, input.available()); - assertTrue("InputStream.mark() is available", input.markSupported()); + assertWithMessage("InputStream.skip()").that(skipped1).isEqualTo(nearEndIndex); + assertWithMessage("InputStream.available()") + .that(input.available()) + .isEqualTo(stringSize - skipped1); + assertWithMessage("InputStream.mark() is available").that(input.markSupported()).isTrue(); input.mark(0); - assertEquals( - "InputStream.skip(), read()", stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read()); - assertEquals("InputStream.available()", stringSize - skipped1 - 1, input.available()); + assertWithMessage("InputStream.skip(), read()") + .that(stringUnderTest.byteAt(nearEndIndex) & 0xFF) + .isEqualTo(input.read()); + assertWithMessage("InputStream.available()") + .that(input.available()) + .isEqualTo(stringSize - skipped1 - 1); long skipped2 = input.skip(stringSize); - assertEquals("InputStream.skip() incomplete", skipped2, stringSize - skipped1 - 1); - assertEquals("InputStream.skip(), no more input", 0, input.available()); - assertEquals("InputStream.skip(), no more input", -1, input.read()); + assertWithMessage("InputStream.skip() incomplete") + .that(skipped2) + .isEqualTo(stringSize - skipped1 - 1); + assertWithMessage("InputStream.skip(), no more input").that(input.available()).isEqualTo(0); + assertWithMessage("InputStream.skip(), no more input").that(input.read()).isEqualTo(-1); assertThat(input.skip(1)).isEqualTo(0); assertThat(input.read(new byte[1], /* off= */ 0, /*len=*/ 0)).isEqualTo(-1); input.reset(); - assertEquals("InputStream.reset() succeeded", stringSize - skipped1, input.available()); - assertEquals( - "InputStream.reset(), read()", stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read()); + assertWithMessage("InputStream.reset() succeeded") + .that(input.available()) + .isEqualTo(stringSize - skipped1); + assertWithMessage("InputStream.reset(), read()") + .that(input.read()) + .isEqualTo(stringUnderTest.byteAt(nearEndIndex) & 0xFF); } + @Test public void testNewCodedInput() throws IOException { CodedInputStream cis = stringUnderTest.newCodedInput(); byte[] roundTripBytes = cis.readRawBytes(referenceBytes.length); - assertTrue( - classUnderTest + " must give the same bytes back from the CodedInputStream", - Arrays.equals(referenceBytes, roundTripBytes)); - assertTrue(classUnderTest + " CodedInputStream must now be exhausted", cis.isAtEnd()); + assertWithMessage("%s must give the same bytes back from the CodedInputStream", classUnderTest) + .that(Arrays.equals(referenceBytes, roundTripBytes)) + .isTrue(); + assertWithMessage(" %s CodedInputStream must now be exhausted", classUnderTest) + .that(cis.isAtEnd()) + .isTrue(); } /** * Make sure we keep things simple when concatenating with empty. See also {@link * ByteStringTest#testConcat_empty()}. */ + @Test public void testConcat_empty() { - assertSame( - classUnderTest + " concatenated with empty must give " + classUnderTest, - stringUnderTest.concat(ByteString.EMPTY), - stringUnderTest); - assertSame( - "empty concatenated with " + classUnderTest + " must give " + classUnderTest, - ByteString.EMPTY.concat(stringUnderTest), - stringUnderTest); + assertWithMessage("%s concatenated with empty must give %s ", classUnderTest, classUnderTest) + .that(stringUnderTest.concat(ByteString.EMPTY)) + .isSameInstanceAs(stringUnderTest); + assertWithMessage("empty concatenated with %s must give %s", classUnderTest, classUnderTest) + .that(ByteString.EMPTY.concat(stringUnderTest)) + .isSameInstanceAs(stringUnderTest); } + @Test public void testJavaSerialization() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); @@ -588,7 +677,7 @@ InputStream in = new ByteArrayInputStream(pickled); ObjectInputStream ois = new ObjectInputStream(in); Object o = ois.readObject(); - assertTrue("Didn't get a ByteString back", o instanceof ByteString); - assertEquals("Should get an equal ByteString back", stringUnderTest, o); + assertWithMessage("Didn't get a ByteString back").that(o).isInstanceOf(ByteString.class); + assertWithMessage("Should get an equal ByteString back").that(o).isEqualTo(stringUnderTest); } }
diff --git a/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java b/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java index d6fbaf9..2982e0c 100644 --- a/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java
@@ -30,39 +30,44 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static java.util.Arrays.asList; import com.google.protobuf.Internal.LongList; import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.Iterator; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Tests for {@link LongArrayList}. - * - * @author dweis@google.com (Daniel Weis) - */ -public class LongArrayListTest extends TestCase { +/** Tests for {@link LongArrayList}. */ +@RunWith(JUnit4.class) +public class LongArrayListTest { private static final LongArrayList UNARY_LIST = newImmutableLongArrayList(1); private static final LongArrayList TERTIARY_LIST = newImmutableLongArrayList(1, 2, 3); private LongArrayList list; - @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { list = new LongArrayList(); } + @Test public void testEmptyListReturnsSameInstance() { - assertSame(LongArrayList.emptyList(), LongArrayList.emptyList()); + assertThat(LongArrayList.emptyList()).isSameInstanceAs(LongArrayList.emptyList()); } + @Test public void testEmptyListIsImmutable() { assertImmutable(LongArrayList.emptyList()); } + @Test public void testMakeImmutable() { list.addLong(3); list.addLong(4); @@ -72,19 +77,20 @@ assertImmutable(list); } + @Test public void testModificationWithIteration() { list.addAll(asList(1L, 2L, 3L, 4L)); Iterator<Long> iterator = list.iterator(); - assertEquals(4, list.size()); - assertEquals(1L, (long) list.get(0)); - assertEquals(1L, (long) iterator.next()); + assertThat(list).hasSize(4); + assertThat((long) list.get(0)).isEqualTo(1L); + assertThat((long) iterator.next()).isEqualTo(1L); list.set(0, 1L); - assertEquals(2L, (long) iterator.next()); + assertThat((long) iterator.next()).isEqualTo(2L); list.remove(0); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail(); } catch (ConcurrentModificationException e) { // expected } @@ -93,191 +99,211 @@ list.add(0, 0L); try { iterator.next(); - fail(); + assertWithMessage("expected exception").fail(); } catch (ConcurrentModificationException e) { // expected } } + @Test public void testGet() { - assertEquals(1L, (long) TERTIARY_LIST.get(0)); - assertEquals(2L, (long) TERTIARY_LIST.get(1)); - assertEquals(3L, (long) TERTIARY_LIST.get(2)); + assertThat((long) TERTIARY_LIST.get(0)).isEqualTo(1L); + assertThat((long) TERTIARY_LIST.get(1)).isEqualTo(2L); + assertThat((long) TERTIARY_LIST.get(2)).isEqualTo(3L); try { TERTIARY_LIST.get(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { TERTIARY_LIST.get(3); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testGetLong() { - assertEquals(1L, TERTIARY_LIST.getLong(0)); - assertEquals(2L, TERTIARY_LIST.getLong(1)); - assertEquals(3L, TERTIARY_LIST.getLong(2)); + assertThat(TERTIARY_LIST.getLong(0)).isEqualTo(1L); + assertThat(TERTIARY_LIST.getLong(1)).isEqualTo(2L); + assertThat(TERTIARY_LIST.getLong(2)).isEqualTo(3L); try { TERTIARY_LIST.get(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { TERTIARY_LIST.get(3); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testIndexOf_nullElement() { - assertEquals(-1, TERTIARY_LIST.indexOf(null)); + assertThat(TERTIARY_LIST.indexOf(null)).isEqualTo(-1); } + @Test public void testIndexOf_incompatibleElementType() { - assertEquals(-1, TERTIARY_LIST.indexOf(new Object())); + assertThat(TERTIARY_LIST.indexOf(new Object())).isEqualTo(-1); } + @Test public void testIndexOf_notInList() { - assertEquals(-1, UNARY_LIST.indexOf(2L)); + assertThat(UNARY_LIST.indexOf(2L)).isEqualTo(-1); } + @Test public void testIndexOf_notInListWithDuplicates() { LongArrayList listWithDupes = newImmutableLongArrayList(1L, 1L); - assertEquals(-1, listWithDupes.indexOf(2L)); + assertThat(listWithDupes.indexOf(2L)).isEqualTo(-1); } + @Test public void testIndexOf_inList() { - assertEquals(1, TERTIARY_LIST.indexOf(2L)); + assertThat(TERTIARY_LIST.indexOf(2L)).isEqualTo(1); } + @Test public void testIndexOf_inListWithDuplicates_matchAtHead() { LongArrayList listWithDupes = newImmutableLongArrayList(1L, 1L, 2L); - assertEquals(0, listWithDupes.indexOf(1L)); + assertThat(listWithDupes.indexOf(1L)).isEqualTo(0); } + @Test public void testIndexOf_inListWithDuplicates_matchMidList() { LongArrayList listWithDupes = newImmutableLongArrayList(2L, 1L, 1L, 2L); - assertEquals(1, listWithDupes.indexOf(1L)); + assertThat(listWithDupes.indexOf(1L)).isEqualTo(1); } + @Test public void testContains_nullElement() { - assertEquals(false, TERTIARY_LIST.contains(null)); + assertThat(TERTIARY_LIST).doesNotContain(null); } + @Test public void testContains_incompatibleElementType() { - assertEquals(false, TERTIARY_LIST.contains(new Object())); + assertThat(TERTIARY_LIST).doesNotContain(new Object()); } + @Test public void testContains_notInList() { - assertEquals(false, UNARY_LIST.contains(2L)); + assertThat(UNARY_LIST).doesNotContain(2L); } + @Test public void testContains_notInListWithDuplicates() { LongArrayList listWithDupes = newImmutableLongArrayList(1L, 1L); - assertEquals(false, listWithDupes.contains(2L)); + assertThat(listWithDupes).doesNotContain(2L); } + @Test public void testContains_inList() { - assertEquals(true, TERTIARY_LIST.contains(2L)); + assertThat(TERTIARY_LIST).contains(2L); } + @Test public void testContains_inListWithDuplicates_matchAtHead() { LongArrayList listWithDupes = newImmutableLongArrayList(1L, 1L, 2L); - assertEquals(true, listWithDupes.contains(1L)); + assertThat(listWithDupes).contains(1L); } + @Test public void testContains_inListWithDuplicates_matchMidList() { LongArrayList listWithDupes = newImmutableLongArrayList(2L, 1L, 1L, 2L); - assertEquals(true, listWithDupes.contains(1L)); + assertThat(listWithDupes).contains(1L); } + @Test public void testSize() { - assertEquals(0, LongArrayList.emptyList().size()); - assertEquals(1, UNARY_LIST.size()); - assertEquals(3, TERTIARY_LIST.size()); + assertThat(LongArrayList.emptyList()).isEmpty(); + assertThat(UNARY_LIST).hasSize(1); + assertThat(TERTIARY_LIST).hasSize(3); list.addLong(3); list.addLong(4); list.addLong(6); list.addLong(8); - assertEquals(4, list.size()); + assertThat(list).hasSize(4); list.remove(0); - assertEquals(3, list.size()); + assertThat(list).hasSize(3); list.add(17L); - assertEquals(4, list.size()); + assertThat(list).hasSize(4); } + @Test public void testSet() { list.addLong(2); list.addLong(4); - assertEquals(2L, (long) list.set(0, 3L)); - assertEquals(3L, list.getLong(0)); + assertThat((long) list.set(0, 3L)).isEqualTo(2L); + assertThat(list.getLong(0)).isEqualTo(3L); - assertEquals(4L, (long) list.set(1, 0L)); - assertEquals(0L, list.getLong(1)); + assertThat((long) list.set(1, 0L)).isEqualTo(4L); + assertThat(list.getLong(1)).isEqualTo(0L); try { list.set(-1, 0L); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.set(2, 0L); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testSetLong() { list.addLong(1); list.addLong(3); - assertEquals(1L, list.setLong(0, 0)); - assertEquals(0L, list.getLong(0)); + assertThat(list.setLong(0, 0)).isEqualTo(1L); + assertThat(list.getLong(0)).isEqualTo(0L); - assertEquals(3L, list.setLong(1, 0)); - assertEquals(0L, list.getLong(1)); + assertThat(list.setLong(1, 0)).isEqualTo(3L); + assertThat(list.getLong(1)).isEqualTo(0L); try { list.setLong(-1, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.setLong(2, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testAdd() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); - assertTrue(list.add(2L)); - assertEquals(asList(2L), list); + assertThat(list.add(2L)).isTrue(); + assertThat(list).containsExactly(2L); - assertTrue(list.add(3L)); + assertThat(list.add(3L)).isTrue(); list.add(0, 4L); - assertEquals(asList(4L, 2L, 3L), list); + assertThat(list).containsExactly(4L, 2L, 3L).inOrder(); list.add(0, 1L); list.add(0, 0L); @@ -285,7 +311,7 @@ for (int i = 0; i < 6; i++) { list.add(Long.valueOf(5 + i)); } - assertEquals(asList(0L, 1L, 4L, 2L, 3L, 5L, 6L, 7L, 8L, 9L, 10L), list); + assertThat(list).containsExactly(0L, 1L, 4L, 2L, 3L, 5L, 6L, 7L, 8L, 9L, 10L).inOrder(); try { list.add(-1, 5L); @@ -300,90 +326,98 @@ } } + @Test public void testAddLong() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); list.addLong(2); - assertEquals(asList(2L), list); + assertThat(list).containsExactly(2L); list.addLong(3); - assertEquals(asList(2L, 3L), list); + assertThat(list).containsExactly(2L, 3L).inOrder(); } + @Test public void testAddAll() { - assertEquals(0, list.size()); + assertThat(list).isEmpty(); - assertTrue(list.addAll(Collections.singleton(1L))); - assertEquals(1, list.size()); - assertEquals(1L, (long) list.get(0)); - assertEquals(1L, list.getLong(0)); + assertThat(list.addAll(Collections.singleton(1L))).isTrue(); + assertThat(list).hasSize(1); + assertThat((long) list.get(0)).isEqualTo(1L); + assertThat(list.getLong(0)).isEqualTo(1L); - assertTrue(list.addAll(asList(2L, 3L, 4L, 5L, 6L))); - assertEquals(asList(1L, 2L, 3L, 4L, 5L, 6L), list); + assertThat(list.addAll(asList(2L, 3L, 4L, 5L, 6L))).isTrue(); + assertThat(list).containsExactly(1L, 2L, 3L, 4L, 5L, 6L).inOrder(); - assertTrue(list.addAll(TERTIARY_LIST)); - assertEquals(asList(1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L), list); + assertThat(list.addAll(TERTIARY_LIST)).isTrue(); + assertThat(list).containsExactly(1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L).inOrder(); - assertFalse(list.addAll(Collections.<Long>emptyList())); - assertFalse(list.addAll(LongArrayList.emptyList())); + assertThat(list.addAll(Collections.<Long>emptyList())).isFalse(); + assertThat(list.addAll(LongArrayList.emptyList())).isFalse(); } + @Test public void testEquals() { LongArrayList list1 = new LongArrayList(); LongArrayList list2 = new LongArrayList(); - assertEquals(list1, list2); + assertThat(list1).isEqualTo(list2); } + @Test public void testRemove() { list.addAll(TERTIARY_LIST); - assertEquals(1L, (long) list.remove(0)); - assertEquals(asList(2L, 3L), list); + assertThat((long) list.remove(0)).isEqualTo(1L); + assertThat(list).containsExactly(2L, 3L).inOrder(); - assertTrue(list.remove(Long.valueOf(3))); - assertEquals(asList(2L), list); + assertThat(list.remove(Long.valueOf(3))).isTrue(); + assertThat(list).containsExactly(2L); - assertFalse(list.remove(Long.valueOf(3))); - assertEquals(asList(2L), list); + assertThat(list.remove(Long.valueOf(3))).isFalse(); + assertThat(list).containsExactly(2L); - assertEquals(2L, (long) list.remove(0)); - assertEquals(asList(), list); + assertThat((long) list.remove(0)).isEqualTo(2L); + assertThat(list).isEmpty(); try { list.remove(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } try { list.remove(0); + assertWithMessage("expected exception").fail(); } catch (IndexOutOfBoundsException e) { // expected } } + @Test public void testRemoveEnd_listAtCapacity() { LongList toRemove = LongArrayList.emptyList().mutableCopyWithCapacity(1); toRemove.addLong(3); toRemove.remove(0); - assertEquals(0, toRemove.size()); + assertThat(toRemove).isEmpty(); } + @Test public void testRemove_listAtCapacity() { LongList toRemove = LongArrayList.emptyList().mutableCopyWithCapacity(2); toRemove.addLong(3); toRemove.addLong(4); toRemove.remove(0); - assertEquals(1, toRemove.size()); - assertEquals(4L, (long) toRemove.get(0)); + assertThat(toRemove).hasSize(1); + assertThat((long) toRemove.get(0)).isEqualTo(4L); } + @Test public void testSublistRemoveEndOfCapacity() { LongList toRemove = LongArrayList.emptyList().mutableCopyWithCapacity(1); toRemove.addLong(3); toRemove.subList(0, 1).clear(); - assertEquals(0, toRemove.size()); + assertThat(toRemove).isEmpty(); } private void assertImmutable(LongList list) { @@ -393,147 +427,147 @@ try { list.add(1L); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.add(0, 1L); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(Collections.<Long>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(Collections.singletonList(1L)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(new LongArrayList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, Collections.singleton(1L)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addAll(0, Collections.<Long>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.addLong(0); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.clear(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.remove(1); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.remove(new Object()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(Collections.<Long>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(Collections.singleton(1L)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.removeAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(Collections.<Long>emptyList()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(Collections.singleton(1L)); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.retainAll(UNARY_LIST); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.set(0, 0L); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { list.setLong(0, 0); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected }
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 4de09cd..b143dce 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
@@ -30,6 +30,9 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import map_lite_test.MapForProto2TestProto.BizarroTestMap; import map_lite_test.MapForProto2TestProto.TestMap; import map_lite_test.MapForProto2TestProto.TestMap.MessageValue; @@ -38,13 +41,15 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Unit tests for map fields. */ -public final class MapForProto2LiteTest extends TestCase { +@RunWith(JUnit4.class) +public final class MapForProto2LiteTest { private void setMapValues(TestMap.Builder builder) { builder @@ -68,6 +73,7 @@ .putStringToInt32Field("3", 33); } + @Test public void testSetMapValues() { TestMap.Builder mapBuilder = TestMap.newBuilder(); setMapValues(mapBuilder); @@ -86,35 +92,35 @@ } private void assertMapValuesSet(TestMap message) { - 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()); + assertThat(message.getInt32ToInt32FieldMap()).hasSize(3); + assertThat(message.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(11); + assertThat(message.getInt32ToInt32FieldMap().get(2).intValue()).isEqualTo(22); + assertThat(message.getInt32ToInt32FieldMap().get(3).intValue()).isEqualTo(33); - assertEquals(3, message.getInt32ToStringFieldMap().size()); - assertEquals("11", message.getInt32ToStringFieldMap().get(1)); - assertEquals("22", message.getInt32ToStringFieldMap().get(2)); - assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertThat(message.getInt32ToStringFieldMap()).hasSize(3); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(1, "11"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(2, "22"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(3, "33"); - 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)); + assertThat(message.getInt32ToBytesFieldMap()).hasSize(3); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(1, TestUtil.toBytes("11")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(2, TestUtil.toBytes("22")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(3, TestUtil.toBytes("33")); - 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)); + assertThat(message.getInt32ToEnumFieldMap()).hasSize(3); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.FOO); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(2, TestMap.EnumValue.BAR); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(3, TestMap.EnumValue.BAZ); - 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()); + assertThat(message.getInt32ToMessageFieldMap()).hasSize(3); + assertThat(message.getInt32ToMessageFieldMap().get(1).getValue()).isEqualTo(11); + assertThat(message.getInt32ToMessageFieldMap().get(2).getValue()).isEqualTo(22); + assertThat(message.getInt32ToMessageFieldMap().get(3).getValue()).isEqualTo(33); - 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()); + assertThat(message.getStringToInt32FieldMap()).hasSize(3); + assertThat(message.getStringToInt32FieldMap().get("1").intValue()).isEqualTo(11); + assertThat(message.getStringToInt32FieldMap().get("2").intValue()).isEqualTo(22); + assertThat(message.getStringToInt32FieldMap().get("3").intValue()).isEqualTo(33); } private void updateMapValues(TestMap.Builder builder) { @@ -139,6 +145,7 @@ .putStringToInt32Field("4", 44); } + @Test public void testUpdateMapValues() { TestMap.Builder mapBuilder = TestMap.newBuilder(); setMapValues(mapBuilder); @@ -152,52 +159,53 @@ } private void assertMapValuesUpdated(TestMap message) { - 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()); + assertThat(message.getInt32ToInt32FieldMap()).hasSize(3); + assertThat(message.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(111); + assertThat(message.getInt32ToInt32FieldMap().get(3).intValue()).isEqualTo(33); + assertThat(message.getInt32ToInt32FieldMap().get(4).intValue()).isEqualTo(44); - assertEquals(3, message.getInt32ToStringFieldMap().size()); - assertEquals("111", message.getInt32ToStringFieldMap().get(1)); - assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals("44", message.getInt32ToStringFieldMap().get(4)); + assertThat(message.getInt32ToStringFieldMap()).hasSize(3); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(1, "111"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(3, "33"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(4, "44"); - 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)); + assertThat(message.getInt32ToBytesFieldMap()).hasSize(3); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(1, TestUtil.toBytes("111")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(3, TestUtil.toBytes("33")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(4, TestUtil.toBytes("44")); - 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)); + assertThat(message.getInt32ToEnumFieldMap()).hasSize(3); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.BAR); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(3, TestMap.EnumValue.BAZ); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(4, TestMap.EnumValue.QUX); - 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()); + assertThat(message.getInt32ToMessageFieldMap()).hasSize(3); + assertThat(message.getInt32ToMessageFieldMap().get(1).getValue()).isEqualTo(111); + assertThat(message.getInt32ToMessageFieldMap().get(3).getValue()).isEqualTo(33); + assertThat(message.getInt32ToMessageFieldMap().get(4).getValue()).isEqualTo(44); - 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()); + assertThat(message.getStringToInt32FieldMap()).hasSize(3); + assertThat(message.getStringToInt32FieldMap().get("1").intValue()).isEqualTo(111); + assertThat(message.getStringToInt32FieldMap().get("3").intValue()).isEqualTo(33); + assertThat(message.getStringToInt32FieldMap().get("4").intValue()).isEqualTo(44); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); - assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); + assertThat(testMapOrBuilder.getInt32ToInt32FieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToInt32FieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToStringFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToStringFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToBytesFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToBytesFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToEnumFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToEnumFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToMessageFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToMessageFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getStringToInt32FieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getStringToInt32FieldCount()).isEqualTo(0); } + @Test public void testSanityCopyOnWrite() throws InvalidProtocolBufferException { // Since builders are implemented as a thin wrapper around a message // instance, we attempt to verify that we can't cause the builder to modify @@ -206,15 +214,16 @@ TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); builder.putInt32ToInt32Field(1, 2); - assertTrue(message.getInt32ToInt32FieldMap().isEmpty()); + assertThat(message.getInt32ToInt32FieldMap()).isEmpty(); message = builder.build(); - assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); + assertThat(message.getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2)); + assertThat(builder.getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2)); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); + assertThat(message.getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2)); + assertThat(builder.getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2, 2, 3)); } + @Test public void testGetMapIsImmutable() { TestMap.Builder builder = TestMap.newBuilder(); assertMapsAreImmutable(builder); @@ -238,57 +247,58 @@ private <K, V> void assertImmutable(Map<K, V> map, K key, V value) { try { map.put(key, value); - fail(); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException e) { // expected } if (!map.isEmpty()) { try { map.entrySet().remove(map.entrySet().iterator().next()); - fail(); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException e) { // expected } } } + @Test public void testMutableMapLifecycle() { TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); + assertThat(builder.build().getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2)); + assertThat(builder.getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2)); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); + assertThat(builder.getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2, 2, 3)); builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap()); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap()); + assertThat(builder.build().getInt32ToEnumFieldMap()) + .isEqualTo(newMap(1, TestMap.EnumValue.BAR)); + assertThat(builder.getInt32ToEnumFieldMap()).isEqualTo(newMap(1, TestMap.EnumValue.BAR)); builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO); - assertEquals( - newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), - builder.getInt32ToEnumFieldMap()); + assertThat(builder.getInt32ToEnumFieldMap()) + .isEqualTo(newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO)); builder.putInt32ToStringField(1, "1"); - assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap()); - assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap()); + assertThat(builder.build().getInt32ToStringFieldMap()).isEqualTo(newMap(1, "1")); + assertThat(builder.getInt32ToStringFieldMap()).isEqualTo(newMap(1, "1")); builder.putInt32ToStringField(2, "2"); - assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap()); + assertThat(builder.getInt32ToStringFieldMap()).isEqualTo(newMap(1, "1", 2, "2")); builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance()); - assertEquals( - newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.build().getInt32ToMessageFieldMap()); - assertEquals( - newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap()); + assertThat(builder.build().getInt32ToMessageFieldMap()) + .isEqualTo(newMap(1, TestMap.MessageValue.getDefaultInstance())); + assertThat(builder.getInt32ToMessageFieldMap()) + .isEqualTo(newMap(1, TestMap.MessageValue.getDefaultInstance())); builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance()); - assertEquals( - newMap( - 1, - TestMap.MessageValue.getDefaultInstance(), - 2, - TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageFieldMap()); + assertThat(builder.getInt32ToMessageFieldMap()) + .isEqualTo( + newMap( + 1, + TestMap.MessageValue.getDefaultInstance(), + 2, + TestMap.MessageValue.getDefaultInstance())); } + @Test public void testGettersAndSetters() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); @@ -311,6 +321,7 @@ assertMapValuesCleared(message); } + @Test public void testPutAll() throws Exception { TestMap.Builder sourceBuilder = TestMap.newBuilder(); setMapValues(sourceBuilder); @@ -322,64 +333,66 @@ assertMapValuesSet(destination.build()); } + @Test public void testPutChecksNullKeysAndValues() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); try { builder.putInt32ToStringField(1, null); - fail(); + assertWithMessage("Expected NullPointerException").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToBytesField(1, null); - fail(); + assertWithMessage("Expected NullPointerException").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToEnumField(1, null); - fail(); + assertWithMessage("Expected NullPointerException").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToMessageField(1, null); - fail(); + assertWithMessage("Expected NullPointerException").fail(); } catch (NullPointerException e) { // expected. } try { builder.putStringToInt32Field(null, 1); - fail(); + assertWithMessage("Expected NullPointerException").fail();; } catch (NullPointerException e) { // expected. } } + @Test public void testSerializeAndParse() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesSet(message); builder = message.toBuilder(); updateMapValues(builder); message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesUpdated(message); builder = message.toBuilder(); builder.clear(); message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesCleared(message); } @@ -392,39 +405,41 @@ return TestMap.parser().parseFrom(ByteString.copyFrom(byteArrayOutputStream.toByteArray())); } + @Test public void testParseError() throws Exception { ByteString bytes = TestUtil.toBytes("SOME BYTES"); String stringKey = "a string key"; TestMap map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToInt32Field(5, bytes).build()); - assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1)); + assertThat(map.getInt32ToInt32FieldOrDefault(5, -1)).isEqualTo(0); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToStringField(stringKey, 5).build()); - assertEquals("", map.getInt32ToStringFieldOrDefault(0, null)); + assertThat(map.getInt32ToStringFieldOrDefault(0, null)).isEmpty(); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToBytesField(stringKey, 5).build()); - assertEquals(map.getInt32ToBytesFieldOrDefault(0, null), ByteString.EMPTY); + assertThat(ByteString.EMPTY).isEqualTo(map.getInt32ToBytesFieldOrDefault(0, null)); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToEnumField(stringKey, bytes).build()); - assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null)); + assertThat(map.getInt32ToEnumFieldOrDefault(0, null)).isEqualTo(TestMap.EnumValue.FOO); try { tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToMessageField(stringKey, bytes).build()); - fail(); + assertWithMessage("Expected InvalidProtocolBufferException").fail(); } catch (InvalidProtocolBufferException expected) { - assertTrue(expected.getUnfinishedMessage() instanceof TestMap); + assertThat(expected.getUnfinishedMessage()).isInstanceOf(TestMap.class); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); + assertThat(map.getInt32ToMessageFieldMap()).isEmpty(); } map = tryParseTestMap( BizarroTestMap.newBuilder().putStringToInt32Field(stringKey, bytes).build()); - assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1)); + assertThat(map.getStringToInt32FieldOrDefault(stringKey, -1)).isEqualTo(0); } + @Test public void testMergeFrom() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); @@ -435,6 +450,7 @@ assertMapValuesSet(other.build()); } + @Test public void testEqualsAndHashCode() throws Exception { // Test that generated equals() and hashCode() will disregard the order // of map entries when comparing/hashing map fields. @@ -455,17 +471,18 @@ .putInt32ToInt32Field(3, 4); TestMap m2 = b2.build(); - assertEquals(m1, m2); - assertEquals(m1.hashCode(), m2.hashCode()); + assertThat(m2).isEqualTo(m1); + assertThat(m2.hashCode()).isEqualTo(m1.hashCode()); // Make sure we did compare map fields. b2.putInt32ToInt32Field(1, 0); m2 = b2.build(); - assertFalse(m1.equals(m2)); + assertThat(m1.equals(m2)).isFalse(); // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed // to be different. } + @Test public void testUnknownEnumValues() throws Exception { ByteString data = TestUnknownEnumValue.newBuilder() @@ -474,27 +491,30 @@ .build() .toByteString(); - TestMap message = TestMap.parseFrom(data); + TestMap message = TestMap.parseFrom(data, ExtensionRegistryLite.getEmptyRegistry()); // Entries with unknown enum values will be stored into UnknownFieldSet so // there is only one entry in the map. - assertEquals(1, message.getInt32ToEnumFieldMap().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertThat(message.getInt32ToEnumFieldMap()).hasSize(1); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.BAR); // Serializing and parsing should preserve the unknown entry. data = message.toByteString(); - TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data); - assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size()); - assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue()); - assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue()); + TestUnknownEnumValue messageWithUnknownEnums = + TestUnknownEnumValue.parseFrom(data, ExtensionRegistryLite.getEmptyRegistry()); + assertThat(messageWithUnknownEnums.getInt32ToInt32FieldMap()).hasSize(2); + assertThat(messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(1); + assertThat(messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue()) + .isEqualTo(54321); } + @Test public void testIterationOrder() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - assertEquals( - Arrays.asList("1", "2", "3"), - new ArrayList<String>(message.getStringToInt32FieldMap().keySet())); + assertThat(new ArrayList<String>(message.getStringToInt32FieldMap().keySet())) + .containsExactly("1", "2", "3") + .inOrder(); } private static <K, V> Map<K, V> newMap(K key1, V value1) { @@ -510,16 +530,18 @@ return map; } + @Test public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); + assertThat(message.getStringToInt32FieldMap()).isEqualTo(message.getStringToInt32FieldMap()); + assertThat(message.getInt32ToBytesFieldMap()).isEqualTo(message.getInt32ToBytesFieldMap()); + assertThat(message.getInt32ToEnumFieldMap()).isEqualTo(message.getInt32ToEnumFieldMap()); + assertThat(message.getInt32ToMessageFieldMap()).isEqualTo(message.getInt32ToMessageFieldMap()); } + @Test public void testContains() { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); @@ -528,37 +550,38 @@ } private void assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder) { - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(1)); - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(2)); - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(3)); - assertFalse(testMapOrBuilder.containsInt32ToInt32Field(-1)); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToStringField(1)); - assertTrue(testMapOrBuilder.containsInt32ToStringField(2)); - assertTrue(testMapOrBuilder.containsInt32ToStringField(3)); - assertFalse(testMapOrBuilder.containsInt32ToStringField(-1)); + assertThat(testMapOrBuilder.containsInt32ToStringField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(1)); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(2)); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(3)); - assertFalse(testMapOrBuilder.containsInt32ToBytesField(-1)); + assertThat(testMapOrBuilder.containsInt32ToBytesField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(1)); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(2)); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(3)); - assertFalse(testMapOrBuilder.containsInt32ToEnumField(-1)); + assertThat(testMapOrBuilder.containsInt32ToEnumField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(1)); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(2)); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(3)); - assertFalse(testMapOrBuilder.containsInt32ToMessageField(-1)); + assertThat(testMapOrBuilder.containsInt32ToMessageField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsStringToInt32Field("1")); - assertTrue(testMapOrBuilder.containsStringToInt32Field("2")); - assertTrue(testMapOrBuilder.containsStringToInt32Field("3")); - assertFalse(testMapOrBuilder.containsStringToInt32Field("-1")); + assertThat(testMapOrBuilder.containsStringToInt32Field("1")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("2")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("3")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("-1")).isFalse(); } + @Test public void testCount() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -570,23 +593,24 @@ assertMapCounts(3, message); builder = message.toBuilder().putInt32ToInt32Field(4, 44); - assertEquals(4, builder.getInt32ToInt32FieldCount()); - assertEquals(4, builder.build().getInt32ToInt32FieldCount()); + assertThat(builder.getInt32ToInt32FieldCount()).isEqualTo(4); + assertThat(builder.build().getInt32ToInt32FieldCount()).isEqualTo(4); // already present - should be unchanged builder.putInt32ToInt32Field(4, 44); - assertEquals(4, builder.getInt32ToInt32FieldCount()); + assertThat(builder.getInt32ToInt32FieldCount()).isEqualTo(4); } private void assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder) { - assertEquals(expectedCount, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getStringToInt32FieldCount()); + assertThat(testMapOrBuilder.getInt32ToInt32FieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToStringFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToBytesFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToEnumFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToMessageFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getStringToInt32FieldCount()).isEqualTo(expectedCount); } + @Test public void testGetOrDefault() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -596,34 +620,38 @@ } public void doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder) { - assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11)); - assertEquals(-11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11)); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11)).isEqualTo(11); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11)).isEqualTo(-11); - assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11")); - assertNull("-11", testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11")).isEqualTo("11"); + assertWithMessage("-11") + .that(testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null)) + .isNull(); - assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null)) + .isEqualTo(TestUtil.toBytes("11")); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null)).isNull(); - assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null)) + .isEqualTo(TestMap.EnumValue.FOO); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null)).isNull(); - assertEquals( - MessageValue.newBuilder().setValue(11).build(), - testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null)) + .isEqualTo(MessageValue.newBuilder().setValue(11).build()); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null)).isNull(); - assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11)); - assertEquals(-11, testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11)); + assertThat(testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11)).isEqualTo(11); + assertThat(testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11)).isEqualTo(-11); try { testMapOrBuilder.getStringToInt32FieldOrDefault(null, -11); - fail(); + assertWithMessage("Expected NullPointerException").fail(); } catch (NullPointerException e) { // expected } } + @Test public void testGetOrThrow() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -633,100 +661,100 @@ } public void doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder) { - assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); try { testMapOrBuilder.getInt32ToInt32FieldOrThrow(-1); - fail(); + assertWithMessage("Expected IllegalArgumentException").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToStringFieldOrThrow(1)).isEqualTo("11"); try { testMapOrBuilder.getInt32ToStringFieldOrThrow(-1); - fail(); + assertWithMessage("Expected IllegalArgumentException").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); try { testMapOrBuilder.getInt32ToBytesFieldOrThrow(-1); - fail(); + assertWithMessage("Expected IllegalArgumentException").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); try { testMapOrBuilder.getInt32ToEnumFieldOrThrow(-1); - fail(); + assertWithMessage("Expected IllegalArgumentException").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals( - MessageValue.newBuilder().setValue(11).build(), - testMapOrBuilder.getInt32ToMessageFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrThrow(1)) + .isEqualTo(MessageValue.newBuilder().setValue(11).build()); try { testMapOrBuilder.getInt32ToMessageFieldOrThrow(-1); - fail(); + assertWithMessage("Expected IllegalArgumentException").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrThrow("1")); + assertThat(testMapOrBuilder.getStringToInt32FieldOrThrow("1")).isEqualTo(11); try { testMapOrBuilder.getStringToInt32FieldOrThrow("-1"); - fail(); + assertWithMessage("Expected IllegalArgumentException").fail(); } catch (IllegalArgumentException e) { // expected } try { testMapOrBuilder.getStringToInt32FieldOrThrow(null); - fail(); + assertWithMessage("Expected NullPointerException").fail(); } catch (NullPointerException e) { // expected } } + @Test public void testPut() { TestMap.Builder builder = TestMap.newBuilder(); builder.putInt32ToInt32Field(1, 11); - assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); + assertThat(builder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); builder.putInt32ToStringField(1, "a"); - assertEquals("a", builder.getInt32ToStringFieldOrThrow(1)); + assertThat(builder.getInt32ToStringFieldOrThrow(1)).isEqualTo("a"); try { builder.putInt32ToStringField(1, null); - fail(); + assertWithMessage("Expected NullPointerException").fail(); } catch (NullPointerException e) { // expected } builder.putInt32ToBytesField(1, TestUtil.toBytes("11")); - assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); + assertThat(builder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); try { builder.putInt32ToBytesField(1, null); - fail(); + assertWithMessage("Expected NullPointerException").fail(); } catch (NullPointerException e) { // expected } builder.putInt32ToEnumField(1, TestMap.EnumValue.FOO); - assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); + assertThat(builder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); try { builder.putInt32ToEnumField(1, null); - fail(); + assertWithMessage("Expected NullPointerException").fail(); } catch (NullPointerException e) { // expected } builder.putStringToInt32Field("a", 1); - assertEquals(1, builder.getStringToInt32FieldOrThrow("a")); + assertThat(builder.getStringToInt32FieldOrThrow("a")).isEqualTo(1); try { builder.putStringToInt32Field(null, -1); } catch (NullPointerException e) { @@ -734,42 +762,43 @@ } } + @Test public void testRemove() { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); - assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); + assertThat(builder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); for (int times = 0; times < 2; times++) { builder.removeInt32ToInt32Field(1); - assertEquals(-1, builder.getInt32ToInt32FieldOrDefault(1, -1)); + assertThat(builder.getInt32ToInt32FieldOrDefault(1, -1)).isEqualTo(-1); } - assertEquals("11", builder.getInt32ToStringFieldOrThrow(1)); + assertThat(builder.getInt32ToStringFieldOrThrow(1)).isEqualTo("11"); for (int times = 0; times < 2; times++) { builder.removeInt32ToStringField(1); - assertNull(builder.getInt32ToStringFieldOrDefault(1, null)); + assertThat(builder.getInt32ToStringFieldOrDefault(1, null)).isNull(); } - assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); + assertThat(builder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); for (int times = 0; times < 2; times++) { builder.removeInt32ToBytesField(1); - assertNull(builder.getInt32ToBytesFieldOrDefault(1, null)); + assertThat(builder.getInt32ToBytesFieldOrDefault(1, null)).isNull(); } - assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); + assertThat(builder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); for (int times = 0; times < 2; times++) { builder.removeInt32ToEnumField(1); - assertNull(builder.getInt32ToEnumFieldOrDefault(1, null)); + assertThat(builder.getInt32ToEnumFieldOrDefault(1, null)).isNull(); } - assertEquals(11, builder.getStringToInt32FieldOrThrow("1")); + assertThat(builder.getStringToInt32FieldOrThrow("1")).isEqualTo(11); for (int times = 0; times < 2; times++) { builder.removeStringToInt32Field("1"); - assertEquals(-1, builder.getStringToInt32FieldOrDefault("1", -1)); + assertThat(builder.getStringToInt32FieldOrDefault("1", -1)).isEqualTo(-1); } try { builder.removeStringToInt32Field(null); - fail(); + assertWithMessage("Expected NullPointerException").fail(); } catch (NullPointerException e) { // expected }
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 25c5625..821b93c 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
@@ -30,6 +30,9 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import com.google.protobuf.Descriptors.FieldDescriptor; import map_test.MapForProto2TestProto.BizarroTestMap; import map_test.MapForProto2TestProto.ReservedAsMapField; @@ -40,17 +43,21 @@ import map_test.MapForProto2TestProto.TestMapOrBuilder; import map_test.MapForProto2TestProto.TestRecursiveMap; import map_test.MapForProto2TestProto.TestUnknownEnumValue; +import map_test.Message1; +import map_test.RedactAllTypes; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Unit tests for map fields in proto2 protos. */ -public class MapForProto2Test extends TestCase { +@RunWith(JUnit4.class) +public class MapForProto2Test { private void setMapValuesUsingMutableMap(TestMap.Builder builder) { builder.getMutableInt32ToInt32Field().put(1, 11); @@ -103,6 +110,7 @@ .putStringToInt32Field("3", 33); } + @Test public void testSetMapValues() { TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder(); setMapValuesUsingMutableMap(usingMutableMapBuilder); @@ -114,7 +122,7 @@ TestMap usingAccessors = usingAccessorsBuilder.build(); assertMapValuesSet(usingAccessors); - assertEquals(usingAccessors, usingMutableMap); + assertThat(usingAccessors).isEqualTo(usingMutableMap); } private void copyMapValues(TestMap source, TestMap.Builder destination) { @@ -128,35 +136,35 @@ } private void assertMapValuesSet(TestMapOrBuilder message) { - 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()); + assertThat(message.getInt32ToInt32FieldMap()).hasSize(3); + assertThat(message.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(11); + assertThat(message.getInt32ToInt32FieldMap().get(2).intValue()).isEqualTo(22); + assertThat(message.getInt32ToInt32FieldMap().get(3).intValue()).isEqualTo(33); - assertEquals(3, message.getInt32ToStringFieldMap().size()); - assertEquals("11", message.getInt32ToStringFieldMap().get(1)); - assertEquals("22", message.getInt32ToStringFieldMap().get(2)); - assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertThat(message.getInt32ToStringFieldMap()).hasSize(3); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(1, "11"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(2, "22"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(3, "33"); - 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)); + assertThat(message.getInt32ToBytesFieldMap()).hasSize(3); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(1, TestUtil.toBytes("11")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(2, TestUtil.toBytes("22")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(3, TestUtil.toBytes("33")); - 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)); + assertThat(message.getInt32ToEnumFieldMap()).hasSize(3); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.FOO); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(2, TestMap.EnumValue.BAR); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(3, TestMap.EnumValue.BAZ); - 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()); + assertThat(message.getInt32ToMessageFieldMap()).hasSize(3); + assertThat(message.getInt32ToMessageFieldMap().get(1).getValue()).isEqualTo(11); + assertThat(message.getInt32ToMessageFieldMap().get(2).getValue()).isEqualTo(22); + assertThat(message.getInt32ToMessageFieldMap().get(3).getValue()).isEqualTo(33); - 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()); + assertThat(message.getStringToInt32FieldMap()).hasSize(3); + assertThat(message.getStringToInt32FieldMap().get("1").intValue()).isEqualTo(11); + assertThat(message.getStringToInt32FieldMap().get("2").intValue()).isEqualTo(22); + assertThat(message.getStringToInt32FieldMap().get("3").intValue()).isEqualTo(33); } private void updateMapValuesUsingMutableMap(TestMap.Builder builder) { @@ -209,6 +217,7 @@ .putStringToInt32Field("4", 44); } + @Test public void testUpdateMapValues() { TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder(); setMapValuesUsingMutableMap(usingMutableMapBuilder); @@ -220,7 +229,7 @@ TestMap usingAccessors = usingAccessorsBuilder.build(); assertMapValuesSet(usingAccessors); - assertEquals(usingAccessors, usingMutableMap); + assertThat(usingAccessors).isEqualTo(usingMutableMap); // usingMutableMapBuilder = usingMutableMap.toBuilder(); updateMapValuesUsingMutableMap(usingMutableMapBuilder); @@ -232,56 +241,57 @@ usingAccessors = usingAccessorsBuilder.build(); assertMapValuesUpdated(usingAccessors); - assertEquals(usingAccessors, usingMutableMap); + assertThat(usingAccessors).isEqualTo(usingMutableMap); } private void assertMapValuesUpdated(TestMap message) { - 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()); + assertThat(message.getInt32ToInt32FieldMap()).hasSize(3); + assertThat(message.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(111); + assertThat(message.getInt32ToInt32FieldMap().get(3).intValue()).isEqualTo(33); + assertThat(message.getInt32ToInt32FieldMap().get(4).intValue()).isEqualTo(44); - assertEquals(3, message.getInt32ToStringFieldMap().size()); - assertEquals("111", message.getInt32ToStringFieldMap().get(1)); - assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals("44", message.getInt32ToStringFieldMap().get(4)); + assertThat(message.getInt32ToStringFieldMap()).hasSize(3); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(1, "111"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(3, "33"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(4, "44"); - 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)); + assertThat(message.getInt32ToBytesFieldMap()).hasSize(3); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(1, TestUtil.toBytes("111")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(3, TestUtil.toBytes("33")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(4, TestUtil.toBytes("44")); - 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)); + assertThat(message.getInt32ToEnumFieldMap()).hasSize(3); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.BAR); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(3, TestMap.EnumValue.BAZ); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(4, TestMap.EnumValue.QUX); - 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()); + assertThat(message.getInt32ToMessageFieldMap()).hasSize(3); + assertThat(message.getInt32ToMessageFieldMap().get(1).getValue()).isEqualTo(111); + assertThat(message.getInt32ToMessageFieldMap().get(3).getValue()).isEqualTo(33); + assertThat(message.getInt32ToMessageFieldMap().get(4).getValue()).isEqualTo(44); - 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()); + assertThat(message.getStringToInt32FieldMap()).hasSize(3); + assertThat(message.getStringToInt32FieldMap().get("1").intValue()).isEqualTo(111); + assertThat(message.getStringToInt32FieldMap().get("3").intValue()).isEqualTo(33); + assertThat(message.getStringToInt32FieldMap().get("4").intValue()).isEqualTo(44); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); - assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); + assertThat(testMapOrBuilder.getInt32ToInt32FieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToInt32FieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToStringFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToStringFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToBytesFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToBytesFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToEnumFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToEnumFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToMessageFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToMessageFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getStringToInt32FieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getStringToInt32FieldCount()).isEqualTo(0); } + @Test public void testGetMapIsImmutable() { TestMap.Builder builder = TestMap.newBuilder(); assertMapsAreImmutable(builder); @@ -305,120 +315,119 @@ private <K, V> void assertImmutable(Map<K, V> map, K key, V value) { try { map.put(key, value); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } } + @Test public void testMutableMapLifecycle() { TestMap.Builder builder = TestMap.newBuilder(); Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); intMap.put(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + assertThat(builder.build().getInt32ToInt32Field()).isEqualTo(newMap(1, 2)); try { intMap.put(2, 3); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertThat(builder.getInt32ToInt32Field()).isEqualTo(newMap(1, 2)); builder.getMutableInt32ToInt32Field().put(2, 3); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertThat(builder.getInt32ToInt32Field()).isEqualTo(newMap(1, 2, 2, 3)); // Map<Integer, TestMap.EnumValue> enumMap = builder.getMutableInt32ToEnumField(); enumMap.put(1, TestMap.EnumValue.BAR); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); + assertThat(builder.build().getInt32ToEnumField()) + .isEqualTo(newMap(1, TestMap.EnumValue.BAR)); try { enumMap.put(2, TestMap.EnumValue.FOO); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); + assertThat(builder.getInt32ToEnumField()).isEqualTo(newMap(1, TestMap.EnumValue.BAR)); builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.FOO); - assertEquals( - newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), - builder.getInt32ToEnumField()); + assertThat(builder.getInt32ToEnumField()) + .isEqualTo(newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO)); // Map<Integer, String> stringMap = builder.getMutableInt32ToStringField(); stringMap.put(1, "1"); - assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); + assertThat(builder.build().getInt32ToStringField()).isEqualTo(newMap(1, "1")); try { stringMap.put(2, "2"); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); + assertThat(builder.getInt32ToStringField()).isEqualTo(newMap(1, "1")); builder.getMutableInt32ToStringField().put(2, "2"); - assertEquals( - newMap(1, "1", 2, "2"), - builder.getInt32ToStringField()); + assertThat(builder.getInt32ToStringField()).isEqualTo(newMap(1, "1", 2, "2")); // Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField(); messageMap.put(1, TestMap.MessageValue.getDefaultInstance()); - assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.build().getInt32ToMessageField()); + assertThat(builder.build().getInt32ToMessageField()) + .isEqualTo(newMap(1, TestMap.MessageValue.getDefaultInstance())); try { messageMap.put(2, TestMap.MessageValue.getDefaultInstance()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageField()); + assertThat(builder.getInt32ToMessageField()) + .isEqualTo(newMap(1, TestMap.MessageValue.getDefaultInstance())); builder.getMutableInt32ToMessageField().put(2, TestMap.MessageValue.getDefaultInstance()); - assertEquals( + assertThat(builder.getInt32ToMessageField()).isEqualTo( newMap(1, TestMap.MessageValue.getDefaultInstance(), - 2, TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageField()); + 2, TestMap.MessageValue.getDefaultInstance())); } // + @Test public void testMutableMapLifecycle_collections() { TestMap.Builder builder = TestMap.newBuilder(); Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); intMap.put(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + assertThat(builder.build().getInt32ToInt32Field()).isEqualTo(newMap(1, 2)); try { intMap.remove(2); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { intMap.entrySet().remove(new Object()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { intMap.entrySet().iterator().remove(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { intMap.keySet().remove(new Object()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { intMap.values().remove(new Object()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { intMap.values().iterator().remove(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(newMap(1, 2), intMap); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + assertThat(intMap).isEqualTo(newMap(1, 2)); + assertThat(builder.getInt32ToInt32Field()).isEqualTo(newMap(1, 2)); + assertThat(builder.build().getInt32ToInt32Field()).isEqualTo(newMap(1, 2)); } // private static <K, V> Map<K, V> newMap(K key1, V value1) { @@ -434,6 +443,7 @@ return map; } + @Test public void testGettersAndSetters() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); @@ -456,6 +466,7 @@ assertMapValuesCleared(message); } + @Test public void testPutAll() throws Exception { TestMap.Builder sourceBuilder = TestMap.newBuilder(); setMapValuesUsingAccessors(sourceBuilder); @@ -466,67 +477,69 @@ copyMapValues(source, destination); assertMapValuesSet(destination.build()); - assertEquals(3, destination.getInt32ToEnumFieldCount()); + assertThat(destination.getInt32ToEnumFieldCount()).isEqualTo(3); } + @Test public void testPutChecksNullKeysAndValues() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); try { builder.putInt32ToStringField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToBytesField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToEnumField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToMessageField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putStringToInt32Field(null, 1); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } } + @Test public void testSerializeAndParse() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); TestMap message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesSet(message); builder = message.toBuilder(); updateMapValuesUsingAccessors(builder); message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesUpdated(message); builder = message.toBuilder(); builder.clear(); message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesCleared(message); } @@ -539,39 +552,41 @@ return TestMap.parser().parseFrom(ByteString.copyFrom(byteArrayOutputStream.toByteArray())); } + @Test public void testParseError() throws Exception { ByteString bytes = TestUtil.toBytes("SOME BYTES"); String stringKey = "a string key"; TestMap map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToInt32Field(5, bytes).build()); - assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1)); + assertThat(map.getInt32ToInt32FieldOrDefault(5, -1)).isEqualTo(0); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToStringField(stringKey, 5).build()); - assertEquals("", map.getInt32ToStringFieldOrDefault(0, null)); + assertThat(map.getInt32ToStringFieldOrDefault(0, null)).isEmpty(); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToBytesField(stringKey, 5).build()); - assertEquals(map.getInt32ToBytesFieldOrDefault(0, null), ByteString.EMPTY); + assertThat(ByteString.EMPTY).isEqualTo(map.getInt32ToBytesFieldOrDefault(0, null)); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToEnumField(stringKey, bytes).build()); - assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null)); + assertThat(map.getInt32ToEnumFieldOrDefault(0, null)).isEqualTo(TestMap.EnumValue.FOO); try { tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToMessageField(stringKey, bytes).build()); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { - assertTrue(expected.getUnfinishedMessage() instanceof TestMap); + assertThat(expected.getUnfinishedMessage()).isInstanceOf(TestMap.class); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); + assertThat(map.getInt32ToMessageFieldMap()).isEmpty(); } map = tryParseTestMap( BizarroTestMap.newBuilder().putStringToInt32Field(stringKey, bytes).build()); - assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1)); + assertThat(map.getStringToInt32FieldOrDefault(stringKey, -1)).isEqualTo(0); } + @Test public void testMergeFrom() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); @@ -582,6 +597,7 @@ assertMapValuesSet(other.build()); } + @Test public void testEqualsAndHashCode() throws Exception { // Test that generated equals() and hashCode() will disregard the order // of map entries when comparing/hashing map fields. @@ -600,13 +616,13 @@ b2.putInt32ToInt32Field(3, 4); TestMap m2 = b2.build(); - assertEquals(m1, m2); - assertEquals(m1.hashCode(), m2.hashCode()); + assertThat(m2).isEqualTo(m1); + assertThat(m2.hashCode()).isEqualTo(m1.hashCode()); // Make sure we did compare map fields. b2.putInt32ToInt32Field(1, 0); m2 = b2.build(); - assertFalse(m1.equals(m2)); + assertThat(m1.equals(m2)).isFalse(); // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed // to be different. } @@ -636,16 +652,16 @@ Message mapEntry = (Message) entry; Object key = getFieldValue(mapEntry, "key"); Object value = getFieldValue(mapEntry, "value"); - assertTrue(values.containsKey(key)); - assertEquals(value, values.get(key)); + assertThat(values.containsKey(key)).isTrue(); + assertThat(values.get(key)).isEqualTo(value); } - assertEquals(values.size(), message.getRepeatedFieldCount(field)); + assertThat(message.getRepeatedFieldCount(field)).isEqualTo(values.size()); for (int i = 0; i < message.getRepeatedFieldCount(field); i++) { Message mapEntry = (Message) message.getRepeatedField(field, i); Object key = getFieldValue(mapEntry, "key"); Object value = getFieldValue(mapEntry, "value"); - assertTrue(values.containsKey(key)); - assertEquals(value, values.get(key)); + assertThat(values.containsKey(key)).isTrue(); + assertThat(values.get(key)).isEqualTo(value); } } @@ -660,7 +676,7 @@ } private static void setMapValues(Message.Builder builder, String name, Map<?, ?> values) { - List<Message> entryList = new ArrayList<Message>(); + List<Message> entryList = new ArrayList<>(); for (Map.Entry<?, ?> entry : values.entrySet()) { entryList.add(newMapEntry(builder, name, entry.getKey(), entry.getValue())); } @@ -669,12 +685,13 @@ } private static <K, V> Map<K, V> mapForValues(K key1, V value1, K key2, V value2) { - Map<K, V> map = new HashMap<K, V>(); + Map<K, V> map = new HashMap<>(); map.put(key1, value1); map.put(key2, value2); return map; } + @Test public void testReflectionApi() throws Exception { // In reflection API, map fields are just repeated message fields. TestMap.Builder builder = @@ -698,8 +715,8 @@ builder.clearField(f("int32_to_int32_field")); builder.clearField(f("int32_to_message_field")); message = builder.build(); - assertEquals(0, message.getInt32ToInt32FieldMap().size()); - assertEquals(0, message.getInt32ToMessageFieldMap().size()); + assertThat(message.getInt32ToInt32FieldMap()).isEmpty(); + assertThat(message.getInt32ToMessageFieldMap()).isEmpty(); // Test setField() setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44)); @@ -710,10 +727,10 @@ 111, MessageValue.newBuilder().setValue(222).build(), 333, MessageValue.newBuilder().setValue(444).build())); message = builder.build(); - 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()); + assertThat(message.getInt32ToInt32FieldMap().get(11).intValue()).isEqualTo(22); + assertThat(message.getInt32ToInt32FieldMap().get(33).intValue()).isEqualTo(44); + assertThat(message.getInt32ToMessageFieldMap().get(111).getValue()).isEqualTo(222); + assertThat(message.getInt32ToMessageFieldMap().get(333).getValue()).isEqualTo(444); // Test addRepeatedField builder.addRepeatedField( @@ -726,8 +743,8 @@ 555, MessageValue.newBuilder().setValue(666).build())); message = builder.build(); - assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue()); - assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue()); + assertThat(message.getInt32ToInt32FieldMap().get(55).intValue()).isEqualTo(66); + assertThat(message.getInt32ToMessageFieldMap().get(555).getValue()).isEqualTo(666); // Test addRepeatedField (overriding existing values) builder.addRepeatedField( @@ -740,8 +757,8 @@ 555, MessageValue.newBuilder().setValue(555).build())); message = builder.build(); - assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); - assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue()); + assertThat(message.getInt32ToInt32FieldMap().get(55).intValue()).isEqualTo(55); + assertThat(message.getInt32ToMessageFieldMap().get(555).getValue()).isEqualTo(555); // Test setRepeatedField for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) { @@ -755,12 +772,13 @@ builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build()); } message = builder.build(); - assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue()); - assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue()); - assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertThat(message.getInt32ToInt32FieldMap().get(22).intValue()).isEqualTo(11); + assertThat(message.getInt32ToInt32FieldMap().get(44).intValue()).isEqualTo(33); + assertThat(message.getInt32ToInt32FieldMap().get(55).intValue()).isEqualTo(55); } // See additional coverage in TextFormatTest.java. + @Test public void testTextFormat() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); @@ -775,6 +793,7 @@ assertMapValuesSet(message); } + @Test public void testDynamicMessage() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); @@ -782,14 +801,18 @@ Message dynamicDefaultInstance = DynamicMessage.getDefaultInstance(TestMap.getDescriptor()); Message dynamicMessage = - dynamicDefaultInstance.newBuilderForType().mergeFrom(message.toByteString()).build(); + dynamicDefaultInstance + .newBuilderForType() + .mergeFrom(message.toByteString(), ExtensionRegistry.getEmptyRegistry()) + .build(); - assertEquals(message, dynamicMessage); - assertEquals(message.hashCode(), dynamicMessage.hashCode()); + assertThat(dynamicMessage).isEqualTo(message); + assertThat(dynamicMessage.hashCode()).isEqualTo(message.hashCode()); } // Check that DynamicMessage handles map field serialization the same way as generated code // regarding unset key and value field in a map entry. + @Test public void testDynamicMessageUnsetKeyAndValue() throws Exception { FieldDescriptor field = f("int32_to_int32_field"); @@ -800,11 +823,12 @@ Message message = builder.build(); ByteString bytes = message.toByteString(); // Parse it back to the same generated type. - Message generatedMessage = TestMap.parseFrom(bytes); + Message generatedMessage = TestMap.parseFrom(bytes, ExtensionRegistry.getEmptyRegistry()); // Assert the serialized bytes are equivalent. - assertEquals(generatedMessage.toByteString(), bytes); + assertThat(bytes).isEqualTo(generatedMessage.toByteString()); } + @Test public void testReflectionEqualsAndHashCode() throws Exception { // Test that generated equals() and hashCode() will disregard the order // of map entries when comparing/hashing map fields. @@ -825,69 +849,80 @@ b2.addRepeatedField(field, newMapEntry(b2, "int32_to_int32_field", 3, 4)); Message m2 = b2.build(); - assertEquals(m1, m2); - assertEquals(m1.hashCode(), m2.hashCode()); + assertThat(m2).isEqualTo(m1); + assertThat(m2.hashCode()).isEqualTo(m1.hashCode()); // Make sure we did compare map fields. b2.setRepeatedField(field, 0, newMapEntry(b1, "int32_to_int32_field", 0, 0)); m2 = b2.build(); - assertFalse(m1.equals(m2)); + assertThat(m1.equals(m2)).isFalse(); // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed // to be different. } + @Test public void testUnknownEnumValues() throws Exception { - TestUnknownEnumValue.Builder builder = - TestUnknownEnumValue.newBuilder().putInt32ToInt32Field(1, 1).putInt32ToInt32Field(2, 54321); - ByteString data = builder.build().toByteString(); + TestUnknownEnumValue builder = + TestUnknownEnumValue.newBuilder() + .putInt32ToInt32Field(1, 1) + .putInt32ToInt32Field(2, 54321) + .build(); + ByteString data = builder.toByteString(); - TestMap message = TestMap.parseFrom(data); + TestMap message = TestMap.parseFrom(data, ExtensionRegistry.getEmptyRegistry()); // Entries with unknown enum values will be stored into UnknownFieldSet so // there is only one entry in the map. - assertEquals(1, message.getInt32ToEnumFieldMap().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertThat(message.getInt32ToEnumFieldMap()).hasSize(1); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.BAR); // UnknownFieldSet should not be empty. - assertFalse(message.getUnknownFields().asMap().isEmpty()); + assertThat(message.getUnknownFields().asMap()).isNotEmpty(); // Serializing and parsing should preserve the unknown entry. data = message.toByteString(); - TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data); - assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size()); - assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue()); - assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue()); + TestUnknownEnumValue messageWithUnknownEnums = + TestUnknownEnumValue.parseFrom(data, ExtensionRegistry.getEmptyRegistry()); + assertThat(messageWithUnknownEnums.getInt32ToInt32FieldMap()).hasSize(2); + assertThat(messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(1); + assertThat(messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue()) + .isEqualTo(54321); } + @Test public void testRequiredMessage() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); builder.putRequiredMessageMap(0, MessageWithRequiredFields.newBuilder().buildPartial()); TestMap message = builder.buildPartial(); - assertFalse(message.isInitialized()); + assertThat(message.isInitialized()).isFalse(); builder.putRequiredMessageMap(0, MessageWithRequiredFields.newBuilder().setValue(1).build()); message = builder.build(); - assertTrue(message.isInitialized()); + assertThat(message.isInitialized()).isTrue(); } + @Test public void testRecursiveMap() throws Exception { TestRecursiveMap.Builder builder = TestRecursiveMap.newBuilder(); builder.putRecursiveMapField(1, TestRecursiveMap.newBuilder().setValue(2).build()); builder.putRecursiveMapField(3, TestRecursiveMap.newBuilder().setValue(4).build()); ByteString data = builder.build().toByteString(); - TestRecursiveMap message = TestRecursiveMap.parseFrom(data); - assertEquals(2, message.getRecursiveMapFieldMap().get(1).getValue()); - assertEquals(4, message.getRecursiveMapFieldMap().get(3).getValue()); + TestRecursiveMap message = + TestRecursiveMap.parseFrom(data, ExtensionRegistry.getEmptyRegistry()); + assertThat(message.getRecursiveMapFieldMap().get(1).getValue()).isEqualTo(2); + assertThat(message.getRecursiveMapFieldMap().get(3).getValue()).isEqualTo(4); } + @Test public void testIterationOrder() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); TestMap message = builder.build(); - assertEquals( - Arrays.asList("1", "2", "3"), - new ArrayList<String>(message.getStringToInt32FieldMap().keySet())); + assertThat(new ArrayList<String>(message.getStringToInt32FieldMap().keySet())) + .containsExactly("1", "2", "3") + .inOrder(); } + @Test public void testContains() { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); @@ -896,37 +931,38 @@ } private void assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder) { - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(1)); - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(2)); - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(3)); - assertFalse(testMapOrBuilder.containsInt32ToInt32Field(-1)); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToStringField(1)); - assertTrue(testMapOrBuilder.containsInt32ToStringField(2)); - assertTrue(testMapOrBuilder.containsInt32ToStringField(3)); - assertFalse(testMapOrBuilder.containsInt32ToStringField(-1)); + assertThat(testMapOrBuilder.containsInt32ToStringField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(1)); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(2)); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(3)); - assertFalse(testMapOrBuilder.containsInt32ToBytesField(-1)); + assertThat(testMapOrBuilder.containsInt32ToBytesField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(1)); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(2)); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(3)); - assertFalse(testMapOrBuilder.containsInt32ToEnumField(-1)); + assertThat(testMapOrBuilder.containsInt32ToEnumField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(1)); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(2)); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(3)); - assertFalse(testMapOrBuilder.containsInt32ToMessageField(-1)); + assertThat(testMapOrBuilder.containsInt32ToMessageField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsStringToInt32Field("1")); - assertTrue(testMapOrBuilder.containsStringToInt32Field("2")); - assertTrue(testMapOrBuilder.containsStringToInt32Field("3")); - assertFalse(testMapOrBuilder.containsStringToInt32Field("-1")); + assertThat(testMapOrBuilder.containsStringToInt32Field("1")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("2")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("3")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("-1")).isFalse(); } + @Test public void testCount() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -938,23 +974,24 @@ assertMapCounts(3, message); builder = message.toBuilder().putInt32ToInt32Field(4, 44); - assertEquals(4, builder.getInt32ToInt32FieldCount()); - assertEquals(4, builder.build().getInt32ToInt32FieldCount()); + assertThat(builder.getInt32ToInt32FieldCount()).isEqualTo(4); + assertThat(builder.build().getInt32ToInt32FieldCount()).isEqualTo(4); // already present - should be unchanged builder.putInt32ToInt32Field(4, 44); - assertEquals(4, builder.getInt32ToInt32FieldCount()); + assertThat(builder.getInt32ToInt32FieldCount()).isEqualTo(4); } private void assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder) { - assertEquals(expectedCount, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getStringToInt32FieldCount()); + assertThat(testMapOrBuilder.getInt32ToInt32FieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToStringFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToBytesFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToEnumFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToMessageFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getStringToInt32FieldCount()).isEqualTo(expectedCount); } + @Test public void testGetOrDefault() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -964,34 +1001,38 @@ } public void doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder) { - assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11)); - assertEquals(-11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11)); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11)).isEqualTo(11); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11)).isEqualTo(-11); - assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11")); - assertNull("-11", testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11")).isEqualTo("11"); + assertWithMessage("-11") + .that(testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null)) + .isNull(); - assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null)) + .isEqualTo(TestUtil.toBytes("11")); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null)).isNull(); - assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null)) + .isEqualTo(TestMap.EnumValue.FOO); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null)).isNull(); - assertEquals( - MessageValue.newBuilder().setValue(11).build(), - testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null)) + .isEqualTo(MessageValue.newBuilder().setValue(11).build()); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null)).isNull(); - assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11)); - assertEquals(-11, testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11)); + assertThat(testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11)).isEqualTo(11); + assertThat(testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11)).isEqualTo(-11); try { testMapOrBuilder.getStringToInt32FieldOrDefault(null, -11); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } } + @Test public void testGetOrThrow() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -1001,100 +1042,100 @@ } public void doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder) { - assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); try { testMapOrBuilder.getInt32ToInt32FieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToStringFieldOrThrow(1)).isEqualTo("11"); try { testMapOrBuilder.getInt32ToStringFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); try { testMapOrBuilder.getInt32ToBytesFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); try { testMapOrBuilder.getInt32ToEnumFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals( - MessageValue.newBuilder().setValue(11).build(), - testMapOrBuilder.getInt32ToMessageFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrThrow(1)) + .isEqualTo(MessageValue.newBuilder().setValue(11).build()); try { testMapOrBuilder.getInt32ToMessageFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrThrow("1")); + assertThat(testMapOrBuilder.getStringToInt32FieldOrThrow("1")).isEqualTo(11); try { testMapOrBuilder.getStringToInt32FieldOrThrow("-1"); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } try { testMapOrBuilder.getStringToInt32FieldOrThrow(null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } } + @Test public void testPut() { TestMap.Builder builder = TestMap.newBuilder(); builder.putInt32ToInt32Field(1, 11); - assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); + assertThat(builder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); builder.putInt32ToStringField(1, "a"); - assertEquals("a", builder.getInt32ToStringFieldOrThrow(1)); + assertThat(builder.getInt32ToStringFieldOrThrow(1)).isEqualTo("a"); try { builder.putInt32ToStringField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } builder.putInt32ToBytesField(1, TestUtil.toBytes("11")); - assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); + assertThat(builder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); try { builder.putInt32ToBytesField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } builder.putInt32ToEnumField(1, TestMap.EnumValue.FOO); - assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); + assertThat(builder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); try { builder.putInt32ToEnumField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } builder.putStringToInt32Field("a", 1); - assertEquals(1, builder.getStringToInt32FieldOrThrow("a")); + assertThat(builder.getStringToInt32FieldOrThrow("a")).isEqualTo(1); try { builder.putStringToInt32Field(null, -1); } catch (NullPointerException e) { @@ -1102,79 +1143,79 @@ } } + @Test public void testRemove() { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); - assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); + assertThat(builder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); for (int times = 0; times < 2; times++) { builder.removeInt32ToInt32Field(1); - assertEquals(-1, builder.getInt32ToInt32FieldOrDefault(1, -1)); + assertThat(builder.getInt32ToInt32FieldOrDefault(1, -1)).isEqualTo(-1); } - assertEquals("11", builder.getInt32ToStringFieldOrThrow(1)); + assertThat(builder.getInt32ToStringFieldOrThrow(1)).isEqualTo("11"); for (int times = 0; times < 2; times++) { builder.removeInt32ToStringField(1); - assertNull(builder.getInt32ToStringFieldOrDefault(1, null)); + assertThat(builder.getInt32ToStringFieldOrDefault(1, null)).isNull(); } - assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); + assertThat(builder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); for (int times = 0; times < 2; times++) { builder.removeInt32ToBytesField(1); - assertNull(builder.getInt32ToBytesFieldOrDefault(1, null)); + assertThat(builder.getInt32ToBytesFieldOrDefault(1, null)).isNull(); } - assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); + assertThat(builder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); for (int times = 0; times < 2; times++) { builder.removeInt32ToEnumField(1); - assertNull(builder.getInt32ToEnumFieldOrDefault(1, null)); + assertThat(builder.getInt32ToEnumFieldOrDefault(1, null)).isNull(); } - assertEquals(11, builder.getStringToInt32FieldOrThrow("1")); + assertThat(builder.getStringToInt32FieldOrThrow("1")).isEqualTo(11); for (int times = 0; times < 2; times++) { builder.removeStringToInt32Field("1"); - assertEquals(-1, builder.getStringToInt32FieldOrDefault("1", -1)); + assertThat(builder.getStringToInt32FieldOrDefault("1", -1)).isEqualTo(-1); } try { builder.removeStringToInt32Field(null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } } // Regression test for b/20494788 + @Test public void testMapInitializationOrder() throws Exception { - assertEquals( - "RedactAllTypes", - map_test.RedactAllTypes.getDefaultInstance() - .getDescriptorForType() - .getName()); + assertThat(RedactAllTypes.getDefaultInstance().getDescriptorForType().getName()) + .isEqualTo("RedactAllTypes"); - map_test.Message1.Builder builder = - map_test.Message1.newBuilder(); + Message1.Builder builder = Message1.newBuilder(); builder.putMapField("key", true); - map_test.Message1 message = builder.build(); + Message1 message = builder.build(); Message mapEntry = (Message) message.getRepeatedField( message.getDescriptorForType().findFieldByName("map_field"), 0); - assertEquals(2, mapEntry.getAllFields().size()); + assertThat(mapEntry.getAllFields()).hasSize(2); } + @Test public void testReservedWordsFieldNames() { - ReservedAsMapField unused1 = ReservedAsMapField.newBuilder().build(); - ReservedAsMapFieldWithEnumValue unused2 = ReservedAsMapFieldWithEnumValue.newBuilder().build(); + ReservedAsMapField unused1 = ReservedAsMapField.getDefaultInstance(); + ReservedAsMapFieldWithEnumValue unused2 = ReservedAsMapFieldWithEnumValue.getDefaultInstance(); } + @Test public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); assertMapValuesSet(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); + assertThat(message.getStringToInt32FieldMap()).isEqualTo(message.getStringToInt32FieldMap()); + assertThat(message.getInt32ToBytesFieldMap()).isEqualTo(message.getInt32ToBytesFieldMap()); + assertThat(message.getInt32ToEnumFieldMap()).isEqualTo(message.getInt32ToEnumFieldMap()); + assertThat(message.getInt32ToMessageFieldMap()).isEqualTo(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 33282ad..5f39893 100644 --- a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java
@@ -30,7 +30,8 @@ package com.google.protobuf; -import static org.junit.Assert.assertArrayEquals; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import map_lite_test.MapTestProto.BizarroTestMap; import map_lite_test.MapTestProto.TestMap; @@ -39,13 +40,15 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Unit tests for map fields. */ -public final class MapLiteTest extends TestCase { +@RunWith(JUnit4.class) +public final class MapLiteTest { private void setMapValues(TestMap.Builder builder) { builder @@ -69,6 +72,7 @@ .putStringToInt32Field("3", 33); } + @Test public void testSetMapValues() { TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder(); setMapValues(usingMutableMapBuilder); @@ -79,7 +83,7 @@ setMapValues(usingAccessorsBuilder); TestMap usingAccessors = usingAccessorsBuilder.build(); assertMapValuesSet(usingAccessors); - assertEquals(usingAccessors, usingMutableMap); + assertThat(usingMutableMap).isEqualTo(usingAccessors); } private void copyMapValues(TestMap source, TestMap.Builder destination) { @@ -93,35 +97,35 @@ } private void assertMapValuesSet(TestMap message) { - 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()); + assertThat(message.getInt32ToInt32FieldMap()).hasSize(3); + assertThat(message.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(11); + assertThat(message.getInt32ToInt32FieldMap().get(2).intValue()).isEqualTo(22); + assertThat(message.getInt32ToInt32FieldMap().get(3).intValue()).isEqualTo(33); - assertEquals(3, message.getInt32ToStringFieldMap().size()); - assertEquals("11", message.getInt32ToStringFieldMap().get(1)); - assertEquals("22", message.getInt32ToStringFieldMap().get(2)); - assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertThat(message.getInt32ToStringFieldMap()).hasSize(3); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(1, "11"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(2, "22"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(3, "33"); - 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)); + assertThat(message.getInt32ToBytesFieldMap()).hasSize(3); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(1, TestUtil.toBytes("11")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(2, TestUtil.toBytes("22")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(3, TestUtil.toBytes("33")); - 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)); + assertThat(message.getInt32ToEnumFieldMap()).hasSize(3); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.FOO); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(2, TestMap.EnumValue.BAR); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(3, TestMap.EnumValue.BAZ); - 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()); + assertThat(message.getInt32ToMessageFieldMap()).hasSize(3); + assertThat(message.getInt32ToMessageFieldMap().get(1).getValue()).isEqualTo(11); + assertThat(message.getInt32ToMessageFieldMap().get(2).getValue()).isEqualTo(22); + assertThat(message.getInt32ToMessageFieldMap().get(3).getValue()).isEqualTo(33); - 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()); + assertThat(message.getStringToInt32FieldMap()).hasSize(3); + assertThat(message.getStringToInt32FieldMap().get("1").intValue()).isEqualTo(11); + assertThat(message.getStringToInt32FieldMap().get("2").intValue()).isEqualTo(22); + assertThat(message.getStringToInt32FieldMap().get("3").intValue()).isEqualTo(33); } private void updateMapValues(TestMap.Builder builder) { @@ -146,6 +150,7 @@ .putStringToInt32Field("4", 44); } + @Test public void testUpdateMapValues() { TestMap.Builder mapBuilder = TestMap.newBuilder(); setMapValues(mapBuilder); @@ -159,52 +164,53 @@ } private void assertMapValuesUpdated(TestMap message) { - 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()); + assertThat(message.getInt32ToInt32FieldMap()).hasSize(3); + assertThat(message.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(111); + assertThat(message.getInt32ToInt32FieldMap().get(3).intValue()).isEqualTo(33); + assertThat(message.getInt32ToInt32FieldMap().get(4).intValue()).isEqualTo(44); - assertEquals(3, message.getInt32ToStringFieldMap().size()); - assertEquals("111", message.getInt32ToStringFieldMap().get(1)); - assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals("44", message.getInt32ToStringFieldMap().get(4)); + assertThat(message.getInt32ToStringFieldMap()).hasSize(3); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(1, "111"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(3, "33"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(4, "44"); - 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)); + assertThat(message.getInt32ToBytesFieldMap()).hasSize(3); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(1, TestUtil.toBytes("111")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(3, TestUtil.toBytes("33")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(4, TestUtil.toBytes("44")); - 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)); + assertThat(message.getInt32ToEnumFieldMap()).hasSize(3); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.BAR); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(3, TestMap.EnumValue.BAZ); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(4, TestMap.EnumValue.QUX); - 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()); + assertThat(message.getInt32ToMessageFieldMap()).hasSize(3); + assertThat(message.getInt32ToMessageFieldMap().get(1).getValue()).isEqualTo(111); + assertThat(message.getInt32ToMessageFieldMap().get(3).getValue()).isEqualTo(33); + assertThat(message.getInt32ToMessageFieldMap().get(4).getValue()).isEqualTo(44); - 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()); + assertThat(message.getStringToInt32FieldMap()).hasSize(3); + assertThat(message.getStringToInt32FieldMap().get("1").intValue()).isEqualTo(111); + assertThat(message.getStringToInt32FieldMap().get("3").intValue()).isEqualTo(33); + assertThat(message.getStringToInt32FieldMap().get("4").intValue()).isEqualTo(44); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); - assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); + assertThat(testMapOrBuilder.getInt32ToInt32FieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToInt32FieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToStringFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToStringFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToBytesFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToBytesFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToEnumFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToEnumFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToMessageFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToMessageFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getStringToInt32FieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getStringToInt32FieldCount()).isEqualTo(0); } + @Test public void testSanityCopyOnWrite() throws InvalidProtocolBufferException { // Since builders are implemented as a thin wrapper around a message // instance, we attempt to verify that we can't cause the builder to modify @@ -213,14 +219,15 @@ TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); builder.putInt32ToInt32Field(1, 2); - assertTrue(message.getInt32ToInt32FieldMap().isEmpty()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); + assertThat(message.getInt32ToInt32FieldMap()).isEmpty(); + assertThat(builder.getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2)); message = builder.build(); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); + assertThat(message.getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2)); + assertThat(builder.getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2, 2, 3)); } + @Test public void testGetMapIsImmutable() { TestMap.Builder builder = TestMap.newBuilder(); assertMapsAreImmutable(builder); @@ -244,63 +251,65 @@ private <K, V> void assertImmutable(Map<K, V> map, K key, V value) { try { map.put(key, value); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } if (!map.isEmpty()) { try { map.entrySet().remove(map.entrySet().iterator().next()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } } } + @Test public void testMapFieldClear() { TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2); builder.clearInt32ToInt32Field(); - assertEquals(0, builder.getInt32ToInt32FieldCount()); + assertThat(builder.getInt32ToInt32FieldCount()).isEqualTo(0); } + @Test public void testMutableMapLifecycle() { TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); + assertThat(builder.build().getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2)); + assertThat(builder.getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2)); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); + assertThat(builder.getInt32ToInt32FieldMap()).isEqualTo(newMap(1, 2, 2, 3)); builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap()); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap()); + assertThat(builder.build().getInt32ToEnumFieldMap()) + .isEqualTo(newMap(1, TestMap.EnumValue.BAR)); + assertThat(builder.getInt32ToEnumFieldMap()).isEqualTo(newMap(1, TestMap.EnumValue.BAR)); builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO); - assertEquals( - newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), - builder.getInt32ToEnumFieldMap()); + assertThat(builder.getInt32ToEnumFieldMap()) + .isEqualTo(newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO)); builder.putInt32ToStringField(1, "1"); - assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap()); - assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap()); + assertThat(builder.build().getInt32ToStringFieldMap()).isEqualTo(newMap(1, "1")); + assertThat(builder.getInt32ToStringFieldMap()).isEqualTo(newMap(1, "1")); builder.putInt32ToStringField(2, "2"); - assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap()); + assertThat(builder.getInt32ToStringFieldMap()).isEqualTo(newMap(1, "1", 2, "2")); builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance()); - assertEquals( - newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.build().getInt32ToMessageFieldMap()); - assertEquals( - newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap()); + assertThat(builder.build().getInt32ToMessageFieldMap()) + .isEqualTo(newMap(1, TestMap.MessageValue.getDefaultInstance())); + assertThat(builder.getInt32ToMessageFieldMap()) + .isEqualTo(newMap(1, TestMap.MessageValue.getDefaultInstance())); builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance()); - assertEquals( - newMap( - 1, - TestMap.MessageValue.getDefaultInstance(), - 2, - TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageFieldMap()); + assertThat(builder.getInt32ToMessageFieldMap()) + .isEqualTo( + newMap( + 1, + TestMap.MessageValue.getDefaultInstance(), + 2, + TestMap.MessageValue.getDefaultInstance())); } + @Test public void testGettersAndSetters() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); @@ -323,6 +332,7 @@ assertMapValuesCleared(message); } + @Test public void testPutAll() throws Exception { TestMap.Builder sourceBuilder = TestMap.newBuilder(); setMapValues(sourceBuilder); @@ -334,6 +344,7 @@ assertMapValuesSet(destination.build()); } + @Test public void testPutAllForUnknownEnumValues() throws Exception { TestMap.Builder sourceBuilder = TestMap.newBuilder() @@ -346,84 +357,88 @@ destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap()); TestMap destination = destinationBuilder.build(); - 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()); + assertThat(destination.getInt32ToEnumFieldValueMap().get(0).intValue()).isEqualTo(0); + assertThat(destination.getInt32ToEnumFieldValueMap().get(1).intValue()).isEqualTo(1); + assertThat(destination.getInt32ToEnumFieldValueMap().get(2).intValue()).isEqualTo(1000); + assertThat(destination.getInt32ToEnumFieldCount()).isEqualTo(3); } + @Test public void testPutForUnknownEnumValues() throws Exception { - TestMap.Builder builder = + TestMap builder = TestMap.newBuilder() .putInt32ToEnumFieldValue(0, 0) .putInt32ToEnumFieldValue(1, 1) - .putInt32ToEnumFieldValue(2, 1000); // unknown value. - TestMap message = builder.build(); + .putInt32ToEnumFieldValue(2, 1000) + .build(); // unknown value. + TestMap message = builder; - assertEquals(0, message.getInt32ToEnumFieldValueOrThrow(0)); - assertEquals(1, message.getInt32ToEnumFieldValueOrThrow(1)); - assertEquals(1000, message.getInt32ToEnumFieldValueOrThrow(2)); - assertEquals(3, message.getInt32ToEnumFieldCount()); + assertThat(message.getInt32ToEnumFieldValueOrThrow(0)).isEqualTo(0); + assertThat(message.getInt32ToEnumFieldValueOrThrow(1)).isEqualTo(1); + assertThat(message.getInt32ToEnumFieldValueOrThrow(2)).isEqualTo(1000); + assertThat(message.getInt32ToEnumFieldCount()).isEqualTo(3); } + @Test public void testPutChecksNullKeysAndValues() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); try { builder.putInt32ToStringField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToBytesField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToEnumField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToMessageField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putStringToInt32Field(null, 1); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } } + @Test public void testSerializeAndParse() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesSet(message); builder = message.toBuilder(); updateMapValues(builder); message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesUpdated(message); builder = message.toBuilder(); builder.clear(); message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesCleared(message); } @@ -436,39 +451,41 @@ return TestMap.parser().parseFrom(ByteString.copyFrom(byteArrayOutputStream.toByteArray())); } + @Test public void testParseError() throws Exception { ByteString bytes = TestUtil.toBytes("SOME BYTES"); String stringKey = "a string key"; TestMap map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToInt32Field(5, bytes).build()); - assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1)); + assertThat(map.getInt32ToInt32FieldOrDefault(5, -1)).isEqualTo(0); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToStringField(stringKey, 5).build()); - assertEquals("", map.getInt32ToStringFieldOrDefault(0, null)); + assertThat(map.getInt32ToStringFieldOrDefault(0, null)).isEmpty(); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToBytesField(stringKey, 5).build()); - assertEquals(map.getInt32ToBytesFieldOrDefault(0, null), ByteString.EMPTY); + assertThat(ByteString.EMPTY).isEqualTo(map.getInt32ToBytesFieldOrDefault(0, null)); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToEnumField(stringKey, bytes).build()); - assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null)); + assertThat(map.getInt32ToEnumFieldOrDefault(0, null)).isEqualTo(TestMap.EnumValue.FOO); try { tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToMessageField(stringKey, bytes).build()); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { - assertTrue(expected.getUnfinishedMessage() instanceof TestMap); + assertThat(expected.getUnfinishedMessage()).isInstanceOf(TestMap.class); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); + assertThat(map.getInt32ToMessageFieldMap()).isEmpty(); } map = tryParseTestMap( BizarroTestMap.newBuilder().putStringToInt32Field(stringKey, bytes).build()); - assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1)); + assertThat(map.getStringToInt32FieldOrDefault(stringKey, -1)).isEqualTo(0); } + @Test public void testMergeFrom() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); @@ -479,18 +496,20 @@ assertMapValuesSet(other.build()); } + @Test public void testEqualsAndHashCode() throws Exception { // Test that generated equals() and hashCode() will disregard the order // of map entries when comparing/hashing map fields. // We can't control the order of elements in a HashMap. The best we can do // here is to add elements in different order. - TestMap.Builder b1 = + TestMap b1 = TestMap.newBuilder() .putInt32ToInt32Field(1, 2) .putInt32ToInt32Field(3, 4) - .putInt32ToInt32Field(5, 6); - TestMap m1 = b1.build(); + .putInt32ToInt32Field(5, 6) + .build(); + TestMap m1 = b1; TestMap.Builder b2 = TestMap.newBuilder() @@ -499,13 +518,13 @@ .putInt32ToInt32Field(3, 4); TestMap m2 = b2.build(); - assertEquals(m1, m2); - assertEquals(m1.hashCode(), m2.hashCode()); + assertThat(m2).isEqualTo(m1); + assertThat(m2.hashCode()).isEqualTo(m1.hashCode()); // Make sure we did compare map fields. b2.putInt32ToInt32Field(1, 0); m2 = b2.build(); - assertFalse(m1.equals(m2)); + assertThat(m1.equals(m2)).isFalse(); // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed // to be different. @@ -513,10 +532,11 @@ // equals() should return false. b2.removeInt32ToInt32Field(1); m2 = b2.build(); - assertFalse(m1.equals(m2)); - assertFalse(m2.equals(m1)); + assertThat(m1.equals(m2)).isFalse(); + assertThat(m2.equals(m1)).isFalse(); } + @Test public void testUnknownEnumValues() throws Exception { TestMap.Builder builder = TestMap.newBuilder() @@ -525,55 +545,60 @@ .putInt32ToEnumFieldValue(2, 1000); // unknown value. TestMap message = builder.build(); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(0, TestMap.EnumValue.FOO); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.BAR); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(2, TestMap.EnumValue.UNRECOGNIZED); builder.putAllInt32ToEnumFieldValue(newMap(2, 1000)); // unknown value. message = builder.build(); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(2, TestMap.EnumValue.UNRECOGNIZED); // Unknown enum values should be preserved after: // 1. Serialization and parsing. // 2. toBuild(). // 3. mergeFrom(). - message = TestMap.parseFrom(message.toByteString()); - assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); + message = TestMap.parseFrom(message.toByteString(), ExtensionRegistryLite.getEmptyRegistry()); + assertThat(message.getInt32ToEnumFieldValueMap().get(2).intValue()).isEqualTo(1000); builder = message.toBuilder(); - assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); + assertThat(builder.getInt32ToEnumFieldValueMap().get(2).intValue()).isEqualTo(1000); builder = TestMap.newBuilder().mergeFrom(message); - assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); + assertThat(builder.getInt32ToEnumFieldValueMap().get(2).intValue()).isEqualTo(1000); // hashCode()/equals() should take unknown enum values into account. builder.putAllInt32ToEnumFieldValue(newMap(2, 1001)); TestMap message2 = builder.build(); - assertFalse(message.hashCode() == message2.hashCode()); - assertFalse(message.equals(message2)); + assertThat(message.hashCode()).isNotEqualTo(message2.hashCode()); + assertThat(message.equals(message2)).isFalse(); // Unknown values will be converted to UNRECOGNIZED so the resulted enum map // should be the same. - assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertThat(message.getInt32ToEnumFieldMap()).isEqualTo(message2.getInt32ToEnumFieldMap()); } + @Test public void testIterationOrder() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - assertEquals( - Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet())); + assertThat(new ArrayList<>(message.getStringToInt32FieldMap().keySet())) + .containsExactly("1", "2", "3") + .inOrder(); } + @Test public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - 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()); + assertThat(message.getStringToInt32FieldMap()).isEqualTo(message.getStringToInt32FieldMap()); + assertThat(message.getInt32ToBytesFieldMap()).isEqualTo(message.getInt32ToBytesFieldMap()); + assertThat(message.getInt32ToEnumFieldMap()).isEqualTo(message.getInt32ToEnumFieldMap()); + assertThat(message.getInt32ToEnumFieldValueMap()) + .isEqualTo(message.getInt32ToEnumFieldValueMap()); + assertThat(message.getInt32ToMessageFieldMap()).isEqualTo(message.getInt32ToMessageFieldMap()); } + @Test public void testContains() { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); @@ -582,37 +607,38 @@ } private void assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder) { - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(1)); - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(2)); - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(3)); - assertFalse(testMapOrBuilder.containsInt32ToInt32Field(-1)); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToStringField(1)); - assertTrue(testMapOrBuilder.containsInt32ToStringField(2)); - assertTrue(testMapOrBuilder.containsInt32ToStringField(3)); - assertFalse(testMapOrBuilder.containsInt32ToStringField(-1)); + assertThat(testMapOrBuilder.containsInt32ToStringField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(1)); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(2)); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(3)); - assertFalse(testMapOrBuilder.containsInt32ToBytesField(-1)); + assertThat(testMapOrBuilder.containsInt32ToBytesField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(1)); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(2)); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(3)); - assertFalse(testMapOrBuilder.containsInt32ToEnumField(-1)); + assertThat(testMapOrBuilder.containsInt32ToEnumField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(1)); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(2)); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(3)); - assertFalse(testMapOrBuilder.containsInt32ToMessageField(-1)); + assertThat(testMapOrBuilder.containsInt32ToMessageField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsStringToInt32Field("1")); - assertTrue(testMapOrBuilder.containsStringToInt32Field("2")); - assertTrue(testMapOrBuilder.containsStringToInt32Field("3")); - assertFalse(testMapOrBuilder.containsStringToInt32Field("-1")); + assertThat(testMapOrBuilder.containsStringToInt32Field("1")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("2")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("3")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("-1")).isFalse(); } + @Test public void testCount() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -624,23 +650,24 @@ assertMapCounts(3, message); builder = message.toBuilder().putInt32ToInt32Field(4, 44); - assertEquals(4, builder.getInt32ToInt32FieldCount()); - assertEquals(4, builder.build().getInt32ToInt32FieldCount()); + assertThat(builder.getInt32ToInt32FieldCount()).isEqualTo(4); + assertThat(builder.build().getInt32ToInt32FieldCount()).isEqualTo(4); // already present - should be unchanged builder.putInt32ToInt32Field(4, 44); - assertEquals(4, builder.getInt32ToInt32FieldCount()); + assertThat(builder.getInt32ToInt32FieldCount()).isEqualTo(4); } private void assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder) { - assertEquals(expectedCount, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getStringToInt32FieldCount()); + assertThat(testMapOrBuilder.getInt32ToInt32FieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToStringFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToBytesFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToEnumFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToMessageFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getStringToInt32FieldCount()).isEqualTo(expectedCount); } + @Test public void testGetOrDefault() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -650,39 +677,42 @@ } public void doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder) { - assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11)); - assertEquals(-11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11)); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11)).isEqualTo(11); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11)).isEqualTo(-11); - assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11")); - assertNull("-11", testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11")).isEqualTo("11"); + assertWithMessage("-11") + .that(testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null)) + .isNull(); - assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null)) + .isEqualTo(TestUtil.toBytes("11")); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null)).isNull(); - assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null)) + .isEqualTo(TestMap.EnumValue.FOO); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null)).isNull(); - assertEquals( - TestMap.EnumValue.BAR.getNumber(), - testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(2, -1)); - assertEquals(-1, testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(-1000, -1)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(2, -1)) + .isEqualTo(TestMap.EnumValue.BAR.getNumber()); + assertThat(testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(-1000, -1)).isEqualTo(-1); - assertEquals( - MessageValue.newBuilder().setValue(11).build(), - testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null)) + .isEqualTo(MessageValue.newBuilder().setValue(11).build()); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null)).isNull(); - assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11)); - assertEquals(-11, testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11)); + assertThat(testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11)).isEqualTo(11); + assertThat(testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11)).isEqualTo(-11); try { testMapOrBuilder.getStringToInt32FieldOrDefault(null, -11); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } } + @Test public void testGetOrThrow() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -692,109 +722,109 @@ } public void doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder) { - assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); try { testMapOrBuilder.getInt32ToInt32FieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToStringFieldOrThrow(1)).isEqualTo("11"); try { testMapOrBuilder.getInt32ToStringFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); try { testMapOrBuilder.getInt32ToBytesFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); try { testMapOrBuilder.getInt32ToEnumFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals( - TestMap.EnumValue.BAR.getNumber(), testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(2)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(2)) + .isEqualTo(TestMap.EnumValue.BAR.getNumber()); try { testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals( - MessageValue.newBuilder().setValue(11).build(), - testMapOrBuilder.getInt32ToMessageFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrThrow(1)) + .isEqualTo(MessageValue.newBuilder().setValue(11).build()); try { testMapOrBuilder.getInt32ToMessageFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrThrow("1")); + assertThat(testMapOrBuilder.getStringToInt32FieldOrThrow("1")).isEqualTo(11); try { testMapOrBuilder.getStringToInt32FieldOrThrow("-1"); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } try { testMapOrBuilder.getStringToInt32FieldOrThrow(null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } } + @Test public void testPut() { TestMap.Builder builder = TestMap.newBuilder(); builder.putInt32ToInt32Field(1, 11); - assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); + assertThat(builder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); builder.putInt32ToStringField(1, "a"); - assertEquals("a", builder.getInt32ToStringFieldOrThrow(1)); + assertThat(builder.getInt32ToStringFieldOrThrow(1)).isEqualTo("a"); try { builder.putInt32ToStringField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } builder.putInt32ToBytesField(1, TestUtil.toBytes("11")); - assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); + assertThat(builder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); try { builder.putInt32ToBytesField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } builder.putInt32ToEnumField(1, TestMap.EnumValue.FOO); - assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); + assertThat(builder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); try { builder.putInt32ToEnumField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } builder.putStringToInt32Field("a", 1); - assertEquals(1, builder.getStringToInt32FieldOrThrow("a")); + assertThat(builder.getStringToInt32FieldOrThrow("a")).isEqualTo(1); try { builder.putStringToInt32Field(null, -1); } catch (NullPointerException e) { @@ -802,42 +832,43 @@ } } + @Test public void testRemove() { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); - assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); + assertThat(builder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); for (int times = 0; times < 2; times++) { builder.removeInt32ToInt32Field(1); - assertEquals(-1, builder.getInt32ToInt32FieldOrDefault(1, -1)); + assertThat(builder.getInt32ToInt32FieldOrDefault(1, -1)).isEqualTo(-1); } - assertEquals("11", builder.getInt32ToStringFieldOrThrow(1)); + assertThat(builder.getInt32ToStringFieldOrThrow(1)).isEqualTo("11"); for (int times = 0; times < 2; times++) { builder.removeInt32ToStringField(1); - assertNull(builder.getInt32ToStringFieldOrDefault(1, null)); + assertThat(builder.getInt32ToStringFieldOrDefault(1, null)).isNull(); } - assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); + assertThat(builder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); for (int times = 0; times < 2; times++) { builder.removeInt32ToBytesField(1); - assertNull(builder.getInt32ToBytesFieldOrDefault(1, null)); + assertThat(builder.getInt32ToBytesFieldOrDefault(1, null)).isNull(); } - assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); + assertThat(builder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); for (int times = 0; times < 2; times++) { builder.removeInt32ToEnumField(1); - assertNull(builder.getInt32ToEnumFieldOrDefault(1, null)); + assertThat(builder.getInt32ToEnumFieldOrDefault(1, null)).isNull(); } - assertEquals(11, builder.getStringToInt32FieldOrThrow("1")); + assertThat(builder.getStringToInt32FieldOrThrow("1")).isEqualTo(11); for (int times = 0; times < 2; times++) { builder.removeStringToInt32Field("1"); - assertEquals(-1, builder.getStringToInt32FieldOrDefault("1", -1)); + assertThat(builder.getStringToInt32FieldOrDefault("1", -1)).isEqualTo(-1); } try { builder.removeStringToInt32Field(null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } @@ -856,40 +887,41 @@ return map; } + @Test public void testMap_withNulls() { TestMap.Builder builder = TestMap.newBuilder(); try { builder.putStringToInt32Field(null, 3); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { } try { builder.putAllStringToInt32Field(newMap(null, 3, "hi", 4)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { } try { builder.putInt32ToMessageField(3, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { } try { builder.putAllInt32ToMessageField( MapLiteTest.<Integer, MessageValue>newMap(4, null, 5, null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { } try { builder.putAllInt32ToMessageField(null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { } - assertArrayEquals(new byte[0], builder.build().toByteArray()); + assertThat(builder.build().toByteArray()).isEqualTo(new byte[0]); } }
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 c3b1fa3..cc7a121 100644 --- a/java/core/src/test/java/com/google/protobuf/MapTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapTest.java
@@ -30,7 +30,8 @@ package com.google.protobuf; -import static org.junit.Assert.assertArrayEquals; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; @@ -46,14 +47,16 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Unit tests for map fields. */ -public class MapTest extends TestCase { +@RunWith(JUnit4.class) +public class MapTest { private void setMapValuesUsingMutableMap(TestMap.Builder builder) { builder.getMutableInt32ToInt32Field().put(1, 11); @@ -106,6 +109,7 @@ .putStringToInt32Field("3", 33); } + @Test public void testSetMapValues() { TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder(); setMapValuesUsingMutableMap(usingMutableMapBuilder); @@ -117,7 +121,7 @@ TestMap usingAccessors = usingAccessorsBuilder.build(); assertMapValuesSet(usingAccessors); - assertEquals(usingAccessors, usingMutableMap); + assertThat(usingAccessors).isEqualTo(usingMutableMap); } private void copyMapValues(TestMap source, TestMap.Builder destination) { @@ -131,35 +135,35 @@ } private void assertMapValuesSet(TestMap message) { - 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()); + assertThat(message.getInt32ToInt32FieldMap()).hasSize(3); + assertThat(message.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(11); + assertThat(message.getInt32ToInt32FieldMap().get(2).intValue()).isEqualTo(22); + assertThat(message.getInt32ToInt32FieldMap().get(3).intValue()).isEqualTo(33); - assertEquals(3, message.getInt32ToStringFieldMap().size()); - assertEquals("11", message.getInt32ToStringFieldMap().get(1)); - assertEquals("22", message.getInt32ToStringFieldMap().get(2)); - assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertThat(message.getInt32ToStringFieldMap()).hasSize(3); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(1, "11"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(2, "22"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(3, "33"); - 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)); + assertThat(message.getInt32ToBytesFieldMap()).hasSize(3); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(1, TestUtil.toBytes("11")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(2, TestUtil.toBytes("22")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(3, TestUtil.toBytes("33")); - 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)); + assertThat(message.getInt32ToEnumFieldMap()).hasSize(3); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.FOO); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(2, TestMap.EnumValue.BAR); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(3, TestMap.EnumValue.BAZ); - 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()); + assertThat(message.getInt32ToMessageFieldMap()).hasSize(3); + assertThat(message.getInt32ToMessageFieldMap().get(1).getValue()).isEqualTo(11); + assertThat(message.getInt32ToMessageFieldMap().get(2).getValue()).isEqualTo(22); + assertThat(message.getInt32ToMessageFieldMap().get(3).getValue()).isEqualTo(33); - 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()); + assertThat(message.getStringToInt32FieldMap()).hasSize(3); + assertThat(message.getStringToInt32FieldMap().get("1").intValue()).isEqualTo(11); + assertThat(message.getStringToInt32FieldMap().get("2").intValue()).isEqualTo(22); + assertThat(message.getStringToInt32FieldMap().get("3").intValue()).isEqualTo(33); } private void updateMapValuesUsingMutableMap(TestMap.Builder builder) { @@ -212,6 +216,7 @@ .putStringToInt32Field("4", 44); } + @Test public void testUpdateMapValues() { TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder(); setMapValuesUsingMutableMap(usingMutableMapBuilder); @@ -223,7 +228,7 @@ TestMap usingAccessors = usingAccessorsBuilder.build(); assertMapValuesSet(usingAccessors); - assertEquals(usingAccessors, usingMutableMap); + assertThat(usingAccessors).isEqualTo(usingMutableMap); // usingMutableMapBuilder = usingMutableMap.toBuilder(); updateMapValuesUsingMutableMap(usingMutableMapBuilder); @@ -235,56 +240,57 @@ usingAccessors = usingAccessorsBuilder.build(); assertMapValuesUpdated(usingAccessors); - assertEquals(usingAccessors, usingMutableMap); + assertThat(usingAccessors).isEqualTo(usingMutableMap); } private void assertMapValuesUpdated(TestMap message) { - 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()); + assertThat(message.getInt32ToInt32FieldMap()).hasSize(3); + assertThat(message.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(111); + assertThat(message.getInt32ToInt32FieldMap().get(3).intValue()).isEqualTo(33); + assertThat(message.getInt32ToInt32FieldMap().get(4).intValue()).isEqualTo(44); - assertEquals(3, message.getInt32ToStringFieldMap().size()); - assertEquals("111", message.getInt32ToStringFieldMap().get(1)); - assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals("44", message.getInt32ToStringFieldMap().get(4)); + assertThat(message.getInt32ToStringFieldMap()).hasSize(3); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(1, "111"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(3, "33"); + assertThat(message.getInt32ToStringFieldMap()).containsEntry(4, "44"); - 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)); + assertThat(message.getInt32ToBytesFieldMap()).hasSize(3); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(1, TestUtil.toBytes("111")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(3, TestUtil.toBytes("33")); + assertThat(message.getInt32ToBytesFieldMap()).containsEntry(4, TestUtil.toBytes("44")); - 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)); + assertThat(message.getInt32ToEnumFieldMap()).hasSize(3); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.BAR); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(3, TestMap.EnumValue.BAZ); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(4, TestMap.EnumValue.QUX); - 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()); + assertThat(message.getInt32ToMessageFieldMap()).hasSize(3); + assertThat(message.getInt32ToMessageFieldMap().get(1).getValue()).isEqualTo(111); + assertThat(message.getInt32ToMessageFieldMap().get(3).getValue()).isEqualTo(33); + assertThat(message.getInt32ToMessageFieldMap().get(4).getValue()).isEqualTo(44); - 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()); + assertThat(message.getStringToInt32FieldMap()).hasSize(3); + assertThat(message.getStringToInt32FieldMap().get("1").intValue()).isEqualTo(111); + assertThat(message.getStringToInt32FieldMap().get("3").intValue()).isEqualTo(33); + assertThat(message.getStringToInt32FieldMap().get("4").intValue()).isEqualTo(44); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); - assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); + assertThat(testMapOrBuilder.getInt32ToInt32FieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToInt32FieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToStringFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToStringFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToBytesFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToBytesFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToEnumFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToEnumFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getInt32ToMessageFieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getInt32ToMessageFieldCount()).isEqualTo(0); + assertThat(testMapOrBuilder.getStringToInt32FieldMap()).isEmpty(); + assertThat(testMapOrBuilder.getStringToInt32FieldCount()).isEqualTo(0); } + @Test public void testGetMapIsImmutable() { TestMap.Builder builder = TestMap.newBuilder(); assertMapsAreImmutable(builder); @@ -308,122 +314,122 @@ private <K, V> void assertImmutable(Map<K, V> map, K key, V value) { try { map.put(key, value); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } } + @Test public void testMutableMapLifecycle() { TestMap.Builder builder = TestMap.newBuilder(); Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); intMap.put(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + assertThat(builder.build().getInt32ToInt32Field()).isEqualTo(newMap(1, 2)); try { intMap.put(2, 3); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertThat(builder.getInt32ToInt32Field()).isEqualTo(newMap(1, 2)); builder.getMutableInt32ToInt32Field().put(2, 3); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertThat(builder.getInt32ToInt32Field()).isEqualTo(newMap(1, 2, 2, 3)); // Map<Integer, TestMap.EnumValue> enumMap = builder.getMutableInt32ToEnumField(); enumMap.put(1, TestMap.EnumValue.BAR); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); + assertThat(builder.build().getInt32ToEnumField()) + .isEqualTo(newMap(1, TestMap.EnumValue.BAR)); try { enumMap.put(2, TestMap.EnumValue.FOO); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); + assertThat(builder.getInt32ToEnumField()).isEqualTo(newMap(1, TestMap.EnumValue.BAR)); builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.FOO); - assertEquals( - newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), - builder.getInt32ToEnumField()); + assertThat(builder.getInt32ToEnumField()).isEqualTo( + newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO)); // Map<Integer, String> stringMap = builder.getMutableInt32ToStringField(); stringMap.put(1, "1"); - assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); + assertThat(builder.build().getInt32ToStringField()).isEqualTo(newMap(1, "1")); try { stringMap.put(2, "2"); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); + assertThat(builder.getInt32ToStringField()).isEqualTo(newMap(1, "1")); builder.putInt32ToStringField(2, "2"); - assertEquals( - newMap(1, "1", 2, "2"), - builder.getInt32ToStringField()); + assertThat(builder.getInt32ToStringField()).isEqualTo(newMap(1, "1", 2, "2")); // Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField(); messageMap.put(1, TestMap.MessageValue.getDefaultInstance()); - assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.build().getInt32ToMessageField()); + assertThat( builder.build().getInt32ToMessageField()) + .isEqualTo(newMap(1, TestMap.MessageValue.getDefaultInstance())); try { messageMap.put(2, TestMap.MessageValue.getDefaultInstance()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageField()); + assertThat(builder.getInt32ToMessageField()) + .isEqualTo(newMap(1, TestMap.MessageValue.getDefaultInstance())); builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance()); - assertEquals( + assertThat(builder.getInt32ToMessageField()).isEqualTo( newMap(1, TestMap.MessageValue.getDefaultInstance(), - 2, TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageField()); + 2, TestMap.MessageValue.getDefaultInstance())); } // + @Test public void testMutableMapLifecycle_collections() { TestMap.Builder builder = TestMap.newBuilder(); Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field(); intMap.put(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + assertThat(builder.build().getInt32ToInt32Field()).isEqualTo(newMap(1, 2)); try { intMap.remove(2); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { intMap.entrySet().remove(new Object()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { intMap.entrySet().iterator().remove(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { intMap.keySet().remove(new Object()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { intMap.values().remove(new Object()); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { intMap.values().iterator().remove(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(newMap(1, 2), intMap); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); + assertThat(intMap).isEqualTo(newMap(1, 2)); + assertThat(builder.getInt32ToInt32Field()).isEqualTo(newMap(1, 2)); + assertThat(builder.build().getInt32ToInt32Field()).isEqualTo(newMap(1, 2)); } + @Test public void testGettersAndSetters() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); @@ -446,6 +452,7 @@ assertMapValuesCleared(message); } + @Test public void testPutAll() throws Exception { TestMap.Builder sourceBuilder = TestMap.newBuilder(); setMapValuesUsingAccessors(sourceBuilder); @@ -457,6 +464,7 @@ assertMapValuesSet(destination.build()); } + @Test public void testPutAllForUnknownEnumValues() throws Exception { TestMap source = TestMap.newBuilder() @@ -472,12 +480,13 @@ .putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap()) .build(); - 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()); + assertThat(destination.getInt32ToEnumFieldValueMap().get(0).intValue()).isEqualTo(0); + assertThat(destination.getInt32ToEnumFieldValueMap().get(1).intValue()).isEqualTo(1); + assertThat(destination.getInt32ToEnumFieldValueMap().get(2).intValue()).isEqualTo(1000); + assertThat(destination.getInt32ToEnumFieldCount()).isEqualTo(3); } + @Test public void testPutForUnknownEnumValues() throws Exception { TestMap message = TestMap.newBuilder() @@ -485,70 +494,72 @@ .putInt32ToEnumFieldValue(1, 1) .putInt32ToEnumFieldValue(2, 1000) // unknown value. .build(); - assertEquals(0, message.getInt32ToEnumFieldValueOrThrow(0)); - assertEquals(1, message.getInt32ToEnumFieldValueOrThrow(1)); - assertEquals(1000, message.getInt32ToEnumFieldValueOrThrow(2)); - assertEquals(3, message.getInt32ToEnumFieldCount()); + assertThat(message.getInt32ToEnumFieldValueOrThrow(0)).isEqualTo(0); + assertThat(message.getInt32ToEnumFieldValueOrThrow(1)).isEqualTo(1); + assertThat(message.getInt32ToEnumFieldValueOrThrow(2)).isEqualTo(1000); + assertThat(message.getInt32ToEnumFieldCount()).isEqualTo(3); } + @Test public void testPutChecksNullKeysAndValues() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); try { builder.putInt32ToStringField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToBytesField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToEnumField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putInt32ToMessageField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } try { builder.putStringToInt32Field(null, 1); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } } + @Test public void testSerializeAndParse() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); TestMap message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesSet(message); builder = message.toBuilder(); updateMapValuesUsingAccessors(builder); message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesUpdated(message); builder = message.toBuilder(); builder.clear(); message = builder.build(); - assertEquals(message.getSerializedSize(), message.toByteString().size()); + assertThat(message.toByteString().size()).isEqualTo(message.getSerializedSize()); message = TestMap.parser().parseFrom(message.toByteString()); assertMapValuesCleared(message); } @@ -561,39 +572,41 @@ return TestMap.parser().parseFrom(ByteString.copyFrom(byteArrayOutputStream.toByteArray())); } + @Test public void testParseError() throws Exception { ByteString bytes = TestUtil.toBytes("SOME BYTES"); String stringKey = "a string key"; TestMap map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToInt32Field(5, bytes).build()); - assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1)); + assertThat(map.getInt32ToInt32FieldOrDefault(5, -1)).isEqualTo(0); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToStringField(stringKey, 5).build()); - assertEquals("", map.getInt32ToStringFieldOrDefault(0, null)); + assertThat(map.getInt32ToStringFieldOrDefault(0, null)).isEmpty(); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToBytesField(stringKey, 5).build()); - assertEquals(map.getInt32ToBytesFieldOrDefault(0, null), ByteString.EMPTY); + assertThat(ByteString.EMPTY).isEqualTo(map.getInt32ToBytesFieldOrDefault(0, null)); map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToEnumField(stringKey, bytes).build()); - assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null)); + assertThat(map.getInt32ToEnumFieldOrDefault(0, null)).isEqualTo(TestMap.EnumValue.FOO); try { tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToMessageField(stringKey, bytes).build()); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { - assertTrue(expected.getUnfinishedMessage() instanceof TestMap); + assertThat(expected.getUnfinishedMessage()).isInstanceOf(TestMap.class); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); + assertThat(map.getInt32ToMessageFieldMap()).isEmpty(); } map = tryParseTestMap( BizarroTestMap.newBuilder().putStringToInt32Field(stringKey, bytes).build()); - assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1)); + assertThat(map.getStringToInt32FieldOrDefault(stringKey, -1)).isEqualTo(0); } + @Test public void testMergeFrom() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); @@ -604,6 +617,7 @@ assertMapValuesSet(other.build()); } + @Test public void testEqualsAndHashCode() throws Exception { // Test that generated equals() and hashCode() will disregard the order // of map entries when comparing/hashing map fields. @@ -624,13 +638,13 @@ .putInt32ToInt32Field(3, 4); TestMap m2 = b2.build(); - assertEquals(m1, m2); - assertEquals(m1.hashCode(), m2.hashCode()); + assertThat(m2).isEqualTo(m1); + assertThat(m2.hashCode()).isEqualTo(m1.hashCode()); // Make sure we did compare map fields. b2.putInt32ToInt32Field(1, 0); m2 = b2.build(); - assertFalse(m1.equals(m2)); + assertThat(m1.equals(m2)).isFalse(); // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed // to be different. @@ -638,22 +652,25 @@ // equals() should return false. b2.removeInt32ToInt32Field(1); m2 = b2.build(); - assertFalse(m1.equals(m2)); - assertFalse(m2.equals(m1)); + assertThat(m1.equals(m2)).isFalse(); + assertThat(m2.equals(m1)).isFalse(); } + @Test public void testNestedBuilderOnChangeEventPropagation() { TestOnChangeEventPropagation.Builder parent = TestOnChangeEventPropagation.newBuilder(); parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 2); TestOnChangeEventPropagation message = parent.build(); - assertEquals(2, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); + assertThat(message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()) + .isEqualTo(2); // 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().getInt32ToInt32FieldMap().get(1).intValue()); + assertThat(message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()) + .isEqualTo(3); // Make another change using mergeFrom() TestMap other = TestMap.newBuilder().putInt32ToInt32Field(1, 4).build(); @@ -661,16 +678,18 @@ // Should be able to observe the change. message = parent.build(); - assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); + assertThat(message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()) + .isEqualTo(4); // 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().getInt32ToInt32FieldMap().size()); + assertThat(message.getOptionalMessage().getInt32ToInt32FieldMap()).isEmpty(); } + @Test public void testNestedBuilderOnChangeEventPropagationReflection() { FieldDescriptor intMapField = f("int32_to_int32_field"); // Create an outer message builder with nested builder. @@ -685,7 +704,7 @@ // Should be able to observe the change. TestOnChangeEventPropagation message = parentBuilder.build(); - assertEquals(1, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); + assertThat(message.getOptionalMessage().getInt32ToInt32FieldMap()).hasSize(1); // Change the entry value. entryBuilder.putInt32ToInt32Field(1, 4); @@ -694,7 +713,8 @@ // Should be able to observe the change. message = parentBuilder.build(); - assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); + assertThat(message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()) + .isEqualTo(4); // Clear the nested builder. testMapBuilder = parentBuilder.getOptionalMessageBuilder(); @@ -702,7 +722,7 @@ // Should be able to observe the change. message = parentBuilder.build(); - assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); + assertThat(message.getOptionalMessage().getInt32ToInt32FieldMap()).isEmpty(); } // The following methods are used to test reflection API. @@ -729,16 +749,16 @@ Message mapEntry = (Message) entry; Object key = getFieldValue(mapEntry, "key"); Object value = getFieldValue(mapEntry, "value"); - assertTrue(values.containsKey(key)); - assertEquals(value, values.get(key)); + assertThat(values.containsKey(key)).isTrue(); + assertThat(values.get(key)).isEqualTo(value); } - assertEquals(values.size(), message.getRepeatedFieldCount(field)); + assertThat(message.getRepeatedFieldCount(field)).isEqualTo(values.size()); for (int i = 0; i < message.getRepeatedFieldCount(field); i++) { Message mapEntry = (Message) message.getRepeatedField(field, i); Object key = getFieldValue(mapEntry, "key"); Object value = getFieldValue(mapEntry, "value"); - assertTrue(values.containsKey(key)); - assertEquals(value, values.get(key)); + assertThat(values.containsKey(key)).isTrue(); + assertThat(values.get(key)).isEqualTo(value); } } @@ -768,6 +788,7 @@ return map; } + @Test public void testReflectionApi() throws Exception { // In reflection API, map fields are just repeated message fields. TestMap.Builder builder = @@ -791,8 +812,8 @@ builder.clearField(f("int32_to_int32_field")); builder.clearField(f("int32_to_message_field")); message = builder.build(); - assertEquals(0, message.getInt32ToInt32FieldMap().size()); - assertEquals(0, message.getInt32ToMessageFieldMap().size()); + assertThat(message.getInt32ToInt32FieldMap()).isEmpty(); + assertThat(message.getInt32ToMessageFieldMap()).isEmpty(); // Test setField() setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44)); @@ -803,10 +824,10 @@ 111, MessageValue.newBuilder().setValue(222).build(), 333, MessageValue.newBuilder().setValue(444).build())); message = builder.build(); - 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()); + assertThat(message.getInt32ToInt32FieldMap().get(11).intValue()).isEqualTo(22); + assertThat(message.getInt32ToInt32FieldMap().get(33).intValue()).isEqualTo(44); + assertThat(message.getInt32ToMessageFieldMap().get(111).getValue()).isEqualTo(222); + assertThat(message.getInt32ToMessageFieldMap().get(333).getValue()).isEqualTo(444); // Test addRepeatedField builder.addRepeatedField( @@ -819,8 +840,8 @@ 555, MessageValue.newBuilder().setValue(666).build())); message = builder.build(); - assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue()); - assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue()); + assertThat(message.getInt32ToInt32FieldMap().get(55).intValue()).isEqualTo(66); + assertThat(message.getInt32ToMessageFieldMap().get(555).getValue()).isEqualTo(666); // Test addRepeatedField (overriding existing values) builder.addRepeatedField( @@ -833,8 +854,8 @@ 555, MessageValue.newBuilder().setValue(555).build())); message = builder.build(); - assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); - assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue()); + assertThat(message.getInt32ToInt32FieldMap().get(55).intValue()).isEqualTo(55); + assertThat(message.getInt32ToMessageFieldMap().get(555).getValue()).isEqualTo(555); // Test setRepeatedField for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) { @@ -848,12 +869,13 @@ builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build()); } message = builder.build(); - assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue()); - assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue()); - assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertThat(message.getInt32ToInt32FieldMap().get(22).intValue()).isEqualTo(11); + assertThat(message.getInt32ToInt32FieldMap().get(44).intValue()).isEqualTo(33); + assertThat(message.getInt32ToInt32FieldMap().get(55).intValue()).isEqualTo(55); } // See additional coverage in TextFormatTest.java. + @Test public void testTextFormat() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); @@ -868,6 +890,7 @@ assertMapValuesSet(message); } + @Test public void testDynamicMessage() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); @@ -875,14 +898,18 @@ Message dynamicDefaultInstance = DynamicMessage.getDefaultInstance(TestMap.getDescriptor()); Message dynamicMessage = - dynamicDefaultInstance.newBuilderForType().mergeFrom(message.toByteString()).build(); + dynamicDefaultInstance + .newBuilderForType() + .mergeFrom(message.toByteString(), ExtensionRegistry.getEmptyRegistry()) + .build(); - assertEquals(message, dynamicMessage); - assertEquals(message.hashCode(), dynamicMessage.hashCode()); + assertThat(dynamicMessage).isEqualTo(message); + assertThat(dynamicMessage.hashCode()).isEqualTo(message.hashCode()); } // Check that DynamicMessage handles map field serialization the same way as generated code // regarding unset key and value field in a map entry. + @Test public void testDynamicMessageUnsetKeyAndValue() throws Exception { FieldDescriptor field = f("int32_to_int32_field"); @@ -893,11 +920,12 @@ Message message = builder.build(); ByteString bytes = message.toByteString(); // Parse it back to the same generated type. - Message generatedMessage = TestMap.parseFrom(bytes); + Message generatedMessage = TestMap.parseFrom(bytes, ExtensionRegistry.getEmptyRegistry()); // Assert the serialized bytes are equivalent. - assertEquals(generatedMessage.toByteString(), bytes); + assertThat(bytes).isEqualTo(generatedMessage.toByteString()); } + @Test public void testReflectionEqualsAndHashCode() throws Exception { // Test that generated equals() and hashCode() will disregard the order // of map entries when comparing/hashing map fields. @@ -918,17 +946,18 @@ b2.addRepeatedField(field, newMapEntry(b2, "int32_to_int32_field", 3, 4)); Message m2 = b2.build(); - assertEquals(m1, m2); - assertEquals(m1.hashCode(), m2.hashCode()); + assertThat(m2).isEqualTo(m1); + assertThat(m2.hashCode()).isEqualTo(m1.hashCode()); // Make sure we did compare map fields. b2.setRepeatedField(field, 0, newMapEntry(b1, "int32_to_int32_field", 0, 0)); m2 = b2.build(); - assertFalse(m1.equals(m2)); + assertThat(m1).isNotEqualTo(m2); // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed // to be different. } + @Test public void testUnknownEnumValues() throws Exception { TestMap.Builder builder = TestMap.newBuilder() @@ -939,32 +968,33 @@ 2, 1000)); // unknown value. TestMap message = builder.build(); - 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()); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(0, TestMap.EnumValue.FOO); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(1, TestMap.EnumValue.BAR); + assertThat(message.getInt32ToEnumFieldMap()).containsEntry(2, TestMap.EnumValue.UNRECOGNIZED); + assertThat(message.getInt32ToEnumFieldValueMap().get(2).intValue()).isEqualTo(1000); // Unknown enum values should be preserved after: // 1. Serialization and parsing. // 2. toBuild(). // 3. mergeFrom(). - message = TestMap.parseFrom(message.toByteString()); - assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); + message = TestMap.parseFrom(message.toByteString(), ExtensionRegistry.getEmptyRegistry()); + assertThat(message.getInt32ToEnumFieldValueMap().get(2).intValue()).isEqualTo(1000); builder = message.toBuilder(); - assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); + assertThat(builder.getInt32ToEnumFieldValueMap().get(2).intValue()).isEqualTo(1000); builder = TestMap.newBuilder().mergeFrom(message); - assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); + assertThat(builder.getInt32ToEnumFieldValueMap().get(2).intValue()).isEqualTo(1000); // hashCode()/equals() should take unknown enum values into account. builder.putAllInt32ToEnumFieldValue(newMap(2, 1001)); TestMap message2 = builder.build(); - assertFalse(message.hashCode() == message2.hashCode()); - assertFalse(message.equals(message2)); + assertThat(message.hashCode()).isNotEqualTo(message2.hashCode()); + assertThat(message.equals(message2)).isFalse(); // Unknown values will be converted to UNRECOGNIZED so the resulted enum map // should be the same. - assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertThat(message.getInt32ToEnumFieldMap()).isEqualTo(message2.getInt32ToEnumFieldMap()); } + @Test public void testUnknownEnumValuesInReflectionApi() throws Exception { Descriptor descriptor = TestMap.getDescriptor(); EnumDescriptor enumDescriptor = TestMap.EnumValue.getDescriptor(); @@ -983,7 +1013,7 @@ Message mapEntry = (Message) builder.getRepeatedField(field, i); int key = ((Integer) getFieldValue(mapEntry, "key")).intValue(); int value = ((EnumValueDescriptor) getFieldValue(mapEntry, "value")).getNumber(); - assertEquals(data.get(key).intValue(), value); + assertThat(value).isEqualTo(data.get(key).intValue()); Message.Builder mapEntryBuilder = mapEntry.toBuilder(); // Increase the value by 1. setFieldValue( @@ -994,30 +1024,35 @@ // Verify that enum values have been successfully updated. TestMap message = builder.build(); for (Map.Entry<Integer, Integer> entry : message.getInt32ToEnumFieldValueMap().entrySet()) { - assertEquals(data.get(entry.getKey()) + 1, entry.getValue().intValue()); + assertThat(entry.getValue().intValue()).isEqualTo(data.get(entry.getKey()) + 1); } } + @Test public void testIterationOrder() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); TestMap message = builder.build(); - assertEquals( - Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet())); + assertThat(new ArrayList<>(message.getStringToInt32FieldMap().keySet())) + .containsExactly("1", "2", "3") + .inOrder(); } + @Test public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); TestMap message = builder.build(); - 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()); + assertThat(message.getStringToInt32FieldMap()).isEqualTo(message.getStringToInt32FieldMap()); + assertThat(message.getInt32ToBytesFieldMap()).isEqualTo(message.getInt32ToBytesFieldMap()); + assertThat(message.getInt32ToEnumFieldMap()).isEqualTo(message.getInt32ToEnumFieldMap()); + assertThat(message.getInt32ToEnumFieldValueMap()) + .isEqualTo(message.getInt32ToEnumFieldValueMap()); + assertThat(message.getInt32ToMessageFieldMap()).isEqualTo(message.getInt32ToMessageFieldMap()); } + @Test public void testContains() { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); @@ -1026,37 +1061,38 @@ } private void assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder) { - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(1)); - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(2)); - assertTrue(testMapOrBuilder.containsInt32ToInt32Field(3)); - assertFalse(testMapOrBuilder.containsInt32ToInt32Field(-1)); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToInt32Field(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToStringField(1)); - assertTrue(testMapOrBuilder.containsInt32ToStringField(2)); - assertTrue(testMapOrBuilder.containsInt32ToStringField(3)); - assertFalse(testMapOrBuilder.containsInt32ToStringField(-1)); + assertThat(testMapOrBuilder.containsInt32ToStringField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToStringField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(1)); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(2)); - assertTrue(testMapOrBuilder.containsInt32ToBytesField(3)); - assertFalse(testMapOrBuilder.containsInt32ToBytesField(-1)); + assertThat(testMapOrBuilder.containsInt32ToBytesField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToBytesField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(1)); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(2)); - assertTrue(testMapOrBuilder.containsInt32ToEnumField(3)); - assertFalse(testMapOrBuilder.containsInt32ToEnumField(-1)); + assertThat(testMapOrBuilder.containsInt32ToEnumField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToEnumField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(1)); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(2)); - assertTrue(testMapOrBuilder.containsInt32ToMessageField(3)); - assertFalse(testMapOrBuilder.containsInt32ToMessageField(-1)); + assertThat(testMapOrBuilder.containsInt32ToMessageField(1)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(2)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(3)).isTrue(); + assertThat(testMapOrBuilder.containsInt32ToMessageField(-1)).isFalse(); - assertTrue(testMapOrBuilder.containsStringToInt32Field("1")); - assertTrue(testMapOrBuilder.containsStringToInt32Field("2")); - assertTrue(testMapOrBuilder.containsStringToInt32Field("3")); - assertFalse(testMapOrBuilder.containsStringToInt32Field("-1")); + assertThat(testMapOrBuilder.containsStringToInt32Field("1")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("2")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("3")).isTrue(); + assertThat(testMapOrBuilder.containsStringToInt32Field("-1")).isFalse(); } + @Test public void testCount() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -1068,23 +1104,24 @@ assertMapCounts(3, message); builder = message.toBuilder().putInt32ToInt32Field(4, 44); - assertEquals(4, builder.getInt32ToInt32FieldCount()); - assertEquals(4, builder.build().getInt32ToInt32FieldCount()); + assertThat(builder.getInt32ToInt32FieldCount()).isEqualTo(4); + assertThat(builder.build().getInt32ToInt32FieldCount()).isEqualTo(4); // already present - should be unchanged builder.putInt32ToInt32Field(4, 44); - assertEquals(4, builder.getInt32ToInt32FieldCount()); + assertThat(builder.getInt32ToInt32FieldCount()).isEqualTo(4); } private void assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder) { - assertEquals(expectedCount, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(expectedCount, testMapOrBuilder.getStringToInt32FieldCount()); + assertThat(testMapOrBuilder.getInt32ToInt32FieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToStringFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToBytesFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToEnumFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getInt32ToMessageFieldCount()).isEqualTo(expectedCount); + assertThat(testMapOrBuilder.getStringToInt32FieldCount()).isEqualTo(expectedCount); } + @Test public void testGetOrDefault() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -1094,39 +1131,42 @@ } public void doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder) { - assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11)); - assertEquals(-11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11)); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11)).isEqualTo(11); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11)).isEqualTo(-11); - assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11")); - assertNull("-11", testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11")).isEqualTo("11"); + assertWithMessage("-11") + .that(testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null)) + .isNull(); - assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null)) + .isEqualTo(TestUtil.toBytes("11")); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null)).isNull(); - assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null)) + .isEqualTo(TestMap.EnumValue.FOO); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null)).isNull(); - assertEquals( - TestMap.EnumValue.BAR.getNumber(), - testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(2, -1)); - assertEquals(-1, testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(-1000, -1)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(2, -1)) + .isEqualTo(TestMap.EnumValue.BAR.getNumber()); + assertThat(testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(-1000, -1)).isEqualTo(-1); - assertEquals( - MessageValue.newBuilder().setValue(11).build(), - testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null)); - assertNull(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null)); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null)) + .isEqualTo(MessageValue.newBuilder().setValue(11).build()); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null)).isNull(); - assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11)); - assertEquals(-11, testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11)); + assertThat(testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11)).isEqualTo(11); + assertThat(testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11)).isEqualTo(-11); try { testMapOrBuilder.getStringToInt32FieldOrDefault(null, -11); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } } + @Test public void testGetOrThrow() { TestMap.Builder builder = TestMap.newBuilder(); assertMapCounts(0, builder); @@ -1136,115 +1176,116 @@ } public void doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder) { - assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); try { testMapOrBuilder.getInt32ToInt32FieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToStringFieldOrThrow(1)).isEqualTo("11"); try { testMapOrBuilder.getInt32ToStringFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); try { testMapOrBuilder.getInt32ToBytesFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); try { testMapOrBuilder.getInt32ToEnumFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals( - TestMap.EnumValue.BAR.getNumber(), testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(2)); + assertThat(testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(2)) + .isEqualTo(TestMap.EnumValue.BAR.getNumber()); try { testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals( - MessageValue.newBuilder().setValue(11).build(), - testMapOrBuilder.getInt32ToMessageFieldOrThrow(1)); + assertThat(testMapOrBuilder.getInt32ToMessageFieldOrThrow(1)) + .isEqualTo(MessageValue.newBuilder().setValue(11).build()); try { testMapOrBuilder.getInt32ToMessageFieldOrThrow(-1); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } - assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrThrow("1")); + assertThat(testMapOrBuilder.getStringToInt32FieldOrThrow("1")).isEqualTo(11); try { testMapOrBuilder.getStringToInt32FieldOrThrow("-1"); - fail(); + assertWithMessage("expected exception").fail(); } catch (IllegalArgumentException e) { // expected } try { testMapOrBuilder.getStringToInt32FieldOrThrow(null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } } + @Test public void testPut() { TestMap.Builder builder = TestMap.newBuilder(); builder.putInt32ToInt32Field(1, 11); - assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); + assertThat(builder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); builder.putInt32ToStringField(1, "a"); - assertEquals("a", builder.getInt32ToStringFieldOrThrow(1)); + assertThat(builder.getInt32ToStringFieldOrThrow(1)).isEqualTo("a"); try { builder.putInt32ToStringField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } builder.putInt32ToBytesField(1, TestUtil.toBytes("11")); - assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); + assertThat(builder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); try { builder.putInt32ToBytesField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } builder.putInt32ToEnumField(1, TestMap.EnumValue.FOO); - assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); + assertThat(builder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); try { builder.putInt32ToEnumField(1, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } builder.putInt32ToEnumFieldValue(1, TestMap.EnumValue.BAR.getNumber()); - assertEquals(TestMap.EnumValue.BAR.getNumber(), builder.getInt32ToEnumFieldValueOrThrow(1)); + assertThat(builder.getInt32ToEnumFieldValueOrThrow(1)) + .isEqualTo(TestMap.EnumValue.BAR.getNumber()); builder.putInt32ToEnumFieldValue(1, -1); - assertEquals(-1, builder.getInt32ToEnumFieldValueOrThrow(1)); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, builder.getInt32ToEnumFieldOrThrow(1)); + assertThat(builder.getInt32ToEnumFieldValueOrThrow(1)).isEqualTo(-1); + assertThat(builder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.UNRECOGNIZED); builder.putStringToInt32Field("a", 1); - assertEquals(1, builder.getStringToInt32FieldOrThrow("a")); + assertThat(builder.getStringToInt32FieldOrThrow("a")).isEqualTo(1); try { builder.putStringToInt32Field(null, -1); } catch (NullPointerException e) { @@ -1252,53 +1293,56 @@ } } + @Test public void testRemove() { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); - assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1)); + assertThat(builder.getInt32ToInt32FieldOrThrow(1)).isEqualTo(11); for (int times = 0; times < 2; times++) { builder.removeInt32ToInt32Field(1); - assertEquals(-1, builder.getInt32ToInt32FieldOrDefault(1, -1)); + assertThat(builder.getInt32ToInt32FieldOrDefault(1, -1)).isEqualTo(-1); } - assertEquals("11", builder.getInt32ToStringFieldOrThrow(1)); + assertThat(builder.getInt32ToStringFieldOrThrow(1)).isEqualTo("11"); for (int times = 0; times < 2; times++) { builder.removeInt32ToStringField(1); - assertNull(builder.getInt32ToStringFieldOrDefault(1, null)); + assertThat(builder.getInt32ToStringFieldOrDefault(1, null)).isNull(); } - assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1)); + assertThat(builder.getInt32ToBytesFieldOrThrow(1)).isEqualTo(TestUtil.toBytes("11")); for (int times = 0; times < 2; times++) { builder.removeInt32ToBytesField(1); - assertNull(builder.getInt32ToBytesFieldOrDefault(1, null)); + assertThat(builder.getInt32ToBytesFieldOrDefault(1, null)).isNull(); } - assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1)); + assertThat(builder.getInt32ToEnumFieldOrThrow(1)).isEqualTo(TestMap.EnumValue.FOO); for (int times = 0; times < 2; times++) { builder.removeInt32ToEnumField(1); - assertNull(builder.getInt32ToEnumFieldOrDefault(1, null)); + assertThat(builder.getInt32ToEnumFieldOrDefault(1, null)).isNull(); } - assertEquals(11, builder.getStringToInt32FieldOrThrow("1")); + assertThat(builder.getStringToInt32FieldOrThrow("1")).isEqualTo(11); for (int times = 0; times < 2; times++) { builder.removeStringToInt32Field("1"); - assertEquals(-1, builder.getStringToInt32FieldOrDefault("1", -1)); + assertThat(builder.getStringToInt32FieldOrDefault("1", -1)).isEqualTo(-1); } try { builder.removeStringToInt32Field(null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected } } + @Test public void testReservedWordsFieldNames() { - ReservedAsMapField unused1 = ReservedAsMapField.newBuilder().build(); - ReservedAsMapFieldWithEnumValue unused2 = ReservedAsMapFieldWithEnumValue.newBuilder().build(); + ReservedAsMapField unused1 = ReservedAsMapField.getDefaultInstance(); + ReservedAsMapFieldWithEnumValue unused2 = ReservedAsMapFieldWithEnumValue.getDefaultInstance(); } - public void testDeterministicSerialziation() throws Exception { + @Test + public void testDeterministicSerialization() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); // int32->int32 builder.putInt32ToInt32Field(5, 1); @@ -1363,16 +1407,17 @@ int64Keys.add(readMapLongKey(input)); break; default: - fail("Unexpected fields."); + assertWithMessage("Unexpected fields.").fail(); } input.popLimit(oldLimit); } - assertEquals(Arrays.asList(-2, 0, 1, 4, 5), int32Keys); - assertEquals(Arrays.asList(-2, 0, 1, 4, 5), uint32Keys); - assertEquals(Arrays.asList(-2L, 0L, 1L, 4L, 5L), int64Keys); - assertEquals(Arrays.asList("", "bar", "baz", "foo", "hello", "world"), stringKeys); + assertThat(int32Keys).containsExactly(-2, 0, 1, 4, 5).inOrder(); + assertThat(uint32Keys).containsExactly(-2, 0, 1, 4, 5).inOrder(); + assertThat(int64Keys).containsExactly(-2L, 0L, 1L, 4L, 5L).inOrder(); + assertThat(stringKeys).containsExactly("", "bar", "baz", "foo", "hello", "world").inOrder(); } + @Test public void testInitFromPartialDynamicMessage() { FieldDescriptor fieldDescriptor = TestMap.getDescriptor().findFieldByNumber(TestMap.INT32_TO_MESSAGE_FIELD_FIELD_NUMBER); @@ -1389,11 +1434,11 @@ .build()) .build(); TestMap message = TestMap.newBuilder().mergeFrom(dynamicMessage).build(); - assertEquals( - TestMap.MessageValue.newBuilder().setValue(10).build(), - message.getInt32ToMessageFieldMap().get(10)); + assertThat(message.getInt32ToMessageFieldMap()) + .containsEntry(10, TestMap.MessageValue.newBuilder().setValue(10).build()); } + @Test public void testInitFromFullyDynamicMessage() { FieldDescriptor fieldDescriptor = TestMap.getDescriptor().findFieldByNumber(TestMap.INT32_TO_MESSAGE_FIELD_FIELD_NUMBER); @@ -1415,38 +1460,37 @@ .build()) .build(); TestMap message = TestMap.newBuilder().mergeFrom(dynamicMessage).build(); - assertEquals( - TestMap.MessageValue.newBuilder().setValue(10).build(), - message.getInt32ToMessageFieldMap().get(10)); + assertThat(message.getInt32ToMessageFieldMap()) + .containsEntry(10, TestMap.MessageValue.newBuilder().setValue(10).build()); } private int readMapIntegerKey(CodedInputStream input) throws IOException { int tag = input.readTag(); - assertEquals(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT), tag); + assertThat(tag).isEqualTo(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT)); int ret = input.readInt32(); // skip the value field. input.skipField(input.readTag()); - assertTrue(input.isAtEnd()); + assertThat(input.isAtEnd()).isTrue(); return ret; } private long readMapLongKey(CodedInputStream input) throws IOException { int tag = input.readTag(); - assertEquals(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT), tag); + assertThat(tag).isEqualTo(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT)); long ret = input.readInt64(); // skip the value field. input.skipField(input.readTag()); - assertTrue(input.isAtEnd()); + assertThat(input.isAtEnd()).isTrue(); return ret; } private String readMapStringKey(CodedInputStream input) throws IOException { int tag = input.readTag(); - assertEquals(WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED), tag); + assertThat(tag).isEqualTo(WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED)); String ret = input.readString(); // skip the value field. input.skipField(input.readTag()); - assertTrue(input.isAtEnd()); + assertThat(input.isAtEnd()).isTrue(); return ret; } @@ -1471,39 +1515,40 @@ return map; } + @Test public void testMap_withNulls() { TestMap.Builder builder = TestMap.newBuilder(); try { builder.putStringToInt32Field(null, 3); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { } try { builder.putAllStringToInt32Field(newMap(null, 3, "hi", 4)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { } try { builder.putInt32ToMessageField(3, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { } try { builder.putAllInt32ToMessageField(MapTest.<Integer, MessageValue>newMap(4, null, 5, null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { } try { builder.putAllInt32ToMessageField(null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { } - assertArrayEquals(new byte[0], builder.build().toByteArray()); + assertThat(builder.build().toByteArray()).isEqualTo(new byte[0]); } }
diff --git a/java/core/src/test/java/com/google/protobuf/MessageTest.java b/java/core/src/test/java/com/google/protobuf/MessageTest.java index 760511b..9c34161 100644 --- a/java/core/src/test/java/com/google/protobuf/MessageTest.java +++ b/java/core/src/test/java/com/google/protobuf/MessageTest.java
@@ -30,20 +30,22 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import protobuf_unittest.UnittestProto.ForeignMessage; import protobuf_unittest.UnittestProto.TestAllExtensions; import protobuf_unittest.UnittestProto.TestAllTypes; import protobuf_unittest.UnittestProto.TestRequired; import protobuf_unittest.UnittestProto.TestRequiredForeign; import java.util.List; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Misc. unit tests for message operations that apply to both generated and dynamic messages. - * - * @author kenton@google.com Kenton Varda - */ -public class MessageTest extends TestCase { +/** Misc. unit tests for message operations that apply to both generated and dynamic messages. */ +@RunWith(JUnit4.class) +public class MessageTest { // ================================================================= // Message-merging tests. @@ -74,41 +76,45 @@ + "repeated_string: \"qux\"\n" + "repeated_string: \"bar\"\n"; + @Test public void testParsingWithNullExtensionRegistry() throws Exception { try { TestAllTypes.parseFrom(new byte[] {}, null); - fail(); + assertWithMessage("Expected exception").fail(); } catch (NullPointerException expected) { } } + @Test public void testMergeFrom() throws Exception { TestAllTypes result = TestAllTypes.newBuilder(MERGE_DEST).mergeFrom(MERGE_SOURCE).build(); - assertEquals(MERGE_RESULT_TEXT, result.toString()); + assertThat(result.toString()).isEqualTo(MERGE_RESULT_TEXT); } /** * Test merging a DynamicMessage into a GeneratedMessage. As long as they have the same * descriptor, this should work, but it is an entirely different code path. */ + @Test public void testMergeFromDynamic() throws Exception { TestAllTypes result = TestAllTypes.newBuilder(MERGE_DEST) .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build()) .build(); - assertEquals(MERGE_RESULT_TEXT, result.toString()); + assertThat(result.toString()).isEqualTo(MERGE_RESULT_TEXT); } /** Test merging two DynamicMessages. */ + @Test public void testDynamicMergeFrom() throws Exception { DynamicMessage result = DynamicMessage.newBuilder(MERGE_DEST) .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build()) .build(); - assertEquals(MERGE_RESULT_TEXT, result.toString()); + assertThat(result.toString()).isEqualTo(MERGE_RESULT_TEXT); } // ================================================================= @@ -118,103 +124,111 @@ private static final TestRequired TEST_REQUIRED_INITIALIZED = TestRequired.newBuilder().setA(1).setB(2).setC(3).build(); + @Test public void testRequired() throws Exception { TestRequired.Builder builder = TestRequired.newBuilder(); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setA(1); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setB(1); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setC(1); - assertTrue(builder.isInitialized()); + assertThat(builder.isInitialized()).isTrue(); } + @Test public void testRequiredForeign() throws Exception { TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder(); - assertTrue(builder.isInitialized()); + assertThat(builder.isInitialized()).isTrue(); builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED); - assertTrue(builder.isInitialized()); + assertThat(builder.isInitialized()).isTrue(); builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED); - assertTrue(builder.isInitialized()); + assertThat(builder.isInitialized()).isTrue(); } + @Test public void testRequiredExtension() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); - assertTrue(builder.isInitialized()); + assertThat(builder.isInitialized()).isTrue(); builder.setExtension(TestRequired.single, TEST_REQUIRED_UNINITIALIZED); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setExtension(TestRequired.single, TEST_REQUIRED_INITIALIZED); - assertTrue(builder.isInitialized()); + assertThat(builder.isInitialized()).isTrue(); builder.addExtension(TestRequired.multi, TEST_REQUIRED_UNINITIALIZED); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setExtension(TestRequired.multi, 0, TEST_REQUIRED_INITIALIZED); - assertTrue(builder.isInitialized()); + assertThat(builder.isInitialized()).isTrue(); } + @Test public void testRequiredDynamic() throws Exception { Descriptors.Descriptor descriptor = TestRequired.getDescriptor(); DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setField(descriptor.findFieldByName("a"), 1); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setField(descriptor.findFieldByName("b"), 1); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setField(descriptor.findFieldByName("c"), 1); - assertTrue(builder.isInitialized()); + assertThat(builder.isInitialized()).isTrue(); } + @Test public void testRequiredDynamicForeign() throws Exception { Descriptors.Descriptor descriptor = TestRequiredForeign.getDescriptor(); DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor); - assertTrue(builder.isInitialized()); + assertThat(builder.isInitialized()).isTrue(); builder.setField(descriptor.findFieldByName("optional_message"), TEST_REQUIRED_UNINITIALIZED); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setField(descriptor.findFieldByName("optional_message"), TEST_REQUIRED_INITIALIZED); - assertTrue(builder.isInitialized()); + assertThat(builder.isInitialized()).isTrue(); builder.addRepeatedField( descriptor.findFieldByName("repeated_message"), TEST_REQUIRED_UNINITIALIZED); - assertFalse(builder.isInitialized()); + assertThat(builder.isInitialized()).isFalse(); builder.setRepeatedField( descriptor.findFieldByName("repeated_message"), 0, TEST_REQUIRED_INITIALIZED); - assertTrue(builder.isInitialized()); + assertThat(builder.isInitialized()).isTrue(); } + @Test public void testUninitializedException() throws Exception { try { TestRequired.newBuilder().build(); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (UninitializedMessageException e) { - assertEquals("Message missing required fields: a, b, c", e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo("Message missing required fields: a, b, c"); } } + @Test public void testBuildPartial() throws Exception { // We're mostly testing that no exception is thrown. TestRequired message = TestRequired.newBuilder().buildPartial(); - assertFalse(message.isInitialized()); + assertThat(message.isInitialized()).isFalse(); } + @Test public void testNestedUninitializedException() throws Exception { try { TestRequiredForeign.newBuilder() @@ -222,23 +236,25 @@ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED) .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED) .build(); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (UninitializedMessageException e) { - assertEquals( - "Message missing required fields: " - + "optional_message.a, " - + "optional_message.b, " - + "optional_message.c, " - + "repeated_message[0].a, " - + "repeated_message[0].b, " - + "repeated_message[0].c, " - + "repeated_message[1].a, " - + "repeated_message[1].b, " - + "repeated_message[1].c", - e.getMessage()); + assertThat(e) + .hasMessageThat() + .isEqualTo( + "Message missing required fields: " + + "optional_message.a, " + + "optional_message.b, " + + "optional_message.c, " + + "repeated_message[0].a, " + + "repeated_message[0].b, " + + "repeated_message[0].c, " + + "repeated_message[1].a, " + + "repeated_message[1].b, " + + "repeated_message[1].c"); } } + @Test public void testBuildNestedPartial() throws Exception { // We're mostly testing that no exception is thrown. TestRequiredForeign message = @@ -247,18 +263,20 @@ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED) .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED) .buildPartial(); - assertFalse(message.isInitialized()); + assertThat(message.isInitialized()).isFalse(); } + @Test public void testParseUnititialized() throws Exception { try { TestRequired.parseFrom(ByteString.EMPTY); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (InvalidProtocolBufferException e) { - assertEquals("Message missing required fields: a, b, c", e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo("Message missing required fields: a, b, c"); } } + @Test public void testParseNestedUnititialized() throws Exception { ByteString data = TestRequiredForeign.newBuilder() @@ -270,49 +288,54 @@ try { TestRequiredForeign.parseFrom(data); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (InvalidProtocolBufferException e) { - assertEquals( - "Message missing required fields: " - + "optional_message.a, " - + "optional_message.b, " - + "optional_message.c, " - + "repeated_message[0].a, " - + "repeated_message[0].b, " - + "repeated_message[0].c, " - + "repeated_message[1].a, " - + "repeated_message[1].b, " - + "repeated_message[1].c", - e.getMessage()); + assertThat(e) + .hasMessageThat() + .isEqualTo( + "Message missing required fields: " + + "optional_message.a, " + + "optional_message.b, " + + "optional_message.c, " + + "repeated_message[0].a, " + + "repeated_message[0].b, " + + "repeated_message[0].c, " + + "repeated_message[1].a, " + + "repeated_message[1].b, " + + "repeated_message[1].c"); } } + @Test public void testDynamicUninitializedException() throws Exception { try { DynamicMessage.newBuilder(TestRequired.getDescriptor()).build(); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (UninitializedMessageException e) { - assertEquals("Message missing required fields: a, b, c", e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo("Message missing required fields: a, b, c"); } } + @Test public void testDynamicBuildPartial() throws Exception { // We're mostly testing that no exception is thrown. DynamicMessage message = DynamicMessage.newBuilder(TestRequired.getDescriptor()).buildPartial(); - assertFalse(message.isInitialized()); + assertThat(message.isInitialized()).isFalse(); } + @Test public void testDynamicParseUnititialized() throws Exception { try { Descriptors.Descriptor descriptor = TestRequired.getDescriptor(); DynamicMessage.parseFrom(descriptor, ByteString.EMPTY); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (InvalidProtocolBufferException e) { - assertEquals("Message missing required fields: a, b, c", e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo("Message missing required fields: a, b, c"); } } /** Test reading unset repeated message from DynamicMessage. */ + @Test public void testDynamicRepeatedMessageNull() throws Exception { TestRequired.getDescriptor(); DynamicMessage result = @@ -320,16 +343,18 @@ .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build()) .build(); - assertTrue( - result.getField(result.getDescriptorForType().findFieldByName("repeated_foreign_message")) - instanceof List<?>); - assertEquals( - 0, - result.getRepeatedFieldCount( - result.getDescriptorForType().findFieldByName("repeated_foreign_message"))); + assertThat( + result.getField( + result.getDescriptorForType().findFieldByName("repeated_foreign_message"))) + .isInstanceOf(List.class); + assertThat( + result.getRepeatedFieldCount( + result.getDescriptorForType().findFieldByName("repeated_foreign_message"))) + .isEqualTo(0); } /** Test reading repeated message from DynamicMessage. */ + @Test public void testDynamicRepeatedMessageNotNull() throws Exception { TestAllTypes repeatedNested = TestAllTypes.newBuilder() @@ -346,12 +371,13 @@ .mergeFrom(DynamicMessage.newBuilder(repeatedNested).build()) .build(); - assertTrue( - result.getField(result.getDescriptorForType().findFieldByName("repeated_foreign_message")) - instanceof List<?>); - assertEquals( - 2, - result.getRepeatedFieldCount( - result.getDescriptorForType().findFieldByName("repeated_foreign_message"))); + assertThat( + result.getField( + result.getDescriptorForType().findFieldByName("repeated_foreign_message"))) + .isInstanceOf(List.class); + assertThat( + result.getRepeatedFieldCount( + result.getDescriptorForType().findFieldByName("repeated_foreign_message"))) + .isEqualTo(2); } }
diff --git a/java/core/src/test/java/com/google/protobuf/NestedBuildersTest.java b/java/core/src/test/java/com/google/protobuf/NestedBuildersTest.java index 1af3f93..961c0b5 100644 --- a/java/core/src/test/java/com/google/protobuf/NestedBuildersTest.java +++ b/java/core/src/test/java/com/google/protobuf/NestedBuildersTest.java
@@ -30,21 +30,25 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import protobuf_unittest.Engine; import protobuf_unittest.Vehicle; import protobuf_unittest.Wheel; import java.util.ArrayList; import java.util.List; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Test cases that exercise end-to-end use cases involving {@link SingleFieldBuilder} and {@link * RepeatedFieldBuilder}. - * - * @author jonp@google.com (Jon Perlow) */ -public class NestedBuildersTest extends TestCase { +@RunWith(JUnit4.class) +public class NestedBuildersTest { + @Test public void testMessagesAndBuilders() { Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); vehicleBuilder.addWheelBuilder().setRadius(4).setWidth(1); @@ -54,13 +58,13 @@ vehicleBuilder.getEngineBuilder().setLiters(10); Vehicle vehicle = vehicleBuilder.build(); - assertEquals(4, vehicle.getWheelCount()); + assertThat(vehicle.getWheelCount()).isEqualTo(4); for (int i = 0; i < 4; i++) { Wheel wheel = vehicle.getWheel(i); - assertEquals(4, wheel.getRadius()); - assertEquals(i + 1, wheel.getWidth()); + assertThat(wheel.getRadius()).isEqualTo(4); + assertThat(wheel.getWidth()).isEqualTo(i + 1); } - assertEquals(10, vehicle.getEngine().getLiters()); + assertThat(vehicle.getEngine().getLiters()).isEqualTo(10); for (int i = 0; i < 4; i++) { vehicleBuilder.getWheelBuilder(i).setRadius(5).setWidth(i + 10); @@ -70,16 +74,17 @@ vehicle = vehicleBuilder.build(); for (int i = 0; i < 4; i++) { Wheel wheel = vehicle.getWheel(i); - assertEquals(5, wheel.getRadius()); - assertEquals(i + 10, wheel.getWidth()); + assertThat(wheel.getRadius()).isEqualTo(5); + assertThat(wheel.getWidth()).isEqualTo(i + 10); } - assertEquals(20, vehicle.getEngine().getLiters()); - assertTrue(vehicle.hasEngine()); + assertThat(vehicle.getEngine().getLiters()).isEqualTo(20); + assertThat(vehicle.hasEngine()).isTrue(); engineBuilder.setLiters(50); - assertEquals(50, vehicleBuilder.getEngine().getLiters()); + assertThat(vehicleBuilder.getEngine().getLiters()).isEqualTo(50); } + @Test public void testMessagesAreCached() { Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); vehicleBuilder.addWheelBuilder().setRadius(1).setWidth(2); @@ -90,7 +95,7 @@ // Make sure messages are cached. List<Wheel> wheels = new ArrayList<Wheel>(vehicleBuilder.getWheelList()); for (int i = 0; i < wheels.size(); i++) { - assertSame(wheels.get(i), vehicleBuilder.getWheel(i)); + assertThat(wheels.get(i)).isSameInstanceAs(vehicleBuilder.getWheel(i)); } // Now get builders and check they didn't change. @@ -98,7 +103,7 @@ vehicleBuilder.getWheel(i); } for (int i = 0; i < wheels.size(); i++) { - assertSame(wheels.get(i), vehicleBuilder.getWheel(i)); + assertThat(wheels.get(i)).isSameInstanceAs(vehicleBuilder.getWheel(i)); } // Change just one @@ -107,33 +112,36 @@ // Now get wheels and check that only that one changed for (int i = 0; i < wheels.size(); i++) { if (i < 3) { - assertSame(wheels.get(i), vehicleBuilder.getWheel(i)); + assertThat(wheels.get(i)).isSameInstanceAs(vehicleBuilder.getWheel(i)); } else { - assertNotSame(wheels.get(i), vehicleBuilder.getWheel(i)); + assertThat(wheels.get(i)).isNotSameInstanceAs(vehicleBuilder.getWheel(i)); } } } + @Test public void testRemove_WithNestedBuilders() { Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); vehicleBuilder.addWheelBuilder().setRadius(1).setWidth(1); vehicleBuilder.addWheelBuilder().setRadius(2).setWidth(2); vehicleBuilder.removeWheel(0); - assertEquals(1, vehicleBuilder.getWheelCount()); - assertEquals(2, vehicleBuilder.getWheel(0).getRadius()); + assertThat(vehicleBuilder.getWheelCount()).isEqualTo(1); + assertThat(vehicleBuilder.getWheel(0).getRadius()).isEqualTo(2); } + @Test public void testRemove_WithNestedMessages() { Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); vehicleBuilder.addWheel(Wheel.newBuilder().setRadius(1).setWidth(1)); vehicleBuilder.addWheel(Wheel.newBuilder().setRadius(2).setWidth(2)); vehicleBuilder.removeWheel(0); - assertEquals(1, vehicleBuilder.getWheelCount()); - assertEquals(2, vehicleBuilder.getWheel(0).getRadius()); + assertThat(vehicleBuilder.getWheelCount()).isEqualTo(1); + assertThat(vehicleBuilder.getWheel(0).getRadius()).isEqualTo(2); } + @Test public void testMerge() { Vehicle vehicle1 = Vehicle.newBuilder() @@ -143,16 +151,17 @@ Vehicle vehicle2 = Vehicle.newBuilder().mergeFrom(vehicle1).build(); // List should be the same -- no allocation - assertSame(vehicle1.getWheelList(), vehicle2.getWheelList()); + assertThat(vehicle1.getWheelList()).isSameInstanceAs(vehicle2.getWheelList()); Vehicle vehicle3 = vehicle1.toBuilder().build(); - assertSame(vehicle1.getWheelList(), vehicle3.getWheelList()); + assertThat(vehicle1.getWheelList()).isSameInstanceAs(vehicle3.getWheelList()); } + @Test public void testGettingBuilderMarksFieldAsHaving() { Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); vehicleBuilder.getEngineBuilder(); Vehicle vehicle = vehicleBuilder.buildPartial(); - assertTrue(vehicle.hasEngine()); + assertThat(vehicle.hasEngine()).isTrue(); } }
diff --git a/java/core/src/test/java/com/google/protobuf/NioByteStringTest.java b/java/core/src/test/java/com/google/protobuf/NioByteStringTest.java index 489bb7c..1f14271 100644 --- a/java/core/src/test/java/com/google/protobuf/NioByteStringTest.java +++ b/java/core/src/test/java/com/google/protobuf/NioByteStringTest.java
@@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static com.google.protobuf.Internal.UTF_8; import java.io.ByteArrayInputStream; @@ -46,10 +48,13 @@ import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Tests for {@link NioByteString}. */ -public class NioByteStringTest extends TestCase { +@RunWith(JUnit4.class) +public class NioByteStringTest { private static final ByteString EMPTY = new NioByteString(ByteBuffer.wrap(new byte[0])); private static final String CLASSNAME = NioByteString.class.getSimpleName(); private static final byte[] BYTES = ByteStringTest.getTestBytes(1234, 11337766L); @@ -58,9 +63,12 @@ private final ByteBuffer backingBuffer = ByteBuffer.wrap(BYTES.clone()); private final ByteString testString = new NioByteString(backingBuffer); + @Test public void testExpectedType() { String actualClassName = getActualClassName(testString); - assertEquals(CLASSNAME + " should match type exactly", CLASSNAME, actualClassName); + assertWithMessage("%s should match type exactly", CLASSNAME) + .that(CLASSNAME) + .isEqualTo(actualClassName); } protected String getActualClassName(Object object) { @@ -69,31 +77,36 @@ return actualClassName; } + @Test public void testByteAt() { boolean stillEqual = true; for (int i = 0; stillEqual && i < BYTES.length; ++i) { stillEqual = (BYTES[i] == testString.byteAt(i)); } - assertTrue(CLASSNAME + " must capture the right bytes", stillEqual); + assertWithMessage("%s must capture the right bytes", CLASSNAME).that(stillEqual).isTrue(); } + @Test public void testByteIterator() { boolean stillEqual = true; ByteString.ByteIterator iter = testString.iterator(); for (int i = 0; stillEqual && i < BYTES.length; ++i) { stillEqual = (iter.hasNext() && BYTES[i] == iter.nextByte()); } - assertTrue(CLASSNAME + " must capture the right bytes", stillEqual); - assertFalse(CLASSNAME + " must have exhausted the iterator", iter.hasNext()); + assertWithMessage("%s must capture the right bytes", CLASSNAME).that(stillEqual).isTrue(); + assertWithMessage("%s must have exhausted the iterator", CLASSNAME) + .that(iter.hasNext()) + .isFalse(); try { iter.nextByte(); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NoSuchElementException e) { // This is success } } + @Test public void testByteIterable() { boolean stillEqual = true; int j = 0; @@ -101,22 +114,34 @@ stillEqual = (BYTES[j] == quantum); ++j; } - assertTrue(CLASSNAME + " must capture the right bytes as Bytes", stillEqual); - assertEquals(CLASSNAME + " iterable character count", BYTES.length, j); + assertWithMessage("%s must capture the right bytes as Bytes", CLASSNAME) + .that(stillEqual) + .isTrue(); + assertWithMessage("%s iterable character count", CLASSNAME).that(BYTES).hasLength(j); } + @Test public void testSize() { - assertEquals(CLASSNAME + " must have the expected size", BYTES.length, testString.size()); + assertWithMessage("%s must have the expected size", CLASSNAME) + .that(BYTES) + .hasLength(testString.size()); } + @Test public void testGetTreeDepth() { - assertEquals(CLASSNAME + " must have depth 0", 0, testString.getTreeDepth()); + assertWithMessage("%s must have depth 0", CLASSNAME) + .that(testString.getTreeDepth()) + .isEqualTo(0); } + @Test public void testIsBalanced() { - assertTrue(CLASSNAME + " is technically balanced", testString.isBalanced()); + assertWithMessage("%s is technically balanced", CLASSNAME) + .that(testString.isBalanced()) + .isTrue(); } + @Test public void testCopyTo_ByteArrayOffsetLength() { int destinationOffset = 50; int length = 100; @@ -127,9 +152,12 @@ for (int i = 0; stillEqual && i < length; ++i) { stillEqual = BYTES[i + sourceOffset] == destination[i + destinationOffset]; } - assertTrue(CLASSNAME + ".copyTo(4 arg) must give the expected bytes", stillEqual); + assertWithMessage("%s.copyTo(4 arg) must give the expected bytes", CLASSNAME) + .that(stillEqual) + .isTrue(); } + @Test public void testCopyTo_ByteArrayOffsetLengthErrors() { int destinationOffset = 50; int length = 100; @@ -138,7 +166,9 @@ try { // Copy one too many bytes testString.copyTo(destination, testString.size() + 1 - length, destinationOffset, length); - fail("Should have thrown an exception when copying too many bytes of a " + CLASSNAME); + assertWithMessage( + "Should have thrown an exception when copying too many bytes of a %s", CLASSNAME) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } @@ -146,7 +176,10 @@ try { // Copy with illegal negative sourceOffset testString.copyTo(destination, -1, destinationOffset, length); - fail("Should have thrown an exception when given a negative sourceOffset in " + CLASSNAME); + assertWithMessage( + "Should have thrown an exception when given a negative sourceOffset in %s ", + CLASSNAME) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } @@ -154,9 +187,10 @@ try { // Copy with illegal negative destinationOffset testString.copyTo(destination, 0, -1, length); - fail( - "Should have thrown an exception when given a negative destinationOffset in " - + CLASSNAME); + assertWithMessage( + "Should have thrown an exception when given a negative destinationOffset in %s", + CLASSNAME) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } @@ -164,7 +198,9 @@ try { // Copy with illegal negative size testString.copyTo(destination, 0, 0, -1); - fail("Should have thrown an exception when given a negative size in " + CLASSNAME); + assertWithMessage( + "Should have thrown an exception when given a negative size in %s", CLASSNAME) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } @@ -172,9 +208,10 @@ try { // Copy with illegal too-large sourceOffset testString.copyTo(destination, 2 * testString.size(), 0, length); - fail( - "Should have thrown an exception when the destinationOffset is too large in " - + CLASSNAME); + assertWithMessage( + "Should have thrown an exception when the destinationOffset is too large in %s", + CLASSNAME) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } @@ -182,33 +219,38 @@ try { // Copy with illegal too-large destinationOffset testString.copyTo(destination, 0, 2 * destination.length, length); - fail( - "Should have thrown an exception when the destinationOffset is too large in " - + CLASSNAME); + assertWithMessage( + "Should have thrown an exception when the destinationOffset is too large in %s", + CLASSNAME) + .fail(); } catch (IndexOutOfBoundsException expected) { // This is success } } + @Test public void testCopyTo_ByteBuffer() { // Same length. ByteBuffer myBuffer = ByteBuffer.allocate(BYTES.length); testString.copyTo(myBuffer); myBuffer.flip(); - assertEquals( - CLASSNAME + ".copyTo(ByteBuffer) must give back the same bytes", backingBuffer, myBuffer); + assertWithMessage("%s.copyTo(ByteBuffer) must give back the same bytes", CLASSNAME) + .that(backingBuffer) + .isEqualTo(myBuffer); // Target buffer bigger than required. myBuffer = ByteBuffer.allocate(testString.size() + 1); testString.copyTo(myBuffer); myBuffer.flip(); - assertEquals(backingBuffer, myBuffer); + assertThat(backingBuffer).isEqualTo(myBuffer); // Target buffer has no space. myBuffer = ByteBuffer.allocate(0); try { testString.copyTo(myBuffer); - fail("Should have thrown an exception when target ByteBuffer has insufficient capacity"); + assertWithMessage( + "Should have thrown an exception when target ByteBuffer has insufficient capacity") + .fail(); } catch (BufferOverflowException e) { // Expected. } @@ -217,17 +259,23 @@ myBuffer = ByteBuffer.allocate(1); try { testString.copyTo(myBuffer); - fail("Should have thrown an exception when target ByteBuffer has insufficient capacity"); + assertWithMessage( + "Should have thrown an exception when target ByteBuffer has insufficient capacity") + .fail(); } catch (BufferOverflowException e) { // Expected. } } + @Test public void testMarkSupported() { InputStream stream = testString.newInput(); - assertTrue(CLASSNAME + ".newInput() must support marking", stream.markSupported()); + assertWithMessage("%s.newInput() must support marking", CLASSNAME) + .that(stream.markSupported()) + .isTrue(); } + @Test public void testMarkAndReset() throws IOException { int fraction = testString.size() / 3; @@ -235,21 +283,18 @@ stream.mark(testString.size()); // First, mark() the end. skipFully(stream, fraction); // Skip a large fraction, but not all. - assertEquals( - CLASSNAME + ": after skipping to the 'middle', half the bytes are available", - (testString.size() - fraction), - stream.available()); + assertWithMessage("%s: after skipping to the 'middle', half the bytes are available", CLASSNAME) + .that((testString.size() - fraction)) + .isEqualTo(stream.available()); stream.reset(); - assertEquals( - CLASSNAME + ": after resetting, all bytes are available", - testString.size(), - stream.available()); + assertWithMessage("%s: after resetting, all bytes are available", CLASSNAME) + .that(testString.size()) + .isEqualTo(stream.available()); skipFully(stream, testString.size()); // Skip to the end. - assertEquals( - CLASSNAME + ": after skipping to the end, no more bytes are available", - 0, - stream.available()); + assertWithMessage("%s: after skipping to the end, no more bytes are available", CLASSNAME) + .that(stream.available()) + .isEqualTo(0); } /** @@ -285,50 +330,55 @@ } } + @Test public void testAsReadOnlyByteBuffer() { ByteBuffer byteBuffer = testString.asReadOnlyByteBuffer(); byte[] roundTripBytes = new byte[BYTES.length]; - assertTrue(byteBuffer.remaining() == BYTES.length); - assertTrue(byteBuffer.isReadOnly()); + assertThat(byteBuffer.remaining() == BYTES.length).isTrue(); + assertThat(byteBuffer.isReadOnly()).isTrue(); byteBuffer.get(roundTripBytes); - assertTrue( - CLASSNAME + ".asReadOnlyByteBuffer() must give back the same bytes", - Arrays.equals(BYTES, roundTripBytes)); + assertWithMessage("%s.asReadOnlyByteBuffer() must give back the same bytes", CLASSNAME) + .that(Arrays.equals(BYTES, roundTripBytes)) + .isTrue(); } + @Test public void testAsReadOnlyByteBufferList() { List<ByteBuffer> byteBuffers = testString.asReadOnlyByteBufferList(); int bytesSeen = 0; byte[] roundTripBytes = new byte[BYTES.length]; for (ByteBuffer byteBuffer : byteBuffers) { int thisLength = byteBuffer.remaining(); - assertTrue(byteBuffer.isReadOnly()); - assertTrue(bytesSeen + thisLength <= BYTES.length); + assertThat(byteBuffer.isReadOnly()).isTrue(); + assertThat(bytesSeen + thisLength <= BYTES.length).isTrue(); byteBuffer.get(roundTripBytes, bytesSeen, thisLength); bytesSeen += thisLength; } - assertTrue(bytesSeen == BYTES.length); - assertTrue( - CLASSNAME + ".asReadOnlyByteBufferTest() must give back the same bytes", - Arrays.equals(BYTES, roundTripBytes)); + assertThat(BYTES).hasLength(bytesSeen); + assertWithMessage("%s.asReadOnlyByteBufferTest() must give back the same bytes", CLASSNAME) + .that(Arrays.equals(BYTES, roundTripBytes)) + .isTrue(); } + @Test public void testToByteArray() { byte[] roundTripBytes = testString.toByteArray(); - assertTrue( - CLASSNAME + ".toByteArray() must give back the same bytes", - Arrays.equals(BYTES, roundTripBytes)); + assertWithMessage("%s.toByteArray() must give back the same bytes", CLASSNAME) + .that(Arrays.equals(BYTES, roundTripBytes)) + .isTrue(); } + @Test public void testWriteTo() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); testString.writeTo(bos); byte[] roundTripBytes = bos.toByteArray(); - assertTrue( - CLASSNAME + ".writeTo() must give back the same bytes", - Arrays.equals(BYTES, roundTripBytes)); + assertWithMessage("%s.writeTo() must give back the same bytes", CLASSNAME) + .that(Arrays.equals(BYTES, roundTripBytes)) + .isTrue(); } + @Test public void testWriteToShouldNotExposeInternalBufferToOutputStream() throws IOException { OutputStream os = new OutputStream() { @@ -345,11 +395,12 @@ byte[] original = Arrays.copyOf(BYTES, BYTES.length); testString.writeTo(os); - assertTrue( - CLASSNAME + ".writeTo() must NOT grant access to underlying buffer", - Arrays.equals(original, BYTES)); + assertWithMessage("%s.writeTo() must NOT grant access to underlying buffer", CLASSNAME) + .that(Arrays.equals(original, BYTES)) + .isTrue(); } + @Test public void testWriteToInternalShouldExposeInternalBufferToOutputStream() throws IOException { OutputStream os = new OutputStream() { @@ -366,11 +417,12 @@ testString.writeToInternal(os, 0, testString.size()); byte[] allZeros = new byte[testString.size()]; - assertTrue( - CLASSNAME + ".writeToInternal() must grant access to underlying buffer", - Arrays.equals(allZeros, backingBuffer.array())); + assertWithMessage("%s.writeToInternal() must grant access to underlying buffer", CLASSNAME) + .that(Arrays.equals(allZeros, backingBuffer.array())) + .isTrue(); } + @Test public void testWriteToShouldExposeInternalBufferToByteOutput() throws IOException { ByteOutput out = new ByteOutput() { @@ -403,128 +455,157 @@ testString.writeTo(out); byte[] allZeros = new byte[testString.size()]; - assertTrue( - CLASSNAME + ".writeTo() must grant access to underlying buffer", - Arrays.equals(allZeros, backingBuffer.array())); + assertWithMessage("%s.writeTo() must grant access to underlying buffer", CLASSNAME) + .that(Arrays.equals(allZeros, backingBuffer.array())) + .isTrue(); } + @Test public void testNewOutput() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteString.Output output = ByteString.newOutput(); testString.writeTo(output); - assertEquals("Output Size returns correct result", output.size(), testString.size()); + assertWithMessage("Output Size returns correct result") + .that(output.size()) + .isEqualTo(testString.size()); output.writeTo(bos); - assertTrue( - "Output.writeTo() must give back the same bytes", Arrays.equals(BYTES, bos.toByteArray())); + assertWithMessage("Output.writeTo() must give back the same bytes") + .that(Arrays.equals(BYTES, bos.toByteArray())) + .isTrue(); // write the output stream to itself! This should cause it to double output.writeTo(output); - assertEquals( - "Writing an output stream to itself is successful", - testString.concat(testString), - output.toByteString()); + assertWithMessage("Writing an output stream to itself is successful") + .that(testString.concat(testString)) + .isEqualTo(output.toByteString()); output.reset(); - assertEquals("Output.reset() resets the output", 0, output.size()); - assertEquals("Output.reset() resets the output", EMPTY, output.toByteString()); + assertWithMessage("Output.reset() resets the output").that(output.size()).isEqualTo(0); + assertWithMessage("Output.reset() resets the output") + .that(output.toByteString()) + .isEqualTo(EMPTY); } + @Test public void testToString() { String testString = "I love unicode \u1234\u5678 characters"; ByteString unicode = forString(testString); String roundTripString = unicode.toString(UTF_8); - assertEquals(CLASSNAME + " unicode must match", testString, roundTripString); + assertWithMessage("%s unicode must match", CLASSNAME) + .that(testString) + .isEqualTo(roundTripString); } + @Test public void testCharsetToString() { String testString = "I love unicode \u1234\u5678 characters"; ByteString unicode = forString(testString); String roundTripString = unicode.toString(UTF_8); - assertEquals(CLASSNAME + " unicode must match", testString, roundTripString); + assertWithMessage("%s unicode must match", CLASSNAME) + .that(testString) + .isEqualTo(roundTripString); } + @Test public void testToString_returnsCanonicalEmptyString() { - assertSame( - CLASSNAME + " must be the same string references", - EMPTY.toString(UTF_8), - new NioByteString(ByteBuffer.wrap(new byte[0])).toString(UTF_8)); + assertWithMessage("%s must be the same string references", CLASSNAME) + .that(EMPTY.toString(UTF_8)) + .isSameInstanceAs(new NioByteString(ByteBuffer.wrap(new byte[0])).toString(UTF_8)); } + @Test public void testToString_raisesException() { try { EMPTY.toString("invalid"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (UnsupportedEncodingException expected) { // This is success } try { testString.toString("invalid"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (UnsupportedEncodingException expected) { // This is success } } + @Test + @SuppressWarnings("TruthSelfEquals") public void testEquals() { - assertEquals(CLASSNAME + " must not equal null", false, testString.equals(null)); - assertEquals(CLASSNAME + " must equal self", testString, testString); - assertFalse(CLASSNAME + " must not equal the empty string", testString.equals(EMPTY)); - assertEquals(CLASSNAME + " empty strings must be equal", EMPTY, testString.substring(55, 55)); - assertEquals( - CLASSNAME + " must equal another string with the same value", - testString, - new NioByteString(backingBuffer)); + assertWithMessage("%s must not equal null", CLASSNAME).that(testString).isNotEqualTo(null); + assertWithMessage("%s must equal self", CLASSNAME).that(testString).isEqualTo(testString); + assertWithMessage("%s must not equal the empty string", CLASSNAME) + .that(testString) + .isNotEqualTo(EMPTY); + assertWithMessage("%s empty strings must be equal", CLASSNAME) + .that(EMPTY) + .isEqualTo(testString.substring(55, 55)); + assertWithMessage("%s must equal another string with the same value", CLASSNAME) + .that(testString) + .isEqualTo(new NioByteString(backingBuffer)); byte[] mungedBytes = mungedBytes(); - assertFalse( - CLASSNAME + " must not equal every string with the same length", - testString.equals(new NioByteString(ByteBuffer.wrap(mungedBytes)))); + assertWithMessage("%s must not equal every string with the same length", CLASSNAME) + .that(testString.equals(new NioByteString(ByteBuffer.wrap(mungedBytes)))) + .isFalse(); } + @Test public void testEqualsLiteralByteString() { ByteString literal = ByteString.copyFrom(BYTES); - assertEquals(CLASSNAME + " must equal LiteralByteString with same value", literal, testString); - assertEquals(CLASSNAME + " must equal LiteralByteString with same value", testString, literal); - assertFalse( - CLASSNAME + " must not equal the empty string", testString.equals(ByteString.EMPTY)); - assertEquals( - CLASSNAME + " empty strings must be equal", ByteString.EMPTY, testString.substring(55, 55)); + assertWithMessage("%s must equal LiteralByteString with same value", CLASSNAME) + .that(literal) + .isEqualTo(testString); + assertWithMessage("%s must equal LiteralByteString with same value", CLASSNAME) + .that(testString) + .isEqualTo(literal); + assertWithMessage("%s must not equal the empty string", CLASSNAME) + .that(testString) + .isNotEqualTo(ByteString.EMPTY); + assertWithMessage("%s empty strings must be equal", CLASSNAME) + .that(ByteString.EMPTY) + .isEqualTo(testString.substring(55, 55)); literal = ByteString.copyFrom(mungedBytes()); - assertFalse( - CLASSNAME + " must not equal every LiteralByteString with the same length", - testString.equals(literal)); - assertFalse( - CLASSNAME + " must not equal every LiteralByteString with the same length", - literal.equals(testString)); + assertWithMessage("%s must not equal every LiteralByteString with the same length", CLASSNAME) + .that(testString) + .isNotEqualTo(literal); + assertWithMessage("%s must not equal every LiteralByteString with the same length", CLASSNAME) + .that(literal) + .isNotEqualTo(testString); } + @Test public void testEqualsRopeByteString() { ByteString p1 = ByteString.copyFrom(BYTES, 0, 5); ByteString p2 = ByteString.copyFrom(BYTES, 5, BYTES.length - 5); ByteString rope = p1.concat(p2); - assertEquals(CLASSNAME + " must equal RopeByteString with same value", rope, testString); - assertEquals(CLASSNAME + " must equal RopeByteString with same value", testString, rope); - assertFalse( - CLASSNAME + " must not equal the empty string", - testString.equals(ByteString.EMPTY.concat(ByteString.EMPTY))); - assertEquals( - CLASSNAME + " empty strings must be equal", - ByteString.EMPTY.concat(ByteString.EMPTY), - testString.substring(55, 55)); + assertWithMessage("%s must equal RopeByteString with same value", CLASSNAME) + .that(rope) + .isEqualTo(testString); + assertWithMessage("%s must equal RopeByteString with same value", CLASSNAME) + .that(testString) + .isEqualTo(rope); + assertWithMessage("%s must not equal the empty string", CLASSNAME) + .that(testString) + .isNotEqualTo(ByteString.EMPTY.concat(ByteString.EMPTY)); + assertWithMessage("%s empty strings must be equal", CLASSNAME) + .that(ByteString.EMPTY.concat(ByteString.EMPTY)) + .isEqualTo(testString.substring(55, 55)); byte[] mungedBytes = mungedBytes(); p1 = ByteString.copyFrom(mungedBytes, 0, 5); p2 = ByteString.copyFrom(mungedBytes, 5, mungedBytes.length - 5); rope = p1.concat(p2); - assertFalse( - CLASSNAME + " must not equal every RopeByteString with the same length", - testString.equals(rope)); - assertFalse( - CLASSNAME + " must not equal every RopeByteString with the same length", - rope.equals(testString)); + assertWithMessage("%s must not equal every RopeByteString with the same length", CLASSNAME) + .that(testString) + .isNotEqualTo(rope); + + assertWithMessage("%s must not equal every RopeByteString with the same length", CLASSNAME) + .that(rope) + .isNotEqualTo(testString); } private byte[] mungedBytes() { @@ -534,91 +615,118 @@ return mungedBytes; } + @Test public void testHashCode() { int hash = testString.hashCode(); - assertEquals(CLASSNAME + " must have expected hashCode", EXPECTED_HASH, hash); + assertWithMessage("%s must have expected hashCode", CLASSNAME) + .that(hash) + .isEqualTo(EXPECTED_HASH); } + @Test public void testPeekCachedHashCode() { ByteString newString = new NioByteString(backingBuffer); - assertEquals( - CLASSNAME + ".peekCachedHashCode() should return zero at first", - 0, - newString.peekCachedHashCode()); - newString.hashCode(); - assertEquals( - CLASSNAME + ".peekCachedHashCode should return zero at first", - EXPECTED_HASH, - newString.peekCachedHashCode()); + assertWithMessage("%s.peekCachedHashCode() should return zero at first", CLASSNAME) + .that(newString.peekCachedHashCode()) + .isEqualTo(0); + int unused = newString.hashCode(); + assertWithMessage("%s.peekCachedHashCode should return zero at first", CLASSNAME) + .that(newString.peekCachedHashCode()) + .isEqualTo(EXPECTED_HASH); } + @Test public void testPartialHash() { // partialHash() is more strenuously tested elsewhere by testing hashes of substrings. // This test would fail if the expected hash were 1. It's not. int hash = testString.partialHash(testString.size(), 0, testString.size()); - assertEquals(CLASSNAME + ".partialHash() must yield expected hashCode", EXPECTED_HASH, hash); + assertWithMessage("%s.partialHash() must yield expected hashCode", CLASSNAME) + .that(hash) + .isEqualTo(EXPECTED_HASH); } + @Test public void testNewInput() throws IOException { InputStream input = testString.newInput(); - assertEquals( - "InputStream.available() returns correct value", testString.size(), input.available()); + assertWithMessage("InputStream.available() returns correct value") + .that(testString.size()) + .isEqualTo(input.available()); boolean stillEqual = true; for (byte referenceByte : BYTES) { int expectedInt = (referenceByte & 0xFF); stillEqual = (expectedInt == input.read()); } - assertEquals("InputStream.available() returns correct value", 0, input.available()); - assertTrue(CLASSNAME + " must give the same bytes from the InputStream", stillEqual); - assertEquals(CLASSNAME + " InputStream must now be exhausted", -1, input.read()); + assertWithMessage("InputStream.available() returns correct value") + .that(input.available()) + .isEqualTo(0); + assertWithMessage("%s must give the same bytes from the InputStream", CLASSNAME) + .that(stillEqual) + .isTrue(); + assertWithMessage("%s InputStream must now be exhausted", CLASSNAME) + .that(input.read()) + .isEqualTo(-1); } + @Test public void testNewInput_skip() throws IOException { InputStream input = testString.newInput(); int stringSize = testString.size(); int nearEndIndex = stringSize * 2 / 3; long skipped1 = input.skip(nearEndIndex); - assertEquals("InputStream.skip()", skipped1, nearEndIndex); - assertEquals("InputStream.available()", stringSize - skipped1, input.available()); - assertTrue("InputStream.mark() is available", input.markSupported()); + assertWithMessage("InputStream.skip()").that(skipped1).isEqualTo(nearEndIndex); + assertWithMessage("InputStream.available()") + .that(input.available()) + .isEqualTo(stringSize - skipped1); + assertWithMessage("InputStream.mark() is available").that(input.markSupported()).isTrue(); input.mark(0); - assertEquals( - "InputStream.skip(), read()", testString.byteAt(nearEndIndex) & 0xFF, input.read()); - assertEquals("InputStream.available()", stringSize - skipped1 - 1, input.available()); + assertWithMessage("InputStream.skip(), read()") + .that(input.read()) + .isEqualTo(testString.byteAt(nearEndIndex) & 0xFF); + assertWithMessage("InputStream.available()") + .that(input.available()) + .isEqualTo(stringSize - skipped1 - 1); long skipped2 = input.skip(stringSize); - assertEquals("InputStream.skip() incomplete", skipped2, stringSize - skipped1 - 1); - assertEquals("InputStream.skip(), no more input", 0, input.available()); - assertEquals("InputStream.skip(), no more input", -1, input.read()); + assertWithMessage("InputStream.skip() incomplete") + .that(skipped2) + .isEqualTo(stringSize - skipped1 - 1); + assertWithMessage("InputStream.skip(), no more input").that(input.available()).isEqualTo(0); + assertWithMessage("InputStream.skip(), no more input").that(input.read()).isEqualTo(-1); input.reset(); - assertEquals("InputStream.reset() succeeded", stringSize - skipped1, input.available()); - assertEquals( - "InputStream.reset(), read()", testString.byteAt(nearEndIndex) & 0xFF, input.read()); + assertWithMessage("InputStream.reset() succeeded") + .that(input.available()) + .isEqualTo(stringSize - skipped1); + assertWithMessage("InputStream.reset(), read()") + .that(input.read()) + .isEqualTo(testString.byteAt(nearEndIndex) & 0xFF); } + @Test public void testNewCodedInput() throws IOException { CodedInputStream cis = testString.newCodedInput(); byte[] roundTripBytes = cis.readRawBytes(BYTES.length); - assertTrue( - CLASSNAME + " must give the same bytes back from the CodedInputStream", - Arrays.equals(BYTES, roundTripBytes)); - assertTrue(CLASSNAME + " CodedInputStream must now be exhausted", cis.isAtEnd()); + assertWithMessage("%s must give the same bytes back from the CodedInputStream", CLASSNAME) + .that(Arrays.equals(BYTES, roundTripBytes)) + .isTrue(); + assertWithMessage("%s CodedInputStream must now be exhausted", CLASSNAME) + .that(cis.isAtEnd()) + .isTrue(); } /** * Make sure we keep things simple when concatenating with empty. See also {@link * ByteStringTest#testConcat_empty()}. */ + @Test public void testConcat_empty() { - assertSame( - CLASSNAME + " concatenated with empty must give " + CLASSNAME, - testString.concat(EMPTY), - testString); - assertSame( - "empty concatenated with " + CLASSNAME + " must give " + CLASSNAME, - EMPTY.concat(testString), - testString); + assertWithMessage("%s concatenated with empty must give %s", CLASSNAME, CLASSNAME) + .that(testString.concat(EMPTY)) + .isSameInstanceAs(testString); + assertWithMessage("empty concatenated with %s must give %s", CLASSNAME, CLASSNAME) + .that(EMPTY.concat(testString)) + .isSameInstanceAs(testString); } + @Test public void testJavaSerialization() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); @@ -628,8 +736,8 @@ InputStream in = new ByteArrayInputStream(pickled); ObjectInputStream ois = new ObjectInputStream(in); Object o = ois.readObject(); - assertTrue("Didn't get a ByteString back", o instanceof ByteString); - assertEquals("Should get an equal ByteString back", testString, o); + assertWithMessage("Didn't get a ByteString back").that(o).isInstanceOf(ByteString.class); + assertWithMessage("Should get an equal ByteString back").that(o).isEqualTo(testString); } private static ByteString forString(String str) {
diff --git a/java/core/src/test/java/com/google/protobuf/PackedFieldTest.java b/java/core/src/test/java/com/google/protobuf/PackedFieldTest.java index 2397d2e..ce77baa 100644 --- a/java/core/src/test/java/com/google/protobuf/PackedFieldTest.java +++ b/java/core/src/test/java/com/google/protobuf/PackedFieldTest.java
@@ -30,13 +30,18 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import com.google.protobuf.PackedFieldTestProto.TestAllTypes; import com.google.protobuf.PackedFieldTestProto.TestAllTypes.NestedEnum; import com.google.protobuf.PackedFieldTestProto.TestUnpackedTypes; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Tests primitive repeated fields in proto3 are packed in wire format. */ -public class PackedFieldTest extends TestCase { +@RunWith(JUnit4.class) +public class PackedFieldTest { static final ByteString expectedPackedRawBytes = ByteString.copyFrom( new byte[] { @@ -191,29 +196,34 @@ 0x01, // repeated nested enum }); + @Test public void testPackedGeneratedMessage() throws Exception { TestAllTypes message = TestAllTypes.parseFrom(expectedPackedRawBytes); - assertEquals(expectedPackedRawBytes, message.toByteString()); + assertThat(message.toByteString()).isEqualTo(expectedPackedRawBytes); } + @Test public void testPackedDynamicMessageSerialize() throws Exception { DynamicMessage message = DynamicMessage.parseFrom(TestAllTypes.getDescriptor(), expectedPackedRawBytes); - assertEquals(expectedPackedRawBytes, message.toByteString()); + assertThat(message.toByteString()).isEqualTo(expectedPackedRawBytes); } + @Test public void testUnpackedGeneratedMessage() throws Exception { TestUnpackedTypes message = TestUnpackedTypes.parseFrom(expectedUnpackedRawBytes); - assertEquals(expectedUnpackedRawBytes, message.toByteString()); + assertThat(message.toByteString()).isEqualTo(expectedUnpackedRawBytes); } + @Test public void testUnPackedDynamicMessageSerialize() throws Exception { DynamicMessage message = DynamicMessage.parseFrom(TestUnpackedTypes.getDescriptor(), expectedUnpackedRawBytes); - assertEquals(expectedUnpackedRawBytes, message.toByteString()); + assertThat(message.toByteString()).isEqualTo(expectedUnpackedRawBytes); } // Make sure we haven't screwed up the code generation for packing fields by default. + @Test public void testPackedSerialization() throws Exception { TestAllTypes message = TestAllTypes.newBuilder() @@ -225,7 +235,7 @@ while (!in.isAtEnd()) { int tag = in.readTag(); - assertEquals(WireFormat.WIRETYPE_LENGTH_DELIMITED, WireFormat.getTagWireType(tag)); + assertThat(WireFormat.getTagWireType(tag)).isEqualTo(WireFormat.WIRETYPE_LENGTH_DELIMITED); in.skipField(tag); } }
diff --git a/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java b/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java index 4e63ee7..c1660a8 100644 --- a/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java +++ b/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java
@@ -30,9 +30,7 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.protobuf.DescriptorProtos.DescriptorProto; @@ -250,9 +248,8 @@ private void verifyExceptions(ParseTester parseTester) { // No exception try { - assertEquals( - DescriptorProto.getDescriptor().toProto(), - parseTester.parse(new ByteArrayInputStream(serializedProto))); + assertThat(parseTester.parse(new ByteArrayInputStream(serializedProto))) + .isEqualTo(DescriptorProto.getDescriptor().toProto()); } catch (IOException e) { fail("No exception expected: " + e); } @@ -263,7 +260,7 @@ parseTester.parse(broken(new ByteArrayInputStream(serializedProto))); fail("IOException expected but not thrown"); } catch (IOException e) { - assertFalse(e instanceof InvalidProtocolBufferException); + assertThat(e).isNotInstanceOf(InvalidProtocolBufferException.class); } // InvalidProtocolBufferException @@ -275,7 +272,7 @@ parseTester.parse(new ByteArrayInputStream(serializedProto)); fail("InvalidProtocolBufferException expected but not thrown"); } catch (IOException e) { - assertTrue(e instanceof InvalidProtocolBufferException); + assertThat(e).isInstanceOf(InvalidProtocolBufferException.class); } }
diff --git a/java/core/src/test/java/com/google/protobuf/ParserLiteTest.java b/java/core/src/test/java/com/google/protobuf/ParserLiteTest.java index eb2dc3d..fd0bf45 100644 --- a/java/core/src/test/java/com/google/protobuf/ParserLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/ParserLiteTest.java
@@ -30,15 +30,21 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import com.google.protobuf.UnittestLite.TestAllTypesLite; import com.google.protobuf.UnittestLite.TestPackedExtensionsLite; import com.google.protobuf.UnittestLite.TestParsingMergeLite; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -public class ParserLiteTest extends TestCase { +@RunWith(JUnit4.class) +public class ParserLiteTest { + private void assertRoundTripEquals(MessageLite message, ExtensionRegistryLite registry) throws Exception { final byte[] data = message.toByteArray(); @@ -46,15 +52,16 @@ final int length = data.length; final int padding = 30; Parser<? extends MessageLite> parser = message.getParserForType(); - assertEquals(message, parser.parseFrom(data, registry)); - assertEquals( - message, - parser.parseFrom(generatePaddingArray(data, offset, padding), offset, length, registry)); - assertEquals(message, parser.parseFrom(message.toByteString(), registry)); - assertEquals(message, parser.parseFrom(new ByteArrayInputStream(data), registry)); - assertEquals(message, parser.parseFrom(CodedInputStream.newInstance(data), registry)); - assertEquals( - message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer(), registry)); + assertThat(message).isEqualTo(parser.parseFrom(data, registry)); + assertThat(message) + .isEqualTo( + parser.parseFrom( + generatePaddingArray(data, offset, padding), offset, length, registry)); + assertThat(message).isEqualTo(parser.parseFrom(message.toByteString(), registry)); + assertThat(message).isEqualTo(parser.parseFrom(new ByteArrayInputStream(data), registry)); + assertThat(message).isEqualTo(parser.parseFrom(CodedInputStream.newInstance(data), registry)); + assertThat(message) + .isEqualTo(parser.parseFrom(message.toByteString().asReadOnlyByteBuffer(), registry)); } @SuppressWarnings("unchecked") @@ -65,13 +72,13 @@ final int padding = 30; Parser<MessageLite> parser = (Parser<MessageLite>) message.getParserForType(); - assertEquals(message, parser.parseFrom(data)); - assertEquals( - message, parser.parseFrom(generatePaddingArray(data, offset, padding), offset, length)); - assertEquals(message, parser.parseFrom(message.toByteString())); - assertEquals(message, parser.parseFrom(new ByteArrayInputStream(data))); - assertEquals(message, parser.parseFrom(CodedInputStream.newInstance(data))); - assertEquals(message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer())); + assertThat(message).isEqualTo(parser.parseFrom(data)); + assertThat(message) + .isEqualTo(parser.parseFrom(generatePaddingArray(data, offset, padding), offset, length)); + assertThat(message).isEqualTo(parser.parseFrom(message.toByteString())); + assertThat(message).isEqualTo(parser.parseFrom(new ByteArrayInputStream(data))); + assertThat(message).isEqualTo(parser.parseFrom(CodedInputStream.newInstance(data))); + assertThat(message).isEqualTo(parser.parseFrom(message.toByteString().asReadOnlyByteBuffer())); } private byte[] generatePaddingArray(byte[] data, int offset, int padding) { @@ -80,21 +87,25 @@ return result; } + @Test public void testParseExtensionsLite() throws Exception { assertRoundTripEquals( TestUtilLite.getAllLiteExtensionsSet(), TestUtilLite.getExtensionRegistryLite()); } + @Test public void testParsePacked() throws Exception { assertRoundTripEquals(TestUtil.getPackedSet()); assertRoundTripEquals(TestUtil.getPackedExtensionsSet(), TestUtil.getExtensionRegistry()); } + @Test public void testParsePackedLite() throws Exception { assertRoundTripEquals( TestUtilLite.getLitePackedExtensionsSet(), TestUtilLite.getExtensionRegistryLite()); } + @Test public void testParseDelimitedToLite() throws Exception { // Write MessageLite with packed extension fields. TestPackedExtensionsLite packedMessage = TestUtilLite.getLitePackedExtensionsSet(); @@ -103,25 +114,26 @@ packedMessage.writeDelimitedTo(output); InputStream input = new ByteArrayInputStream(output.toByteArray()); - assertEquals( - packedMessage, - packedMessage - .getParserForType() - .parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite())); - assertEquals( - packedMessage, - packedMessage - .getParserForType() - .parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite())); + assertThat(packedMessage) + .isEqualTo( + packedMessage + .getParserForType() + .parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite())); + assertThat(packedMessage) + .isEqualTo( + packedMessage + .getParserForType() + .parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite())); } /** Helper method for {@link #testParsingMergeLite()}. */ private void assertMessageMerged(TestAllTypesLite allTypes) throws Exception { - assertEquals(3, allTypes.getOptionalInt32()); - assertEquals(2, allTypes.getOptionalInt64()); - assertEquals("hello", allTypes.getOptionalString()); + assertThat(allTypes.getOptionalInt32()).isEqualTo(3); + assertThat(allTypes.getOptionalInt64()).isEqualTo(2); + assertThat(allTypes.getOptionalString()).isEqualTo("hello"); } + @Test public void testParsingMergeLite() throws Exception { // Build messages. TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder(); @@ -184,8 +196,8 @@ assertMessageMerged(parsingMerge.getExtension(TestParsingMergeLite.optionalExt)); // Repeated fields should not be merged. - assertEquals(3, parsingMerge.getRepeatedAllTypesCount()); - assertEquals(3, parsingMerge.getRepeatedGroupCount()); - assertEquals(3, parsingMerge.getExtensionCount(TestParsingMergeLite.repeatedExt)); + assertThat(parsingMerge.getRepeatedAllTypesCount()).isEqualTo(3); + assertThat(parsingMerge.getRepeatedGroupCount()).isEqualTo(3); + assertThat(parsingMerge.getExtensionCount(TestParsingMergeLite.repeatedExt)).isEqualTo(3); } }
diff --git a/java/core/src/test/java/com/google/protobuf/ParserTest.java b/java/core/src/test/java/com/google/protobuf/ParserTest.java index 983caec..e78c671 100644 --- a/java/core/src/test/java/com/google/protobuf/ParserTest.java +++ b/java/core/src/test/java/com/google/protobuf/ParserTest.java
@@ -30,6 +30,9 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import protobuf_unittest.UnittestOptimizeFor; import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize; import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize; @@ -44,17 +47,18 @@ import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Unit test for {@link Parser}. - * - * @author liujisi@google.com (Pherl Liu) - */ -public class ParserTest extends TestCase { +/** Unit test for {@link Parser}. */ +@RunWith(JUnit4.class) +public class ParserTest { + + @Test public void testGeneratedMessageParserSingleton() throws Exception { for (int i = 0; i < 10; i++) { - assertEquals(TestAllTypes.parser(), TestUtil.getAllSet().getParserForType()); + assertThat(TestUtil.getAllSet().getParserForType()).isEqualTo(TestAllTypes.parser()); } } @@ -95,9 +99,9 @@ private void assertMessageEquals(MessageLite expected, MessageLite actual) throws Exception { if (expected instanceof Message) { - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } else { - assertEquals(expected.toByteString(), actual.toByteString()); + assertThat(actual.toByteString()).isEqualTo(expected.toByteString()); } } @@ -107,11 +111,13 @@ return result; } + @Test public void testNormalMessage() throws Exception { assertRoundTripEquals(TestUtil.getAllSet()); } + @Test public void testParsePartial() throws Exception { assertParsePartial(TestRequired.parser(), TestRequired.newBuilder().setA(1).buildPartial()); } @@ -122,15 +128,16 @@ // parsePartialFrom should pass. byte[] data = partialMessage.toByteArray(); - assertEquals(partialMessage, parser.parsePartialFrom(data)); - assertEquals(partialMessage, parser.parsePartialFrom(partialMessage.toByteString())); - assertEquals(partialMessage, parser.parsePartialFrom(new ByteArrayInputStream(data))); - assertEquals(partialMessage, parser.parsePartialFrom(CodedInputStream.newInstance(data))); + assertThat(parser.parsePartialFrom(data)).isEqualTo(partialMessage); + assertThat(parser.parsePartialFrom(partialMessage.toByteString())).isEqualTo(partialMessage); + assertThat(parser.parsePartialFrom(new ByteArrayInputStream(data))).isEqualTo(partialMessage); + assertThat(parser.parsePartialFrom(CodedInputStream.newInstance(data))) + .isEqualTo(partialMessage); // parseFrom(ByteArray) try { parser.parseFrom(partialMessage.toByteArray()); - fail(errorString); + assertWithMessage(errorString).fail(); } catch (InvalidProtocolBufferException e) { // pass. } @@ -138,7 +145,7 @@ // parseFrom(ByteString) try { parser.parseFrom(partialMessage.toByteString()); - fail(errorString); + assertWithMessage(errorString).fail(); } catch (InvalidProtocolBufferException e) { // pass. } @@ -146,7 +153,7 @@ // parseFrom(InputStream) try { parser.parseFrom(new ByteArrayInputStream(partialMessage.toByteArray())); - fail(errorString); + assertWithMessage(errorString).fail(); } catch (IOException e) { // pass. } @@ -154,21 +161,24 @@ // parseFrom(CodedInputStream) try { parser.parseFrom(CodedInputStream.newInstance(partialMessage.toByteArray())); - fail(errorString); + assertWithMessage(errorString).fail(); } catch (IOException e) { // pass. } } + @Test public void testParseExtensions() throws Exception { assertRoundTripEquals(TestUtil.getAllExtensionsSet(), TestUtil.getExtensionRegistry()); } + @Test public void testParsePacked() throws Exception { assertRoundTripEquals(TestUtil.getPackedSet()); assertRoundTripEquals(TestUtil.getPackedExtensionsSet(), TestUtil.getExtensionRegistry()); } + @Test public void testParseDelimitedTo() throws Exception { // Write normal Message. TestAllTypes normalMessage = TestUtil.getAllSet(); @@ -181,14 +191,16 @@ assertMessageEquals(normalMessage, normalMessage.getParserForType().parseDelimitedFrom(input)); } + @Test public void testParseUnknownFields() throws Exception { // All fields will be treated as unknown fields in emptyMessage. TestEmptyMessage emptyMessage = TestEmptyMessage.parser().parseFrom(TestUtil.getAllSet().toByteString()); - assertEquals(TestUtil.getAllSet().toByteString(), emptyMessage.toByteString()); + assertThat(emptyMessage.toByteString()).isEqualTo(TestUtil.getAllSet().toByteString()); } + @Test public void testOptimizeForSize() throws Exception { TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder(); builder.setI(12).setMsg(ForeignMessage.newBuilder().setC(34).build()); @@ -206,11 +218,12 @@ /** Helper method for {@link #testParsingMerge()}. */ private void assertMessageMerged(TestAllTypes allTypes) throws Exception { - assertEquals(3, allTypes.getOptionalInt32()); - assertEquals(2, allTypes.getOptionalInt64()); - assertEquals("hello", allTypes.getOptionalString()); + assertThat(allTypes.getOptionalInt32()).isEqualTo(3); + assertThat(allTypes.getOptionalInt64()).isEqualTo(2); + assertThat(allTypes.getOptionalString()).isEqualTo("hello"); } + @Test public void testParsingMerge() throws Exception { // Build messages. TestAllTypes.Builder builder = TestAllTypes.newBuilder(); @@ -273,11 +286,12 @@ assertMessageMerged(parsingMerge.getExtension(TestParsingMerge.optionalExt)); // Repeated fields should not be merged. - assertEquals(3, parsingMerge.getRepeatedAllTypesCount()); - assertEquals(3, parsingMerge.getRepeatedGroupCount()); - assertEquals(3, parsingMerge.getExtensionCount(TestParsingMerge.repeatedExt)); + assertThat(parsingMerge.getRepeatedAllTypesCount()).isEqualTo(3); + assertThat(parsingMerge.getRepeatedGroupCount()).isEqualTo(3); + assertThat(parsingMerge.getExtensionCount(TestParsingMerge.repeatedExt)).isEqualTo(3); } + @Test public void testParseDelimitedFrom_firstByteInterrupted_preservesCause() { try { TestAllTypes.parseDelimitedFrom( @@ -287,12 +301,13 @@ throw new InterruptedIOException(); } }); - fail("Expected InterruptedIOException"); + assertWithMessage("Expected InterruptedIOException").fail(); } catch (Exception e) { - assertEquals(InterruptedIOException.class, e.getClass()); + assertThat(e.getClass()).isEqualTo(InterruptedIOException.class); } } + @Test public void testParseDelimitedFrom_secondByteInterrupted_preservesCause() { try { TestAllTypes.parseDelimitedFrom( @@ -311,9 +326,9 @@ } } }); - fail("Expected InterruptedIOException"); + assertWithMessage("Expected InterruptedIOException").fail(); } catch (Exception e) { - assertEquals(InterruptedIOException.class, e.getClass()); + assertThat(e.getClass()).isEqualTo(InterruptedIOException.class); } } }
diff --git a/java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java b/java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java index dfda4b3..07864a9 100644 --- a/java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java +++ b/java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java
@@ -30,9 +30,8 @@ package com.google.protobuf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import com.google.protobuf.testing.Proto2Testing; import com.google.protobuf.testing.Proto2Testing.Proto2Message; @@ -67,14 +66,14 @@ Proto2MessageWithExtensions message = ExperimentalSerializationUtil.fromByteArray( data, Proto2MessageWithExtensions.class, extensionRegistry); - assertEquals(base, message); + assertThat(message).isEqualTo(base); Proto2MessageWithExtensions roundtripMessage = ExperimentalSerializationUtil.fromByteArray( ExperimentalSerializationUtil.toByteArray(message), Proto2MessageWithExtensions.class, extensionRegistry); - assertEquals(base, roundtripMessage); + assertThat(roundtripMessage).isEqualTo(base); } @Test @@ -82,7 +81,7 @@ // Use unknown fields to hold invalid enum values. UnknownFieldSetLite unknowns = UnknownFieldSetLite.newInstance(); final int outOfRange = 1000; - assertNull(TestEnum.forNumber(outOfRange)); + assertThat(TestEnum.forNumber(outOfRange)).isNull(); unknowns.storeField( WireFormat.makeTag(Proto2Message.FIELD_ENUM_13_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT), (long) outOfRange); @@ -125,17 +124,17 @@ Proto2MessageWithExtensions parsed = ExperimentalSerializationUtil.fromByteArray( output, Proto2MessageWithExtensions.class, extensionRegistry); - assertFalse( - "out-of-range singular enum should not be in message", - parsed.hasExtension(Proto2Testing.fieldEnum13)); + assertWithMessage("out-of-range singular enum should not be in message") + .that(parsed.hasExtension(Proto2Testing.fieldEnum13)) + .isFalse(); { List<Long> singularEnum = parsed .getUnknownFields() .getField(Proto2Message.FIELD_ENUM_13_FIELD_NUMBER) .getVarintList(); - assertEquals(1, singularEnum.size()); - assertEquals((Long) (long) outOfRange, singularEnum.get(0)); + assertThat(singularEnum).hasSize(1); + assertThat(singularEnum.get(0)).isEqualTo((Long) (long) outOfRange); } { List<Long> repeatedEnum = @@ -143,8 +142,8 @@ .getUnknownFields() .getField(Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER) .getVarintList(); - assertEquals(1, repeatedEnum.size()); - assertEquals((Long) (long) outOfRange, repeatedEnum.get(0)); + assertThat(repeatedEnum).hasSize(1); + assertThat(repeatedEnum.get(0)).isEqualTo((Long) (long) outOfRange); } { List<Long> packedRepeatedEnum = @@ -152,20 +151,18 @@ .getUnknownFields() .getField(Proto2Message.FIELD_ENUM_LIST_PACKED_44_FIELD_NUMBER) .getVarintList(); - assertEquals(1, packedRepeatedEnum.size()); - assertEquals((Long) (long) outOfRange, packedRepeatedEnum.get(0)); + assertThat(packedRepeatedEnum).hasSize(1); + assertThat(packedRepeatedEnum.get(0)).isEqualTo((Long) (long) outOfRange); } - assertEquals( - "out-of-range repeated enum should not be in message", - 2, - parsed.getExtension(Proto2Testing.fieldEnumList30).size()); - assertEquals(TestEnum.ONE, parsed.getExtension(Proto2Testing.fieldEnumList30, 0)); - assertEquals(TestEnum.TWO, parsed.getExtension(Proto2Testing.fieldEnumList30, 1)); - assertEquals( - "out-of-range packed repeated enum should not be in message", - 2, - parsed.getExtension(Proto2Testing.fieldEnumListPacked44).size()); - assertEquals(TestEnum.ONE, parsed.getExtension(Proto2Testing.fieldEnumListPacked44, 0)); - assertEquals(TestEnum.TWO, parsed.getExtension(Proto2Testing.fieldEnumListPacked44, 1)); + assertWithMessage("out-of-range repeated enum should not be in message") + .that(parsed.getExtension(Proto2Testing.fieldEnumList30).size()) + .isEqualTo(2); + assertThat(parsed.getExtension(Proto2Testing.fieldEnumList30, 0)).isEqualTo(TestEnum.ONE); + assertThat(parsed.getExtension(Proto2Testing.fieldEnumList30, 1)).isEqualTo(TestEnum.TWO); + assertWithMessage("out-of-range packed repeated enum should not be in message") + .that(parsed.getExtension(Proto2Testing.fieldEnumListPacked44).size()) + .isEqualTo(2); + assertThat(parsed.getExtension(Proto2Testing.fieldEnumListPacked44, 0)).isEqualTo(TestEnum.ONE); + assertThat(parsed.getExtension(Proto2Testing.fieldEnumListPacked44, 1)).isEqualTo(TestEnum.TWO); } }
diff --git a/java/core/src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java b/java/core/src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java index 57ac069..d1e4a90 100644 --- a/java/core/src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java +++ b/java/core/src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java
@@ -30,14 +30,19 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import com.google.protobuf.Descriptors.FieldDescriptor; import protobuf_unittest.UnittestProto; import protobuf_unittest.UnittestProto.TestAllExtensions; import protobuf_unittest.UnittestProto.TestAllTypes; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Unit tests for proto2 that treats unknown enum values as unknown fields. */ -public class Proto2UnknownEnumValueTest extends TestCase { +@RunWith(JUnit4.class) +public class Proto2UnknownEnumValueTest { FieldDescriptor singularField = TestAllTypes.getDescriptor().findFieldByName("optional_nested_enum"); FieldDescriptor repeatedField = @@ -64,48 +69,47 @@ return builder.build().toByteArray(); } + @Test public void testUnknownEnumValues() throws Exception { TestAllTypes message = TestAllTypes.parseFrom(payload); // Known enum values should be preserved. - assertEquals(TestAllTypes.NestedEnum.BAR, message.getOptionalNestedEnum()); - assertEquals(2, message.getRepeatedNestedEnumList().size()); - assertEquals(TestAllTypes.NestedEnum.FOO, message.getRepeatedNestedEnum(0)); - assertEquals(TestAllTypes.NestedEnum.BAZ, message.getRepeatedNestedEnum(1)); + assertThat(message.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.BAR); + assertThat(message.getRepeatedNestedEnumList().size()).isEqualTo(2); + assertThat(message.getRepeatedNestedEnum(0)).isEqualTo(TestAllTypes.NestedEnum.FOO); + assertThat(message.getRepeatedNestedEnum(1)).isEqualTo(TestAllTypes.NestedEnum.BAZ); // Unknown enum values should be found in UnknownFieldSet. UnknownFieldSet unknown = message.getUnknownFields(); - assertEquals( - 1901, unknown.getField(singularField.getNumber()).getVarintList().get(0).longValue()); - assertEquals( - 1902, unknown.getField(repeatedField.getNumber()).getVarintList().get(0).longValue()); - assertEquals( - 1903, unknown.getField(repeatedField.getNumber()).getVarintList().get(1).longValue()); + assertThat(unknown.getField(singularField.getNumber()).getVarintList().get(0).longValue()) + .isEqualTo(1901); + assertThat(unknown.getField(repeatedField.getNumber()).getVarintList().get(0).longValue()) + .isEqualTo(1902); + assertThat(unknown.getField(repeatedField.getNumber()).getVarintList().get(1).longValue()) + .isEqualTo(1903); } + @Test public void testExtensionUnknownEnumValues() throws Exception { ExtensionRegistry registry = ExtensionRegistry.newInstance(); UnittestProto.registerAllExtensions(registry); TestAllExtensions message = TestAllExtensions.parseFrom(payload, registry); - assertEquals( - TestAllTypes.NestedEnum.BAR, - message.getExtension(UnittestProto.optionalNestedEnumExtension)); - assertEquals(2, message.getExtension(UnittestProto.repeatedNestedEnumExtension).size()); - assertEquals( - TestAllTypes.NestedEnum.FOO, - message.getExtension(UnittestProto.repeatedNestedEnumExtension, 0)); - assertEquals( - TestAllTypes.NestedEnum.BAZ, - message.getExtension(UnittestProto.repeatedNestedEnumExtension, 1)); + assertThat(message.getExtension(UnittestProto.optionalNestedEnumExtension)) + .isEqualTo(TestAllTypes.NestedEnum.BAR); + assertThat(message.getExtension(UnittestProto.repeatedNestedEnumExtension).size()).isEqualTo(2); + assertThat(message.getExtension(UnittestProto.repeatedNestedEnumExtension, 0)) + .isEqualTo(TestAllTypes.NestedEnum.FOO); + assertThat(message.getExtension(UnittestProto.repeatedNestedEnumExtension, 1)) + .isEqualTo(TestAllTypes.NestedEnum.BAZ); // Unknown enum values should be found in UnknownFieldSet. UnknownFieldSet unknown = message.getUnknownFields(); - assertEquals( - 1901, unknown.getField(singularField.getNumber()).getVarintList().get(0).longValue()); - assertEquals( - 1902, unknown.getField(repeatedField.getNumber()).getVarintList().get(0).longValue()); - assertEquals( - 1903, unknown.getField(repeatedField.getNumber()).getVarintList().get(1).longValue()); + assertThat(unknown.getField(singularField.getNumber()).getVarintList().get(0).longValue()) + .isEqualTo(1901); + assertThat(unknown.getField(repeatedField.getNumber()).getVarintList().get(0).longValue()) + .isEqualTo(1902); + assertThat(unknown.getField(repeatedField.getNumber()).getVarintList().get(1).longValue()) + .isEqualTo(1903); } }
diff --git a/java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java b/java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java index c42813c..18d90fe 100644 --- a/java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java +++ b/java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java
@@ -30,70 +30,77 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import protobuf_unittest.UnittestProto.TestAllTypes; import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; import java.util.Collections; import java.util.List; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Tests for {@link RepeatedFieldBuilderV3}. This tests basic functionality. More extensive testing is * provided via other tests that exercise the builder. - * - * @author jonp@google.com (Jon Perlow) */ -public class RepeatedFieldBuilderV3Test extends TestCase { +@RunWith(JUnit4.class) +public class RepeatedFieldBuilderV3Test { + @Test public void testBasicUse() { TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = newRepeatedFieldBuilderV3(mockParent); builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); - assertEquals(0, builder.getMessage(0).getOptionalInt32()); - assertEquals(1, builder.getMessage(1).getOptionalInt32()); + assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(0); + assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(1); List<TestAllTypes> list = builder.build(); - assertEquals(2, list.size()); - assertEquals(0, list.get(0).getOptionalInt32()); - assertEquals(1, list.get(1).getOptionalInt32()); + assertThat(list).hasSize(2); + assertThat(list.get(0).getOptionalInt32()).isEqualTo(0); + assertThat(list.get(1).getOptionalInt32()).isEqualTo(1); assertIsUnmodifiable(list); // Make sure it doesn't change. List<TestAllTypes> list2 = builder.build(); - assertSame(list, list2); - assertEquals(0, mockParent.getInvalidationCount()); + assertThat(list).isSameInstanceAs(list2); + assertThat(mockParent.getInvalidationCount()).isEqualTo(0); } + @Test public void testGoingBackAndForth() { TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = newRepeatedFieldBuilderV3(mockParent); builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); - assertEquals(0, builder.getMessage(0).getOptionalInt32()); - assertEquals(1, builder.getMessage(1).getOptionalInt32()); + assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(0); + assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(1); // Convert to list List<TestAllTypes> list = builder.build(); - assertEquals(2, list.size()); - assertEquals(0, list.get(0).getOptionalInt32()); - assertEquals(1, list.get(1).getOptionalInt32()); + assertThat(list).hasSize(2); + assertThat(list.get(0).getOptionalInt32()).isEqualTo(0); + assertThat(list.get(1).getOptionalInt32()).isEqualTo(1); assertIsUnmodifiable(list); // Update 0th item - assertEquals(0, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(0); builder.getBuilder(0).setOptionalString("foo"); - assertEquals(1, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(1); list = builder.build(); - assertEquals(2, list.size()); - assertEquals(0, list.get(0).getOptionalInt32()); - assertEquals("foo", list.get(0).getOptionalString()); - assertEquals(1, list.get(1).getOptionalInt32()); + assertThat(list).hasSize(2); + assertThat(list.get(0).getOptionalInt32()).isEqualTo(0); + assertThat(list.get(0).getOptionalString()).isEqualTo("foo"); + assertThat(list.get(1).getOptionalInt32()).isEqualTo(1); assertIsUnmodifiable(list); - assertEquals(1, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(1); } + @Test public void testVariousMethods() { TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = @@ -103,63 +110,64 @@ builder.addBuilder(0, TestAllTypes.getDefaultInstance()).setOptionalInt32(0); builder.addBuilder(TestAllTypes.getDefaultInstance()).setOptionalInt32(3); - assertEquals(0, builder.getMessage(0).getOptionalInt32()); - assertEquals(1, builder.getMessage(1).getOptionalInt32()); - assertEquals(2, builder.getMessage(2).getOptionalInt32()); - assertEquals(3, builder.getMessage(3).getOptionalInt32()); + assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(0); + assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(1); + assertThat(builder.getMessage(2).getOptionalInt32()).isEqualTo(2); + assertThat(builder.getMessage(3).getOptionalInt32()).isEqualTo(3); - assertEquals(0, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(0); List<TestAllTypes> messages = builder.build(); - assertEquals(4, messages.size()); - assertSame(messages, builder.build()); // expect same list + assertThat(messages).hasSize(4); + assertThat(messages).isSameInstanceAs(builder.build()); // expect same list // Remove a message. builder.remove(2); - assertEquals(1, mockParent.getInvalidationCount()); - assertEquals(3, builder.getCount()); - assertEquals(0, builder.getMessage(0).getOptionalInt32()); - assertEquals(1, builder.getMessage(1).getOptionalInt32()); - assertEquals(3, builder.getMessage(2).getOptionalInt32()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(1); + assertThat(builder.getCount()).isEqualTo(3); + assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(0); + assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(1); + assertThat(builder.getMessage(2).getOptionalInt32()).isEqualTo(3); // Remove a builder. builder.remove(0); - assertEquals(1, mockParent.getInvalidationCount()); - assertEquals(2, builder.getCount()); - assertEquals(1, builder.getMessage(0).getOptionalInt32()); - assertEquals(3, builder.getMessage(1).getOptionalInt32()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(1); + assertThat(builder.getCount()).isEqualTo(2); + assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(1); + assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(3); // Test clear. builder.clear(); - assertEquals(1, mockParent.getInvalidationCount()); - assertEquals(0, builder.getCount()); - assertTrue(builder.isEmpty()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(1); + assertThat(builder.getCount()).isEqualTo(0); + assertThat(builder.isEmpty()).isTrue(); } + @Test public void testLists() { TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = newRepeatedFieldBuilderV3(mockParent); builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build()); builder.addMessage(0, TestAllTypes.newBuilder().setOptionalInt32(0).build()); - assertEquals(0, builder.getMessage(0).getOptionalInt32()); - assertEquals(1, builder.getMessage(1).getOptionalInt32()); + assertThat(builder.getMessage(0).getOptionalInt32()).isEqualTo(0); + assertThat(builder.getMessage(1).getOptionalInt32()).isEqualTo(1); // Use list of builders. List<TestAllTypes.Builder> builders = builder.getBuilderList(); - assertEquals(0, builders.get(0).getOptionalInt32()); - assertEquals(1, builders.get(1).getOptionalInt32()); + assertThat(builders.get(0).getOptionalInt32()).isEqualTo(0); + assertThat(builders.get(1).getOptionalInt32()).isEqualTo(1); builders.get(0).setOptionalInt32(10); builders.get(1).setOptionalInt32(11); // Use list of protos List<TestAllTypes> protos = builder.getMessageList(); - assertEquals(10, protos.get(0).getOptionalInt32()); - assertEquals(11, protos.get(1).getOptionalInt32()); + assertThat(protos.get(0).getOptionalInt32()).isEqualTo(10); + assertThat(protos.get(1).getOptionalInt32()).isEqualTo(11); // Add an item to the builders and verify it's updated in both builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(12).build()); - assertEquals(3, builders.size()); - assertEquals(3, protos.size()); + assertThat(builders).hasSize(3); + assertThat(protos).hasSize(3); } private void assertIsUnmodifiable(List<?> list) { @@ -168,7 +176,7 @@ } else { try { list.clear(); - fail("List wasn't immutable"); + assertWithMessage("List wasn't immutable").fail(); } catch (UnsupportedOperationException e) { // good }
diff --git a/java/core/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java b/java/core/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java index d726216..0bfc0be 100644 --- a/java/core/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java +++ b/java/core/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java
@@ -30,19 +30,25 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertWithMessage; + import java.io.UnsupportedEncodingException; import java.util.Iterator; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * This class tests {@link RopeByteString#substring(int, int)} by inheriting the tests from {@link * LiteralByteStringTest}. Only a couple of methods are overridden. - * - * @author carlanton@google.com (Carl Haverl) */ +@RunWith(JUnit4.class) public class RopeByteStringSubstringTest extends LiteralByteStringTest { @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { classUnderTest = "RopeByteString"; byte[] sourceBytes = ByteStringTest.getTestBytes(22341, 22337766L); Iterator<ByteString> iter = ByteStringTest.makeConcretePieces(sourceBytes).iterator(); @@ -60,12 +66,15 @@ } @Override + @Test public void testGetTreeDepth() { - assertEquals( - classUnderTest + " must have the expected tree depth", 3, stringUnderTest.getTreeDepth()); + assertWithMessage("%s must have the expected tree depth", classUnderTest) + .that(stringUnderTest.getTreeDepth()) + .isEqualTo(3); } @Override + @Test public void testToString() throws UnsupportedEncodingException { String sourceString = "I love unicode \u1234\u5678 characters"; ByteString sourceByteString = ByteString.copyFromUtf8(sourceString); @@ -84,21 +93,24 @@ testString = testString.substring(2, testString.length() - 6); unicode = unicode.substring(2, unicode.size() - 6); - assertEquals( - classUnderTest + " from string must have the expected type", - classUnderTest, - getActualClassName(unicode)); + assertWithMessage("%s from string must have the expected type", classUnderTest) + .that(classUnderTest) + .isEqualTo(getActualClassName(unicode)); String roundTripString = unicode.toString(UTF_8); - assertEquals(classUnderTest + " unicode bytes must match", testString, roundTripString); + assertWithMessage("%s unicode bytes must match", classUnderTest) + .that(testString) + .isEqualTo(roundTripString); ByteString flatString = ByteString.copyFromUtf8(testString); - assertEquals(classUnderTest + " string must equal the flat string", flatString, unicode); - assertEquals( - classUnderTest + " string must must have same hashCode as the flat string", - flatString.hashCode(), - unicode.hashCode()); + assertWithMessage("%s string must equal the flat string", classUnderTest) + .that(flatString) + .isEqualTo(unicode); + assertWithMessage("%s string must must have same hashCode as the flat string", classUnderTest) + .that(flatString.hashCode()) + .isEqualTo(unicode.hashCode()); } @Override + @Test public void testCharsetToString() { String sourceString = "I love unicode \u1234\u5678 characters"; ByteString sourceByteString = ByteString.copyFromUtf8(sourceString); @@ -117,17 +129,19 @@ testString = testString.substring(2, testString.length() - 6); unicode = unicode.substring(2, unicode.size() - 6); - assertEquals( - classUnderTest + " from string must have the expected type", - classUnderTest, - getActualClassName(unicode)); + assertWithMessage("%s from string must have the expected type", classUnderTest) + .that(classUnderTest) + .isEqualTo(getActualClassName(unicode)); String roundTripString = unicode.toString(Internal.UTF_8); - assertEquals(classUnderTest + " unicode bytes must match", testString, roundTripString); + assertWithMessage("%s unicode bytes must match", classUnderTest) + .that(testString) + .isEqualTo(roundTripString); ByteString flatString = ByteString.copyFromUtf8(testString); - assertEquals(classUnderTest + " string must equal the flat string", flatString, unicode); - assertEquals( - classUnderTest + " string must must have same hashCode as the flat string", - flatString.hashCode(), - unicode.hashCode()); + assertWithMessage("%s string must equal the flat string", classUnderTest) + .that(flatString) + .isEqualTo(unicode); + assertWithMessage("%s string must must have same hashCode as the flat string", classUnderTest) + .that(flatString.hashCode()) + .isEqualTo(unicode.hashCode()); } }
diff --git a/java/core/src/test/java/com/google/protobuf/RopeByteStringTest.java b/java/core/src/test/java/com/google/protobuf/RopeByteStringTest.java index 46c2d86..bdb8132 100644 --- a/java/core/src/test/java/com/google/protobuf/RopeByteStringTest.java +++ b/java/core/src/test/java/com/google/protobuf/RopeByteStringTest.java
@@ -30,6 +30,9 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -38,6 +41,10 @@ import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.Iterator; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * This class tests {@link RopeByteString} by inheriting the tests from {@link @@ -45,13 +52,13 @@ * * <p>A full test of the result of {@link RopeByteString#substring(int, int)} is found in the * separate class {@link RopeByteStringSubstringTest}. - * - * @author carlanton@google.com (Carl Haverl) */ +@RunWith(JUnit4.class) public class RopeByteStringTest extends LiteralByteStringTest { @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { classUnderTest = "RopeByteString"; referenceBytes = ByteStringTest.getTestBytes(22341, 22337766L); Iterator<ByteString> iter = ByteStringTest.makeConcretePieces(referenceBytes).iterator(); @@ -62,28 +69,32 @@ expectedHashCode = -1214197238; } + @Test public void testMinLength() { // minLength should match the Fibonacci sequence int a = 1; int b = 1; int i; for (i = 0; a > 0; i++) { - assertEquals(a, RopeByteString.minLength(i)); + assertThat(a).isEqualTo(RopeByteString.minLength(i)); int c = a + b; a = b; b = c; } - assertEquals(Integer.MAX_VALUE, RopeByteString.minLength(i)); - assertEquals(Integer.MAX_VALUE, RopeByteString.minLength(i + 1)); - assertEquals(i + 1, RopeByteString.minLengthByDepth.length); + assertThat(RopeByteString.minLength(i)).isEqualTo(Integer.MAX_VALUE); + assertThat(RopeByteString.minLength(i + 1)).isEqualTo(Integer.MAX_VALUE); + assertThat(RopeByteString.minLengthByDepth).hasLength(i + 1); } @Override + @Test public void testGetTreeDepth() { - assertEquals( - classUnderTest + " must have the expected tree depth", 4, stringUnderTest.getTreeDepth()); + assertWithMessage("%s must have the expected tree depth", classUnderTest) + .that(stringUnderTest.getTreeDepth()) + .isEqualTo(4); } + @Test public void testBalance() { int numberOfPieces = 10000; int pieceSize = 64; @@ -95,25 +106,26 @@ concatenated = concatenated.concat(ByteString.copyFrom(testBytes, i * pieceSize, pieceSize)); } - assertEquals( - classUnderTest + " from string must have the expected type", - classUnderTest, - getActualClassName(concatenated)); - assertTrue( - classUnderTest + " underlying bytes must match after balancing", - Arrays.equals(testBytes, concatenated.toByteArray())); + assertWithMessage("%s from string must have the expected type", classUnderTest) + .that(classUnderTest) + .isEqualTo(getActualClassName(concatenated)); + assertWithMessage("%s underlying bytes must match after balancing", classUnderTest) + .that(Arrays.equals(testBytes, concatenated.toByteArray())) + .isTrue(); ByteString testString = ByteString.copyFrom(testBytes); - assertEquals( - classUnderTest + " balanced string must equal flat string", testString, concatenated); - assertEquals( - classUnderTest + " flat string must equal balanced string", concatenated, testString); - assertEquals( - classUnderTest + " balanced string must have same hash code as flat string", - testString.hashCode(), - concatenated.hashCode()); + assertWithMessage("%s balanced string must equal flat string", classUnderTest) + .that(testString) + .isEqualTo(concatenated); + assertWithMessage("%s flat string must equal balanced string", classUnderTest) + .that(concatenated) + .isEqualTo(testString); + assertWithMessage("%s balanced string must have same hash code as flat string", classUnderTest) + .that(testString.hashCode()) + .isEqualTo(concatenated.hashCode()); } @Override + @Test public void testToString() throws UnsupportedEncodingException { String sourceString = "I love unicode \u1234\u5678 characters"; ByteString sourceByteString = ByteString.copyFromUtf8(sourceString); @@ -128,21 +140,24 @@ } String testString = builder.toString(); - assertEquals( - classUnderTest + " from string must have the expected type", - classUnderTest, - getActualClassName(unicode)); + assertWithMessage("%s from string must have the expected type", classUnderTest) + .that(classUnderTest) + .isEqualTo(getActualClassName(unicode)); String roundTripString = unicode.toString(UTF_8); - assertEquals(classUnderTest + " unicode bytes must match", testString, roundTripString); + assertWithMessage("%s unicode bytes must match", classUnderTest) + .that(testString) + .isEqualTo(roundTripString); ByteString flatString = ByteString.copyFromUtf8(testString); - assertEquals(classUnderTest + " string must equal the flat string", flatString, unicode); - assertEquals( - classUnderTest + " string must must have same hashCode as the flat string", - flatString.hashCode(), - unicode.hashCode()); + assertWithMessage("%s string must equal the flat string", classUnderTest) + .that(flatString) + .isEqualTo(unicode); + assertWithMessage("%s string must must have same hashCode as the flat string", classUnderTest) + .that(flatString.hashCode()) + .isEqualTo(unicode.hashCode()); } @Override + @Test public void testCharsetToString() { String sourceString = "I love unicode \u1234\u5678 characters"; ByteString sourceByteString = ByteString.copyFromUtf8(sourceString); @@ -157,36 +172,39 @@ } String testString = builder.toString(); - assertEquals( - classUnderTest + " from string must have the expected type", - classUnderTest, - getActualClassName(unicode)); + assertWithMessage("%s from string must have the expected type", classUnderTest) + .that(classUnderTest) + .isEqualTo(getActualClassName(unicode)); String roundTripString = unicode.toString(Internal.UTF_8); - assertEquals(classUnderTest + " unicode bytes must match", testString, roundTripString); + assertWithMessage("%s unicode bytes must match", classUnderTest) + .that(testString) + .isEqualTo(roundTripString); ByteString flatString = ByteString.copyFromUtf8(testString); - assertEquals(classUnderTest + " string must equal the flat string", flatString, unicode); - assertEquals( - classUnderTest + " string must must have same hashCode as the flat string", - flatString.hashCode(), - unicode.hashCode()); + assertWithMessage("%s string must equal the flat string", classUnderTest) + .that(flatString) + .isEqualTo(unicode); + assertWithMessage("%s string must must have same hashCode as the flat string", classUnderTest) + .that(flatString.hashCode()) + .isEqualTo(unicode.hashCode()); } @Override + @Test public void testToString_returnsCanonicalEmptyString() { RopeByteString ropeByteString = RopeByteString.newInstanceForTest(ByteString.EMPTY, ByteString.EMPTY); - assertSame( - classUnderTest + " must be the same string references", - ByteString.EMPTY.toString(Internal.UTF_8), - ropeByteString.toString(Internal.UTF_8)); + assertWithMessage("%s must be the same string references", classUnderTest) + .that(ByteString.EMPTY.toString(Internal.UTF_8)) + .isSameInstanceAs(ropeByteString.toString(Internal.UTF_8)); } @Override + @Test public void testToString_raisesException() { try { ByteString byteString = RopeByteString.newInstanceForTest(ByteString.EMPTY, ByteString.EMPTY); byteString.toString("invalid"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (UnsupportedEncodingException expected) { // This is success } @@ -196,13 +214,14 @@ RopeByteString.concatenate( ByteString.copyFromUtf8("foo"), ByteString.copyFromUtf8("bar")); byteString.toString("invalid"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (UnsupportedEncodingException expected) { // This is success } } @Override + @Test public void testJavaSerialization() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); @@ -212,7 +231,7 @@ InputStream in = new ByteArrayInputStream(pickled); ObjectInputStream ois = new ObjectInputStream(in); Object o = ois.readObject(); - assertTrue("Didn't get a ByteString back", o instanceof ByteString); - assertEquals("Should get an equal ByteString back", stringUnderTest, o); + assertWithMessage("Didn't get a ByteString back").that(o).isInstanceOf(ByteString.class); + assertWithMessage("Should get an equal ByteString back").that(o).isEqualTo(stringUnderTest); } }
diff --git a/java/core/src/test/java/com/google/protobuf/ServiceTest.java b/java/core/src/test/java/com/google/protobuf/ServiceTest.java index 1592433..8b98661 100644 --- a/java/core/src/test/java/com/google/protobuf/ServiceTest.java +++ b/java/core/src/test/java/com/google/protobuf/ServiceTest.java
@@ -30,6 +30,9 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.MethodDescriptor; import protobuf_unittest.MessageWithNoOuter; @@ -43,17 +46,17 @@ import protobuf_unittest.no_generic_services_test.UnittestNoGenericServices; import java.util.HashSet; import java.util.Set; -import junit.framework.TestCase; import org.easymock.classextension.EasyMock; import org.easymock.IArgumentMatcher; import org.easymock.classextension.IMocksControl; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Tests services and stubs. - * - * @author kenton@google.com Kenton Varda - */ -public class ServiceTest extends TestCase { +/** Tests services and stubs. */ +@RunWith(JUnit4.class) +public class ServiceTest { private IMocksControl control; private RpcController mockController; @@ -62,9 +65,8 @@ private final Descriptors.MethodDescriptor barDescriptor = TestService.getDescriptor().getMethods().get(1); - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { control = EasyMock.createStrictControl(); mockController = control.createMock(RpcController.class); } @@ -72,6 +74,7 @@ // ================================================================= /** Tests Service.callMethod(). */ + @Test public void testCallMethod() throws Exception { FooRequest fooRequest = FooRequest.newBuilder().build(); BarRequest barRequest = BarRequest.newBuilder().build(); @@ -99,16 +102,22 @@ } /** Tests Service.get{Request,Response}Prototype(). */ + @Test public void testGetPrototype() throws Exception { TestService mockService = control.createMock(TestService.class); - assertSame(mockService.getRequestPrototype(fooDescriptor), FooRequest.getDefaultInstance()); - assertSame(mockService.getResponsePrototype(fooDescriptor), FooResponse.getDefaultInstance()); - assertSame(mockService.getRequestPrototype(barDescriptor), BarRequest.getDefaultInstance()); - assertSame(mockService.getResponsePrototype(barDescriptor), BarResponse.getDefaultInstance()); + assertThat(mockService.getRequestPrototype(fooDescriptor)) + .isSameInstanceAs(FooRequest.getDefaultInstance()); + assertThat(mockService.getResponsePrototype(fooDescriptor)) + .isSameInstanceAs(FooResponse.getDefaultInstance()); + assertThat(mockService.getRequestPrototype(barDescriptor)) + .isSameInstanceAs(BarRequest.getDefaultInstance()); + assertThat(mockService.getResponsePrototype(barDescriptor)) + .isSameInstanceAs(BarResponse.getDefaultInstance()); } /** Tests generated stubs. */ + @Test public void testStub() throws Exception { FooRequest fooRequest = FooRequest.newBuilder().build(); BarRequest barRequest = BarRequest.newBuilder().build(); @@ -137,6 +146,7 @@ } /** Tests generated blocking stubs. */ + @Test public void testBlockingStub() throws Exception { FooRequest fooRequest = FooRequest.newBuilder().build(); BarRequest barRequest = BarRequest.newBuilder().build(); @@ -162,11 +172,12 @@ .andReturn(barResponse); control.replay(); - assertSame(fooResponse, stub.foo(mockController, fooRequest)); - assertSame(barResponse, stub.bar(mockController, barRequest)); + assertThat(fooResponse).isSameInstanceAs(stub.foo(mockController, fooRequest)); + assertThat(barResponse).isSameInstanceAs(stub.bar(mockController, barRequest)); control.verify(); } + @Test public void testNewReflectiveService() { ServiceWithNoOuter.Interface impl = control.createMock(ServiceWithNoOuter.Interface.class); RpcController controller = control.createMock(RpcController.class); @@ -179,7 +190,7 @@ @Override public void run(Message parameter) { // No reason this should be run. - fail(); + assertWithMessage("should not run").fail(); } }; RpcCallback<TestAllTypes> specializedCallback = RpcUtil.specializeCallback(callback); @@ -194,6 +205,7 @@ control.verify(); } + @Test public void testNewReflectiveBlockingService() throws ServiceException { ServiceWithNoOuter.BlockingInterface impl = control.createMock(ServiceWithNoOuter.BlockingInterface.class); @@ -210,11 +222,12 @@ control.replay(); Message response = service.callBlockingMethod(fooMethod, controller, request); - assertEquals(expectedResponse, response); + assertThat(response).isEqualTo(expectedResponse); control.verify(); } + @Test public void testNoGenericServices() throws Exception { // Non-services should be usable. UnittestNoGenericServices.TestMessage message = @@ -222,8 +235,8 @@ .setA(123) .setExtension(UnittestNoGenericServices.testExtension, 456) .build(); - assertEquals(123, message.getA()); - assertEquals(1, UnittestNoGenericServices.TestEnum.FOO.getNumber()); + assertThat(message.getA()).isEqualTo(123); + assertThat(UnittestNoGenericServices.TestEnum.FOO.getNumber()).isEqualTo(1); // Build a list of the class names nested in UnittestNoGenericServices. String outerName = @@ -239,7 +252,7 @@ // mentioned in the documentation for java.lang.Class. I don't want to // make assumptions, so I'm just going to accept any character as the // separator. - assertTrue(fullName.startsWith(outerName)); + assertThat(fullName).startsWith(outerName); if (!Service.class.isAssignableFrom(innerClass) && !Message.class.isAssignableFrom(innerClass) @@ -252,16 +265,16 @@ } // No service class should have been generated. - assertTrue(innerClassNames.contains("TestMessage")); - assertTrue(innerClassNames.contains("TestEnum")); - assertFalse(innerClassNames.contains("TestService")); + assertThat(innerClassNames).contains("TestMessage"); + assertThat(innerClassNames).contains("TestEnum"); + assertThat(innerClassNames).doesNotContain("TestService"); // But descriptors are there. FileDescriptor file = UnittestNoGenericServices.getDescriptor(); - assertEquals(1, file.getServices().size()); - assertEquals("TestService", file.getServices().get(0).getName()); - assertEquals(1, file.getServices().get(0).getMethods().size()); - assertEquals("Foo", file.getServices().get(0).getMethods().get(0).getName()); + assertThat(file.getServices()).hasSize(1); + assertThat(file.getServices().get(0).getName()).isEqualTo("TestService"); + assertThat(file.getServices().get(0).getMethods()).hasSize(1); + assertThat(file.getServices().get(0).getMethods().get(0).getName()).isEqualTo("Foo"); } @@ -308,7 +321,7 @@ if (!(actual instanceof RpcCallback)) { return false; } - RpcCallback actualCallback = (RpcCallback) actual; + RpcCallback<?> actualCallback = (RpcCallback<?>) actual; callback.reset(); actualCallback.run(null);
diff --git a/java/core/src/test/java/com/google/protobuf/SingleFieldBuilderV3Test.java b/java/core/src/test/java/com/google/protobuf/SingleFieldBuilderV3Test.java index f2ae8f9..d2215b0 100644 --- a/java/core/src/test/java/com/google/protobuf/SingleFieldBuilderV3Test.java +++ b/java/core/src/test/java/com/google/protobuf/SingleFieldBuilderV3Test.java
@@ -30,100 +30,103 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import protobuf_unittest.UnittestProto.TestAllTypes; import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Tests for {@link SingleFieldBuilderV3}. This tests basic functionality. More extensive testing is * provided via other tests that exercise the builder. - * - * @author jonp@google.com (Jon Perlow) */ -public class SingleFieldBuilderV3Test extends TestCase { +@RunWith(JUnit4.class) +public class SingleFieldBuilderV3Test { + @Test public void testBasicUseAndInvalidations() { TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = - new SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder>( - TestAllTypes.getDefaultInstance(), mockParent, false); - assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); - assertEquals(TestAllTypes.getDefaultInstance(), builder.getBuilder().buildPartial()); - assertEquals(0, mockParent.getInvalidationCount()); + new SingleFieldBuilderV3<>(TestAllTypes.getDefaultInstance(), mockParent, false); + assertThat(builder.getMessage()).isSameInstanceAs(TestAllTypes.getDefaultInstance()); + assertThat(builder.getBuilder().buildPartial()).isEqualTo(TestAllTypes.getDefaultInstance()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(0); builder.getBuilder().setOptionalInt32(10); - assertEquals(0, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(0); TestAllTypes message = builder.build(); - assertEquals(10, message.getOptionalInt32()); + assertThat(message.getOptionalInt32()).isEqualTo(10); // Test that we receive invalidations now that build has been called. - assertEquals(0, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(0); builder.getBuilder().setOptionalInt32(20); - assertEquals(1, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(1); // Test that we don't keep getting invalidations on every change builder.getBuilder().setOptionalInt32(30); - assertEquals(1, mockParent.getInvalidationCount()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(1); } + @Test public void testSetMessage() { TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = - new SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder>( - TestAllTypes.getDefaultInstance(), mockParent, false); + new SingleFieldBuilderV3<>(TestAllTypes.getDefaultInstance(), mockParent, false); builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); - assertEquals(0, builder.getMessage().getOptionalInt32()); + assertThat(builder.getMessage().getOptionalInt32()).isEqualTo(0); // Update message using the builder builder.getBuilder().setOptionalInt32(1); - assertEquals(0, mockParent.getInvalidationCount()); - assertEquals(1, builder.getBuilder().getOptionalInt32()); - assertEquals(1, builder.getMessage().getOptionalInt32()); + assertThat(mockParent.getInvalidationCount()).isEqualTo(0); + assertThat(builder.getBuilder().getOptionalInt32()).isEqualTo(1); + assertThat(builder.getMessage().getOptionalInt32()).isEqualTo(1); builder.build(); builder.getBuilder().setOptionalInt32(2); - assertEquals(2, builder.getBuilder().getOptionalInt32()); - assertEquals(2, builder.getMessage().getOptionalInt32()); + assertThat(builder.getBuilder().getOptionalInt32()).isEqualTo(2); + assertThat(builder.getMessage().getOptionalInt32()).isEqualTo(2); // Make sure message stays cached - assertSame(builder.getMessage(), builder.getMessage()); + assertThat(builder.getMessage()).isSameInstanceAs(builder.getMessage()); } + @Test public void testClear() { TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = - new SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder>( - TestAllTypes.getDefaultInstance(), mockParent, false); + new SingleFieldBuilderV3<>(TestAllTypes.getDefaultInstance(), mockParent, false); builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build()); - assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + assertThat(TestAllTypes.getDefaultInstance()).isNotSameInstanceAs(builder.getMessage()); builder.clear(); - assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + assertThat(builder.getMessage()).isSameInstanceAs(TestAllTypes.getDefaultInstance()); builder.getBuilder().setOptionalInt32(1); - assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + assertThat(TestAllTypes.getDefaultInstance()).isNotSameInstanceAs(builder.getMessage()); builder.clear(); - assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + assertThat(builder.getMessage()).isSameInstanceAs(TestAllTypes.getDefaultInstance()); } + @Test public void testMerge() { TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent(); SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder> builder = - new SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder, TestAllTypesOrBuilder>( - TestAllTypes.getDefaultInstance(), mockParent, false); + new SingleFieldBuilderV3<>(TestAllTypes.getDefaultInstance(), mockParent, false); // Merge into default field. builder.mergeFrom(TestAllTypes.getDefaultInstance()); - assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage()); + assertThat(builder.getMessage()).isSameInstanceAs(TestAllTypes.getDefaultInstance()); // Merge into non-default field on existing builder. builder.getBuilder().setOptionalInt32(2); builder.mergeFrom(TestAllTypes.newBuilder().setOptionalDouble(4.0).buildPartial()); - assertEquals(2, builder.getMessage().getOptionalInt32()); - assertEquals(4.0, builder.getMessage().getOptionalDouble(), 0.0); + assertThat(builder.getMessage().getOptionalInt32()).isEqualTo(2); + assertThat(builder.getMessage().getOptionalDouble()).isEqualTo(4.0); // Merge into non-default field on existing message builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(10).buildPartial()); builder.mergeFrom(TestAllTypes.newBuilder().setOptionalDouble(5.0).buildPartial()); - assertEquals(10, builder.getMessage().getOptionalInt32()); - assertEquals(5.0, builder.getMessage().getOptionalDouble(), 0.0); + assertThat(builder.getMessage().getOptionalInt32()).isEqualTo(10); + assertThat(builder.getMessage().getOptionalDouble()).isEqualTo(5.0); } }
diff --git a/java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java b/java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java index a1a7194..fdeccc2 100644 --- a/java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java +++ b/java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java
@@ -30,6 +30,10 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static java.lang.Math.min; + import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -38,10 +42,12 @@ import java.util.Map; import java.util.Set; import java.util.TreeSet; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** @author darick@google.com Darick Tong */ -public class SmallSortedMapTest extends TestCase { +@RunWith(JUnit4.class) +public class SmallSortedMapTest { // java.util.AbstractMap.SimpleEntry is private in JDK 1.5. We re-implement it // here for JDK 1.5 users. private static class SimpleEntry<K, V> implements Map.Entry<K, V> { @@ -79,7 +85,7 @@ if (!(o instanceof Map.Entry)) { return false; } - Map.Entry e = (Map.Entry) o; + Map.Entry<?, ?> e = (Map.Entry<?, ?>) o; return eq(key, e.getKey()) && eq(value, e.getValue()); } @@ -89,10 +95,12 @@ } } + @Test public void testPutAndGetArrayEntriesOnly() { runPutAndGetTest(3); } + @Test public void testPutAndGetOverflowEntries() { runPutAndGetTest(6); } @@ -106,214 +114,224 @@ // Test with puts in ascending order. for (int i = 0; i < numElements; i++) { - assertNull(map1.put(i, i + 1)); - assertNull(map2.put(i, i + 1)); + assertThat(map1.put(i, i + 1)).isNull(); + assertThat(map2.put(i, i + 1)).isNull(); } // Test with puts in descending order. for (int i = numElements - 1; i >= 0; i--) { - assertNull(map3.put(i, i + 1)); - assertNull(map4.put(i, i + 1)); + assertThat(map3.put(i, i + 1)).isNull(); + assertThat(map4.put(i, i + 1)).isNull(); } - assertEquals(Math.min(3, numElements), map1.getNumArrayEntries()); - assertEquals(Math.min(4, numElements), map2.getNumArrayEntries()); - assertEquals(Math.min(3, numElements), map3.getNumArrayEntries()); - assertEquals(Math.min(4, numElements), map4.getNumArrayEntries()); + assertThat(map1.getNumArrayEntries()).isEqualTo(min(3, numElements)); + assertThat(map2.getNumArrayEntries()).isEqualTo(min(4, numElements)); + assertThat(map3.getNumArrayEntries()).isEqualTo(min(3, numElements)); + assertThat(map4.getNumArrayEntries()).isEqualTo(min(4, numElements)); - List<SmallSortedMap<Integer, Integer>> allMaps = - new ArrayList<SmallSortedMap<Integer, Integer>>(); + List<SmallSortedMap<Integer, Integer>> allMaps = new ArrayList<>(); allMaps.add(map1); allMaps.add(map2); allMaps.add(map3); allMaps.add(map4); for (SmallSortedMap<Integer, Integer> map : allMaps) { - assertEquals(numElements, map.size()); + assertThat(map).hasSize(numElements); for (int i = 0; i < numElements; i++) { - assertEquals(Integer.valueOf(i + 1), map.get(i)); + assertThat(map).containsEntry(i, Integer.valueOf(i + 1)); } } - assertEquals(map1, map2); - assertEquals(map2, map3); - assertEquals(map3, map4); + assertThat(map1).isEqualTo(map2); + assertThat(map2).isEqualTo(map3); + assertThat(map3).isEqualTo(map4); } + @Test public void testReplacingPut() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); for (int i = 0; i < 6; i++) { - assertNull(map.put(i, i + 1)); - assertNull(map.remove(i + 1)); + assertThat(map.put(i, i + 1)).isNull(); + assertThat(map.remove(i + 1)).isNull(); } for (int i = 0; i < 6; i++) { - assertEquals(Integer.valueOf(i + 1), map.put(i, i + 2)); + assertThat(map.put(i, i + 2)).isEqualTo(Integer.valueOf(i + 1)); } } + @Test public void testRemove() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); for (int i = 0; i < 6; i++) { - assertNull(map.put(i, i + 1)); - assertNull(map.remove(i + 1)); + assertThat(map.put(i, i + 1)).isNull(); + assertThat(map.remove(i + 1)).isNull(); } - assertEquals(3, map.getNumArrayEntries()); - assertEquals(3, map.getNumOverflowEntries()); - assertEquals(6, map.size()); - assertEquals(makeSortedKeySet(0, 1, 2, 3, 4, 5), map.keySet()); + assertThat(map.getNumArrayEntries()).isEqualTo(3); + assertThat(map.getNumOverflowEntries()).isEqualTo(3); + assertThat(map).hasSize(6); + assertThat(map.keySet()).isEqualTo(makeSortedKeySet(0, 1, 2, 3, 4, 5)); - assertEquals(Integer.valueOf(2), map.remove(1)); - assertEquals(3, map.getNumArrayEntries()); - assertEquals(2, map.getNumOverflowEntries()); - assertEquals(5, map.size()); - assertEquals(makeSortedKeySet(0, 2, 3, 4, 5), map.keySet()); + assertThat(map.remove(1)).isEqualTo(Integer.valueOf(2)); + assertThat(map.getNumArrayEntries()).isEqualTo(3); + assertThat(map.getNumOverflowEntries()).isEqualTo(2); + assertThat(map).hasSize(5); + assertThat(map.keySet()).isEqualTo(makeSortedKeySet(0, 2, 3, 4, 5)); - assertEquals(Integer.valueOf(5), map.remove(4)); - assertEquals(3, map.getNumArrayEntries()); - assertEquals(1, map.getNumOverflowEntries()); - assertEquals(4, map.size()); - assertEquals(makeSortedKeySet(0, 2, 3, 5), map.keySet()); + assertThat(map.remove(4)).isEqualTo(Integer.valueOf(5)); + assertThat(map.getNumArrayEntries()).isEqualTo(3); + assertThat(map.getNumOverflowEntries()).isEqualTo(1); + assertThat(map).hasSize(4); + assertThat(map.keySet()).isEqualTo(makeSortedKeySet(0, 2, 3, 5)); - assertEquals(Integer.valueOf(4), map.remove(3)); - assertEquals(3, map.getNumArrayEntries()); - assertEquals(0, map.getNumOverflowEntries()); - assertEquals(3, map.size()); - assertEquals(makeSortedKeySet(0, 2, 5), map.keySet()); + assertThat(map.remove(3)).isEqualTo(Integer.valueOf(4)); + assertThat(map.getNumArrayEntries()).isEqualTo(3); + assertThat(map.getNumOverflowEntries()).isEqualTo(0); + assertThat(map).hasSize(3); + assertThat(map.keySet()).isEqualTo(makeSortedKeySet(0, 2, 5)); - assertNull(map.remove(3)); - assertEquals(3, map.getNumArrayEntries()); - assertEquals(0, map.getNumOverflowEntries()); - assertEquals(3, map.size()); + assertThat(map.remove(3)).isNull(); + assertThat(map.getNumArrayEntries()).isEqualTo(3); + assertThat(map.getNumOverflowEntries()).isEqualTo(0); + assertThat(map).hasSize(3); - assertEquals(Integer.valueOf(1), map.remove(0)); - assertEquals(2, map.getNumArrayEntries()); - assertEquals(0, map.getNumOverflowEntries()); - assertEquals(2, map.size()); + assertThat(map.remove(0)).isEqualTo(Integer.valueOf(1)); + assertThat(map.getNumArrayEntries()).isEqualTo(2); + assertThat(map.getNumOverflowEntries()).isEqualTo(0); + assertThat(map).hasSize(2); } + @Test public void testClear() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); for (int i = 0; i < 6; i++) { - assertNull(map.put(i, i + 1)); + assertThat(map.put(i, i + 1)).isNull(); } map.clear(); - assertEquals(0, map.getNumArrayEntries()); - assertEquals(0, map.getNumOverflowEntries()); - assertEquals(0, map.size()); + assertThat(map.getNumArrayEntries()).isEqualTo(0); + assertThat(map.getNumOverflowEntries()).isEqualTo(0); + assertThat(map).isEmpty(); } + @Test public void testGetArrayEntryAndOverflowEntries() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); for (int i = 0; i < 6; i++) { - assertNull(map.put(i, i + 1)); + assertThat(map.put(i, i + 1)).isNull(); } - assertEquals(3, map.getNumArrayEntries()); + assertThat(map.getNumArrayEntries()).isEqualTo(3); for (int i = 0; i < 3; i++) { Map.Entry<Integer, Integer> entry = map.getArrayEntryAt(i); - assertEquals(Integer.valueOf(i), entry.getKey()); - assertEquals(Integer.valueOf(i + 1), entry.getValue()); + assertThat(entry.getKey()).isEqualTo(Integer.valueOf(i)); + assertThat(entry.getValue()).isEqualTo(Integer.valueOf(i + 1)); } Iterator<Map.Entry<Integer, Integer>> it = map.getOverflowEntries().iterator(); for (int i = 3; i < 6; i++) { - assertTrue(it.hasNext()); + assertThat(it.hasNext()).isTrue(); Map.Entry<Integer, Integer> entry = it.next(); - assertEquals(Integer.valueOf(i), entry.getKey()); - assertEquals(Integer.valueOf(i + 1), entry.getValue()); + assertThat(entry.getKey()).isEqualTo(Integer.valueOf(i)); + assertThat(entry.getValue()).isEqualTo(Integer.valueOf(i + 1)); } - assertFalse(it.hasNext()); + assertThat(it.hasNext()).isFalse(); } + @Test public void testEntrySetContains() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); for (int i = 0; i < 6; i++) { - assertNull(map.put(i, i + 1)); + assertThat(map.put(i, i + 1)).isNull(); } Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet(); for (int i = 0; i < 6; i++) { - assertTrue(entrySet.contains(new SimpleEntry<Integer, Integer>(i, i + 1))); - assertFalse(entrySet.contains(new SimpleEntry<Integer, Integer>(i, i))); + assertThat(entrySet).contains(new SimpleEntry<Integer, Integer>(i, i + 1)); + assertThat(entrySet).doesNotContain(new SimpleEntry<Integer, Integer>(i, i)); } } + @Test public void testEntrySetAdd() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet(); for (int i = 0; i < 6; i++) { - Map.Entry<Integer, Integer> entry = new SimpleEntry<Integer, Integer>(i, i + 1); - assertTrue(entrySet.add(entry)); - assertFalse(entrySet.add(entry)); + Map.Entry<Integer, Integer> entry = new SimpleEntry<>(i, i + 1); + assertThat(entrySet.add(entry)).isTrue(); + assertThat(entrySet.add(entry)).isFalse(); } for (int i = 0; i < 6; i++) { - assertEquals(Integer.valueOf(i + 1), map.get(i)); + assertThat(map).containsEntry(i, Integer.valueOf(i + 1)); } - assertEquals(3, map.getNumArrayEntries()); - assertEquals(3, map.getNumOverflowEntries()); - assertEquals(6, map.size()); + assertThat(map.getNumArrayEntries()).isEqualTo(3); + assertThat(map.getNumOverflowEntries()).isEqualTo(3); + assertThat(map).hasSize(6); } + @Test public void testEntrySetRemove() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet(); for (int i = 0; i < 6; i++) { - assertNull(map.put(i, i + 1)); + assertThat(map.put(i, i + 1)).isNull(); } for (int i = 0; i < 6; i++) { - Map.Entry<Integer, Integer> entry = new SimpleEntry<Integer, Integer>(i, i + 1); - assertTrue(entrySet.remove(entry)); - assertFalse(entrySet.remove(entry)); + Map.Entry<Integer, Integer> entry = new SimpleEntry<>(i, i + 1); + assertThat(entrySet.remove(entry)).isTrue(); + assertThat(entrySet.remove(entry)).isFalse(); } - assertTrue(map.isEmpty()); - assertEquals(0, map.getNumArrayEntries()); - assertEquals(0, map.getNumOverflowEntries()); - assertEquals(0, map.size()); + assertThat(map).isEmpty(); + assertThat(map.getNumArrayEntries()).isEqualTo(0); + assertThat(map.getNumOverflowEntries()).isEqualTo(0); + assertThat(map).isEmpty(); } + @Test public void testEntrySetClear() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); for (int i = 0; i < 6; i++) { - assertNull(map.put(i, i + 1)); + assertThat(map.put(i, i + 1)).isNull(); } map.clear(); - assertTrue(map.isEmpty()); - assertEquals(0, map.getNumArrayEntries()); - assertEquals(0, map.getNumOverflowEntries()); - assertEquals(0, map.size()); + assertThat(map).isEmpty(); + assertThat(map.getNumArrayEntries()).isEqualTo(0); + assertThat(map.getNumOverflowEntries()).isEqualTo(0); + assertThat(map).isEmpty(); } + @Test public void testEntrySetIteratorNext() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); for (int i = 0; i < 6; i++) { - assertNull(map.put(i, i + 1)); + assertThat(map.put(i, i + 1)).isNull(); } Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator(); for (int i = 0; i < 6; i++) { - assertTrue(it.hasNext()); + assertThat(it.hasNext()).isTrue(); Map.Entry<Integer, Integer> entry = it.next(); - assertEquals(Integer.valueOf(i), entry.getKey()); - assertEquals(Integer.valueOf(i + 1), entry.getValue()); + assertThat(entry.getKey()).isEqualTo(Integer.valueOf(i)); + assertThat(entry.getValue()).isEqualTo(Integer.valueOf(i + 1)); } - assertFalse(it.hasNext()); + assertThat(it.hasNext()).isFalse(); } + @Test public void testEntrySetIteratorRemove() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); for (int i = 0; i < 6; i++) { - assertNull(map.put(i, i + 1)); + assertThat(map.put(i, i + 1)).isNull(); } Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator(); for (int i = 0; i < 6; i++) { - assertTrue(map.containsKey(i)); + assertThat(map).containsKey(i); it.next(); it.remove(); - assertFalse(map.containsKey(i)); - assertEquals(6 - i - 1, map.size()); + assertThat(map).doesNotContainKey(i); + assertThat(map).hasSize(6 - i - 1); } } + @Test public void testMapEntryModification() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); for (int i = 0; i < 6; i++) { - assertNull(map.put(i, i + 1)); + assertThat(map.put(i, i + 1)).isNull(); } Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator(); for (int i = 0; i < 6; i++) { @@ -321,49 +339,50 @@ entry.setValue(i + 23); } for (int i = 0; i < 6; i++) { - assertEquals(Integer.valueOf(i + 23), map.get(i)); + assertThat(map).containsEntry(i, Integer.valueOf(i + 23)); } } + @Test public void testMakeImmutable() { SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3); for (int i = 0; i < 6; i++) { - assertNull(map.put(i, i + 1)); + assertThat(map.put(i, i + 1)).isNull(); } map.makeImmutable(); - assertEquals(Integer.valueOf(1), map.get(0)); - assertEquals(6, map.size()); + assertThat(map).containsEntry(0, Integer.valueOf(1)); + assertThat(map).hasSize(6); try { map.put(23, 23); - fail("Expected UnsupportedOperationException"); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException expected) { } - Map<Integer, Integer> other = new HashMap<Integer, Integer>(); + Map<Integer, Integer> other = new HashMap<>(); other.put(23, 23); try { map.putAll(other); - fail("Expected UnsupportedOperationException"); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException expected) { } try { map.remove(0); - fail("Expected UnsupportedOperationException"); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException expected) { } try { map.clear(); - fail("Expected UnsupportedOperationException"); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException expected) { } Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet(); try { entrySet.clear(); - fail("Expected UnsupportedOperationException"); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException expected) { } @@ -372,12 +391,12 @@ Map.Entry<Integer, Integer> entry = it.next(); try { entry.setValue(0); - fail("Expected UnsupportedOperationException"); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException expected) { } try { it.remove(); - fail("Expected UnsupportedOperationException"); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException expected) { } } @@ -385,7 +404,7 @@ Set<Integer> keySet = map.keySet(); try { keySet.clear(); - fail("Expected UnsupportedOperationException"); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException expected) { } @@ -394,18 +413,18 @@ Integer key = keys.next(); try { keySet.remove(key); - fail("Expected UnsupportedOperationException"); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException expected) { } try { keys.remove(); - fail("Expected UnsupportedOperationException"); + assertWithMessage("Expected UnsupportedOperationException").fail(); } catch (UnsupportedOperationException expected) { } } } private Set<Integer> makeSortedKeySet(Integer... keys) { - return new TreeSet<Integer>(Arrays.<Integer>asList(keys)); + return new TreeSet<>(Arrays.<Integer>asList(keys)); } }
diff --git a/java/core/src/test/java/com/google/protobuf/TestBadIdentifiersLite.java b/java/core/src/test/java/com/google/protobuf/TestBadIdentifiersLite.java index 523e23a..ab32e2a 100644 --- a/java/core/src/test/java/com/google/protobuf/TestBadIdentifiersLite.java +++ b/java/core/src/test/java/com/google/protobuf/TestBadIdentifiersLite.java
@@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import junit.framework.TestCase; /** @@ -55,37 +57,37 @@ TestBadIdentifiersProto.TestConflictingFieldNames message = TestBadIdentifiersProto.TestConflictingFieldNames.getDefaultInstance(); // Make sure generated accessors are properly named. - assertEquals(0, message.getInt32Field1Count()); - assertEquals(0, message.getEnumField2Count()); - assertEquals(0, message.getStringField3Count()); - assertEquals(0, message.getBytesField4Count()); - assertEquals(0, message.getMessageField5Count()); + assertThat(message.getInt32Field1Count()).isEqualTo(0); + assertThat(message.getEnumField2Count()).isEqualTo(0); + assertThat(message.getStringField3Count()).isEqualTo(0); + assertThat(message.getBytesField4Count()).isEqualTo(0); + assertThat(message.getMessageField5Count()).isEqualTo(0); - assertEquals(0, message.getInt32FieldCount11()); - assertEquals(0, message.getEnumFieldCount12().getNumber()); - assertEquals("", message.getStringFieldCount13()); - assertEquals(ByteString.EMPTY, message.getBytesFieldCount14()); - assertEquals(0, message.getMessageFieldCount15().getSerializedSize()); + assertThat(message.getInt32FieldCount11()).isEqualTo(0); + assertThat(message.getEnumFieldCount12().getNumber()).isEqualTo(0); + assertThat(message.getStringFieldCount13()).isEmpty(); + assertThat(message.getBytesFieldCount14()).isEqualTo(ByteString.EMPTY); + assertThat(message.getMessageFieldCount15().getSerializedSize()).isEqualTo(0); - assertEquals(0, message.getInt32Field21Count()); - assertEquals(0, message.getEnumField22Count()); - assertEquals(0, message.getStringField23Count()); - assertEquals(0, message.getBytesField24Count()); - assertEquals(0, message.getMessageField25Count()); + assertThat(message.getInt32Field21Count()).isEqualTo(0); + assertThat(message.getEnumField22Count()).isEqualTo(0); + assertThat(message.getStringField23Count()).isEqualTo(0); + assertThat(message.getBytesField24Count()).isEqualTo(0); + assertThat(message.getMessageField25Count()).isEqualTo(0); - assertEquals(0, message.getInt32Field1List().size()); - assertEquals(0, message.getInt32FieldList31()); + assertThat(message.getInt32Field1List()).isEmpty(); + assertThat(message.getInt32FieldList31()).isEqualTo(0); - assertEquals(0, message.getInt64FieldCount()); - assertEquals( - 0L, - message - .getExtension(TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldCount) - .longValue()); - assertEquals( - 0L, - message - .getExtension(TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldList) - .longValue()); + assertThat(message.getInt64FieldCount()).isEqualTo(0); + assertThat( + message + .getExtension(TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldCount) + .longValue()) + .isEqualTo(0L); + assertThat( + message + .getExtension(TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldList) + .longValue()) + .isEqualTo(0L); } }
diff --git a/java/core/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java index 6c1021f..936a525 100644 --- a/java/core/src/test/java/com/google/protobuf/TestUtil.java +++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java
@@ -3770,7 +3770,7 @@ } catch (IOException e) { throw new RuntimeException("Couldn't get canonical name of working directory.", e); } - + String srcRootCheck = "src/google/protobuf"; // If we're running w/ Bazel on Windows, we're not in a sandbox, so we @@ -3779,6 +3779,7 @@ if (testBinaryName != null && testBinaryName.endsWith(".exe")) { srcRootCheck = srcRootCheck + "/descriptor.cc"; } + while (ancestor != null && ancestor.exists()) { // Identify the true source root. if (new File(ancestor, srcRootCheck).exists()) {
diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java index ff41372..5d0eb62 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java
@@ -30,13 +30,20 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import protobuf_unittest.UnittestProto.TestAllTypes; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Test @{link TextFormatParseInfoTree}. */ -public class TextFormatParseInfoTreeTest extends TestCase { +@RunWith(JUnit4.class) +public class TextFormatParseInfoTreeTest { private static final Descriptor DESCRIPTOR = TestAllTypes.getDescriptor(); private static final FieldDescriptor OPTIONAL_INT32 = @@ -57,110 +64,121 @@ private TextFormatParseInfoTree.Builder rootBuilder; - @Override + @Before public void setUp() { rootBuilder = TextFormatParseInfoTree.builder(); } + @Test public void testBuildEmptyParseTree() { TextFormatParseInfoTree tree = rootBuilder.build(); - assertTrue(tree.getLocations(null).isEmpty()); + assertThat(tree.getLocations(null)).isEmpty(); } + @Test public void testGetLocationReturnsSingleLocation() { rootBuilder.setLocation(OPTIONAL_INT32, LOC0); TextFormatParseInfoTree root = rootBuilder.build(); - assertEquals(LOC0, root.getLocation(OPTIONAL_INT32, 0)); - assertEquals(1, root.getLocations(OPTIONAL_INT32).size()); + assertThat(root.getLocation(OPTIONAL_INT32, 0)).isEqualTo(LOC0); + assertThat(root.getLocations(OPTIONAL_INT32)).hasSize(1); } + @Test public void testGetLocationsReturnsNoParseLocationsForUnknownField() { - assertTrue(rootBuilder.build().getLocations(OPTIONAL_INT32).isEmpty()); + assertThat(rootBuilder.build().getLocations(OPTIONAL_INT32)).isEmpty(); rootBuilder.setLocation(OPTIONAL_BOOLEAN, LOC0); TextFormatParseInfoTree root = rootBuilder.build(); - assertTrue(root.getLocations(OPTIONAL_INT32).isEmpty()); - assertEquals(LOC0, root.getLocations(OPTIONAL_BOOLEAN).get(0)); + assertThat(root.getLocations(OPTIONAL_INT32)).isEmpty(); + assertThat(root.getLocations(OPTIONAL_BOOLEAN).get(0)).isEqualTo(LOC0); } + @Test public void testGetLocationThrowsIllegalArgumentExceptionForUnknownField() { rootBuilder.setLocation(REPEATED_INT32, LOC0); TextFormatParseInfoTree root = rootBuilder.build(); try { root.getNestedTree(OPTIONAL_INT32, 0); - fail("Did not detect unknown field"); + assertWithMessage("Did not detect unknown field").fail(); } catch (IllegalArgumentException expected) { // pass } } + @Test public void testGetLocationThrowsIllegalArgumentExceptionForInvalidIndex() { TextFormatParseInfoTree root = rootBuilder.setLocation(OPTIONAL_INT32, LOC0).build(); try { root.getLocation(OPTIONAL_INT32, 1); - fail("Invalid index not detected"); + assertWithMessage("Invalid index not detected").fail(); } catch (IllegalArgumentException expected) { // pass } try { root.getLocation(OPTIONAL_INT32, -1); - fail("Negative index not detected"); + assertWithMessage("Negative index not detected").fail(); } catch (IllegalArgumentException expected) { // pass } } + @Test public void testGetLocationsReturnsMultipleLocations() { rootBuilder.setLocation(REPEATED_INT32, LOC0); rootBuilder.setLocation(REPEATED_INT32, LOC1); TextFormatParseInfoTree root = rootBuilder.build(); - assertEquals(LOC0, root.getLocation(REPEATED_INT32, 0)); - assertEquals(LOC1, root.getLocation(REPEATED_INT32, 1)); - assertEquals(2, root.getLocations(REPEATED_INT32).size()); + assertThat(root.getLocation(REPEATED_INT32, 0)).isEqualTo(LOC0); + assertThat(root.getLocation(REPEATED_INT32, 1)).isEqualTo(LOC1); + assertThat(root.getLocations(REPEATED_INT32)).hasSize(2); } + @Test public void testGetNestedTreeThrowsIllegalArgumentExceptionForUnknownField() { rootBuilder.setLocation(REPEATED_INT32, LOC0); TextFormatParseInfoTree root = rootBuilder.build(); try { root.getNestedTree(OPTIONAL_NESTED_MESSAGE, 0); - fail("Did not detect unknown field"); + assertWithMessage("Did not detect unknown field").fail(); } catch (IllegalArgumentException expected) { // pass } } + @Test public void testGetNestedTreesReturnsNoParseInfoTreesForUnknownField() { rootBuilder.setLocation(REPEATED_INT32, LOC0); TextFormatParseInfoTree root = rootBuilder.build(); - assertTrue(root.getNestedTrees(OPTIONAL_NESTED_MESSAGE).isEmpty()); + assertThat(root.getNestedTrees(OPTIONAL_NESTED_MESSAGE)).isEmpty(); } + @Test public void testGetNestedTreeThrowsIllegalArgumentExceptionForInvalidIndex() { rootBuilder.setLocation(REPEATED_INT32, LOC0); rootBuilder.getBuilderForSubMessageField(OPTIONAL_NESTED_MESSAGE); TextFormatParseInfoTree root = rootBuilder.build(); try { root.getNestedTree(OPTIONAL_NESTED_MESSAGE, 1); - fail("Submessage index that is too large not detected"); + assertWithMessage("Submessage index that is too large not detected").fail(); } catch (IllegalArgumentException expected) { // pass } try { rootBuilder.build().getNestedTree(OPTIONAL_NESTED_MESSAGE, -1); - fail("Invalid submessage index (-1) not detected"); + assertWithMessage("Invalid submessage index (-1) not detected").fail(); } catch (IllegalArgumentException expected) { // pass } } + @Test public void testGetNestedTreesReturnsSingleTree() { rootBuilder.getBuilderForSubMessageField(OPTIONAL_NESTED_MESSAGE); TextFormatParseInfoTree root = rootBuilder.build(); - assertEquals(1, root.getNestedTrees(OPTIONAL_NESTED_MESSAGE).size()); + assertThat(root.getNestedTrees(OPTIONAL_NESTED_MESSAGE)).hasSize(1); TextFormatParseInfoTree subtree = root.getNestedTrees(OPTIONAL_NESTED_MESSAGE).get(0); - assertNotNull(subtree); + assertThat(subtree).isNotNull(); } + @Test public void testGetNestedTreesReturnsMultipleTrees() { TextFormatParseInfoTree.Builder subtree1Builder = rootBuilder.getBuilderForSubMessageField(REPEATED_NESTED_MESSAGE); @@ -170,10 +188,10 @@ rootBuilder.getBuilderForSubMessageField(REPEATED_NESTED_MESSAGE); subtree2Builder.getBuilderForSubMessageField(FIELD_BB); TextFormatParseInfoTree root = rootBuilder.build(); - assertEquals(2, root.getNestedTrees(REPEATED_NESTED_MESSAGE).size()); - assertEquals( - 2, root.getNestedTrees(REPEATED_NESTED_MESSAGE).get(0).getNestedTrees(FIELD_BB).size()); - assertEquals( - 1, root.getNestedTrees(REPEATED_NESTED_MESSAGE).get(1).getNestedTrees(FIELD_BB).size()); + assertThat(root.getNestedTrees(REPEATED_NESTED_MESSAGE)).hasSize(2); + assertThat(root.getNestedTrees(REPEATED_NESTED_MESSAGE).get(0).getNestedTrees(FIELD_BB)) + .hasSize(2); + assertThat(root.getNestedTrees(REPEATED_NESTED_MESSAGE).get(1).getNestedTrees(FIELD_BB)) + .hasSize(1); } }
diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatParseLocationTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatParseLocationTest.java index 19abc3f..ed20df5 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatParseLocationTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatParseLocationTest.java
@@ -30,55 +30,66 @@ package com.google.protobuf; -import junit.framework.TestCase; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Test @{link TextFormatParseLocation}. */ -public class TextFormatParseLocationTest extends TestCase { +@RunWith(JUnit4.class) +public class TextFormatParseLocationTest { + @Test public void testCreateEmpty() { TextFormatParseLocation location = TextFormatParseLocation.create(-1, -1); - assertEquals(TextFormatParseLocation.EMPTY, location); + assertThat(location).isEqualTo(TextFormatParseLocation.EMPTY); } + @Test public void testCreate() { TextFormatParseLocation location = TextFormatParseLocation.create(2, 1); - assertEquals(2, location.getLine()); - assertEquals(1, location.getColumn()); + assertThat(location.getLine()).isEqualTo(2); + assertThat(location.getColumn()).isEqualTo(1); } + @Test public void testCreateThrowsIllegalArgumentExceptionForInvalidIndex() { try { TextFormatParseLocation.create(-1, 0); - fail("Should throw IllegalArgumentException if line is less than 0"); + assertWithMessage("Should throw IllegalArgumentException if line is less than 0").fail(); } catch (IllegalArgumentException unused) { // pass } try { TextFormatParseLocation.create(0, -1); - fail("Should throw, column < 0"); + assertWithMessage("Should throw, column < 0").fail(); } catch (IllegalArgumentException unused) { // pass } } + @Test public void testHashCode() { TextFormatParseLocation loc0 = TextFormatParseLocation.create(2, 1); TextFormatParseLocation loc1 = TextFormatParseLocation.create(2, 1); - assertEquals(loc0.hashCode(), loc1.hashCode()); - assertEquals( - TextFormatParseLocation.EMPTY.hashCode(), TextFormatParseLocation.EMPTY.hashCode()); + assertThat(loc0.hashCode()).isEqualTo(loc1.hashCode()); + assertThat(TextFormatParseLocation.EMPTY.hashCode()) + .isEqualTo(TextFormatParseLocation.EMPTY.hashCode()); } + @Test public void testEquals() { TextFormatParseLocation loc0 = TextFormatParseLocation.create(2, 1); TextFormatParseLocation loc1 = TextFormatParseLocation.create(1, 2); TextFormatParseLocation loc2 = TextFormatParseLocation.create(2, 2); TextFormatParseLocation loc3 = TextFormatParseLocation.create(2, 1); - assertEquals(loc0, loc3); - assertNotSame(loc0, loc1); - assertNotSame(loc0, loc2); - assertNotSame(loc1, loc2); + assertThat(loc0).isEqualTo(loc3); + assertThat(loc0).isNotSameInstanceAs(loc1); + assertThat(loc0).isNotSameInstanceAs(loc2); + assertThat(loc1).isNotSameInstanceAs(loc2); } }
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 a919f3b..69568e1 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
@@ -31,6 +31,7 @@ package com.google.protobuf; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static com.google.protobuf.TestUtil.TEST_REQUIRED_INITIALIZED; import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED; @@ -59,16 +60,17 @@ import java.util.Arrays; import java.util.List; import java.util.logging.Logger; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Test case for {@link TextFormat}. * * <p>TODO(wenboz): ExtensionTest and rest of text_format_unittest.cc. - * - * @author wenboz@google.com (Wenbo Zhu) */ -public class TextFormatTest extends TestCase { +@RunWith(JUnit4.class) +public class TextFormatTest { // A basic string with different escapable characters for testing. private static final String ESCAPE_TEST_STRING = @@ -79,12 +81,12 @@ "\\\"A string with \\' characters \\n and \\r newlines " + "and \\t tabs and \\001 slashes \\\\"; - private static String allFieldsSetText = + private static final String ALL_FIELDS_SET_TEXT = TestUtil.readTextFromFile("text_format_unittest_data_oneof_implemented.txt"); - private static String allExtensionsSetText = + private static final String ALL_EXTENSIONS_SET_TEXT = TestUtil.readTextFromFile("text_format_unittest_extensions_data.txt"); - private static String exoticText = + private static final String EXOTIC_TEXT = "" + "repeated_int32: -1\n" + "repeated_int32: -2147483648\n" @@ -114,8 +116,8 @@ + "\\341\\210\\264\"\n" + "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n"; - private static String canonicalExoticText = - exoticText + private static final String CANONICAL_EXOTIC_TEXT = + EXOTIC_TEXT .replace(": .", ": 0.") .replace(": -.", ": -0.") // short-form double .replace("23e", "23E") @@ -123,7 +125,7 @@ .replace("0.23E17", "2.3E16") .replace(",", ""); - private String messageSetText = + private static final String MESSAGE_SET_TEXT = "" + "[protobuf_unittest.TestMessageSetExtension1] {\n" + " i: 123\n" @@ -132,7 +134,7 @@ + " str: \"foo\"\n" + "}\n"; - private String messageSetTextWithRepeatedExtension = + private static final String MESSAGE_SET_TEXT_WITH_REPEATED_EXTENSION = "" + "[protobuf_unittest.TestMessageSetExtension1] {\n" + " i: 123\n" @@ -141,20 +143,21 @@ + " i: 456\n" + "}\n"; - private final TextFormat.Parser parserAllowingUnknownFields = + private static final TextFormat.Parser PARSER_ALLOWING_UNKNOWN_FIELDS = TextFormat.Parser.newBuilder().setAllowUnknownFields(true).build(); - private final TextFormat.Parser parserAllowingUnknownExtensions = + private static final TextFormat.Parser PARSER_ALLOWING_UNKNOWN_EXTENSIONS = TextFormat.Parser.newBuilder().setAllowUnknownExtensions(true).build(); - private final TextFormat.Parser parserWithOverwriteForbidden = + private static final TextFormat.Parser PARSER_WITH_OVERWRITE_FORBIDDEN = TextFormat.Parser.newBuilder() .setSingularOverwritePolicy(SingularOverwritePolicy.FORBID_SINGULAR_OVERWRITES) .build(); - private final TextFormat.Parser defaultParser = TextFormat.Parser.newBuilder().build(); + private static final TextFormat.Parser DEFAULT_PARSER = TextFormat.Parser.newBuilder().build(); /** Print TestAllTypes and compare with golden file. */ + @Test public void testPrintMessage() throws Exception { String javaText = TextFormat.printer().printToString(TestUtil.getAllSet()); @@ -163,10 +166,11 @@ // C++ and Java TextFormat classes, so we need to conform. javaText = javaText.replace(".0\n", "\n"); - assertEquals(allFieldsSetText, javaText); + assertThat(javaText).isEqualTo(ALL_FIELDS_SET_TEXT); } /** Print TestAllTypes as Builder and compare with golden file. */ + @Test public void testPrintMessageBuilder() throws Exception { String javaText = TextFormat.printer().printToString(TestUtil.getAllSetBuilder()); @@ -175,10 +179,11 @@ // C++ and Java TextFormat classes, so we need to conform. javaText = javaText.replace(".0\n", "\n"); - assertEquals(allFieldsSetText, javaText); + assertThat(javaText).isEqualTo(ALL_FIELDS_SET_TEXT); } /** Print TestAllExtensions and compare with golden file. */ + @Test public void testPrintExtensions() throws Exception { String javaText = TextFormat.printer().printToString(TestUtil.getAllExtensionsSet()); @@ -187,7 +192,7 @@ // C++ and Java TextFormat classes, so we need to conform. javaText = javaText.replace(".0\n", "\n"); - assertEquals(allExtensionsSetText, javaText); + assertThat(javaText).isEqualTo(ALL_EXTENSIONS_SET_TEXT); } // Creates an example unknown field set. @@ -223,44 +228,45 @@ .build(); } + @Test public void testPrintUnknownFields() throws Exception { // Test printing of unknown fields in a message. TestEmptyMessage message = TestEmptyMessage.newBuilder().setUnknownFields(makeUnknownFieldSet()).build(); - assertEquals( - "5: 1\n" - + "5: 0x00000002\n" - + "5: 0x0000000000000003\n" - + "5: \"4\"\n" - + "5: {\n" - + " 12: 6\n" - + "}\n" - + "5 {\n" - + " 10: 5\n" - + "}\n" - + "8: 1\n" - + "8: 2\n" - + "8: 3\n" - + "15: 12379813812177893520\n" - + "15: 0xabcd1234\n" - + "15: 0xabcdef1234567890\n", - TextFormat.printer().printToString(message)); + assertThat(TextFormat.printer().printToString(message)) + .isEqualTo( + "5: 1\n" + + "5: 0x00000002\n" + + "5: 0x0000000000000003\n" + + "5: \"4\"\n" + + "5: {\n" + + " 12: 6\n" + + "}\n" + + "5 {\n" + + " 10: 5\n" + + "}\n" + + "8: 1\n" + + "8: 2\n" + + "8: 3\n" + + "15: 12379813812177893520\n" + + "15: 0xabcd1234\n" + + "15: 0xabcdef1234567890\n"); } + @Test public void testPrintField() throws Exception { final FieldDescriptor dataField = OneString.getDescriptor().findFieldByName("data"); - assertEquals( - "data: \"test data\"\n", TextFormat.printer().printFieldToString(dataField, "test data")); + assertThat(TextFormat.printer().printFieldToString(dataField, "test data")) + .isEqualTo("data: \"test data\"\n"); final FieldDescriptor optionalField = TestAllTypes.getDescriptor().findFieldByName("optional_nested_message"); final Object value = NestedMessage.newBuilder().setBb(42).build(); - assertEquals( - "optional_nested_message {\n bb: 42\n}\n", - TextFormat.printer().printFieldToString(optionalField, value)); + assertThat(TextFormat.printer().printFieldToString(optionalField, value)) + .isEqualTo("optional_nested_message {\n bb: 42\n}\n"); } /** @@ -283,6 +289,7 @@ return ByteString.copyFrom(bytes); } + @Test public void testPrintExotic() throws Exception { Message message = TestAllTypes.newBuilder() @@ -319,9 +326,10 @@ .addRepeatedBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"\u00fe")) .build(); - assertEquals(canonicalExoticText, message.toString()); + assertThat(message.toString()).isEqualTo(CANONICAL_EXOTIC_TEXT); } + @Test public void testRoundtripProto3Optional() throws Exception { Message message = TestProto3Optional.newBuilder() @@ -332,14 +340,15 @@ TestProto3Optional.Builder message2 = TestProto3Optional.newBuilder(); TextFormat.merge(message.toString(), message2); - assertTrue(message2.hasOptionalInt32()); - assertTrue(message2.hasOptionalInt64()); - assertTrue(message2.hasOptionalNestedEnum()); - assertEquals(1, message2.getOptionalInt32()); - assertEquals(2, message2.getOptionalInt64()); - assertEquals(NestedEnum.BAZ, message2.getOptionalNestedEnum()); + assertThat(message2.hasOptionalInt32()).isTrue(); + assertThat(message2.hasOptionalInt64()).isTrue(); + assertThat(message2.hasOptionalNestedEnum()).isTrue(); + assertThat(message2.getOptionalInt32()).isEqualTo(1); + assertThat(message2.getOptionalInt64()).isEqualTo(2); + assertThat(message2.getOptionalNestedEnum()).isEqualTo(NestedEnum.BAZ); } + @Test public void testPrintMessageSet() throws Exception { TestMessageSet messageSet = TestMessageSet.newBuilder() @@ -351,69 +360,79 @@ TestMessageSetExtension2.newBuilder().setStr("foo").build()) .build(); - assertEquals(messageSetText, messageSet.toString()); + assertThat(messageSet.toString()).isEqualTo(MESSAGE_SET_TEXT); } // ================================================================= + @Test public void testMerge() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - TextFormat.merge(allFieldsSetText, builder); + TextFormat.merge(ALL_FIELDS_SET_TEXT, builder); TestUtil.assertAllFieldsSet(builder.build()); } + @Test public void testParse() throws Exception { - TestUtil.assertAllFieldsSet(TextFormat.parse(allFieldsSetText, TestAllTypes.class)); + TestUtil.assertAllFieldsSet(TextFormat.parse(ALL_FIELDS_SET_TEXT, TestAllTypes.class)); } + @Test public void testMergeInitialized() throws Exception { TestRequired.Builder builder = TestRequired.newBuilder(); TextFormat.merge(TEST_REQUIRED_INITIALIZED.toString(), builder); - assertEquals(TEST_REQUIRED_INITIALIZED.toString(), builder.buildPartial().toString()); - assertTrue(builder.isInitialized()); + assertThat(builder.buildPartial().toString()).isEqualTo(TEST_REQUIRED_INITIALIZED.toString()); + assertThat(builder.isInitialized()).isTrue(); } + @Test public void testParseInitialized() throws Exception { TestRequired parsed = TextFormat.parse(TEST_REQUIRED_INITIALIZED.toString(), TestRequired.class); - assertEquals(TEST_REQUIRED_INITIALIZED.toString(), parsed.toString()); - assertTrue(parsed.isInitialized()); + assertThat(parsed.toString()).isEqualTo(TEST_REQUIRED_INITIALIZED.toString()); + assertThat(parsed.isInitialized()).isTrue(); } + @Test public void testMergeUninitialized() throws Exception { TestRequired.Builder builder = TestRequired.newBuilder(); TextFormat.merge(TEST_REQUIRED_UNINITIALIZED.toString(), builder); - assertEquals(TEST_REQUIRED_UNINITIALIZED.toString(), builder.buildPartial().toString()); - assertFalse(builder.isInitialized()); + assertThat(builder.buildPartial().toString()).isEqualTo(TEST_REQUIRED_UNINITIALIZED.toString()); + assertThat(builder.isInitialized()).isFalse(); } + @Test public void testParseUninitialized() throws Exception { try { TextFormat.parse(TEST_REQUIRED_UNINITIALIZED.toString(), TestRequired.class); - fail("Expected UninitializedMessageException."); + assertWithMessage("Expected UninitializedMessageException.").fail(); } catch (UninitializedMessageException e) { - assertEquals("Message missing required fields: b, c", e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo("Message missing required fields: b, c"); } } + @Test public void testMergeReader() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - TextFormat.merge(new StringReader(allFieldsSetText), builder); + TextFormat.merge(new StringReader(ALL_FIELDS_SET_TEXT), builder); TestUtil.assertAllFieldsSet(builder.build()); } + @Test public void testMergeExtensions() throws Exception { TestAllExtensions.Builder builder = TestAllExtensions.newBuilder(); - TextFormat.merge(allExtensionsSetText, TestUtil.getFullExtensionRegistry(), builder); + TextFormat.merge(ALL_EXTENSIONS_SET_TEXT, TestUtil.getFullExtensionRegistry(), builder); TestUtil.assertAllExtensionsSet(builder.build()); } + @Test public void testParseExtensions() throws Exception { TestUtil.assertAllExtensionsSet( TextFormat.parse( - allExtensionsSetText, TestUtil.getFullExtensionRegistry(), TestAllExtensions.class)); + ALL_EXTENSIONS_SET_TEXT, TestUtil.getFullExtensionRegistry(), TestAllExtensions.class)); } + @Test public void testMergeAndParseCompatibility() throws Exception { String original = "repeated_float: inf\n" @@ -445,82 +464,93 @@ // Test merge(). TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TextFormat.merge(original, builder); - assertEquals(canonical, builder.build().toString()); + assertThat(builder.build().toString()).isEqualTo(canonical); // Test parse(). - assertEquals(canonical, TextFormat.parse(original, TestAllTypes.class).toString()); + assertThat(TextFormat.parse(original, TestAllTypes.class).toString()).isEqualTo(canonical); } + @Test public void testMergeAndParseExotic() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - TextFormat.merge(exoticText, builder); + TextFormat.merge(EXOTIC_TEXT, builder); // Too lazy to check things individually. Don't try to debug this // if testPrintExotic() is failing. - assertEquals(canonicalExoticText, builder.build().toString()); - assertEquals(canonicalExoticText, TextFormat.parse(exoticText, TestAllTypes.class).toString()); + assertThat(builder.build().toString()).isEqualTo(CANONICAL_EXOTIC_TEXT); + assertThat(TextFormat.parse(EXOTIC_TEXT, TestAllTypes.class).toString()) + .isEqualTo(CANONICAL_EXOTIC_TEXT); } + @Test public void testMergeMessageSet() throws Exception { ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); extensionRegistry.add(TestMessageSetExtension2.messageSetExtension); TestMessageSet.Builder builder = TestMessageSet.newBuilder(); - TextFormat.merge(messageSetText, extensionRegistry, builder); + TextFormat.merge(MESSAGE_SET_TEXT, extensionRegistry, builder); TestMessageSet messageSet = builder.build(); - assertTrue(messageSet.hasExtension(TestMessageSetExtension1.messageSetExtension)); - assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); - assertTrue(messageSet.hasExtension(TestMessageSetExtension2.messageSetExtension)); - assertEquals( - "foo", messageSet.getExtension(TestMessageSetExtension2.messageSetExtension).getStr()); + assertThat(messageSet.hasExtension(TestMessageSetExtension1.messageSetExtension)).isTrue(); + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()) + .isEqualTo(123); + assertThat(messageSet.hasExtension(TestMessageSetExtension2.messageSetExtension)).isTrue(); + assertThat(messageSet.getExtension(TestMessageSetExtension2.messageSetExtension).getStr()) + .isEqualTo("foo"); builder = TestMessageSet.newBuilder(); - TextFormat.merge(messageSetTextWithRepeatedExtension, extensionRegistry, builder); + TextFormat.merge(MESSAGE_SET_TEXT_WITH_REPEATED_EXTENSION, extensionRegistry, builder); messageSet = builder.build(); - assertEquals(456, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()) + .isEqualTo(456); } + @Test public void testMergeMessageSetWithOverwriteForbidden() throws Exception { ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); extensionRegistry.add(TestMessageSetExtension2.messageSetExtension); TestMessageSet.Builder builder = TestMessageSet.newBuilder(); - parserWithOverwriteForbidden.merge(messageSetText, extensionRegistry, builder); + PARSER_WITH_OVERWRITE_FORBIDDEN.merge(MESSAGE_SET_TEXT, extensionRegistry, builder); TestMessageSet messageSet = builder.build(); - assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); - assertEquals( - "foo", messageSet.getExtension(TestMessageSetExtension2.messageSetExtension).getStr()); + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()) + .isEqualTo(123); + assertThat(messageSet.getExtension(TestMessageSetExtension2.messageSetExtension).getStr()) + .isEqualTo("foo"); builder = TestMessageSet.newBuilder(); try { - parserWithOverwriteForbidden.merge( - messageSetTextWithRepeatedExtension, extensionRegistry, builder); - fail("expected parse exception"); + PARSER_WITH_OVERWRITE_FORBIDDEN.merge( + MESSAGE_SET_TEXT_WITH_REPEATED_EXTENSION, extensionRegistry, builder); + assertWithMessage("expected parse exception").fail(); } catch (TextFormat.ParseException e) { - assertEquals( - "4:44: Non-repeated field " - + "\"protobuf_unittest.TestMessageSetExtension1.message_set_extension\"" - + " cannot be overwritten.", - e.getMessage()); + assertThat(e) + .hasMessageThat() + .isEqualTo( + "4:44: Non-repeated field " + + "\"protobuf_unittest.TestMessageSetExtension1.message_set_extension\"" + + " cannot be overwritten."); } } + @Test public void testMergeNumericEnum() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TextFormat.merge("optional_nested_enum: 2", builder); - assertEquals(TestAllTypes.NestedEnum.BAR, builder.getOptionalNestedEnum()); + assertThat(builder.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.BAR); } + @Test public void testMergeAngleBrackets() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TextFormat.merge("OptionalGroup: < a: 1 >", builder); - assertTrue(builder.hasOptionalGroup()); - assertEquals(1, builder.getOptionalGroup().getA()); + assertThat(builder.hasOptionalGroup()).isTrue(); + assertThat(builder.getOptionalGroup().getA()).isEqualTo(1); } + @Test public void testMergeComment() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TextFormat.merge( @@ -529,10 +559,11 @@ + "optional_int64: 2\n" + "# EOF comment", builder); - assertEquals(1, builder.getOptionalInt32()); - assertEquals(2, builder.getOptionalInt64()); + assertThat(builder.getOptionalInt32()).isEqualTo(1); + assertThat(builder.getOptionalInt64()).isEqualTo(2); } + @Test public void testPrintAny_customBuiltTypeRegistry() throws Exception { TestAny testAny = TestAny.newBuilder() @@ -553,7 +584,7 @@ + " optional_int32: 12345\n" + " }\n" + "}\n"; - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } private static Descriptor createDescriptorForAny(FieldDescriptorProto... fields) @@ -573,6 +604,7 @@ return fileDescriptor.getMessageTypes().get(0); } + @Test public void testPrintAny_anyWithDynamicMessage() throws Exception { Descriptor descriptor = createDescriptorForAny( @@ -605,9 +637,10 @@ "[type.googleapis.com/protobuf_unittest.TestAllTypes] {\n" + " optional_int32: 12345\n" + "}\n"; - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } + @Test public void testPrintAny_anyFromWithNoValueField() throws Exception { Descriptor descriptor = createDescriptorForAny( @@ -628,9 +661,10 @@ .usingTypeRegistry(TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build()) .printToString(testAny); String expected = "type_url: \"type.googleapis.com/protobuf_unittest.TestAllTypes\"\n"; - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } + @Test public void testPrintAny_anyFromWithNoTypeUrlField() throws Exception { Descriptor descriptor = createDescriptorForAny( @@ -651,9 +685,10 @@ .usingTypeRegistry(TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build()) .printToString(testAny); String expected = "value: \"\\b\\271`\"\n"; - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } + @Test public void testPrintAny_anyWithInvalidFieldType() throws Exception { Descriptor descriptor = createDescriptorForAny( @@ -682,10 +717,11 @@ .printToString(testAny); String expected = "type_url: \"type.googleapis.com/protobuf_unittest.TestAllTypes\"\n" + "value: \"test\"\n"; - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } + @Test public void testMergeAny_customBuiltTypeRegistry() throws Exception { TestAny.Builder builder = TestAny.newBuilder(); TextFormat.Parser.newBuilder() @@ -701,21 +737,22 @@ + "}\n" + "}", builder); - assertEquals( - TestAny.newBuilder() - .setValue( - Any.newBuilder() - .setTypeUrl("type.googleapis.com/" + TestAllTypes.getDescriptor().getFullName()) - .setValue( - TestAllTypes.newBuilder() - .setOptionalInt32(12345) - .setOptionalNestedMessage( - TestAllTypes.NestedMessage.newBuilder().setBb(123)) - .build() - .toByteString()) - .build()) - .build(), - builder.build()); + assertThat(builder.build()) + .isEqualTo( + TestAny.newBuilder() + .setValue( + Any.newBuilder() + .setTypeUrl( + "type.googleapis.com/" + TestAllTypes.getDescriptor().getFullName()) + .setValue( + TestAllTypes.newBuilder() + .setOptionalInt32(12345) + .setOptionalNestedMessage( + TestAllTypes.NestedMessage.newBuilder().setBb(123)) + .build() + .toByteString()) + .build()) + .build()); } @@ -724,71 +761,72 @@ TestAllTypes.Builder builder = TestAllTypes.newBuilder(); try { TextFormat.merge(text, TestUtil.getFullExtensionRegistry(), builder); - fail("Expected parse exception."); + assertWithMessage("Expected parse exception.").fail(); } catch (TextFormat.ParseException e) { - assertEquals(error, e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo(error); } // Test parse(). try { TextFormat.parse(text, TestUtil.getFullExtensionRegistry(), TestAllTypes.class); - fail("Expected parse exception."); + assertWithMessage("Expected parse exception.").fail(); } catch (TextFormat.ParseException e) { - assertEquals(error, e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo(error); } } private void assertParseErrorWithUnknownFields(String error, String text) { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); try { - parserAllowingUnknownFields.merge(text, TestUtil.getFullExtensionRegistry(), builder); - fail("Expected parse exception."); + PARSER_ALLOWING_UNKNOWN_FIELDS.merge(text, TestUtil.getFullExtensionRegistry(), builder); + assertWithMessage("Expected parse exception.").fail(); } catch (TextFormat.ParseException e) { - assertEquals(error, e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo(error); } } private TestAllTypes assertParseSuccessWithUnknownFields(String text) throws TextFormat.ParseException { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - parserAllowingUnknownFields.merge(text, TestUtil.getFullExtensionRegistry(), builder); + PARSER_ALLOWING_UNKNOWN_FIELDS.merge(text, TestUtil.getFullExtensionRegistry(), builder); return builder.build(); } private void assertParseErrorWithUnknownExtensions(String error, String text) { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); try { - parserAllowingUnknownExtensions.merge(text, builder); - fail("Expected parse exception."); + PARSER_ALLOWING_UNKNOWN_EXTENSIONS.merge(text, builder); + assertWithMessage("Expected parse exception.").fail(); } catch (TextFormat.ParseException e) { - assertEquals(error, e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo(error); } } private TestAllTypes assertParseSuccessWithUnknownExtensions(String text) throws TextFormat.ParseException { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - parserAllowingUnknownExtensions.merge(text, builder); + PARSER_ALLOWING_UNKNOWN_EXTENSIONS.merge(text, builder); return builder.build(); } private void assertParseErrorWithOverwriteForbidden(String error, String text) { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); try { - parserWithOverwriteForbidden.merge(text, TestUtil.getFullExtensionRegistry(), builder); - fail("Expected parse exception."); + PARSER_WITH_OVERWRITE_FORBIDDEN.merge(text, TestUtil.getFullExtensionRegistry(), builder); + assertWithMessage("Expected parse exception.").fail(); } catch (TextFormat.ParseException e) { - assertEquals(error, e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo(error); } } private TestAllTypes assertParseSuccessWithOverwriteForbidden(String text) throws TextFormat.ParseException { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); - parserWithOverwriteForbidden.merge(text, TestUtil.getFullExtensionRegistry(), builder); + PARSER_WITH_OVERWRITE_FORBIDDEN.merge(text, TestUtil.getFullExtensionRegistry(), builder); return builder.build(); } + @Test public void testParseErrors() throws Exception { assertParseError("1:16: Expected \":\".", "optional_int32 123"); assertParseError("1:23: Expected identifier. Found '?'", "optional_nested_enum: ?"); @@ -837,73 +875,70 @@ // ================================================================= + @Test public void testEscape() throws Exception { // Escape sequences. - assertEquals( - "\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\177", - TextFormat.escapeBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"\177"))); - assertEquals( - "\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\177", - TextFormat.escapeText("\0\001\007\b\f\n\r\t\013\\\'\"\177")); - assertEquals( - bytes("\0\001\007\b\f\n\r\t\013\\\'\""), - TextFormat.unescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"")); - assertEquals( - "\0\001\007\b\f\n\r\t\013\\\'\"", - TextFormat.unescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"")); - assertEquals(ESCAPE_TEST_STRING_ESCAPED, TextFormat.escapeText(ESCAPE_TEST_STRING)); - assertEquals(ESCAPE_TEST_STRING, TextFormat.unescapeText(ESCAPE_TEST_STRING_ESCAPED)); + assertThat(TextFormat.escapeBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"\177"))) + .isEqualTo("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\177"); + assertThat(TextFormat.escapeText("\0\001\007\b\f\n\r\t\013\\\'\"\177")) + .isEqualTo("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\177"); + assertThat(TextFormat.unescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"")) + .isEqualTo(bytes("\0\001\007\b\f\n\r\t\013\\\'\"")); + assertThat(TextFormat.unescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"")) + .isEqualTo("\0\001\007\b\f\n\r\t\013\\\'\""); + assertThat(TextFormat.escapeText(ESCAPE_TEST_STRING)).isEqualTo(ESCAPE_TEST_STRING_ESCAPED); + assertThat(TextFormat.unescapeText(ESCAPE_TEST_STRING_ESCAPED)).isEqualTo(ESCAPE_TEST_STRING); // Invariant - assertEquals("hello", TextFormat.escapeBytes(bytes("hello"))); - assertEquals("hello", TextFormat.escapeText("hello")); - assertEquals(bytes("hello"), TextFormat.unescapeBytes("hello")); - assertEquals("hello", TextFormat.unescapeText("hello")); + assertThat(TextFormat.escapeBytes(bytes("hello"))).isEqualTo("hello"); + assertThat(TextFormat.escapeText("hello")).isEqualTo("hello"); + assertThat(TextFormat.unescapeBytes("hello")).isEqualTo(bytes("hello")); + assertThat(TextFormat.unescapeText("hello")).isEqualTo("hello"); // Unicode handling. - assertEquals("\\341\\210\\264", TextFormat.escapeText("\u1234")); - assertEquals("\\341\\210\\264", TextFormat.escapeBytes(bytes(0xe1, 0x88, 0xb4))); - assertEquals("\u1234", TextFormat.unescapeText("\\341\\210\\264")); - 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")); + assertThat(TextFormat.escapeText("\u1234")).isEqualTo("\\341\\210\\264"); + assertThat(TextFormat.escapeBytes(bytes(0xe1, 0x88, 0xb4))).isEqualTo("\\341\\210\\264"); + assertThat(TextFormat.unescapeText("\\341\\210\\264")).isEqualTo("\u1234"); + assertThat(TextFormat.unescapeBytes("\\341\\210\\264")).isEqualTo(bytes(0xe1, 0x88, 0xb4)); + assertThat(TextFormat.unescapeText("\\xe1\\x88\\xb4")).isEqualTo("\u1234"); + assertThat(TextFormat.unescapeBytes("\\xe1\\x88\\xb4")).isEqualTo(bytes(0xe1, 0x88, 0xb4)); + assertThat(TextFormat.unescapeText("\\u1234")).isEqualTo("\u1234"); + assertThat(TextFormat.unescapeBytes("\\u1234")).isEqualTo(bytes(0xe1, 0x88, 0xb4)); + assertThat(TextFormat.unescapeBytes("\\U00001234")).isEqualTo(bytes(0xe1, 0x88, 0xb4)); + assertThat(TextFormat.unescapeText("\\xf0\\x90\\x90\\xb7")) + .isEqualTo(new String(new int[] {0x10437}, 0, 1)); + assertThat(TextFormat.unescapeBytes("\\U00010437")).isEqualTo(bytes(0xf0, 0x90, 0x90, 0xb7)); // Handling of strings with unescaped Unicode characters > 255. final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c"; ByteString zhByteString = ByteString.copyFromUtf8(zh); - assertEquals(zhByteString, TextFormat.unescapeBytes(zh)); + assertThat(TextFormat.unescapeBytes(zh)).isEqualTo(zhByteString); // Errors. try { TextFormat.unescapeText("\\x"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { // success } try { TextFormat.unescapeText("\\z"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { // success } try { TextFormat.unescapeText("\\"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { // success } try { TextFormat.unescapeText("\\u"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { assertThat(e) .hasMessageThat() @@ -912,7 +947,7 @@ try { TextFormat.unescapeText("\\ud800"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { assertThat(e) .hasMessageThat() @@ -921,7 +956,7 @@ try { TextFormat.unescapeText("\\ud800\\u1234"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { assertThat(e) .hasMessageThat() @@ -930,7 +965,7 @@ try { TextFormat.unescapeText("\\udc00"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { assertThat(e) .hasMessageThat() @@ -939,7 +974,7 @@ try { TextFormat.unescapeText("\\ud801\\udc37"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { assertThat(e) .hasMessageThat() @@ -948,7 +983,7 @@ try { TextFormat.unescapeText("\\U1234"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { assertThat(e) .hasMessageThat() @@ -957,7 +992,7 @@ try { TextFormat.unescapeText("\\U1234no more hex"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { assertThat(e) .hasMessageThat() @@ -966,7 +1001,7 @@ try { TextFormat.unescapeText("\\U00110000"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { assertThat(e) .hasMessageThat() @@ -975,7 +1010,7 @@ try { TextFormat.unescapeText("\\U0000d801\\U00000dc37"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.InvalidEscapeSequenceException e) { assertThat(e) .hasMessageThat() @@ -983,106 +1018,107 @@ } } + @Test public void testParseInteger() throws Exception { - assertEquals(0, TextFormat.parseInt32("0")); - assertEquals(1, TextFormat.parseInt32("1")); - assertEquals(-1, TextFormat.parseInt32("-1")); - assertEquals(12345, TextFormat.parseInt32("12345")); - assertEquals(-12345, TextFormat.parseInt32("-12345")); - assertEquals(2147483647, TextFormat.parseInt32("2147483647")); - assertEquals(-2147483648, TextFormat.parseInt32("-2147483648")); + assertThat(TextFormat.parseInt32("0")).isEqualTo(0); + assertThat(TextFormat.parseInt32("1")).isEqualTo(1); + assertThat(TextFormat.parseInt32("-1")).isEqualTo(-1); + assertThat(TextFormat.parseInt32("12345")).isEqualTo(12345); + assertThat(TextFormat.parseInt32("-12345")).isEqualTo(-12345); + assertThat(TextFormat.parseInt32("2147483647")).isEqualTo(2147483647); + assertThat(TextFormat.parseInt32("-2147483648")).isEqualTo(-2147483648); - assertEquals(0, TextFormat.parseUInt32("0")); - assertEquals(1, TextFormat.parseUInt32("1")); - assertEquals(12345, TextFormat.parseUInt32("12345")); - assertEquals(2147483647, TextFormat.parseUInt32("2147483647")); - assertEquals((int) 2147483648L, TextFormat.parseUInt32("2147483648")); - assertEquals((int) 4294967295L, TextFormat.parseUInt32("4294967295")); + assertThat(TextFormat.parseUInt32("0")).isEqualTo(0); + assertThat(TextFormat.parseUInt32("1")).isEqualTo(1); + assertThat(TextFormat.parseUInt32("12345")).isEqualTo(12345); + assertThat(TextFormat.parseUInt32("2147483647")).isEqualTo(2147483647); + assertThat(TextFormat.parseUInt32("2147483648")).isEqualTo((int) 2147483648L); + assertThat(TextFormat.parseUInt32("4294967295")).isEqualTo((int) 4294967295L); - assertEquals(0L, TextFormat.parseInt64("0")); - assertEquals(1L, TextFormat.parseInt64("1")); - assertEquals(-1L, TextFormat.parseInt64("-1")); - assertEquals(12345L, TextFormat.parseInt64("12345")); - assertEquals(-12345L, TextFormat.parseInt64("-12345")); - assertEquals(2147483647L, TextFormat.parseInt64("2147483647")); - assertEquals(-2147483648L, TextFormat.parseInt64("-2147483648")); - assertEquals(4294967295L, TextFormat.parseInt64("4294967295")); - assertEquals(4294967296L, TextFormat.parseInt64("4294967296")); - assertEquals(9223372036854775807L, TextFormat.parseInt64("9223372036854775807")); - assertEquals(-9223372036854775808L, TextFormat.parseInt64("-9223372036854775808")); + assertThat(TextFormat.parseInt64("0")).isEqualTo(0L); + assertThat(TextFormat.parseInt64("1")).isEqualTo(1L); + assertThat(TextFormat.parseInt64("-1")).isEqualTo(-1L); + assertThat(TextFormat.parseInt64("12345")).isEqualTo(12345L); + assertThat(TextFormat.parseInt64("-12345")).isEqualTo(-12345L); + assertThat(TextFormat.parseInt64("2147483647")).isEqualTo(2147483647L); + assertThat(TextFormat.parseInt64("-2147483648")).isEqualTo(-2147483648L); + assertThat(TextFormat.parseInt64("4294967295")).isEqualTo(4294967295L); + assertThat(TextFormat.parseInt64("4294967296")).isEqualTo(4294967296L); + assertThat(TextFormat.parseInt64("9223372036854775807")).isEqualTo(9223372036854775807L); + assertThat(TextFormat.parseInt64("-9223372036854775808")).isEqualTo(-9223372036854775808L); - assertEquals(0L, TextFormat.parseUInt64("0")); - assertEquals(1L, TextFormat.parseUInt64("1")); - assertEquals(12345L, TextFormat.parseUInt64("12345")); - assertEquals(2147483647L, TextFormat.parseUInt64("2147483647")); - assertEquals(4294967295L, TextFormat.parseUInt64("4294967295")); - assertEquals(4294967296L, TextFormat.parseUInt64("4294967296")); - assertEquals(9223372036854775807L, TextFormat.parseUInt64("9223372036854775807")); - assertEquals(-9223372036854775808L, TextFormat.parseUInt64("9223372036854775808")); - assertEquals(-1L, TextFormat.parseUInt64("18446744073709551615")); + assertThat(TextFormat.parseUInt64("0")).isEqualTo(0L); + assertThat(TextFormat.parseUInt64("1")).isEqualTo(1L); + assertThat(TextFormat.parseUInt64("12345")).isEqualTo(12345L); + assertThat(TextFormat.parseUInt64("2147483647")).isEqualTo(2147483647L); + assertThat(TextFormat.parseUInt64("4294967295")).isEqualTo(4294967295L); + assertThat(TextFormat.parseUInt64("4294967296")).isEqualTo(4294967296L); + assertThat(TextFormat.parseUInt64("9223372036854775807")).isEqualTo(9223372036854775807L); + assertThat(TextFormat.parseUInt64("9223372036854775808")).isEqualTo(-9223372036854775808L); + assertThat(TextFormat.parseUInt64("18446744073709551615")).isEqualTo(-1L); // Hex - assertEquals(0x1234abcd, TextFormat.parseInt32("0x1234abcd")); - assertEquals(-0x1234abcd, TextFormat.parseInt32("-0x1234abcd")); - assertEquals(-1, TextFormat.parseUInt64("0xffffffffffffffff")); - assertEquals(0x7fffffffffffffffL, TextFormat.parseInt64("0x7fffffffffffffff")); + assertThat(TextFormat.parseInt32("0x1234abcd")).isEqualTo(0x1234abcd); + assertThat(TextFormat.parseInt32("-0x1234abcd")).isEqualTo(-0x1234abcd); + assertThat(TextFormat.parseUInt64("0xffffffffffffffff")).isEqualTo(-1); + assertThat(TextFormat.parseInt64("0x7fffffffffffffff")).isEqualTo(0x7fffffffffffffffL); // Octal - assertEquals(01234567, TextFormat.parseInt32("01234567")); + assertThat(TextFormat.parseInt32("01234567")).isEqualTo(01234567); // Out-of-range try { TextFormat.parseInt32("2147483648"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NumberFormatException e) { // success } try { TextFormat.parseInt32("-2147483649"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NumberFormatException e) { // success } try { TextFormat.parseUInt32("4294967296"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NumberFormatException e) { // success } try { TextFormat.parseUInt32("-1"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NumberFormatException e) { // success } try { TextFormat.parseInt64("9223372036854775808"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NumberFormatException e) { // success } try { TextFormat.parseInt64("-9223372036854775809"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NumberFormatException e) { // success } try { TextFormat.parseUInt64("18446744073709551616"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NumberFormatException e) { // success } try { TextFormat.parseUInt64("-1"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NumberFormatException e) { // success } @@ -1090,19 +1126,21 @@ // Not a number. try { TextFormat.parseInt32("abcd"); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (NumberFormatException e) { // success } } + @Test public void testParseString() throws Exception { final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c"; TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TextFormat.merge("optional_string: \"" + zh + "\"", builder); - assertEquals(zh, builder.getOptionalString()); + assertThat(builder.getOptionalString()).isEqualTo(zh); } + @Test public void testParseLongString() throws Exception { String longText = "123456789012345678901234567890123456789012345678901234567890" @@ -1128,9 +1166,10 @@ TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TextFormat.merge("optional_string: \"" + longText + "\"", builder); - assertEquals(longText, builder.getOptionalString()); + assertThat(builder.getOptionalString()).isEqualTo(longText); } + @Test public void testParseBoolean() throws Exception { String goodText = "repeated_bool: t repeated_bool : 0\n" @@ -1145,30 +1184,32 @@ + "repeated_bool: true\n"; TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TextFormat.merge(goodText, builder); - assertEquals(goodTextCanonical, builder.build().toString()); + assertThat(builder.build().toString()).isEqualTo(goodTextCanonical); try { TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder(); TextFormat.merge("optional_bool:2", badBuilder); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.ParseException e) { // success } try { TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder(); TextFormat.merge("optional_bool: foo", badBuilder); - fail("Should have thrown an exception."); + assertWithMessage("Should have thrown an exception.").fail(); } catch (TextFormat.ParseException e) { // success } } + @Test public void testParseAdjacentStringLiterals() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TextFormat.merge("optional_string: \"foo\" 'corge' \"grault\"", builder); - assertEquals("foocorgegrault", builder.getOptionalString()); + assertThat(builder.getOptionalString()).isEqualTo("foocorgegrault"); } + @Test public void testPrintFieldValue() throws Exception { assertPrintFieldValue("\"Hello\"", "Hello", "repeated_string"); assertPrintFieldValue("123.0", 123f, "repeated_float"); @@ -1187,133 +1228,139 @@ StringBuilder sb = new StringBuilder(); TextFormat.printer() .printFieldValue(TestAllTypes.getDescriptor().findFieldByName(fieldName), value, sb); - assertEquals(expect, sb.toString()); + assertThat(sb.toString()).isEqualTo(expect); } + @Test public void testShortDebugString() { - assertEquals( - "optional_nested_message { bb: 42 } repeated_int32: 1 repeated_uint32: 2", - TextFormat.shortDebugString( - TestAllTypes.newBuilder() - .addRepeatedInt32(1) - .addRepeatedUint32(2) - .setOptionalNestedMessage(NestedMessage.newBuilder().setBb(42).build()) - .build())); + assertThat( + TextFormat.shortDebugString( + TestAllTypes.newBuilder() + .addRepeatedInt32(1) + .addRepeatedUint32(2) + .setOptionalNestedMessage(NestedMessage.newBuilder().setBb(42).build()) + .build())) + .isEqualTo("optional_nested_message { bb: 42 } repeated_int32: 1 repeated_uint32: 2"); } + @Test public void testShortDebugString_field() { final FieldDescriptor dataField = OneString.getDescriptor().findFieldByName("data"); - assertEquals( - "data: \"test data\"", - TextFormat.printer().shortDebugString(dataField, "test data")); + assertThat(TextFormat.printer().shortDebugString(dataField, "test data")) + .isEqualTo("data: \"test data\""); final FieldDescriptor optionalField = TestAllTypes.getDescriptor().findFieldByName("optional_nested_message"); final Object value = NestedMessage.newBuilder().setBb(42).build(); - assertEquals( - "optional_nested_message { bb: 42 }", - TextFormat.printer().shortDebugString(optionalField, value)); + assertThat(TextFormat.printer().shortDebugString(optionalField, value)) + .isEqualTo("optional_nested_message { bb: 42 }"); } + @Test public void testShortDebugString_unknown() { - assertEquals( - "5: 1 5: 0x00000002 5: 0x0000000000000003 5: \"4\" 5: { 12: 6 } 5 { 10: 5 }" - + " 8: 1 8: 2 8: 3 15: 12379813812177893520 15: 0xabcd1234 15:" - + " 0xabcdef1234567890", - TextFormat.printer().shortDebugString(makeUnknownFieldSet())); + assertThat(TextFormat.printer().shortDebugString(makeUnknownFieldSet())) + .isEqualTo( + "5: 1 5: 0x00000002 5: 0x0000000000000003 5: \"4\" 5: { 12: 6 } 5 { 10: 5 }" + + " 8: 1 8: 2 8: 3 15: 12379813812177893520 15: 0xabcd1234 15:" + + " 0xabcdef1234567890"); } + @Test public void testPrintToUnicodeString() throws Exception { - assertEquals( - "optional_string: \"abc\u3042efg\"\n" - + "optional_bytes: \"\\343\\201\\202\"\n" - + "repeated_string: \"\u3093XYZ\"\n", - TextFormat.printer() - .escapingNonAscii(false) - .printToString( - TestAllTypes.newBuilder() - .setOptionalString("abc\u3042efg") - .setOptionalBytes(bytes(0xe3, 0x81, 0x82)) - .addRepeatedString("\u3093XYZ") - .build())); + assertThat( + TextFormat.printer() + .escapingNonAscii(false) + .printToString( + TestAllTypes.newBuilder() + .setOptionalString("abc\u3042efg") + .setOptionalBytes(bytes(0xe3, 0x81, 0x82)) + .addRepeatedString("\u3093XYZ") + .build())) + .isEqualTo( + "optional_string: \"abc\u3042efg\"\n" + + "optional_bytes: \"\\343\\201\\202\"\n" + + "repeated_string: \"\u3093XYZ\"\n"); // Double quotes and backslashes should be escaped - assertEquals( - "optional_string: \"a\\\\bc\\\"ef\\\"g\"\n", - TextFormat.printer() - .escapingNonAscii(false) - .printToString(TestAllTypes.newBuilder().setOptionalString("a\\bc\"ef\"g").build())); + assertThat( + TextFormat.printer() + .escapingNonAscii(false) + .printToString(TestAllTypes.newBuilder().setOptionalString("a\\bc\"ef\"g").build())) + .isEqualTo("optional_string: \"a\\\\bc\\\"ef\\\"g\"\n"); // Test escaping roundtrip TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("a\\bc\\\"ef\"g").build(); TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TextFormat.merge(TextFormat.printer().escapingNonAscii(false).printToString(message), builder); - assertEquals(message.getOptionalString(), builder.getOptionalString()); + assertThat(builder.getOptionalString()).isEqualTo(message.getOptionalString()); } + @Test public void testPrintToUnicodeStringWithNewlines() throws Exception { // No newlines at start and end - assertEquals( - "optional_string: \"test newlines\\n\\nin\\nstring\"\n", - TextFormat.printer() - .escapingNonAscii(false) - .printToString( - TestAllTypes.newBuilder() - .setOptionalString("test newlines\n\nin\nstring") - .build())); + assertThat( + TextFormat.printer() + .escapingNonAscii(false) + .printToString( + TestAllTypes.newBuilder() + .setOptionalString("test newlines\n\nin\nstring") + .build())) + .isEqualTo("optional_string: \"test newlines\\n\\nin\\nstring\"\n"); // Newlines at start and end - assertEquals( - "optional_string: \"\\ntest\\nnewlines\\n\\nin\\nstring\\n\"\n", - TextFormat.printer() - .escapingNonAscii(false) - .printToString( - TestAllTypes.newBuilder() - .setOptionalString("\ntest\nnewlines\n\nin\nstring\n") - .build())); + assertThat( + TextFormat.printer() + .escapingNonAscii(false) + .printToString( + TestAllTypes.newBuilder() + .setOptionalString("\ntest\nnewlines\n\nin\nstring\n") + .build())) + .isEqualTo("optional_string: \"\\ntest\\nnewlines\\n\\nin\\nstring\\n\"\n"); // Strings with 0, 1 and 2 newlines. - assertEquals( - "optional_string: \"\"\n", - TextFormat.printer() - .escapingNonAscii(false) - .printToString(TestAllTypes.newBuilder().setOptionalString("").build())); - assertEquals( - "optional_string: \"\\n\"\n", - TextFormat.printer() - .escapingNonAscii(false) - .printToString(TestAllTypes.newBuilder().setOptionalString("\n").build())); - assertEquals( - "optional_string: \"\\n\\n\"\n", - TextFormat.printer() - .escapingNonAscii(false) - .printToString(TestAllTypes.newBuilder().setOptionalString("\n\n").build())); + assertThat( + TextFormat.printer() + .escapingNonAscii(false) + .printToString(TestAllTypes.newBuilder().setOptionalString("").build())) + .isEqualTo("optional_string: \"\"\n"); + assertThat( + TextFormat.printer() + .escapingNonAscii(false) + .printToString(TestAllTypes.newBuilder().setOptionalString("\n").build())) + .isEqualTo("optional_string: \"\\n\"\n"); + assertThat( + TextFormat.printer() + .escapingNonAscii(false) + .printToString(TestAllTypes.newBuilder().setOptionalString("\n\n").build())) + .isEqualTo("optional_string: \"\\n\\n\"\n"); // Test escaping roundtrip TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("\ntest\nnewlines\n\nin\nstring\n").build(); TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TextFormat.merge(TextFormat.printer().escapingNonAscii(false).printToString(message), builder); - assertEquals(message.getOptionalString(), builder.getOptionalString()); + assertThat(builder.getOptionalString()).isEqualTo(message.getOptionalString()); } + @Test public void testPrintToUnicodeString_unknown() { - assertEquals( - "1: \"\\343\\201\\202\"\n", - TextFormat.printer() - .escapingNonAscii(false) - .printToString( - UnknownFieldSet.newBuilder() - .addField( - 1, - UnknownFieldSet.Field.newBuilder() - .addLengthDelimited(bytes(0xe3, 0x81, 0x82)) - .build()) - .build())); + assertThat( + TextFormat.printer() + .escapingNonAscii(false) + .printToString( + UnknownFieldSet.newBuilder() + .addField( + 1, + UnknownFieldSet.Field.newBuilder() + .addLengthDelimited(bytes(0xe3, 0x81, 0x82)) + .build()) + .build())) + .isEqualTo("1: \"\\343\\201\\202\"\n"); } + @Test public void testParseUnknownExtensions() throws Exception { TestUtil.TestLogHandler logHandler = new TestUtil.TestLogHandler(); Logger logger = Logger.getLogger(TextFormat.class.getName()); @@ -1323,16 +1370,16 @@ assertParseSuccessWithUnknownExtensions( "[unknown_extension]: 123\n" + "[unknown_ext]: inf\n" + "[unknown]: 1.234"); // Test warning messages. - assertEquals( - "Input contains unknown fields and/or extensions:\n" - + "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]", - logHandler.getStoredLogRecords().get(0).getMessage()); - assertEquals( - "Input contains unknown fields and/or extensions:\n" - + "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]\n" - + "2:2:\tprotobuf_unittest.TestAllTypes.[unknown_ext]\n" - + "3:2:\tprotobuf_unittest.TestAllTypes.[unknown]", - logHandler.getStoredLogRecords().get(1).getMessage()); + assertThat(logHandler.getStoredLogRecords().get(0).getMessage()) + .isEqualTo( + "Input contains unknown fields and/or extensions:\n" + + "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]"); + assertThat(logHandler.getStoredLogRecords().get(1).getMessage()) + .isEqualTo( + "Input contains unknown fields and/or extensions:\n" + + "1:2:\tprotobuf_unittest.TestAllTypes.[unknown_extension]\n" + + "2:2:\tprotobuf_unittest.TestAllTypes.[unknown_ext]\n" + + "3:2:\tprotobuf_unittest.TestAllTypes.[unknown]"); // Test unknown field can not pass. assertParseErrorWithUnknownExtensions( @@ -1363,6 +1410,7 @@ } // See additional coverage in testOneofOverwriteForbidden and testMapOverwriteForbidden. + @Test public void testParseNonRepeatedFields() throws Exception { assertParseSuccessWithOverwriteForbidden("repeated_int32: 1\nrepeated_int32: 2\n"); assertParseSuccessWithOverwriteForbidden("RepeatedGroup { a: 1 }\nRepeatedGroup { a: 2 }\n"); @@ -1398,6 +1446,7 @@ "default_string: \"zxcv\"\ndefault_string: \"asdf\"\n"); } + @Test public void testParseShortRepeatedFormOfRepeatedFields() throws Exception { assertParseSuccessWithOverwriteForbidden("repeated_foreign_enum: [FOREIGN_FOO, FOREIGN_BAR]"); assertParseSuccessWithOverwriteForbidden("repeated_int32: [ 1, 2 ]\n"); @@ -1406,6 +1455,7 @@ // See also testMapShortForm. } + @Test public void testParseShortRepeatedFormOfEmptyRepeatedFields() throws Exception { assertParseSuccessWithOverwriteForbidden("repeated_foreign_enum: []"); assertParseSuccessWithOverwriteForbidden("repeated_int32: []\n"); @@ -1414,6 +1464,7 @@ // See also testMapShortFormEmpty. } + @Test public void testParseShortRepeatedFormWithTrailingComma() throws Exception { assertParseErrorWithOverwriteForbidden( "1:38: Expected identifier. Found \']\'", "repeated_foreign_enum: [FOREIGN_FOO, ]\n"); @@ -1425,6 +1476,7 @@ // See also testMapShortFormTrailingComma. } + @Test public void testParseShortRepeatedFormOfNonRepeatedFields() throws Exception { assertParseErrorWithOverwriteForbidden( "1:17: Couldn't parse integer: For input string: \"[\"", "optional_int32: [1]\n"); @@ -1435,6 +1487,7 @@ // ======================================================================= // test oneof + @Test public void testOneofTextFormat() throws Exception { TestOneof2.Builder builder = TestOneof2.newBuilder(); TestUtil.setOneof(builder); @@ -1444,34 +1497,38 @@ TestUtil.assertOneofSet(dest.build()); } + @Test public void testOneofOverwriteForbidden() throws Exception { String input = "foo_string: \"stringvalue\" foo_int: 123"; TestOneof2.Builder builder = TestOneof2.newBuilder(); try { - parserWithOverwriteForbidden.merge(input, TestUtil.getFullExtensionRegistry(), builder); - fail("Expected parse exception."); + PARSER_WITH_OVERWRITE_FORBIDDEN.merge(input, TestUtil.getFullExtensionRegistry(), builder); + assertWithMessage("Expected parse exception.").fail(); } catch (TextFormat.ParseException e) { - assertEquals( - "1:34: Field \"protobuf_unittest.TestOneof2.foo_int\"" - + " is specified along with field \"protobuf_unittest.TestOneof2.foo_string\"," - + " another member of oneof \"foo\".", - e.getMessage()); + assertThat(e) + .hasMessageThat() + .isEqualTo( + "1:34: Field \"protobuf_unittest.TestOneof2.foo_int\"" + + " is specified along with field \"protobuf_unittest.TestOneof2.foo_string\"," + + " another member of oneof \"foo\"."); } } + @Test public void testOneofOverwriteAllowed() throws Exception { String input = "foo_string: \"stringvalue\" foo_int: 123"; TestOneof2.Builder builder = TestOneof2.newBuilder(); - defaultParser.merge(input, TestUtil.getFullExtensionRegistry(), builder); + DEFAULT_PARSER.merge(input, TestUtil.getFullExtensionRegistry(), builder); // Only the last value sticks. TestOneof2 oneof = builder.build(); - assertFalse(oneof.hasFooString()); - assertTrue(oneof.hasFooInt()); + assertThat(oneof.hasFooString()).isFalse(); + assertThat(oneof.hasFooInt()).isTrue(); } // ======================================================================= // test map + @Test public void testMapTextFormat() throws Exception { TestMap message = TestMap.newBuilder() @@ -1483,15 +1540,16 @@ { TestMap.Builder dest = TestMap.newBuilder(); TextFormat.merge(text, dest); - assertEquals(message, dest.build()); + assertThat(dest.build()).isEqualTo(message); } { TestMap.Builder dest = TestMap.newBuilder(); - parserWithOverwriteForbidden.merge(text, dest); - assertEquals(message, dest.build()); + PARSER_WITH_OVERWRITE_FORBIDDEN.merge(text, dest); + assertThat(dest.build()).isEqualTo(message); } } + @Test public void testMapDuplicateKeys() throws Exception { String input = "int32_to_int32_field: {\n" @@ -1510,43 +1568,47 @@ int i1 = msg.getInt32ToInt32FieldMap().get(1); TestMap msg2 = TextFormat.parse(msg.toString(), TestMap.class); int i2 = msg2.getInt32ToInt32FieldMap().get(1); - assertEquals(i1, i2); + assertThat(i1).isEqualTo(i2); } + @Test public void testMapShortForm() throws Exception { String text = "string_to_int32_field [{ key: 'x' value: 10 }, { key: 'y' value: 20 }]\n" + "int32_to_message_field " + "[{ key: 1 value { value: 100 } }, { key: 2 value: { value: 200 } }]\n"; TestMap.Builder dest = TestMap.newBuilder(); - parserWithOverwriteForbidden.merge(text, dest); + PARSER_WITH_OVERWRITE_FORBIDDEN.merge(text, dest); TestMap message = dest.build(); - assertEquals(2, message.getStringToInt32FieldMap().size()); - assertEquals(2, message.getInt32ToMessageFieldMap().size()); - assertEquals(10, message.getStringToInt32FieldMap().get("x").intValue()); - assertEquals(200, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertThat(message.getStringToInt32FieldMap()).hasSize(2); + assertThat(message.getInt32ToMessageFieldMap()).hasSize(2); + assertThat(message.getStringToInt32FieldMap().get("x").intValue()).isEqualTo(10); + assertThat(message.getInt32ToMessageFieldMap().get(2).getValue()).isEqualTo(200); } + @Test public void testMapShortFormEmpty() throws Exception { String text = "string_to_int32_field []\nint32_to_message_field: []\n"; TestMap.Builder dest = TestMap.newBuilder(); - parserWithOverwriteForbidden.merge(text, dest); + PARSER_WITH_OVERWRITE_FORBIDDEN.merge(text, dest); TestMap message = dest.build(); - assertEquals(0, message.getStringToInt32FieldMap().size()); - assertEquals(0, message.getInt32ToMessageFieldMap().size()); + assertThat(message.getStringToInt32FieldMap()).isEmpty(); + assertThat(message.getInt32ToMessageFieldMap()).isEmpty(); } + @Test public void testMapShortFormTrailingComma() throws Exception { String text = "string_to_int32_field [{ key: 'x' value: 10 }, ]\n"; TestMap.Builder dest = TestMap.newBuilder(); try { - parserWithOverwriteForbidden.merge(text, dest); - fail("Expected parse exception."); + PARSER_WITH_OVERWRITE_FORBIDDEN.merge(text, dest); + assertWithMessage("Expected parse exception.").fail(); } catch (TextFormat.ParseException e) { - assertEquals("1:48: Expected \"{\".", e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo("1:48: Expected \"{\"."); } } + @Test public void testMapOverwrite() throws Exception { String text = "int32_to_int32_field { key: 1 value: 10 }\n" @@ -1556,38 +1618,39 @@ { // With default parser, last value set for the key holds. TestMap.Builder builder = TestMap.newBuilder(); - defaultParser.merge(text, builder); + DEFAULT_PARSER.merge(text, builder); TestMap map = builder.build(); - assertEquals(2, map.getInt32ToInt32FieldMap().size()); - assertEquals(30, map.getInt32ToInt32FieldMap().get(1).intValue()); + assertThat(map.getInt32ToInt32FieldMap()).hasSize(2); + assertThat(map.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(30); } { // With overwrite forbidden, same behavior. // TODO(b/29122459): Expect parse exception here. TestMap.Builder builder = TestMap.newBuilder(); - parserWithOverwriteForbidden.merge(text, builder); + PARSER_WITH_OVERWRITE_FORBIDDEN.merge(text, builder); TestMap map = builder.build(); - assertEquals(2, map.getInt32ToInt32FieldMap().size()); - assertEquals(30, map.getInt32ToInt32FieldMap().get(1).intValue()); + assertThat(map.getInt32ToInt32FieldMap()).hasSize(2); + assertThat(map.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(30); } { // With overwrite forbidden and a dynamic message, same behavior. // TODO(b/29122459): Expect parse exception here. Message.Builder builder = DynamicMessage.newBuilder(TestMap.getDescriptor()); - parserWithOverwriteForbidden.merge(text, builder); + PARSER_WITH_OVERWRITE_FORBIDDEN.merge(text, builder); TestMap map = TestMap.parseFrom( builder.build().toByteString(), ExtensionRegistryLite.getEmptyRegistry()); - assertEquals(2, map.getInt32ToInt32FieldMap().size()); - assertEquals(30, map.getInt32ToInt32FieldMap().get(1).intValue()); + assertThat(map.getInt32ToInt32FieldMap()).hasSize(2); + assertThat(map.getInt32ToInt32FieldMap().get(1).intValue()).isEqualTo(30); } } // ======================================================================= // test location information + @Test public void testParseInfoTreeBuilding() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); @@ -1652,7 +1715,7 @@ // Verify a NULL tree for an unknown nested field. try { tree.getNestedTree(nestedField, 2); - fail("unknown nested field should throw"); + assertWithMessage("unknown nested field should throw").fail(); } catch (IllegalArgumentException unused) { // pass } @@ -1669,15 +1732,16 @@ if (index < locs.size()) { TextFormatParseLocation location = locs.get(index); TextFormatParseLocation expected = TextFormatParseLocation.create(line, column); - assertEquals(expected, location); + assertThat(location).isEqualTo(expected); } else if (line != -1 && column != -1) { - fail( - String.format( + assertWithMessage( "Tree/descriptor/fieldname did not contain index %d, line %d column %d expected", - index, line, column)); + index, line, column) + .fail(); } } + @Test public void testSortMapFields() throws Exception { TestMap message = TestMap.newBuilder() @@ -1713,6 +1777,6 @@ + " key: \"cherry\"\n" + " value: 30\n" + "}\n"; - assertEquals(text, TextFormat.printer().printToString(message)); + assertThat(TextFormat.printer().printToString(message)).isEqualTo(text); } }
diff --git a/java/core/src/test/java/com/google/protobuf/TypeRegistryTest.java b/java/core/src/test/java/com/google/protobuf/TypeRegistryTest.java index 0cd9677..c9defb3 100644 --- a/java/core/src/test/java/com/google/protobuf/TypeRegistryTest.java +++ b/java/core/src/test/java/com/google/protobuf/TypeRegistryTest.java
@@ -30,8 +30,7 @@ package com.google.protobuf; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; +import static com.google.common.truth.Truth.assertThat; import com.google.protobuf.Descriptors.Descriptor; import protobuf_unittest.UnittestProto; @@ -45,26 +44,26 @@ @Test public void findDescriptorByFullName() throws Exception { Descriptor descriptor = UnittestProto.TestAllTypes.getDescriptor(); - assertNull(TypeRegistry.getEmptyTypeRegistry().find(descriptor.getFullName())); + assertThat(TypeRegistry.getEmptyTypeRegistry().find(descriptor.getFullName())).isNull(); - assertSame( - descriptor, - TypeRegistry.newBuilder().add(descriptor).build().find(descriptor.getFullName())); + assertThat(TypeRegistry.newBuilder().add(descriptor).build().find(descriptor.getFullName())) + .isSameInstanceAs(descriptor); } @Test public void findDescriptorByTypeUrl() throws Exception { Descriptor descriptor = UnittestProto.TestAllTypes.getDescriptor(); - assertNull( - TypeRegistry.getEmptyTypeRegistry() - .getDescriptorForTypeUrl("type.googleapis.com/" + descriptor.getFullName())); + assertThat( + TypeRegistry.getEmptyTypeRegistry() + .getDescriptorForTypeUrl("type.googleapis.com/" + descriptor.getFullName())) + .isNull(); - assertSame( - descriptor, - TypeRegistry.newBuilder() - .add(descriptor) - .build() - .getDescriptorForTypeUrl("type.googleapis.com/" + descriptor.getFullName())); + assertThat( + TypeRegistry.newBuilder() + .add(descriptor) + .build() + .getDescriptorForTypeUrl("type.googleapis.com/" + descriptor.getFullName())) + .isSameInstanceAs(descriptor); } }
diff --git a/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java b/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java index 7daef02..bf4af71 100644 --- a/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java +++ b/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java
@@ -30,6 +30,9 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; @@ -40,75 +43,83 @@ import com.google.protobuf.Proto2UnknownEnumValuesTestProto.Proto2TestEnum; import com.google.protobuf.Proto2UnknownEnumValuesTestProto.Proto2TestEnumSubset; import com.google.protobuf.TextFormat.ParseException; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** * Unit tests for protos that keep unknown enum values rather than discard them as unknown fields. */ -public class UnknownEnumValueTest extends TestCase { +@RunWith(JUnit4.class) +public class UnknownEnumValueTest { + @Test public void testUnknownEnumValues() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); builder.setOptionalNestedEnumValue(4321); builder.addRepeatedNestedEnumValue(5432); builder.addPackedNestedEnumValue(6543); TestAllTypes message = builder.build(); - assertEquals(4321, message.getOptionalNestedEnumValue()); - assertEquals(5432, message.getRepeatedNestedEnumValue(0)); - assertEquals(5432, message.getRepeatedNestedEnumValueList().get(0).intValue()); - assertEquals(6543, message.getPackedNestedEnumValue(0)); + assertThat(message.getOptionalNestedEnumValue()).isEqualTo(4321); + assertThat(message.getRepeatedNestedEnumValue(0)).isEqualTo(5432); + assertThat(message.getRepeatedNestedEnumValueList().get(0).intValue()).isEqualTo(5432); + assertThat(message.getPackedNestedEnumValue(0)).isEqualTo(6543); // Returns UNRECOGNIZED if an enum type is requested. - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getOptionalNestedEnum()); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getRepeatedNestedEnum(0)); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getRepeatedNestedEnumList().get(0)); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getPackedNestedEnum(0)); + assertThat(message.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(message.getRepeatedNestedEnum(0)).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(message.getRepeatedNestedEnumList().get(0)) + .isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(message.getPackedNestedEnum(0)).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); // Test serialization and parsing. ByteString data = message.toByteString(); message = TestAllTypes.parseFrom(data); - assertEquals(4321, message.getOptionalNestedEnumValue()); - assertEquals(5432, message.getRepeatedNestedEnumValue(0)); - assertEquals(5432, message.getRepeatedNestedEnumValueList().get(0).intValue()); - assertEquals(6543, message.getPackedNestedEnumValue(0)); + assertThat(message.getOptionalNestedEnumValue()).isEqualTo(4321); + assertThat(message.getRepeatedNestedEnumValue(0)).isEqualTo(5432); + assertThat(message.getRepeatedNestedEnumValueList().get(0).intValue()).isEqualTo(5432); + assertThat(message.getPackedNestedEnumValue(0)).isEqualTo(6543); // Returns UNRECOGNIZED if an enum type is requested. - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getOptionalNestedEnum()); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getRepeatedNestedEnum(0)); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getRepeatedNestedEnumList().get(0)); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, message.getPackedNestedEnum(0)); + assertThat(message.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(message.getRepeatedNestedEnum(0)).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(message.getRepeatedNestedEnumList().get(0)) + .isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(message.getPackedNestedEnum(0)).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); // Test toBuilder(). builder = message.toBuilder(); - assertEquals(4321, builder.getOptionalNestedEnumValue()); - assertEquals(5432, builder.getRepeatedNestedEnumValue(0)); - assertEquals(5432, builder.getRepeatedNestedEnumValueList().get(0).intValue()); - assertEquals(6543, builder.getPackedNestedEnumValue(0)); + assertThat(builder.getOptionalNestedEnumValue()).isEqualTo(4321); + assertThat(builder.getRepeatedNestedEnumValue(0)).isEqualTo(5432); + assertThat(builder.getRepeatedNestedEnumValueList().get(0).intValue()).isEqualTo(5432); + assertThat(builder.getPackedNestedEnumValue(0)).isEqualTo(6543); // Returns UNRECOGNIZED if an enum type is requested. - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getOptionalNestedEnum()); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getRepeatedNestedEnum(0)); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getRepeatedNestedEnumList().get(0)); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getPackedNestedEnum(0)); + assertThat(builder.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(builder.getRepeatedNestedEnum(0)).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(builder.getRepeatedNestedEnumList().get(0)) + .isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(builder.getPackedNestedEnum(0)).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); // Test mergeFrom(). builder = TestAllTypes.newBuilder().mergeFrom(message); - assertEquals(4321, builder.getOptionalNestedEnumValue()); - assertEquals(5432, builder.getRepeatedNestedEnumValue(0)); - assertEquals(5432, builder.getRepeatedNestedEnumValueList().get(0).intValue()); - assertEquals(6543, builder.getPackedNestedEnumValue(0)); + assertThat(builder.getOptionalNestedEnumValue()).isEqualTo(4321); + assertThat(builder.getRepeatedNestedEnumValue(0)).isEqualTo(5432); + assertThat(builder.getRepeatedNestedEnumValueList().get(0).intValue()).isEqualTo(5432); + assertThat(builder.getPackedNestedEnumValue(0)).isEqualTo(6543); // Returns UNRECOGNIZED if an enum type is requested. - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getOptionalNestedEnum()); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getRepeatedNestedEnum(0)); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getRepeatedNestedEnumList().get(0)); - assertEquals(TestAllTypes.NestedEnum.UNRECOGNIZED, builder.getPackedNestedEnum(0)); + assertThat(builder.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(builder.getRepeatedNestedEnum(0)).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(builder.getRepeatedNestedEnumList().get(0)) + .isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(builder.getPackedNestedEnum(0)).isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); // Test equals() and hashCode() TestAllTypes sameMessage = builder.build(); - assertEquals(message, sameMessage); - assertEquals(message.hashCode(), sameMessage.hashCode()); + assertThat(sameMessage).isEqualTo(message); + assertThat(sameMessage.hashCode()).isEqualTo(message.hashCode()); // Getting the numeric value of UNRECOGNIZED will throw an exception. try { TestAllTypes.NestedEnum.UNRECOGNIZED.getNumber(); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IllegalArgumentException e) { // Expected. } @@ -116,18 +127,19 @@ // Setting an enum field to an UNRECOGNIZED value will throw an exception. try { builder.setOptionalNestedEnum(builder.getOptionalNestedEnum()); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IllegalArgumentException e) { // Expected. } try { builder.addRepeatedNestedEnum(builder.getOptionalNestedEnum()); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IllegalArgumentException e) { // Expected. } } + @Test public void testUnknownEnumValueInReflectionApi() throws Exception { Descriptor descriptor = TestAllTypes.getDescriptor(); FieldDescriptor optionalNestedEnumField = descriptor.findFieldByName("optional_nested_enum"); @@ -150,17 +162,17 @@ (EnumValueDescriptor) message.getRepeatedField(repeatedNestedEnumField, 0); EnumValueDescriptor unknown6543 = (EnumValueDescriptor) message.getRepeatedField(packedNestedEnumField, 0); - assertEquals(4321, unknown4321.getNumber()); - assertEquals(5432, unknown5432.getNumber()); - assertEquals(6543, unknown6543.getNumber()); + assertThat(unknown4321.getNumber()).isEqualTo(4321); + assertThat(unknown5432.getNumber()).isEqualTo(5432); + assertThat(unknown6543.getNumber()).isEqualTo(6543); // Unknown EnumValueDescriptor will map to UNRECOGNIZED. - assertEquals( - TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown4321)); - assertEquals( - TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown5432)); - assertEquals( - TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown6543)); + assertThat(TestAllTypes.NestedEnum.valueOf(unknown4321)) + .isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(TestAllTypes.NestedEnum.valueOf(unknown5432)) + .isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); + assertThat(TestAllTypes.NestedEnum.valueOf(unknown6543)) + .isEqualTo(TestAllTypes.NestedEnum.UNRECOGNIZED); // Setters also accept unknown EnumValueDescriptor. builder.setField(optionalNestedEnumField, unknown6543); @@ -169,11 +181,12 @@ message = builder.build(); // Like other descriptors, unknown EnumValueDescriptor can be compared by // object identity. - assertSame(message.getField(optionalNestedEnumField), unknown6543); - assertSame(message.getRepeatedField(repeatedNestedEnumField, 0), unknown4321); - assertSame(message.getRepeatedField(packedNestedEnumField, 0), unknown5432); + assertThat(unknown6543).isSameInstanceAs(message.getField(optionalNestedEnumField)); + assertThat(unknown4321).isSameInstanceAs(message.getRepeatedField(repeatedNestedEnumField, 0)); + assertThat(unknown5432).isSameInstanceAs(message.getRepeatedField(packedNestedEnumField, 0)); } + @Test public void testUnknownEnumValueWithDynamicMessage() throws Exception { Descriptor descriptor = TestAllTypes.getDescriptor(); FieldDescriptor optionalNestedEnumField = descriptor.findFieldByName("optional_nested_enum"); @@ -190,26 +203,28 @@ builder.addRepeatedField( packedNestedEnumField, enumType.findValueByNumberCreatingIfUnknown(6543)); Message message = builder.build(); - assertEquals( - 4321, ((EnumValueDescriptor) message.getField(optionalNestedEnumField)).getNumber()); - assertEquals( - 5432, - ((EnumValueDescriptor) message.getRepeatedField(repeatedNestedEnumField, 0)).getNumber()); - assertEquals( - 6543, - ((EnumValueDescriptor) message.getRepeatedField(packedNestedEnumField, 0)).getNumber()); + assertThat(((EnumValueDescriptor) message.getField(optionalNestedEnumField)).getNumber()) + .isEqualTo(4321); + assertThat( + ((EnumValueDescriptor) message.getRepeatedField(repeatedNestedEnumField, 0)) + .getNumber()) + .isEqualTo(5432); + assertThat( + ((EnumValueDescriptor) message.getRepeatedField(packedNestedEnumField, 0)).getNumber()) + .isEqualTo(6543); // Test reflection based serialization/parsing implementation. ByteString data = message.toByteString(); message = dynamicMessageDefaultInstance.newBuilderForType().mergeFrom(data).build(); - assertEquals( - 4321, ((EnumValueDescriptor) message.getField(optionalNestedEnumField)).getNumber()); - assertEquals( - 5432, - ((EnumValueDescriptor) message.getRepeatedField(repeatedNestedEnumField, 0)).getNumber()); - assertEquals( - 6543, - ((EnumValueDescriptor) message.getRepeatedField(packedNestedEnumField, 0)).getNumber()); + assertThat(((EnumValueDescriptor) message.getField(optionalNestedEnumField)).getNumber()) + .isEqualTo(4321); + assertThat( + ((EnumValueDescriptor) message.getRepeatedField(repeatedNestedEnumField, 0)) + .getNumber()) + .isEqualTo(5432); + assertThat( + ((EnumValueDescriptor) message.getRepeatedField(packedNestedEnumField, 0)).getNumber()) + .isEqualTo(6543); // Test reflection based equals()/hashCode(). builder = dynamicMessageDefaultInstance.newBuilderForType(); @@ -219,13 +234,14 @@ builder.addRepeatedField( packedNestedEnumField, enumType.findValueByNumberCreatingIfUnknown(6543)); Message sameMessage = builder.build(); - assertEquals(message, sameMessage); - assertEquals(message.hashCode(), sameMessage.hashCode()); + assertThat(sameMessage).isEqualTo(message); + assertThat(sameMessage.hashCode()).isEqualTo(message.hashCode()); builder.setField(optionalNestedEnumField, enumType.findValueByNumberCreatingIfUnknown(0)); Message differentMessage = builder.build(); - assertFalse(message.equals(differentMessage)); + assertThat(message.equals(differentMessage)).isFalse(); } + @Test public void testUnknownEnumValuesInTextFormat() { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); builder.setOptionalNestedEnumValue(4321); @@ -235,22 +251,23 @@ // We can print a message with unknown enum values. String textData = TextFormat.printer().printToString(message); - assertEquals( - "optional_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_4321\n" - + "repeated_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_5432\n" - + "packed_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_6543\n", - textData); + assertThat(textData) + .isEqualTo( + "optional_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_4321\n" + + "repeated_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_5432\n" + + "packed_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_6543\n"); // Parsing unknown enum values will fail just like parsing other kinds of // unknown fields. try { TextFormat.merge(textData, builder); - fail(); + assertWithMessage("Expected exception").fail(); } catch (ParseException e) { // expected. } } + @Test public void testUnknownEnumValuesInProto2() throws Exception { Proto2EnumMessage.Builder sourceMessage = Proto2EnumMessage.newBuilder(); sourceMessage @@ -262,21 +279,24 @@ Proto2EnumMessageWithEnumSubset.parseFrom(sourceMessage.build().toByteArray()); // Known enum values should be preserved. - assertEquals(2, destMessage.getRepeatedPackedEnumCount()); - assertEquals(Proto2TestEnumSubset.TESTENUM_SUBSET_ZERO, destMessage.getRepeatedPackedEnum(0)); - assertEquals(Proto2TestEnumSubset.TESTENUM_SUBSET_ONE, destMessage.getRepeatedPackedEnum(1)); + assertThat(destMessage.getRepeatedPackedEnumCount()).isEqualTo(2); + assertThat(destMessage.getRepeatedPackedEnum(0)) + .isEqualTo(Proto2TestEnumSubset.TESTENUM_SUBSET_ZERO); + assertThat(destMessage.getRepeatedPackedEnum(1)) + .isEqualTo(Proto2TestEnumSubset.TESTENUM_SUBSET_ONE); // Unknown enum values should be found in UnknownFieldSet. UnknownFieldSet unknown = destMessage.getUnknownFields(); - assertEquals( - Proto2TestEnum.TWO_VALUE, - unknown - .getField(Proto2EnumMessageWithEnumSubset.REPEATED_PACKED_ENUM_FIELD_NUMBER) - .getVarintList() - .get(0) - .longValue()); + assertThat( + unknown + .getField(Proto2EnumMessageWithEnumSubset.REPEATED_PACKED_ENUM_FIELD_NUMBER) + .getVarintList() + .get(0) + .longValue()) + .isEqualTo(Proto2TestEnum.TWO_VALUE); } + @Test public void testUnknownEnumValuesInProto2WithDynamicMessage() throws Exception { Descriptor descriptor = Proto2EnumMessageWithEnumSubset.getDescriptor(); FieldDescriptor repeatedPackedField = descriptor.findFieldByName("repeated_packed_enum"); @@ -292,19 +312,18 @@ Proto2EnumMessageWithEnumSubset.getDescriptor(), sourceMessage.build().toByteArray()); // Known enum values should be preserved. - assertEquals(2, message.getRepeatedFieldCount(repeatedPackedField)); + assertThat(message.getRepeatedFieldCount(repeatedPackedField)).isEqualTo(2); EnumValueDescriptor enumValue0 = (EnumValueDescriptor) message.getRepeatedField(repeatedPackedField, 0); EnumValueDescriptor enumValue1 = (EnumValueDescriptor) message.getRepeatedField(repeatedPackedField, 1); - assertEquals(Proto2TestEnumSubset.TESTENUM_SUBSET_ZERO_VALUE, enumValue0.getNumber()); - assertEquals(Proto2TestEnumSubset.TESTENUM_SUBSET_ONE_VALUE, enumValue1.getNumber()); + assertThat(enumValue0.getNumber()).isEqualTo(Proto2TestEnumSubset.TESTENUM_SUBSET_ZERO_VALUE); + assertThat(enumValue1.getNumber()).isEqualTo(Proto2TestEnumSubset.TESTENUM_SUBSET_ONE_VALUE); // Unknown enum values should be found in UnknownFieldSet. UnknownFieldSet unknown = message.getUnknownFields(); - assertEquals( - Proto2TestEnum.TWO_VALUE, - unknown.getField(repeatedPackedField.getNumber()).getVarintList().get(0).longValue()); + assertThat(unknown.getField(repeatedPackedField.getNumber()).getVarintList().get(0).longValue()) + .isEqualTo(Proto2TestEnum.TWO_VALUE); } }
diff --git a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java index c7eb57c..1e5bc96 100644 --- a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java +++ b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
@@ -30,6 +30,9 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import protobuf_unittest.UnittestProto; import protobuf_unittest.UnittestProto.ForeignEnum; import protobuf_unittest.UnittestProto.TestAllExtensions; @@ -39,17 +42,17 @@ import protobuf_unittest.UnittestProto.TestPackedExtensions; import protobuf_unittest.UnittestProto.TestPackedTypes; import proto3_unittest.UnittestProto3; -import java.util.Arrays; import java.util.Map; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Tests related to unknown field handling. - * - * @author kenton@google.com (Kenton Varda) - */ -public class UnknownFieldSetTest extends TestCase { - @Override +/** Tests related to unknown field handling. */ +@RunWith(JUnit4.class) +public class UnknownFieldSetTest { + + @Before public void setUp() throws Exception { descriptor = TestAllTypes.getDescriptor(); allFields = TestUtil.getAllSet(); @@ -60,7 +63,7 @@ UnknownFieldSet.Field getField(String name) { Descriptors.FieldDescriptor field = descriptor.findFieldByName(name); - assertNotNull(field); + assertThat(field).isNotNull(); return unknownFields.getField(field.getNumber()); } @@ -97,60 +100,69 @@ // ================================================================= + @Test public void testVarint() throws Exception { UnknownFieldSet.Field field = getField("optional_int32"); - assertEquals(1, field.getVarintList().size()); - assertEquals(allFields.getOptionalInt32(), (long) field.getVarintList().get(0)); + assertThat(field.getVarintList()).hasSize(1); + assertThat((long) field.getVarintList().get(0)).isEqualTo(allFields.getOptionalInt32()); } + @Test public void testFixed32() throws Exception { UnknownFieldSet.Field field = getField("optional_fixed32"); - assertEquals(1, field.getFixed32List().size()); - assertEquals(allFields.getOptionalFixed32(), (int) field.getFixed32List().get(0)); + assertThat(field.getFixed32List()).hasSize(1); + assertThat((int) field.getFixed32List().get(0)).isEqualTo(allFields.getOptionalFixed32()); } + @Test public void testFixed64() throws Exception { UnknownFieldSet.Field field = getField("optional_fixed64"); - assertEquals(1, field.getFixed64List().size()); - assertEquals(allFields.getOptionalFixed64(), (long) field.getFixed64List().get(0)); + assertThat(field.getFixed64List()).hasSize(1); + assertThat((long) field.getFixed64List().get(0)).isEqualTo(allFields.getOptionalFixed64()); } + @Test public void testLengthDelimited() throws Exception { UnknownFieldSet.Field field = getField("optional_bytes"); - assertEquals(1, field.getLengthDelimitedList().size()); - assertEquals(allFields.getOptionalBytes(), field.getLengthDelimitedList().get(0)); + assertThat(field.getLengthDelimitedList()).hasSize(1); + assertThat(field.getLengthDelimitedList().get(0)).isEqualTo(allFields.getOptionalBytes()); } + @Test public void testGroup() throws Exception { Descriptors.FieldDescriptor nestedFieldDescriptor = TestAllTypes.OptionalGroup.getDescriptor().findFieldByName("a"); - assertNotNull(nestedFieldDescriptor); + assertThat(nestedFieldDescriptor).isNotNull(); UnknownFieldSet.Field field = getField("optionalgroup"); - assertEquals(1, field.getGroupList().size()); + assertThat(field.getGroupList()).hasSize(1); UnknownFieldSet group = field.getGroupList().get(0); - assertEquals(1, group.asMap().size()); - assertTrue(group.hasField(nestedFieldDescriptor.getNumber())); + assertThat(group.asMap()).hasSize(1); + assertThat(group.hasField(nestedFieldDescriptor.getNumber())).isTrue(); UnknownFieldSet.Field nestedField = group.getField(nestedFieldDescriptor.getNumber()); - assertEquals(1, nestedField.getVarintList().size()); - assertEquals(allFields.getOptionalGroup().getA(), (long) nestedField.getVarintList().get(0)); + assertThat(nestedField.getVarintList()).hasSize(1); + assertThat((long) nestedField.getVarintList().get(0)) + .isEqualTo(allFields.getOptionalGroup().getA()); } + @Test public void testSerialize() throws Exception { // Check that serializing the UnknownFieldSet produces the original data // again. ByteString data = emptyMessage.toByteString(); - assertEquals(allFieldsData, data); + assertThat(data).isEqualTo(allFieldsData); } + @Test public void testCopyFrom() throws Exception { TestEmptyMessage message = TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).build(); - assertEquals(emptyMessage.toString(), message.toString()); + assertThat(message.toString()).isEqualTo(emptyMessage.toString()); } + @Test public void testMergeFrom() throws Exception { TestEmptyMessage source = TestEmptyMessage.newBuilder() @@ -170,27 +182,31 @@ .mergeFrom(source) .build(); - assertEquals("1: 1\n2: 2\n3: 3\n3: 4\n", destination.toString()); + assertThat(destination.toString()).isEqualTo("1: 1\n2: 2\n3: 3\n3: 4\n"); } + @Test public void testClear() throws Exception { UnknownFieldSet fields = UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build(); - assertTrue(fields.asMap().isEmpty()); + assertThat(fields.asMap()).isEmpty(); } + @Test public void testClearMessage() throws Exception { TestEmptyMessage message = TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).clear().build(); - assertEquals(0, message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(0); } + @Test public void testClearField() throws Exception { int fieldNumber = unknownFields.asMap().keySet().iterator().next(); UnknownFieldSet fields = UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clearField(fieldNumber).build(); - assertFalse(fields.hasField(fieldNumber)); + assertThat(fields.hasField(fieldNumber)).isFalse(); } + @Test public void testParseKnownAndUnknown() throws Exception { // Test mixing known and unknown fields when parsing. @@ -203,13 +219,14 @@ TestAllTypes destination = TestAllTypes.parseFrom(data); TestUtil.assertAllFieldsSet(destination); - assertEquals(1, destination.getUnknownFields().asMap().size()); + assertThat(destination.getUnknownFields().asMap()).hasSize(1); UnknownFieldSet.Field field = destination.getUnknownFields().getField(123456); - assertEquals(1, field.getVarintList().size()); - assertEquals(654321, (long) field.getVarintList().get(0)); + assertThat(field.getVarintList()).hasSize(1); + assertThat((long) field.getVarintList().get(0)).isEqualTo(654321); } + @Test public void testWrongTypeTreatedAsUnknown() throws Exception { // Test that fields of the wrong wire type are treated like unknown fields // when parsing. @@ -220,9 +237,10 @@ // All fields should have been interpreted as unknown, so the debug strings // should be the same. - assertEquals(emptyMessage.toString(), allTypesMessage.toString()); + assertThat(emptyMessage.toString()).isEqualTo(allTypesMessage.toString()); } + @Test public void testUnknownExtensions() throws Exception { // Make sure fields are properly parsed to the UnknownFieldSet even when // they are declared as extension numbers. @@ -230,10 +248,11 @@ TestEmptyMessageWithExtensions message = TestEmptyMessageWithExtensions.parseFrom(allFieldsData); - assertEquals(unknownFields.asMap().size(), message.getUnknownFields().asMap().size()); - assertEquals(allFieldsData, message.toByteString()); + assertThat(unknownFields.asMap()).hasSize(message.getUnknownFields().asMap().size()); + assertThat(allFieldsData).isEqualTo(message.toByteString()); } + @Test public void testWrongExtensionTypeTreatedAsUnknown() throws Exception { // Test that fields of the wrong wire type are treated like unknown fields // when parsing extensions. @@ -244,16 +263,17 @@ // All fields should have been interpreted as unknown, so the debug strings // should be the same. - assertEquals(emptyMessage.toString(), allExtensionsMessage.toString()); + assertThat(emptyMessage.toString()).isEqualTo(allExtensionsMessage.toString()); } + @Test public void testParseUnknownEnumValue() throws Exception { Descriptors.FieldDescriptor singularField = TestAllTypes.getDescriptor().findFieldByName("optional_nested_enum"); Descriptors.FieldDescriptor repeatedField = TestAllTypes.getDescriptor().findFieldByName("repeated_nested_enum"); - assertNotNull(singularField); - assertNotNull(repeatedField); + assertThat(singularField).isNotNull(); + assertThat(repeatedField).isNotNull(); ByteString data = UnknownFieldSet.newBuilder() @@ -276,36 +296,34 @@ { TestAllTypes message = TestAllTypes.parseFrom(data); - assertEquals(TestAllTypes.NestedEnum.BAR, message.getOptionalNestedEnum()); - assertEquals( - Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ), - message.getRepeatedNestedEnumList()); - assertEquals( - Arrays.asList(5L), - message.getUnknownFields().getField(singularField.getNumber()).getVarintList()); - assertEquals( - Arrays.asList(4L, 6L), - message.getUnknownFields().getField(repeatedField.getNumber()).getVarintList()); + assertThat(message.getOptionalNestedEnum()).isEqualTo(TestAllTypes.NestedEnum.BAR); + assertThat(message.getRepeatedNestedEnumList()) + .containsExactly(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ) + .inOrder(); + assertThat(message.getUnknownFields().getField(singularField.getNumber()).getVarintList()) + .containsExactly(5L); + assertThat(message.getUnknownFields().getField(repeatedField.getNumber()).getVarintList()) + .containsExactly(4L, 6L) + .inOrder(); } { TestAllExtensions message = TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry()); - assertEquals( - TestAllTypes.NestedEnum.BAR, - message.getExtension(UnittestProto.optionalNestedEnumExtension)); - assertEquals( - Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ), - message.getExtension(UnittestProto.repeatedNestedEnumExtension)); - assertEquals( - Arrays.asList(5L), - message.getUnknownFields().getField(singularField.getNumber()).getVarintList()); - assertEquals( - Arrays.asList(4L, 6L), - message.getUnknownFields().getField(repeatedField.getNumber()).getVarintList()); + assertThat(message.getExtension(UnittestProto.optionalNestedEnumExtension)) + .isEqualTo(TestAllTypes.NestedEnum.BAR); + assertThat(message.getExtension(UnittestProto.repeatedNestedEnumExtension)) + .containsExactly(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ) + .inOrder(); + assertThat(message.getUnknownFields().getField(singularField.getNumber()).getVarintList()) + .containsExactly(5L); + assertThat(message.getUnknownFields().getField(repeatedField.getNumber()).getVarintList()) + .containsExactly(4L, 6L) + .inOrder(); } } + @Test public void testLargeVarint() throws Exception { ByteString data = UnknownFieldSet.newBuilder() @@ -314,10 +332,11 @@ .toByteString(); UnknownFieldSet parsed = UnknownFieldSet.parseFrom(data); UnknownFieldSet.Field field = parsed.getField(1); - assertEquals(1, field.getVarintList().size()); - assertEquals(0x7FFFFFFFFFFFFFFFL, (long) field.getVarintList().get(0)); + assertThat(field.getVarintList()).hasSize(1); + assertThat((long) field.getVarintList().get(0)).isEqualTo(0x7FFFFFFFFFFFFFFFL); } + @Test public void testEqualsAndHashCode() { UnknownFieldSet.Field fixed32Field = UnknownFieldSet.Field.newBuilder().addFixed32(1).build(); UnknownFieldSet.Field fixed64Field = UnknownFieldSet.Field.newBuilder().addFixed64(1).build(); @@ -359,49 +378,50 @@ */ private void checkNotEqual(UnknownFieldSet s1, UnknownFieldSet s2) { String equalsError = String.format("%s should not be equal to %s", s1, s2); - assertFalse(equalsError, s1.equals(s2)); - assertFalse(equalsError, s2.equals(s1)); + assertWithMessage(equalsError).that(s1).isNotEqualTo(s2); + assertWithMessage(equalsError).that(s2).isNotEqualTo(s1); - assertFalse( - String.format("%s should have a different hash code from %s", s1, s2), - s1.hashCode() == s2.hashCode()); + assertWithMessage("%s should have a different hash code from %s", s1, s2) + .that(s1.hashCode()) + .isNotEqualTo(s2.hashCode()); } /** Asserts that the given field sets are equal and have identical hash codes. */ private void checkEqualsIsConsistent(UnknownFieldSet set) { // Object should be equal to itself. - assertEquals(set, set); + assertThat(set.equals(set)).isTrue(); // Object should be equal to a copy of itself. UnknownFieldSet copy = UnknownFieldSet.newBuilder(set).build(); - assertEquals(set, copy); - assertEquals(copy, set); - assertEquals(set.hashCode(), copy.hashCode()); + assertThat(copy).isEqualTo(set); + assertThat(set).isEqualTo(copy); + assertThat(set.hashCode()).isEqualTo(copy.hashCode()); } // ================================================================= + @Test public void testProto3RoundTrip() throws Exception { ByteString data = getBizarroData(); UnittestProto3.TestEmptyMessage message = UnittestProto3.TestEmptyMessage.parseFrom(data, ExtensionRegistryLite.getEmptyRegistry()); - assertEquals(data, message.toByteString()); + assertThat(message.toByteString()).isEqualTo(data); message = UnittestProto3.TestEmptyMessage.newBuilder().mergeFrom(message).build(); - assertEquals(data, message.toByteString()); + assertThat(message.toByteString()).isEqualTo(data); - assertEquals( - data, - UnittestProto3.TestMessageWithDummy.parseFrom( - data, ExtensionRegistryLite.getEmptyRegistry()) - .toBuilder() - // force copy-on-write - .setDummy(true) - .build() - .toBuilder() - .clearDummy() - .build() - .toByteString()); + assertThat(data) + .isEqualTo( + UnittestProto3.TestMessageWithDummy.parseFrom( + data, ExtensionRegistryLite.getEmptyRegistry()) + .toBuilder() + // force copy-on-write + .setDummy(true) + .build() + .toBuilder() + .clearDummy() + .build() + .toByteString()); } }
diff --git a/java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java b/java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java index bc73cc9..d5d9195 100644 --- a/java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java +++ b/java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java
@@ -30,17 +30,19 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import java.util.Iterator; import java.util.List; import java.util.ListIterator; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Tests for {@link UnmodifiableLazyStringList}. - * - * @author jonp@google.com (Jon Perlow) - */ -public class UnmodifiableLazyStringListTest extends TestCase { +/** Tests for {@link UnmodifiableLazyStringList}. */ +@RunWith(JUnit4.class) +public class UnmodifiableLazyStringListTest { private static final String STRING_A = "A"; private static final String STRING_B = "B"; @@ -50,80 +52,83 @@ private static final ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B"); private static final ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C"); + @Test public void testReadOnlyMethods() { LazyStringArrayList rawList = createSampleList(); UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); - assertEquals(3, list.size()); - assertSame(STRING_A, list.get(0)); - assertSame(STRING_B, list.get(1)); - assertSame(STRING_C, list.get(2)); - assertEquals(BYTE_STRING_A, list.getByteString(0)); - assertEquals(BYTE_STRING_B, list.getByteString(1)); - assertEquals(BYTE_STRING_C, list.getByteString(2)); + assertThat(list).hasSize(3); + assertThat(list.get(0)).isSameInstanceAs(STRING_A); + assertThat(list.get(1)).isSameInstanceAs(STRING_B); + assertThat(list.get(2)).isSameInstanceAs(STRING_C); + assertThat(list.getByteString(0)).isEqualTo(BYTE_STRING_A); + assertThat(list.getByteString(1)).isEqualTo(BYTE_STRING_B); + assertThat(list.getByteString(2)).isEqualTo(BYTE_STRING_C); List<ByteString> byteStringList = list.asByteStringList(); - assertSame(list.getByteString(0), byteStringList.get(0)); - assertSame(list.getByteString(1), byteStringList.get(1)); - assertSame(list.getByteString(2), byteStringList.get(2)); + assertThat(byteStringList.get(0)).isSameInstanceAs(list.getByteString(0)); + assertThat(byteStringList.get(1)).isSameInstanceAs(list.getByteString(1)); + assertThat(byteStringList.get(2)).isSameInstanceAs(list.getByteString(2)); } + @Test public void testModifyMethods() { LazyStringArrayList rawList = createSampleList(); UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); try { list.remove(0); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(3, list.size()); + assertThat(list).hasSize(3); try { list.add(STRING_B); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(3, list.size()); + assertThat(list).hasSize(3); try { list.set(1, STRING_B); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(3, list.size()); + assertThat(list).hasSize(3); List<ByteString> byteStringList = list.asByteStringList(); try { byteStringList.remove(0); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(3, list.size()); - assertEquals(3, byteStringList.size()); + assertThat(list).hasSize(3); + assertThat(byteStringList).hasSize(3); try { byteStringList.add(BYTE_STRING_B); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(3, list.size()); - assertEquals(3, byteStringList.size()); + assertThat(list).hasSize(3); + assertThat(byteStringList).hasSize(3); try { byteStringList.set(1, BYTE_STRING_B); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } - assertEquals(3, list.size()); - assertEquals(3, byteStringList.size()); + assertThat(list).hasSize(3); + assertThat(byteStringList).hasSize(3); } + @Test public void testIterator() { LazyStringArrayList rawList = createSampleList(); UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); @@ -135,12 +140,12 @@ count++; try { iter.remove(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } } - assertEquals(3, count); + assertThat(count).isEqualTo(3); List<ByteString> byteStringList = list.asByteStringList(); Iterator<ByteString> byteIter = byteStringList.iterator(); @@ -150,14 +155,15 @@ count++; try { byteIter.remove(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } } - assertEquals(3, count); + assertThat(count).isEqualTo(3); } + @Test public void testListIterator() { LazyStringArrayList rawList = createSampleList(); UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList); @@ -169,24 +175,24 @@ count++; try { iter.remove(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { iter.set("bar"); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { iter.add("bar"); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } } - assertEquals(3, count); + assertThat(count).isEqualTo(3); List<ByteString> byteStringList = list.asByteStringList(); ListIterator<ByteString> byteIter = byteStringList.listIterator(); @@ -196,24 +202,24 @@ count++; try { byteIter.remove(); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { byteIter.set(BYTE_STRING_A); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } try { byteIter.add(BYTE_STRING_A); - fail(); + assertWithMessage("expected exception").fail(); } catch (UnsupportedOperationException e) { // expected } } - assertEquals(3, count); + assertThat(count).isEqualTo(3); } private LazyStringArrayList createSampleList() {
diff --git a/java/core/src/test/java/com/google/protobuf/Utf8Test.java b/java/core/src/test/java/com/google/protobuf/Utf8Test.java index bc3c985..89f080e 100644 --- a/java/core/src/test/java/com/google/protobuf/Utf8Test.java +++ b/java/core/src/test/java/com/google/protobuf/Utf8Test.java
@@ -30,19 +30,23 @@ package com.google.protobuf; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Random; -import java.util.regex.Pattern; -import junit.framework.TestCase; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; -/** Unit tests for {@link Utf8}. */ -public class Utf8Test extends TestCase { +import java.nio.ByteBuffer; +import java.util.Random; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class Utf8Test { private static final int NUM_CHARS = 16384; private static final Utf8.Processor safeProcessor = new Utf8.SafeProcessor(); private static final Utf8.Processor unsafeProcessor = new Utf8.UnsafeProcessor(); + @Test public void testEncode() { assertEncoding(randomString(0x80)); assertEncoding(randomString(0x90)); @@ -51,6 +55,7 @@ assertEncoding(randomString(0x10ffff)); } + @Test public void testEncode_insufficientSpace() { assertEncoding_insufficientSpace(randomString(0x80)); assertEncoding_insufficientSpace(randomString(0x90)); @@ -59,22 +64,26 @@ assertEncoding_insufficientSpace(randomString(0x10ffff)); } + @Test public void testValid() { assertIsValid(new byte[] {(byte) 0xE0, (byte) 0xB9, (byte) 0x96}, true); assertIsValid(new byte[] {(byte) 0xF0, (byte) 0xB2, (byte) 0x83, (byte) 0xBC}, true); } + @Test public void testOverlongIsInvalid() { assertIsValid(new byte[] {(byte) 0xC0, (byte) 0x81}, false); assertIsValid(new byte[] {(byte) 0xE0, (byte) 0x81, (byte) 0x81}, false); assertIsValid(new byte[] {(byte) 0xF0, (byte) 0x81, (byte) 0x81, (byte) 0x81}, false); } + @Test public void testMaxCodepointExceeded() { // byte1 > 0xF4 assertIsValid(new byte[] {(byte) 0xF5, (byte) 0x81, (byte) 0x81, (byte) 0x81}, false); } + @Test public void testInvalidSurrogateCodepoint() { assertIsValid(new byte[] {(byte) 0xED, (byte) 0xA1, (byte) 0x81}, false); @@ -99,46 +108,51 @@ } private static void assertIsValid(byte[] data, boolean valid) { - assertEquals("isValidUtf8[ARRAY]", valid, safeProcessor.isValidUtf8(data, 0, data.length)); - assertEquals( - "isValidUtf8[ARRAY_UNSAFE]", valid, unsafeProcessor.isValidUtf8(data, 0, data.length)); + assertWithMessage("isValidUtf8[ARRAY]") + .that(safeProcessor.isValidUtf8(data, 0, data.length)) + .isEqualTo(valid); + assertWithMessage("isValidUtf8[ARRAY_UNSAFE]") + .that(unsafeProcessor.isValidUtf8(data, 0, data.length)) + .isEqualTo(valid); ByteBuffer buffer = ByteBuffer.wrap(data); - assertEquals( - "isValidUtf8[NIO_HEAP]", - valid, - safeProcessor.isValidUtf8(buffer, buffer.position(), buffer.remaining())); + assertWithMessage("isValidUtf8[NIO_HEAP]") + .that(safeProcessor.isValidUtf8(buffer, buffer.position(), buffer.remaining())) + .isEqualTo(valid); // Direct buffers. buffer = ByteBuffer.allocateDirect(data.length); buffer.put(data); buffer.flip(); - assertEquals( - "isValidUtf8[NIO_DEFAULT]", - valid, - safeProcessor.isValidUtf8(buffer, buffer.position(), buffer.remaining())); - assertEquals( - "isValidUtf8[NIO_UNSAFE]", - valid, - unsafeProcessor.isValidUtf8(buffer, buffer.position(), buffer.remaining())); + assertWithMessage("isValidUtf8[NIO_DEFAULT]") + .that(safeProcessor.isValidUtf8(buffer, buffer.position(), buffer.remaining())) + .isEqualTo(valid); + assertWithMessage("isValidUtf8[NIO_UNSAFE]") + .that(unsafeProcessor.isValidUtf8(buffer, buffer.position(), buffer.remaining())) + .isEqualTo(valid); } private static void assertEncoding(String message) { byte[] expected = message.getBytes(Internal.UTF_8); byte[] output = encodeToByteArray(message, expected.length, safeProcessor); - assertTrue("encodeUtf8[ARRAY]", Arrays.equals(expected, output)); + assertWithMessage("encodeUtf8[ARRAY]") + .that(output).isEqualTo(expected); output = encodeToByteArray(message, expected.length, unsafeProcessor); - assertTrue("encodeUtf8[ARRAY_UNSAFE]", Arrays.equals(expected, output)); + assertWithMessage("encodeUtf8[ARRAY_UNSAFE]") + .that(output).isEqualTo(expected); output = encodeToByteBuffer(message, expected.length, false, safeProcessor); - assertTrue("encodeUtf8[NIO_HEAP]", Arrays.equals(expected, output)); + assertWithMessage("encodeUtf8[NIO_HEAP]") + .that(output).isEqualTo(expected); output = encodeToByteBuffer(message, expected.length, true, safeProcessor); - assertTrue("encodeUtf8[NIO_DEFAULT]", Arrays.equals(expected, output)); + assertWithMessage("encodeUtf8[NIO_DEFAULT]") + .that(output).isEqualTo(expected); output = encodeToByteBuffer(message, expected.length, true, unsafeProcessor); - assertTrue("encodeUtf8[NIO_UNSAFE]", Arrays.equals(expected, output)); + assertWithMessage("encodeUtf8[NIO_UNSAFE]") + .that(output).isEqualTo(expected); } private void assertEncoding_insufficientSpace(String message) { @@ -147,54 +161,56 @@ try { encodeToByteArray(message, length, safeProcessor); - fail("Expected " + clazz.getSimpleName()); + assertWithMessage("Expected " + clazz.getSimpleName()).fail(); } catch (Throwable t) { // Expected - assertExceptionType(t, clazz); + assertThat(t).isInstanceOf(clazz); // byte[] + safeProcessor will not exit early. We can't match the message since we don't // know which char/index due to random input. } try { encodeToByteArray(message, length, unsafeProcessor); - fail("Expected " + clazz.getSimpleName()); + assertWithMessage("Expected " + clazz.getSimpleName()).fail(); } catch (Throwable t) { - assertExceptionType(t, clazz); + assertThat(t).isInstanceOf(clazz); // byte[] + unsafeProcessor will exit early, so we have can match the message. - assertExceptionMessage(t, length); + String pattern = "Failed writing (.) at index " + length; + assertThat(t).hasMessageThat().matches(pattern); } try { encodeToByteBuffer(message, length, false, safeProcessor); - fail("Expected " + clazz.getSimpleName()); + assertWithMessage("Expected " + clazz.getSimpleName()).fail(); } catch (Throwable t) { // Expected - assertExceptionType(t, clazz); + assertThat(t).isInstanceOf(clazz); // ByteBuffer + safeProcessor will not exit early. We can't match the message since we don't // know which char/index due to random input. } try { encodeToByteBuffer(message, length, true, safeProcessor); - fail("Expected " + clazz.getSimpleName()); + assertWithMessage("Expected " + clazz.getSimpleName()).fail(); } catch (Throwable t) { // Expected - assertExceptionType(t, clazz); + assertThat(t).isInstanceOf(clazz); // ByteBuffer + safeProcessor will not exit early. We can't match the message since we don't // know which char/index due to random input. } try { encodeToByteBuffer(message, length, true, unsafeProcessor); - fail("Expected " + clazz.getSimpleName()); + assertWithMessage("Expected " + clazz.getSimpleName()).fail(); } catch (Throwable t) { // Expected - assertExceptionType(t, clazz); + assertThat(t).isInstanceOf(clazz); // Direct ByteBuffer + unsafeProcessor will exit early if it's not on Android, so we can // match the message. On Android, a direct ByteBuffer will have hasArray() being true and // it will take a different code path and produces a different message. if (!Android.isOnAndroidDevice()) { - assertExceptionMessage(t, length); + String pattern = "Failed writing (.) at index " + length; + assertThat(t).hasMessageThat().matches(pattern); } } } @@ -217,16 +233,4 @@ return output; } - private <T extends Throwable> void assertExceptionType(Throwable t, Class<T> expected) { - if (!expected.isAssignableFrom(t.getClass())) { - fail("Expected " + expected.getSimpleName() + ", but found " + t.getClass().getSimpleName()); - } - } - - private void assertExceptionMessage(Throwable t, int index) { - String pattern = "Failed writing (.) at index " + index; - assertTrue( - t.getMessage() + " does not match pattern " + pattern, - Pattern.matches(pattern, t.getMessage())); - } }
diff --git a/java/core/src/test/java/com/google/protobuf/WireFormatLiteTest.java b/java/core/src/test/java/com/google/protobuf/WireFormatLiteTest.java index a725d41..cbed9fc 100644 --- a/java/core/src/test/java/com/google/protobuf/WireFormatLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/WireFormatLiteTest.java
@@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite; import com.google.protobuf.UnittestLite.ForeignEnumLite; @@ -55,11 +57,15 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.Arrays; import java.util.List; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -public class WireFormatLiteTest extends TestCase { +@RunWith(JUnit4.class) +public class WireFormatLiteTest { + + @Test public void testSerializeExtensionsLite() throws Exception { // TestAllTypes and TestAllExtensions should have compatible wire formats, // so if we serialize a TestAllExtensions then parse it as TestAllTypes @@ -67,13 +73,14 @@ TestAllExtensionsLite message = TestUtilLite.getAllLiteExtensionsSet(); ByteString rawBytes = message.toByteString(); - assertEquals(rawBytes.size(), message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size()); TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); TestUtil.assertAllFieldsSet(message2); } + @Test public void testSerializePackedExtensionsLite() throws Exception { // TestPackedTypes and TestPackedExtensions should have compatible wire // formats; check that they serialize to the same string. @@ -83,9 +90,10 @@ TestPackedTypes message2 = TestUtil.getPackedSet(); ByteString rawBytes2 = message2.toByteString(); - assertEquals(rawBytes, rawBytes2); + assertThat(rawBytes2).isEqualTo(rawBytes); } + @Test public void testParseExtensionsLite() throws Exception { // TestAllTypes and TestAllExtensions should have compatible wire formats, // so if we serialize a TestAllTypes then parse it as TestAllExtensions @@ -102,6 +110,7 @@ TestUtil.assertAllExtensionsSet(message2); } + @Test public void testParsePackedExtensionsLite() throws Exception { // Ensure that packed extensions can be properly parsed. TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet(); @@ -115,28 +124,31 @@ TestUtil.assertPackedExtensionsSet(message2); } + @Test public void testSerialization() throws Exception { TestAllTypes message = TestUtil.getAllSet(); ByteString rawBytes = message.toByteString(); - assertEquals(rawBytes.size(), message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size()); TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); TestUtil.assertAllFieldsSet(message2); } + @Test public void testSerializationPacked() throws Exception { TestPackedTypes message = TestUtil.getPackedSet(); ByteString rawBytes = message.toByteString(); - assertEquals(rawBytes.size(), message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size()); TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes); TestUtil.assertPackedFieldsSet(message2); } + @Test public void testSerializeExtensions() throws Exception { // TestAllTypes and TestAllExtensions should have compatible wire formats, // so if we serialize a TestAllExtensions then parse it as TestAllTypes @@ -144,13 +156,14 @@ TestAllExtensions message = TestUtil.getAllExtensionsSet(); ByteString rawBytes = message.toByteString(); - assertEquals(rawBytes.size(), message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size()); TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); TestUtil.assertAllFieldsSet(message2); } + @Test public void testSerializePackedExtensions() throws Exception { // TestPackedTypes and TestPackedExtensions should have compatible wire // formats; check that they serialize to the same string. @@ -160,9 +173,10 @@ TestPackedTypes message2 = TestUtil.getPackedSet(); ByteString rawBytes2 = message2.toByteString(); - assertEquals(rawBytes, rawBytes2); + assertThat(rawBytes2).isEqualTo(rawBytes); } + @Test public void testSerializationPackedWithoutGetSerializedSize() throws Exception { // Write directly to an OutputStream, without invoking getSerializedSize() // This used to be a bug where the size of a packed field was incorrect, @@ -183,6 +197,7 @@ TestUtil.assertPackedFieldsSet(message2); } + @Test public void testParseExtensions() throws Exception { // TestAllTypes and TestAllExtensions should have compatible wire formats, // so if we serialize a TestAllTypes then parse it as TestAllExtensions @@ -198,6 +213,7 @@ TestUtil.assertAllExtensionsSet(message2); } + @Test public void testParsePackedExtensions() throws Exception { // Ensure that packed extensions can be properly parsed. TestPackedExtensions message = TestUtil.getPackedExtensionsSet(); @@ -210,6 +226,7 @@ TestUtil.assertPackedExtensionsSet(message2); } + @Test public void testSerializeDelimited() throws Exception { ByteArrayOutputStream output = new ByteArrayOutputStream(); TestUtil.getAllSet().writeDelimitedTo(output); @@ -220,13 +237,13 @@ ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); TestUtil.assertAllFieldsSet(TestAllTypes.parseDelimitedFrom(input)); - assertEquals(12, input.read()); + assertThat(input.read()).isEqualTo(12); TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input)); - assertEquals(34, input.read()); - assertEquals(-1, input.read()); + assertThat(input.read()).isEqualTo(34); + assertThat(input.read()).isEqualTo(-1); // We're at EOF, so parsing again should return null. - assertNull(TestAllTypes.parseDelimitedFrom(input)); + assertThat(TestAllTypes.parseDelimitedFrom(input)).isNull(); } private ExtensionRegistryLite getTestFieldOrderingsRegistry() { @@ -236,6 +253,7 @@ return result; } + @Test public void testParseMultipleExtensionRanges() throws Exception { // Make sure we can parse a message that contains multiple extensions // ranges. @@ -249,7 +267,7 @@ .build(); TestFieldOrderings dest = TestFieldOrderings.parseFrom(source.toByteString(), getTestFieldOrderingsRegistry()); - assertEquals(source, dest); + assertThat(dest).isEqualTo(source); } private static ExtensionRegistryLite getTestExtensionInsideTableRegistry() { @@ -258,6 +276,7 @@ return result; } + @Test public void testExtensionInsideTable() throws Exception { // Make sure the extension within the range of table is parsed correctly in experimental // runtime. @@ -269,17 +288,19 @@ TestExtensionInsideTable dest = TestExtensionInsideTable.parseFrom( source.toByteString(), getTestExtensionInsideTableRegistry()); - assertEquals(source, dest); + assertThat(dest).isEqualTo(source); } private static final int UNKNOWN_TYPE_ID = 1550055; private static final int TYPE_ID_1 = 1545008; private static final int TYPE_ID_2 = 1547769; + @Test public void testSerializeMessageSetEagerly() throws Exception { testSerializeMessageSetWithFlag(true); } + @Test public void testSerializeMessageSetNotEagerly() throws Exception { testSerializeMessageSetWithFlag(false); } @@ -309,26 +330,28 @@ // Parse back using RawMessageSet and check the contents. RawMessageSet raw = RawMessageSet.parseFrom(data); - assertEquals(3, raw.getItemCount()); - assertEquals(TYPE_ID_1, raw.getItem(0).getTypeId()); - assertEquals(TYPE_ID_2, raw.getItem(1).getTypeId()); - assertEquals(UNKNOWN_TYPE_ID, raw.getItem(2).getTypeId()); + assertThat(raw.getItemCount()).isEqualTo(3); + assertThat(raw.getItem(0).getTypeId()).isEqualTo(TYPE_ID_1); + assertThat(raw.getItem(1).getTypeId()).isEqualTo(TYPE_ID_2); + assertThat(raw.getItem(2).getTypeId()).isEqualTo(UNKNOWN_TYPE_ID); TestMessageSetExtension1 message1 = TestMessageSetExtension1.parseFrom(raw.getItem(0).getMessage()); - assertEquals(123, message1.getI()); + assertThat(message1.getI()).isEqualTo(123); TestMessageSetExtension2 message2 = TestMessageSetExtension2.parseFrom(raw.getItem(1).getMessage()); - assertEquals("foo", message2.getStr()); + assertThat(message2.getStr()).isEqualTo("foo"); - assertEquals("bar", raw.getItem(2).getMessage().toStringUtf8()); + assertThat(raw.getItem(2).getMessage().toStringUtf8()).isEqualTo("bar"); } + @Test public void testParseMessageSetEagerly() throws Exception { testParseMessageSetWithFlag(true); } + @Test public void testParseMessageSetNotEagerly() throws Exception { testParseMessageSetWithFlag(false); } @@ -366,15 +389,18 @@ // Parse as a TestMessageSet and check the contents. TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry); - assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); - assertEquals( - "foo", messageSet.getExtension(TestMessageSetExtension2.messageSetExtension).getStr()); + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()) + .isEqualTo(123); + assertThat(messageSet.getExtension(TestMessageSetExtension2.messageSetExtension).getStr()) + .isEqualTo("foo"); } + @Test public void testParseMessageSetExtensionEagerly() throws Exception { testParseMessageSetExtensionWithFlag(true); } + @Test public void testParseMessageSetExtensionNotEagerly() throws Exception { testParseMessageSetExtensionWithFlag(false); } @@ -400,13 +426,16 @@ // Parse as a TestMessageSet and check the contents. TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry); - assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()) + .isEqualTo(123); } + @Test public void testMergeLazyMessageSetExtensionEagerly() throws Exception { testMergeLazyMessageSetExtensionWithFlag(true); } + @Test public void testMergeLazyMessageSetExtensionNotEagerly() throws Exception { testMergeLazyMessageSetExtensionWithFlag(false); } @@ -434,13 +463,16 @@ TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry); // Merge lazy field check the contents. messageSet = messageSet.toBuilder().mergeFrom(data, extensionRegistry).build(); - assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()) + .isEqualTo(123); } + @Test public void testMergeMessageSetExtensionEagerly() throws Exception { testMergeMessageSetExtensionWithFlag(true); } + @Test public void testMergeMessageSetExtensionNotEagerly() throws Exception { testMergeMessageSetExtensionWithFlag(false); } @@ -477,31 +509,34 @@ // Merge bytes into TestMessageSet and check the contents. TestMessageSet messageSet = TestMessageSet.newBuilder().mergeFrom(data, extensionRegistry).build(); - assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()) + .isEqualTo(123); } // ================================================================ // oneof + @Test public void testOneofWireFormat() throws Exception { TestOneof2.Builder builder = TestOneof2.newBuilder(); TestUtil.setOneof(builder); TestOneof2 message = builder.build(); ByteString rawBytes = message.toByteString(); - assertEquals(rawBytes.size(), message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size()); TestOneof2 message2 = TestOneof2.parseFrom(rawBytes); TestUtil.assertOneofSet(message2); } + @Test public void testOneofOnlyLastSet() throws Exception { TestOneofBackwardsCompatible source = TestOneofBackwardsCompatible.newBuilder().setFooInt(100).setFooString("101").build(); ByteString rawBytes = source.toByteString(); TestOneof2 message = TestOneof2.parseFrom(rawBytes); - assertFalse(message.hasFooInt()); - assertTrue(message.hasFooString()); + assertThat(message.hasFooInt()).isFalse(); + assertThat(message.hasFooString()).isTrue(); } private void assertInvalidWireFormat( @@ -509,27 +544,27 @@ // Test all combinations: (builder vs parser) x (byte[] vs. InputStream). try { defaultInstance.newBuilderForType().mergeFrom(data, offset, length); - fail("Expected exception"); + assertWithMessage("Expected exception").fail(); } catch (InvalidProtocolBufferException e) { // Pass. } try { defaultInstance.getParserForType().parseFrom(data, offset, length); - fail("Expected exception"); + assertWithMessage("Expected exception").fail(); } catch (InvalidProtocolBufferException e) { // Pass. } try { InputStream input = new ByteArrayInputStream(data, offset, length); defaultInstance.newBuilderForType().mergeFrom(input); - fail("Expected exception"); + assertWithMessage("Expected exception").fail(); } catch (IOException e) { // Pass. } try { InputStream input = new ByteArrayInputStream(data, offset, length); defaultInstance.getParserForType().parseFrom(input); - fail("Expected exception"); + assertWithMessage("Expected exception").fail(); } catch (IOException e) { // Pass. } @@ -544,6 +579,7 @@ assertInvalidWireFormat(UnittestProto3.TestAllTypes.getDefaultInstance(), data); } + @Test public void testParserRejectInvalidTag() throws Exception { byte[] invalidTags = new byte[] { @@ -609,6 +645,7 @@ } } + @Test public void testUnmatchedGroupTag() throws Exception { int startTag = WireFormat.makeTag(16, WireFormat.WIRETYPE_START_GROUP); byte[] data = @@ -637,11 +674,12 @@ defaultInstance.newBuilderForType().mergeFrom(new ByteArrayInputStream(data)).build(); MessageLite message4 = defaultInstance.getParserForType().parseFrom(new ByteArrayInputStream(data)); - assertEquals(message1, message2); - assertEquals(message2, message3); - assertEquals(message3, message4); + assertThat(message2).isEqualTo(message1); + assertThat(message3).isEqualTo(message2); + assertThat(message4).isEqualTo(message3); } + @Test public void testUnmatchedWireType() throws Exception { // Build a payload with all fields from 1 to 128 being varints. Parsing it into TestAllTypes // or other message types should succeed even though the wire type doesn't match for some @@ -660,6 +698,7 @@ assertAccepted(MapForProto2TestProto.TestMap.getDefaultInstance(), data); } + @Test public void testParseTruncatedPackedFields() throws Exception { TestPackedTypes all = TestUtil.getPackedSet(); TestPackedTypes[] messages = @@ -687,6 +726,7 @@ } } + @Test public void testParsePackedFieldsWithIncorrectLength() throws Exception { // Set the length-prefix to 1 with a 4-bytes payload to test what happens when reading a packed // element moves the reading position past the given length limit. It should result in an @@ -758,6 +798,7 @@ } } + @Test public void testParseVarintMinMax() throws Exception { TestAllTypes message = TestAllTypes.newBuilder() @@ -767,55 +808,61 @@ .addRepeatedInt64(Long.MAX_VALUE) .build(); TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); - assertEquals(Integer.MIN_VALUE, parsed.getOptionalInt32()); - assertEquals(Integer.MAX_VALUE, parsed.getRepeatedInt32(0)); - assertEquals(Long.MIN_VALUE, parsed.getOptionalInt64()); - assertEquals(Long.MAX_VALUE, parsed.getRepeatedInt64(0)); + assertThat(parsed.getOptionalInt32()).isEqualTo(Integer.MIN_VALUE); + assertThat(parsed.getRepeatedInt32(0)).isEqualTo(Integer.MAX_VALUE); + assertThat(parsed.getOptionalInt64()).isEqualTo(Long.MIN_VALUE); + assertThat(parsed.getRepeatedInt64(0)).isEqualTo(Long.MAX_VALUE); } + @Test public void testParseAllVarintBits() throws Exception { for (int i = 0; i < 32; i++) { final int value = 1 << i; TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(value).build(); TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); - assertEquals(value, parsed.getOptionalInt32()); + assertThat(parsed.getOptionalInt32()).isEqualTo(value); } for (int i = 0; i < 64; i++) { final long value = 1L << i; TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt64(value).build(); TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); - assertEquals(value, parsed.getOptionalInt64()); + assertThat(parsed.getOptionalInt64()).isEqualTo(value); } } + @Test public void testParseEmptyUnknownLengthDelimitedField() throws Exception { byte[] data = new byte[] {(byte) WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED), 0}; TestAllTypes parsed = TestAllTypes.parseFrom(data); - assertTrue(Arrays.equals(data, parsed.toByteArray())); + assertThat(parsed.toByteArray()).isEqualTo(data); } + @Test public void testParseEmptyString() throws Exception { TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("").build(); TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); - assertEquals("", parsed.getOptionalString()); + assertThat(parsed.getOptionalString()).isEmpty(); } + @Test public void testParseEmptyStringProto3() throws Exception { TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("").build(); // Note that we are parsing from a proto2 proto to a proto3 proto because empty string field is // not serialized in proto3. UnittestProto3.TestAllTypes parsed = UnittestProto3.TestAllTypes.parseFrom(message.toByteArray()); - assertEquals("", parsed.getOptionalString()); + assertThat(parsed.getOptionalString()).isEmpty(); } + @Test public void testParseEmptyBytes() throws Exception { TestAllTypes message = TestAllTypes.newBuilder().setOptionalBytes(ByteString.EMPTY).build(); TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); - assertEquals(ByteString.EMPTY, parsed.getOptionalBytes()); + assertThat(parsed.getOptionalBytes()).isEqualTo(ByteString.EMPTY); } + @Test public void testParseEmptyRepeatedStringField() throws Exception { TestAllTypes message = TestAllTypes.newBuilder() @@ -824,12 +871,13 @@ .addRepeatedString("0") .build(); TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); - assertEquals(3, parsed.getRepeatedStringCount()); - assertEquals("", parsed.getRepeatedString(0)); - assertEquals("", parsed.getRepeatedString(1)); - assertEquals("0", parsed.getRepeatedString(2)); + assertThat(parsed.getRepeatedStringCount()).isEqualTo(3); + assertThat(parsed.getRepeatedString(0)).isEmpty(); + assertThat(parsed.getRepeatedString(1)).isEmpty(); + assertThat(parsed.getRepeatedString(2)).isEqualTo("0"); } + @Test public void testParseEmptyRepeatedStringFieldProto3() throws Exception { TestAllTypes message = TestAllTypes.newBuilder() @@ -840,12 +888,13 @@ .build(); UnittestProto3.TestAllTypes parsed = UnittestProto3.TestAllTypes.parseFrom(message.toByteArray()); - assertEquals(3, parsed.getRepeatedStringCount()); - assertEquals("", parsed.getRepeatedString(0)); - assertEquals("", parsed.getRepeatedString(1)); - assertEquals("0", parsed.getRepeatedString(2)); + assertThat(parsed.getRepeatedStringCount()).isEqualTo(3); + assertThat(parsed.getRepeatedString(0)).isEmpty(); + assertThat(parsed.getRepeatedString(1)).isEmpty(); + assertThat(parsed.getRepeatedString(2)).isEqualTo("0"); } + @Test public void testParseEmptyRepeatedBytesField() throws Exception { ByteString oneByte = ByteString.copyFrom(new byte[] {1}); TestAllTypes message = @@ -855,12 +904,13 @@ .addRepeatedBytes(oneByte) .build(); TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); - assertEquals(3, parsed.getRepeatedBytesCount()); - assertEquals(ByteString.EMPTY, parsed.getRepeatedBytes(0)); - assertEquals(ByteString.EMPTY, parsed.getRepeatedBytes(1)); - assertEquals(oneByte, parsed.getRepeatedBytes(2)); + assertThat(parsed.getRepeatedBytesCount()).isEqualTo(3); + assertThat(parsed.getRepeatedBytes(0)).isEqualTo(ByteString.EMPTY); + assertThat(parsed.getRepeatedBytes(1)).isEqualTo(ByteString.EMPTY); + assertThat(parsed.getRepeatedBytes(2)).isEqualTo(oneByte); } + @Test public void testSkipUnknownFieldInMessageSetItem() throws Exception { ByteArrayOutputStream output = new ByteArrayOutputStream(); // MessageSet item's start tag. @@ -881,109 +931,119 @@ // Convert to RawMessageSet for inspection. RawMessageSet raw = RawMessageSet.parseFrom(parsed.toByteArray()); - assertEquals(1, raw.getItemCount()); - assertEquals(100, raw.getItem(0).getTypeId()); - assertEquals(0, raw.getItem(0).getMessage().size()); + assertThat(raw.getItemCount()).isEqualTo(1); + assertThat(raw.getItem(0).getTypeId()).isEqualTo(100); + assertThat(raw.getItem(0).getMessage().size()).isEqualTo(0); } + @Test public void testProto2UnknownEnumValuesInOptionalField() throws Exception { // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with // unknown enum values UnittestProto3.TestAllTypes message = UnittestProto3.TestAllTypes.newBuilder().setOptionalNestedEnumValue(4321).build(); TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); - assertFalse(parsed.hasOptionalNestedEnum()); + assertThat(parsed.hasOptionalNestedEnum()).isFalse(); // Make sure unknown enum values are preserved. UnittestProto3.TestAllTypes actual = UnittestProto3.TestAllTypes.parseFrom(parsed.toByteArray()); - assertEquals(4321, actual.getOptionalNestedEnumValue()); + assertThat(actual.getOptionalNestedEnumValue()).isEqualTo(4321); } + @Test public void testProto2UnknownEnumValuesInRepeatedField() throws Exception { // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with // unknown enum values UnittestProto3.TestAllTypes message = UnittestProto3.TestAllTypes.newBuilder().addRepeatedNestedEnumValue(5432).build(); TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray()); - assertEquals(0, parsed.getRepeatedNestedEnumCount()); + assertThat(parsed.getRepeatedNestedEnumCount()).isEqualTo(0); // Make sure unknown enum values are preserved. UnittestProto3.TestAllTypes actual = UnittestProto3.TestAllTypes.parseFrom(parsed.toByteArray()); - assertEquals(1, actual.getRepeatedNestedEnumCount()); - assertEquals(5432, actual.getRepeatedNestedEnumValue(0)); + assertThat(actual.getRepeatedNestedEnumCount()).isEqualTo(1); + assertThat(actual.getRepeatedNestedEnumValue(0)).isEqualTo(5432); } + @Test public void testProto2UnknownEnumValuesInMapField() throws Exception { // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with // unknown enum values TestMap message = TestMap.newBuilder().putInt32ToEnumFieldValue(1, 4321).build(); MapForProto2TestProto.TestMap parsed = MapForProto2TestProto.TestMap.parseFrom(message.toByteArray()); - assertEquals(0, parsed.getInt32ToEnumFieldMap().size()); + assertThat(parsed.getInt32ToEnumFieldMap()).isEmpty(); // Make sure unknown enum values are preserved. TestMap actual = TestMap.parseFrom(parsed.toByteArray()); - assertEquals(1, actual.getInt32ToEnumFieldMap().size()); - assertEquals(4321, actual.getInt32ToEnumFieldValueOrThrow(1)); + assertThat(actual.getInt32ToEnumFieldMap()).hasSize(1); + assertThat(actual.getInt32ToEnumFieldValueOrThrow(1)).isEqualTo(4321); } + @Test public void testProto2UnknownEnumValuesInOneof() throws Exception { // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with // unknown enum values UnittestProto3.TestOneof2 message = UnittestProto3.TestOneof2.newBuilder().setFooEnumValue(1234).build(); TestOneof2 parsed = TestOneof2.parseFrom(message.toByteArray()); - assertFalse(parsed.hasFooEnum()); + assertThat(parsed.hasFooEnum()).isFalse(); // Make sure unknown enum values are preserved. UnittestProto3.TestOneof2 actual = UnittestProto3.TestOneof2.parseFrom(parsed.toByteArray()); - assertEquals(1234, actual.getFooEnumValue()); + assertThat(actual.getFooEnumValue()).isEqualTo(1234); } + @Test public void testProto2UnknownEnumValuesInExtension() throws Exception { ExtensionRegistryLite extensionRegistry = TestUtilLite.getExtensionRegistryLite(); // Raw bytes for "[.optional_foreign_enum_extension_lite]: 10" final byte[] rawBytes = new byte[]{-80, 1, 10}; TestAllExtensionsLite testAllExtensionsLite = TestAllExtensionsLite.parseFrom(rawBytes, extensionRegistry); - assertEquals(ForeignEnumLite.FOREIGN_LITE_FOO, - testAllExtensionsLite.getExtension(optionalForeignEnumExtensionLite)); + assertThat(testAllExtensionsLite.getExtension(optionalForeignEnumExtensionLite)) + .isEqualTo(ForeignEnumLite.FOREIGN_LITE_FOO); final byte[] resultRawBytes = testAllExtensionsLite.toByteArray(); - assertEquals(rawBytes.length, resultRawBytes.length); + assertThat(resultRawBytes).hasLength(rawBytes.length); for (int i = 0; i < rawBytes.length; i++) { - assertEquals(rawBytes[i], resultRawBytes[i]); + assertThat(resultRawBytes[i]).isEqualTo(rawBytes[i]); } } + @Test public void testProto3UnknownEnumValuesInOptionalField() throws Exception { UnittestProto3.TestAllTypes message = UnittestProto3.TestAllTypes.newBuilder().setOptionalNestedEnumValue(4321).build(); UnittestProto3.TestAllTypes parsed = UnittestProto3.TestAllTypes.parseFrom(message.toByteArray()); - assertEquals(4321, parsed.getOptionalNestedEnumValue()); + assertThat(parsed.getOptionalNestedEnumValue()).isEqualTo(4321); } + @Test public void testProto3UnknownEnumValuesInRepeatedField() throws Exception { UnittestProto3.TestAllTypes message = UnittestProto3.TestAllTypes.newBuilder().addRepeatedNestedEnumValue(5432).build(); UnittestProto3.TestAllTypes parsed = UnittestProto3.TestAllTypes.parseFrom(message.toByteArray()); - assertEquals(1, parsed.getRepeatedNestedEnumCount()); - assertEquals(5432, parsed.getRepeatedNestedEnumValue(0)); + assertThat(parsed.getRepeatedNestedEnumCount()).isEqualTo(1); + assertThat(parsed.getRepeatedNestedEnumValue(0)).isEqualTo(5432); } + @Test public void testProto3UnknownEnumValuesInMapField() throws Exception { TestMap message = TestMap.newBuilder().putInt32ToEnumFieldValue(1, 4321).build(); TestMap parsed = TestMap.parseFrom(message.toByteArray()); - assertEquals(1, parsed.getInt32ToEnumFieldMap().size()); - assertEquals(4321, parsed.getInt32ToEnumFieldValueOrThrow(1)); + assertThat(parsed.getInt32ToEnumFieldMap()).hasSize(1); + assertThat(parsed.getInt32ToEnumFieldValueOrThrow(1)).isEqualTo(4321); } + @Test public void testProto3UnknownEnumValuesInOneof() throws Exception { UnittestProto3.TestOneof2 message = UnittestProto3.TestOneof2.newBuilder().setFooEnumValue(1234).build(); UnittestProto3.TestOneof2 parsed = UnittestProto3.TestOneof2.parseFrom(message.toByteArray()); - assertEquals(1234, parsed.getFooEnumValue()); + assertThat(parsed.getFooEnumValue()).isEqualTo(1234); } + @Test public void testProto3MessageFieldMergeBehavior() throws Exception { UnittestProto3.NestedTestAllTypes message1 = UnittestProto3.NestedTestAllTypes.newBuilder() @@ -1006,12 +1066,13 @@ .mergeFrom(message2.toByteArray()) .build(); // Field values coming later in the stream override earlier values. - assertEquals(4321, merged.getPayload().getOptionalInt32()); + assertThat(merged.getPayload().getOptionalInt32()).isEqualTo(4321); // Field values present in either message should be present in the merged result. - assertEquals(5678, merged.getPayload().getOptionalInt64()); - assertEquals(8765, merged.getPayload().getOptionalUint32()); + assertThat(merged.getPayload().getOptionalInt64()).isEqualTo(5678); + assertThat(merged.getPayload().getOptionalUint32()).isEqualTo(8765); } + @Test public void testMergeFromPartialByteArray() throws Exception { byte[] data = TestUtil.getAllSet().toByteArray(); byte[] dataWithPaddings = new byte[data.length + 2];
diff --git a/java/core/src/test/java/com/google/protobuf/WireFormatTest.java b/java/core/src/test/java/com/google/protobuf/WireFormatTest.java index 45a396a..e072eb8 100644 --- a/java/core/src/test/java/com/google/protobuf/WireFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/WireFormatTest.java
@@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import protobuf_unittest.UnittestMset.RawMessageSet; import protobuf_unittest.UnittestMset.TestMessageSetExtension1; import protobuf_unittest.UnittestMset.TestMessageSetExtension2; @@ -46,14 +48,13 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.List; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Tests related to parsing and serialization. - * - * @author kenton@google.com (Kenton Varda) - */ -public class WireFormatTest extends TestCase { +/** Tests related to parsing and serialization. */ +@RunWith(JUnit4.class) +public class WireFormatTest { private static final int TYPE_ID_1 = TestMessageSetExtension1.getDescriptor().getExtensions().get(0).getNumber(); @@ -61,28 +62,31 @@ TestMessageSetExtension2.getDescriptor().getExtensions().get(0).getNumber(); private static final int UNKNOWN_TYPE_ID = 1550055; + @Test public void testSerialization() throws Exception { TestAllTypes message = TestUtil.getAllSet(); ByteString rawBytes = message.toByteString(); - assertEquals(rawBytes.size(), message.getSerializedSize()); + assertThat(rawBytes.size()).isEqualTo(message.getSerializedSize()); TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); TestUtil.assertAllFieldsSet(message2); } + @Test public void testSerializationPacked() throws Exception { TestPackedTypes message = TestUtil.getPackedSet(); ByteString rawBytes = message.toByteString(); - assertEquals(rawBytes.size(), message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size()); TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes); TestUtil.assertPackedFieldsSet(message2); } + @Test public void testSerializeExtensions() throws Exception { // TestAllTypes and TestAllExtensions should have compatible wire formats, // so if we serialize a TestAllExtensions then parse it as TestAllTypes @@ -90,13 +94,14 @@ TestAllExtensions message = TestUtil.getAllExtensionsSet(); ByteString rawBytes = message.toByteString(); - assertEquals(rawBytes.size(), message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size()); TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); TestUtil.assertAllFieldsSet(message2); } + @Test public void testSerializePackedExtensions() throws Exception { // TestPackedTypes and TestPackedExtensions should have compatible wire // formats; check that they serialize to the same string. @@ -106,9 +111,10 @@ TestPackedTypes message2 = TestUtil.getPackedSet(); ByteString rawBytes2 = message2.toByteString(); - assertEquals(rawBytes, rawBytes2); + assertThat(rawBytes).isEqualTo(rawBytes2); } + @Test public void testSerializationPackedWithoutGetSerializedSize() throws Exception { // Write directly to an OutputStream, without invoking getSerializedSize() // This used to be a bug where the size of a packed field was incorrect, @@ -129,6 +135,7 @@ TestUtil.assertPackedFieldsSet(message2); } + @Test public void testParseExtensions() throws Exception { // TestAllTypes and TestAllExtensions should have compatible wire formats, // so if we serialize a TestAllTypes then parse it as TestAllExtensions @@ -144,6 +151,7 @@ TestUtil.assertAllExtensionsSet(message2); } + @Test public void testParsePackedExtensions() throws Exception { // Ensure that packed extensions can be properly parsed. TestPackedExtensions message = TestUtil.getPackedExtensionsSet(); @@ -156,6 +164,7 @@ TestUtil.assertPackedExtensionsSet(message2); } + @Test public void testSerializeDelimited() throws Exception { ByteArrayOutputStream output = new ByteArrayOutputStream(); TestUtil.getAllSet().writeDelimitedTo(output); @@ -166,13 +175,13 @@ ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); TestUtil.assertAllFieldsSet(TestAllTypes.parseDelimitedFrom(input)); - assertEquals(12, input.read()); + assertThat(input.read()).isEqualTo(12); TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input)); - assertEquals(34, input.read()); - assertEquals(-1, input.read()); + assertThat(input.read()).isEqualTo(34); + assertThat(input.read()).isEqualTo(-1); // We're at EOF, so parsing again should return null. - assertTrue(TestAllTypes.parseDelimitedFrom(input) == null); + assertThat(TestAllTypes.parseDelimitedFrom(input)).isNull(); } private void assertFieldsInOrder(ByteString data) throws Exception { @@ -185,12 +194,13 @@ break; } - assertTrue(tag > previousTag); + assertThat(tag).isGreaterThan(previousTag); previousTag = tag; input.skipField(tag); } } + @Test public void testInterleavedFieldsAndExtensions() throws Exception { // Tests that fields are written in order even when extension ranges // are interleaved with field numbers. @@ -225,6 +235,7 @@ return result; } + @Test public void testParseMultipleExtensionRanges() throws Exception { // Make sure we can parse a message that contains multiple extensions // ranges. @@ -238,7 +249,7 @@ .build(); TestFieldOrderings dest = TestFieldOrderings.parseFrom(source.toByteString(), getTestFieldOrderingsRegistry()); - assertEquals(source, dest); + assertThat(source).isEqualTo(dest); } private static ExtensionRegistry getTestExtensionInsideTableRegistry() { @@ -247,6 +258,7 @@ return result; } + @Test public void testExtensionInsideTable() throws Exception { // Make sure the extension within the range of table is parsed correctly in experimental // runtime. @@ -258,9 +270,10 @@ TestExtensionInsideTable dest = TestExtensionInsideTable.parseFrom( source.toByteString(), getTestExtensionInsideTableRegistry()); - assertEquals(source, dest); + assertThat(source).isEqualTo(dest); } + @Test public void testParseMultipleExtensionRangesDynamic() throws Exception { // Same as above except with DynamicMessage. Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor(); @@ -275,13 +288,15 @@ DynamicMessage dest = DynamicMessage.parseFrom( descriptor, source.toByteString(), getTestFieldOrderingsRegistry()); - assertEquals(source, dest); + assertThat(source).isEqualTo(dest); } + @Test public void testSerializeMessageSetEagerly() throws Exception { testSerializeMessageSetWithFlag(true); } + @Test public void testSerializeMessageSetNotEagerly() throws Exception { testSerializeMessageSetWithFlag(false); } @@ -312,28 +327,30 @@ // Parse back using RawMessageSet and check the contents. RawMessageSet raw = RawMessageSet.parseFrom(data); - assertTrue(raw.getUnknownFields().asMap().isEmpty()); + assertThat(raw.getUnknownFields().asMap()).isEmpty(); - assertEquals(3, raw.getItemCount()); - assertEquals(TYPE_ID_1, raw.getItem(0).getTypeId()); - assertEquals(TYPE_ID_2, raw.getItem(1).getTypeId()); - assertEquals(UNKNOWN_TYPE_ID, raw.getItem(2).getTypeId()); + assertThat(raw.getItemCount()).isEqualTo(3); + assertThat(raw.getItem(0).getTypeId()).isEqualTo(TYPE_ID_1); + assertThat(raw.getItem(1).getTypeId()).isEqualTo(TYPE_ID_2); + assertThat(raw.getItem(2).getTypeId()).isEqualTo(UNKNOWN_TYPE_ID); TestMessageSetExtension1 message1 = TestMessageSetExtension1.parseFrom(raw.getItem(0).getMessage()); - assertEquals(123, message1.getI()); + assertThat(message1.getI()).isEqualTo(123); TestMessageSetExtension2 message2 = TestMessageSetExtension2.parseFrom(raw.getItem(1).getMessage()); - assertEquals("foo", message2.getStr()); + assertThat(message2.getStr()).isEqualTo("foo"); - assertEquals("bar", raw.getItem(2).getMessage().toStringUtf8()); + assertThat(raw.getItem(2).getMessage().toStringUtf8()).isEqualTo("bar"); } + @Test public void testParseMessageSetEagerly() throws Exception { testParseMessageSetWithFlag(true); } + @Test public void testParseMessageSetNotEagerly() throws Exception { testParseMessageSetWithFlag(false); } @@ -371,25 +388,28 @@ // Parse as a TestMessageSet and check the contents. TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry); - assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); - assertEquals( - "foo", messageSet.getExtension(TestMessageSetExtension2.messageSetExtension).getStr()); + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()) + .isEqualTo(123); + assertThat(messageSet.getExtension(TestMessageSetExtension2.messageSetExtension).getStr()) + .isEqualTo("foo"); // Check for unknown field with type LENGTH_DELIMITED, // number UNKNOWN_TYPE_ID, and contents "bar". UnknownFieldSet unknownFields = messageSet.getUnknownFields(); - assertEquals(1, unknownFields.asMap().size()); - assertTrue(unknownFields.hasField(UNKNOWN_TYPE_ID)); + assertThat(unknownFields.asMap()).hasSize(1); + assertThat(unknownFields.hasField(UNKNOWN_TYPE_ID)).isTrue(); UnknownFieldSet.Field field = unknownFields.getField(UNKNOWN_TYPE_ID); - assertEquals(1, field.getLengthDelimitedList().size()); - assertEquals("bar", field.getLengthDelimitedList().get(0).toStringUtf8()); + assertThat(field.getLengthDelimitedList()).hasSize(1); + assertThat(field.getLengthDelimitedList().get(0).toStringUtf8()).isEqualTo("bar"); } + @Test public void testParseMessageSetExtensionEagerly() throws Exception { testParseMessageSetExtensionWithFlag(true); } + @Test public void testParseMessageSetExtensionNotEagerly() throws Exception { testParseMessageSetExtensionWithFlag(false); } @@ -414,13 +434,16 @@ // Parse as a TestMessageSet and check the contents. TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry); - assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()) + .isEqualTo(123); } + @Test public void testMergeLazyMessageSetExtensionEagerly() throws Exception { testMergeLazyMessageSetExtensionWithFlag(true); } + @Test public void testMergeLazyMessageSetExtensionNotEagerly() throws Exception { testMergeLazyMessageSetExtensionWithFlag(false); } @@ -447,13 +470,16 @@ TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry); // Merge lazy field check the contents. messageSet = messageSet.toBuilder().mergeFrom(data, extensionRegistry).build(); - assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()) + .isEqualTo(123); } + @Test public void testMergeMessageSetExtensionEagerly() throws Exception { testMergeMessageSetExtensionWithFlag(true); } + @Test public void testMergeMessageSetExtensionNotEagerly() throws Exception { testMergeMessageSetExtensionWithFlag(false); } @@ -490,30 +516,33 @@ // Merge bytes into TestMessageSet and check the contents. TestMessageSet messageSet = TestMessageSet.newBuilder().mergeFrom(data, extensionRegistry).build(); - assertEquals(123, messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()); + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI()) + .isEqualTo(123); } // ================================================================ // oneof + @Test public void testOneofWireFormat() throws Exception { TestOneof2.Builder builder = TestOneof2.newBuilder(); TestUtil.setOneof(builder); TestOneof2 message = builder.build(); ByteString rawBytes = message.toByteString(); - assertEquals(rawBytes.size(), message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size()); TestOneof2 message2 = TestOneof2.parseFrom(rawBytes); TestUtil.assertOneofSet(message2); } + @Test public void testOneofOnlyLastSet() throws Exception { TestOneofBackwardsCompatible source = TestOneofBackwardsCompatible.newBuilder().setFooInt(100).setFooString("101").build(); ByteString rawBytes = source.toByteString(); TestOneof2 message = TestOneof2.parseFrom(rawBytes); - assertFalse(message.hasFooInt()); - assertTrue(message.hasFooString()); + assertThat(message.hasFooInt()).isFalse(); + assertThat(message.hasFooString()).isTrue(); } }
diff --git a/java/core/src/test/java/com/google/protobuf/WrappersLiteOfMethodTest.java b/java/core/src/test/java/com/google/protobuf/WrappersLiteOfMethodTest.java index 4a3c764..fc1e09f 100644 --- a/java/core/src/test/java/com/google/protobuf/WrappersLiteOfMethodTest.java +++ b/java/core/src/test/java/com/google/protobuf/WrappersLiteOfMethodTest.java
@@ -30,11 +30,17 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import com.google.protobuf.wrapperstest.WrappersTestProto.TopLevelMessage; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -public class WrappersLiteOfMethodTest extends TestCase { +@RunWith(JUnit4.class) +public class WrappersLiteOfMethodTest { + @Test public void testOf() throws Exception { TopLevelMessage.Builder builder = TopLevelMessage.newBuilder(); builder.setFieldDouble(DoubleValue.of(2.333)); @@ -48,14 +54,14 @@ builder.setFieldBytes(BytesValue.of(ByteString.wrap("233".getBytes(Internal.UTF_8)))); TopLevelMessage message = builder.build(); - assertTrue(2.333 == message.getFieldDouble().getValue()); - assertTrue(2.333f == message.getFieldFloat().getValue()); - assertTrue(2333 == message.getFieldInt32().getValue()); - assertTrue(23333333333333L == message.getFieldInt64().getValue()); - assertTrue(2333 == message.getFieldUint32().getValue()); - assertTrue(23333333333333L == message.getFieldUint64().getValue()); - assertTrue(true == message.getFieldBool().getValue()); - assertTrue(message.getFieldString().getValue().equals("23333")); - assertTrue(message.getFieldBytes().getValue().toStringUtf8().equals("233")); + assertThat(message.getFieldDouble().getValue()).isEqualTo(2.333); + assertThat(message.getFieldFloat().getValue()).isEqualTo(2.333F); + assertThat(message.getFieldInt32().getValue()).isEqualTo(2333); + assertThat(message.getFieldInt64().getValue()).isEqualTo(23333333333333L); + assertThat(message.getFieldUint32().getValue()).isEqualTo(2333); + assertThat(message.getFieldUint64().getValue()).isEqualTo(23333333333333L); + assertThat(true).isSameInstanceAs(message.getFieldBool().getValue()); + assertThat(message.getFieldString().getValue().equals("23333")).isTrue(); + assertThat(message.getFieldBytes().getValue().toStringUtf8().equals("233")).isTrue(); } }
diff --git a/java/core/src/test/java/com/google/protobuf/WrappersOfMethodTest.java b/java/core/src/test/java/com/google/protobuf/WrappersOfMethodTest.java index f0d662d..44c4ad6 100644 --- a/java/core/src/test/java/com/google/protobuf/WrappersOfMethodTest.java +++ b/java/core/src/test/java/com/google/protobuf/WrappersOfMethodTest.java
@@ -30,11 +30,17 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import com.google.protobuf.wrapperstest.WrappersTestProto.TopLevelMessage; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -public class WrappersOfMethodTest extends TestCase { +@RunWith(JUnit4.class) +public class WrappersOfMethodTest { + @Test public void testOf() throws Exception { TopLevelMessage.Builder builder = TopLevelMessage.newBuilder(); builder.setFieldDouble(DoubleValue.of(2.333)); @@ -48,14 +54,14 @@ builder.setFieldBytes(BytesValue.of(ByteString.wrap("233".getBytes(Internal.UTF_8)))); TopLevelMessage message = builder.build(); - assertTrue(2.333 == message.getFieldDouble().getValue()); - assertTrue(2.333f == message.getFieldFloat().getValue()); - assertTrue(2333 == message.getFieldInt32().getValue()); - assertTrue(23333333333333L == message.getFieldInt64().getValue()); - assertTrue(2333 == message.getFieldUint32().getValue()); - assertTrue(23333333333333L == message.getFieldUint64().getValue()); - assertTrue(true == message.getFieldBool().getValue()); - assertTrue(message.getFieldString().getValue().equals("23333")); - assertTrue(message.getFieldBytes().getValue().toStringUtf8().equals("233")); + assertThat(message.getFieldDouble().getValue()).isEqualTo(2.333); + assertThat(message.getFieldFloat().getValue()).isEqualTo(2.333F); + assertThat(message.getFieldInt32().getValue()).isEqualTo(2333); + assertThat(message.getFieldInt64().getValue()).isEqualTo(23333333333333L); + assertThat(message.getFieldUint32().getValue()).isEqualTo(2333); + assertThat(message.getFieldUint64().getValue()).isEqualTo(23333333333333L); + assertThat(true).isSameInstanceAs(message.getFieldBool().getValue()); + assertThat(message.getFieldString().getValue().equals("23333")).isTrue(); + assertThat(message.getFieldBytes().getValue().toStringUtf8().equals("233")).isTrue(); } }
diff --git a/java/kotlin/src/main/kotlin/com/google/protobuf/ByteStrings.kt b/java/kotlin/src/main/kotlin/com/google/protobuf/ByteStrings.kt new file mode 100644 index 0000000..3befb3b --- /dev/null +++ b/java/kotlin/src/main/kotlin/com/google/protobuf/ByteStrings.kt
@@ -0,0 +1,50 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf.kotlin + +import com.google.protobuf.ByteString +import java.nio.ByteBuffer + +/** Encodes this String into a sequence of UTF-8 bytes and returns the result as a [ByteString]. */ +fun String.toByteStringUtf8(): ByteString = ByteString.copyFromUtf8(this) +// symmetric from ByteString.toStringUtf8() + +/** Concatenates the given [ByteString] to this one. */ +operator fun ByteString.plus(other: ByteString): ByteString = concat(other) + +/** Gets the byte at [index]. */ +operator fun ByteString.get(index: Int): Byte = byteAt(index) + +/** Returns a copy of this [ByteArray] as an immutable [ByteString]. */ +fun ByteArray.toByteString(): ByteString = ByteString.copyFrom(this) + +/** Copies the remaining bytes from this [ByteBuffer] to a [ByteString]. */ +fun ByteBuffer.toByteString(): ByteString = ByteString.copyFrom(this)
diff --git a/java/kotlin/src/test/kotlin/com/google/protobuf/ByteStringsTest.kt b/java/kotlin/src/test/kotlin/com/google/protobuf/ByteStringsTest.kt new file mode 100644 index 0000000..99c8c98 --- /dev/null +++ b/java/kotlin/src/test/kotlin/com/google/protobuf/ByteStringsTest.kt
@@ -0,0 +1,97 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf.kotlin + +import com.google.common.truth.Truth.assertThat +import com.google.protobuf.ByteString +import java.lang.IndexOutOfBoundsException +import java.nio.ByteBuffer +import kotlin.test.assertFailsWith +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +/** Tests for the extension functions in ByteStrings.kt. */ +@RunWith(JUnit4::class) +class ByteStringsTest { + @Test + fun toByteStringUtf8() { + assertThat("abc".toByteStringUtf8()) + .isEqualTo(ByteString.copyFrom("abc".toByteArray(Charsets.UTF_8))) + } + + @Test + fun plus() { + assertThat("abc".toByteStringUtf8() + "def".toByteStringUtf8()) + .isEqualTo(ByteString.copyFrom("abcdef".toByteArray(Charsets.UTF_8))) + } + + @Test + fun byteAt() { + val str = "abc".toByteStringUtf8() + assertThat(str[0]).isEqualTo('a'.toByte()) + assertThat(str[2]).isEqualTo('c'.toByte()) + } + + @Test + fun byteAtBelowZero() { + val str = "abc".toByteStringUtf8() + assertFailsWith<IndexOutOfBoundsException> { str[-1] } + assertFailsWith<IndexOutOfBoundsException> { str[-2] } + } + + @Test + fun byteAtAboveLength() { + val str = "abc".toByteStringUtf8() + assertFailsWith<IndexOutOfBoundsException> { str[3] } + assertFailsWith<IndexOutOfBoundsException> { str[4] } + } + + @Test + fun byteArrayToByteString() { + assertThat("abc".toByteArray(Charsets.UTF_8).toByteString()) + .isEqualTo(ByteString.copyFromUtf8("abc")) + } + + @Test + fun byteBufferToByteString() { + val buffer = ByteBuffer.wrap("abc".toByteArray(Charsets.UTF_8)) + assertThat(buffer.toByteString()).isEqualTo(ByteString.copyFromUtf8("abc")) + } + + @Test + fun byteBufferToByteStringRespectsPositionAndLimit() { + val buffer = ByteBuffer.wrap("abc".toByteArray(Charsets.UTF_8)) + buffer.position(1) + buffer.limit(2) + assertThat(buffer.toByteString()).isEqualTo(ByteString.copyFromUtf8("b")) + } +}
diff --git a/java/lite/src/test/java/com/google/protobuf/LiteTest.java b/java/lite/src/test/java/com/google/protobuf/LiteTest.java index f2ce461..7cbc764 100644 --- a/java/lite/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/lite/src/test/java/com/google/protobuf/LiteTest.java
@@ -30,7 +30,8 @@ package com.google.protobuf; -import static java.util.Collections.emptyList; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static java.util.Collections.singletonList; import com.google.protobuf.FieldPresenceTestProto.TestAllTypes; @@ -70,15 +71,16 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Test lite runtime. - * - * @author kenton@google.com Kenton Varda - */ -public class LiteTest extends TestCase { - @Override +/** Test lite runtime. */ +@RunWith(JUnit4.class) +public class LiteTest { + + @Before public void setUp() throws Exception { // Test that nested extensions are initialized correctly even if the outer // class has not been accessed directly. This was once a bug with lite @@ -86,9 +88,10 @@ // // We put this in setUp() rather than in its own test method because we // need to make sure it runs before any actual tests. - assertNotNull(TestNestedExtensionLite.nestedExtension); + assertThat(TestNestedExtensionLite.nestedExtension).isNotNull(); } + @Test public void testLite() throws Exception { // Since lite messages are a subset of regular messages, we can mostly // assume that the functionality of lite messages is already thoroughly @@ -109,12 +112,13 @@ TestAllTypesLite message2 = TestAllTypesLite.parseFrom(data); - assertEquals(123, message2.getOptionalInt32()); - assertEquals(1, message2.getRepeatedStringCount()); - assertEquals("hello", message2.getRepeatedString(0)); - assertEquals(7, message2.getOptionalNestedMessage().getBb()); + assertThat(message2.getOptionalInt32()).isEqualTo(123); + assertThat(message2.getRepeatedStringCount()).isEqualTo(1); + assertThat(message2.getRepeatedString(0)).isEqualTo("hello"); + assertThat(message2.getOptionalNestedMessage().getBb()).isEqualTo(7); } + @Test public void testLite_unknownEnumAtListBoundary() throws Exception { ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); CodedOutputStream output = CodedOutputStream.newInstance(byteStream); @@ -129,6 +133,7 @@ TestAllTypesLite.parseFrom(new ByteArrayInputStream(byteStream.toByteArray())); } + @Test public void testLiteExtensions() throws Exception { // TODO(kenton): Unlike other features of the lite library, extensions are // implemented completely differently from the regular library. We @@ -149,61 +154,66 @@ // writing, parsing hasn't been implemented yet. TestAllExtensionsLite message2 = message.toBuilder().build(); - assertEquals(123, (int) message2.getExtension(UnittestLite.optionalInt32ExtensionLite)); - assertEquals(1, message2.getExtensionCount(UnittestLite.repeatedStringExtensionLite)); - assertEquals(1, message2.getExtension(UnittestLite.repeatedStringExtensionLite).size()); - assertEquals("hello", message2.getExtension(UnittestLite.repeatedStringExtensionLite, 0)); - assertEquals( - NestedEnum.BAZ, message2.getExtension(UnittestLite.optionalNestedEnumExtensionLite)); - assertEquals(7, message2.getExtension(UnittestLite.optionalNestedMessageExtensionLite).getBb()); + assertThat((int) message2.getExtension(UnittestLite.optionalInt32ExtensionLite)).isEqualTo(123); + assertThat(message2.getExtensionCount(UnittestLite.repeatedStringExtensionLite)).isEqualTo(1); + assertThat(message2.getExtension(UnittestLite.repeatedStringExtensionLite)).hasSize(1); + assertThat(message2.getExtension(UnittestLite.repeatedStringExtensionLite, 0)) + .isEqualTo("hello"); + assertThat(message2.getExtension(UnittestLite.optionalNestedEnumExtensionLite)) + .isEqualTo(NestedEnum.BAZ); + assertThat(message2.getExtension(UnittestLite.optionalNestedMessageExtensionLite).getBb()) + .isEqualTo(7); } + @Test public void testClone() { TestAllTypesLite.Builder expected = TestAllTypesLite.newBuilder().setOptionalInt32(123); - assertEquals(expected.getOptionalInt32(), expected.clone().getOptionalInt32()); + assertThat(expected.getOptionalInt32()).isEqualTo(expected.clone().getOptionalInt32()); TestAllExtensionsLite.Builder expected2 = TestAllExtensionsLite.newBuilder() .setExtension(UnittestLite.optionalInt32ExtensionLite, 123); - assertEquals( - expected2.getExtension(UnittestLite.optionalInt32ExtensionLite), - expected2.clone().getExtension(UnittestLite.optionalInt32ExtensionLite)); + assertThat(expected2.getExtension(UnittestLite.optionalInt32ExtensionLite)) + .isEqualTo(expected2.clone().getExtension(UnittestLite.optionalInt32ExtensionLite)); } + @Test public void testAddAll() { try { TestAllTypesLite.newBuilder().addAllRepeatedBytes(null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // expected. } } + @Test public void testMemoization() throws Exception { TestAllExtensionsLite message = TestUtilLite.getAllLiteExtensionsSet(); // Test serialized size is memoized message.memoizedSerializedSize = -1; int size = message.getSerializedSize(); - assertTrue(size > 0); - assertEquals(size, message.memoizedSerializedSize); + assertThat(size).isGreaterThan(0); + assertThat(message.memoizedSerializedSize).isEqualTo(size); // Test hashCode is memoized - assertEquals(0, message.memoizedHashCode); + assertThat(message.memoizedHashCode).isEqualTo(0); int hashCode = message.hashCode(); - assertTrue(hashCode != 0); - assertEquals(hashCode, message.memoizedHashCode); + assertThat(hashCode).isNotEqualTo(0); + assertThat(hashCode).isEqualTo(message.memoizedHashCode); // Test isInitialized is memoized Field memo = message.getClass().getDeclaredField("memoizedIsInitialized"); memo.setAccessible(true); memo.set(message, (byte) -1); boolean initialized = message.isInitialized(); - assertTrue(initialized); + assertThat(initialized).isTrue(); // We have to cast to Byte first. Casting to byte causes a type error - assertEquals(1, ((Byte) memo.get(message)).intValue()); + assertThat(((Byte) memo.get(message)).intValue()).isEqualTo(1); } + @Test public void testSanityCopyOnWrite() throws InvalidProtocolBufferException { // Since builders are implemented as a thin wrapper around a message // instance, we attempt to verify that we can't cause the builder to modify @@ -213,1093 +223,1107 @@ TestAllTypesLite message = builder.build(); TestAllTypesLite messageAfterBuild; builder.setOptionalBool(true); - assertEquals(false, message.getOptionalBool()); - assertEquals(true, builder.getOptionalBool()); + assertThat(message.getOptionalBool()).isFalse(); + assertThat(builder.getOptionalBool()).isTrue(); messageAfterBuild = builder.build(); - assertEquals(true, messageAfterBuild.getOptionalBool()); - assertEquals(false, message.getOptionalBool()); + assertThat(messageAfterBuild.getOptionalBool()).isTrue(); + assertThat(message.getOptionalBool()).isFalse(); builder.clearOptionalBool(); - assertEquals(false, builder.getOptionalBool()); - assertEquals(true, messageAfterBuild.getOptionalBool()); + assertThat(builder.getOptionalBool()).isFalse(); + assertThat(messageAfterBuild.getOptionalBool()).isTrue(); message = builder.build(); builder.setOptionalBytes(ByteString.copyFromUtf8("hi")); - assertEquals(ByteString.EMPTY, message.getOptionalBytes()); - assertEquals(ByteString.copyFromUtf8("hi"), builder.getOptionalBytes()); + assertThat(message.getOptionalBytes()).isEqualTo(ByteString.EMPTY); + assertThat(builder.getOptionalBytes()).isEqualTo(ByteString.copyFromUtf8("hi")); messageAfterBuild = builder.build(); - assertEquals(ByteString.copyFromUtf8("hi"), messageAfterBuild.getOptionalBytes()); - assertEquals(ByteString.EMPTY, message.getOptionalBytes()); + assertThat(messageAfterBuild.getOptionalBytes()).isEqualTo(ByteString.copyFromUtf8("hi")); + assertThat(message.getOptionalBytes()).isEqualTo(ByteString.EMPTY); builder.clearOptionalBytes(); - assertEquals(ByteString.EMPTY, builder.getOptionalBytes()); - assertEquals(ByteString.copyFromUtf8("hi"), messageAfterBuild.getOptionalBytes()); + assertThat(builder.getOptionalBytes()).isEqualTo(ByteString.EMPTY); + assertThat(messageAfterBuild.getOptionalBytes()).isEqualTo(ByteString.copyFromUtf8("hi")); message = builder.build(); builder.setOptionalCord("hi"); - assertEquals("", message.getOptionalCord()); - assertEquals("hi", builder.getOptionalCord()); + assertThat(message.getOptionalCord()).isEmpty(); + assertThat(builder.getOptionalCord()).isEqualTo("hi"); messageAfterBuild = builder.build(); - assertEquals("hi", messageAfterBuild.getOptionalCord()); - assertEquals("", message.getOptionalCord()); + assertThat(messageAfterBuild.getOptionalCord()).isEqualTo("hi"); + assertThat(message.getOptionalCord()).isEmpty(); builder.clearOptionalCord(); - assertEquals("", builder.getOptionalCord()); - assertEquals("hi", messageAfterBuild.getOptionalCord()); + assertThat(builder.getOptionalCord()).isEmpty(); + assertThat(messageAfterBuild.getOptionalCord()).isEqualTo("hi"); message = builder.build(); builder.setOptionalCordBytes(ByteString.copyFromUtf8("no")); - assertEquals(ByteString.EMPTY, message.getOptionalCordBytes()); - assertEquals(ByteString.copyFromUtf8("no"), builder.getOptionalCordBytes()); + assertThat(message.getOptionalCordBytes()).isEqualTo(ByteString.EMPTY); + assertThat(builder.getOptionalCordBytes()).isEqualTo(ByteString.copyFromUtf8("no")); messageAfterBuild = builder.build(); - assertEquals(ByteString.copyFromUtf8("no"), messageAfterBuild.getOptionalCordBytes()); - assertEquals(ByteString.EMPTY, message.getOptionalCordBytes()); + assertThat(messageAfterBuild.getOptionalCordBytes()).isEqualTo(ByteString.copyFromUtf8("no")); + assertThat(message.getOptionalCordBytes()).isEqualTo(ByteString.EMPTY); builder.clearOptionalCord(); - assertEquals(ByteString.EMPTY, builder.getOptionalCordBytes()); - assertEquals(ByteString.copyFromUtf8("no"), messageAfterBuild.getOptionalCordBytes()); + assertThat(builder.getOptionalCordBytes()).isEqualTo(ByteString.EMPTY); + assertThat(messageAfterBuild.getOptionalCordBytes()).isEqualTo(ByteString.copyFromUtf8("no")); message = builder.build(); builder.setOptionalDouble(1); - assertEquals(0D, message.getOptionalDouble(), 0.0); - assertEquals(1D, builder.getOptionalDouble(), 0.0); + assertThat(message.getOptionalDouble()).isEqualTo(0D); + assertThat(builder.getOptionalDouble()).isEqualTo(1D); messageAfterBuild = builder.build(); - assertEquals(1D, messageAfterBuild.getOptionalDouble(), 0.0); - assertEquals(0D, message.getOptionalDouble(), 0.0); + assertThat(messageAfterBuild.getOptionalDouble()).isEqualTo(1D); + assertThat(message.getOptionalDouble()).isEqualTo(0D); builder.clearOptionalDouble(); - assertEquals(0D, builder.getOptionalDouble(), 0.0); - assertEquals(1D, messageAfterBuild.getOptionalDouble(), 0.0); + assertThat(builder.getOptionalDouble()).isEqualTo(0D); + assertThat(messageAfterBuild.getOptionalDouble()).isEqualTo(1D); message = builder.build(); builder.setOptionalFixed32(1); - assertEquals(0, message.getOptionalFixed32()); - assertEquals(1, builder.getOptionalFixed32()); + assertThat(message.getOptionalFixed32()).isEqualTo(0); + assertThat(builder.getOptionalFixed32()).isEqualTo(1); messageAfterBuild = builder.build(); - assertEquals(1, messageAfterBuild.getOptionalFixed32()); - assertEquals(0, message.getOptionalFixed32()); + assertThat(messageAfterBuild.getOptionalFixed32()).isEqualTo(1); + assertThat(message.getOptionalFixed32()).isEqualTo(0); builder.clearOptionalFixed32(); - assertEquals(0, builder.getOptionalFixed32()); - assertEquals(1, messageAfterBuild.getOptionalFixed32()); + assertThat(builder.getOptionalFixed32()).isEqualTo(0); + assertThat(messageAfterBuild.getOptionalFixed32()).isEqualTo(1); message = builder.build(); builder.setOptionalFixed64(1); - assertEquals(0L, message.getOptionalFixed64()); - assertEquals(1L, builder.getOptionalFixed64()); + assertThat(message.getOptionalFixed64()).isEqualTo(0L); + assertThat(builder.getOptionalFixed64()).isEqualTo(1L); messageAfterBuild = builder.build(); - assertEquals(1L, messageAfterBuild.getOptionalFixed64()); - assertEquals(0L, message.getOptionalFixed64()); + assertThat(messageAfterBuild.getOptionalFixed64()).isEqualTo(1L); + assertThat(message.getOptionalFixed64()).isEqualTo(0L); builder.clearOptionalFixed64(); - assertEquals(0L, builder.getOptionalFixed64()); - assertEquals(1L, messageAfterBuild.getOptionalFixed64()); + assertThat(builder.getOptionalFixed64()).isEqualTo(0L); + assertThat(messageAfterBuild.getOptionalFixed64()).isEqualTo(1L); message = builder.build(); builder.setOptionalFloat(1); - assertEquals(0F, message.getOptionalFloat(), 0.0f); - assertEquals(1F, builder.getOptionalFloat(), 0.0f); + assertThat(message.getOptionalFloat()).isEqualTo(0F); + assertThat(builder.getOptionalFloat()).isEqualTo(1F); messageAfterBuild = builder.build(); - assertEquals(1F, messageAfterBuild.getOptionalFloat(), 0.0f); - assertEquals(0F, message.getOptionalFloat(), 0.0f); + assertThat(messageAfterBuild.getOptionalFloat()).isEqualTo(1F); + assertThat(message.getOptionalFloat()).isEqualTo(0F); builder.clearOptionalFloat(); - assertEquals(0F, builder.getOptionalFloat(), 0.0f); - assertEquals(1F, messageAfterBuild.getOptionalFloat(), 0.0f); + assertThat(builder.getOptionalFloat()).isEqualTo(0F); + assertThat(messageAfterBuild.getOptionalFloat()).isEqualTo(1F); message = builder.build(); builder.setOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR); - assertEquals(ForeignEnumLite.FOREIGN_LITE_FOO, message.getOptionalForeignEnum()); - assertEquals(ForeignEnumLite.FOREIGN_LITE_BAR, builder.getOptionalForeignEnum()); + assertThat(message.getOptionalForeignEnum()).isEqualTo(ForeignEnumLite.FOREIGN_LITE_FOO); + assertThat(builder.getOptionalForeignEnum()).isEqualTo(ForeignEnumLite.FOREIGN_LITE_BAR); messageAfterBuild = builder.build(); - assertEquals(ForeignEnumLite.FOREIGN_LITE_BAR, messageAfterBuild.getOptionalForeignEnum()); - assertEquals(ForeignEnumLite.FOREIGN_LITE_FOO, message.getOptionalForeignEnum()); + assertThat(messageAfterBuild.getOptionalForeignEnum()) + .isEqualTo(ForeignEnumLite.FOREIGN_LITE_BAR); + assertThat(message.getOptionalForeignEnum()).isEqualTo(ForeignEnumLite.FOREIGN_LITE_FOO); builder.clearOptionalForeignEnum(); - assertEquals(ForeignEnumLite.FOREIGN_LITE_FOO, builder.getOptionalForeignEnum()); - assertEquals(ForeignEnumLite.FOREIGN_LITE_BAR, messageAfterBuild.getOptionalForeignEnum()); + assertThat(builder.getOptionalForeignEnum()).isEqualTo(ForeignEnumLite.FOREIGN_LITE_FOO); + assertThat(messageAfterBuild.getOptionalForeignEnum()) + .isEqualTo(ForeignEnumLite.FOREIGN_LITE_BAR); message = builder.build(); ForeignMessageLite foreignMessage = ForeignMessageLite.newBuilder().setC(1).build(); builder.setOptionalForeignMessage(foreignMessage); - assertEquals(ForeignMessageLite.getDefaultInstance(), message.getOptionalForeignMessage()); - assertEquals(foreignMessage, builder.getOptionalForeignMessage()); + assertThat(message.getOptionalForeignMessage()) + .isEqualTo(ForeignMessageLite.getDefaultInstance()); + assertThat(builder.getOptionalForeignMessage()).isEqualTo(foreignMessage); messageAfterBuild = builder.build(); - assertEquals(foreignMessage, messageAfterBuild.getOptionalForeignMessage()); - assertEquals(ForeignMessageLite.getDefaultInstance(), message.getOptionalForeignMessage()); + assertThat(messageAfterBuild.getOptionalForeignMessage()).isEqualTo(foreignMessage); + assertThat(message.getOptionalForeignMessage()) + .isEqualTo(ForeignMessageLite.getDefaultInstance()); builder.clearOptionalForeignMessage(); - assertEquals(ForeignMessageLite.getDefaultInstance(), builder.getOptionalForeignMessage()); - assertEquals(foreignMessage, messageAfterBuild.getOptionalForeignMessage()); + assertThat(builder.getOptionalForeignMessage()) + .isEqualTo(ForeignMessageLite.getDefaultInstance()); + assertThat(messageAfterBuild.getOptionalForeignMessage()).isEqualTo(foreignMessage); message = builder.build(); ForeignMessageLite foreignMessageC3 = ForeignMessageLite.newBuilder().setC(3).build(); builder.setOptionalForeignMessage(foreignMessageC3); - assertEquals(ForeignMessageLite.getDefaultInstance(), message.getOptionalForeignMessage()); - assertEquals(foreignMessageC3, builder.getOptionalForeignMessage()); + assertThat(message.getOptionalForeignMessage()) + .isEqualTo(ForeignMessageLite.getDefaultInstance()); + assertThat(builder.getOptionalForeignMessage()).isEqualTo(foreignMessageC3); messageAfterBuild = builder.build(); - assertEquals(foreignMessageC3, messageAfterBuild.getOptionalForeignMessage()); - assertEquals(ForeignMessageLite.getDefaultInstance(), message.getOptionalForeignMessage()); + assertThat(messageAfterBuild.getOptionalForeignMessage()).isEqualTo(foreignMessageC3); + assertThat(message.getOptionalForeignMessage()) + .isEqualTo(ForeignMessageLite.getDefaultInstance()); builder.clearOptionalForeignMessage(); - assertEquals(ForeignMessageLite.getDefaultInstance(), builder.getOptionalForeignMessage()); - assertEquals(foreignMessageC3, messageAfterBuild.getOptionalForeignMessage()); + assertThat(builder.getOptionalForeignMessage()) + .isEqualTo(ForeignMessageLite.getDefaultInstance()); + assertThat(messageAfterBuild.getOptionalForeignMessage()).isEqualTo(foreignMessageC3); message = builder.build(); OptionalGroup optionalGroup = OptionalGroup.newBuilder().setA(1).build(); builder.setOptionalGroup(optionalGroup); - assertEquals(OptionalGroup.getDefaultInstance(), message.getOptionalGroup()); - assertEquals(optionalGroup, builder.getOptionalGroup()); + assertThat(message.getOptionalGroup()).isEqualTo(OptionalGroup.getDefaultInstance()); + assertThat(builder.getOptionalGroup()).isEqualTo(optionalGroup); messageAfterBuild = builder.build(); - assertEquals(optionalGroup, messageAfterBuild.getOptionalGroup()); - assertEquals(OptionalGroup.getDefaultInstance(), message.getOptionalGroup()); + assertThat(messageAfterBuild.getOptionalGroup()).isEqualTo(optionalGroup); + assertThat(message.getOptionalGroup()).isEqualTo(OptionalGroup.getDefaultInstance()); builder.clearOptionalGroup(); - assertEquals(OptionalGroup.getDefaultInstance(), builder.getOptionalGroup()); - assertEquals(optionalGroup, messageAfterBuild.getOptionalGroup()); + assertThat(builder.getOptionalGroup()).isEqualTo(OptionalGroup.getDefaultInstance()); + assertThat(messageAfterBuild.getOptionalGroup()).isEqualTo(optionalGroup); message = builder.build(); OptionalGroup.Builder optionalGroupBuilder = OptionalGroup.newBuilder().setA(3); builder.setOptionalGroup(optionalGroupBuilder); - assertEquals(OptionalGroup.getDefaultInstance(), message.getOptionalGroup()); - assertEquals(optionalGroupBuilder.build(), builder.getOptionalGroup()); + assertThat(message.getOptionalGroup()).isEqualTo(OptionalGroup.getDefaultInstance()); + assertThat(builder.getOptionalGroup()).isEqualTo(optionalGroupBuilder.build()); messageAfterBuild = builder.build(); - assertEquals(optionalGroupBuilder.build(), messageAfterBuild.getOptionalGroup()); - assertEquals(OptionalGroup.getDefaultInstance(), message.getOptionalGroup()); + assertThat(messageAfterBuild.getOptionalGroup()).isEqualTo(optionalGroupBuilder.build()); + assertThat(message.getOptionalGroup()).isEqualTo(OptionalGroup.getDefaultInstance()); builder.clearOptionalGroup(); - assertEquals(OptionalGroup.getDefaultInstance(), builder.getOptionalGroup()); - assertEquals(optionalGroupBuilder.build(), messageAfterBuild.getOptionalGroup()); + assertThat(builder.getOptionalGroup()).isEqualTo(OptionalGroup.getDefaultInstance()); + assertThat(messageAfterBuild.getOptionalGroup()).isEqualTo(optionalGroupBuilder.build()); message = builder.build(); builder.setOptionalInt32(1); - assertEquals(0, message.getOptionalInt32()); - assertEquals(1, builder.getOptionalInt32()); + assertThat(message.getOptionalInt32()).isEqualTo(0); + assertThat(builder.getOptionalInt32()).isEqualTo(1); messageAfterBuild = builder.build(); - assertEquals(1, messageAfterBuild.getOptionalInt32()); - assertEquals(0, message.getOptionalInt32()); + assertThat(messageAfterBuild.getOptionalInt32()).isEqualTo(1); + assertThat(message.getOptionalInt32()).isEqualTo(0); builder.clearOptionalInt32(); - assertEquals(0, builder.getOptionalInt32()); - assertEquals(1, messageAfterBuild.getOptionalInt32()); + assertThat(builder.getOptionalInt32()).isEqualTo(0); + assertThat(messageAfterBuild.getOptionalInt32()).isEqualTo(1); message = builder.build(); builder.setOptionalInt64(1); - assertEquals(0L, message.getOptionalInt64()); - assertEquals(1L, builder.getOptionalInt64()); + assertThat(message.getOptionalInt64()).isEqualTo(0L); + assertThat(builder.getOptionalInt64()).isEqualTo(1L); messageAfterBuild = builder.build(); - assertEquals(1L, messageAfterBuild.getOptionalInt64()); - assertEquals(0L, message.getOptionalInt64()); + assertThat(messageAfterBuild.getOptionalInt64()).isEqualTo(1L); + assertThat(message.getOptionalInt64()).isEqualTo(0L); builder.clearOptionalInt64(); - assertEquals(0L, builder.getOptionalInt64()); - assertEquals(1L, messageAfterBuild.getOptionalInt64()); + assertThat(builder.getOptionalInt64()).isEqualTo(0L); + assertThat(messageAfterBuild.getOptionalInt64()).isEqualTo(1L); message = builder.build(); NestedMessage nestedMessage = NestedMessage.newBuilder().setBb(1).build(); builder.setOptionalLazyMessage(nestedMessage); - assertEquals(NestedMessage.getDefaultInstance(), message.getOptionalLazyMessage()); - assertEquals(nestedMessage, builder.getOptionalLazyMessage()); + assertThat(message.getOptionalLazyMessage()).isEqualTo(NestedMessage.getDefaultInstance()); + assertThat(builder.getOptionalLazyMessage()).isEqualTo(nestedMessage); messageAfterBuild = builder.build(); - assertEquals(nestedMessage, messageAfterBuild.getOptionalLazyMessage()); - assertEquals(NestedMessage.getDefaultInstance(), message.getOptionalLazyMessage()); + assertThat(messageAfterBuild.getOptionalLazyMessage()).isEqualTo(nestedMessage); + assertThat(message.getOptionalLazyMessage()).isEqualTo(NestedMessage.getDefaultInstance()); builder.clearOptionalLazyMessage(); - assertEquals(NestedMessage.getDefaultInstance(), builder.getOptionalLazyMessage()); - assertEquals(nestedMessage, messageAfterBuild.getOptionalLazyMessage()); + assertThat(builder.getOptionalLazyMessage()).isEqualTo(NestedMessage.getDefaultInstance()); + assertThat(messageAfterBuild.getOptionalLazyMessage()).isEqualTo(nestedMessage); message = builder.build(); NestedMessage.Builder nestedMessageBuilder = NestedMessage.newBuilder().setBb(3); builder.setOptionalLazyMessage(nestedMessageBuilder); - assertEquals(NestedMessage.getDefaultInstance(), message.getOptionalLazyMessage()); - assertEquals(nestedMessageBuilder.build(), builder.getOptionalLazyMessage()); + assertThat(message.getOptionalLazyMessage()).isEqualTo(NestedMessage.getDefaultInstance()); + assertThat(builder.getOptionalLazyMessage()).isEqualTo(nestedMessageBuilder.build()); messageAfterBuild = builder.build(); - assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getOptionalLazyMessage()); - assertEquals(NestedMessage.getDefaultInstance(), message.getOptionalLazyMessage()); + assertThat(messageAfterBuild.getOptionalLazyMessage()).isEqualTo(nestedMessageBuilder.build()); + assertThat(message.getOptionalLazyMessage()).isEqualTo(NestedMessage.getDefaultInstance()); builder.clearOptionalLazyMessage(); - assertEquals(NestedMessage.getDefaultInstance(), builder.getOptionalLazyMessage()); - assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getOptionalLazyMessage()); + assertThat(builder.getOptionalLazyMessage()).isEqualTo(NestedMessage.getDefaultInstance()); + assertThat(messageAfterBuild.getOptionalLazyMessage()).isEqualTo(nestedMessageBuilder.build()); message = builder.build(); builder.setOptionalSfixed32(1); - assertEquals(0, message.getOptionalSfixed32()); - assertEquals(1, builder.getOptionalSfixed32()); + assertThat(message.getOptionalSfixed32()).isEqualTo(0); + assertThat(builder.getOptionalSfixed32()).isEqualTo(1); messageAfterBuild = builder.build(); - assertEquals(1, messageAfterBuild.getOptionalSfixed32()); - assertEquals(0, message.getOptionalSfixed32()); + assertThat(messageAfterBuild.getOptionalSfixed32()).isEqualTo(1); + assertThat(message.getOptionalSfixed32()).isEqualTo(0); builder.clearOptionalSfixed32(); - assertEquals(0, builder.getOptionalSfixed32()); - assertEquals(1, messageAfterBuild.getOptionalSfixed32()); + assertThat(builder.getOptionalSfixed32()).isEqualTo(0); + assertThat(messageAfterBuild.getOptionalSfixed32()).isEqualTo(1); message = builder.build(); builder.setOptionalSfixed64(1); - assertEquals(0L, message.getOptionalSfixed64()); - assertEquals(1L, builder.getOptionalSfixed64()); + assertThat(message.getOptionalSfixed64()).isEqualTo(0L); + assertThat(builder.getOptionalSfixed64()).isEqualTo(1L); messageAfterBuild = builder.build(); - assertEquals(1L, messageAfterBuild.getOptionalSfixed64()); - assertEquals(0L, message.getOptionalSfixed64()); + assertThat(messageAfterBuild.getOptionalSfixed64()).isEqualTo(1L); + assertThat(message.getOptionalSfixed64()).isEqualTo(0L); builder.clearOptionalSfixed64(); - assertEquals(0L, builder.getOptionalSfixed64()); - assertEquals(1L, messageAfterBuild.getOptionalSfixed64()); + assertThat(builder.getOptionalSfixed64()).isEqualTo(0L); + assertThat(messageAfterBuild.getOptionalSfixed64()).isEqualTo(1L); message = builder.build(); builder.setOptionalSint32(1); - assertEquals(0, message.getOptionalSint32()); - assertEquals(1, builder.getOptionalSint32()); + assertThat(message.getOptionalSint32()).isEqualTo(0); + assertThat(builder.getOptionalSint32()).isEqualTo(1); messageAfterBuild = builder.build(); - assertEquals(1, messageAfterBuild.getOptionalSint32()); + assertThat(messageAfterBuild.getOptionalSint32()).isEqualTo(1); builder.clearOptionalSint32(); - assertEquals(0, builder.getOptionalSint32()); - assertEquals(1, messageAfterBuild.getOptionalSint32()); + assertThat(builder.getOptionalSint32()).isEqualTo(0); + assertThat(messageAfterBuild.getOptionalSint32()).isEqualTo(1); message = builder.build(); builder.setOptionalSint64(1); - assertEquals(0L, message.getOptionalSint64()); - assertEquals(1L, builder.getOptionalSint64()); + assertThat(message.getOptionalSint64()).isEqualTo(0L); + assertThat(builder.getOptionalSint64()).isEqualTo(1L); messageAfterBuild = builder.build(); - assertEquals(1L, messageAfterBuild.getOptionalSint64()); - assertEquals(0L, message.getOptionalSint64()); + assertThat(messageAfterBuild.getOptionalSint64()).isEqualTo(1L); + assertThat(message.getOptionalSint64()).isEqualTo(0L); builder.clearOptionalSint64(); - assertEquals(0L, builder.getOptionalSint64()); - assertEquals(1L, messageAfterBuild.getOptionalSint64()); + assertThat(builder.getOptionalSint64()).isEqualTo(0L); + assertThat(messageAfterBuild.getOptionalSint64()).isEqualTo(1L); message = builder.build(); builder.setOptionalString("hi"); - assertEquals("", message.getOptionalString()); - assertEquals("hi", builder.getOptionalString()); + assertThat(message.getOptionalString()).isEmpty(); + assertThat(builder.getOptionalString()).isEqualTo("hi"); messageAfterBuild = builder.build(); - assertEquals("hi", messageAfterBuild.getOptionalString()); - assertEquals("", message.getOptionalString()); + assertThat(messageAfterBuild.getOptionalString()).isEqualTo("hi"); + assertThat(message.getOptionalString()).isEmpty(); builder.clearOptionalString(); - assertEquals("", builder.getOptionalString()); - assertEquals("hi", messageAfterBuild.getOptionalString()); + assertThat(builder.getOptionalString()).isEmpty(); + assertThat(messageAfterBuild.getOptionalString()).isEqualTo("hi"); message = builder.build(); builder.setOptionalStringBytes(ByteString.copyFromUtf8("no")); - assertEquals(ByteString.EMPTY, message.getOptionalStringBytes()); - assertEquals(ByteString.copyFromUtf8("no"), builder.getOptionalStringBytes()); + assertThat(message.getOptionalStringBytes()).isEqualTo(ByteString.EMPTY); + assertThat(builder.getOptionalStringBytes()).isEqualTo(ByteString.copyFromUtf8("no")); messageAfterBuild = builder.build(); - assertEquals(ByteString.copyFromUtf8("no"), messageAfterBuild.getOptionalStringBytes()); - assertEquals(ByteString.EMPTY, message.getOptionalStringBytes()); + assertThat(messageAfterBuild.getOptionalStringBytes()).isEqualTo(ByteString.copyFromUtf8("no")); + assertThat(message.getOptionalStringBytes()).isEqualTo(ByteString.EMPTY); builder.clearOptionalString(); - assertEquals(ByteString.EMPTY, builder.getOptionalStringBytes()); - assertEquals(ByteString.copyFromUtf8("no"), messageAfterBuild.getOptionalStringBytes()); + assertThat(builder.getOptionalStringBytes()).isEqualTo(ByteString.EMPTY); + assertThat(messageAfterBuild.getOptionalStringBytes()).isEqualTo(ByteString.copyFromUtf8("no")); message = builder.build(); builder.setOptionalStringPiece("hi"); - assertEquals("", message.getOptionalStringPiece()); - assertEquals("hi", builder.getOptionalStringPiece()); + assertThat(message.getOptionalStringPiece()).isEmpty(); + assertThat(builder.getOptionalStringPiece()).isEqualTo("hi"); messageAfterBuild = builder.build(); - assertEquals("hi", messageAfterBuild.getOptionalStringPiece()); - assertEquals("", message.getOptionalStringPiece()); + assertThat(messageAfterBuild.getOptionalStringPiece()).isEqualTo("hi"); + assertThat(message.getOptionalStringPiece()).isEmpty(); builder.clearOptionalStringPiece(); - assertEquals("", builder.getOptionalStringPiece()); - assertEquals("hi", messageAfterBuild.getOptionalStringPiece()); + assertThat(builder.getOptionalStringPiece()).isEmpty(); + assertThat(messageAfterBuild.getOptionalStringPiece()).isEqualTo("hi"); message = builder.build(); builder.setOptionalStringPieceBytes(ByteString.copyFromUtf8("no")); - assertEquals(ByteString.EMPTY, message.getOptionalStringPieceBytes()); - assertEquals(ByteString.copyFromUtf8("no"), builder.getOptionalStringPieceBytes()); + assertThat(message.getOptionalStringPieceBytes()).isEqualTo(ByteString.EMPTY); + assertThat(builder.getOptionalStringPieceBytes()).isEqualTo(ByteString.copyFromUtf8("no")); messageAfterBuild = builder.build(); - assertEquals(ByteString.copyFromUtf8("no"), messageAfterBuild.getOptionalStringPieceBytes()); - assertEquals(ByteString.EMPTY, message.getOptionalStringPieceBytes()); + assertThat(messageAfterBuild.getOptionalStringPieceBytes()) + .isEqualTo(ByteString.copyFromUtf8("no")); + assertThat(message.getOptionalStringPieceBytes()).isEqualTo(ByteString.EMPTY); builder.clearOptionalStringPiece(); - assertEquals(ByteString.EMPTY, builder.getOptionalStringPieceBytes()); - assertEquals(ByteString.copyFromUtf8("no"), messageAfterBuild.getOptionalStringPieceBytes()); + assertThat(builder.getOptionalStringPieceBytes()).isEqualTo(ByteString.EMPTY); + assertThat(messageAfterBuild.getOptionalStringPieceBytes()) + .isEqualTo(ByteString.copyFromUtf8("no")); message = builder.build(); builder.setOptionalUint32(1); - assertEquals(0, message.getOptionalUint32()); - assertEquals(1, builder.getOptionalUint32()); + assertThat(message.getOptionalUint32()).isEqualTo(0); + assertThat(builder.getOptionalUint32()).isEqualTo(1); messageAfterBuild = builder.build(); - assertEquals(1, messageAfterBuild.getOptionalUint32()); - assertEquals(0, message.getOptionalUint32()); + assertThat(messageAfterBuild.getOptionalUint32()).isEqualTo(1); + assertThat(message.getOptionalUint32()).isEqualTo(0); builder.clearOptionalUint32(); - assertEquals(0, builder.getOptionalUint32()); - assertEquals(1, messageAfterBuild.getOptionalUint32()); + assertThat(builder.getOptionalUint32()).isEqualTo(0); + assertThat(messageAfterBuild.getOptionalUint32()).isEqualTo(1); message = builder.build(); builder.setOptionalUint64(1); - assertEquals(0L, message.getOptionalUint64()); - assertEquals(1L, builder.getOptionalUint64()); + assertThat(message.getOptionalUint64()).isEqualTo(0L); + assertThat(builder.getOptionalUint64()).isEqualTo(1L); messageAfterBuild = builder.build(); - assertEquals(1L, messageAfterBuild.getOptionalUint64()); - assertEquals(0L, message.getOptionalUint64()); + assertThat(messageAfterBuild.getOptionalUint64()).isEqualTo(1L); + assertThat(message.getOptionalUint64()).isEqualTo(0L); builder.clearOptionalUint64(); - assertEquals(0L, builder.getOptionalUint64()); - assertEquals(1L, messageAfterBuild.getOptionalUint64()); + assertThat(builder.getOptionalUint64()).isEqualTo(0L); + assertThat(messageAfterBuild.getOptionalUint64()).isEqualTo(1L); message = builder.build(); builder.addAllRepeatedBool(singletonList(true)); - assertEquals(emptyList(), message.getRepeatedBoolList()); - assertEquals(singletonList(true), builder.getRepeatedBoolList()); - assertEquals(emptyList(), message.getRepeatedBoolList()); + assertThat(message.getRepeatedBoolList()).isEmpty(); + assertThat(builder.getRepeatedBoolList()).containsExactly(true); + assertThat(message.getRepeatedBoolList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedBool(); - assertEquals(emptyList(), builder.getRepeatedBoolList()); - assertEquals(singletonList(true), messageAfterBuild.getRepeatedBoolList()); + assertThat(builder.getRepeatedBoolList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedBoolList()).containsExactly(true); message = builder.build(); builder.addAllRepeatedBytes(singletonList(ByteString.copyFromUtf8("hi"))); - assertEquals(emptyList(), message.getRepeatedBytesList()); - assertEquals(singletonList(ByteString.copyFromUtf8("hi")), builder.getRepeatedBytesList()); - assertEquals(emptyList(), message.getRepeatedBytesList()); + assertThat(message.getRepeatedBytesList()).isEmpty(); + assertThat(builder.getRepeatedBytesList()).containsExactly(ByteString.copyFromUtf8("hi")); + assertThat(message.getRepeatedBytesList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedBytes(); - assertEquals(emptyList(), builder.getRepeatedBytesList()); - assertEquals( - singletonList(ByteString.copyFromUtf8("hi")), messageAfterBuild.getRepeatedBytesList()); + assertThat(builder.getRepeatedBytesList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedBytesList()) + .containsExactly(ByteString.copyFromUtf8("hi")); message = builder.build(); builder.addAllRepeatedCord(singletonList("hi")); - assertEquals(emptyList(), message.getRepeatedCordList()); - assertEquals(singletonList("hi"), builder.getRepeatedCordList()); - assertEquals(emptyList(), message.getRepeatedCordList()); + assertThat(message.getRepeatedCordList()).isEmpty(); + assertThat(builder.getRepeatedCordList()).containsExactly("hi"); + assertThat(message.getRepeatedCordList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedCord(); - assertEquals(emptyList(), builder.getRepeatedCordList()); - assertEquals(singletonList("hi"), messageAfterBuild.getRepeatedCordList()); + assertThat(builder.getRepeatedCordList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedCordList()).containsExactly("hi"); message = builder.build(); builder.addAllRepeatedDouble(singletonList(1D)); - assertEquals(emptyList(), message.getRepeatedDoubleList()); - assertEquals(singletonList(1D), builder.getRepeatedDoubleList()); - assertEquals(emptyList(), message.getRepeatedDoubleList()); + assertThat(message.getRepeatedDoubleList()).isEmpty(); + assertThat(builder.getRepeatedDoubleList()).containsExactly(1D); + assertThat(message.getRepeatedDoubleList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedDouble(); - assertEquals(emptyList(), builder.getRepeatedDoubleList()); - assertEquals(singletonList(1D), messageAfterBuild.getRepeatedDoubleList()); + assertThat(builder.getRepeatedDoubleList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedDoubleList()).containsExactly(1D); message = builder.build(); builder.addAllRepeatedFixed32(singletonList(1)); - assertEquals(emptyList(), message.getRepeatedFixed32List()); - assertEquals(singletonList(1), builder.getRepeatedFixed32List()); - assertEquals(emptyList(), message.getRepeatedFixed32List()); + assertThat(message.getRepeatedFixed32List()).isEmpty(); + assertThat(builder.getRepeatedFixed32List()).containsExactly(1); + assertThat(message.getRepeatedFixed32List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedFixed32(); - assertEquals(emptyList(), builder.getRepeatedFixed32List()); - assertEquals(singletonList(1), messageAfterBuild.getRepeatedFixed32List()); + assertThat(builder.getRepeatedFixed32List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedFixed32List()).containsExactly(1); message = builder.build(); builder.addAllRepeatedFixed64(singletonList(1L)); - assertEquals(emptyList(), message.getRepeatedFixed64List()); - assertEquals(singletonList(1L), builder.getRepeatedFixed64List()); - assertEquals(emptyList(), message.getRepeatedFixed64List()); + assertThat(message.getRepeatedFixed64List()).isEmpty(); + assertThat(builder.getRepeatedFixed64List()).containsExactly(1L); + assertThat(message.getRepeatedFixed64List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedFixed64(); - assertEquals(emptyList(), builder.getRepeatedFixed64List()); - assertEquals(singletonList(1L), messageAfterBuild.getRepeatedFixed64List()); + assertThat(builder.getRepeatedFixed64List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedFixed64List()).containsExactly(1L); message = builder.build(); builder.addAllRepeatedFloat(singletonList(1F)); - assertEquals(emptyList(), message.getRepeatedFloatList()); - assertEquals(singletonList(1F), builder.getRepeatedFloatList()); - assertEquals(emptyList(), message.getRepeatedFloatList()); + assertThat(message.getRepeatedFloatList()).isEmpty(); + assertThat(builder.getRepeatedFloatList()).containsExactly(1F); + assertThat(message.getRepeatedFloatList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedFloat(); - assertEquals(emptyList(), builder.getRepeatedFloatList()); - assertEquals(singletonList(1F), messageAfterBuild.getRepeatedFloatList()); + assertThat(builder.getRepeatedFloatList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedFloatList()).containsExactly(1F); message = builder.build(); builder.addAllRepeatedForeignEnum(singletonList(ForeignEnumLite.FOREIGN_LITE_BAR)); - assertEquals(emptyList(), message.getRepeatedForeignEnumList()); - assertEquals( - singletonList(ForeignEnumLite.FOREIGN_LITE_BAR), builder.getRepeatedForeignEnumList()); - assertEquals(emptyList(), message.getRepeatedForeignEnumList()); + assertThat(message.getRepeatedForeignEnumList()).isEmpty(); + assertThat(builder.getRepeatedForeignEnumList()) + .containsExactly(ForeignEnumLite.FOREIGN_LITE_BAR); + assertThat(message.getRepeatedForeignEnumList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedForeignEnum(); - assertEquals(emptyList(), builder.getRepeatedForeignEnumList()); - assertEquals( - singletonList(ForeignEnumLite.FOREIGN_LITE_BAR), - messageAfterBuild.getRepeatedForeignEnumList()); + assertThat(builder.getRepeatedForeignEnumList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedForeignEnumList()) + .containsExactly(ForeignEnumLite.FOREIGN_LITE_BAR); message = builder.build(); builder.addAllRepeatedForeignMessage(singletonList(foreignMessage)); - assertEquals(emptyList(), message.getRepeatedForeignMessageList()); - assertEquals(singletonList(foreignMessage), builder.getRepeatedForeignMessageList()); - assertEquals(emptyList(), message.getRepeatedForeignMessageList()); + assertThat(message.getRepeatedForeignMessageList()).isEmpty(); + assertThat(builder.getRepeatedForeignMessageList()).containsExactly(foreignMessage); + assertThat(message.getRepeatedForeignMessageList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedForeignMessage(); - assertEquals(emptyList(), builder.getRepeatedForeignMessageList()); - assertEquals(singletonList(foreignMessage), messageAfterBuild.getRepeatedForeignMessageList()); + assertThat(builder.getRepeatedForeignMessageList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedForeignMessageList()).containsExactly(foreignMessage); message = builder.build(); builder.addAllRepeatedGroup(singletonList(RepeatedGroup.getDefaultInstance())); - assertEquals(emptyList(), message.getRepeatedGroupList()); - assertEquals(singletonList(RepeatedGroup.getDefaultInstance()), builder.getRepeatedGroupList()); - assertEquals(emptyList(), message.getRepeatedGroupList()); + assertThat(message.getRepeatedGroupList()).isEmpty(); + assertThat(builder.getRepeatedGroupList()).containsExactly(RepeatedGroup.getDefaultInstance()); + assertThat(message.getRepeatedGroupList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedGroup(); - assertEquals(emptyList(), builder.getRepeatedGroupList()); - assertEquals( - singletonList(RepeatedGroup.getDefaultInstance()), - messageAfterBuild.getRepeatedGroupList()); + assertThat(builder.getRepeatedGroupList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedGroupList()) + .containsExactly(RepeatedGroup.getDefaultInstance()); message = builder.build(); builder.addAllRepeatedInt32(singletonList(1)); - assertEquals(emptyList(), message.getRepeatedInt32List()); - assertEquals(singletonList(1), builder.getRepeatedInt32List()); - assertEquals(emptyList(), message.getRepeatedInt32List()); + assertThat(message.getRepeatedInt32List()).isEmpty(); + assertThat(builder.getRepeatedInt32List()).containsExactly(1); + assertThat(message.getRepeatedInt32List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedInt32(); - assertEquals(emptyList(), builder.getRepeatedInt32List()); - assertEquals(singletonList(1), messageAfterBuild.getRepeatedInt32List()); + assertThat(builder.getRepeatedInt32List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedInt32List()).containsExactly(1); message = builder.build(); builder.addAllRepeatedInt64(singletonList(1L)); - assertEquals(emptyList(), message.getRepeatedInt64List()); - assertEquals(singletonList(1L), builder.getRepeatedInt64List()); - assertEquals(emptyList(), message.getRepeatedInt64List()); + assertThat(message.getRepeatedInt64List()).isEmpty(); + assertThat(builder.getRepeatedInt64List()).containsExactly(1L); + assertThat(message.getRepeatedInt64List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedInt64(); - assertEquals(emptyList(), builder.getRepeatedInt64List()); - assertEquals(singletonList(1L), messageAfterBuild.getRepeatedInt64List()); + assertThat(builder.getRepeatedInt64List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedInt64List()).containsExactly(1L); message = builder.build(); builder.addAllRepeatedLazyMessage(singletonList(nestedMessage)); - assertEquals(emptyList(), message.getRepeatedLazyMessageList()); - assertEquals(singletonList(nestedMessage), builder.getRepeatedLazyMessageList()); - assertEquals(emptyList(), message.getRepeatedLazyMessageList()); + assertThat(message.getRepeatedLazyMessageList()).isEmpty(); + assertThat(builder.getRepeatedLazyMessageList()).containsExactly(nestedMessage); + assertThat(message.getRepeatedLazyMessageList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedLazyMessage(); - assertEquals(emptyList(), builder.getRepeatedLazyMessageList()); - assertEquals(singletonList(nestedMessage), messageAfterBuild.getRepeatedLazyMessageList()); + assertThat(builder.getRepeatedLazyMessageList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedLazyMessageList()).containsExactly(nestedMessage); message = builder.build(); builder.addAllRepeatedSfixed32(singletonList(1)); - assertEquals(emptyList(), message.getRepeatedSfixed32List()); - assertEquals(singletonList(1), builder.getRepeatedSfixed32List()); - assertEquals(emptyList(), message.getRepeatedSfixed32List()); + assertThat(message.getRepeatedSfixed32List()).isEmpty(); + assertThat(builder.getRepeatedSfixed32List()).containsExactly(1); + assertThat(message.getRepeatedSfixed32List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedSfixed32(); - assertEquals(emptyList(), builder.getRepeatedSfixed32List()); - assertEquals(singletonList(1), messageAfterBuild.getRepeatedSfixed32List()); + assertThat(builder.getRepeatedSfixed32List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedSfixed32List()).containsExactly(1); message = builder.build(); builder.addAllRepeatedSfixed64(singletonList(1L)); - assertEquals(emptyList(), message.getRepeatedSfixed64List()); - assertEquals(singletonList(1L), builder.getRepeatedSfixed64List()); - assertEquals(emptyList(), message.getRepeatedSfixed64List()); + assertThat(message.getRepeatedSfixed64List()).isEmpty(); + assertThat(builder.getRepeatedSfixed64List()).containsExactly(1L); + assertThat(message.getRepeatedSfixed64List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedSfixed64(); - assertEquals(emptyList(), builder.getRepeatedSfixed64List()); - assertEquals(singletonList(1L), messageAfterBuild.getRepeatedSfixed64List()); + assertThat(builder.getRepeatedSfixed64List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedSfixed64List()).containsExactly(1L); message = builder.build(); builder.addAllRepeatedSint32(singletonList(1)); - assertEquals(emptyList(), message.getRepeatedSint32List()); - assertEquals(singletonList(1), builder.getRepeatedSint32List()); - assertEquals(emptyList(), message.getRepeatedSint32List()); + assertThat(message.getRepeatedSint32List()).isEmpty(); + assertThat(builder.getRepeatedSint32List()).containsExactly(1); + assertThat(message.getRepeatedSint32List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedSint32(); - assertEquals(emptyList(), builder.getRepeatedSint32List()); - assertEquals(singletonList(1), messageAfterBuild.getRepeatedSint32List()); + assertThat(builder.getRepeatedSint32List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedSint32List()).containsExactly(1); message = builder.build(); builder.addAllRepeatedSint64(singletonList(1L)); - assertEquals(emptyList(), message.getRepeatedSint64List()); - assertEquals(singletonList(1L), builder.getRepeatedSint64List()); - assertEquals(emptyList(), message.getRepeatedSint64List()); + assertThat(message.getRepeatedSint64List()).isEmpty(); + assertThat(builder.getRepeatedSint64List()).containsExactly(1L); + assertThat(message.getRepeatedSint64List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedSint64(); - assertEquals(emptyList(), builder.getRepeatedSint64List()); - assertEquals(singletonList(1L), messageAfterBuild.getRepeatedSint64List()); + assertThat(builder.getRepeatedSint64List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedSint64List()).containsExactly(1L); message = builder.build(); builder.addAllRepeatedString(singletonList("hi")); - assertEquals(emptyList(), message.getRepeatedStringList()); - assertEquals(singletonList("hi"), builder.getRepeatedStringList()); - assertEquals(emptyList(), message.getRepeatedStringList()); + assertThat(message.getRepeatedStringList()).isEmpty(); + assertThat(builder.getRepeatedStringList()).containsExactly("hi"); + assertThat(message.getRepeatedStringList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedString(); - assertEquals(emptyList(), builder.getRepeatedStringList()); - assertEquals(singletonList("hi"), messageAfterBuild.getRepeatedStringList()); + assertThat(builder.getRepeatedStringList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedStringList()).containsExactly("hi"); message = builder.build(); builder.addAllRepeatedStringPiece(singletonList("hi")); - assertEquals(emptyList(), message.getRepeatedStringPieceList()); - assertEquals(singletonList("hi"), builder.getRepeatedStringPieceList()); - assertEquals(emptyList(), message.getRepeatedStringPieceList()); + assertThat(message.getRepeatedStringPieceList()).isEmpty(); + assertThat(builder.getRepeatedStringPieceList()).containsExactly("hi"); + assertThat(message.getRepeatedStringPieceList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedStringPiece(); - assertEquals(emptyList(), builder.getRepeatedStringPieceList()); - assertEquals(singletonList("hi"), messageAfterBuild.getRepeatedStringPieceList()); + assertThat(builder.getRepeatedStringPieceList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedStringPieceList()).containsExactly("hi"); message = builder.build(); builder.addAllRepeatedUint32(singletonList(1)); - assertEquals(emptyList(), message.getRepeatedUint32List()); - assertEquals(singletonList(1), builder.getRepeatedUint32List()); - assertEquals(emptyList(), message.getRepeatedUint32List()); + assertThat(message.getRepeatedUint32List()).isEmpty(); + assertThat(builder.getRepeatedUint32List()).containsExactly(1); + assertThat(message.getRepeatedUint32List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedUint32(); - assertEquals(emptyList(), builder.getRepeatedUint32List()); - assertEquals(singletonList(1), messageAfterBuild.getRepeatedUint32List()); + assertThat(builder.getRepeatedUint32List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedUint32List()).containsExactly(1); message = builder.build(); builder.addAllRepeatedUint64(singletonList(1L)); - assertEquals(emptyList(), message.getRepeatedUint64List()); - assertEquals(singletonList(1L), builder.getRepeatedUint64List()); - assertEquals(emptyList(), message.getRepeatedUint64List()); + assertThat(message.getRepeatedUint64List()).isEmpty(); + assertThat(builder.getRepeatedUint64List()).containsExactly(1L); + assertThat(message.getRepeatedUint64List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedUint64(); - assertEquals(emptyList(), builder.getRepeatedUint64List()); - assertEquals(singletonList(1L), messageAfterBuild.getRepeatedUint64List()); + assertThat(builder.getRepeatedUint64List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedUint64List()).containsExactly(1L); message = builder.build(); builder.addRepeatedBool(true); - assertEquals(emptyList(), message.getRepeatedBoolList()); - assertEquals(singletonList(true), builder.getRepeatedBoolList()); - assertEquals(emptyList(), message.getRepeatedBoolList()); + assertThat(message.getRepeatedBoolList()).isEmpty(); + assertThat(builder.getRepeatedBoolList()).containsExactly(true); + assertThat(message.getRepeatedBoolList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedBool(); - assertEquals(emptyList(), builder.getRepeatedBoolList()); - assertEquals(singletonList(true), messageAfterBuild.getRepeatedBoolList()); + assertThat(builder.getRepeatedBoolList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedBoolList()).containsExactly(true); message = builder.build(); builder.addRepeatedBytes(ByteString.copyFromUtf8("hi")); - assertEquals(emptyList(), message.getRepeatedBytesList()); - assertEquals(singletonList(ByteString.copyFromUtf8("hi")), builder.getRepeatedBytesList()); - assertEquals(emptyList(), message.getRepeatedBytesList()); + assertThat(message.getRepeatedBytesList()).isEmpty(); + assertThat(builder.getRepeatedBytesList()).containsExactly(ByteString.copyFromUtf8("hi")); + assertThat(message.getRepeatedBytesList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedBytes(); - assertEquals(emptyList(), builder.getRepeatedBytesList()); - assertEquals( - singletonList(ByteString.copyFromUtf8("hi")), messageAfterBuild.getRepeatedBytesList()); + assertThat(builder.getRepeatedBytesList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedBytesList()) + .containsExactly(ByteString.copyFromUtf8("hi")); message = builder.build(); builder.addRepeatedCord("hi"); - assertEquals(emptyList(), message.getRepeatedCordList()); - assertEquals(singletonList("hi"), builder.getRepeatedCordList()); - assertEquals(emptyList(), message.getRepeatedCordList()); + assertThat(message.getRepeatedCordList()).isEmpty(); + assertThat(builder.getRepeatedCordList()).containsExactly("hi"); + assertThat(message.getRepeatedCordList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedCord(); - assertEquals(emptyList(), builder.getRepeatedCordList()); - assertEquals(singletonList("hi"), messageAfterBuild.getRepeatedCordList()); + assertThat(builder.getRepeatedCordList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedCordList()).containsExactly("hi"); message = builder.build(); builder.addRepeatedDouble(1D); - assertEquals(emptyList(), message.getRepeatedDoubleList()); - assertEquals(singletonList(1D), builder.getRepeatedDoubleList()); - assertEquals(emptyList(), message.getRepeatedDoubleList()); + assertThat(message.getRepeatedDoubleList()).isEmpty(); + assertThat(builder.getRepeatedDoubleList()).containsExactly(1D); + assertThat(message.getRepeatedDoubleList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedDouble(); - assertEquals(emptyList(), builder.getRepeatedDoubleList()); - assertEquals(singletonList(1D), messageAfterBuild.getRepeatedDoubleList()); + assertThat(builder.getRepeatedDoubleList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedDoubleList()).containsExactly(1D); message = builder.build(); builder.addRepeatedFixed32(1); - assertEquals(emptyList(), message.getRepeatedFixed32List()); - assertEquals(singletonList(1), builder.getRepeatedFixed32List()); - assertEquals(emptyList(), message.getRepeatedFixed32List()); + assertThat(message.getRepeatedFixed32List()).isEmpty(); + assertThat(builder.getRepeatedFixed32List()).containsExactly(1); + assertThat(message.getRepeatedFixed32List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedFixed32(); - assertEquals(emptyList(), builder.getRepeatedFixed32List()); - assertEquals(singletonList(1), messageAfterBuild.getRepeatedFixed32List()); + assertThat(builder.getRepeatedFixed32List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedFixed32List()).containsExactly(1); message = builder.build(); builder.addRepeatedFixed64(1L); - assertEquals(emptyList(), message.getRepeatedFixed64List()); - assertEquals(singletonList(1L), builder.getRepeatedFixed64List()); - assertEquals(emptyList(), message.getRepeatedFixed64List()); + assertThat(message.getRepeatedFixed64List()).isEmpty(); + assertThat(builder.getRepeatedFixed64List()).containsExactly(1L); + assertThat(message.getRepeatedFixed64List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedFixed64(); - assertEquals(emptyList(), builder.getRepeatedFixed64List()); - assertEquals(singletonList(1L), messageAfterBuild.getRepeatedFixed64List()); + assertThat(builder.getRepeatedFixed64List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedFixed64List()).containsExactly(1L); message = builder.build(); builder.addRepeatedFloat(1F); - assertEquals(emptyList(), message.getRepeatedFloatList()); - assertEquals(singletonList(1F), builder.getRepeatedFloatList()); - assertEquals(emptyList(), message.getRepeatedFloatList()); + assertThat(message.getRepeatedFloatList()).isEmpty(); + assertThat(builder.getRepeatedFloatList()).containsExactly(1F); + assertThat(message.getRepeatedFloatList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedFloat(); - assertEquals(emptyList(), builder.getRepeatedFloatList()); - assertEquals(singletonList(1F), messageAfterBuild.getRepeatedFloatList()); + assertThat(builder.getRepeatedFloatList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedFloatList()).containsExactly(1F); message = builder.build(); builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR); - assertEquals(emptyList(), message.getRepeatedForeignEnumList()); - assertEquals( - singletonList(ForeignEnumLite.FOREIGN_LITE_BAR), builder.getRepeatedForeignEnumList()); - assertEquals(emptyList(), message.getRepeatedForeignEnumList()); + assertThat(message.getRepeatedForeignEnumList()).isEmpty(); + assertThat(builder.getRepeatedForeignEnumList()) + .containsExactly(ForeignEnumLite.FOREIGN_LITE_BAR); + assertThat(message.getRepeatedForeignEnumList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedForeignEnum(); - assertEquals(emptyList(), builder.getRepeatedForeignEnumList()); - assertEquals( - singletonList(ForeignEnumLite.FOREIGN_LITE_BAR), - messageAfterBuild.getRepeatedForeignEnumList()); + assertThat(builder.getRepeatedForeignEnumList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedForeignEnumList()) + .containsExactly(ForeignEnumLite.FOREIGN_LITE_BAR); message = builder.build(); builder.addRepeatedForeignMessage(foreignMessage); - assertEquals(emptyList(), message.getRepeatedForeignMessageList()); - assertEquals(singletonList(foreignMessage), builder.getRepeatedForeignMessageList()); - assertEquals(emptyList(), message.getRepeatedForeignMessageList()); + assertThat(message.getRepeatedForeignMessageList()).isEmpty(); + assertThat(builder.getRepeatedForeignMessageList()).containsExactly(foreignMessage); + assertThat(message.getRepeatedForeignMessageList()).isEmpty(); messageAfterBuild = builder.build(); builder.removeRepeatedForeignMessage(0); - assertEquals(emptyList(), builder.getRepeatedForeignMessageList()); - assertEquals(singletonList(foreignMessage), messageAfterBuild.getRepeatedForeignMessageList()); + assertThat(builder.getRepeatedForeignMessageList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedForeignMessageList()).containsExactly(foreignMessage); message = builder.build(); builder.addRepeatedGroup(RepeatedGroup.getDefaultInstance()); - assertEquals(emptyList(), message.getRepeatedGroupList()); - assertEquals(singletonList(RepeatedGroup.getDefaultInstance()), builder.getRepeatedGroupList()); - assertEquals(emptyList(), message.getRepeatedGroupList()); + assertThat(message.getRepeatedGroupList()).isEmpty(); + assertThat(builder.getRepeatedGroupList()).containsExactly(RepeatedGroup.getDefaultInstance()); + assertThat(message.getRepeatedGroupList()).isEmpty(); messageAfterBuild = builder.build(); builder.removeRepeatedGroup(0); - assertEquals(emptyList(), builder.getRepeatedGroupList()); - assertEquals( - singletonList(RepeatedGroup.getDefaultInstance()), - messageAfterBuild.getRepeatedGroupList()); + assertThat(builder.getRepeatedGroupList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedGroupList()) + .containsExactly(RepeatedGroup.getDefaultInstance()); message = builder.build(); builder.addRepeatedInt32(1); - assertEquals(emptyList(), message.getRepeatedInt32List()); - assertEquals(singletonList(1), builder.getRepeatedInt32List()); - assertEquals(emptyList(), message.getRepeatedInt32List()); + assertThat(message.getRepeatedInt32List()).isEmpty(); + assertThat(builder.getRepeatedInt32List()).containsExactly(1); + assertThat(message.getRepeatedInt32List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedInt32(); - assertEquals(emptyList(), builder.getRepeatedInt32List()); - assertEquals(singletonList(1), messageAfterBuild.getRepeatedInt32List()); + assertThat(builder.getRepeatedInt32List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedInt32List()).containsExactly(1); message = builder.build(); builder.addRepeatedInt64(1L); - assertEquals(emptyList(), message.getRepeatedInt64List()); - assertEquals(singletonList(1L), builder.getRepeatedInt64List()); - assertEquals(emptyList(), message.getRepeatedInt64List()); + assertThat(message.getRepeatedInt64List()).isEmpty(); + assertThat(builder.getRepeatedInt64List()).containsExactly(1L); + assertThat(message.getRepeatedInt64List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedInt64(); - assertEquals(emptyList(), builder.getRepeatedInt64List()); - assertEquals(singletonList(1L), messageAfterBuild.getRepeatedInt64List()); + assertThat(builder.getRepeatedInt64List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedInt64List()).containsExactly(1L); message = builder.build(); builder.addRepeatedLazyMessage(nestedMessage); - assertEquals(emptyList(), message.getRepeatedLazyMessageList()); - assertEquals(singletonList(nestedMessage), builder.getRepeatedLazyMessageList()); - assertEquals(emptyList(), message.getRepeatedLazyMessageList()); + assertThat(message.getRepeatedLazyMessageList()).isEmpty(); + assertThat(builder.getRepeatedLazyMessageList()).containsExactly(nestedMessage); + assertThat(message.getRepeatedLazyMessageList()).isEmpty(); messageAfterBuild = builder.build(); builder.removeRepeatedLazyMessage(0); - assertEquals(emptyList(), builder.getRepeatedLazyMessageList()); - assertEquals(singletonList(nestedMessage), messageAfterBuild.getRepeatedLazyMessageList()); + assertThat(builder.getRepeatedLazyMessageList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedLazyMessageList()).containsExactly(nestedMessage); message = builder.build(); builder.addRepeatedSfixed32(1); - assertEquals(emptyList(), message.getRepeatedSfixed32List()); - assertEquals(singletonList(1), builder.getRepeatedSfixed32List()); - assertEquals(emptyList(), message.getRepeatedSfixed32List()); + assertThat(message.getRepeatedSfixed32List()).isEmpty(); + assertThat(builder.getRepeatedSfixed32List()).containsExactly(1); + assertThat(message.getRepeatedSfixed32List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedSfixed32(); - assertEquals(emptyList(), builder.getRepeatedSfixed32List()); - assertEquals(singletonList(1), messageAfterBuild.getRepeatedSfixed32List()); + assertThat(builder.getRepeatedSfixed32List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedSfixed32List()).containsExactly(1); message = builder.build(); builder.addRepeatedSfixed64(1L); - assertEquals(emptyList(), message.getRepeatedSfixed64List()); - assertEquals(singletonList(1L), builder.getRepeatedSfixed64List()); - assertEquals(emptyList(), message.getRepeatedSfixed64List()); + assertThat(message.getRepeatedSfixed64List()).isEmpty(); + assertThat(builder.getRepeatedSfixed64List()).containsExactly(1L); + assertThat(message.getRepeatedSfixed64List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedSfixed64(); - assertEquals(emptyList(), builder.getRepeatedSfixed64List()); - assertEquals(singletonList(1L), messageAfterBuild.getRepeatedSfixed64List()); + assertThat(builder.getRepeatedSfixed64List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedSfixed64List()).containsExactly(1L); message = builder.build(); builder.addRepeatedSint32(1); - assertEquals(emptyList(), message.getRepeatedSint32List()); - assertEquals(singletonList(1), builder.getRepeatedSint32List()); - assertEquals(emptyList(), message.getRepeatedSint32List()); + assertThat(message.getRepeatedSint32List()).isEmpty(); + assertThat(builder.getRepeatedSint32List()).containsExactly(1); + assertThat(message.getRepeatedSint32List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedSint32(); - assertEquals(emptyList(), builder.getRepeatedSint32List()); - assertEquals(singletonList(1), messageAfterBuild.getRepeatedSint32List()); + assertThat(builder.getRepeatedSint32List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedSint32List()).containsExactly(1); message = builder.build(); builder.addRepeatedSint64(1L); - assertEquals(emptyList(), message.getRepeatedSint64List()); - assertEquals(singletonList(1L), builder.getRepeatedSint64List()); - assertEquals(emptyList(), message.getRepeatedSint64List()); + assertThat(message.getRepeatedSint64List()).isEmpty(); + assertThat(builder.getRepeatedSint64List()).containsExactly(1L); + assertThat(message.getRepeatedSint64List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedSint64(); - assertEquals(emptyList(), builder.getRepeatedSint64List()); - assertEquals(singletonList(1L), messageAfterBuild.getRepeatedSint64List()); + assertThat(builder.getRepeatedSint64List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedSint64List()).containsExactly(1L); message = builder.build(); builder.addRepeatedString("hi"); - assertEquals(emptyList(), message.getRepeatedStringList()); - assertEquals(singletonList("hi"), builder.getRepeatedStringList()); - assertEquals(emptyList(), message.getRepeatedStringList()); + assertThat(message.getRepeatedStringList()).isEmpty(); + assertThat(builder.getRepeatedStringList()).containsExactly("hi"); + assertThat(message.getRepeatedStringList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedString(); - assertEquals(emptyList(), builder.getRepeatedStringList()); - assertEquals(singletonList("hi"), messageAfterBuild.getRepeatedStringList()); + assertThat(builder.getRepeatedStringList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedStringList()).containsExactly("hi"); message = builder.build(); builder.addRepeatedStringPiece("hi"); - assertEquals(emptyList(), message.getRepeatedStringPieceList()); - assertEquals(singletonList("hi"), builder.getRepeatedStringPieceList()); - assertEquals(emptyList(), message.getRepeatedStringPieceList()); + assertThat(message.getRepeatedStringPieceList()).isEmpty(); + assertThat(builder.getRepeatedStringPieceList()).containsExactly("hi"); + assertThat(message.getRepeatedStringPieceList()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedStringPiece(); - assertEquals(emptyList(), builder.getRepeatedStringPieceList()); - assertEquals(singletonList("hi"), messageAfterBuild.getRepeatedStringPieceList()); + assertThat(builder.getRepeatedStringPieceList()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedStringPieceList()).containsExactly("hi"); message = builder.build(); builder.addRepeatedUint32(1); - assertEquals(emptyList(), message.getRepeatedUint32List()); - assertEquals(singletonList(1), builder.getRepeatedUint32List()); - assertEquals(emptyList(), message.getRepeatedUint32List()); + assertThat(message.getRepeatedUint32List()).isEmpty(); + assertThat(builder.getRepeatedUint32List()).containsExactly(1); + assertThat(message.getRepeatedUint32List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedUint32(); - assertEquals(emptyList(), builder.getRepeatedUint32List()); - assertEquals(singletonList(1), messageAfterBuild.getRepeatedUint32List()); + assertThat(builder.getRepeatedUint32List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedUint32List()).containsExactly(1); message = builder.build(); builder.addRepeatedUint64(1L); - assertEquals(emptyList(), message.getRepeatedUint64List()); - assertEquals(singletonList(1L), builder.getRepeatedUint64List()); - assertEquals(emptyList(), message.getRepeatedUint64List()); + assertThat(message.getRepeatedUint64List()).isEmpty(); + assertThat(builder.getRepeatedUint64List()).containsExactly(1L); + assertThat(message.getRepeatedUint64List()).isEmpty(); messageAfterBuild = builder.build(); builder.clearRepeatedUint64(); - assertEquals(emptyList(), builder.getRepeatedUint64List()); - assertEquals(singletonList(1L), messageAfterBuild.getRepeatedUint64List()); + assertThat(builder.getRepeatedUint64List()).isEmpty(); + assertThat(messageAfterBuild.getRepeatedUint64List()).containsExactly(1L); message = builder.build(); builder.addRepeatedBool(true); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedBoolCount()); + assertThat(message.getRepeatedBoolCount()).isEqualTo(0); builder.setRepeatedBool(0, false); - assertEquals(true, messageAfterBuild.getRepeatedBool(0)); - assertEquals(false, builder.getRepeatedBool(0)); + assertThat(messageAfterBuild.getRepeatedBool(0)).isTrue(); + assertThat(builder.getRepeatedBool(0)).isFalse(); builder.clearRepeatedBool(); message = builder.build(); builder.addRepeatedBytes(ByteString.copyFromUtf8("hi")); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedBytesCount()); + assertThat(message.getRepeatedBytesCount()).isEqualTo(0); builder.setRepeatedBytes(0, ByteString.EMPTY); - assertEquals(ByteString.copyFromUtf8("hi"), messageAfterBuild.getRepeatedBytes(0)); - assertEquals(ByteString.EMPTY, builder.getRepeatedBytes(0)); + assertThat(messageAfterBuild.getRepeatedBytes(0)).isEqualTo(ByteString.copyFromUtf8("hi")); + assertThat(builder.getRepeatedBytes(0)).isEqualTo(ByteString.EMPTY); builder.clearRepeatedBytes(); message = builder.build(); builder.addRepeatedCord("hi"); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedCordCount()); + assertThat(message.getRepeatedCordCount()).isEqualTo(0); builder.setRepeatedCord(0, ""); - assertEquals("hi", messageAfterBuild.getRepeatedCord(0)); - assertEquals("", builder.getRepeatedCord(0)); + assertThat(messageAfterBuild.getRepeatedCord(0)).isEqualTo("hi"); + assertThat(builder.getRepeatedCord(0)).isEmpty(); builder.clearRepeatedCord(); message = builder.build(); builder.addRepeatedCordBytes(ByteString.copyFromUtf8("hi")); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedCordCount()); + assertThat(message.getRepeatedCordCount()).isEqualTo(0); builder.setRepeatedCord(0, ""); - assertEquals(ByteString.copyFromUtf8("hi"), messageAfterBuild.getRepeatedCordBytes(0)); - assertEquals(ByteString.EMPTY, builder.getRepeatedCordBytes(0)); + assertThat(messageAfterBuild.getRepeatedCordBytes(0)).isEqualTo(ByteString.copyFromUtf8("hi")); + assertThat(builder.getRepeatedCordBytes(0)).isEqualTo(ByteString.EMPTY); builder.clearRepeatedCord(); message = builder.build(); builder.addRepeatedDouble(1D); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedDoubleCount()); + assertThat(message.getRepeatedDoubleCount()).isEqualTo(0); builder.setRepeatedDouble(0, 0D); - assertEquals(1D, messageAfterBuild.getRepeatedDouble(0), 0.0); - assertEquals(0D, builder.getRepeatedDouble(0), 0.0); + assertThat(messageAfterBuild.getRepeatedDouble(0)).isEqualTo(1D); + assertThat(builder.getRepeatedDouble(0)).isEqualTo(0D); builder.clearRepeatedDouble(); message = builder.build(); builder.addRepeatedFixed32(1); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedFixed32Count()); + assertThat(message.getRepeatedFixed32Count()).isEqualTo(0); builder.setRepeatedFixed32(0, 0); - assertEquals(1, messageAfterBuild.getRepeatedFixed32(0)); - assertEquals(0, builder.getRepeatedFixed32(0)); + assertThat(messageAfterBuild.getRepeatedFixed32(0)).isEqualTo(1); + assertThat(builder.getRepeatedFixed32(0)).isEqualTo(0); builder.clearRepeatedFixed32(); message = builder.build(); builder.addRepeatedFixed64(1L); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedFixed64Count()); + assertThat(message.getRepeatedFixed64Count()).isEqualTo(0); builder.setRepeatedFixed64(0, 0L); - assertEquals(1L, messageAfterBuild.getRepeatedFixed64(0)); - assertEquals(0L, builder.getRepeatedFixed64(0)); + assertThat(messageAfterBuild.getRepeatedFixed64(0)).isEqualTo(1L); + assertThat(builder.getRepeatedFixed64(0)).isEqualTo(0L); builder.clearRepeatedFixed64(); message = builder.build(); builder.addRepeatedFloat(1F); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedFloatCount()); + assertThat(message.getRepeatedFloatCount()).isEqualTo(0); builder.setRepeatedFloat(0, 0F); - assertEquals(1F, messageAfterBuild.getRepeatedFloat(0), 0.0f); - assertEquals(0F, builder.getRepeatedFloat(0), 0.0f); + assertThat(messageAfterBuild.getRepeatedFloat(0)).isEqualTo(1F); + assertThat(builder.getRepeatedFloat(0)).isEqualTo(0F); builder.clearRepeatedFloat(); message = builder.build(); builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedForeignEnumCount()); + assertThat(message.getRepeatedForeignEnumCount()).isEqualTo(0); builder.setRepeatedForeignEnum(0, ForeignEnumLite.FOREIGN_LITE_FOO); - assertEquals(ForeignEnumLite.FOREIGN_LITE_BAR, messageAfterBuild.getRepeatedForeignEnum(0)); - assertEquals(ForeignEnumLite.FOREIGN_LITE_FOO, builder.getRepeatedForeignEnum(0)); + assertThat(messageAfterBuild.getRepeatedForeignEnum(0)) + .isEqualTo(ForeignEnumLite.FOREIGN_LITE_BAR); + assertThat(builder.getRepeatedForeignEnum(0)).isEqualTo(ForeignEnumLite.FOREIGN_LITE_FOO); builder.clearRepeatedForeignEnum(); message = builder.build(); builder.addRepeatedForeignMessage(foreignMessage); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedForeignMessageCount()); + assertThat(message.getRepeatedForeignMessageCount()).isEqualTo(0); builder.setRepeatedForeignMessage(0, ForeignMessageLite.getDefaultInstance()); - assertEquals(foreignMessage, messageAfterBuild.getRepeatedForeignMessage(0)); - assertEquals(ForeignMessageLite.getDefaultInstance(), builder.getRepeatedForeignMessage(0)); + assertThat(messageAfterBuild.getRepeatedForeignMessage(0)).isEqualTo(foreignMessage); + assertThat(builder.getRepeatedForeignMessage(0)) + .isEqualTo(ForeignMessageLite.getDefaultInstance()); builder.clearRepeatedForeignMessage(); message = builder.build(); builder.addRepeatedForeignMessage(foreignMessageC3); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedForeignMessageCount()); + assertThat(message.getRepeatedForeignMessageCount()).isEqualTo(0); builder.setRepeatedForeignMessage(0, ForeignMessageLite.getDefaultInstance()); - assertEquals(foreignMessageC3, messageAfterBuild.getRepeatedForeignMessage(0)); - assertEquals(ForeignMessageLite.getDefaultInstance(), builder.getRepeatedForeignMessage(0)); + assertThat(messageAfterBuild.getRepeatedForeignMessage(0)).isEqualTo(foreignMessageC3); + assertThat(builder.getRepeatedForeignMessage(0)) + .isEqualTo(ForeignMessageLite.getDefaultInstance()); builder.clearRepeatedForeignMessage(); message = builder.build(); builder.addRepeatedForeignMessage(0, foreignMessage); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedForeignMessageCount()); + assertThat(message.getRepeatedForeignMessageCount()).isEqualTo(0); builder.setRepeatedForeignMessage(0, foreignMessageC3); - assertEquals(foreignMessage, messageAfterBuild.getRepeatedForeignMessage(0)); - assertEquals(foreignMessageC3, builder.getRepeatedForeignMessage(0)); + assertThat(messageAfterBuild.getRepeatedForeignMessage(0)).isEqualTo(foreignMessage); + assertThat(builder.getRepeatedForeignMessage(0)).isEqualTo(foreignMessageC3); builder.clearRepeatedForeignMessage(); message = builder.build(); RepeatedGroup repeatedGroup = RepeatedGroup.newBuilder().setA(1).build(); builder.addRepeatedGroup(repeatedGroup); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedGroupCount()); + assertThat(message.getRepeatedGroupCount()).isEqualTo(0); builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance()); - assertEquals(repeatedGroup, messageAfterBuild.getRepeatedGroup(0)); - assertEquals(RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0)); + assertThat(messageAfterBuild.getRepeatedGroup(0)).isEqualTo(repeatedGroup); + assertThat(builder.getRepeatedGroup(0)).isEqualTo(RepeatedGroup.getDefaultInstance()); builder.clearRepeatedGroup(); message = builder.build(); builder.addRepeatedGroup(0, repeatedGroup); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedGroupCount()); + assertThat(message.getRepeatedGroupCount()).isEqualTo(0); builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance()); - assertEquals(repeatedGroup, messageAfterBuild.getRepeatedGroup(0)); - assertEquals(RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0)); + assertThat(messageAfterBuild.getRepeatedGroup(0)).isEqualTo(repeatedGroup); + assertThat(builder.getRepeatedGroup(0)).isEqualTo(RepeatedGroup.getDefaultInstance()); builder.clearRepeatedGroup(); message = builder.build(); RepeatedGroup.Builder repeatedGroupBuilder = RepeatedGroup.newBuilder().setA(3); builder.addRepeatedGroup(repeatedGroupBuilder); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedGroupCount()); + assertThat(message.getRepeatedGroupCount()).isEqualTo(0); builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance()); - assertEquals(repeatedGroupBuilder.build(), messageAfterBuild.getRepeatedGroup(0)); - assertEquals(RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0)); + assertThat(messageAfterBuild.getRepeatedGroup(0)).isEqualTo(repeatedGroupBuilder.build()); + assertThat(builder.getRepeatedGroup(0)).isEqualTo(RepeatedGroup.getDefaultInstance()); builder.clearRepeatedGroup(); message = builder.build(); builder.addRepeatedGroup(0, repeatedGroupBuilder); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedGroupCount()); + assertThat(message.getRepeatedGroupCount()).isEqualTo(0); builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance()); - assertEquals(repeatedGroupBuilder.build(), messageAfterBuild.getRepeatedGroup(0)); - assertEquals(RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0)); + assertThat(messageAfterBuild.getRepeatedGroup(0)).isEqualTo(repeatedGroupBuilder.build()); + assertThat(builder.getRepeatedGroup(0)).isEqualTo(RepeatedGroup.getDefaultInstance()); builder.clearRepeatedGroup(); message = builder.build(); builder.addRepeatedInt32(1); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedInt32Count()); + assertThat(message.getRepeatedInt32Count()).isEqualTo(0); builder.setRepeatedInt32(0, 0); - assertEquals(1, messageAfterBuild.getRepeatedInt32(0)); - assertEquals(0, builder.getRepeatedInt32(0)); + assertThat(messageAfterBuild.getRepeatedInt32(0)).isEqualTo(1); + assertThat(builder.getRepeatedInt32(0)).isEqualTo(0); builder.clearRepeatedInt32(); message = builder.build(); builder.addRepeatedInt64(1L); messageAfterBuild = builder.build(); - assertEquals(0L, message.getRepeatedInt64Count()); + assertThat(message.getRepeatedInt64Count()).isEqualTo(0L); builder.setRepeatedInt64(0, 0L); - assertEquals(1L, messageAfterBuild.getRepeatedInt64(0)); - assertEquals(0L, builder.getRepeatedInt64(0)); + assertThat(messageAfterBuild.getRepeatedInt64(0)).isEqualTo(1L); + assertThat(builder.getRepeatedInt64(0)).isEqualTo(0L); builder.clearRepeatedInt64(); message = builder.build(); builder.addRepeatedLazyMessage(nestedMessage); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedLazyMessageCount()); + assertThat(message.getRepeatedLazyMessageCount()).isEqualTo(0); builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance()); - assertEquals(nestedMessage, messageAfterBuild.getRepeatedLazyMessage(0)); - assertEquals(NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0)); + assertThat(messageAfterBuild.getRepeatedLazyMessage(0)).isEqualTo(nestedMessage); + assertThat(builder.getRepeatedLazyMessage(0)).isEqualTo(NestedMessage.getDefaultInstance()); builder.clearRepeatedLazyMessage(); message = builder.build(); builder.addRepeatedLazyMessage(0, nestedMessage); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedLazyMessageCount()); + assertThat(message.getRepeatedLazyMessageCount()).isEqualTo(0); builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance()); - assertEquals(nestedMessage, messageAfterBuild.getRepeatedLazyMessage(0)); - assertEquals(NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0)); + assertThat(messageAfterBuild.getRepeatedLazyMessage(0)).isEqualTo(nestedMessage); + assertThat(builder.getRepeatedLazyMessage(0)).isEqualTo(NestedMessage.getDefaultInstance()); builder.clearRepeatedLazyMessage(); message = builder.build(); builder.addRepeatedLazyMessage(nestedMessageBuilder); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedLazyMessageCount()); + assertThat(message.getRepeatedLazyMessageCount()).isEqualTo(0); builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance()); - assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getRepeatedLazyMessage(0)); - assertEquals(NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0)); + assertThat(messageAfterBuild.getRepeatedLazyMessage(0)).isEqualTo(nestedMessageBuilder.build()); + assertThat(builder.getRepeatedLazyMessage(0)).isEqualTo(NestedMessage.getDefaultInstance()); builder.clearRepeatedLazyMessage(); message = builder.build(); builder.addRepeatedLazyMessage(0, nestedMessageBuilder); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedLazyMessageCount()); + assertThat(message.getRepeatedLazyMessageCount()).isEqualTo(0); builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance()); - assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getRepeatedLazyMessage(0)); - assertEquals(NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0)); + assertThat(messageAfterBuild.getRepeatedLazyMessage(0)).isEqualTo(nestedMessageBuilder.build()); + assertThat(builder.getRepeatedLazyMessage(0)).isEqualTo(NestedMessage.getDefaultInstance()); builder.clearRepeatedLazyMessage(); message = builder.build(); builder.addRepeatedSfixed32(1); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedSfixed32Count()); + assertThat(message.getRepeatedSfixed32Count()).isEqualTo(0); builder.setRepeatedSfixed32(0, 0); - assertEquals(1, messageAfterBuild.getRepeatedSfixed32(0)); - assertEquals(0, builder.getRepeatedSfixed32(0)); + assertThat(messageAfterBuild.getRepeatedSfixed32(0)).isEqualTo(1); + assertThat(builder.getRepeatedSfixed32(0)).isEqualTo(0); builder.clearRepeatedSfixed32(); message = builder.build(); builder.addRepeatedSfixed64(1L); messageAfterBuild = builder.build(); - assertEquals(0L, message.getRepeatedSfixed64Count()); + assertThat(message.getRepeatedSfixed64Count()).isEqualTo(0L); builder.setRepeatedSfixed64(0, 0L); - assertEquals(1L, messageAfterBuild.getRepeatedSfixed64(0)); - assertEquals(0L, builder.getRepeatedSfixed64(0)); + assertThat(messageAfterBuild.getRepeatedSfixed64(0)).isEqualTo(1L); + assertThat(builder.getRepeatedSfixed64(0)).isEqualTo(0L); builder.clearRepeatedSfixed64(); message = builder.build(); builder.addRepeatedSint32(1); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedSint32Count()); + assertThat(message.getRepeatedSint32Count()).isEqualTo(0); builder.setRepeatedSint32(0, 0); - assertEquals(1, messageAfterBuild.getRepeatedSint32(0)); - assertEquals(0, builder.getRepeatedSint32(0)); + assertThat(messageAfterBuild.getRepeatedSint32(0)).isEqualTo(1); + assertThat(builder.getRepeatedSint32(0)).isEqualTo(0); builder.clearRepeatedSint32(); message = builder.build(); builder.addRepeatedSint64(1L); messageAfterBuild = builder.build(); - assertEquals(0L, message.getRepeatedSint64Count()); + assertThat(message.getRepeatedSint64Count()).isEqualTo(0L); builder.setRepeatedSint64(0, 0L); - assertEquals(1L, messageAfterBuild.getRepeatedSint64(0)); - assertEquals(0L, builder.getRepeatedSint64(0)); + assertThat(messageAfterBuild.getRepeatedSint64(0)).isEqualTo(1L); + assertThat(builder.getRepeatedSint64(0)).isEqualTo(0L); builder.clearRepeatedSint64(); message = builder.build(); builder.addRepeatedString("hi"); messageAfterBuild = builder.build(); - assertEquals(0L, message.getRepeatedStringCount()); + assertThat(message.getRepeatedStringCount()).isEqualTo(0L); builder.setRepeatedString(0, ""); - assertEquals("hi", messageAfterBuild.getRepeatedString(0)); - assertEquals("", builder.getRepeatedString(0)); + assertThat(messageAfterBuild.getRepeatedString(0)).isEqualTo("hi"); + assertThat(builder.getRepeatedString(0)).isEmpty(); builder.clearRepeatedString(); message = builder.build(); builder.addRepeatedStringBytes(ByteString.copyFromUtf8("hi")); messageAfterBuild = builder.build(); - assertEquals(0L, message.getRepeatedStringCount()); + assertThat(message.getRepeatedStringCount()).isEqualTo(0L); builder.setRepeatedString(0, ""); - assertEquals(ByteString.copyFromUtf8("hi"), messageAfterBuild.getRepeatedStringBytes(0)); - assertEquals(ByteString.EMPTY, builder.getRepeatedStringBytes(0)); + assertThat(messageAfterBuild.getRepeatedStringBytes(0)) + .isEqualTo(ByteString.copyFromUtf8("hi")); + assertThat(builder.getRepeatedStringBytes(0)).isEqualTo(ByteString.EMPTY); builder.clearRepeatedString(); message = builder.build(); builder.addRepeatedStringPiece("hi"); messageAfterBuild = builder.build(); - assertEquals(0L, message.getRepeatedStringPieceCount()); + assertThat(message.getRepeatedStringPieceCount()).isEqualTo(0L); builder.setRepeatedStringPiece(0, ""); - assertEquals("hi", messageAfterBuild.getRepeatedStringPiece(0)); - assertEquals("", builder.getRepeatedStringPiece(0)); + assertThat(messageAfterBuild.getRepeatedStringPiece(0)).isEqualTo("hi"); + assertThat(builder.getRepeatedStringPiece(0)).isEmpty(); builder.clearRepeatedStringPiece(); message = builder.build(); builder.addRepeatedStringPieceBytes(ByteString.copyFromUtf8("hi")); messageAfterBuild = builder.build(); - assertEquals(0L, message.getRepeatedStringPieceCount()); + assertThat(message.getRepeatedStringPieceCount()).isEqualTo(0L); builder.setRepeatedStringPiece(0, ""); - assertEquals(ByteString.copyFromUtf8("hi"), messageAfterBuild.getRepeatedStringPieceBytes(0)); - assertEquals(ByteString.EMPTY, builder.getRepeatedStringPieceBytes(0)); + assertThat(messageAfterBuild.getRepeatedStringPieceBytes(0)) + .isEqualTo(ByteString.copyFromUtf8("hi")); + assertThat(builder.getRepeatedStringPieceBytes(0)).isEqualTo(ByteString.EMPTY); builder.clearRepeatedStringPiece(); message = builder.build(); builder.addRepeatedUint32(1); messageAfterBuild = builder.build(); - assertEquals(0, message.getRepeatedUint32Count()); + assertThat(message.getRepeatedUint32Count()).isEqualTo(0); builder.setRepeatedUint32(0, 0); - assertEquals(1, messageAfterBuild.getRepeatedUint32(0)); - assertEquals(0, builder.getRepeatedUint32(0)); + assertThat(messageAfterBuild.getRepeatedUint32(0)).isEqualTo(1); + assertThat(builder.getRepeatedUint32(0)).isEqualTo(0); builder.clearRepeatedUint32(); message = builder.build(); builder.addRepeatedUint64(1L); messageAfterBuild = builder.build(); - assertEquals(0L, message.getRepeatedUint64Count()); + assertThat(message.getRepeatedUint64Count()).isEqualTo(0L); builder.setRepeatedUint64(0, 0L); - assertEquals(1L, messageAfterBuild.getRepeatedUint64(0)); - assertEquals(0L, builder.getRepeatedUint64(0)); + assertThat(messageAfterBuild.getRepeatedUint64(0)).isEqualTo(1L); + assertThat(builder.getRepeatedUint64(0)).isEqualTo(0L); builder.clearRepeatedUint64(); message = builder.build(); - assertEquals(0, message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(0); builder.mergeFrom(TestAllTypesLite.newBuilder().setOptionalBool(true).build()); - assertEquals(0, message.getSerializedSize()); - assertEquals(true, builder.build().getOptionalBool()); + assertThat(message.getSerializedSize()).isEqualTo(0); + assertThat(builder.build().getOptionalBool()).isTrue(); builder.clearOptionalBool(); message = builder.build(); - assertEquals(0, message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(0); builder.mergeFrom(TestAllTypesLite.newBuilder().setOptionalBool(true).build()); - assertEquals(0, message.getSerializedSize()); - assertEquals(true, builder.build().getOptionalBool()); + assertThat(message.getSerializedSize()).isEqualTo(0); + assertThat(builder.build().getOptionalBool()).isTrue(); builder.clear(); - assertEquals(0, builder.build().getSerializedSize()); + assertThat(builder.build().getSerializedSize()).isEqualTo(0); message = builder.build(); - assertEquals(0, message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(0); builder.mergeOptionalForeignMessage(foreignMessage); - assertEquals(0, message.getSerializedSize()); - assertEquals(foreignMessage.getC(), builder.build().getOptionalForeignMessage().getC()); + assertThat(message.getSerializedSize()).isEqualTo(0); + assertThat(builder.build().getOptionalForeignMessage().getC()).isEqualTo(foreignMessage.getC()); builder.clearOptionalForeignMessage(); message = builder.build(); - assertEquals(0, message.getSerializedSize()); + assertThat(message.getSerializedSize()).isEqualTo(0); builder.mergeOptionalLazyMessage(nestedMessage); - assertEquals(0, message.getSerializedSize()); - assertEquals(nestedMessage.getBb(), builder.build().getOptionalLazyMessage().getBb()); + assertThat(message.getSerializedSize()).isEqualTo(0); + assertThat(builder.build().getOptionalLazyMessage().getBb()).isEqualTo(nestedMessage.getBb()); builder.clearOptionalLazyMessage(); message = builder.build(); builder.setOneofString("hi"); - assertEquals(OneofFieldCase.ONEOFFIELD_NOT_SET, message.getOneofFieldCase()); - assertEquals(OneofFieldCase.ONEOF_STRING, builder.getOneofFieldCase()); - assertEquals("hi", builder.getOneofString()); + assertThat(message.getOneofFieldCase()).isEqualTo(OneofFieldCase.ONEOFFIELD_NOT_SET); + assertThat(builder.getOneofFieldCase()).isEqualTo(OneofFieldCase.ONEOF_STRING); + assertThat(builder.getOneofString()).isEqualTo("hi"); messageAfterBuild = builder.build(); - assertEquals(OneofFieldCase.ONEOF_STRING, messageAfterBuild.getOneofFieldCase()); - assertEquals("hi", messageAfterBuild.getOneofString()); + assertThat(messageAfterBuild.getOneofFieldCase()).isEqualTo(OneofFieldCase.ONEOF_STRING); + assertThat(messageAfterBuild.getOneofString()).isEqualTo("hi"); builder.setOneofUint32(1); - assertEquals(OneofFieldCase.ONEOF_STRING, messageAfterBuild.getOneofFieldCase()); - assertEquals("hi", messageAfterBuild.getOneofString()); - assertEquals(OneofFieldCase.ONEOF_UINT32, builder.getOneofFieldCase()); - assertEquals(1, builder.getOneofUint32()); + assertThat(messageAfterBuild.getOneofFieldCase()).isEqualTo(OneofFieldCase.ONEOF_STRING); + assertThat(messageAfterBuild.getOneofString()).isEqualTo("hi"); + assertThat(builder.getOneofFieldCase()).isEqualTo(OneofFieldCase.ONEOF_UINT32); + assertThat(builder.getOneofUint32()).isEqualTo(1); TestAllTypesLiteOrBuilder messageOrBuilder = builder; - assertEquals(OneofFieldCase.ONEOF_UINT32, messageOrBuilder.getOneofFieldCase()); + assertThat(messageOrBuilder.getOneofFieldCase()).isEqualTo(OneofFieldCase.ONEOF_UINT32); TestAllExtensionsLite.Builder extendableMessageBuilder = TestAllExtensionsLite.newBuilder(); TestAllExtensionsLite extendableMessage = extendableMessageBuilder.build(); extendableMessageBuilder.setExtension(UnittestLite.optionalInt32ExtensionLite, 1); - assertFalse(extendableMessage.hasExtension(UnittestLite.optionalInt32ExtensionLite)); + assertThat(extendableMessage.hasExtension(UnittestLite.optionalInt32ExtensionLite)).isFalse(); extendableMessage = extendableMessageBuilder.build(); - assertEquals( - 1, (int) extendableMessageBuilder.getExtension(UnittestLite.optionalInt32ExtensionLite)); - assertEquals(1, (int) extendableMessage.getExtension(UnittestLite.optionalInt32ExtensionLite)); + assertThat((int) extendableMessageBuilder.getExtension(UnittestLite.optionalInt32ExtensionLite)) + .isEqualTo(1); + assertThat((int) extendableMessage.getExtension(UnittestLite.optionalInt32ExtensionLite)) + .isEqualTo(1); extendableMessageBuilder.setExtension(UnittestLite.optionalInt32ExtensionLite, 3); - assertEquals( - 3, (int) extendableMessageBuilder.getExtension(UnittestLite.optionalInt32ExtensionLite)); - assertEquals(1, (int) extendableMessage.getExtension(UnittestLite.optionalInt32ExtensionLite)); + assertThat((int) extendableMessageBuilder.getExtension(UnittestLite.optionalInt32ExtensionLite)) + .isEqualTo(3); + assertThat((int) extendableMessage.getExtension(UnittestLite.optionalInt32ExtensionLite)) + .isEqualTo(1); extendableMessage = extendableMessageBuilder.build(); - assertEquals( - 3, (int) extendableMessageBuilder.getExtension(UnittestLite.optionalInt32ExtensionLite)); - assertEquals(3, (int) extendableMessage.getExtension(UnittestLite.optionalInt32ExtensionLite)); + assertThat((int) extendableMessageBuilder.getExtension(UnittestLite.optionalInt32ExtensionLite)) + .isEqualTo(3); + assertThat((int) extendableMessage.getExtension(UnittestLite.optionalInt32ExtensionLite)) + .isEqualTo(3); // No extension registry, so it should be in unknown fields. extendableMessage = TestAllExtensionsLite.parseFrom(extendableMessage.toByteArray()); - assertFalse(extendableMessage.hasExtension(UnittestLite.optionalInt32ExtensionLite)); + assertThat(extendableMessage.hasExtension(UnittestLite.optionalInt32ExtensionLite)).isFalse(); extendableMessageBuilder = extendableMessage.toBuilder(); extendableMessageBuilder.mergeFrom( @@ -1313,21 +1337,24 @@ extendableMessage = TestAllExtensionsLite.parseFrom(extendableMessage.toByteArray(), registry); // The unknown field was preserved. - assertEquals(3, (int) extendableMessage.getExtension(UnittestLite.optionalInt32ExtensionLite)); - assertEquals( - 11, (int) extendableMessage.getExtension(UnittestLite.optionalFixed32ExtensionLite)); + assertThat((int) extendableMessage.getExtension(UnittestLite.optionalInt32ExtensionLite)) + .isEqualTo(3); + assertThat((int) extendableMessage.getExtension(UnittestLite.optionalFixed32ExtensionLite)) + .isEqualTo(11); } + @Test public void testBuilderMergeFromNull() throws Exception { try { TestAllTypesLite.newBuilder().mergeFrom((TestAllTypesLite) null); - fail("Expected exception"); + assertWithMessage("expected exception").fail(); } catch (NullPointerException e) { // Pass. } } // Builder.mergeFrom() should keep existing extensions. + @Test public void testBuilderMergeFromWithExtensions() throws Exception { TestAllExtensionsLite message = TestAllExtensionsLite.newBuilder() @@ -1341,12 +1368,15 @@ builder.mergeFrom(message.toByteArray(), registry); builder.mergeFrom(message.toByteArray(), registry); TestAllExtensionsLite result = builder.build(); - assertEquals(2, result.getExtensionCount(UnittestLite.repeatedInt32ExtensionLite)); - assertEquals(12, result.getExtension(UnittestLite.repeatedInt32ExtensionLite, 0).intValue()); - assertEquals(12, result.getExtension(UnittestLite.repeatedInt32ExtensionLite, 1).intValue()); + assertThat(result.getExtensionCount(UnittestLite.repeatedInt32ExtensionLite)).isEqualTo(2); + assertThat(result.getExtension(UnittestLite.repeatedInt32ExtensionLite, 0).intValue()) + .isEqualTo(12); + assertThat(result.getExtension(UnittestLite.repeatedInt32ExtensionLite, 1).intValue()) + .isEqualTo(12); } // Builder.mergeFrom() should keep existing unknown fields. + @Test public void testBuilderMergeFromWithUnknownFields() throws Exception { TestAllTypesLite message = TestAllTypesLite.newBuilder().addRepeatedInt32(1).build(); @@ -1354,9 +1384,10 @@ builder.mergeFrom(message.toByteArray()); builder.mergeFrom(message.toByteArray()); NestedMessage result = builder.build(); - assertEquals(message.getSerializedSize() * 2, result.getSerializedSize()); + assertThat(result.getSerializedSize()).isEqualTo(message.getSerializedSize() * 2); } + @Test public void testMergeFrom_differentFieldsSetWithinOneField() throws Exception { TestAllTypesLite result = TestAllTypesLite.newBuilder() @@ -1370,6 +1401,7 @@ assertToStringEquals("oneof_nested_message2 {\n dd: 3\n}", result); } + @Test public void testMergeFrom_differentFieldsOfSameTypeSetWithinOneField() throws Exception { TestAllTypesLite result = TestAllTypesLite.newBuilder() @@ -1383,6 +1415,7 @@ assertToStringEquals("oneof_lazy_nested_message {\n cc: 3\n}", result); } + @Test public void testMergeFrom_sameFieldSetWithinOneofField() throws Exception { TestAllTypesLite result = TestAllTypesLite.newBuilder() @@ -1396,16 +1429,19 @@ assertToStringEquals("oneof_nested_message {\n bb: 2\n cc: 4\n}", result); } + @Test public void testToStringDefaultInstance() throws Exception { assertToStringEquals("", TestAllTypesLite.getDefaultInstance()); } + @Test public void testToStringScalarFieldsSuffixedWithList() throws Exception { assertToStringEquals( "deceptively_named_list: 7", TestAllTypesLite.newBuilder().setDeceptivelyNamedList(7).build()); } + @Test public void testToStringPrimitives() throws Exception { TestAllTypesLite proto = TestAllTypesLite.newBuilder() @@ -1427,6 +1463,7 @@ } + @Test public void testToStringStringFields() throws Exception { TestAllTypesLite proto = TestAllTypesLite.newBuilder().setOptionalString("foo\"bar\nbaz\\").build(); @@ -1436,6 +1473,7 @@ assertToStringEquals("optional_string: \"\\346\\226\\207\"", proto); } + @Test public void testToStringNestedMessage() throws Exception { TestAllTypesLite proto = TestAllTypesLite.newBuilder() @@ -1450,6 +1488,7 @@ assertToStringEquals("optional_nested_message {\n bb: 7\n}", proto); } + @Test public void testToStringRepeatedFields() throws Exception { TestAllTypesLite proto = TestAllTypesLite.newBuilder() @@ -1468,6 +1507,7 @@ "repeated_lazy_message {\n bb: 7\n}\nrepeated_lazy_message {\n bb: 8\n}", proto); } + @Test public void testToStringForeignFields() throws Exception { TestAllTypesLite proto = TestAllTypesLite.newBuilder() @@ -1481,6 +1521,7 @@ proto); } + @Test public void testToStringExtensions() throws Exception { TestAllExtensionsLite message = TestAllExtensionsLite.newBuilder() @@ -1496,6 +1537,7 @@ "[1]: 123\n[18] {\n bb: 7\n}\n[21]: 3\n[44]: \"spam\"\n[44]: \"eggs\"", message); } + @Test public void testToStringUnknownFields() throws Exception { TestAllExtensionsLite messageWithExtensions = TestAllExtensionsLite.newBuilder() @@ -1513,6 +1555,7 @@ "1: 123\n18: \"\\b\\a\"\n21: 3\n44: \"spam\"\n44: \"eggs\"", messageWithUnknownFields); } + @Test public void testToStringLazyMessage() throws Exception { TestAllTypesLite message = TestAllTypesLite.newBuilder() @@ -1521,6 +1564,7 @@ assertToStringEquals("optional_lazy_message {\n bb: 1\n}", message); } + @Test public void testToStringGroup() throws Exception { TestAllTypesLite message = TestAllTypesLite.newBuilder() @@ -1529,11 +1573,13 @@ assertToStringEquals("optional_group {\n a: 1\n}", message); } + @Test public void testToStringOneof() throws Exception { TestAllTypesLite message = TestAllTypesLite.newBuilder().setOneofString("hello").build(); assertToStringEquals("oneof_string: \"hello\"", message); } + @Test public void testToStringMapFields() throws Exception { TestMap message1 = TestMap.newBuilder() @@ -1577,15 +1623,16 @@ // comparison as it contains unstable addresses. private static void assertToStringEquals(String expected, MessageLite message) { String toString = message.toString(); - assertEquals('#', toString.charAt(0)); + assertThat(toString.charAt(0)).isEqualTo('#'); if (toString.contains("\n")) { toString = toString.substring(toString.indexOf("\n") + 1); } else { toString = ""; } - assertEquals(expected, toString); + assertThat(toString).isEqualTo(expected); } + @Test public void testParseLazy() throws Exception { ByteString bb = TestAllTypesLite.newBuilder() @@ -1601,10 +1648,11 @@ ByteString concat = bb.concat(cc); TestAllTypesLite message = TestAllTypesLite.parseFrom(concat); - assertEquals(11, message.getOptionalLazyMessage().getBb()); - assertEquals(22L, message.getOptionalLazyMessage().getCc()); + assertThat(message.getOptionalLazyMessage().getBb()).isEqualTo(11); + assertThat(message.getOptionalLazyMessage().getCc()).isEqualTo(22L); } + @Test public void testParseLazy_oneOf() throws Exception { ByteString bb = TestAllTypesLite.newBuilder() @@ -1620,26 +1668,29 @@ ByteString concat = bb.concat(cc); TestAllTypesLite message = TestAllTypesLite.parseFrom(concat); - assertEquals(11, message.getOneofLazyNestedMessage().getBb()); - assertEquals(22L, message.getOneofLazyNestedMessage().getCc()); + assertThat(message.getOneofLazyNestedMessage().getBb()).isEqualTo(11); + assertThat(message.getOneofLazyNestedMessage().getCc()).isEqualTo(22L); } + @Test public void testMergeFromStream_repeatedField() throws Exception { TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder().addRepeatedString("hello"); builder.mergeFrom(CodedInputStream.newInstance(builder.build().toByteArray())); - assertEquals(2, builder.getRepeatedStringCount()); + assertThat(builder.getRepeatedStringCount()).isEqualTo(2); } + @Test public void testMergeFromStream_invalidBytes() throws Exception { TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder().setDefaultBool(true); try { builder.mergeFrom(CodedInputStream.newInstance("Invalid bytes".getBytes(Internal.UTF_8))); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { } } + @Test public void testParseFromStream_IOExceptionNotLost() throws Exception { final IOException readException = new IOException(); try { @@ -1651,7 +1702,7 @@ throw readException; } })); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { boolean found = false; for (Throwable exception = expected; exception != null; exception = exception.getCause()) { @@ -1666,6 +1717,7 @@ } } + @Test public void testParseDelimitedFromStream_IOExceptionNotLost() throws Exception { final IOException readException = new IOException(); try { @@ -1676,7 +1728,7 @@ throw readException; } }); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { boolean found = false; for (Throwable exception = expected; exception != null; exception = exception.getCause()) { @@ -1691,6 +1743,7 @@ } } + @Test public void testParseFromArray_manyNestedMessagesError() throws Exception { RecursiveMessage.Builder recursiveMessage = RecursiveMessage.newBuilder().setPayload(ByteString.copyFrom(new byte[1])); @@ -1705,7 +1758,7 @@ 0; // Set invalid tag try { RecursiveMessage.parseFrom(result); - fail("Result was: " + Arrays.toString(result)); + assertWithMessage("Result was: " + Arrays.toString(result)).fail(); } catch (InvalidProtocolBufferException expected) { boolean found = false; int exceptionCount = 0; @@ -1733,6 +1786,7 @@ } } + @Test public void testParseFromStream_manyNestedMessagesError() throws Exception { RecursiveMessage.Builder recursiveMessage = RecursiveMessage.newBuilder().setPayload(ByteString.copyFrom(new byte[1])); @@ -1747,7 +1801,7 @@ 0; // Set invalid tag try { RecursiveMessage.parseFrom(CodedInputStream.newInstance(new ByteArrayInputStream(result))); - fail("Result was: " + Arrays.toString(result)); + assertWithMessage("Result was: " + Arrays.toString(result)).fail(); } catch (InvalidProtocolBufferException expected) { boolean found = false; int exceptionCount = 0; @@ -1774,6 +1828,7 @@ } } + @Test public void testParseFromStream_sneakyNestedException() throws Exception { final InvalidProtocolBufferException sketchy = new InvalidProtocolBufferException("Created in a sketchy way!") @@ -1787,13 +1842,14 @@ throw sketchy; } })); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { - assertNotSame(expected, sketchy); + assertThat(expected).isNotSameInstanceAs(sketchy); } - assertEquals(sketchy.getUnfinishedMessage(), TestAllTypesLite.getDefaultInstance()); + assertThat(sketchy.getUnfinishedMessage()).isEqualTo(TestAllTypesLite.getDefaultInstance()); } + @Test public void testMergeFrom_sanity() throws Exception { TestAllTypesLite one = TestUtilLite.getAllLiteSetBuilder().build(); byte[] bytes = one.toByteArray(); @@ -1801,388 +1857,391 @@ one = one.toBuilder().mergeFrom(one).build(); two = two.toBuilder().mergeFrom(bytes).build(); - assertEquals(one, two); - assertEquals(two, one); - assertEquals(one.hashCode(), two.hashCode()); + assertThat(one).isEqualTo(two); + assertThat(two).isEqualTo(one); + assertThat(one.hashCode()).isEqualTo(two.hashCode()); } + @Test public void testMergeFromNoLazyFieldSharing() throws Exception { TestAllTypesLite.Builder sourceBuilder = TestAllTypesLite.newBuilder().setOptionalLazyMessage(NestedMessage.newBuilder().setBb(1)); TestAllTypesLite.Builder targetBuilder = TestAllTypesLite.newBuilder().mergeFrom(sourceBuilder.build()); - assertEquals(1, sourceBuilder.getOptionalLazyMessage().getBb()); + assertThat(sourceBuilder.getOptionalLazyMessage().getBb()).isEqualTo(1); // now change the sourceBuilder, and target value shouldn't be affected. sourceBuilder.setOptionalLazyMessage(NestedMessage.newBuilder().setBb(2)); - assertEquals(1, targetBuilder.getOptionalLazyMessage().getBb()); + assertThat(targetBuilder.getOptionalLazyMessage().getBb()).isEqualTo(1); } + @Test public void testEquals_notEqual() throws Exception { TestAllTypesLite one = TestUtilLite.getAllLiteSetBuilder().build(); byte[] bytes = one.toByteArray(); TestAllTypesLite two = one.toBuilder().mergeFrom(one).mergeFrom(bytes).build(); - assertFalse(one.equals(two)); - assertFalse(two.equals(one)); + assertThat(one.equals(two)).isFalse(); + assertThat(two.equals(one)).isFalse(); - assertFalse(one.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(one)); + assertThat(one.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(one)).isFalse(); TestAllTypesLite oneFieldSet = TestAllTypesLite.newBuilder().setDefaultBool(true).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultCord("").build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultCordBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultDouble(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultFixed32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultFixed64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultFloat(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder() .setDefaultForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR) .build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultImportEnum(ImportEnumLite.IMPORT_LITE_BAR).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultInt32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultInt64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultNestedEnum(NestedEnum.BAR).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultSfixed32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultSfixed64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultSint32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultSint64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultString("").build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultStringBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultStringPiece("").build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultStringPieceBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultUint32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setDefaultUint64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedBool(true).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedCord("").build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedCordBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedDouble(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedFixed32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedFixed64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedFloat(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder() .addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR) .build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedImportEnum(ImportEnumLite.IMPORT_LITE_BAR).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedInt32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedInt64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedNestedEnum(NestedEnum.BAR).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedSfixed32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedSfixed64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedSint32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedSint64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedString("").build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedStringBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedStringPiece("").build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedStringPieceBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedUint32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().addRepeatedUint64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalBool(true).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalCord("").build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalCordBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalDouble(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalFixed32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalFixed64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalFloat(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder() .setOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR) .build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalImportEnum(ImportEnumLite.IMPORT_LITE_BAR).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalInt32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalInt64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalNestedEnum(NestedEnum.BAR).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalSfixed32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalSfixed64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalSint32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalSint64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalString("").build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalStringBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalStringPiece("").build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalStringPieceBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalUint32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalUint64(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOneofBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder() .setOneofLazyNestedMessage(NestedMessage.getDefaultInstance()) .build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder() .setOneofNestedMessage(NestedMessage.getDefaultInstance()) .build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOneofString("").build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOneofStringBytes(ByteString.EMPTY).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOneofUint32(0).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder() .setOptionalForeignMessage(ForeignMessageLite.getDefaultInstance()) .build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder().setOptionalGroup(OptionalGroup.getDefaultInstance()).build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder() .setOptionalPublicImportMessage(PublicImportMessageLite.getDefaultInstance()) .build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder() .setOptionalLazyMessage(NestedMessage.getDefaultInstance()) .build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); oneFieldSet = TestAllTypesLite.newBuilder() .addRepeatedLazyMessage(NestedMessage.getDefaultInstance()) .build(); - assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())); - assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)); + assertThat(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance())).isFalse(); + assertThat(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet)).isFalse(); } + @Test public void testEquals() throws Exception { // Check that two identical objs are equal. Foo foo1a = Foo.newBuilder().setValue(1).addBar(Bar.newBuilder().setName("foo1")).build(); @@ -2190,19 +2249,20 @@ Foo foo2 = Foo.newBuilder().setValue(1).addBar(Bar.newBuilder().setName("foo2")).build(); // Check that equals is doing value rather than object equality. - assertEquals(foo1a, foo1b); - assertEquals(foo1a.hashCode(), foo1b.hashCode()); + assertThat(foo1a).isEqualTo(foo1b); + assertThat(foo1a.hashCode()).isEqualTo(foo1b.hashCode()); // Check that a different object is not equal. - assertFalse(foo1a.equals(foo2)); + assertThat(foo1a.equals(foo2)).isFalse(); // Check that two objects which have different types but the same field values are not // considered to be equal. Bar bar = Bar.newBuilder().setName("bar").build(); BarPrime barPrime = BarPrime.newBuilder().setName("bar").build(); - assertFalse(bar.equals(barPrime)); + assertThat(bar).isNotEqualTo((Object) barPrime); // compiler already won't let this happen. } + @Test public void testEqualsAndHashCodeForTrickySchemaTypes() { Foo foo1 = Foo.getDefaultInstance(); Foo foo2 = Foo.newBuilder().setSint64(1).build(); @@ -2214,6 +2274,7 @@ assertEqualsAndHashCodeAreFalse(foo1, foo4); } + @Test public void testOneofEquals() throws Exception { TestOneofEquals.Builder builder = TestOneofEquals.newBuilder(); TestOneofEquals message1 = builder.build(); @@ -2221,20 +2282,21 @@ // check with the oneof case. builder.setName(""); TestOneofEquals message2 = builder.build(); - assertFalse(message1.equals(message2)); + assertThat(message1.equals(message2)).isFalse(); } + @Test public void testEquals_sanity() throws Exception { TestAllTypesLite one = TestUtilLite.getAllLiteSetBuilder().build(); TestAllTypesLite two = TestAllTypesLite.parseFrom(one.toByteArray()); - assertEquals(one, two); - assertEquals(one.hashCode(), two.hashCode()); + assertThat(one).isEqualTo(two); + assertThat(one.hashCode()).isEqualTo(two.hashCode()); - assertEquals( - one.toBuilder().mergeFrom(two).build(), - two.toBuilder().mergeFrom(two.toByteArray()).build()); + assertThat(one.toBuilder().mergeFrom(two).build()) + .isEqualTo(two.toBuilder().mergeFrom(two.toByteArray()).build()); } + @Test public void testEqualsAndHashCodeWithUnknownFields() throws InvalidProtocolBufferException { Foo fooWithOnlyValue = Foo.newBuilder().setValue(1).build(); @@ -2251,6 +2313,7 @@ assertEqualsAndHashCodeAreFalse(fooWithValueAndExtension, fooWithValueAndUnknownFields); } + @Test public void testEqualsAndHashCodeWithExtensions() throws InvalidProtocolBufferException { Foo fooWithOnlyValue = Foo.newBuilder().setValue(1).build(); @@ -2265,6 +2328,7 @@ } // Test to ensure we avoid a class cast exception with oneofs. + @Test public void testEquals_oneOfMessages() { TestAllTypesLite mine = TestAllTypesLite.newBuilder().setOneofString("Hello").build(); @@ -2273,10 +2337,11 @@ .setOneofNestedMessage(NestedMessage.getDefaultInstance()) .build(); - assertFalse(mine.equals(other)); - assertFalse(other.equals(mine)); + assertThat(mine.equals(other)).isFalse(); + assertThat(other.equals(mine)).isFalse(); } + @Test public void testHugeFieldNumbers() throws InvalidProtocolBufferException { TestHugeFieldNumbersLite message = TestHugeFieldNumbersLite.newBuilder() @@ -2289,23 +2354,25 @@ TestHugeFieldNumbersLite parsedMessage = TestHugeFieldNumbersLite.parseFrom(message.toByteArray()); - assertEquals(1, parsedMessage.getOptionalInt32()); - assertEquals(2, parsedMessage.getRepeatedInt32(0)); - assertEquals(ForeignEnumLite.FOREIGN_LITE_FOO, parsedMessage.getOptionalEnum()); - assertEquals("xyz", parsedMessage.getOptionalString()); - assertEquals(3, parsedMessage.getOptionalMessage().getC()); + assertThat(parsedMessage.getOptionalInt32()).isEqualTo(1); + assertThat(parsedMessage.getRepeatedInt32(0)).isEqualTo(2); + assertThat(parsedMessage.getOptionalEnum()).isEqualTo(ForeignEnumLite.FOREIGN_LITE_FOO); + assertThat(parsedMessage.getOptionalString()).isEqualTo("xyz"); + assertThat(parsedMessage.getOptionalMessage().getC()).isEqualTo(3); } private void assertEqualsAndHashCodeAreFalse(Object o1, Object o2) { - assertFalse(o1.equals(o2)); - assertFalse(o1.hashCode() == o2.hashCode()); + assertThat(o1.equals(o2)).isFalse(); + assertThat(o1.hashCode()).isNotEqualTo(o2.hashCode()); } + @Test public void testRecursiveHashcode() { // This tests that we don't infinite loop. - TestRecursiveOneof.getDefaultInstance().hashCode(); + int unused = TestRecursiveOneof.getDefaultInstance().hashCode(); } + @Test public void testParseFromByteBuffer() throws Exception { TestAllTypesLite message = TestAllTypesLite.newBuilder() @@ -2317,13 +2384,14 @@ TestAllTypesLite copy = TestAllTypesLite.parseFrom(message.toByteString().asReadOnlyByteBuffer()); - assertEquals(message, copy); + assertThat(message).isEqualTo(copy); } + @Test public void testParseFromByteBufferThrows() { try { TestAllTypesLite.parseFrom(ByteBuffer.wrap(new byte[] {0x5})); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { } @@ -2333,14 +2401,14 @@ ByteBuffer buffer = ByteBuffer.wrap(message.toByteArray(), 0, message.getSerializedSize() - 1); try { TestAllTypesLite.parseFrom(buffer); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { - assertEquals( - TestAllTypesLite.newBuilder().setOptionalInt32(123).build(), - expected.getUnfinishedMessage()); + assertThat(TestAllTypesLite.newBuilder().setOptionalInt32(123).build()) + .isEqualTo(expected.getUnfinishedMessage()); } } + @Test public void testParseFromByteBuffer_extensions() throws Exception { TestAllExtensionsLite message = TestAllExtensionsLite.newBuilder() @@ -2358,15 +2426,16 @@ TestAllExtensionsLite copy = TestAllExtensionsLite.parseFrom(message.toByteString().asReadOnlyByteBuffer(), registry); - assertEquals(message, copy); + assertThat(message).isEqualTo(copy); } + @Test public void testParseFromByteBufferThrows_extensions() { ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); UnittestLite.registerAllExtensions(registry); try { TestAllExtensionsLite.parseFrom(ByteBuffer.wrap(new byte[] {0x5}), registry); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { } @@ -2379,17 +2448,18 @@ ByteBuffer buffer = ByteBuffer.wrap(message.toByteArray(), 0, message.getSerializedSize() - 1); try { TestAllExtensionsLite.parseFrom(buffer, registry); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException expected) { - assertEquals( - TestAllExtensionsLite.newBuilder() - .setExtension(UnittestLite.optionalInt32ExtensionLite, 123) - .build(), - expected.getUnfinishedMessage()); + assertThat( + TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 123) + .build()) + .isEqualTo(expected.getUnfinishedMessage()); } } // Make sure we haven't screwed up the code generation for packing fields by default. + @Test public void testPackedSerialization() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); builder.addRepeatedInt32(4321); @@ -2400,11 +2470,12 @@ while (!in.isAtEnd()) { int tag = in.readTag(); - assertEquals(WireFormat.WIRETYPE_LENGTH_DELIMITED, WireFormat.getTagWireType(tag)); + assertThat(WireFormat.getTagWireType(tag)).isEqualTo(WireFormat.WIRETYPE_LENGTH_DELIMITED); in.skipField(tag); } } + @Test public void testAddAllIteratesOnce() { TestAllTypesLite unused = TestAllTypesLite.newBuilder() @@ -2428,133 +2499,134 @@ .build(); } + @Test public void testAddAllIteratesOnce_throwsOnNull() { TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder(); try { builder.addAllRepeatedBool(new OneTimeIterableList<>(true, false, null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 2 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedBoolCount()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 2 is null."); + assertThat(builder.getRepeatedBoolCount()).isEqualTo(0); } try { builder.addAllRepeatedBool(new OneTimeIterable<>(true, false, null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 2 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedBoolCount()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 2 is null."); + assertThat(builder.getRepeatedBoolCount()).isEqualTo(0); } try { builder = TestAllTypesLite.newBuilder(); builder.addAllRepeatedBool(new OneTimeIterableList<>((Boolean) null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 0 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedBoolCount()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 0 is null."); + assertThat(builder.getRepeatedBoolCount()).isEqualTo(0); } try { builder = TestAllTypesLite.newBuilder(); builder.addAllRepeatedInt32(new OneTimeIterableList<>((Integer) null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 0 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedInt32Count()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 0 is null."); + assertThat(builder.getRepeatedInt32Count()).isEqualTo(0); } try { builder = TestAllTypesLite.newBuilder(); builder.addAllRepeatedInt64(new OneTimeIterableList<>((Long) null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 0 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedInt64Count()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 0 is null."); + assertThat(builder.getRepeatedInt64Count()).isEqualTo(0); } try { builder = TestAllTypesLite.newBuilder(); builder.addAllRepeatedFloat(new OneTimeIterableList<>((Float) null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 0 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedFloatCount()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 0 is null."); + assertThat(builder.getRepeatedFloatCount()).isEqualTo(0); } try { builder = TestAllTypesLite.newBuilder(); builder.addAllRepeatedDouble(new OneTimeIterableList<>((Double) null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 0 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedDoubleCount()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 0 is null."); + assertThat(builder.getRepeatedDoubleCount()).isEqualTo(0); } try { builder = TestAllTypesLite.newBuilder(); builder.addAllRepeatedBytes(new OneTimeIterableList<>((ByteString) null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 0 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedBytesCount()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 0 is null."); + assertThat(builder.getRepeatedBytesCount()).isEqualTo(0); } try { builder = TestAllTypesLite.newBuilder(); builder.addAllRepeatedString(new OneTimeIterableList<>("", "", null, "")); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 2 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedStringCount()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 2 is null."); + assertThat(builder.getRepeatedStringCount()).isEqualTo(0); } try { builder = TestAllTypesLite.newBuilder(); builder.addAllRepeatedString(new OneTimeIterable<>("", "", null, "")); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 2 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedStringCount()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 2 is null."); + assertThat(builder.getRepeatedStringCount()).isEqualTo(0); } try { builder = TestAllTypesLite.newBuilder(); builder.addAllRepeatedString(new OneTimeIterableList<>((String) null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 0 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedStringCount()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 0 is null."); + assertThat(builder.getRepeatedStringCount()).isEqualTo(0); } try { builder = TestAllTypesLite.newBuilder(); builder.addAllRepeatedNestedMessage(new OneTimeIterableList<>((NestedMessage) null)); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { - assertEquals("Element at index 0 is null.", expected.getMessage()); - assertEquals(0, builder.getRepeatedNestedMessageCount()); + assertThat(expected).hasMessageThat().isEqualTo("Element at index 0 is null."); + assertThat(builder.getRepeatedNestedMessageCount()).isEqualTo(0); } } + @Test public void testExtensionRenamesKeywords() { - assertTrue(NonNestedExtensionLite.package_ instanceof GeneratedMessageLite.GeneratedExtension); - assertTrue( - NestedExtensionLite.MyNestedExtensionLite.private_ - instanceof GeneratedMessageLite.GeneratedExtension); + assertThat(NonNestedExtensionLite.package_) + .isInstanceOf(GeneratedMessageLite.GeneratedExtension.class); + assertThat(NestedExtensionLite.MyNestedExtensionLite.private_) + .isInstanceOf(GeneratedMessageLite.GeneratedExtension.class); NonNestedExtensionLite.MessageLiteToBeExtended msg = NonNestedExtensionLite.MessageLiteToBeExtended.newBuilder() .setExtension(NonNestedExtensionLite.package_, true) .build(); - assertTrue(msg.getExtension(NonNestedExtensionLite.package_)); + assertThat(msg.getExtension(NonNestedExtensionLite.package_)).isTrue(); msg = NonNestedExtensionLite.MessageLiteToBeExtended.newBuilder() .setExtension(NestedExtensionLite.MyNestedExtensionLite.private_, 2.4) .build(); - assertEquals( - 2.4, msg.getExtension(NestedExtensionLite.MyNestedExtensionLite.private_), 0.001); + assertThat(msg.getExtension(NestedExtensionLite.MyNestedExtensionLite.private_)).isEqualTo(2.4); } private static final class OneTimeIterableList<T> extends ArrayList<T> { @@ -2567,7 +2639,7 @@ @Override public Iterator<T> iterator() { if (wasIterated) { - fail(); + assertWithMessage("expected exception").fail(); } wasIterated = true; return super.iterator(); @@ -2585,21 +2657,23 @@ @Override public Iterator<T> iterator() { if (wasIterated) { - fail(); + assertWithMessage("expected exception").fail(); } wasIterated = true; return list.iterator(); } } + @Test public void testNullExtensionRegistry() throws Exception { try { TestAllTypesLite.parseFrom(new byte[] {}, null); - fail(); + assertWithMessage("expected exception").fail(); } catch (NullPointerException expected) { } } + @Test public void testSerializeToOutputStreamThrowsIOException() { try { TestAllTypesLite.newBuilder() @@ -2613,11 +2687,12 @@ throw new IOException(); } }); - fail(); + assertWithMessage("expected exception").fail(); } catch (IOException expected) { } } + @Test public void testUnpairedSurrogatesReplacedByQuestionMark() throws InvalidProtocolBufferException { String testString = "foo \ud83d bar"; String expectedString = "foo ? bar"; @@ -2629,15 +2704,16 @@ // Behavior is compatible with String.getBytes("UTF-8"), which replaces // unpaired surrogates with a question mark. TestAllTypesLite parsedMessage = TestAllTypesLite.parseFrom(serializedMessage); - assertEquals(expectedString, parsedMessage.getOptionalString()); + assertThat(parsedMessage.getOptionalString()).isEqualTo(expectedString); // Conversion happens during serialization. ByteString expectedBytes = ByteString.copyFromUtf8(expectedString); - assertTrue( - String.format( - "Expected serializedMessage (%s) to contain \"%s\" (%s).", - encodeHex(serializedMessage), expectedString, encodeHex(expectedBytes)), - contains(serializedMessage, expectedBytes)); + assertWithMessage( + String.format( + "Expected serializedMessage (%s) to contain \"%s\" (%s).", + encodeHex(serializedMessage), expectedString, encodeHex(expectedBytes))) + .that(contains(serializedMessage, expectedBytes)) + .isTrue(); } private String encodeHex(ByteString bytes) {
diff --git a/java/util/src/main/java/com/google/protobuf/util/Durations.java b/java/util/src/main/java/com/google/protobuf/util/Durations.java index fd13771..f81da1f 100644 --- a/java/util/src/main/java/com/google/protobuf/util/Durations.java +++ b/java/util/src/main/java/com/google/protobuf/util/Durations.java
@@ -43,6 +43,7 @@ import static com.google.protobuf.util.Timestamps.NANOS_PER_SECOND; import com.google.errorprone.annotations.CanIgnoreReturnValue; +import com.google.errorprone.annotations.CompileTimeConstant; import com.google.protobuf.Duration; import java.io.Serializable; import java.text.ParseException; @@ -275,6 +276,25 @@ } } + /** + * Parses a string in RFC 3339 format into a {@link Duration}. + * + * <p>Identical to {@link #parse(String)}, but throws an {@link IllegalArgumentException} instead + * of a {@link ParseException} if parsing fails. + * + * @return a {@link Duration} parsed from the string + * @throws IllegalArgumentException if parsing fails + */ + public static Duration parseUnchecked(@CompileTimeConstant String value) { + try { + return parse(value); + } catch (ParseException e) { + // While `java.time.format.DateTimeParseException` is a more accurate representation of the + // failure, this library is currently not JDK8 ready because of Android dependencies. + throw new IllegalArgumentException(e); + } + } + // Static factories /** Create a Duration from the number of days. */
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 c32d10a..2de2bd1 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
@@ -398,4 +398,21 @@ public static void merge(FieldMask mask, Message source, Message.Builder destination) { merge(mask, source, destination, new MergeOptions()); } + + /** + * Returns the result of merging the given proto with the given mask and a default instance. + */ + public static <P extends Message> P trim(FieldMask mask, P source) { + return trim(mask, source, new MergeOptions()); + } + + /** + * Returns the result of merging the given proto with the given mask and a default instance. + */ + @SuppressWarnings("unchecked") + public static <P extends Message> P trim(FieldMask mask, P source, MergeOptions options) { + Message.Builder destination = source.newBuilderForType(); + merge(mask, source, destination, options); + return (P) destination.build(); + } }
diff --git a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java index fe9b9a5..8461f67 100644 --- a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java +++ b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
@@ -37,6 +37,7 @@ import static com.google.common.math.LongMath.checkedSubtract; import com.google.errorprone.annotations.CanIgnoreReturnValue; +import com.google.errorprone.annotations.CompileTimeConstant; import com.google.protobuf.Duration; import com.google.protobuf.Timestamp; import java.io.Serializable; @@ -283,6 +284,25 @@ } } + /** + * Parses a string in RFC 3339 format into a {@link Timestamp}. + * + * <p>Identical to {@link #parse(String)}, but throws an {@link IllegalArgumentException} instead + * of a {@link ParseException} if parsing fails. + * + * @return a {@link Timestamp} parsed from the string + * @throws IllegalArgumentException if parsing fails + */ + public static Timestamp parseUnchecked(@CompileTimeConstant String value) { + try { + return parse(value); + } catch (ParseException e) { + // While `java.time.format.DateTimeParseException` is a more accurate representation of the + // failure, this library is currently not JDK8 ready because of Android dependencies. + throw new IllegalArgumentException(e); + } + } + /** Create a Timestamp from the number of seconds elapsed from the epoch. */ @SuppressWarnings("GoodTime") // this is a legacy conversion API public static Timestamp fromSeconds(long seconds) {
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 c829722..98aef02 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
@@ -40,9 +40,13 @@ import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage; import protobuf_unittest.UnittestProto.TestRequired; import protobuf_unittest.UnittestProto.TestRequiredMessage; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -public class FieldMaskTreeTest extends TestCase { +@RunWith(JUnit4.class) +public class FieldMaskTreeTest { + @Test public void testAddFieldPath() throws Exception { FieldMaskTree tree = new FieldMaskTree(); assertThat(tree.toString()).isEmpty(); @@ -50,31 +54,33 @@ assertThat(tree.toString()).isEmpty(); // New branch. tree.addFieldPath("foo"); - assertEquals("foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("foo"); // Redundant path. tree.addFieldPath("foo"); - assertEquals("foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("foo"); // New branch. tree.addFieldPath("bar.baz"); - assertEquals("bar.baz,foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("bar.baz,foo"); // Redundant sub-path. tree.addFieldPath("foo.bar"); - assertEquals("bar.baz,foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("bar.baz,foo"); // New branch from a non-root node. tree.addFieldPath("bar.quz"); - assertEquals("bar.baz,bar.quz,foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("bar.baz,bar.quz,foo"); // A path that matches several existing sub-paths. tree.addFieldPath("bar"); - assertEquals("bar,foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("bar,foo"); } + @Test public void testMergeFromFieldMask() throws Exception { FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString("foo,bar.baz,bar.quz")); - assertEquals("bar.baz,bar.quz,foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("bar.baz,bar.quz,foo"); tree.mergeFromFieldMask(FieldMaskUtil.fromString("foo.bar,bar")); - assertEquals("bar,foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("bar,foo"); } + @Test public void testRemoveFieldPath() throws Exception { String initialTreeString = "bar.baz,bar.quz.bar,foo"; FieldMaskTree tree; @@ -82,41 +88,43 @@ // Empty path. tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath(""); - assertEquals(initialTreeString, tree.toString()); + assertThat(tree.toString()).isEqualTo(initialTreeString); // Non-exist sub-path of an existing leaf. tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("foo.bar"); - assertEquals(initialTreeString, tree.toString()); + assertThat(tree.toString()).isEqualTo(initialTreeString); // Non-exist path. tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("bar.foo"); - assertEquals(initialTreeString, tree.toString()); + assertThat(tree.toString()).isEqualTo(initialTreeString); // 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()); + assertThat(tree.toString()).isEqualTo("bar.baz,bar.quz.bar"); // Match sub-path of an existing leaf node -> recursive removal. tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("bar.quz.bar"); - assertEquals("bar.baz,foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("bar.baz,foo"); // Match a non-leaf node -> remove all children. tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("bar"); - assertEquals("foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("foo"); } + @Test public void testRemoveFromFieldMask() throws Exception { FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString("foo,bar.baz,bar.quz")); - assertEquals("bar.baz,bar.quz,foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("bar.baz,bar.quz,foo"); tree.removeFromFieldMask(FieldMaskUtil.fromString("foo.bar,bar")); - assertEquals("foo", tree.toString()); + assertThat(tree.toString()).isEqualTo("foo"); } + @Test public void testIntersectFieldPath() throws Exception { FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString("foo,bar.baz,bar.quz")); FieldMaskTree result = new FieldMaskTree(); @@ -128,18 +136,19 @@ assertThat(result.toString()).isEmpty(); // Sub-path of an existing leaf. tree.intersectFieldPath("foo.bar", result); - assertEquals("foo.bar", result.toString()); + assertThat(result.toString()).isEqualTo("foo.bar"); // Match an existing leaf node. tree.intersectFieldPath("foo", result); - assertEquals("foo", result.toString()); + assertThat(result.toString()).isEqualTo("foo"); // Non-exist path. tree.intersectFieldPath("bar.foo", result); - assertEquals("foo", result.toString()); + assertThat(result.toString()).isEqualTo("foo"); // Match a non-leaf node. tree.intersectFieldPath("bar", result); - assertEquals("bar.baz,bar.quz,foo", result.toString()); + assertThat(result.toString()).isEqualTo("bar.baz,bar.quz,foo"); } + @Test public void testMerge() throws Exception { testMergeImpl(true); testMergeImpl(false); @@ -183,10 +192,10 @@ builder, options, useDynamicMessage); - assertTrue(builder.hasRequiredMessage()); - assertTrue(builder.getRequiredMessage().hasA()); - assertFalse(builder.getRequiredMessage().hasB()); - assertFalse(builder.getRequiredMessage().hasC()); + assertThat(builder.hasRequiredMessage()).isTrue(); + assertThat(builder.getRequiredMessage().hasA()).isTrue(); + assertThat(builder.getRequiredMessage().hasB()).isFalse(); + assertThat(builder.getRequiredMessage().hasC()).isFalse(); merge( new FieldMaskTree().addFieldPath("required_message.b").addFieldPath("required_message.c"), source, @@ -194,7 +203,7 @@ options, useDynamicMessage); try { - assertEquals(builder.build(), source); + assertThat(source).isEqualTo(builder.build()); } catch (UninitializedMessageException e) { throw new AssertionError("required field isn't set", e); } @@ -232,7 +241,7 @@ merge(new FieldMaskTree(), source, builder, options, useDynamicMessage); NestedTestAllTypes.Builder expected = NestedTestAllTypes.newBuilder(); expected.getPayloadBuilder().addRepeatedInt32(1000); - assertEquals(expected.build(), builder.build()); + assertThat(builder.build()).isEqualTo(expected.build()); // Test merging each individual field. builder = NestedTestAllTypes.newBuilder(); @@ -240,28 +249,28 @@ source, builder, options, useDynamicMessage); expected = NestedTestAllTypes.newBuilder(); expected.getPayloadBuilder().setOptionalInt32(1234); - assertEquals(expected.build(), builder.build()); + assertThat(builder.build()).isEqualTo(expected.build()); builder = NestedTestAllTypes.newBuilder(); merge(new FieldMaskTree().addFieldPath("payload.optional_nested_message"), source, builder, options, useDynamicMessage); expected = NestedTestAllTypes.newBuilder(); expected.getPayloadBuilder().setOptionalNestedMessage(NestedMessage.newBuilder().setBb(5678)); - assertEquals(expected.build(), builder.build()); + assertThat(builder.build()).isEqualTo(expected.build()); builder = NestedTestAllTypes.newBuilder(); merge(new FieldMaskTree().addFieldPath("payload.repeated_int32"), source, builder, options, useDynamicMessage); expected = NestedTestAllTypes.newBuilder(); expected.getPayloadBuilder().addRepeatedInt32(4321); - assertEquals(expected.build(), builder.build()); + assertThat(builder.build()).isEqualTo(expected.build()); builder = NestedTestAllTypes.newBuilder(); merge(new FieldMaskTree().addFieldPath("payload.repeated_nested_message"), source, builder, options, useDynamicMessage); expected = NestedTestAllTypes.newBuilder(); expected.getPayloadBuilder().addRepeatedNestedMessage(NestedMessage.newBuilder().setBb(8765)); - assertEquals(expected.build(), builder.build()); + assertThat(builder.build()).isEqualTo(expected.build()); builder = NestedTestAllTypes.newBuilder(); merge( @@ -272,7 +281,7 @@ useDynamicMessage); expected = NestedTestAllTypes.newBuilder(); expected.getChildBuilder().getPayloadBuilder().setOptionalInt32(1234); - assertEquals(expected.build(), builder.build()); + assertThat(builder.build()).isEqualTo(expected.build()); builder = NestedTestAllTypes.newBuilder(); merge( @@ -286,14 +295,14 @@ .getChildBuilder() .getPayloadBuilder() .setOptionalNestedMessage(NestedMessage.newBuilder().setBb(5678)); - assertEquals(expected.build(), builder.build()); + assertThat(builder.build()).isEqualTo(expected.build()); builder = NestedTestAllTypes.newBuilder(); merge(new FieldMaskTree().addFieldPath("child.payload.repeated_int32"), source, builder, options, useDynamicMessage); expected = NestedTestAllTypes.newBuilder(); expected.getChildBuilder().getPayloadBuilder().addRepeatedInt32(4321); - assertEquals(expected.build(), builder.build()); + assertThat(builder.build()).isEqualTo(expected.build()); builder = NestedTestAllTypes.newBuilder(); merge(new FieldMaskTree().addFieldPath("child.payload.repeated_nested_message"), @@ -303,13 +312,13 @@ .getChildBuilder() .getPayloadBuilder() .addRepeatedNestedMessage(NestedMessage.newBuilder().setBb(8765)); - assertEquals(expected.build(), builder.build()); + assertThat(builder.build()).isEqualTo(expected.build()); // Test merging all fields. builder = NestedTestAllTypes.newBuilder(); merge(new FieldMaskTree().addFieldPath("child").addFieldPath("payload"), source, builder, options, useDynamicMessage); - assertEquals(source, builder.build()); + assertThat(builder.build()).isEqualTo(source); // Test repeated options. builder = NestedTestAllTypes.newBuilder(); @@ -317,15 +326,15 @@ merge(new FieldMaskTree().addFieldPath("payload.repeated_int32"), source, builder, options, useDynamicMessage); // Default behavior is to append repeated fields. - assertEquals(2, builder.getPayload().getRepeatedInt32Count()); - assertEquals(1000, builder.getPayload().getRepeatedInt32(0)); - assertEquals(4321, builder.getPayload().getRepeatedInt32(1)); + assertThat(builder.getPayload().getRepeatedInt32Count()).isEqualTo(2); + assertThat(builder.getPayload().getRepeatedInt32(0)).isEqualTo(1000); + assertThat(builder.getPayload().getRepeatedInt32(1)).isEqualTo(4321); // Change to replace repeated fields. options.setReplaceRepeatedFields(true); merge(new FieldMaskTree().addFieldPath("payload.repeated_int32"), source, builder, options, useDynamicMessage); - assertEquals(1, builder.getPayload().getRepeatedInt32Count()); - assertEquals(4321, builder.getPayload().getRepeatedInt32(0)); + assertThat(builder.getPayload().getRepeatedInt32Count()).isEqualTo(1); + assertThat(builder.getPayload().getRepeatedInt32(0)).isEqualTo(4321); // Test message options. builder = NestedTestAllTypes.newBuilder(); @@ -334,21 +343,21 @@ merge(new FieldMaskTree().addFieldPath("payload"), source, builder, options, useDynamicMessage); // Default behavior is to merge message fields. - assertEquals(1234, builder.getPayload().getOptionalInt32()); - assertEquals(2000, builder.getPayload().getOptionalUint32()); + assertThat(builder.getPayload().getOptionalInt32()).isEqualTo(1234); + assertThat(builder.getPayload().getOptionalUint32()).isEqualTo(2000); // Test merging unset message fields. NestedTestAllTypes clearedSource = source.toBuilder().clearPayload().build(); builder = NestedTestAllTypes.newBuilder(); merge(new FieldMaskTree().addFieldPath("payload"), clearedSource, builder, options, useDynamicMessage); - assertEquals(false, builder.hasPayload()); + assertThat(builder.hasPayload()).isFalse(); // Skip a message field if they are unset in both source and target. builder = NestedTestAllTypes.newBuilder(); merge(new FieldMaskTree().addFieldPath("payload.optional_int32"), clearedSource, builder, options, useDynamicMessage); - assertEquals(false, builder.hasPayload()); + assertThat(builder.hasPayload()).isFalse(); // Change to replace message fields. options.setReplaceMessageFields(true); @@ -357,8 +366,8 @@ builder.getPayloadBuilder().setOptionalUint32(2000); merge(new FieldMaskTree().addFieldPath("payload"), source, builder, options, useDynamicMessage); - assertEquals(1234, builder.getPayload().getOptionalInt32()); - assertEquals(0, builder.getPayload().getOptionalUint32()); + assertThat(builder.getPayload().getOptionalInt32()).isEqualTo(1234); + assertThat(builder.getPayload().getOptionalUint32()).isEqualTo(0); // Test merging unset message fields. builder = NestedTestAllTypes.newBuilder(); @@ -366,7 +375,7 @@ builder.getPayloadBuilder().setOptionalUint32(2000); merge(new FieldMaskTree().addFieldPath("payload"), clearedSource, builder, options, useDynamicMessage); - assertEquals(false, builder.hasPayload()); + assertThat(builder.hasPayload()).isFalse(); // Test merging unset primitive fields. builder = source.toBuilder(); @@ -375,15 +384,15 @@ builder = source.toBuilder(); merge(new FieldMaskTree().addFieldPath("payload.optional_int32"), sourceWithPayloadInt32Unset, builder, options, useDynamicMessage); - assertEquals(true, builder.getPayload().hasOptionalInt32()); - assertEquals(0, builder.getPayload().getOptionalInt32()); + assertThat(builder.getPayload().hasOptionalInt32()).isTrue(); + assertThat(builder.getPayload().getOptionalInt32()).isEqualTo(0); // Change to clear unset primitive fields. options.setReplacePrimitiveFields(true); builder = source.toBuilder(); merge(new FieldMaskTree().addFieldPath("payload.optional_int32"), sourceWithPayloadInt32Unset, builder, options, useDynamicMessage); - assertEquals(true, builder.hasPayload()); - assertEquals(false, builder.getPayload().hasOptionalInt32()); + assertThat(builder.hasPayload()).isTrue(); + assertThat(builder.getPayload().hasOptionalInt32()).isFalse(); } }
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 28e43a7..367fe52 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
@@ -31,57 +31,72 @@ package com.google.protobuf.util; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import com.google.common.collect.ImmutableList; import com.google.protobuf.FieldMask; import protobuf_unittest.UnittestProto.NestedTestAllTypes; import protobuf_unittest.UnittestProto.TestAllTypes; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; /** Unit tests for {@link FieldMaskUtil}. */ -public class FieldMaskUtilTest extends TestCase { +@RunWith(JUnit4.class) +public class FieldMaskUtilTest { + @Test public void testIsValid() throws Exception { - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload")); - assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "nonexist")); - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_int32")); - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_int32")); - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_nested_message")); - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_nested_message")); - assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.nonexist")); + assertThat(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload")).isTrue(); + assertThat(FieldMaskUtil.isValid(NestedTestAllTypes.class, "nonexist")).isFalse(); + assertThat(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_int32")).isTrue(); + assertThat(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_int32")).isTrue(); + assertThat(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_nested_message")) + .isTrue(); + assertThat(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_nested_message")) + .isTrue(); + assertThat(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.nonexist")).isFalse(); - assertTrue( - FieldMaskUtil.isValid(NestedTestAllTypes.class, FieldMaskUtil.fromString("payload"))); - assertFalse( - FieldMaskUtil.isValid(NestedTestAllTypes.class, FieldMaskUtil.fromString("nonexist"))); - assertFalse( - FieldMaskUtil.isValid( - NestedTestAllTypes.class, FieldMaskUtil.fromString("payload,nonexist"))); + assertThat(FieldMaskUtil.isValid(NestedTestAllTypes.class, FieldMaskUtil.fromString("payload"))) + .isTrue(); + assertThat( + FieldMaskUtil.isValid(NestedTestAllTypes.class, FieldMaskUtil.fromString("nonexist"))) + .isFalse(); + assertThat( + FieldMaskUtil.isValid( + NestedTestAllTypes.class, FieldMaskUtil.fromString("payload,nonexist"))) + .isFalse(); - assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "payload")); - assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "nonexist")); + assertThat(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "payload")).isTrue(); + assertThat(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "nonexist")).isFalse(); - assertTrue( - FieldMaskUtil.isValid( - NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("payload"))); - assertFalse( - FieldMaskUtil.isValid( - NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("nonexist"))); + assertThat( + FieldMaskUtil.isValid( + NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("payload"))) + .isTrue(); + assertThat( + FieldMaskUtil.isValid( + NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("nonexist"))) + .isFalse(); - assertTrue( - FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_nested_message.bb")); + assertThat( + FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_nested_message.bb")) + .isTrue(); // Repeated fields cannot have sub-paths. - assertFalse( - FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_nested_message.bb")); + assertThat( + FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_nested_message.bb")) + .isFalse(); // Non-message fields cannot have sub-paths. - assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_int32.bb")); + assertThat(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_int32.bb")) + .isFalse(); } + @Test public void testToString() throws Exception { - assertEquals("", FieldMaskUtil.toString(FieldMask.getDefaultInstance())); + assertThat(FieldMaskUtil.toString(FieldMask.getDefaultInstance())).isEmpty(); FieldMask mask = FieldMask.newBuilder().addPaths("foo").build(); - assertEquals("foo", FieldMaskUtil.toString(mask)); + assertThat(FieldMaskUtil.toString(mask)).isEqualTo("foo"); mask = FieldMask.newBuilder().addPaths("foo").addPaths("bar").build(); - assertEquals("foo,bar", FieldMaskUtil.toString(mask)); + assertThat(FieldMaskUtil.toString(mask)).isEqualTo("foo,bar"); // Empty field paths are ignored. mask = @@ -92,88 +107,93 @@ .addPaths("bar") .addPaths("") .build(); - assertEquals("foo,bar", FieldMaskUtil.toString(mask)); + assertThat(FieldMaskUtil.toString(mask)).isEqualTo("foo,bar"); } + @Test public void testFromString() throws Exception { FieldMask mask = FieldMaskUtil.fromString(""); - assertEquals(0, mask.getPathsCount()); + assertThat(mask.getPathsCount()).isEqualTo(0); mask = FieldMaskUtil.fromString("foo"); - assertEquals(1, mask.getPathsCount()); - assertEquals("foo", mask.getPaths(0)); + assertThat(mask.getPathsCount()).isEqualTo(1); + assertThat(mask.getPaths(0)).isEqualTo("foo"); mask = FieldMaskUtil.fromString("foo,bar.baz"); - assertEquals(2, mask.getPathsCount()); - assertEquals("foo", mask.getPaths(0)); - assertEquals("bar.baz", mask.getPaths(1)); + assertThat(mask.getPathsCount()).isEqualTo(2); + assertThat(mask.getPaths(0)).isEqualTo("foo"); + assertThat(mask.getPaths(1)).isEqualTo("bar.baz"); // Empty field paths are ignore. mask = FieldMaskUtil.fromString(",foo,,bar,"); - assertEquals(2, mask.getPathsCount()); - assertEquals("foo", mask.getPaths(0)); - assertEquals("bar", mask.getPaths(1)); + assertThat(mask.getPathsCount()).isEqualTo(2); + assertThat(mask.getPaths(0)).isEqualTo("foo"); + assertThat(mask.getPaths(1)).isEqualTo("bar"); // Check whether the field paths are valid if a class parameter is provided. mask = FieldMaskUtil.fromString(NestedTestAllTypes.class, ",payload"); try { mask = FieldMaskUtil.fromString(NestedTestAllTypes.class, "payload,nonexist"); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IllegalArgumentException e) { // Expected. } } + @Test public void testFromFieldNumbers() throws Exception { FieldMask mask = FieldMaskUtil.fromFieldNumbers(TestAllTypes.class); - assertEquals(0, mask.getPathsCount()); + assertThat(mask.getPathsCount()).isEqualTo(0); mask = FieldMaskUtil.fromFieldNumbers( TestAllTypes.class, TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER); - assertEquals(1, mask.getPathsCount()); - assertEquals("optional_int32", mask.getPaths(0)); + assertThat(mask.getPathsCount()).isEqualTo(1); + assertThat(mask.getPaths(0)).isEqualTo("optional_int32"); mask = FieldMaskUtil.fromFieldNumbers( TestAllTypes.class, TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, TestAllTypes.OPTIONAL_INT64_FIELD_NUMBER); - assertEquals(2, mask.getPathsCount()); - assertEquals("optional_int32", mask.getPaths(0)); - assertEquals("optional_int64", mask.getPaths(1)); + assertThat(mask.getPathsCount()).isEqualTo(2); + assertThat(mask.getPaths(0)).isEqualTo("optional_int32"); + assertThat(mask.getPaths(1)).isEqualTo("optional_int64"); try { int invalidFieldNumber = 1000; mask = FieldMaskUtil.fromFieldNumbers(TestAllTypes.class, invalidFieldNumber); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IllegalArgumentException expected) { } } + @Test public void testToJsonString() throws Exception { FieldMask mask = FieldMask.getDefaultInstance(); - assertEquals("", FieldMaskUtil.toJsonString(mask)); + assertThat(FieldMaskUtil.toJsonString(mask)).isEmpty(); mask = FieldMask.newBuilder().addPaths("foo").build(); - assertEquals("foo", FieldMaskUtil.toJsonString(mask)); + assertThat(FieldMaskUtil.toJsonString(mask)).isEqualTo("foo"); mask = FieldMask.newBuilder().addPaths("foo.bar_baz").addPaths("").build(); - assertEquals("foo.barBaz", FieldMaskUtil.toJsonString(mask)); + assertThat(FieldMaskUtil.toJsonString(mask)).isEqualTo("foo.barBaz"); mask = FieldMask.newBuilder().addPaths("foo").addPaths("bar_baz").build(); - assertEquals("foo,barBaz", FieldMaskUtil.toJsonString(mask)); + assertThat(FieldMaskUtil.toJsonString(mask)).isEqualTo("foo,barBaz"); } + @Test public void testFromJsonString() throws Exception { FieldMask mask = FieldMaskUtil.fromJsonString(""); - assertEquals(0, mask.getPathsCount()); + assertThat(mask.getPathsCount()).isEqualTo(0); mask = FieldMaskUtil.fromJsonString("foo"); - assertEquals(1, mask.getPathsCount()); - assertEquals("foo", mask.getPaths(0)); + assertThat(mask.getPathsCount()).isEqualTo(1); + assertThat(mask.getPaths(0)).isEqualTo("foo"); mask = FieldMaskUtil.fromJsonString("foo.barBaz"); - assertEquals(1, mask.getPathsCount()); - assertEquals("foo.bar_baz", mask.getPaths(0)); + assertThat(mask.getPathsCount()).isEqualTo(1); + assertThat(mask.getPaths(0)).isEqualTo("foo.bar_baz"); mask = FieldMaskUtil.fromJsonString("foo,barBaz"); - assertEquals(2, mask.getPathsCount()); - assertEquals("foo", mask.getPaths(0)); - assertEquals("bar_baz", mask.getPaths(1)); + assertThat(mask.getPathsCount()).isEqualTo(2); + assertThat(mask.getPaths(0)).isEqualTo("foo"); + assertThat(mask.getPaths(1)).isEqualTo("bar_baz"); } + @Test public void testFromStringList() throws Exception { FieldMask mask = FieldMaskUtil.fromStringList( @@ -206,33 +226,37 @@ .build()); } + @Test public void testUnion() throws Exception { // Only test a simple case here and expect // {@link FieldMaskTreeTest#testAddFieldPath} to cover all scenarios. FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz"); FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar"); FieldMask result = FieldMaskUtil.union(mask1, mask2); - assertEquals("bar,foo", FieldMaskUtil.toString(result)); + assertThat(FieldMaskUtil.toString(result)).isEqualTo("bar,foo"); } + @Test public void testUnion_usingVarArgs() throws Exception { FieldMask mask1 = FieldMaskUtil.fromString("foo"); FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar.quz"); FieldMask mask3 = FieldMaskUtil.fromString("bar.quz"); FieldMask mask4 = FieldMaskUtil.fromString("bar"); FieldMask result = FieldMaskUtil.union(mask1, mask2, mask3, mask4); - assertEquals("bar,foo", FieldMaskUtil.toString(result)); + assertThat(FieldMaskUtil.toString(result)).isEqualTo("bar,foo"); } + @Test public void testSubstract() throws Exception { // Only test a simple case here and expect // {@link FieldMaskTreeTest#testRemoveFieldPath} to cover all scenarios. FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz"); FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar"); FieldMask result = FieldMaskUtil.subtract(mask1, mask2); - assertEquals("foo", FieldMaskUtil.toString(result)); + assertThat(FieldMaskUtil.toString(result)).isEqualTo("foo"); } + @Test public void testSubstract_usingVarArgs() throws Exception { FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz.bar"); FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar.baz.quz"); @@ -242,15 +266,17 @@ assertThat(FieldMaskUtil.toString(result)).isEmpty(); } + @Test public void testIntersection() throws Exception { // Only test a simple case here and expect // {@link FieldMaskTreeTest#testIntersectFieldPath} to cover all scenarios. FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz"); FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar"); FieldMask result = FieldMaskUtil.intersection(mask1, mask2); - assertEquals("bar.baz,bar.quz,foo.bar", FieldMaskUtil.toString(result)); + assertThat(FieldMaskUtil.toString(result)).isEqualTo("bar.baz,bar.quz,foo.bar"); } + @Test public void testMerge() throws Exception { // Only test a simple case here and expect // {@link FieldMaskTreeTest#testMerge} to cover all scenarios. @@ -260,6 +286,6 @@ .build(); NestedTestAllTypes.Builder builder = NestedTestAllTypes.newBuilder(); FieldMaskUtil.merge(FieldMaskUtil.fromString("payload"), source, builder); - assertEquals(1234, builder.getPayload().getOptionalInt32()); + assertThat(builder.getPayload().getOptionalInt32()).isEqualTo(1234); } }
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 6133bb4..fc61a28 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
@@ -30,6 +30,9 @@ package com.google.protobuf.util; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + import com.google.common.collect.ImmutableSet; import com.google.protobuf.Any; import com.google.protobuf.BoolValue; @@ -76,9 +79,12 @@ import java.util.HashSet; import java.util.Locale; import java.util.Set; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -public class JsonFormatTest extends TestCase { +@RunWith(JUnit4.class) +public class JsonFormatTest { public JsonFormatTest() { // Test that locale does not affect JsonFormat. Locale.setDefault(Locale.forLanguageTag("hi-IN")); @@ -150,7 +156,7 @@ Message.Builder builder = message.newBuilderForType(); parser.merge(printer.print(message), builder); Message parsedMessage = builder.build(); - assertEquals(message.toString(), parsedMessage.toString()); + assertThat(parsedMessage.toString()).isEqualTo(message.toString()); } private void assertRoundTripEquals(Message message, com.google.protobuf.TypeRegistry registry) @@ -160,7 +166,7 @@ Message.Builder builder = message.newBuilderForType(); parser.merge(printer.print(message), builder); Message parsedMessage = builder.build(); - assertEquals(message.toString(), parsedMessage.toString()); + assertThat(parsedMessage.toString()).isEqualTo(message.toString()); } private String toJsonString(Message message) throws IOException { @@ -182,59 +188,61 @@ JsonFormat.parser().ignoringUnknownFields().merge(json, builder); } + @Test public void testAllFields() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); setAllFields(builder); TestAllTypes message = builder.build(); - assertEquals( - "{\n" - + " \"optionalInt32\": 1234,\n" - + " \"optionalInt64\": \"1234567890123456789\",\n" - + " \"optionalUint32\": 5678,\n" - + " \"optionalUint64\": \"2345678901234567890\",\n" - + " \"optionalSint32\": 9012,\n" - + " \"optionalSint64\": \"3456789012345678901\",\n" - + " \"optionalFixed32\": 3456,\n" - + " \"optionalFixed64\": \"4567890123456789012\",\n" - + " \"optionalSfixed32\": 7890,\n" - + " \"optionalSfixed64\": \"5678901234567890123\",\n" - + " \"optionalFloat\": 1.5,\n" - + " \"optionalDouble\": 1.25,\n" - + " \"optionalBool\": true,\n" - + " \"optionalString\": \"Hello world!\",\n" - + " \"optionalBytes\": \"AAEC\",\n" - + " \"optionalNestedMessage\": {\n" - + " \"value\": 100\n" - + " },\n" - + " \"optionalNestedEnum\": \"BAR\",\n" - + " \"repeatedInt32\": [1234, 234],\n" - + " \"repeatedInt64\": [\"1234567890123456789\", \"234567890123456789\"],\n" - + " \"repeatedUint32\": [5678, 678],\n" - + " \"repeatedUint64\": [\"2345678901234567890\", \"345678901234567890\"],\n" - + " \"repeatedSint32\": [9012, 10],\n" - + " \"repeatedSint64\": [\"3456789012345678901\", \"456789012345678901\"],\n" - + " \"repeatedFixed32\": [3456, 456],\n" - + " \"repeatedFixed64\": [\"4567890123456789012\", \"567890123456789012\"],\n" - + " \"repeatedSfixed32\": [7890, 890],\n" - + " \"repeatedSfixed64\": [\"5678901234567890123\", \"678901234567890123\"],\n" - + " \"repeatedFloat\": [1.5, 11.5],\n" - + " \"repeatedDouble\": [1.25, 11.25],\n" - + " \"repeatedBool\": [true, true],\n" - + " \"repeatedString\": [\"Hello world!\", \"ello world!\"],\n" - + " \"repeatedBytes\": [\"AAEC\", \"AQI=\"],\n" - + " \"repeatedNestedMessage\": [{\n" - + " \"value\": 100\n" - + " }, {\n" - + " \"value\": 200\n" - + " }],\n" - + " \"repeatedNestedEnum\": [\"BAR\", \"BAZ\"]\n" - + "}", - toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo( + "{\n" + + " \"optionalInt32\": 1234,\n" + + " \"optionalInt64\": \"1234567890123456789\",\n" + + " \"optionalUint32\": 5678,\n" + + " \"optionalUint64\": \"2345678901234567890\",\n" + + " \"optionalSint32\": 9012,\n" + + " \"optionalSint64\": \"3456789012345678901\",\n" + + " \"optionalFixed32\": 3456,\n" + + " \"optionalFixed64\": \"4567890123456789012\",\n" + + " \"optionalSfixed32\": 7890,\n" + + " \"optionalSfixed64\": \"5678901234567890123\",\n" + + " \"optionalFloat\": 1.5,\n" + + " \"optionalDouble\": 1.25,\n" + + " \"optionalBool\": true,\n" + + " \"optionalString\": \"Hello world!\",\n" + + " \"optionalBytes\": \"AAEC\",\n" + + " \"optionalNestedMessage\": {\n" + + " \"value\": 100\n" + + " },\n" + + " \"optionalNestedEnum\": \"BAR\",\n" + + " \"repeatedInt32\": [1234, 234],\n" + + " \"repeatedInt64\": [\"1234567890123456789\", \"234567890123456789\"],\n" + + " \"repeatedUint32\": [5678, 678],\n" + + " \"repeatedUint64\": [\"2345678901234567890\", \"345678901234567890\"],\n" + + " \"repeatedSint32\": [9012, 10],\n" + + " \"repeatedSint64\": [\"3456789012345678901\", \"456789012345678901\"],\n" + + " \"repeatedFixed32\": [3456, 456],\n" + + " \"repeatedFixed64\": [\"4567890123456789012\", \"567890123456789012\"],\n" + + " \"repeatedSfixed32\": [7890, 890],\n" + + " \"repeatedSfixed64\": [\"5678901234567890123\", \"678901234567890123\"],\n" + + " \"repeatedFloat\": [1.5, 11.5],\n" + + " \"repeatedDouble\": [1.25, 11.25],\n" + + " \"repeatedBool\": [true, true],\n" + + " \"repeatedString\": [\"Hello world!\", \"ello world!\"],\n" + + " \"repeatedBytes\": [\"AAEC\", \"AQI=\"],\n" + + " \"repeatedNestedMessage\": [{\n" + + " \"value\": 100\n" + + " }, {\n" + + " \"value\": 200\n" + + " }],\n" + + " \"repeatedNestedEnum\": [\"BAR\", \"BAZ\"]\n" + + "}"); assertRoundTripEquals(message); } + @Test public void testUnknownEnumValues() throws Exception { TestAllTypes message = TestAllTypes.newBuilder() @@ -242,29 +250,30 @@ .addRepeatedNestedEnumValue(12345) .addRepeatedNestedEnumValue(0) .build(); - assertEquals( - "{\n" - + " \"optionalNestedEnum\": 12345,\n" - + " \"repeatedNestedEnum\": [12345, \"FOO\"]\n" - + "}", - toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo( + "{\n" + + " \"optionalNestedEnum\": 12345,\n" + + " \"repeatedNestedEnum\": [12345, \"FOO\"]\n" + + "}"); assertRoundTripEquals(message); TestMap.Builder mapBuilder = TestMap.newBuilder(); mapBuilder.putInt32ToEnumMapValue(1, 0); mapBuilder.putInt32ToEnumMapValue(2, 12345); TestMap mapMessage = mapBuilder.build(); - assertEquals( - "{\n" - + " \"int32ToEnumMap\": {\n" - + " \"1\": \"FOO\",\n" - + " \"2\": 12345\n" - + " }\n" - + "}", - toJsonString(mapMessage)); + assertThat(toJsonString(mapMessage)) + .isEqualTo( + "{\n" + + " \"int32ToEnumMap\": {\n" + + " \"1\": \"FOO\",\n" + + " \"2\": 12345\n" + + " }\n" + + "}"); assertRoundTripEquals(mapMessage); } + @Test public void testSpecialFloatValues() throws Exception { TestAllTypes message = TestAllTypes.newBuilder() @@ -275,16 +284,17 @@ .addRepeatedDouble(Double.POSITIVE_INFINITY) .addRepeatedDouble(Double.NEGATIVE_INFINITY) .build(); - assertEquals( - "{\n" - + " \"repeatedFloat\": [\"NaN\", \"Infinity\", \"-Infinity\"],\n" - + " \"repeatedDouble\": [\"NaN\", \"Infinity\", \"-Infinity\"]\n" - + "}", - toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo( + "{\n" + + " \"repeatedFloat\": [\"NaN\", \"Infinity\", \"-Infinity\"],\n" + + " \"repeatedDouble\": [\"NaN\", \"Infinity\", \"-Infinity\"]\n" + + "}"); assertRoundTripEquals(message); } + @Test public void testParserAcceptStringForNumericField() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); mergeFromJson( @@ -300,16 +310,17 @@ + "}", builder); TestAllTypes message = builder.build(); - assertEquals(1234, message.getOptionalInt32()); - assertEquals(5678, message.getOptionalUint32()); - assertEquals(9012, message.getOptionalSint32()); - assertEquals(3456, message.getOptionalFixed32()); - assertEquals(7890, message.getOptionalSfixed32()); - assertEquals(1.5f, message.getOptionalFloat(), 0.0f); - assertEquals(1.25, message.getOptionalDouble(), 0.0); - assertEquals(true, message.getOptionalBool()); + assertThat(message.getOptionalInt32()).isEqualTo(1234); + assertThat(message.getOptionalUint32()).isEqualTo(5678); + assertThat(message.getOptionalSint32()).isEqualTo(9012); + assertThat(message.getOptionalFixed32()).isEqualTo(3456); + assertThat(message.getOptionalSfixed32()).isEqualTo(7890); + assertThat(message.getOptionalFloat()).isEqualTo(1.5f); + assertThat(message.getOptionalDouble()).isEqualTo(1.25); + assertThat(message.getOptionalBool()).isTrue(); } + @Test public void testParserAcceptFloatingPointValueForIntegerField() throws Exception { // Test that numeric values like "1.000", "1e5" will also be accepted. TestAllTypes.Builder builder = TestAllTypes.newBuilder(); @@ -322,15 +333,15 @@ + "}", builder); int[] expectedValues = new int[] {1, 100000, 1, 100000}; - assertEquals(4, builder.getRepeatedInt32Count()); - assertEquals(4, builder.getRepeatedUint32Count()); - assertEquals(4, builder.getRepeatedInt64Count()); - assertEquals(4, builder.getRepeatedUint64Count()); + assertThat(builder.getRepeatedInt32Count()).isEqualTo(4); + assertThat(builder.getRepeatedUint32Count()).isEqualTo(4); + assertThat(builder.getRepeatedInt64Count()).isEqualTo(4); + assertThat(builder.getRepeatedUint64Count()).isEqualTo(4); for (int i = 0; i < 4; ++i) { - assertEquals(expectedValues[i], builder.getRepeatedInt32(i)); - assertEquals(expectedValues[i], builder.getRepeatedUint32(i)); - assertEquals(expectedValues[i], builder.getRepeatedInt64(i)); - assertEquals(expectedValues[i], builder.getRepeatedUint64(i)); + assertThat(builder.getRepeatedInt32(i)).isEqualTo(expectedValues[i]); + assertThat(builder.getRepeatedUint32(i)).isEqualTo(expectedValues[i]); + assertThat(builder.getRepeatedInt64(i)).isEqualTo(expectedValues[i]); + assertThat(builder.getRepeatedUint64(i)).isEqualTo(expectedValues[i]); } // Non-integers will still be rejected. @@ -345,14 +356,14 @@ try { // Numeric form is rejected. mergeFromJson("{\"" + name + "\":" + value + "}", builder); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IOException e) { // Expected. } try { // String form is also rejected. mergeFromJson("{\"" + name + "\":\"" + value + "\"}", builder); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IOException e) { // Expected. } @@ -366,6 +377,7 @@ mergeFromJson("{\"" + name + "\":\"" + value + "\"}", builder); } + @Test public void testParserRejectOutOfRangeNumericValues() throws Exception { assertAccepts("optionalInt32", String.valueOf(Integer.MAX_VALUE)); assertAccepts("optionalInt32", String.valueOf(Integer.MIN_VALUE)); @@ -376,7 +388,7 @@ assertRejects("optionalUint32", "123456789012345"); assertRejects("optionalUint32", "-1"); - BigInteger one = new BigInteger("1"); + BigInteger one = BigInteger.ONE; BigInteger maxLong = new BigInteger(String.valueOf(Long.MAX_VALUE)); BigInteger minLong = new BigInteger(String.valueOf(Long.MIN_VALUE)); assertAccepts("optionalInt64", maxLong.toString()); @@ -406,6 +418,7 @@ assertRejects("optionalDouble", minDouble.multiply(moreThanOne).toString()); } + @Test public void testParserAcceptNull() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); mergeFromJson( @@ -447,13 +460,13 @@ + "}", builder); TestAllTypes message = builder.build(); - assertEquals(TestAllTypes.getDefaultInstance(), message); + assertThat(message).isEqualTo(TestAllTypes.getDefaultInstance()); // Repeated field elements cannot be null. try { builder = TestAllTypes.newBuilder(); mergeFromJson("{\n" + " \"repeatedInt32\": [null, null],\n" + "}", builder); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException e) { // Exception expected. } @@ -461,34 +474,38 @@ try { builder = TestAllTypes.newBuilder(); mergeFromJson("{\n" + " \"repeatedNestedMessage\": [null, null],\n" + "}", builder); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException e) { // Exception expected. } } + @Test public void testNullInOneof() throws Exception { TestOneof.Builder builder = TestOneof.newBuilder(); mergeFromJson("{\n" + " \"oneofNullValue\": null \n" + "}", builder); TestOneof message = builder.build(); - assertEquals(TestOneof.OneofFieldCase.ONEOF_NULL_VALUE, message.getOneofFieldCase()); - assertEquals(NullValue.NULL_VALUE, message.getOneofNullValue()); + assertThat(message.getOneofFieldCase()).isEqualTo(TestOneof.OneofFieldCase.ONEOF_NULL_VALUE); + assertThat(message.getOneofNullValue()).isEqualTo(NullValue.NULL_VALUE); } + @Test public void testNullFirstInDuplicateOneof() throws Exception { TestOneof.Builder builder = TestOneof.newBuilder(); mergeFromJson("{\"oneofNestedMessage\": null, \"oneofInt32\": 1}", builder); TestOneof message = builder.build(); - assertEquals(1, message.getOneofInt32()); + assertThat(message.getOneofInt32()).isEqualTo(1); } + @Test public void testNullLastInDuplicateOneof() throws Exception { TestOneof.Builder builder = TestOneof.newBuilder(); mergeFromJson("{\"oneofInt32\": 1, \"oneofNestedMessage\": null}", builder); TestOneof message = builder.build(); - assertEquals(1, message.getOneofInt32()); + assertThat(message.getOneofInt32()).isEqualTo(1); } + @Test public void testParserRejectDuplicatedFields() throws Exception { // TODO(xiaofeng): The parser we are currently using (GSON) will accept and keep the last // one if multiple entries have the same name. This is not the desired behavior but it can @@ -504,7 +521,7 @@ + " \"optional_nested_message\": {}\n" + "}", builder); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException e) { // Exception expected. } @@ -518,7 +535,7 @@ + " \"repeated_int32\": [5, 6]\n" + "}", builder); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException e) { // Exception expected. } @@ -527,7 +544,7 @@ try { TestOneof.Builder builder = TestOneof.newBuilder(); mergeFromJson("{\n" + " \"oneofInt32\": 1,\n" + " \"oneof_int32\": 2\n" + "}", builder); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException e) { // Exception expected. } @@ -537,12 +554,13 @@ TestOneof.Builder builder = TestOneof.newBuilder(); mergeFromJson( "{\n" + " \"oneofInt32\": 1,\n" + " \"oneofNullValue\": null\n" + "}", builder); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException e) { // Exception expected. } } + @Test public void testMapFields() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); builder.putInt32ToInt32Map(1, 10); @@ -576,96 +594,96 @@ builder.putInt32ToEnumMap(9, NestedEnum.BAR); TestMap message = builder.build(); - assertEquals( - "{\n" - + " \"int32ToInt32Map\": {\n" - + " \"1\": 10\n" - + " },\n" - + " \"int64ToInt32Map\": {\n" - + " \"1234567890123456789\": 10\n" - + " },\n" - + " \"uint32ToInt32Map\": {\n" - + " \"2\": 20\n" - + " },\n" - + " \"uint64ToInt32Map\": {\n" - + " \"2234567890123456789\": 20\n" - + " },\n" - + " \"sint32ToInt32Map\": {\n" - + " \"3\": 30\n" - + " },\n" - + " \"sint64ToInt32Map\": {\n" - + " \"3234567890123456789\": 30\n" - + " },\n" - + " \"fixed32ToInt32Map\": {\n" - + " \"4\": 40\n" - + " },\n" - + " \"fixed64ToInt32Map\": {\n" - + " \"4234567890123456789\": 40\n" - + " },\n" - + " \"sfixed32ToInt32Map\": {\n" - + " \"5\": 50\n" - + " },\n" - + " \"sfixed64ToInt32Map\": {\n" - + " \"5234567890123456789\": 50\n" - + " },\n" - + " \"boolToInt32Map\": {\n" - + " \"false\": 6\n" - + " },\n" - + " \"stringToInt32Map\": {\n" - + " \"Hello\": 10\n" - + " },\n" - + " \"int32ToInt64Map\": {\n" - + " \"1\": \"1234567890123456789\"\n" - + " },\n" - + " \"int32ToUint32Map\": {\n" - + " \"2\": 20\n" - + " },\n" - + " \"int32ToUint64Map\": {\n" - + " \"2\": \"2234567890123456789\"\n" - + " },\n" - + " \"int32ToSint32Map\": {\n" - + " \"3\": 30\n" - + " },\n" - + " \"int32ToSint64Map\": {\n" - + " \"3\": \"3234567890123456789\"\n" - + " },\n" - + " \"int32ToFixed32Map\": {\n" - + " \"4\": 40\n" - + " },\n" - + " \"int32ToFixed64Map\": {\n" - + " \"4\": \"4234567890123456789\"\n" - + " },\n" - + " \"int32ToSfixed32Map\": {\n" - + " \"5\": 50\n" - + " },\n" - + " \"int32ToSfixed64Map\": {\n" - + " \"5\": \"5234567890123456789\"\n" - + " },\n" - + " \"int32ToFloatMap\": {\n" - + " \"6\": 1.5\n" - + " },\n" - + " \"int32ToDoubleMap\": {\n" - + " \"6\": 1.25\n" - + " },\n" - + " \"int32ToBoolMap\": {\n" - + " \"7\": false\n" - + " },\n" - + " \"int32ToStringMap\": {\n" - + " \"7\": \"World\"\n" - + " },\n" - + " \"int32ToBytesMap\": {\n" - + " \"8\": \"AQID\"\n" - + " },\n" - + " \"int32ToMessageMap\": {\n" - + " \"8\": {\n" - + " \"value\": 1234\n" - + " }\n" - + " },\n" - + " \"int32ToEnumMap\": {\n" - + " \"9\": \"BAR\"\n" - + " }\n" - + "}", - toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo( + "{\n" + + " \"int32ToInt32Map\": {\n" + + " \"1\": 10\n" + + " },\n" + + " \"int64ToInt32Map\": {\n" + + " \"1234567890123456789\": 10\n" + + " },\n" + + " \"uint32ToInt32Map\": {\n" + + " \"2\": 20\n" + + " },\n" + + " \"uint64ToInt32Map\": {\n" + + " \"2234567890123456789\": 20\n" + + " },\n" + + " \"sint32ToInt32Map\": {\n" + + " \"3\": 30\n" + + " },\n" + + " \"sint64ToInt32Map\": {\n" + + " \"3234567890123456789\": 30\n" + + " },\n" + + " \"fixed32ToInt32Map\": {\n" + + " \"4\": 40\n" + + " },\n" + + " \"fixed64ToInt32Map\": {\n" + + " \"4234567890123456789\": 40\n" + + " },\n" + + " \"sfixed32ToInt32Map\": {\n" + + " \"5\": 50\n" + + " },\n" + + " \"sfixed64ToInt32Map\": {\n" + + " \"5234567890123456789\": 50\n" + + " },\n" + + " \"boolToInt32Map\": {\n" + + " \"false\": 6\n" + + " },\n" + + " \"stringToInt32Map\": {\n" + + " \"Hello\": 10\n" + + " },\n" + + " \"int32ToInt64Map\": {\n" + + " \"1\": \"1234567890123456789\"\n" + + " },\n" + + " \"int32ToUint32Map\": {\n" + + " \"2\": 20\n" + + " },\n" + + " \"int32ToUint64Map\": {\n" + + " \"2\": \"2234567890123456789\"\n" + + " },\n" + + " \"int32ToSint32Map\": {\n" + + " \"3\": 30\n" + + " },\n" + + " \"int32ToSint64Map\": {\n" + + " \"3\": \"3234567890123456789\"\n" + + " },\n" + + " \"int32ToFixed32Map\": {\n" + + " \"4\": 40\n" + + " },\n" + + " \"int32ToFixed64Map\": {\n" + + " \"4\": \"4234567890123456789\"\n" + + " },\n" + + " \"int32ToSfixed32Map\": {\n" + + " \"5\": 50\n" + + " },\n" + + " \"int32ToSfixed64Map\": {\n" + + " \"5\": \"5234567890123456789\"\n" + + " },\n" + + " \"int32ToFloatMap\": {\n" + + " \"6\": 1.5\n" + + " },\n" + + " \"int32ToDoubleMap\": {\n" + + " \"6\": 1.25\n" + + " },\n" + + " \"int32ToBoolMap\": {\n" + + " \"7\": false\n" + + " },\n" + + " \"int32ToStringMap\": {\n" + + " \"7\": \"World\"\n" + + " },\n" + + " \"int32ToBytesMap\": {\n" + + " \"8\": \"AQID\"\n" + + " },\n" + + " \"int32ToMessageMap\": {\n" + + " \"8\": {\n" + + " \"value\": 1234\n" + + " }\n" + + " },\n" + + " \"int32ToEnumMap\": {\n" + + " \"9\": \"BAR\"\n" + + " }\n" + + "}"); assertRoundTripEquals(message); // Test multiple entries. @@ -674,12 +692,18 @@ builder.putInt32ToInt32Map(3, 4); message = builder.build(); - assertEquals( - "{\n" + " \"int32ToInt32Map\": {\n" + " \"1\": 2,\n" + " \"3\": 4\n" + " }\n" + "}", - toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo( + "{\n" + + " \"int32ToInt32Map\": {\n" + + " \"1\": 2,\n" + + " \"3\": 4\n" + + " }\n" + + "}"); assertRoundTripEquals(message); } + @Test public void testMapNullValueIsRejected() throws Exception { try { TestMap.Builder builder = TestMap.newBuilder(); @@ -689,7 +713,7 @@ + " \"int32ToMessageMap\": {null: 2}\n" + "}", builder); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException e) { // Exception expected. } @@ -702,30 +726,33 @@ + " \"int32ToMessageMap\": {\"2\": null}\n" + "}", builder); - fail(); + assertWithMessage("expected exception").fail(); } catch (InvalidProtocolBufferException e) { // Exception expected. } } + @Test public void testMapEnumNullValueIsIgnored() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); mergeFromJsonIgnoringUnknownFields( "{\n" + " \"int32ToEnumMap\": {\"1\": null}\n" + "}", builder); TestMap map = builder.build(); - assertEquals(0, map.getInt32ToEnumMapMap().size()); + assertThat(map.getInt32ToEnumMapMap()).isEmpty(); } + @Test public void testParserAcceptNonQuotedObjectKey() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); mergeFromJson( "{\n" + " int32ToInt32Map: {1: 2},\n" + " stringToInt32Map: {hello: 3}\n" + "}", builder); TestMap message = builder.build(); - assertEquals(2, message.getInt32ToInt32MapMap().get(1).intValue()); - assertEquals(3, message.getStringToInt32MapMap().get("hello").intValue()); + assertThat(message.getInt32ToInt32MapMap().get(1).intValue()).isEqualTo(2); + assertThat(message.getStringToInt32MapMap().get("hello").intValue()).isEqualTo(3); } + @Test public void testWrappers() throws Exception { TestWrappers.Builder builder = TestWrappers.newBuilder(); builder.getBoolValueBuilder().setValue(false); @@ -739,19 +766,19 @@ builder.getBytesValueBuilder().setValue(ByteString.EMPTY); TestWrappers message = builder.build(); - assertEquals( - "{\n" - + " \"int32Value\": 0,\n" - + " \"uint32Value\": 0,\n" - + " \"int64Value\": \"0\",\n" - + " \"uint64Value\": \"0\",\n" - + " \"floatValue\": 0.0,\n" - + " \"doubleValue\": 0.0,\n" - + " \"boolValue\": false,\n" - + " \"stringValue\": \"\",\n" - + " \"bytesValue\": \"\"\n" - + "}", - toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo( + "{\n" + + " \"int32Value\": 0,\n" + + " \"uint32Value\": 0,\n" + + " \"int64Value\": \"0\",\n" + + " \"uint64Value\": \"0\",\n" + + " \"floatValue\": 0.0,\n" + + " \"doubleValue\": 0.0,\n" + + " \"boolValue\": false,\n" + + " \"stringValue\": \"\",\n" + + " \"bytesValue\": \"\"\n" + + "}"); assertRoundTripEquals(message); builder = TestWrappers.newBuilder(); @@ -766,52 +793,56 @@ builder.getBytesValueBuilder().setValue(ByteString.copyFrom(new byte[] {8})); message = builder.build(); - assertEquals( - "{\n" - + " \"int32Value\": 1,\n" - + " \"uint32Value\": 3,\n" - + " \"int64Value\": \"2\",\n" - + " \"uint64Value\": \"4\",\n" - + " \"floatValue\": 5.0,\n" - + " \"doubleValue\": 6.0,\n" - + " \"boolValue\": true,\n" - + " \"stringValue\": \"7\",\n" - + " \"bytesValue\": \"CA==\"\n" - + "}", - toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo( + "{\n" + + " \"int32Value\": 1,\n" + + " \"uint32Value\": 3,\n" + + " \"int64Value\": \"2\",\n" + + " \"uint64Value\": \"4\",\n" + + " \"floatValue\": 5.0,\n" + + " \"doubleValue\": 6.0,\n" + + " \"boolValue\": true,\n" + + " \"stringValue\": \"7\",\n" + + " \"bytesValue\": \"CA==\"\n" + + "}"); assertRoundTripEquals(message); } + @Test public void testTimestamp() throws Exception { TestTimestamp message = TestTimestamp.newBuilder() .setTimestampValue(Timestamps.parse("1970-01-01T00:00:00Z")) .build(); - assertEquals( - "{\n" + " \"timestampValue\": \"1970-01-01T00:00:00Z\"\n" + "}", toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo("{\n" + " \"timestampValue\": \"1970-01-01T00:00:00Z\"\n" + "}"); assertRoundTripEquals(message); } + @Test public void testDuration() throws Exception { TestDuration message = TestDuration.newBuilder().setDurationValue(Durations.parse("12345s")).build(); - assertEquals("{\n" + " \"durationValue\": \"12345s\"\n" + "}", toJsonString(message)); + assertThat(toJsonString(message)).isEqualTo("{\n" + " \"durationValue\": \"12345s\"\n" + "}"); assertRoundTripEquals(message); } + @Test public void testFieldMask() throws Exception { TestFieldMask message = TestFieldMask.newBuilder() .setFieldMaskValue(FieldMaskUtil.fromString("foo.bar,baz,foo_bar.baz")) .build(); - assertEquals( - "{\n" + " \"fieldMaskValue\": \"foo.bar,baz,fooBar.baz\"\n" + "}", toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo("{\n" + " \"fieldMaskValue\": \"foo.bar,baz,fooBar.baz\"\n" + "}"); assertRoundTripEquals(message); } + @Test public void testStruct() throws Exception { // Build a struct with all possible values. TestStruct.Builder builder = TestStruct.newBuilder(); @@ -830,25 +861,25 @@ "list_value", Value.newBuilder().setListValue(listBuilder.build()).build()); TestStruct message = builder.build(); - assertEquals( - "{\n" - + " \"structValue\": {\n" - + " \"null_value\": null,\n" - + " \"number_value\": 1.25,\n" - + " \"string_value\": \"hello\",\n" - + " \"struct_value\": {\n" - + " \"number_value\": 1234.0\n" - + " },\n" - + " \"list_value\": [1.125, null]\n" - + " }\n" - + "}", - toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo( + "{\n" + + " \"structValue\": {\n" + + " \"null_value\": null,\n" + + " \"number_value\": 1.25,\n" + + " \"string_value\": \"hello\",\n" + + " \"struct_value\": {\n" + + " \"number_value\": 1234.0\n" + + " },\n" + + " \"list_value\": [1.125, null]\n" + + " }\n" + + "}"); assertRoundTripEquals(message); builder = TestStruct.newBuilder(); builder.setValue(Value.newBuilder().setNullValueValue(0).build()); message = builder.build(); - assertEquals("{\n" + " \"value\": null\n" + "}", toJsonString(message)); + assertThat(toJsonString(message)).isEqualTo("{\n" + " \"value\": null\n" + "}"); assertRoundTripEquals(message); builder = TestStruct.newBuilder(); @@ -856,11 +887,13 @@ listBuilder.addValues(Value.newBuilder().setNumberValue(31831.125).build()); listBuilder.addValues(Value.newBuilder().setNullValueValue(0).build()); message = builder.build(); - assertEquals("{\n" + " \"listValue\": [31831.125, null]\n" + "}", toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo("{\n" + " \"listValue\": [31831.125, null]\n" + "}"); assertRoundTripEquals(message); } + @Test public void testAnyFieldsWithCustomAddedTypeRegistry() throws Exception { TestAllTypes content = TestAllTypes.newBuilder().setOptionalInt32(1234).build(); TestAny message = TestAny.newBuilder().setAnyValue(Any.pack(content)).build(); @@ -869,37 +902,39 @@ com.google.protobuf.TypeRegistry.newBuilder().add(content.getDescriptorForType()).build(); JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(registry); - assertEquals( - "{\n" - + " \"anyValue\": {\n" - + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n" - + " \"optionalInt32\": 1234\n" - + " }\n" - + "}", - printer.print(message)); + assertThat(printer.print(message)) + .isEqualTo( + "{\n" + + " \"anyValue\": {\n" + + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n" + + " \"optionalInt32\": 1234\n" + + " }\n" + + "}"); assertRoundTripEquals(message, registry); TestAny messageWithDefaultAnyValue = TestAny.newBuilder().setAnyValue(Any.getDefaultInstance()).build(); - assertEquals("{\n" + " \"anyValue\": {}\n" + "}", printer.print(messageWithDefaultAnyValue)); + assertThat(printer.print(messageWithDefaultAnyValue)) + .isEqualTo("{\n" + " \"anyValue\": {}\n" + "}"); assertRoundTripEquals(messageWithDefaultAnyValue, registry); // Well-known types have a special formatting when embedded in Any. // // 1. Any in Any. Any anyMessage = Any.pack(Any.pack(content)); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n" - + " \"value\": {\n" - + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n" - + " \"optionalInt32\": 1234\n" - + " }\n" - + "}", - printer.print(anyMessage)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n" + + " \"value\": {\n" + + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n" + + " \"optionalInt32\": 1234\n" + + " }\n" + + "}"); assertRoundTripEquals(anyMessage, registry); } + @Test public void testAnyFields() throws Exception { TestAllTypes content = TestAllTypes.newBuilder().setOptionalInt32(1234).build(); TestAny message = TestAny.newBuilder().setAnyValue(Any.pack(content)).build(); @@ -907,7 +942,7 @@ // A TypeRegistry must be provided in order to convert Any types. try { toJsonString(message); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IOException e) { // Expected. } @@ -916,190 +951,187 @@ JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build(); JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(registry); - assertEquals( - "{\n" - + " \"anyValue\": {\n" - + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n" - + " \"optionalInt32\": 1234\n" - + " }\n" - + "}", - printer.print(message)); + assertThat(printer.print(message)) + .isEqualTo( + "{\n" + + " \"anyValue\": {\n" + + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n" + + " \"optionalInt32\": 1234\n" + + " }\n" + + "}"); assertRoundTripEquals(message, registry); TestAny messageWithDefaultAnyValue = TestAny.newBuilder().setAnyValue(Any.getDefaultInstance()).build(); - assertEquals( - "{\n" - + " \"anyValue\": {}\n" - + "}", - printer.print(messageWithDefaultAnyValue)); + assertThat(printer.print(messageWithDefaultAnyValue)) + .isEqualTo("{\n" + " \"anyValue\": {}\n" + "}"); assertRoundTripEquals(messageWithDefaultAnyValue, registry); // Well-known types have a special formatting when embedded in Any. // // 1. Any in Any. Any anyMessage = Any.pack(Any.pack(content)); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n" - + " \"value\": {\n" - + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n" - + " \"optionalInt32\": 1234\n" - + " }\n" - + "}", - printer.print(anyMessage)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n" + + " \"value\": {\n" + + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n" + + " \"optionalInt32\": 1234\n" + + " }\n" + + "}"); assertRoundTripEquals(anyMessage, registry); // 2. Wrappers in Any. - anyMessage = Any.pack(Int32Value.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Int32Value\",\n" - + " \"value\": 12345\n" - + "}", - printer.print(anyMessage)); + anyMessage = Any.pack(Int32Value.of(12345)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Int32Value\",\n" + + " \"value\": 12345\n" + + "}"); assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(UInt32Value.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.UInt32Value\",\n" - + " \"value\": 12345\n" - + "}", - printer.print(anyMessage)); + anyMessage = Any.pack(UInt32Value.of(12345)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.UInt32Value\",\n" + + " \"value\": 12345\n" + + "}"); assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(Int64Value.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Int64Value\",\n" - + " \"value\": \"12345\"\n" - + "}", - printer.print(anyMessage)); + anyMessage = Any.pack(Int64Value.of(12345)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Int64Value\",\n" + + " \"value\": \"12345\"\n" + + "}"); assertRoundTripEquals(anyMessage, registry); anyMessage = Any.pack(UInt64Value.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.UInt64Value\",\n" - + " \"value\": \"12345\"\n" - + "}", - printer.print(anyMessage)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.UInt64Value\",\n" + + " \"value\": \"12345\"\n" + + "}"); assertRoundTripEquals(anyMessage, registry); anyMessage = Any.pack(FloatValue.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.FloatValue\",\n" - + " \"value\": 12345.0\n" - + "}", - printer.print(anyMessage)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.FloatValue\",\n" + + " \"value\": 12345.0\n" + + "}"); assertRoundTripEquals(anyMessage, registry); anyMessage = Any.pack(DoubleValue.newBuilder().setValue(12345).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.DoubleValue\",\n" - + " \"value\": 12345.0\n" - + "}", - printer.print(anyMessage)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.DoubleValue\",\n" + + " \"value\": 12345.0\n" + + "}"); assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(BoolValue.newBuilder().setValue(true).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.BoolValue\",\n" - + " \"value\": true\n" - + "}", - printer.print(anyMessage)); + anyMessage = Any.pack(BoolValue.of(true)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.BoolValue\",\n" + + " \"value\": true\n" + + "}"); assertRoundTripEquals(anyMessage, registry); - anyMessage = Any.pack(StringValue.newBuilder().setValue("Hello").build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.StringValue\",\n" - + " \"value\": \"Hello\"\n" - + "}", - printer.print(anyMessage)); + anyMessage = Any.pack(StringValue.of("Hello")); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.StringValue\",\n" + + " \"value\": \"Hello\"\n" + + "}"); assertRoundTripEquals(anyMessage, registry); - anyMessage = - Any.pack(BytesValue.newBuilder().setValue(ByteString.copyFrom(new byte[] {1, 2})).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.BytesValue\",\n" - + " \"value\": \"AQI=\"\n" - + "}", - printer.print(anyMessage)); + anyMessage = Any.pack(BytesValue.of(ByteString.copyFrom(new byte[] {1, 2}))); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.BytesValue\",\n" + + " \"value\": \"AQI=\"\n" + + "}"); assertRoundTripEquals(anyMessage, registry); // 3. Timestamp in Any. anyMessage = Any.pack(Timestamps.parse("1969-12-31T23:59:59Z")); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\",\n" - + " \"value\": \"1969-12-31T23:59:59Z\"\n" - + "}", - printer.print(anyMessage)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\",\n" + + " \"value\": \"1969-12-31T23:59:59Z\"\n" + + "}"); assertRoundTripEquals(anyMessage, registry); // 4. Duration in Any anyMessage = Any.pack(Durations.parse("12345.10s")); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n" - + " \"value\": \"12345.100s\"\n" - + "}", - printer.print(anyMessage)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n" + + " \"value\": \"12345.100s\"\n" + + "}"); assertRoundTripEquals(anyMessage, registry); // 5. FieldMask in Any anyMessage = Any.pack(FieldMaskUtil.fromString("foo.bar,baz")); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.FieldMask\",\n" - + " \"value\": \"foo.bar,baz\"\n" - + "}", - printer.print(anyMessage)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.FieldMask\",\n" + + " \"value\": \"foo.bar,baz\"\n" + + "}"); assertRoundTripEquals(anyMessage, registry); // 6. Struct in Any Struct.Builder structBuilder = Struct.newBuilder(); structBuilder.putFields("number", Value.newBuilder().setNumberValue(1.125).build()); anyMessage = Any.pack(structBuilder.build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Struct\",\n" - + " \"value\": {\n" - + " \"number\": 1.125\n" - + " }\n" - + "}", - printer.print(anyMessage)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Struct\",\n" + + " \"value\": {\n" + + " \"number\": 1.125\n" + + " }\n" + + "}"); assertRoundTripEquals(anyMessage, registry); // 7. Value (number type) in Any Value.Builder valueBuilder = Value.newBuilder(); valueBuilder.setNumberValue(1); anyMessage = Any.pack(valueBuilder.build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" - + " \"value\": 1.0\n" - + "}", - printer.print(anyMessage)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" + + " \"value\": 1.0\n" + + "}"); assertRoundTripEquals(anyMessage, registry); // 8. Value (null type) in Any anyMessage = Any.pack(Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build()); - assertEquals( - "{\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" - + " \"value\": null\n" - + "}", - printer.print(anyMessage)); + assertThat(printer.print(anyMessage)) + .isEqualTo( + "{\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" + + " \"value\": null\n" + + "}"); assertRoundTripEquals(anyMessage, registry); } + @Test public void testAnyInMaps() throws Exception { JsonFormat.TypeRegistry registry = JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build(); JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(registry); TestAny.Builder testAny = TestAny.newBuilder(); - testAny.putAnyMap("int32_wrapper", Any.pack(Int32Value.newBuilder().setValue(123).build())); - testAny.putAnyMap("int64_wrapper", Any.pack(Int64Value.newBuilder().setValue(456).build())); + testAny.putAnyMap("int32_wrapper", Any.pack(Int32Value.of(123))); + testAny.putAnyMap("int64_wrapper", Any.pack(Int64Value.of(456))); testAny.putAnyMap("timestamp", Any.pack(Timestamps.parse("1969-12-31T23:59:59Z"))); testAny.putAnyMap("duration", Any.pack(Durations.parse("12345.1s"))); testAny.putAnyMap("field_mask", Any.pack(FieldMaskUtil.fromString("foo.bar,baz"))); @@ -1116,71 +1148,73 @@ testAny.putAnyMap("any_value_default", Any.pack(Any.getDefaultInstance())); testAny.putAnyMap("default", Any.getDefaultInstance()); - assertEquals( - "{\n" - + " \"anyMap\": {\n" - + " \"int32_wrapper\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Int32Value\",\n" - + " \"value\": 123\n" - + " },\n" - + " \"int64_wrapper\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Int64Value\",\n" - + " \"value\": \"456\"\n" - + " },\n" - + " \"timestamp\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\",\n" - + " \"value\": \"1969-12-31T23:59:59Z\"\n" - + " },\n" - + " \"duration\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n" - + " \"value\": \"12345.100s\"\n" - + " },\n" - + " \"field_mask\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.FieldMask\",\n" - + " \"value\": \"foo.bar,baz\"\n" - + " },\n" - + " \"struct\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Struct\",\n" - + " \"value\": {\n" - + " \"number\": 1.125\n" - + " }\n" - + " },\n" - + " \"list_value\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.ListValue\",\n" - + " \"value\": [1.125, null]\n" - + " },\n" - + " \"number_value\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" - + " \"value\": 1.125\n" - + " },\n" - + " \"any_value_number\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n" - + " \"value\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" - + " \"value\": 1.125\n" - + " }\n" - + " },\n" - + " \"any_value_default\": {\n" - + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n" - + " \"value\": {}\n" - + " },\n" - + " \"default\": {}\n" - + " }\n" - + "}", - printer.print(testAny.build())); + assertThat(printer.print(testAny.build())) + .isEqualTo( + "{\n" + + " \"anyMap\": {\n" + + " \"int32_wrapper\": {\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Int32Value\",\n" + + " \"value\": 123\n" + + " },\n" + + " \"int64_wrapper\": {\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Int64Value\",\n" + + " \"value\": \"456\"\n" + + " },\n" + + " \"timestamp\": {\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\",\n" + + " \"value\": \"1969-12-31T23:59:59Z\"\n" + + " },\n" + + " \"duration\": {\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n" + + " \"value\": \"12345.100s\"\n" + + " },\n" + + " \"field_mask\": {\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.FieldMask\",\n" + + " \"value\": \"foo.bar,baz\"\n" + + " },\n" + + " \"struct\": {\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Struct\",\n" + + " \"value\": {\n" + + " \"number\": 1.125\n" + + " }\n" + + " },\n" + + " \"list_value\": {\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.ListValue\",\n" + + " \"value\": [1.125, null]\n" + + " },\n" + + " \"number_value\": {\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" + + " \"value\": 1.125\n" + + " },\n" + + " \"any_value_number\": {\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n" + + " \"value\": {\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n" + + " \"value\": 1.125\n" + + " }\n" + + " },\n" + + " \"any_value_default\": {\n" + + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n" + + " \"value\": {}\n" + + " },\n" + + " \"default\": {}\n" + + " }\n" + + "}"); assertRoundTripEquals(testAny.build(), registry); } + @Test public void testParserMissingTypeUrl() throws Exception { try { Any.Builder builder = Any.newBuilder(); mergeFromJson("{\n" + " \"optionalInt32\": 1234\n" + "}", builder); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IOException e) { // Expected. } } + @Test public void testParserUnexpectedTypeUrl() throws Exception { try { Any.Builder builder = Any.newBuilder(); @@ -1190,17 +1224,18 @@ + " \"optionalInt32\": 12345\n" + "}", builder); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IOException e) { // Expected. } } + @Test public void testParserRejectTrailingComma() throws Exception { try { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); mergeFromJson("{\n" + " \"optionalInt32\": 12345,\n" + "}", builder); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IOException e) { // Expected. } @@ -1221,225 +1256,241 @@ // } } + @Test public void testParserRejectInvalidBase64() throws Exception { assertRejects("optionalBytes", "!@#$"); } + @Test public void testParserAcceptBase64Variants() throws Exception { assertAccepts("optionalBytes", "AQI"); // No padding assertAccepts("optionalBytes", "-_w"); // base64Url, no padding } + @Test public void testParserRejectInvalidEnumValue() throws Exception { try { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); mergeFromJson("{\n" + " \"optionalNestedEnum\": \"XXX\"\n" + "}", builder); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (InvalidProtocolBufferException e) { // Expected. } } + @Test public void testParserUnknownFields() throws Exception { try { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); String json = "{\n" + " \"unknownField\": \"XXX\"\n" + "}"; JsonFormat.parser().merge(json, builder); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (InvalidProtocolBufferException e) { // Expected. } } + @Test public void testParserIgnoringUnknownFields() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); String json = "{\n" + " \"unknownField\": \"XXX\"\n" + "}"; JsonFormat.parser().ignoringUnknownFields().merge(json, builder); } + @Test public void testParserIgnoringUnknownEnums() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); String json = "{\n" + " \"optionalNestedEnum\": \"XXX\"\n" + "}"; JsonFormat.parser().ignoringUnknownFields().merge(json, builder); - assertEquals(0, builder.getOptionalNestedEnumValue()); + assertThat(builder.getOptionalNestedEnumValue()).isEqualTo(0); } + @Test public void testParserSupportAliasEnums() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); String json = "{\n" + " \"optionalAliasedEnum\": \"QUX\"\n" + "}"; JsonFormat.parser().merge(json, builder); - assertEquals(AliasedEnum.ALIAS_BAZ, builder.getOptionalAliasedEnum()); + assertThat(builder.getOptionalAliasedEnum()).isEqualTo(AliasedEnum.ALIAS_BAZ); builder = TestAllTypes.newBuilder(); json = "{\n" + " \"optionalAliasedEnum\": \"qux\"\n" + "}"; JsonFormat.parser().merge(json, builder); - assertEquals(AliasedEnum.ALIAS_BAZ, builder.getOptionalAliasedEnum()); + assertThat(builder.getOptionalAliasedEnum()).isEqualTo(AliasedEnum.ALIAS_BAZ); builder = TestAllTypes.newBuilder(); json = "{\n" + " \"optionalAliasedEnum\": \"bAz\"\n" + "}"; JsonFormat.parser().merge(json, builder); - assertEquals(AliasedEnum.ALIAS_BAZ, builder.getOptionalAliasedEnum()); + assertThat(builder.getOptionalAliasedEnum()).isEqualTo(AliasedEnum.ALIAS_BAZ); } + @Test public void testUnknownEnumMap() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); JsonFormat.parser() .ignoringUnknownFields() .merge("{\n" + " \"int32ToEnumMap\": {1: XXX, 2: FOO}" + "}", builder); - assertEquals(NestedEnum.FOO, builder.getInt32ToEnumMapMap().get(2)); - assertEquals(1, builder.getInt32ToEnumMapMap().size()); + assertThat(builder.getInt32ToEnumMapMap()).containsEntry(2, NestedEnum.FOO); + assertThat(builder.getInt32ToEnumMapMap()).hasSize(1); } + @Test public void testRepeatedUnknownEnum() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); JsonFormat.parser() .ignoringUnknownFields() .merge("{\n" + " \"repeatedNestedEnum\": [XXX, FOO, BAR, BAZ]" + "}", builder); - assertEquals(NestedEnum.FOO, builder.getRepeatedNestedEnum(0)); - assertEquals(NestedEnum.BAR, builder.getRepeatedNestedEnum(1)); - assertEquals(NestedEnum.BAZ, builder.getRepeatedNestedEnum(2)); - assertEquals(3, builder.getRepeatedNestedEnumList().size()); + assertThat(builder.getRepeatedNestedEnum(0)).isEqualTo(NestedEnum.FOO); + assertThat(builder.getRepeatedNestedEnum(1)).isEqualTo(NestedEnum.BAR); + assertThat(builder.getRepeatedNestedEnum(2)).isEqualTo(NestedEnum.BAZ); + assertThat(builder.getRepeatedNestedEnumList()).hasSize(3); } + @Test public void testParserIntegerEnumValue() throws Exception { TestAllTypes.Builder actualBuilder = TestAllTypes.newBuilder(); mergeFromJson("{\n" + " \"optionalNestedEnum\": 2\n" + "}", actualBuilder); TestAllTypes expected = TestAllTypes.newBuilder().setOptionalNestedEnum(NestedEnum.BAZ).build(); - assertEquals(expected, actualBuilder.build()); + assertThat(actualBuilder.build()).isEqualTo(expected); } + @Test public void testCustomJsonName() throws Exception { TestCustomJsonName message = TestCustomJsonName.newBuilder().setValue(12345).build(); - assertEquals("{\n" + " \"@value\": 12345\n" + "}", JsonFormat.printer().print(message)); + assertThat(JsonFormat.printer().print(message)) + .isEqualTo("{\n" + " \"@value\": 12345\n" + "}"); assertRoundTripEquals(message); } // Regression test for b/73832901. Make sure html tags are escaped. + @Test public void testHtmlEscape() throws Exception { TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("</script>").build(); - assertEquals("{\n \"optionalString\": \"\\u003c/script\\u003e\"\n}", toJsonString(message)); + assertThat(toJsonString(message)) + .isEqualTo("{\n \"optionalString\": \"\\u003c/script\\u003e\"\n}"); TestAllTypes.Builder builder = TestAllTypes.newBuilder(); JsonFormat.parser().merge(toJsonString(message), builder); - assertEquals(message.getOptionalString(), builder.getOptionalString()); + assertThat(builder.getOptionalString()).isEqualTo(message.getOptionalString()); } + @Test public void testIncludingDefaultValueFields() throws Exception { TestAllTypes message = TestAllTypes.getDefaultInstance(); - assertEquals("{\n}", JsonFormat.printer().print(message)); - assertEquals( - "{\n" - + " \"optionalInt32\": 0,\n" - + " \"optionalInt64\": \"0\",\n" - + " \"optionalUint32\": 0,\n" - + " \"optionalUint64\": \"0\",\n" - + " \"optionalSint32\": 0,\n" - + " \"optionalSint64\": \"0\",\n" - + " \"optionalFixed32\": 0,\n" - + " \"optionalFixed64\": \"0\",\n" - + " \"optionalSfixed32\": 0,\n" - + " \"optionalSfixed64\": \"0\",\n" - + " \"optionalFloat\": 0.0,\n" - + " \"optionalDouble\": 0.0,\n" - + " \"optionalBool\": false,\n" - + " \"optionalString\": \"\",\n" - + " \"optionalBytes\": \"\",\n" - + " \"optionalNestedEnum\": \"FOO\",\n" - + " \"repeatedInt32\": [],\n" - + " \"repeatedInt64\": [],\n" - + " \"repeatedUint32\": [],\n" - + " \"repeatedUint64\": [],\n" - + " \"repeatedSint32\": [],\n" - + " \"repeatedSint64\": [],\n" - + " \"repeatedFixed32\": [],\n" - + " \"repeatedFixed64\": [],\n" - + " \"repeatedSfixed32\": [],\n" - + " \"repeatedSfixed64\": [],\n" - + " \"repeatedFloat\": [],\n" - + " \"repeatedDouble\": [],\n" - + " \"repeatedBool\": [],\n" - + " \"repeatedString\": [],\n" - + " \"repeatedBytes\": [],\n" - + " \"repeatedNestedMessage\": [],\n" - + " \"repeatedNestedEnum\": [],\n" - + " \"optionalAliasedEnum\": \"ALIAS_FOO\"\n" - + "}", - JsonFormat.printer().includingDefaultValueFields().print(message)); + assertThat(JsonFormat.printer().print(message)).isEqualTo("{\n}"); + assertThat(JsonFormat.printer().includingDefaultValueFields().print(message)) + .isEqualTo( + "{\n" + + " \"optionalInt32\": 0,\n" + + " \"optionalInt64\": \"0\",\n" + + " \"optionalUint32\": 0,\n" + + " \"optionalUint64\": \"0\",\n" + + " \"optionalSint32\": 0,\n" + + " \"optionalSint64\": \"0\",\n" + + " \"optionalFixed32\": 0,\n" + + " \"optionalFixed64\": \"0\",\n" + + " \"optionalSfixed32\": 0,\n" + + " \"optionalSfixed64\": \"0\",\n" + + " \"optionalFloat\": 0.0,\n" + + " \"optionalDouble\": 0.0,\n" + + " \"optionalBool\": false,\n" + + " \"optionalString\": \"\",\n" + + " \"optionalBytes\": \"\",\n" + + " \"optionalNestedEnum\": \"FOO\",\n" + + " \"repeatedInt32\": [],\n" + + " \"repeatedInt64\": [],\n" + + " \"repeatedUint32\": [],\n" + + " \"repeatedUint64\": [],\n" + + " \"repeatedSint32\": [],\n" + + " \"repeatedSint64\": [],\n" + + " \"repeatedFixed32\": [],\n" + + " \"repeatedFixed64\": [],\n" + + " \"repeatedSfixed32\": [],\n" + + " \"repeatedSfixed64\": [],\n" + + " \"repeatedFloat\": [],\n" + + " \"repeatedDouble\": [],\n" + + " \"repeatedBool\": [],\n" + + " \"repeatedString\": [],\n" + + " \"repeatedBytes\": [],\n" + + " \"repeatedNestedMessage\": [],\n" + + " \"repeatedNestedEnum\": [],\n" + + " \"optionalAliasedEnum\": \"ALIAS_FOO\"\n" + + "}"); - Set<FieldDescriptor> fixedFields = new HashSet<FieldDescriptor>(); + Set<FieldDescriptor> fixedFields = new HashSet<>(); for (FieldDescriptor fieldDesc : TestAllTypes.getDescriptor().getFields()) { if (fieldDesc.getName().contains("_fixed")) { fixedFields.add(fieldDesc); } } - assertEquals( - "{\n" - + " \"optionalFixed32\": 0,\n" - + " \"optionalFixed64\": \"0\",\n" - + " \"repeatedFixed32\": [],\n" - + " \"repeatedFixed64\": []\n" - + "}", - JsonFormat.printer().includingDefaultValueFields(fixedFields).print(message)); + assertThat(JsonFormat.printer().includingDefaultValueFields(fixedFields).print(message)) + .isEqualTo( + "{\n" + + " \"optionalFixed32\": 0,\n" + + " \"optionalFixed64\": \"0\",\n" + + " \"repeatedFixed32\": [],\n" + + " \"repeatedFixed64\": []\n" + + "}"); TestAllTypes messageNonDefaults = message.toBuilder().setOptionalInt64(1234).setOptionalFixed32(3232).build(); - assertEquals( - "{\n" - + " \"optionalInt64\": \"1234\",\n" - + " \"optionalFixed32\": 3232,\n" - + " \"optionalFixed64\": \"0\",\n" - + " \"repeatedFixed32\": [],\n" - + " \"repeatedFixed64\": []\n" - + "}", - JsonFormat.printer().includingDefaultValueFields(fixedFields).print(messageNonDefaults)); + assertThat( + JsonFormat.printer().includingDefaultValueFields(fixedFields).print(messageNonDefaults)) + .isEqualTo( + "{\n" + + " \"optionalInt64\": \"1234\",\n" + + " \"optionalFixed32\": 3232,\n" + + " \"optionalFixed64\": \"0\",\n" + + " \"repeatedFixed32\": [],\n" + + " \"repeatedFixed64\": []\n" + + "}"); try { JsonFormat.printer().includingDefaultValueFields().includingDefaultValueFields(); - fail("IllegalStateException is expected."); + assertWithMessage("IllegalStateException is expected.").fail(); } catch (IllegalStateException e) { // Expected. - assertTrue( - "Exception message should mention includingDefaultValueFields.", - e.getMessage().contains("includingDefaultValueFields")); + assertWithMessage("Exception message should mention includingDefaultValueFields.") + .that(e.getMessage().contains("includingDefaultValueFields")) + .isTrue(); } try { JsonFormat.printer().includingDefaultValueFields().includingDefaultValueFields(fixedFields); - fail("IllegalStateException is expected."); + assertWithMessage("IllegalStateException is expected.").fail(); } catch (IllegalStateException e) { // Expected. - assertTrue( - "Exception message should mention includingDefaultValueFields.", - e.getMessage().contains("includingDefaultValueFields")); + assertWithMessage("Exception message should mention includingDefaultValueFields.") + .that(e.getMessage().contains("includingDefaultValueFields")) + .isTrue(); } try { JsonFormat.printer().includingDefaultValueFields(fixedFields).includingDefaultValueFields(); - fail("IllegalStateException is expected."); + assertWithMessage("IllegalStateException is expected.").fail(); } catch (IllegalStateException e) { // Expected. - assertTrue( - "Exception message should mention includingDefaultValueFields.", - e.getMessage().contains("includingDefaultValueFields")); + assertWithMessage("Exception message should mention includingDefaultValueFields.") + .that(e.getMessage().contains("includingDefaultValueFields")) + .isTrue(); } try { JsonFormat.printer() .includingDefaultValueFields(fixedFields) .includingDefaultValueFields(fixedFields); - fail("IllegalStateException is expected."); + assertWithMessage("IllegalStateException is expected.").fail(); } catch (IllegalStateException e) { // Expected. - assertTrue( - "Exception message should mention includingDefaultValueFields.", - e.getMessage().contains("includingDefaultValueFields")); + assertWithMessage("Exception message should mention includingDefaultValueFields.") + .that(e.getMessage().contains("includingDefaultValueFields")) + .isTrue(); } - Set<FieldDescriptor> intFields = new HashSet<FieldDescriptor>(); + Set<FieldDescriptor> intFields = new HashSet<>(); for (FieldDescriptor fieldDesc : TestAllTypes.getDescriptor().getFields()) { if (fieldDesc.getName().contains("_int")) { intFields.add(fieldDesc); @@ -1450,203 +1501,205 @@ JsonFormat.printer() .includingDefaultValueFields(intFields) .includingDefaultValueFields(fixedFields); - fail("IllegalStateException is expected."); + assertWithMessage("IllegalStateException is expected.").fail(); } catch (IllegalStateException e) { // Expected. - assertTrue( - "Exception message should mention includingDefaultValueFields.", - e.getMessage().contains("includingDefaultValueFields")); + assertWithMessage("Exception message should mention includingDefaultValueFields.") + .that(e.getMessage().contains("includingDefaultValueFields")) + .isTrue(); } try { JsonFormat.printer().includingDefaultValueFields(null); - fail("IllegalArgumentException is expected."); + assertWithMessage("IllegalArgumentException is expected.").fail(); } catch (IllegalArgumentException e) { // Expected. - assertTrue( - "Exception message should mention includingDefaultValueFields.", - e.getMessage().contains("includingDefaultValueFields")); + assertWithMessage("Exception message should mention includingDefaultValueFields.") + .that(e.getMessage().contains("includingDefaultValueFields")) + .isTrue(); } try { JsonFormat.printer().includingDefaultValueFields(Collections.<FieldDescriptor>emptySet()); - fail("IllegalArgumentException is expected."); + assertWithMessage("IllegalArgumentException is expected.").fail(); } catch (IllegalArgumentException e) { // Expected. - assertTrue( - "Exception message should mention includingDefaultValueFields.", - e.getMessage().contains("includingDefaultValueFields")); + assertWithMessage("Exception message should mention includingDefaultValueFields.") + .that(e.getMessage().contains("includingDefaultValueFields")) + .isTrue(); } TestMap mapMessage = TestMap.getDefaultInstance(); - assertEquals("{\n}", JsonFormat.printer().print(mapMessage)); - assertEquals( - "{\n" - + " \"int32ToInt32Map\": {\n" - + " },\n" - + " \"int64ToInt32Map\": {\n" - + " },\n" - + " \"uint32ToInt32Map\": {\n" - + " },\n" - + " \"uint64ToInt32Map\": {\n" - + " },\n" - + " \"sint32ToInt32Map\": {\n" - + " },\n" - + " \"sint64ToInt32Map\": {\n" - + " },\n" - + " \"fixed32ToInt32Map\": {\n" - + " },\n" - + " \"fixed64ToInt32Map\": {\n" - + " },\n" - + " \"sfixed32ToInt32Map\": {\n" - + " },\n" - + " \"sfixed64ToInt32Map\": {\n" - + " },\n" - + " \"boolToInt32Map\": {\n" - + " },\n" - + " \"stringToInt32Map\": {\n" - + " },\n" - + " \"int32ToInt64Map\": {\n" - + " },\n" - + " \"int32ToUint32Map\": {\n" - + " },\n" - + " \"int32ToUint64Map\": {\n" - + " },\n" - + " \"int32ToSint32Map\": {\n" - + " },\n" - + " \"int32ToSint64Map\": {\n" - + " },\n" - + " \"int32ToFixed32Map\": {\n" - + " },\n" - + " \"int32ToFixed64Map\": {\n" - + " },\n" - + " \"int32ToSfixed32Map\": {\n" - + " },\n" - + " \"int32ToSfixed64Map\": {\n" - + " },\n" - + " \"int32ToFloatMap\": {\n" - + " },\n" - + " \"int32ToDoubleMap\": {\n" - + " },\n" - + " \"int32ToBoolMap\": {\n" - + " },\n" - + " \"int32ToStringMap\": {\n" - + " },\n" - + " \"int32ToBytesMap\": {\n" - + " },\n" - + " \"int32ToMessageMap\": {\n" - + " },\n" - + " \"int32ToEnumMap\": {\n" - + " }\n" - + "}", - JsonFormat.printer().includingDefaultValueFields().print(mapMessage)); + assertThat(JsonFormat.printer().print(mapMessage)).isEqualTo("{\n}"); + assertThat(JsonFormat.printer().includingDefaultValueFields().print(mapMessage)) + .isEqualTo( + "{\n" + + " \"int32ToInt32Map\": {\n" + + " },\n" + + " \"int64ToInt32Map\": {\n" + + " },\n" + + " \"uint32ToInt32Map\": {\n" + + " },\n" + + " \"uint64ToInt32Map\": {\n" + + " },\n" + + " \"sint32ToInt32Map\": {\n" + + " },\n" + + " \"sint64ToInt32Map\": {\n" + + " },\n" + + " \"fixed32ToInt32Map\": {\n" + + " },\n" + + " \"fixed64ToInt32Map\": {\n" + + " },\n" + + " \"sfixed32ToInt32Map\": {\n" + + " },\n" + + " \"sfixed64ToInt32Map\": {\n" + + " },\n" + + " \"boolToInt32Map\": {\n" + + " },\n" + + " \"stringToInt32Map\": {\n" + + " },\n" + + " \"int32ToInt64Map\": {\n" + + " },\n" + + " \"int32ToUint32Map\": {\n" + + " },\n" + + " \"int32ToUint64Map\": {\n" + + " },\n" + + " \"int32ToSint32Map\": {\n" + + " },\n" + + " \"int32ToSint64Map\": {\n" + + " },\n" + + " \"int32ToFixed32Map\": {\n" + + " },\n" + + " \"int32ToFixed64Map\": {\n" + + " },\n" + + " \"int32ToSfixed32Map\": {\n" + + " },\n" + + " \"int32ToSfixed64Map\": {\n" + + " },\n" + + " \"int32ToFloatMap\": {\n" + + " },\n" + + " \"int32ToDoubleMap\": {\n" + + " },\n" + + " \"int32ToBoolMap\": {\n" + + " },\n" + + " \"int32ToStringMap\": {\n" + + " },\n" + + " \"int32ToBytesMap\": {\n" + + " },\n" + + " \"int32ToMessageMap\": {\n" + + " },\n" + + " \"int32ToEnumMap\": {\n" + + " }\n" + + "}"); TestOneof oneofMessage = TestOneof.getDefaultInstance(); - assertEquals("{\n}", JsonFormat.printer().print(oneofMessage)); - assertEquals("{\n}", JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)); + assertThat(JsonFormat.printer().print(oneofMessage)).isEqualTo("{\n}"); + assertThat(JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)) + .isEqualTo("{\n}"); oneofMessage = TestOneof.newBuilder().setOneofInt32(42).build(); - assertEquals("{\n \"oneofInt32\": 42\n}", JsonFormat.printer().print(oneofMessage)); - assertEquals( - "{\n \"oneofInt32\": 42\n}", - JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)); + assertThat(JsonFormat.printer().print(oneofMessage)).isEqualTo("{\n \"oneofInt32\": 42\n}"); + assertThat(JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)) + .isEqualTo("{\n \"oneofInt32\": 42\n}"); TestOneof.Builder oneofBuilder = TestOneof.newBuilder(); mergeFromJson("{\n" + " \"oneofNullValue\": null \n" + "}", oneofBuilder); oneofMessage = oneofBuilder.build(); - assertEquals("{\n \"oneofNullValue\": null\n}", JsonFormat.printer().print(oneofMessage)); - assertEquals( - "{\n \"oneofNullValue\": null\n}", - JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)); + assertThat(JsonFormat.printer().print(oneofMessage)) + .isEqualTo("{\n \"oneofNullValue\": null\n}"); + assertThat(JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)) + .isEqualTo("{\n \"oneofNullValue\": null\n}"); } + @Test public void testPreservingProtoFieldNames() throws Exception { TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(12345).build(); - assertEquals("{\n" + " \"optionalInt32\": 12345\n" + "}", JsonFormat.printer().print(message)); - assertEquals( - "{\n" + " \"optional_int32\": 12345\n" + "}", - JsonFormat.printer().preservingProtoFieldNames().print(message)); + assertThat(JsonFormat.printer().print(message)) + .isEqualTo("{\n" + " \"optionalInt32\": 12345\n" + "}"); + assertThat(JsonFormat.printer().preservingProtoFieldNames().print(message)) + .isEqualTo("{\n" + " \"optional_int32\": 12345\n" + "}"); // The json_name field option is ignored when configured to use original proto field names. TestCustomJsonName messageWithCustomJsonName = TestCustomJsonName.newBuilder().setValue(12345).build(); - assertEquals( - "{\n" + " \"value\": 12345\n" + "}", - JsonFormat.printer().preservingProtoFieldNames().print(messageWithCustomJsonName)); + assertThat(JsonFormat.printer().preservingProtoFieldNames().print(messageWithCustomJsonName)) + .isEqualTo("{\n" + " \"value\": 12345\n" + "}"); // Parsers accept both original proto field names and lowerCamelCase names. TestAllTypes.Builder builder = TestAllTypes.newBuilder(); JsonFormat.parser().merge("{\"optionalInt32\": 12345}", builder); - assertEquals(12345, builder.getOptionalInt32()); + assertThat(builder.getOptionalInt32()).isEqualTo(12345); builder.clear(); JsonFormat.parser().merge("{\"optional_int32\": 54321}", builder); - assertEquals(54321, builder.getOptionalInt32()); + assertThat(builder.getOptionalInt32()).isEqualTo(54321); } + @Test public void testPrintingEnumsAsInts() throws Exception { TestAllTypes message = TestAllTypes.newBuilder().setOptionalNestedEnum(NestedEnum.BAR).build(); - assertEquals( - "{\n" + " \"optionalNestedEnum\": 1\n" + "}", - JsonFormat.printer().printingEnumsAsInts().print(message)); + assertThat(JsonFormat.printer().printingEnumsAsInts().print(message)) + .isEqualTo("{\n" + " \"optionalNestedEnum\": 1\n" + "}"); } + @Test public void testOmittingInsignificantWhiteSpace() throws Exception { TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(12345).build(); - assertEquals( - "{" + "\"optionalInt32\":12345" + "}", - JsonFormat.printer().omittingInsignificantWhitespace().print(message)); + assertThat(JsonFormat.printer().omittingInsignificantWhitespace().print(message)) + .isEqualTo("{" + "\"optionalInt32\":12345" + "}"); TestAllTypes message1 = TestAllTypes.getDefaultInstance(); - assertEquals("{}", JsonFormat.printer().omittingInsignificantWhitespace().print(message1)); + assertThat(JsonFormat.printer().omittingInsignificantWhitespace().print(message1)) + .isEqualTo("{}"); TestAllTypes.Builder builder = TestAllTypes.newBuilder(); setAllFields(builder); TestAllTypes message2 = builder.build(); - assertEquals( - "{" - + "\"optionalInt32\":1234," - + "\"optionalInt64\":\"1234567890123456789\"," - + "\"optionalUint32\":5678," - + "\"optionalUint64\":\"2345678901234567890\"," - + "\"optionalSint32\":9012," - + "\"optionalSint64\":\"3456789012345678901\"," - + "\"optionalFixed32\":3456," - + "\"optionalFixed64\":\"4567890123456789012\"," - + "\"optionalSfixed32\":7890," - + "\"optionalSfixed64\":\"5678901234567890123\"," - + "\"optionalFloat\":1.5," - + "\"optionalDouble\":1.25," - + "\"optionalBool\":true," - + "\"optionalString\":\"Hello world!\"," - + "\"optionalBytes\":\"AAEC\"," - + "\"optionalNestedMessage\":{" - + "\"value\":100" - + "}," - + "\"optionalNestedEnum\":\"BAR\"," - + "\"repeatedInt32\":[1234,234]," - + "\"repeatedInt64\":[\"1234567890123456789\",\"234567890123456789\"]," - + "\"repeatedUint32\":[5678,678]," - + "\"repeatedUint64\":[\"2345678901234567890\",\"345678901234567890\"]," - + "\"repeatedSint32\":[9012,10]," - + "\"repeatedSint64\":[\"3456789012345678901\",\"456789012345678901\"]," - + "\"repeatedFixed32\":[3456,456]," - + "\"repeatedFixed64\":[\"4567890123456789012\",\"567890123456789012\"]," - + "\"repeatedSfixed32\":[7890,890]," - + "\"repeatedSfixed64\":[\"5678901234567890123\",\"678901234567890123\"]," - + "\"repeatedFloat\":[1.5,11.5]," - + "\"repeatedDouble\":[1.25,11.25]," - + "\"repeatedBool\":[true,true]," - + "\"repeatedString\":[\"Hello world!\",\"ello world!\"]," - + "\"repeatedBytes\":[\"AAEC\",\"AQI=\"]," - + "\"repeatedNestedMessage\":[{" - + "\"value\":100" - + "},{" - + "\"value\":200" - + "}]," - + "\"repeatedNestedEnum\":[\"BAR\",\"BAZ\"]" - + "}", - toCompactJsonString(message2)); + assertThat(toCompactJsonString(message2)) + .isEqualTo( + "{" + + "\"optionalInt32\":1234," + + "\"optionalInt64\":\"1234567890123456789\"," + + "\"optionalUint32\":5678," + + "\"optionalUint64\":\"2345678901234567890\"," + + "\"optionalSint32\":9012," + + "\"optionalSint64\":\"3456789012345678901\"," + + "\"optionalFixed32\":3456," + + "\"optionalFixed64\":\"4567890123456789012\"," + + "\"optionalSfixed32\":7890," + + "\"optionalSfixed64\":\"5678901234567890123\"," + + "\"optionalFloat\":1.5," + + "\"optionalDouble\":1.25," + + "\"optionalBool\":true," + + "\"optionalString\":\"Hello world!\"," + + "\"optionalBytes\":\"AAEC\"," + + "\"optionalNestedMessage\":{" + + "\"value\":100" + + "}," + + "\"optionalNestedEnum\":\"BAR\"," + + "\"repeatedInt32\":[1234,234]," + + "\"repeatedInt64\":[\"1234567890123456789\",\"234567890123456789\"]," + + "\"repeatedUint32\":[5678,678]," + + "\"repeatedUint64\":[\"2345678901234567890\",\"345678901234567890\"]," + + "\"repeatedSint32\":[9012,10]," + + "\"repeatedSint64\":[\"3456789012345678901\",\"456789012345678901\"]," + + "\"repeatedFixed32\":[3456,456]," + + "\"repeatedFixed64\":[\"4567890123456789012\",\"567890123456789012\"]," + + "\"repeatedSfixed32\":[7890,890]," + + "\"repeatedSfixed64\":[\"5678901234567890123\",\"678901234567890123\"]," + + "\"repeatedFloat\":[1.5,11.5]," + + "\"repeatedDouble\":[1.25,11.25]," + + "\"repeatedBool\":[true,true]," + + "\"repeatedString\":[\"Hello world!\",\"ello world!\"]," + + "\"repeatedBytes\":[\"AAEC\",\"AQI=\"]," + + "\"repeatedNestedMessage\":[{" + + "\"value\":100" + + "},{" + + "\"value\":200" + + "}]," + + "\"repeatedNestedEnum\":[\"BAR\",\"BAZ\"]" + + "}"); } // Regression test for b/29892357 + @Test public void testEmptyWrapperTypesInAny() throws Exception { JsonFormat.TypeRegistry registry = JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build(); @@ -1660,40 +1713,42 @@ + "}\n", builder); Any any = builder.build(); - assertEquals(0, any.getValue().size()); + assertThat(any.getValue().size()).isEqualTo(0); } + @Test public void testRecursionLimit() throws Exception { String input = - "{\n" - + " \"nested\": {\n" - + " \"nested\": {\n" - + " \"nested\": {\n" - + " \"nested\": {\n" - + " \"value\": 1234\n" - + " }\n" - + " }\n" - + " }\n" - + " }\n" - + "}\n"; + "{\n" + + " \"nested\": {\n" + + " \"nested\": {\n" + + " \"nested\": {\n" + + " \"nested\": {\n" + + " \"value\": 1234\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; JsonFormat.Parser parser = JsonFormat.parser(); TestRecursive.Builder builder = TestRecursive.newBuilder(); parser.merge(input, builder); TestRecursive message = builder.build(); - assertEquals(1234, message.getNested().getNested().getNested().getNested().getValue()); + assertThat(message.getNested().getNested().getNested().getNested().getValue()).isEqualTo(1234); parser = JsonFormat.parser().usingRecursionLimit(3); builder = TestRecursive.newBuilder(); try { parser.merge(input, builder); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (InvalidProtocolBufferException e) { // Expected. } } // Test that we are not leaking out JSON exceptions. + @Test public void testJsonException() throws Exception { InputStream throwingInputStream = new InputStream() { @@ -1708,9 +1763,9 @@ try { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); JsonFormat.parser().merge(throwingReader, builder); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (IOException e) { - assertEquals("12345", e.getMessage()); + assertThat(e).hasMessageThat().isEqualTo("12345"); } Reader invalidJsonReader = new StringReader("{ xxx - yyy }"); @@ -1719,13 +1774,14 @@ try { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); JsonFormat.parser().merge(invalidJsonReader, builder); - fail("Exception is expected."); + assertWithMessage("Exception is expected.").fail(); } catch (InvalidProtocolBufferException e) { // Expected. } } // Test that an error is thrown if a nested JsonObject is parsed as a primitive field. + @Test public void testJsonObjectForPrimitiveField() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); try { @@ -1741,6 +1797,7 @@ } } + @Test public void testSortedMapKeys() throws Exception { TestMap.Builder mapBuilder = TestMap.newBuilder(); mapBuilder.putStringToInt32Map("\ud834\udd20", 3); // utf-8 F0 9D 84 A0 @@ -1759,43 +1816,45 @@ mapBuilder.putInt32ToInt32Map(2, 2); mapBuilder.putInt32ToInt32Map(-3, -3); TestMap mapMessage = mapBuilder.build(); - assertEquals( - "{\n" - + " \"int32ToInt32Map\": {\n" - + " \"-3\": -3,\n" - + " \"1\": 1,\n" - + " \"2\": 2,\n" - + " \"3\": 3,\n" - + " \"4\": 4,\n" - + " \"5\": 5,\n" - + " \"10\": 10\n" - + " },\n" - + " \"stringToInt32Map\": {\n" - + " \"19\": 19,\n" - + " \"8\": 8,\n" - + " \"abc\": 20,\n" - + " \"foo\": 99,\n" - + " \"xxx\": 123,\n" - + " \"\u20ac\": 1,\n" - + " \"\ufb00\": 2,\n" - + " \"\ud834\udd20\": 3\n" - + " }\n" - + "}", - toSortedJsonString(mapMessage)); + assertThat(toSortedJsonString(mapMessage)) + .isEqualTo( + "{\n" + + " \"int32ToInt32Map\": {\n" + + " \"-3\": -3,\n" + + " \"1\": 1,\n" + + " \"2\": 2,\n" + + " \"3\": 3,\n" + + " \"4\": 4,\n" + + " \"5\": 5,\n" + + " \"10\": 10\n" + + " },\n" + + " \"stringToInt32Map\": {\n" + + " \"19\": 19,\n" + + " \"8\": 8,\n" + + " \"abc\": 20,\n" + + " \"foo\": 99,\n" + + " \"xxx\": 123,\n" + + " \"\u20ac\": 1,\n" + + " \"\ufb00\": 2,\n" + + " \"\ud834\udd20\": 3\n" + + " }\n" + + "}"); TestMap emptyMap = TestMap.getDefaultInstance(); - assertEquals("{\n}", toSortedJsonString(emptyMap)); + assertThat(toSortedJsonString(emptyMap)).isEqualTo("{\n}"); } + @Test public void testPrintingEnumsAsIntsChainedAfterIncludingDefaultValueFields() throws Exception { TestAllTypes message = TestAllTypes.newBuilder().setOptionalBool(false).build(); - assertEquals( - "{\n" + " \"optionalBool\": false\n" + "}", - JsonFormat.printer() - .includingDefaultValueFields( - ImmutableSet.of(message.getDescriptorForType().findFieldByName("optional_bool"))) - .printingEnumsAsInts() - .print(message)); + assertThat( + JsonFormat.printer() + .includingDefaultValueFields( + ImmutableSet.of( + message.getDescriptorForType().findFieldByName("optional_bool"))) + .printingEnumsAsInts() + .print(message)) + .isEqualTo("{\n" + " \"optionalBool\": false\n" + "}"); } }
diff --git a/java/util/src/test/java/com/google/protobuf/util/StructsTest.java b/java/util/src/test/java/com/google/protobuf/util/StructsTest.java index 265aff5..9eb4cc6 100644 --- a/java/util/src/test/java/com/google/protobuf/util/StructsTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/StructsTest.java
@@ -33,22 +33,28 @@ import static com.google.common.truth.Truth.assertThat; import com.google.protobuf.Struct; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -public final class StructsTest extends TestCase { +@RunWith(JUnit4.class) +public final class StructsTest { + @Test public void test1pair_constructsObject() throws Exception { Struct.Builder expected = Struct.newBuilder(); JsonFormat.parser().merge("{\"k1\": 1}", expected); assertThat(Structs.of("k1", Values.of(1))).isEqualTo(expected.build()); } + @Test public void test2pair_constructsObject() throws Exception { Struct.Builder expected = Struct.newBuilder(); JsonFormat.parser().merge("{\"k1\": 1, \"k2\": 2}", expected); assertThat(Structs.of("k1", Values.of(1), "k2", Values.of(2))).isEqualTo(expected.build()); } + @Test public void test3pair_constructsObject() throws Exception { Struct.Builder expected = Struct.newBuilder(); JsonFormat.parser().merge("{\"k1\": 1, \"k2\": 2, \"k3\": 3}", expected);
diff --git a/java/util/src/test/java/com/google/protobuf/util/ValuesTest.java b/java/util/src/test/java/com/google/protobuf/util/ValuesTest.java index d646e97..9e172c8 100644 --- a/java/util/src/test/java/com/google/protobuf/util/ValuesTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/ValuesTest.java
@@ -38,19 +38,25 @@ import com.google.protobuf.Value; import java.util.ArrayList; import java.util.List; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -public final class ValuesTest extends TestCase { +@RunWith(JUnit4.class) +public final class ValuesTest { + @Test public void testOfNull_IsNullValue() throws Exception { assertThat(Values.ofNull()) .isEqualTo(Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build()); } + @Test public void testOfBoolean_ConstructsValue() { assertThat(Values.of(true)).isEqualTo(Value.newBuilder().setBoolValue(true).build()); assertThat(Values.of(false)).isEqualTo(Value.newBuilder().setBoolValue(false).build()); } + @Test public void testOfNumeric_ConstructsValue() { assertThat(Values.of(100)).isEqualTo(Value.newBuilder().setNumberValue(100).build()); assertThat(Values.of(1000L)).isEqualTo(Value.newBuilder().setNumberValue(1000).build()); @@ -58,11 +64,13 @@ assertThat(Values.of(10000.23)).isEqualTo(Value.newBuilder().setNumberValue(10000.23).build()); } + @Test public void testOfString_ConstructsValue() { assertThat(Values.of("")).isEqualTo(Value.newBuilder().setStringValue("").build()); assertThat(Values.of("foo")).isEqualTo(Value.newBuilder().setStringValue("foo").build()); } + @Test public void testOfStruct_ConstructsValue() { Struct.Builder builder = Struct.newBuilder(); builder.putFields("a", Values.of("a")); @@ -72,6 +80,7 @@ .isEqualTo(Value.newBuilder().setStructValue(builder.build()).build()); } + @Test public void testOfListValue_ConstructsInstance() { ListValue.Builder builder = ListValue.newBuilder(); builder.addValues(Values.of(1)); @@ -81,6 +90,7 @@ .isEqualTo(Value.newBuilder().setListValue(builder.build()).build()); } + @Test public void testOfIterable_ReturnsTheValue() { ListValue.Builder builder = ListValue.newBuilder(); builder.addValues(Values.of(1));
diff --git a/python/google/protobuf/internal/api_implementation.py b/python/google/protobuf/internal/api_implementation.py index be1af7d..a366731 100644 --- a/python/google/protobuf/internal/api_implementation.py +++ b/python/google/protobuf/internal/api_implementation.py
@@ -80,8 +80,7 @@ # and Python 3 default to `_api_version = 2` (C++ implementation V2). pass -_default_implementation_type = ( - 'python' if _api_version <= 0 else 'cpp') +_default_implementation_type = ('python' if _api_version <= 0 else 'cpp') # This environment variable can be used to switch to a certain implementation # of the Python API, overriding the compile-time constants in the
diff --git a/python/google/protobuf/internal/more_extensions.proto b/python/google/protobuf/internal/more_extensions.proto index 5038fd2..5340a70 100644 --- a/python/google/protobuf/internal/more_extensions.proto +++ b/python/google/protobuf/internal/more_extensions.proto
@@ -34,11 +34,14 @@ package google.protobuf.internal; - message TopLevelMessage { - optional ExtendedMessage submessage = 1; + optional ExtendedMessage submessage = 1 [lazy = true]; + optional NestedMessage nested_message = 2 [lazy = true]; } +message NestedMessage { + optional ExtendedMessage submessage = 1 [lazy = true]; +} message ExtendedMessage { optional int32 optional_int32 = 1001; @@ -46,12 +49,10 @@ extensions 1 to 999; } - message ForeignMessage { optional int32 foreign_message_int = 1; } - extend ExtendedMessage { optional int32 optional_int_extension = 1; optional ForeignMessage optional_message_extension = 2;
diff --git a/python/google/protobuf/internal/proto_builder_test.py b/python/google/protobuf/internal/proto_builder_test.py index 3ee14e4..d7d63c8 100755 --- a/python/google/protobuf/internal/proto_builder_test.py +++ b/python/google/protobuf/internal/proto_builder_test.py
@@ -32,16 +32,13 @@ """Tests for google.protobuf.proto_builder.""" -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict #PY26 +import collections try: import unittest2 as unittest except ImportError: import unittest -from google.protobuf import descriptor_pb2 +from google.protobuf import descriptor_pb2 # pylint: disable=g-import-not-at-top from google.protobuf import descriptor from google.protobuf import descriptor_pool from google.protobuf import proto_builder @@ -51,7 +48,7 @@ class ProtoBuilderTest(unittest.TestCase): def setUp(self): - self.ordered_fields = OrderedDict([ + self.ordered_fields = collections.OrderedDict([ ('foo', descriptor_pb2.FieldDescriptorProto.TYPE_INT64), ('bar', descriptor_pb2.FieldDescriptorProto.TYPE_STRING), ])
diff --git a/python/google/protobuf/proto_api.h b/python/google/protobuf/proto_api.h index c869bce..2e2156a 100644 --- a/python/google/protobuf/proto_api.h +++ b/python/google/protobuf/proto_api.h
@@ -78,6 +78,18 @@ // With the current implementation, only empty messages are in this case. virtual Message* GetMutableMessagePointer(PyObject* msg) const = 0; + // If the passed object is a Python Message Descriptor, returns its internal + // pointer. + // Otherwise, returns NULL with an exception set. + virtual const Descriptor* MessageDescriptor_AsDescriptor( + PyObject* desc) const = 0; + + // If the passed object is a Python Enum Descriptor, returns its internal + // pointer. + // Otherwise, returns NULL with an exception set. + virtual const EnumDescriptor* EnumDescriptor_AsDescriptor( + PyObject* enum_desc) const = 0; + // Expose the underlying DescriptorPool and MessageFactory to enable C++ code // to create Python-compatible message. virtual const DescriptorPool* GetDefaultDescriptorPool() const = 0; @@ -108,6 +120,15 @@ // python objects referencing the same C++ object. virtual PyObject* NewMessageOwnedExternally( Message* msg, PyObject* py_message_factory) const = 0; + + // Returns a new reference for the given DescriptorPool. + // The returned object does not manage the C++ DescriptorPool: it is the + // responsibility of the caller to keep it alive. + // As long as the returned Python DescriptorPool object is kept alive, + // functions that process C++ descriptors or messages created from this pool + // can work and return their Python counterparts. + virtual PyObject* DescriptorPool_FromPool( + const google::protobuf::DescriptorPool* pool) const = 0; }; inline const char* PyProtoAPICapsuleName() {
diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc index b607956..7154d31 100644 --- a/python/google/protobuf/pyext/descriptor_pool.cc +++ b/python/google/protobuf/pyext/descriptor_pool.cc
@@ -111,6 +111,8 @@ cpool->error_collector = nullptr; cpool->underlay = NULL; cpool->database = NULL; + cpool->is_owned = false; + cpool->is_mutable = false; cpool->descriptor_options = new std::unordered_map<const void*, PyObject*>(); @@ -138,6 +140,8 @@ return NULL; } cpool->pool = new DescriptorPool(underlay); + cpool->is_owned = true; + cpool->is_mutable = true; cpool->underlay = underlay; if (!descriptor_pool_map->insert( @@ -159,10 +163,13 @@ if (database != NULL) { cpool->error_collector = new BuildFileErrorCollector(); cpool->pool = new DescriptorPool(database, cpool->error_collector); + cpool->is_mutable = false; cpool->database = database; } else { cpool->pool = new DescriptorPool(); + cpool->is_mutable = true; } + cpool->is_owned = true; if (!descriptor_pool_map->insert(std::make_pair(cpool->pool, cpool)).second) { // Should never happen -- would indicate an internal error / bug. @@ -201,7 +208,9 @@ } delete self->descriptor_options; delete self->database; - delete self->pool; + if (self->is_owned) { + delete self->pool; + } delete self->error_collector; Py_TYPE(self)->tp_free(pself); } @@ -582,6 +591,12 @@ "Add your file to the underlying database."); return NULL; } + if (!self->is_mutable) { + PyErr_SetString( + PyExc_ValueError, + "This DescriptorPool is not mutable and cannot add new definitions."); + return nullptr; + } if (PyBytes_AsStringAndSize(serialized_pb, &message_type, &message_len) < 0) { return NULL; @@ -606,8 +621,9 @@ BuildFileErrorCollector error_collector; const FileDescriptor* descriptor = - self->pool->BuildFileCollectingErrors(file_proto, - &error_collector); + // Pool is mutable, we can remove the "const". + const_cast<DescriptorPool*>(self->pool) + ->BuildFileCollectingErrors(file_proto, &error_collector); if (descriptor == NULL) { PyErr_Format(PyExc_TypeError, "Couldn't build proto file into descriptor pool!\n%s", @@ -615,6 +631,7 @@ return NULL; } + return PyFileDescriptor_FromDescriptorWithSerializedPb( descriptor, serialized_pb); } @@ -768,6 +785,33 @@ return it->second; } +PyObject* PyDescriptorPool_FromPool(const DescriptorPool* pool) { + PyDescriptorPool* existing_pool = GetDescriptorPool_FromPool(pool); + if (existing_pool != nullptr) { + Py_INCREF(existing_pool); + return reinterpret_cast<PyObject*>(existing_pool); + } else { + PyErr_Clear(); + } + + PyDescriptorPool* cpool = cdescriptor_pool::_CreateDescriptorPool(); + if (cpool == nullptr) { + return nullptr; + } + cpool->pool = const_cast<DescriptorPool*>(pool); + cpool->is_owned = false; + cpool->is_mutable = false; + cpool->underlay = nullptr; + + if (!descriptor_pool_map->insert(std::make_pair(cpool->pool, cpool)).second) { + // Should never happen -- We already checked the existence above. + PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered"); + return nullptr; + } + + return reinterpret_cast<PyObject*>(cpool); +} + } // namespace python } // namespace protobuf } // namespace google
diff --git a/python/google/protobuf/pyext/descriptor_pool.h b/python/google/protobuf/pyext/descriptor_pool.h index 2d456f9..48658d3 100644 --- a/python/google/protobuf/pyext/descriptor_pool.h +++ b/python/google/protobuf/pyext/descriptor_pool.h
@@ -54,10 +54,18 @@ // "Methods" that interacts with this DescriptorPool are in the cdescriptor_pool // namespace. typedef struct PyDescriptorPool { - PyObject_HEAD + PyObject_HEAD; // The C++ pool containing Descriptors. - DescriptorPool* pool; + const DescriptorPool* pool; + + // True if we should free the pointer above. + bool is_owned; + + // True if this pool accepts new proto definitions. + // In this case it is allowed to const_cast<DescriptorPool*>(pool). + bool is_mutable; + // The error collector to store error info. Can be NULL. This pointer is // owned. @@ -116,16 +124,20 @@ } // namespace cdescriptor_pool -// Retrieve the global descriptor pool owned by the _message module. +// Retrieves the global descriptor pool owned by the _message module. // This is the one used by pb2.py generated modules. // Returns a *borrowed* reference. // "Default" pool used to register messages from _pb2.py modules. PyDescriptorPool* GetDefaultDescriptorPool(); -// Retrieve the python descriptor pool owning a C++ descriptor pool. +// Retrieves an existing python descriptor pool owning the C++ descriptor pool. // Returns a *borrowed* reference. PyDescriptorPool* GetDescriptorPool_FromPool(const DescriptorPool* pool); +// Wraps a C++ descriptor pool in a Python object, creates it if necessary. +// Returns a new reference. +PyObject* PyDescriptorPool_FromPool(const DescriptorPool* pool); + // Initialize objects used by this module. bool InitDescriptorPool();
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index 125df32..34816ee 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc
@@ -110,6 +110,10 @@ const std::vector<const FieldDescriptor*>& fields) { lhs->GetReflection()->UnsafeShallowSwapFields(lhs, rhs, fields); } + static bool IsLazyField(const Reflection* reflection, + const FieldDescriptor* field) { + return reflection->IsLazyField(field); + } }; static PyObject* kDESCRIPTOR; @@ -482,6 +486,18 @@ } // namespace message_meta +// Protobuf has a 64MB limit built in, this variable will override this. Please +// do not enable this unless you fully understand the implications: protobufs +// must all be kept in memory at the same time, so if they grow too big you may +// get OOM errors. The protobuf APIs do not provide any tools for processing +// protobufs in chunks. If you have protos this big you should break them up if +// it is at all convenient to do so. +#ifdef PROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS +static bool allow_oversize_protos = true; +#else +static bool allow_oversize_protos = false; +#endif + static PyTypeObject _CMessageClass_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME ".MessageMeta", // tp_name @@ -877,6 +893,7 @@ if (!self->composite_fields) { return 0; } + PyMessageFactory* factory = GetFactoryForMessage(self); for (const auto& item : *self->composite_fields) { const FieldDescriptor* descriptor = item.first; if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && @@ -890,8 +907,8 @@ if (reflection->HasField(*message, descriptor)) { // Message used to be read_only, but is no longer. Get the new pointer // and record it. - Message* mutable_message = - reflection->MutableMessage(message, descriptor, nullptr); + Message* mutable_message = reflection->MutableMessage( + message, descriptor, factory->message_factory); cmsg->message = mutable_message; cmsg->read_only = false; if (FixupMessageAfterMerge(cmsg) < 0) { @@ -1052,6 +1069,9 @@ } } + Arena* arena = Arena::InternalHelper<Message>::GetArenaForAllocation(message); + GOOGLE_DCHECK_EQ(arena, nullptr) + << "python protobuf is expected to be allocated from heap"; // Remove items, starting from the end. for (; length > to; length--) { if (field_descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { @@ -1060,7 +1080,18 @@ } // It seems that RemoveLast() is less efficient for sub-messages, and // the memory is not completely released. Prefer ReleaseLast(). - Message* sub_message = reflection->ReleaseLast(message, field_descriptor); + // + // To work around a debug hardening (PROTOBUF_FORCE_COPY_IN_RELEASE), + // explicitly use UnsafeArenaReleaseLast. To not break rare use cases where + // arena is used, we fallback to ReleaseLast (but GOOGLE_DCHECK to find/fix it). + // + // Note that arena is likely null and GOOGLE_DCHECK and ReleaesLast might be + // redundant. The current approach takes extra cautious path not to disrupt + // production. + Message* sub_message = + (arena == nullptr) + ? reflection->UnsafeArenaReleaseLast(message, field_descriptor) + : reflection->ReleaseLast(message, field_descriptor); // If there is a live weak reference to an item being removed, we "Release" // it, and it takes ownership of the message. if (CMessage* released = self->MaybeReleaseSubMessage(sub_message)) { @@ -1914,18 +1945,6 @@ Py_RETURN_NONE; } -// Protobuf has a 64MB limit built in, this variable will override this. Please -// do not enable this unless you fully understand the implications: protobufs -// must all be kept in memory at the same time, so if they grow too big you may -// get OOM errors. The protobuf APIs do not provide any tools for processing -// protobufs in chunks. If you have protos this big you should break them up if -// it is at all convenient to do so. -#ifdef PROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS -static bool allow_oversize_protos = true; -#else -static bool allow_oversize_protos = false; -#endif - // Provide a method in the module to set allow_oversize_protos to a boolean // value. This method returns the newly value of allow_oversize_protos. PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg) { @@ -2267,8 +2286,6 @@ CMessage* self, const FieldDescriptor* field_descriptor) { const Reflection* reflection = self->message->GetReflection(); PyMessageFactory* factory = GetFactoryForMessage(self); - const Message& sub_message = reflection->GetMessage( - *self->message, field_descriptor, factory->message_factory); CMessageClass* message_class = message_factory::GetOrCreateMessageClass( factory, field_descriptor->message_type()); @@ -2286,7 +2303,20 @@ Py_INCREF(self); cmsg->parent = self; cmsg->parent_field_descriptor = field_descriptor; - cmsg->read_only = !reflection->HasField(*self->message, field_descriptor); + if (reflection->HasField(*self->message, field_descriptor)) { + // Force triggering MutableMessage to set the lazy message 'Dirty' + if (MessageReflectionFriend::IsLazyField(reflection, field_descriptor)) { + Message* sub_message = reflection->MutableMessage( + self->message, field_descriptor, factory->message_factory); + cmsg->read_only = false; + cmsg->message = sub_message; + return cmsg; + } + } else { + cmsg->read_only = true; + } + const Message& sub_message = reflection->GetMessage( + *self->message, field_descriptor, factory->message_factory); cmsg->message = const_cast<Message*>(&sub_message); return cmsg; } @@ -2869,20 +2899,36 @@ return cmsg->message; } -PyObject* PyMessage_New(const Descriptor* descriptor, - PyObject* py_message_factory) { +// Returns a new reference to the MessageClass to use for message creation. +// - if a PyMessageFactory is passed, use it. +// - Otherwise, if a PyDescriptorPool was created, use its factory. +static CMessageClass* GetMessageClassFromDescriptor( + const Descriptor* descriptor, PyObject* py_message_factory) { PyMessageFactory* factory = nullptr; if (py_message_factory == nullptr) { - factory = GetDescriptorPool_FromPool(descriptor->file()->pool()) - ->py_message_factory; + PyDescriptorPool* pool = + GetDescriptorPool_FromPool(descriptor->file()->pool()); + if (pool == nullptr) { + PyErr_SetString(PyExc_TypeError, + "Unknown descriptor pool; C++ users should call " + "DescriptorPool_FromPool and keep it alive"); + return nullptr; + } + factory = pool->py_message_factory; } else if (PyObject_TypeCheck(py_message_factory, &PyMessageFactory_Type)) { factory = reinterpret_cast<PyMessageFactory*>(py_message_factory); } else { PyErr_SetString(PyExc_TypeError, "Expected a MessageFactory"); return nullptr; } - auto* message_class = - message_factory::GetOrCreateMessageClass(factory, descriptor); + + return message_factory::GetOrCreateMessageClass(factory, descriptor); +} + +PyObject* PyMessage_New(const Descriptor* descriptor, + PyObject* py_message_factory) { + CMessageClass* message_class = + GetMessageClassFromDescriptor(descriptor, py_message_factory); if (message_class == nullptr) { return nullptr; } @@ -2897,20 +2943,8 @@ PyObject* PyMessage_NewMessageOwnedExternally(Message* message, PyObject* py_message_factory) { - if (py_message_factory) { - PyErr_SetString(PyExc_NotImplementedError, - "Default message_factory=NULL is the only supported value"); - return nullptr; - } - if (message->GetReflection()->GetMessageFactory() != - MessageFactory::generated_factory()) { - PyErr_SetString(PyExc_TypeError, - "Message pointer was not created from the default factory"); - return nullptr; - } - - CMessageClass* message_class = message_factory::GetOrCreateMessageClass( - GetDefaultDescriptorPool()->py_message_factory, message->GetDescriptor()); + CMessageClass* message_class = GetMessageClassFromDescriptor( + message->GetDescriptor(), py_message_factory); if (message_class == nullptr) { return nullptr; }
diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc index b5975f7..4125dd7 100644 --- a/python/google/protobuf/pyext/message_module.cc +++ b/python/google/protobuf/pyext/message_module.cc
@@ -31,6 +31,7 @@ #include <Python.h> #include <google/protobuf/message_lite.h> +#include <google/protobuf/pyext/descriptor.h> #include <google/protobuf/pyext/descriptor_pool.h> #include <google/protobuf/pyext/message.h> #include <google/protobuf/pyext/message_factory.h> @@ -46,6 +47,15 @@ google::protobuf::Message* GetMutableMessagePointer(PyObject* msg) const override { return google::protobuf::python::PyMessage_GetMutableMessagePointer(msg); } + const google::protobuf::Descriptor* MessageDescriptor_AsDescriptor( + PyObject* desc) const override { + return google::protobuf::python::PyMessageDescriptor_AsDescriptor(desc); + } + const google::protobuf::EnumDescriptor* EnumDescriptor_AsDescriptor( + PyObject* enum_desc) const override { + return google::protobuf::python::PyEnumDescriptor_AsDescriptor(enum_desc); + } + const google::protobuf::DescriptorPool* GetDefaultDescriptorPool() const override { return google::protobuf::python::GetDefaultDescriptorPool()->pool; } @@ -63,6 +73,10 @@ return google::protobuf::python::PyMessage_NewMessageOwnedExternally( msg, py_message_factory); } + PyObject* DescriptorPool_FromPool( + const google::protobuf::DescriptorPool* pool) const override { + return google::protobuf::python::PyDescriptorPool_FromPool(pool); + } }; } // namespace
diff --git a/src/Makefile.am b/src/Makefile.am index edd3660..0129741 100644 --- a/src/Makefile.am +++ b/src/Makefile.am
@@ -107,6 +107,7 @@ google/protobuf/generated_message_util.h \ google/protobuf/has_bits.h \ google/protobuf/implicit_weak_message.h \ + google/protobuf/inlined_string_field.h \ google/protobuf/io/io_win32.h \ google/protobuf/map_entry.h \ google/protobuf/map_entry_lite.h \ @@ -128,6 +129,7 @@ google/protobuf/repeated_field.h \ google/protobuf/service.h \ google/protobuf/source_context.pb.h \ + google/protobuf/string_member_robber.h \ google/protobuf/struct.pb.h \ google/protobuf/text_format.h \ google/protobuf/timestamp.pb.h \ @@ -212,6 +214,7 @@ google/protobuf/generated_message_table_driven_lite.h \ google/protobuf/generated_message_table_driven_lite.cc \ google/protobuf/implicit_weak_message.cc \ + google/protobuf/inlined_string_field.cc \ google/protobuf/map.cc \ google/protobuf/message_lite.cc \ google/protobuf/parse_context.cc \ @@ -703,6 +706,8 @@ google/protobuf/map_test_util.inc \ google/protobuf/map_test_util.h \ google/protobuf/map_test_util_impl.h \ + google/protobuf/reflection_tester.cc \ + google/protobuf/reflection_tester.h \ google/protobuf/test_util.cc \ google/protobuf/test_util.h \ google/protobuf/test_util.inc \ @@ -754,6 +759,7 @@ google/protobuf/dynamic_message_unittest.cc \ google/protobuf/extension_set_unittest.cc \ google/protobuf/generated_message_reflection_unittest.cc \ + google/protobuf/inlined_string_field_unittest.cc \ google/protobuf/map_field_test.cc \ google/protobuf/map_test.cc \ google/protobuf/message_unittest.cc \ @@ -771,6 +777,7 @@ google/protobuf/unknown_field_set_unittest.cc \ google/protobuf/well_known_types_unittest.cc \ google/protobuf/wire_format_unittest.cc \ + google/protobuf/wire_format_unittest.inc \ google/protobuf/io/coded_stream_unittest.cc \ google/protobuf/io/printer_unittest.cc \ google/protobuf/io/tokenizer_unittest.cc \
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index e371a67..7fc1219 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc
@@ -42,11 +42,12 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Any, type_url_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Any, value_), }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(PROTOBUF_NAMESPACE_ID::Any)}, + { 0, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Any)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -175,7 +176,8 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Any.type_url")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // bytes value = 2; case 2: @@ -183,28 +185,29 @@ auto str = _internal_mutable_value(); ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -260,13 +263,7 @@ this->_internal_value()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Any::_class_data_ = { @@ -275,8 +272,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Any::GetClassData() const { return &_class_data_; } -void Any::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Any::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Any *>(to)->MergeFrom( static_cast<const Any &>(from)); } @@ -310,16 +307,18 @@ void Any::InternalSwap(Any* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &type_url_, GetArenaForAllocation(), - &other->type_url_, other->GetArenaForAllocation() + &type_url_, lhs_arena, + &other->type_url_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &value_, GetArenaForAllocation(), - &other->value_, other->GetArenaForAllocation() + &value_, lhs_arena, + &other->value_, rhs_arena ); }
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index 158da76..f727663 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h
@@ -175,7 +175,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Any& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final;
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index b2e14d1..8d45b60 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc
@@ -79,6 +79,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Api, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Api, methods_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Api, options_), @@ -91,6 +92,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Method, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Method, request_type_url_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Method, request_streaming_), @@ -103,13 +105,14 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Mixin, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Mixin, root_), }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(PROTOBUF_NAMESPACE_ID::Api)}, - { 12, -1, sizeof(PROTOBUF_NAMESPACE_ID::Method)}, - { 24, -1, sizeof(PROTOBUF_NAMESPACE_ID::Mixin)}, + { 0, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Api)}, + { 13, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Method)}, + { 26, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Mixin)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -280,7 +283,8 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.name")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.Method methods = 2; case 2: @@ -292,7 +296,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.Option options = 3; case 3: @@ -304,7 +309,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // string version = 4; case 4: @@ -313,14 +319,16 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.version")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // .google.protobuf.SourceContext source_context = 5; case 5: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { ptr = ctx->ParseMessage(_internal_mutable_source_context(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.Mixin mixins = 6; case 6: @@ -332,7 +340,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // .google.protobuf.Syntax syntax = 7; case 7: @@ -340,28 +349,29 @@ ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); _internal_set_syntax(static_cast<PROTOBUF_NAMESPACE_ID::Syntax>(val)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -494,13 +504,7 @@ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Api::_class_data_ = { @@ -509,8 +513,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Api::GetClassData() const { return &_class_data_; } -void Api::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Api::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Api *>(to)->MergeFrom( static_cast<const Api &>(from)); } @@ -553,19 +557,21 @@ void Api::InternalSwap(Api* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); methods_.InternalSwap(&other->methods_); options_.InternalSwap(&other->options_); mixins_.InternalSwap(&other->mixins_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &version_, GetArenaForAllocation(), - &other->version_, other->GetArenaForAllocation() + &version_, lhs_arena, + &other->version_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(Api, syntax_) @@ -688,7 +694,8 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.name")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // string request_type_url = 2; case 2: @@ -697,14 +704,16 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.request_type_url")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // bool request_streaming = 3; case 3: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { request_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // string response_type_url = 4; case 4: @@ -713,14 +722,16 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.response_type_url")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // bool response_streaming = 5; case 5: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 40)) { response_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.Option options = 6; case 6: @@ -732,7 +743,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // .google.protobuf.Syntax syntax = 7; case 7: @@ -740,28 +752,29 @@ ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); _internal_set_syntax(static_cast<PROTOBUF_NAMESPACE_ID::Syntax>(val)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -888,13 +901,7 @@ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Method::_class_data_ = { @@ -903,8 +910,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Method::GetClassData() const { return &_class_data_; } -void Method::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Method::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Method *>(to)->MergeFrom( static_cast<const Method &>(from)); } @@ -951,22 +958,24 @@ void Method::InternalSwap(Method* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); options_.InternalSwap(&other->options_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &request_type_url_, GetArenaForAllocation(), - &other->request_type_url_, other->GetArenaForAllocation() + &request_type_url_, lhs_arena, + &other->request_type_url_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &response_type_url_, GetArenaForAllocation(), - &other->response_type_url_, other->GetArenaForAllocation() + &response_type_url_, lhs_arena, + &other->response_type_url_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(Method, syntax_) @@ -1065,7 +1074,8 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.name")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // string root = 2; case 2: @@ -1074,28 +1084,29 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.root")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1155,13 +1166,7 @@ this->_internal_root()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Mixin::_class_data_ = { @@ -1170,8 +1175,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Mixin::GetClassData() const { return &_class_data_; } -void Mixin::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Mixin::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Mixin *>(to)->MergeFrom( static_cast<const Mixin &>(from)); } @@ -1205,16 +1210,18 @@ void Mixin::InternalSwap(Mixin* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &root_, GetArenaForAllocation(), - &other->root_, other->GetArenaForAllocation() + &root_, lhs_arena, + &other->root_, rhs_arena ); }
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index 67e9d84..1708da8 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h
@@ -152,7 +152,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Api& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -403,7 +403,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Method& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -632,7 +632,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Mixin& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final;
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index bd9516b..c12bf2b 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc
@@ -136,14 +136,14 @@ SerialArena::AllocateAlignedWithCleanupFallback( size_t n, const AllocationPolicy* policy) { AllocateNewBlock(n + kCleanupSize, policy); - return AllocateAlignedWithCleanup(n, policy); + return AllocateFromExistingWithCleanupFallback(n); } PROTOBUF_NOINLINE void* SerialArena::AllocateAlignedFallback(size_t n, const AllocationPolicy* policy) { AllocateNewBlock(n, policy); - return AllocateAligned(n, policy); + return AllocateFromExisting(n); } void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy) { @@ -168,8 +168,8 @@ #endif // ADDRESS_SANITIZER } -uint64 SerialArena::SpaceUsed() const { - uint64 space_used = ptr_ - head_->Pointer(kBlockHeaderSize); +uint64_t SerialArena::SpaceUsed() const { + uint64_t space_used = ptr_ - head_->Pointer(kBlockHeaderSize); space_used += space_used_; // Remove the overhead of the SerialArena itself. space_used -= ThreadSafeArena::kSerialArenaSize; @@ -263,11 +263,11 @@ auto id = tc.next_lifecycle_id; // We increment lifecycle_id's by multiples of two so we can use bit 0 as // a tag. - constexpr uint64 kDelta = 2; - constexpr uint64 kInc = ThreadCache::kPerThreadIds * kDelta; + constexpr uint64_t kDelta = 2; + constexpr uint64_t kInc = ThreadCache::kPerThreadIds * kDelta; if (PROTOBUF_PREDICT_FALSE((id & (kInc - 1)) == 0)) { constexpr auto relaxed = std::memory_order_relaxed; - // On platforms that don't support uint64 atomics we can certainly not + // On platforms that don't support uint64_t atomics we can certainly not // afford to increment by large intervals and expect uniqueness due to // wrapping, hence we only add by 1. id = lifecycle_id_generator_.id.fetch_add(1, relaxed) * kInc; @@ -316,7 +316,7 @@ return mem; } -uint64 ThreadSafeArena::Reset() { +uint64_t ThreadSafeArena::Reset() { // Have to do this in a first pass, because some of the destructors might // refer to memory in other blocks. CleanupList(); @@ -406,18 +406,18 @@ ->AddCleanup(elem, cleanup, AllocPolicy()); } -uint64 ThreadSafeArena::SpaceAllocated() const { +uint64_t ThreadSafeArena::SpaceAllocated() const { SerialArena* serial = threads_.load(std::memory_order_acquire); - uint64 res = 0; + uint64_t res = 0; for (; serial; serial = serial->next()) { res += serial->SpaceAllocated(); } return res; } -uint64 ThreadSafeArena::SpaceUsed() const { +uint64_t ThreadSafeArena::SpaceUsed() const { SerialArena* serial = threads_.load(std::memory_order_acquire); - uint64 space_used = 0; + uint64_t space_used = 0; for (; serial; serial = serial->next()) { space_used += serial->SpaceUsed(); }
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 897a70f..305a511 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h
@@ -91,6 +91,7 @@ namespace internal { struct ArenaStringPtr; // defined in arenastring.h +class InlinedStringField; // defined in inlined_string_field.h class LazyField; // defined in lazy_field.h class EpsCopyInputStream; // defined in parse_context.h @@ -350,19 +351,19 @@ // policies. Do not use these in unit tests. // Returns the total space allocated by the arena, which is the sum of the // sizes of the underlying blocks. - uint64 SpaceAllocated() const { return impl_.SpaceAllocated(); } + uint64_t SpaceAllocated() const { return impl_.SpaceAllocated(); } // Returns the total space used by the arena. Similar to SpaceAllocated but // does not include free space and block overhead. The total space returned // may not include space used by other threads executing concurrently with // the call to this method. - uint64 SpaceUsed() const { return impl_.SpaceUsed(); } + uint64_t SpaceUsed() const { return impl_.SpaceUsed(); } // Frees all storage allocated by this arena after calling destructors // registered with OwnDestructor() and freeing objects registered with Own(). // Any objects allocated on this arena are unusable after this call. It also // returns the total space used by the arena which is the sums of the sizes // of the allocated blocks. This method is not thread-safe. - uint64 Reset() { return impl_.Reset(); } + uint64_t Reset() { return impl_.Reset(); } // Adds |object| to a list of heap-allocated objects to be freed with |delete| // when the arena is destroyed or reset. @@ -632,9 +633,11 @@ CreateInArenaStorageInternal(ptr, arena, typename is_arena_constructable<T>::type(), std::forward<Args>(args)...); - RegisterDestructorInternal( - ptr, arena, - typename InternalHelper<T>::is_destructor_skippable::type()); + if (arena != nullptr) { + RegisterDestructorInternal( + ptr, arena, + typename InternalHelper<T>::is_destructor_skippable::type()); + } } template <typename T, typename... Args> @@ -788,6 +791,7 @@ template <typename Type> friend class internal::GenericTypeHandler; friend struct internal::ArenaStringPtr; // For AllocateAligned. + friend class internal::InlinedStringField; // For AllocateAligned. friend class internal::LazyField; // For CreateMaybeMessage. friend class internal::EpsCopyInputStream; // For parser performance friend class MessageLite;
diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h index 40608df..781d19c 100644 --- a/src/google/protobuf/arena_impl.h +++ b/src/google/protobuf/arena_impl.h
@@ -66,11 +66,11 @@ // Invoked when the arena is about to be destroyed. This method will // typically finalize any metric collection and delete the collector. // space_allocated is the space used by the arena. - virtual void OnDestroy(uint64 space_allocated) = 0; + virtual void OnDestroy(uint64_t space_allocated) = 0; // OnReset() is called when the associated arena is reset. // space_allocated is the space used by the arena just before the reset. - virtual void OnReset(uint64 space_allocated) = 0; + virtual void OnReset(uint64_t space_allocated) = 0; // OnAlloc is called when an allocation happens. // type_info is promised to be static - its lifetime extends to @@ -79,7 +79,7 @@ // intentionally want to avoid monitoring an allocation. (i.e. internal // allocations for managing the arena) virtual void OnAlloc(const std::type_info* allocated_type, - uint64 alloc_size) = 0; + uint64_t alloc_size) = 0; // Does OnAlloc() need to be called? If false, metric collection overhead // will be reduced since we will not do extra work per allocation. @@ -141,10 +141,10 @@ Memory Free(Deallocator deallocator); void CleanupList(); - uint64 SpaceAllocated() const { + uint64_t SpaceAllocated() const { return space_allocated_.load(std::memory_order_relaxed); } - uint64 SpaceUsed() const; + uint64_t SpaceUsed() const; bool HasSpace(size_t n) { return n <= static_cast<size_t>(limit_ - ptr_); } @@ -154,6 +154,11 @@ if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) { return AllocateAlignedFallback(n, policy); } + return AllocateFromExisting(n); + } + + private: + void* AllocateFromExisting(size_t n) { void* ret = ptr_; ptr_ += n; #ifdef ADDRESS_SANITIZER @@ -162,17 +167,13 @@ return ret; } + public: // Allocate space if the current region provides enough space. bool MaybeAllocateAligned(size_t n, void** out) { GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. GOOGLE_DCHECK_GE(limit_, ptr_); if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) return false; - void* ret = ptr_; - ptr_ += n; -#ifdef ADDRESS_SANITIZER - ASAN_UNPOISON_MEMORY_REGION(ret, n); -#endif // ADDRESS_SANITIZER - *out = ret; + *out = AllocateFromExisting(n); return true; } @@ -181,6 +182,12 @@ if (PROTOBUF_PREDICT_FALSE(!HasSpace(n + kCleanupSize))) { return AllocateAlignedWithCleanupFallback(n, policy); } + return AllocateFromExistingWithCleanupFallback(n); + } + + private: + std::pair<void*, CleanupNode*> AllocateFromExistingWithCleanupFallback( + size_t n) { void* ret = ptr_; ptr_ += n; limit_ -= kCleanupSize; @@ -191,6 +198,7 @@ return CreatePair(ret, reinterpret_cast<CleanupNode*>(limit_)); } + public: void AddCleanup(void* elem, void (*cleanup)(void*), const AllocationPolicy* policy) { auto res = AllocateAlignedWithCleanup(0, policy); @@ -277,10 +285,10 @@ // if it was passed in. ~ThreadSafeArena(); - uint64 Reset(); + uint64_t Reset(); - uint64 SpaceAllocated() const; - uint64 SpaceUsed() const; + uint64_t SpaceAllocated() const; + uint64_t SpaceUsed() const; void* AllocateAligned(size_t n, const std::type_info* type) { SerialArena* arena; @@ -312,7 +320,7 @@ private: // Unique for each arena. Changes on Reset(). - uint64 tag_and_id_; + uint64_t tag_and_id_; // The LSB of tag_and_id_ indicates if allocs in this arena are recorded. enum { kRecordAllocs = 1 }; @@ -343,7 +351,7 @@ inline bool ShouldRecordAlloc() const { return tag_and_id_ & kRecordAllocs; } - inline uint64 LifeCycleId() const { + inline uint64_t LifeCycleId() const { return tag_and_id_ & (-kRecordAllocs - 1); } @@ -362,7 +370,7 @@ hint_.store(serial, std::memory_order_release); } - PROTOBUF_NDEBUG_INLINE bool GetSerialArenaFast(uint64 lifecycle_id, + PROTOBUF_NDEBUG_INLINE bool GetSerialArenaFast(uint64_t lifecycle_id, SerialArena** arena) { if (GetSerialArenaFromThreadCache(lifecycle_id, arena)) return true; if (lifecycle_id & kRecordAllocs) return false; @@ -379,7 +387,7 @@ } PROTOBUF_NDEBUG_INLINE bool GetSerialArenaFromThreadCache( - uint64 lifecycle_id, SerialArena** arena) { + uint64_t lifecycle_id, SerialArena** arena) { // If this thread already owns a block in this arena then try to use that. // This fast path optimizes the case where multiple threads allocate from // the same arena. @@ -427,10 +435,10 @@ 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; + uint64_t next_lifecycle_id; // The ThreadCache is considered valid as long as this matches the // lifecycle_id of the arena being used. - uint64 last_lifecycle_id_seen; + uint64_t last_lifecycle_id_seen; SerialArena* last_serial_arena; };
diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 03c3d8d..b6fbd1f 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc
@@ -169,13 +169,13 @@ TEST(ArenaTest, BasicCreate) { Arena arena; - EXPECT_TRUE(Arena::Create<int32>(&arena) != NULL); - EXPECT_TRUE(Arena::Create<int64>(&arena) != NULL); + EXPECT_TRUE(Arena::Create<int32_t>(&arena) != NULL); + EXPECT_TRUE(Arena::Create<int64_t>(&arena) != NULL); EXPECT_TRUE(Arena::Create<float>(&arena) != NULL); EXPECT_TRUE(Arena::Create<double>(&arena) != NULL); EXPECT_TRUE(Arena::Create<std::string>(&arena) != NULL); - arena.Own(new int32); - arena.Own(new int64); + arena.Own(new int32_t); + arena.Own(new int64_t); arena.Own(new float); arena.Own(new double); arena.Own(new std::string); @@ -622,7 +622,7 @@ TestAllTypes::NestedMessage* arena2_submessage = Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2); arena2_submessage->set_bb(42); -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT +#ifdef PROTOBUF_HAS_DEATH_TEST EXPECT_DEBUG_DEATH(arena1_message->set_allocated_optional_nested_message( arena2_submessage), "submessage_arena"); @@ -635,7 +635,7 @@ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1); arena1_submessage->set_bb(42); TestAllTypes* heap_message = new TestAllTypes; -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT +#ifdef PROTOBUF_HAS_DEATH_TEST EXPECT_DEBUG_DEATH( heap_message->set_allocated_optional_nested_message(arena1_submessage), "submessage_arena"); @@ -691,7 +691,7 @@ TestAllTypes::NestedMessage* arena2_submessage = Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2); arena2_submessage->set_bb(42); -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT +#ifdef PROTOBUF_HAS_DEATH_TEST EXPECT_DEBUG_DEATH( r->SetAllocatedMessage(arena1_message, arena2_submessage, msg_field), "GetOwningArena"); @@ -704,7 +704,7 @@ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1); arena1_submessage->set_bb(42); TestAllTypes* heap_message = new TestAllTypes; -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT +#ifdef PROTOBUF_HAS_DEATH_TEST EXPECT_DEBUG_DEATH( r->SetAllocatedMessage(heap_message, arena1_submessage, msg_field), "GetOwningArena"); @@ -803,7 +803,7 @@ TestAllTypes::NestedMessage* arena2_submessage = Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2); arena2_submessage->set_bb(42); -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT +#ifdef PROTOBUF_HAS_DEATH_TEST EXPECT_DEBUG_DEATH( arena1_message->mutable_repeated_nested_message()->AddAllocated( arena2_submessage), @@ -820,7 +820,7 @@ TestAllTypes::NestedMessage* arena2_submessage = Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2); arena2_submessage->set_bb(42); -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT +#ifdef PROTOBUF_HAS_DEATH_TEST EXPECT_DEBUG_DEATH( heap_message->mutable_repeated_nested_message()->AddAllocated( arena2_submessage), @@ -925,7 +925,7 @@ TestAllTypes::NestedMessage* arena2_submessage = Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2); arena2_submessage->set_bb(42); -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT +#ifdef PROTOBUF_HAS_DEATH_TEST EXPECT_DEBUG_DEATH( r->AddAllocatedMessage(arena1_message, fd, arena2_submessage), "value_arena"); @@ -941,7 +941,7 @@ TestAllTypes::NestedMessage* arena2_submessage = Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2); arena2_submessage->set_bb(42); -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT +#ifdef PROTOBUF_HAS_DEATH_TEST EXPECT_DEBUG_DEATH( r->AddAllocatedMessage(heap_message, fd, arena2_submessage), "value_arena"); @@ -1339,7 +1339,7 @@ } // Align n to next multiple of 8 -uint64 Align8(uint64 n) { return (n + 7) & -8; } +uint64_t Align8(uint64_t n) { return (n + 7) & -8; } TEST(ArenaTest, SpaceAllocated_and_Used) { Arena arena_1; @@ -1402,11 +1402,11 @@ opt.start_block_size = opt.max_block_size = i; Arena arena(opt); - *Arena::Create<int64>(&arena) = 42; + *Arena::Create<int64_t>(&arena) = 42; EXPECT_GE(arena.SpaceAllocated(), 8); EXPECT_EQ(8, arena.SpaceUsed()); - *Arena::Create<int64>(&arena) = 42; + *Arena::Create<int64_t>(&arena) = 42; EXPECT_GE(arena.SpaceAllocated(), 16); EXPECT_EQ(16, arena.SpaceUsed()); } @@ -1464,10 +1464,10 @@ } namespace { -uint32 hooks_num_init = 0; -uint32 hooks_num_allocations = 0; -uint32 hooks_num_reset = 0; -uint32 hooks_num_destruct = 0; +uint32_t hooks_num_init = 0; +uint32_t hooks_num_allocations = 0; +uint32_t hooks_num_reset = 0; +uint32_t hooks_num_destruct = 0; void ClearHookCounts() { hooks_num_init = 0; @@ -1502,13 +1502,13 @@ : ArenaMetricsCollector(record_allocs) { ++hooks_num_init; } - void OnDestroy(uint64 space_allocated) override { + void OnDestroy(uint64_t space_allocated) override { ++hooks_num_destruct; delete this; } - void OnReset(uint64 space_allocated) override { ++hooks_num_reset; } + void OnReset(uint64_t space_allocated) override { ++hooks_num_reset; } void OnAlloc(const std::type_info* allocated_type, - uint64 alloc_size) override { + uint64_t alloc_size) override { ++hooks_num_allocations; } }; @@ -1523,8 +1523,8 @@ Arena arena(options); EXPECT_EQ(1, hooks_num_init); EXPECT_EQ(0, hooks_num_allocations); - Arena::Create<uint64>(&arena); - if (std::is_trivially_destructible<uint64>::value) { + Arena::Create<uint64_t>(&arena); + if (std::is_trivially_destructible<uint64_t>::value) { EXPECT_EQ(1, hooks_num_allocations); } else { EXPECT_EQ(2, hooks_num_allocations); @@ -1544,7 +1544,7 @@ Arena arena(options); EXPECT_EQ(0, hooks_num_allocations); - Arena::Create<uint64>(&arena); + Arena::Create<uint64_t>(&arena); EXPECT_EQ(0, hooks_num_allocations); }
diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index 1fafa69..2477369 100644 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h
@@ -352,12 +352,15 @@ tagged_ptr_.Set(const_cast<std::string*>(value)); } +// Make sure rhs_arena allocated rhs, and lhs_arena allocated lhs. inline PROTOBUF_NDEBUG_INLINE void ArenaStringPtr::InternalSwap( // const std::string* default_value, // ArenaStringPtr* rhs, Arena* rhs_arena, // ArenaStringPtr* lhs, Arena* lhs_arena) { + // Silence unused variable warnings in release buildls. (void)default_value; - std::swap(lhs_arena, rhs_arena); + (void)rhs_arena; + (void)lhs_arena; std::swap(lhs->tagged_ptr_, rhs->tagged_ptr_); #ifdef PROTOBUF_FORCE_COPY_IN_SWAP auto force_realloc = [default_value](ArenaStringPtr* p, Arena* arena) { @@ -370,8 +373,10 @@ if (arena == nullptr) delete old_value; p->tagged_ptr_.Set(new_value); }; - force_realloc(lhs, lhs_arena); - force_realloc(rhs, rhs_arena); + // Because, at this point, tagged_ptr_ has been swapped, arena should also be + // swapped. + force_realloc(lhs, rhs_arena); + force_realloc(rhs, lhs_arena); #endif // PROTOBUF_FORCE_COPY_IN_SWAP }
diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index c8d9e49..2cbda27 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h
@@ -103,14 +103,15 @@ GeneratorContext* generator_context, std::string* error) const; - // Sync with plugin.proto. + // This must be kept in sync with plugin.proto. See that file for + // documentation on each value. enum Feature { FEATURE_PROTO3_OPTIONAL = 1, }; // Implement this to indicate what features this code generator supports. - // This should be a bitwise OR of features from the Features enum in - // plugin.proto. + // + // This must be a bitwise OR of values from the Feature enum above (or zero). virtual uint64_t GetSupportedFeatures() const { return 0; } // This is no longer used, but this class is part of the opensource protobuf
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc index 3792db8..670c37f 100644 --- a/src/google/protobuf/compiler/cpp/cpp_extension.cc +++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc
@@ -57,8 +57,9 @@ } // anonymous namespace ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, - const Options& options) - : descriptor_(descriptor), options_(options) { + const Options& options, + MessageSCCAnalyzer* scc_analyzer) + : descriptor_(descriptor), options_(options), scc_analyzer_(scc_analyzer) { // Construct type_traits_. if (descriptor_->is_repeated()) { type_traits_ = "Repeated"; @@ -179,6 +180,18 @@ " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n" " $scoped_name$($constant_name$, $1$);\n", default_str); + + // Register extension verify function if needed. + if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + ShouldVerify(descriptor_->message_type(), options_, scc_analyzer_) && + ShouldVerify(descriptor_->containing_type(), options_, scc_analyzer_)) { + format( + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY " + "::$proto_ns$::internal::RegisterExtensionVerify< $extendee$,\n" + " $1$, $number$> $2$_$name$_register;\n", + ClassName(descriptor_->message_type(), true), + IsScoped() ? ClassName(descriptor_->extension_scope(), false) : ""); + } } } // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.h b/src/google/protobuf/compiler/cpp/cpp_extension.h index 72413f6..bcc8018 100644 --- a/src/google/protobuf/compiler/cpp/cpp_extension.h +++ b/src/google/protobuf/compiler/cpp/cpp_extension.h
@@ -55,6 +55,8 @@ namespace compiler { namespace cpp { +class MessageSCCAnalyzer; + // Generates code for an extension, which may be within the scope of some // message or may be at file scope. This is much simpler than FieldGenerator // since extensions are just simple identifiers with interesting types. @@ -62,7 +64,8 @@ public: // See generator.cc for the meaning of dllexport_decl. explicit ExtensionGenerator(const FieldDescriptor* descriptor, - const Options& options); + const Options& options, + MessageSCCAnalyzer* scc_analyzer); ~ExtensionGenerator(); // Header stuff. @@ -77,6 +80,7 @@ const FieldDescriptor* descriptor_; std::string type_traits_; Options options_; + MessageSCCAnalyzer* scc_analyzer_; std::map<std::string, std::string> variables_;
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc index 82247ff..48ae290 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_field.cc
@@ -61,37 +61,39 @@ namespace { -std::string GenerateAnnotation(StringPiece substitute_template_prefix, - StringPiece prepared_template, - StringPiece substitute_template_suffix, - int field_index, StringPiece lambda_args, - StringPiece access_type) { - return strings::Substitute( - StrCat(substitute_template_prefix, prepared_template, - substitute_template_suffix), - field_index, access_type, lambda_args); +void MaySetAnnotationVariable(const Options& options, + StringPiece annotation_name, + StringPiece substitute_template_prefix, + StringPiece prepared_template, + int field_index, StringPiece access_type, + std::map<std::string, std::string>* variables) { + if (options.field_listener_options.forbidden_field_listener_events.count( + std::string(annotation_name))) + return; + (*variables)[StrCat("annotate_", annotation_name)] = strings::Substitute( + StrCat(substitute_template_prefix, prepared_template, ");\n"), + field_index, access_type); } std::string GenerateTemplateForOneofString(const FieldDescriptor* descriptor, StringPiece proto_ns, StringPiece field_member) { + std::string field_name = google::protobuf::compiler::cpp::FieldName(descriptor); std::string field_pointer = descriptor->options().ctype() == google::protobuf::FieldOptions::STRING ? "$0.GetPointer()" : "$0"; if (descriptor->default_value_string().empty()) { - return strings::Substitute( - StrCat("_internal_has_", - google::protobuf::compiler::cpp::FieldName(descriptor), - "()? _listener_->ExtractFieldInfo(", field_pointer, - "): ::", proto_ns, "::FieldAccessListener::AddressInfo()"), - field_member); + return strings::Substitute(StrCat("_internal_has_", field_name, "() ? ", + field_pointer, ": nullptr"), + field_member); } if (descriptor->options().ctype() == google::protobuf::FieldOptions::STRING_PIECE) { - return StrCat("_listener_->ExtractFieldInfo(_internal_", - google::protobuf::compiler::cpp::FieldName(descriptor), "())"); + return strings::Substitute(StrCat("_internal_has_", field_name, "() ? ", + field_pointer, ": nullptr"), + field_member); } std::string default_value_pointer = @@ -99,26 +101,24 @@ ? "&$1.get()" : "&$1"; return strings::Substitute( - StrCat("_listener_->ExtractFieldInfo(_internal_has_", - google::protobuf::compiler::cpp::FieldName(descriptor), "()? ", - field_pointer, " : ", default_value_pointer, ")"), + StrCat("_internal_has_", field_name, "() ? ", field_pointer, " : ", + default_value_pointer), field_member, MakeDefaultName(descriptor)); } std::string GenerateTemplateForSingleString(const FieldDescriptor* descriptor, StringPiece field_member) { if (descriptor->default_value_string().empty()) { - return strings::Substitute("_listener_->ExtractFieldInfo(&$0)", field_member); + return StrCat("&", field_member); } if (descriptor->options().ctype() == google::protobuf::FieldOptions::STRING) { return strings::Substitute( - "_listener_->ExtractFieldInfo($0.IsDefault(" - "nullptr) ? &$1.get() : $0.GetPointer())", - field_member, MakeDefaultName(descriptor)); + "$0.IsDefault(nullptr) ? &$1.get() : $0.GetPointer()", field_member, + MakeDefaultName(descriptor)); } - return strings::Substitute("_listener_->ExtractFieldInfo(&$0)", field_member); + return StrCat("&", field_member); } } // namespace @@ -143,7 +143,7 @@ " ", FieldName(descriptor), "_AccessedNoStrip = true;\n"); } } - if (!options.inject_field_listener_events) { + if (!options.field_listener_options.inject_field_listener_events) { return; } if (descriptor->file()->options().optimize_for() == @@ -157,50 +157,29 @@ field_member = StrCat(oneof_member->name(), "_.", field_member); } const std::string proto_ns = (*variables)["proto_ns"]; - std::string lambda_args = "_listener_, this"; - std::string lambda_flat_args = "_listener_, this"; - const std::string substitute_template_prefix = StrCat( - " {\n" - " auto _listener_ = ::", - proto_ns, - "::FieldAccessListener::GetListener();\n" - " if (_listener_) _listener_->OnFieldAccess([$2] { return "); - const std::string substitute_template_suffix = StrCat( - "; }, " - "GetDescriptor()->field($0), " - "::", - proto_ns, - "::FieldAccessListener::FieldAccessType::$1);\n" - " }\n"); + const std::string substitute_template_prefix = " _tracker_.$1<$0>(this, "; std::string prepared_template; // Flat template is needed if the prepared one is introspecting the values // inside the returned values, for example, for repeated fields and maps. std::string prepared_flat_template; std::string prepared_add_template; - // TODO(jianzhouzh): Fix all forward declared messages and deal with the - // weak fields. + // TODO(b/190614678): Support fields with type Message or Map. if (descriptor->is_repeated() && !descriptor->is_map()) { if (descriptor->type() != FieldDescriptor::TYPE_MESSAGE && descriptor->type() != FieldDescriptor::TYPE_GROUP) { - lambda_args = "_listener_, this, index"; - prepared_template = strings::Substitute( - "_listener_->ExtractFieldInfo(&$0.Get(index))", field_member); - prepared_add_template = strings::Substitute( - "_listener_->ExtractFieldInfo(&$0.Get($0.size() - 1))", field_member); - } else { - prepared_template = - StrCat("::", proto_ns, "::FieldAccessListener::AddressInfo()"); + prepared_template = strings::Substitute("&$0.Get(index)", field_member); prepared_add_template = - StrCat("::", proto_ns, "::FieldAccessListener::AddressInfo()"); + strings::Substitute("&$0.Get($0.size() - 1)", field_member); + } else { + prepared_template = "nullptr"; + prepared_add_template = "nullptr"; } } else if (descriptor->is_map()) { - prepared_template = - StrCat("::", proto_ns, "::FieldAccessListener::AddressInfo()"); + prepared_template = "nullptr"; } else if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE && !descriptor->options().lazy()) { - prepared_template = - StrCat("::", proto_ns, "::FieldAccessListener::AddressInfo()"); + prepared_template = "nullptr"; } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { if (oneof_member) { prepared_template = GenerateTemplateForOneofString( @@ -210,56 +189,49 @@ GenerateTemplateForSingleString(descriptor, field_member); } } else { - prepared_template = - strings::Substitute("_listener_->ExtractFieldInfo(&$0)", field_member); + prepared_template = StrCat("&", field_member); } if (descriptor->is_repeated() && !descriptor->is_map() && descriptor->type() != FieldDescriptor::TYPE_MESSAGE && descriptor->type() != FieldDescriptor::TYPE_GROUP) { - prepared_flat_template = - strings::Substitute("_listener_->ExtractFieldInfo(&$0)", field_member); + prepared_flat_template = StrCat("&", field_member); } else { prepared_flat_template = prepared_template; } - (*variables)["annotate_get"] = GenerateAnnotation( - substitute_template_prefix, prepared_template, substitute_template_suffix, - descriptor->index(), lambda_args, "kGet"); - (*variables)["annotate_set"] = GenerateAnnotation( - substitute_template_prefix, prepared_template, substitute_template_suffix, - descriptor->index(), lambda_args, "kSet"); - (*variables)["annotate_has"] = GenerateAnnotation( - substitute_template_prefix, prepared_template, substitute_template_suffix, - descriptor->index(), lambda_args, "kHas"); - (*variables)["annotate_mutable"] = GenerateAnnotation( - substitute_template_prefix, prepared_template, substitute_template_suffix, - descriptor->index(), lambda_args, "kMutable"); - (*variables)["annotate_release"] = GenerateAnnotation( - substitute_template_prefix, prepared_template, substitute_template_suffix, - descriptor->index(), lambda_args, "kRelease"); - (*variables)["annotate_clear"] = - GenerateAnnotation(substitute_template_prefix, prepared_flat_template, - substitute_template_suffix, descriptor->index(), - lambda_flat_args, "kClear"); - (*variables)["annotate_size"] = - GenerateAnnotation(substitute_template_prefix, prepared_flat_template, - substitute_template_suffix, descriptor->index(), - lambda_flat_args, "kSize"); - (*variables)["annotate_list"] = - GenerateAnnotation(substitute_template_prefix, prepared_flat_template, - substitute_template_suffix, descriptor->index(), - lambda_flat_args, "kList"); - (*variables)["annotate_mutable_list"] = - GenerateAnnotation(substitute_template_prefix, prepared_flat_template, - substitute_template_suffix, descriptor->index(), - lambda_flat_args, "kMutableList"); - (*variables)["annotate_add"] = - GenerateAnnotation(substitute_template_prefix, prepared_add_template, - substitute_template_suffix, descriptor->index(), - lambda_flat_args, "kAdd"); - (*variables)["annotate_add_mutable"] = - GenerateAnnotation(substitute_template_prefix, prepared_add_template, - substitute_template_suffix, descriptor->index(), - lambda_flat_args, "kAddMutable"); + + MaySetAnnotationVariable(options, "get", substitute_template_prefix, + prepared_template, descriptor->index(), "OnGet", + variables); + MaySetAnnotationVariable(options, "set", substitute_template_prefix, + prepared_template, descriptor->index(), "OnSet", + variables); + MaySetAnnotationVariable(options, "has", substitute_template_prefix, + prepared_template, descriptor->index(), "OnHas", + variables); + MaySetAnnotationVariable(options, "mutable", substitute_template_prefix, + prepared_template, descriptor->index(), "OnMutable", + variables); + MaySetAnnotationVariable(options, "release", substitute_template_prefix, + prepared_template, descriptor->index(), "OnRelease", + variables); + MaySetAnnotationVariable(options, "clear", substitute_template_prefix, + prepared_flat_template, descriptor->index(), + "OnClear", variables); + MaySetAnnotationVariable(options, "size", substitute_template_prefix, + prepared_flat_template, descriptor->index(), + "OnSize", variables); + MaySetAnnotationVariable(options, "list", substitute_template_prefix, + prepared_flat_template, descriptor->index(), + "OnList", variables); + MaySetAnnotationVariable(options, "mutable_list", substitute_template_prefix, + prepared_flat_template, descriptor->index(), + "OnMutableList", variables); + MaySetAnnotationVariable(options, "add", substitute_template_prefix, + prepared_add_template, descriptor->index(), "OnAdd", + variables); + MaySetAnnotationVariable(options, "add_mutable", substitute_template_prefix, + prepared_add_template, descriptor->index(), + "OnAddMutable", variables); } void SetCommonFieldVariables(const FieldDescriptor* descriptor, @@ -310,6 +282,22 @@ strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;"); } +void FieldGenerator::SetInlinedStringIndex(int32_t inlined_string_index) { + if (!IsStringInlined(descriptor_, options_)) { + GOOGLE_CHECK_EQ(inlined_string_index, -1); + return; + } + variables_["inlined_string_donated"] = StrCat( + "(_inlined_string_donated_[", inlined_string_index / 32, "] & 0x", + strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8), + "u) != 0;"); + variables_["donating_states_word"] = + StrCat("_inlined_string_donated_[", inlined_string_index / 32, "]"); + variables_["mask_for_undonate"] = StrCat( + "~0x", strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8), + "u"); +} + void SetCommonOneofFieldVariables( const FieldDescriptor* descriptor, std::map<std::string, std::string>* variables) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index b210ef9..185fa8c 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -181,7 +181,10 @@ // are placed in the message's ByteSize() method. virtual void GenerateByteSize(io::Printer* printer) const = 0; + virtual bool IsInlined() const { return false; } + void SetHasBitIndex(int32_t has_bit_index); + void SetInlinedStringIndex(int32_t inlined_string_index); protected: const FieldDescriptor* descriptor_; @@ -207,6 +210,12 @@ } } + void SetInlinedStringIndices(const std::vector<int>& inlined_string_indices) { + for (int i = 0; i < descriptor_->field_count(); ++i) { + field_generators_[i]->SetInlinedStringIndex(inlined_string_indices[i]); + } + } + private: const Descriptor* descriptor_; std::vector<std::unique_ptr<FieldGenerator>> field_generators_;
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 0c23947..1f20c4d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -130,7 +130,7 @@ } for (int i = 0; i < file->extension_count(); i++) { extension_generators_.emplace_back( - new ExtensionGenerator(file->extension(i), options)); + new ExtensionGenerator(file->extension(i), options, &scc_analyzer_)); } for (int i = 0; i < file->weak_dependency_count(); ++i) { weak_deps_.insert(file->weak_dependency(i)); @@ -463,6 +463,19 @@ DefaultInstanceType(generator->descriptor_, options_), DefaultInstanceName(generator->descriptor_, options_)); + for (int i = 0; i < generator->descriptor_->field_count(); i++) { + const FieldDescriptor* field = generator->descriptor_->field(i); + if (IsStringInlined(field, options_)) { + // Force the initialization of the inlined string in the default instance. + format( + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY std::true_type " + "$1$::_init_inline_$2$_ = " + "($3$._instance.$2$_.Init(), std::true_type{});\n", + ClassName(generator->descriptor_), FieldName(field), + DefaultInstanceName(generator->descriptor_, options_)); + } + } + if (options_.lite_implicit_weak_fields) { format("$1$* $2$ = &$3$;\n", DefaultInstanceType(generator->descriptor_, options_), @@ -578,6 +591,13 @@ "// @@protoc_insertion_point(global_scope)\n"); } +void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* printer) { + Formatter format(printer, variables_); + GenerateSourceIncludes(printer); + NamespaceOpener ns(Namespace(file_, options_), format); + extension_generators_[idx]->GenerateDefinition(printer); +} + void FileGenerator::GenerateGlobalSource(io::Printer* printer) { Formatter format(printer, variables_); GenerateSourceIncludes(printer); @@ -598,21 +618,6 @@ for (int i = 0; i < enum_generators_.size(); i++) { enum_generators_[i]->GenerateMethods(i, printer); } - - // Define extensions. - for (int i = 0; i < extension_generators_.size(); i++) { - extension_generators_[i]->GenerateDefinition(printer); - } - - if (HasGenericServices(file_, options_)) { - // Generate services. - for (int i = 0; i < service_generators_.size(); i++) { - if (i == 0) format("\n"); - format(kThickSeparator); - format("\n"); - service_generators_[i]->GenerateImplementation(printer); - } - } } void FileGenerator::GenerateSource(io::Printer* printer) { @@ -1143,6 +1148,9 @@ GOOGLE_CHECK(!options_.opensource_runtime); IncludeFile("net/proto2/public/lazy_field.h", printer); } + if (ShouldVerify(file_, options_, &scc_analyzer_)) { + IncludeFile("net/proto2/public/wire_format_verify.h", printer); + } if (options_.opensource_runtime) { // Verify the protobuf library header version is compatible with the protoc @@ -1170,6 +1178,9 @@ IncludeFile("net/proto2/io/public/coded_stream.h", printer); IncludeFile("net/proto2/public/arena.h", printer); IncludeFile("net/proto2/public/arenastring.h", printer); + if (options_.force_inline_string || options_.profile_driven_inline_string) { + IncludeFile("net/proto2/public/inlined_string_field.h", printer); + } IncludeFile("net/proto2/public/generated_message_table_driven.h", printer); if (HasGeneratedMethods(file_, options_) && options_.tctable_mode != Options::kTCTableNever) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h index 35a9085..e881602 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.h +++ b/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -82,9 +82,20 @@ void GeneratePBHeader(io::Printer* printer, const std::string& info_path); void GenerateSource(io::Printer* printer); + // The following member functions are used when the lite_implicit_weak_fields + // option is set. In this mode the code is organized a bit differently to + // promote better linker stripping of unused code. In particular, we generate + // one .cc file per message, one .cc file per extension, and a main pb.cc file + // containing everything else. + int NumMessages() const { return message_generators_.size(); } - // Similar to GenerateSource but generates only one message + int NumExtensions() const { return extension_generators_.size(); } + // Generates the source file for one message. void GenerateSourceForMessage(int idx, io::Printer* printer); + // Generates the source file for one extension. + void GenerateSourceForExtension(int idx, io::Printer* printer); + // Generates a source file containing everything except messages and + // extensions. void GenerateGlobalSource(io::Printer* printer); private:
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc index 2a6087e..0851571 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -35,6 +35,7 @@ #include <google/protobuf/compiler/cpp/cpp_generator.h> #include <memory> +#include <string> #include <utility> #include <vector> @@ -53,6 +54,12 @@ CppGenerator::CppGenerator() {} CppGenerator::~CppGenerator() {} +namespace { +std::string NumberedCcFileName(const std::string& basename, int number) { + return StrCat(basename, ".out/", number, ".cc"); +} +} // namespace + bool CppGenerator::Generate(const FileDescriptor* file, const std::string& parameter, GeneratorContext* generator_context, @@ -107,7 +114,19 @@ } else if (options[i].first == "annotate_accessor") { file_options.annotate_accessor = true; } else if (options[i].first == "inject_field_listener_events") { - file_options.inject_field_listener_events = true; + file_options.field_listener_options.inject_field_listener_events = true; + } else if (options[i].first == "forbidden_field_listener_events") { + std::size_t pos = 0; + do { + std::size_t next_pos = options[i].second.find_first_of("+", pos); + if (next_pos == std::string::npos) { + next_pos = options[i].second.size(); + } + if (next_pos > pos) + file_options.field_listener_options.forbidden_field_listener_events + .insert(options[i].second.substr(pos, next_pos - pos)); + pos = next_pos + 1; + } while (pos < options[i].second.size()); } else if (options[i].first == "eagerly_verified_lazy") { file_options.eagerly_verified_lazy = true; } else if (options[i].first == "force_eagerly_verified_lazy") { @@ -204,24 +223,37 @@ file_generator.GenerateGlobalSource(&printer); } - int num_cc_files = file_generator.NumMessages(); + int num_cc_files = + file_generator.NumMessages() + file_generator.NumExtensions(); // If we're using implicit weak fields then we allow the user to // optionally specify how many files to generate, not counting the global // pb.cc file. If we have more files than messages, then some files will // be generated as empty placeholders. if (file_options.num_cc_files > 0) { - GOOGLE_CHECK_LE(file_generator.NumMessages(), file_options.num_cc_files) - << "There must be at least as many numbered .cc files as messages."; + GOOGLE_CHECK_LE(num_cc_files, file_options.num_cc_files) + << "There must be at least as many numbered .cc files as messages " + "and extensions."; num_cc_files = file_options.num_cc_files; } - for (int i = 0; i < num_cc_files; i++) { - std::unique_ptr<io::ZeroCopyOutputStream> output( - generator_context->Open(StrCat(basename, ".out/", i, ".cc"))); + int cc_file_number = 0; + for (int i = 0; i < file_generator.NumMessages(); i++) { + std::unique_ptr<io::ZeroCopyOutputStream> output(generator_context->Open( + NumberedCcFileName(basename, cc_file_number++))); io::Printer printer(output.get(), '$'); - if (i < file_generator.NumMessages()) { - file_generator.GenerateSourceForMessage(i, &printer); - } + file_generator.GenerateSourceForMessage(i, &printer); + } + for (int i = 0; i < file_generator.NumExtensions(); i++) { + std::unique_ptr<io::ZeroCopyOutputStream> output(generator_context->Open( + NumberedCcFileName(basename, cc_file_number++))); + io::Printer printer(output.get(), '$'); + file_generator.GenerateSourceForExtension(i, &printer); + } + // Create empty placeholder files if necessary to match the expected number + // of files. + for (; cc_file_number < num_cc_files; ++cc_file_number) { + std::unique_ptr<io::ZeroCopyOutputStream> output(generator_context->Open( + NumberedCcFileName(basename, cc_file_number))); } } else { std::unique_ptr<io::ZeroCopyOutputStream> output(
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index c25de21..25206db 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -430,9 +430,14 @@ std::string SuperClassName(const Descriptor* descriptor, const Options& options) { - return "::" + ProtobufNamespace(options) + - (HasDescriptorMethods(descriptor->file(), options) ? "::Message" - : "::MessageLite"); + if (!HasDescriptorMethods(descriptor->file(), options)) { + return "::" + ProtobufNamespace(options) + "::MessageLite"; + } + auto simple_base = SimpleBaseClass(descriptor, options); + if (simple_base.empty()) { + return "::" + ProtobufNamespace(options) + "::Message"; + } + return "::" + ProtobufNamespace(options) + "::internal::" + simple_base; } std::string ResolveKeyword(const std::string& name) { @@ -772,6 +777,11 @@ return function_name; } +bool IsStringInlined(const FieldDescriptor* descriptor, + const Options& options) { + return false; +} + static bool HasLazyFields(const Descriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer) { for (int field_idx = 0; field_idx < descriptor->field_count(); field_idx++) { @@ -929,6 +939,16 @@ return false; } +bool ShouldVerify(const Descriptor* descriptor, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + return false; +} + +bool ShouldVerify(const FileDescriptor* file, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + return false; +} + bool IsStringOrMessage(const FieldDescriptor* field) { switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: @@ -1075,21 +1095,12 @@ "VerifyUTF8CordNamedField", format); } -namespace { - -void Flatten(const Descriptor* descriptor, - std::vector<const Descriptor*>* flatten) { - for (int i = 0; i < descriptor->nested_type_count(); i++) - Flatten(descriptor->nested_type(i), flatten); - flatten->push_back(descriptor); -} - -} // namespace - void FlattenMessagesInFile(const FileDescriptor* file, std::vector<const Descriptor*>* result) { for (int i = 0; i < file->message_type_count(); i++) { - Flatten(file->message_type(i), result); + ForEachMessage(file->message_type(i), [&](const Descriptor* descriptor) { + result->push_back(descriptor); + }); } } @@ -1457,6 +1468,10 @@ return FileOptions::SPEED; } +bool EnableMessageOwnedArena(const Descriptor* desc) { + return false; +} + } // namespace cpp } // namespace compiler } // namespace protobuf
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index 8c07e47..88befc0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -315,6 +315,8 @@ return false; } +bool IsStringInlined(const FieldDescriptor* descriptor, const Options& options); + // For a string field, returns the effective ctype. If the actual ctype is // not supported, returns the default of STRING. FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field, @@ -325,6 +327,11 @@ EffectiveStringCType(field, options) == FieldOptions::CORD; } +inline bool IsString(const FieldDescriptor* field, const Options& options) { + return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING && + EffectiveStringCType(field, options) == FieldOptions::STRING; +} + inline bool IsStringPiece(const FieldDescriptor* field, const Options& options) { return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING && @@ -533,6 +540,19 @@ return result; } +template <typename F> +void ForEachMessage(const Descriptor* descriptor, F&& func) { + for (int i = 0; i < descriptor->nested_type_count(); i++) + ForEachMessage(descriptor->nested_type(i), std::forward<F&&>(func)); + func(descriptor); +} + +template <typename F> +void ForEachMessage(const FileDescriptor* descriptor, F&& func) { + for (int i = 0; i < descriptor->message_type_count(); i++) + ForEachMessage(descriptor->message_type(i), std::forward<F&&>(func)); +} + bool HasWeakFields(const Descriptor* desc, const Options& options); bool HasWeakFields(const FileDescriptor* desc, const Options& options); @@ -630,6 +650,27 @@ bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options, MessageSCCAnalyzer* scc_analyzer); +inline bool HasSimpleBaseClass(const Descriptor* desc, const Options& options) { + if (!HasDescriptorMethods(desc->file(), options)) return false; + if (desc->extension_range_count() != 0) return false; + if (desc->field_count() == 0) return true; + // TODO(jorg): Support additional common message types with only one + // or two fields + return false; +} + +inline std::string SimpleBaseClass(const Descriptor* desc, + const Options& options) { + if (!HasDescriptorMethods(desc->file(), options)) return ""; + if (desc->extension_range_count() != 0) return ""; + if (desc->field_count() == 0) { + return "ZeroFieldsBase"; + } + // TODO(jorg): Support additional common message types with only one + // or two fields + return ""; +} + // Formatter is a functor class which acts as a closure around printer and // the variable map. It's much like printer->Print except it supports both named // variables that are substituted using a key value map and direct arguments. In @@ -884,8 +925,12 @@ PROTOC_EXPORT std::string StripProto(const std::string& filename); -inline bool EnableMessageOwnedArena(const Descriptor* /* desc */ ) { return false; } +bool EnableMessageOwnedArena(const Descriptor* desc); +bool ShouldVerify(const Descriptor* descriptor, const Options& options, + MessageSCCAnalyzer* scc_analyzer); +bool ShouldVerify(const FileDescriptor* file, const Options& options, + MessageSCCAnalyzer* scc_analyzer); } // namespace cpp } // namespace compiler } // namespace protobuf
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index ff8b308..d15f9b6 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -43,6 +43,7 @@ #include <utility> #include <vector> +#include <google/protobuf/stubs/common.h> #include <google/protobuf/compiler/cpp/cpp_enum.h> #include <google/protobuf/compiler/cpp/cpp_extension.h> #include <google/protobuf/compiler/cpp/cpp_field.h> @@ -52,6 +53,7 @@ #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/printer.h> +#include <google/protobuf/descriptor.h> #include <google/protobuf/generated_message_table_driven.h> #include <google/protobuf/generated_message_util.h> #include <google/protobuf/map_entry_lite.h> @@ -181,6 +183,10 @@ return ret; } +bool StrContains(const std::string& haystack, const std::string& needle) { + return haystack.find(needle) != std::string::npos; +} + // Finds runs of fields for which `predicate` is true. // RunMap maps from fields that start each run to the number of fields in that // run. This is optimized for the common case that there are very few runs in @@ -295,15 +301,6 @@ return true; } -bool ShouldMarkClearAsFinal(const Descriptor* descriptor, - const Options& options) { - static std::set<std::string> exclusions{ - }; - - const std::string name = ClassName(descriptor, true); - return exclusions.find(name) == exclusions.end() || - options.opensource_runtime; -} // Returns true to make the message serialize in order, decided by the following // factors in the order of precedence. @@ -397,6 +394,16 @@ return v.front()->is_required(); } +bool HasSingularString(const Descriptor* desc, const Options& options) { + for (const auto* field : FieldRange(desc)) { + if (IsString(field, options) && !IsStringInlined(field, options) && + !field->is_repeated() && !field->real_containing_oneof()) { + return true; + } + } + return false; +} + // Collects neighboring fields based on a given criteria (equivalent predicate). template <typename Predicate> std::vector<std::vector<const FieldDescriptor*>> CollectFields( @@ -553,6 +560,88 @@ return true; } +void MaySetAnnotationVariable(const Options& options, + StringPiece annotation_name, + StringPiece injector_template_prefix, + StringPiece injector_template_suffix, + std::map<std::string, std::string>* variables) { + if (options.field_listener_options.forbidden_field_listener_events.count( + std::string(annotation_name))) + return; + (*variables)[StrCat("annotate_", annotation_name)] = strings::Substitute( + StrCat(injector_template_prefix, injector_template_suffix), + (*variables)["classtype"]); +} + +void GenerateExtensionAnnotations( + const Descriptor* descriptor, const Options& options, + std::map<std::string, std::string>* variables) { + const std::map<std::string, std::string> accessor_annotations_to_hooks = { + {"annotate_extension_has", "OnHasExtension"}, + {"annotate_extension_clear", "OnClearExtension"}, + {"annotate_extension_repeated_size", "OnExtensionSize"}, + {"annotate_extension_get", "OnGetExtension"}, + {"annotate_extension_mutable", "OnMutableExtension"}, + {"annotate_extension_set", "OnSetExtension"}, + {"annotate_extension_release", "OnReleaseExtension"}, + {"annotate_repeated_extension_get", "OnGetExtension"}, + {"annotate_repeated_extension_mutable", "OnMutableExtension"}, + {"annotate_repeated_extension_set", "OnSetExtension"}, + {"annotate_repeated_extension_add", "OnAddExtension"}, + {"annotate_repeated_extension_add_mutable", "OnAddMutableExtension"}, + {"annotate_repeated_extension_list", "OnListExtension"}, + {"annotate_repeated_extension_list_mutable", "OnMutableListExtension"}, + }; + for (const auto& annotation : accessor_annotations_to_hooks) { + (*variables)[annotation.first] = ""; + } + if (!options.field_listener_options.inject_field_listener_events || + descriptor->file()->options().optimize_for() == + google::protobuf::FileOptions::LITE_RUNTIME) { + return; + } + for (const auto& annotation : accessor_annotations_to_hooks) { + const std::string& annotation_name = annotation.first; + const std::string& listener_call = annotation.second; + if (!StrContains(annotation_name, "repeated") && + !StrContains(annotation_name, "size") && + !StrContains(annotation_name, "clear")) { + // Primitive fields accessors. + // "Has" is here as users calling "has" on a repeated field is a mistake. + (*variables)[annotation_name] = StrCat( + " _tracker_.", listener_call, + "(this, id.number(), _proto_TypeTraits::GetPtr(id.number(), " + "_extensions_, id.default_value_ref()));"); + } else if (StrContains(annotation_name, "repeated") && + !StrContains(annotation_name, "list") && + !StrContains(annotation_name, "size")) { + // Repeated index accessors. + std::string str_index = "index"; + if (StrContains(annotation_name, "add")) { + str_index = "_extensions_.ExtensionSize(id.number()) - 1"; + } + (*variables)[annotation_name] = + StrCat(" _tracker_.", listener_call, + "(this, id.number(), " + "_proto_TypeTraits::GetPtr(id.number(), _extensions_, ", + str_index, "));"); + } else if (StrContains(annotation_name, "list") || + StrContains(annotation_name, "size")) { + // Repeated full accessors. + (*variables)[annotation_name] = StrCat( + " _tracker_.", listener_call, + "(this, id.number(), _proto_TypeTraits::GetRepeatedPtr(id.number(), " + "_extensions_));"); + } else { + // Generic accessors such as "clear". + // TODO(b/190614678): Generalize clear from both repeated and non repeated + // calls, currently their underlying memory interfaces are very different. + // Or think of removing clear callback as no usages are needed and no + // memory exist after calling clear(). + } + } +} + } // anonymous namespace // =================================================================== @@ -567,6 +656,7 @@ options_(options), field_generators_(descriptor, options, scc_analyzer), max_has_bit_index_(0), + max_inlined_string_index_(0), num_weak_fields_(0), scc_analyzer_(scc_analyzer), variables_(vars) { @@ -583,36 +673,31 @@ variables_["annotate_deserialize"] = ""; variables_["annotate_reflection"] = ""; variables_["annotate_bytesize"] = ""; + variables_["annotate_mergefrom"] = ""; - if (options.inject_field_listener_events && + if (options.field_listener_options.inject_field_listener_events && descriptor->file()->options().optimize_for() != google::protobuf::FileOptions::LITE_RUNTIME) { - const std::string injector_template = StrCat( - " {\n" - " auto _listener_ = ::", - variables_["proto_ns"], - "::FieldAccessListener::GetListener();\n" - " if (_listener_) "); + const std::string injector_template = " _tracker_."; - StrAppend(&variables_["annotate_serialize"], injector_template, - "_listener_->OnSerializationAccess(this);\n" - " }\n"); - StrAppend(&variables_["annotate_deserialize"], injector_template, - " _listener_->OnDeserializationAccess(this);\n" - " }\n"); + MaySetAnnotationVariable(options, "serialize", injector_template, + "OnSerialize(this);\n", &variables_); + MaySetAnnotationVariable(options, "deserialize", injector_template, + "OnDeserialize(this);\n", &variables_); // TODO(danilak): Ideally annotate_reflection should not exist and we need // to annotate all reflective calls on our own, however, as this is a cause // for side effects, i.e. reading values dynamically, we want the users know // that dynamic access can happen. - StrAppend(&variables_["annotate_reflection"], injector_template, - "_listener_->OnReflectionAccess(default_instance()" - ".GetMetadata().descriptor);\n" - " }\n"); - StrAppend(&variables_["annotate_bytesize"], injector_template, - "_listener_->OnByteSizeAccess(this);\n" - " }\n"); + MaySetAnnotationVariable(options, "reflection", injector_template, + "OnGetMetadata();\n", &variables_); + MaySetAnnotationVariable(options, "bytesize", injector_template, + "OnByteSize(this);\n", &variables_); + MaySetAnnotationVariable(options, "mergefrom", injector_template, + "OnMergeFrom(this, &from);\n", &variables_); } + GenerateExtensionAnnotations(descriptor_, options_, &variables_); + SetUnknownFieldsVariable(descriptor_, options_, &variables_); // Compute optimized field order to be used for layout and initialization @@ -640,12 +725,22 @@ } has_bit_indices_[field->index()] = max_has_bit_index_++; } + if (IsStringInlined(field, options_)) { + if (inlined_string_indices_.empty()) { + inlined_string_indices_.resize(descriptor_->field_count(), kNoHasbit); + } + inlined_string_indices_[field->index()] = max_inlined_string_index_++; + } } if (!has_bit_indices_.empty()) { field_generators_.SetHasBitIndices(has_bit_indices_); } + if (!inlined_string_indices_.empty()) { + field_generators_.SetInlinedStringIndices(inlined_string_indices_); + } + num_required_fields_ = 0; for (int i = 0; i < descriptor->field_count(); i++) { if (descriptor->field(i)->is_required()) { @@ -656,8 +751,8 @@ table_driven_ = TableDrivenParsingEnabled(descriptor_, options_, scc_analyzer_); parse_function_generator_.reset(new ParseFunctionGenerator( - descriptor_, max_has_bit_index_, has_bit_indices_, options_, - scc_analyzer_, variables_)); + descriptor_, max_has_bit_index_, has_bit_indices_, + inlined_string_indices_, options_, scc_analyzer_, variables_)); } MessageGenerator::~MessageGenerator() = default; @@ -666,6 +761,10 @@ return (max_has_bit_index_ + 31) / 32; } +size_t MessageGenerator::InlinedStringDonatedSize() const { + return (max_inlined_string_index_ + 31) / 32; +} + int MessageGenerator::HasBitIndex(const FieldDescriptor* field) const { return has_bit_indices_.empty() ? kNoHasbit : has_bit_indices_[field->index()]; @@ -690,8 +789,8 @@ enum_generators_.push_back(enum_generators->back().get()); } for (int i = 0; i < descriptor_->extension_count(); i++) { - extension_generators->emplace_back( - new ExtensionGenerator(descriptor_->extension(i), options_)); + extension_generators->emplace_back(new ExtensionGenerator( + descriptor_->extension(i), options_, scc_analyzer_)); extension_generators_.push_back(extension_generators->back().get()); } } @@ -777,9 +876,206 @@ } if (descriptor_->extension_range_count() > 0) { - // Generate accessors for extensions. We just call a macro located in - // extension_set.h since the accessors about 80 lines of static code. - format("$GOOGLE_PROTOBUF$_EXTENSION_ACCESSORS($classname$)\n"); + // Generate accessors for extensions. + // We use "_proto_TypeTraits" as a type name below because "TypeTraits" + // causes problems if the class has a nested message or enum type with that + // name and "_TypeTraits" is technically reserved for the C++ library since + // it starts with an underscore followed by a capital letter. + // + // For similar reason, we use "_field_type" and "_is_packed" as parameter + // names below, so that "field_type" and "is_packed" can be used as field + // names. + format(R"( +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { +$annotate_extension_has$ + return _extensions_.Has(id.number()); +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); +$annotate_extension_clear$ +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { +$annotate_extension_repeated_size$ + return _extensions_.ExtensionSize(id.number()); +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { +$annotate_extension_get$ + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { +$annotate_extension_mutable$ + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); +$annotate_extension_set$ +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); +$annotate_extension_set$ +} +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); +$annotate_extension_set$ +} +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline PROTOBUF_MUST_USE_RESULT + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { +$annotate_extension_release$ + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); +} +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline typename _proto_TypeTraits::Singular::MutableType +UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { +$annotate_extension_release$ + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { +$annotate_repeated_extension_get$ + return _proto_TypeTraits::Get(id.number(), _extensions_, index); +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { +$annotate_repeated_extension_mutable$ + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); +$annotate_repeated_extension_set$ +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); +$annotate_repeated_extension_add_mutable$ + return to_add; +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); +$annotate_repeated_extension_add$ +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& +GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { +$annotate_repeated_extension_list$ + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); +} + +template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> +inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* +MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { +$annotate_repeated_extension_list_mutable$ + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); +} + +)"); // Generate MessageSet specific APIs for proto2 MessageSet. // For testing purposes we don't check for bridge.MessageSet, so // we don't use IsProto2MessageSet @@ -1145,8 +1441,10 @@ } else { format("inline $classname$() : $classname$(nullptr) {}\n"); } + if (!HasSimpleBaseClass(descriptor_, options_)) { + format("~$classname$() override;\n"); + } format( - "~$classname$() override;\n" "explicit constexpr " "$classname$(::$proto_ns$::internal::ConstantInitialized);\n" "\n" @@ -1213,7 +1511,6 @@ " return default_instance().GetMetadata().descriptor;\n" "}\n" "static const ::$proto_ns$::Reflection* GetReflection() {\n" - "$annotate_reflection$" " return default_instance().GetMetadata().reflection;\n" "}\n"); } @@ -1362,22 +1659,36 @@ if (HasGeneratedMethods(descriptor_->file(), options_)) { if (HasDescriptorMethods(descriptor_->file(), options_)) { - format( - // Use Message's built-in MergeFrom and CopyFrom when the passed-in - // argument is a generic Message instance, and only define the custom - // MergeFrom and CopyFrom instances when the source of the merge/copy - // is known to be the same class as the destination. - // TODO(jorg): Define MergeFrom in terms of MergeImpl, rather than the - // other way around, to save even more code size. - "using $superclass$::CopyFrom;\n" - "void CopyFrom(const $classname$& from);\n" - "" - "using $superclass$::MergeFrom;\n" - "void MergeFrom(const $classname$& from);\n" - "private:\n" - "static void MergeImpl(::$proto_ns$::Message*to, const " - "::$proto_ns$::Message&from);\n" - "public:\n"); + if (!HasSimpleBaseClass(descriptor_, options_)) { + format( + // Use Message's built-in MergeFrom and CopyFrom when the passed-in + // argument is a generic Message instance, and only define the + // custom MergeFrom and CopyFrom instances when the source of the + // merge/copy is known to be the same class as the destination. + // TODO(jorg): Define MergeFrom in terms of MergeImpl, rather than + // the other way around, to save even more code size. + "using $superclass$::CopyFrom;\n" + "void CopyFrom(const $classname$& from);\n" + "" + "using $superclass$::MergeFrom;\n" + "void MergeFrom(const $classname$& from);\n" + "private:\n" + "static void MergeImpl(::$proto_ns$::Message* to, const " + "::$proto_ns$::Message& from);\n" + "public:\n"); + } else { + format( + "using $superclass$::CopyFrom;\n" + "inline void CopyFrom(const $classname$& from) {\n" + " $superclass$::CopyImpl(this, from);\n" + "}\n" + "" + "using $superclass$::MergeFrom;\n" + "void MergeFrom(const $classname$& from) {\n" + " $superclass$::MergeImpl(this, from);\n" + "}\n" + "public:\n"); + } } else { format( "void CheckTypeAndMergeFrom(const ::$proto_ns$::MessageLite& from)" @@ -1386,36 +1697,42 @@ "void MergeFrom(const $classname$& from);\n"); } - format.Set("clear_final", - ShouldMarkClearAsFinal(descriptor_, options_) ? "final" : ""); + if (!HasSimpleBaseClass(descriptor_, options_)) { + format( + "PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;\n" + "bool IsInitialized() const final;\n" + "\n" + "size_t ByteSizeLong() const final;\n"); - format( - "PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear()$ clear_final$;\n" - "bool IsInitialized() const final;\n" - "\n" - "size_t ByteSizeLong() const final;\n"); + parse_function_generator_->GenerateMethodDecls(printer); - parse_function_generator_->GenerateMethodDecls(printer); + format( + "$uint8$* _InternalSerialize(\n" + " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) " + "const final;\n"); - format( - "$uint8$* _InternalSerialize(\n" - " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) " - "const final;\n"); - - // DiscardUnknownFields() is implemented in message.cc using reflections. We - // need to implement this function in generated code for messages. - if (!UseUnknownFieldSet(descriptor_->file(), options_)) { - format("void DiscardUnknownFields()$ full_final$;\n"); + // DiscardUnknownFields() is implemented in message.cc using reflections. + // We need to implement this function in generated code for messages. + if (!UseUnknownFieldSet(descriptor_->file(), options_)) { + format("void DiscardUnknownFields()$ full_final$;\n"); + } } } - format( - "int GetCachedSize() const final { return _cached_size_.Get(); }" - "\n\nprivate:\n" - "void SharedCtor();\n" - "void SharedDtor();\n" - "void SetCachedSize(int size) const$ full_final$;\n" - "void InternalSwap($classname$* other);\n"); + if (options_.field_listener_options.inject_field_listener_events) { + format("static constexpr int _kInternalFieldNumber = $1$;\n", + descriptor_->field_count()); + } + + if (!HasSimpleBaseClass(descriptor_, options_)) { + format( + "int GetCachedSize() const final { return _cached_size_.Get(); }" + "\n\nprivate:\n" + "void SharedCtor();\n" + "void SharedDtor();\n" + "void SetCachedSize(int size) const$ full_final$;\n" + "void InternalSwap($classname$* other);\n"); + } format( // Friend AnyMetadata so that it can call this FullMessageName() method. @@ -1433,9 +1750,13 @@ "protected:\n" "explicit $classname$(::$proto_ns$::Arena* arena,\n" " bool is_message_owned = false);\n" - "private:\n" - "static void ArenaDtor(void* object);\n" - "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n"); + "private:\n"); + + if (!HasSimpleBaseClass(descriptor_, options_)) { + format( + "static void ArenaDtor(void* object);\n" + "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n"); + } format( "public:\n" @@ -1562,6 +1883,21 @@ "\n"); } + if (options_.field_listener_options.inject_field_listener_events && + descriptor_->file()->options().optimize_for() != + google::protobuf::FileOptions::LITE_RUNTIME) { + format("static ::$proto_ns$::AccessListener<$1$> _tracker_;\n", + ClassName(descriptor_)); + } + + // Generate _inlined_string_donated_ for inlined string type. + // TODO(congliu): To avoid affecting the locality of `_has_bits_`, should this + // be below or above `_has_bits_`? + if (!inlined_string_indices_.empty()) { + format("::$proto_ns$::internal::HasBits<$1$> _inlined_string_donated_;\n", + InlinedStringDonatedSize()); + } + format( "template <typename T> friend class " "::$proto_ns$::Arena::InternalHelper;\n" @@ -1731,8 +2067,17 @@ has_offset = !has_bit_indices_.empty() || IsMapEntryMessage(descriptor_) ? offset + has_offset : -1; + int inlined_string_indices_offset; + if (inlined_string_indices_.empty()) { + inlined_string_indices_offset = -1; + } else { + GOOGLE_DCHECK_NE(has_offset, -1); + GOOGLE_DCHECK(!IsMapEntryMessage(descriptor_)); + inlined_string_indices_offset = has_offset + has_bit_indices_.size(); + } - format("{ $1$, $2$, sizeof($classtype$)},\n", offset, has_offset); + format("{ $1$, $2$, $3$, sizeof($classtype$)},\n", offset, has_offset, + inlined_string_indices_offset); } namespace { @@ -1746,7 +2091,9 @@ if (type == FieldDescriptor::TYPE_STRING || type == FieldDescriptor::TYPE_BYTES) { // string field - if (IsCord(field, options)) { + if (generator.IsInlined()) { + type = internal::FieldMetadata::kInlinedType; + } else if (IsCord(field, options)) { type = internal::FieldMetadata::kCordType; } else if (IsStringPiece(field, options)) { type = internal::FieldMetadata::kStringPieceType; @@ -1956,13 +2303,24 @@ " MergeFromInternal(other);\n" "}\n"); if (HasDescriptorMethods(descriptor_->file(), options_)) { - format( - "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" - " return ::$proto_ns$::internal::AssignDescriptors(\n" - " &$desc_table$_getter, &$desc_table$_once,\n" - " $file_level_metadata$[$1$]);\n" - "}\n", - index_in_file_messages_); + if (!descriptor_->options().map_entry()) { + format( + "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" + "$annotate_reflection$" + " return ::$proto_ns$::internal::AssignDescriptors(\n" + " &$desc_table$_getter, &$desc_table$_once,\n" + " $file_level_metadata$[$1$]);\n" + "}\n", + index_in_file_messages_); + } else { + format( + "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" + " return ::$proto_ns$::internal::AssignDescriptors(\n" + " &$desc_table$_getter, &$desc_table$_once,\n" + " $file_level_metadata$[$1$]);\n" + "}\n", + index_in_file_messages_); + } } return; } @@ -2059,10 +2417,12 @@ GenerateClear(printer); format("\n"); - parse_function_generator_->GenerateMethodImpls(printer); - format("\n"); + if (!HasSimpleBaseClass(descriptor_, options_)) { + parse_function_generator_->GenerateMethodImpls(printer); + format("\n"); - parse_function_generator_->GenerateDataDefinitions(printer); + parse_function_generator_->GenerateDataDefinitions(printer); + } GenerateSerializeWithCachedSizesToArray(printer); format("\n"); @@ -2083,6 +2443,8 @@ format("\n"); } + GenerateVerify(printer); + GenerateSwap(printer); format("\n"); @@ -2095,13 +2457,24 @@ index_in_file_messages_); } if (HasDescriptorMethods(descriptor_->file(), options_)) { - format( - "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" - " return ::$proto_ns$::internal::AssignDescriptors(\n" - " &$desc_table$_getter, &$desc_table$_once,\n" - " $file_level_metadata$[$1$]);\n" - "}\n", - index_in_file_messages_); + if (!descriptor_->options().map_entry()) { + format( + "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" + "$annotate_reflection$" + " return ::$proto_ns$::internal::AssignDescriptors(\n" + " &$desc_table$_getter, &$desc_table$_once,\n" + " $file_level_metadata$[$1$]);\n" + "}\n", + index_in_file_messages_); + } else { + format( + "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" + " return ::$proto_ns$::internal::AssignDescriptors(\n" + " &$desc_table$_getter, &$desc_table$_once,\n" + " $file_level_metadata$[$1$]);\n" + "}\n", + index_in_file_messages_); + } } else { format( "std::string $classname$::GetTypeName() const {\n" @@ -2110,6 +2483,14 @@ "\n"); } + if (options_.field_listener_options.inject_field_listener_events && + descriptor_->file()->options().optimize_for() != + google::protobuf::FileOptions::LITE_RUNTIME) { + format( + "::$proto_ns$::AccessListener<$classtype$> " + "$1$::_tracker_(&FullMessageName);\n", + ClassName(descriptor_)); + } } size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { @@ -2148,9 +2529,13 @@ } processing_type = static_cast<unsigned>(field->type()); + const FieldGenerator& generator = field_generators_.get(field); if (field->type() == FieldDescriptor::TYPE_STRING) { switch (EffectiveStringCType(field, options_)) { case FieldOptions::STRING: + if (generator.IsInlined()) { + processing_type = internal::TYPE_STRING_INLINED; + } break; case FieldOptions::CORD: processing_type = internal::TYPE_STRING_CORD; @@ -2162,6 +2547,9 @@ } else if (field->type() == FieldDescriptor::TYPE_BYTES) { switch (EffectiveStringCType(field, options_)) { case FieldOptions::STRING: + if (generator.IsInlined()) { + processing_type = internal::TYPE_BYTES_INLINED; + } break; case FieldOptions::CORD: processing_type = internal::TYPE_BYTES_CORD; @@ -2326,7 +2714,12 @@ } else { format("~0u, // no _weak_field_map_\n"); } - const int kNumGenericOffsets = 5; // the number of fixed offsets above + if (!inlined_string_indices_.empty()) { + format("PROTOBUF_FIELD_OFFSET($classtype$, _inlined_string_donated_),\n"); + } else { + format("~0u, // no _inlined_string_donated_\n"); + } + const int kNumGenericOffsets = 6; // the number of fixed offsets above const size_t offsets = kNumGenericOffsets + descriptor_->field_count() + descriptor_->real_oneof_decl_count(); size_t entries = offsets; @@ -2345,10 +2738,18 @@ format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field)); } + // Some information about a field is in the pdproto profile. The profile is + // only available at compile time. So we embed such information in the + // offset of the field, so that the information is available when reflective + // accessing the field at run time. + // + // Embed whether the field is used to the MSB of the offset. if (!IsFieldUsed(field, options_)) { format(" | 0x80000000u, // unused\n"); } else if (IsEagerlyVerifiedLazy(field, options_, scc_analyzer_)) { format(" | 0x1u, // eagerly verified lazy\n"); + } else if (IsStringInlined(field, options_)) { + format(" | 0x1u, // inlined\n"); } else { format(",\n"); } @@ -2374,11 +2775,21 @@ format("$1$,\n", index); } } + if (!inlined_string_indices_.empty()) { + entries += inlined_string_indices_.size(); + for (int inlined_string_indice : inlined_string_indices_) { + const std::string index = inlined_string_indice >= 0 + ? StrCat(inlined_string_indice) + : "~0u"; + format("$1$,\n", index); + } + } return std::make_pair(entries, offsets); } void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) { + if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); format("void $classname$::SharedCtor() {\n"); @@ -2394,6 +2805,7 @@ } void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) { + if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); format("inline void $classname$::SharedDtor() {\n"); @@ -2424,6 +2836,7 @@ } void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) { + if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); // Generate the ArenaDtor() method. Track whether any fields actually produced @@ -2593,7 +3006,8 @@ bool has_arena_constructor = field->is_repeated(); if (!field->real_containing_oneof() && (IsLazy(field, options_, scc_analyzer_) || - IsStringPiece(field, options_))) { + IsStringPiece(field, options_) || + (IsString(field, options_) && IsStringInlined(field, options_)))) { has_arena_constructor = true; } if (has_arena_constructor) { @@ -2620,15 +3034,29 @@ format( "$classname$::$classname$(::$proto_ns$::Arena* arena,\n" " bool is_message_owned)\n" - " : $1$ {\n" - " SharedCtor();\n" - " if (!is_message_owned) {\n" - " RegisterArenaDtor(arena);\n" - " }\n" - " // @@protoc_insertion_point(arena_constructor:$full_name$)\n" - "}\n", + " : $1$ {\n", initializer_with_arena); + if (!inlined_string_indices_.empty()) { + // Donate inline string fields. + format(" if (arena != nullptr) {\n"); + for (size_t i = 0; i < InlinedStringDonatedSize(); ++i) { + format(" _inlined_string_donated_[$1$] = ~0u;\n", i); + } + format(" }\n"); + } + + if (!HasSimpleBaseClass(descriptor_, options_)) { + format( + " SharedCtor();\n" + " if (!is_message_owned) {\n" + " RegisterArenaDtor(arena);\n" + " }\n"); + } + format( + " // @@protoc_insertion_point(arena_constructor:$full_name$)\n" + "}\n"); + std::map<std::string, std::string> vars; SetUnknownFieldsVariable(descriptor_, options_, &vars); format.AddMap(vars); @@ -2652,6 +3080,9 @@ format.Indent(); format.Indent(); + // Do not copy inlined_string_donated_, because this is not an arena + // constructor. + if (!has_bit_indices_.empty()) { format(",\n_has_bits_(from._has_bits_)"); } @@ -2726,14 +3157,22 @@ GenerateSharedConstructorCode(printer); // Generate the destructor. - format( - "$classname$::~$classname$() {\n" - " // @@protoc_insertion_point(destructor:$full_name$)\n" - " if (GetArenaForAllocation() != nullptr) return;\n" - " SharedDtor();\n" - " _internal_metadata_.Delete<$unknown_fields_type$>();\n" - "}\n" - "\n"); + if (!HasSimpleBaseClass(descriptor_, options_)) { + format( + "$classname$::~$classname$() {\n" + " // @@protoc_insertion_point(destructor:$full_name$)\n" + " if (GetArenaForAllocation() != nullptr) return;\n" + " SharedDtor();\n" + " _internal_metadata_.Delete<$unknown_fields_type$>();\n" + "}\n" + "\n"); + } else { + // For messages using simple base classes, having no destructor + // allows our vtable to share the same destructor as every other + // message with a simple base class. This works only as long as + // we have no fields needing destruction, of course. (No strings + // or extensions) + } // Generate the shared destructor code. GenerateSharedDestructorCode(printer); @@ -2741,11 +3180,13 @@ // Generate the arena-specific destructor code. GenerateArenaDestructorCode(printer); - // Generate SetCachedSize. - format( - "void $classname$::SetCachedSize(int size) const {\n" - " _cached_size_.Set(size);\n" - "}\n"); + if (!HasSimpleBaseClass(descriptor_, options_)) { + // Generate SetCachedSize. + format( + "void $classname$::SetCachedSize(int size) const {\n" + " _cached_size_.Set(size);\n" + "}\n"); + } } void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) { @@ -2759,6 +3200,7 @@ } void MessageGenerator::GenerateClear(io::Printer* printer) { + if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); // The maximum number of bytes we will memset to zero without checking their @@ -2916,6 +3358,8 @@ format("_weak_field_map_.ClearAll();\n"); } + // We don't clear donated status. + if (!has_bit_indices_.empty()) { // Step 5: Everything else. format("_has_bits_.Clear();\n"); @@ -2975,6 +3419,7 @@ } void MessageGenerator::GenerateSwap(io::Printer* printer) { + if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); format("void $classname$::InternalSwap($classname$* other) {\n"); @@ -2989,6 +3434,11 @@ std::map<std::string, std::string> vars; SetUnknownFieldsVariable(descriptor_, options_, &vars); format.AddMap(vars); + if (HasSingularString(descriptor_, options_)) { + format( + "auto* lhs_arena = GetArenaForAllocation();\n" + "auto* rhs_arena = other->GetArenaForAllocation();\n"); + } format("_internal_metadata_.InternalSwap(&other->_internal_metadata_);\n"); if (!has_bit_indices_.empty()) { @@ -3056,47 +3506,64 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* printer) { Formatter format(printer, variables_); - if (HasDescriptorMethods(descriptor_->file(), options_)) { - // We don't override the generalized MergeFrom (aka that which - // takes in the Message base class as a parameter); instead we just - // let the base Message::MergeFrom take care of it. The base MergeFrom - // knows how to quickly confirm the types exactly match, and if so, will - // use GetClassData() to retrieve the address of MergeImpl, which calls - // the fast MergeFrom overload. Most callers avoid all this by passing - // a "from" message that is the same type as the message being merged - // into, rather than a generic Message. + if (!HasSimpleBaseClass(descriptor_, options_)) { + if (HasDescriptorMethods(descriptor_->file(), options_)) { + // We don't override the generalized MergeFrom (aka that which + // takes in the Message base class as a parameter); instead we just + // let the base Message::MergeFrom take care of it. The base MergeFrom + // knows how to quickly confirm the types exactly match, and if so, will + // use GetClassData() to retrieve the address of MergeImpl, which calls + // the fast MergeFrom overload. Most callers avoid all this by passing + // a "from" message that is the same type as the message being merged + // into, rather than a generic Message. + format( + "const ::$proto_ns$::Message::ClassData " + "$classname$::_class_data_ = {\n" + " ::$proto_ns$::Message::CopyWithSizeCheck,\n" + " $classname$::MergeImpl\n" + "};\n" + "const ::$proto_ns$::Message::ClassData*" + "$classname$::GetClassData() const { return &_class_data_; }\n" + "\n" + "void $classname$::MergeImpl(::$proto_ns$::Message* to,\n" + " const ::$proto_ns$::Message& from) {\n" + " static_cast<$classname$ *>(to)->MergeFrom(\n" + " static_cast<const $classname$ &>(from));\n" + "}\n" + "\n"); + } else { + // Generate CheckTypeAndMergeFrom(). + format( + "void $classname$::CheckTypeAndMergeFrom(\n" + " const ::$proto_ns$::MessageLite& from) {\n" + " MergeFrom(*::$proto_ns$::internal::DownCast<const $classname$*>(\n" + " &from));\n" + "}\n"); + } + } else { + // In the simple case, we just define ClassData that vectors back to the + // simple implementation of Copy and Merge. format( "const ::$proto_ns$::Message::ClassData " "$classname$::_class_data_ = {\n" - " ::$proto_ns$::Message::CopyWithSizeCheck,\n" - " $classname$::MergeImpl\n" + " $superclass$::CopyImpl,\n" + " $superclass$::MergeImpl,\n" "};\n" "const ::$proto_ns$::Message::ClassData*" "$classname$::GetClassData() const { return &_class_data_; }\n" "\n" - "void $classname$::MergeImpl(::$proto_ns$::Message*to,\n" - " const ::$proto_ns$::Message&from) {\n" - " static_cast<$classname$ *>(to)->MergeFrom(\n" - " static_cast<const $classname$ &>(from));\n" - "}\n" "\n"); - } else { - // Generate CheckTypeAndMergeFrom(). - format( - "void $classname$::CheckTypeAndMergeFrom(\n" - " const ::$proto_ns$::MessageLite& from) {\n" - " MergeFrom(*::$proto_ns$::internal::DownCast<const $classname$*>(\n" - " &from));\n" - "}\n"); } } void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { + if (HasSimpleBaseClass(descriptor_, options_)) return; // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast. Formatter format(printer, variables_); format( "void $classname$::MergeFrom(const $classname$& from) {\n" + "$annotate_mergefrom$" "// @@protoc_insertion_point(class_specific_merge_from_start:" "$full_name$)\n" " $DCHK$_NE(&from, this);\n"); @@ -3255,6 +3722,7 @@ } void MessageGenerator::GenerateCopyFrom(io::Printer* printer) { + if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); if (HasDescriptorMethods(descriptor_->file(), options_)) { // We don't override the generalized CopyFrom (aka that which @@ -3301,6 +3769,9 @@ format("}\n"); } +void MessageGenerator::GenerateVerify(io::Printer* printer) { +} + void MessageGenerator::GenerateSerializeOneofFields( io::Printer* printer, const std::vector<const FieldDescriptor*>& fields) { Formatter format(printer, variables_); @@ -3376,11 +3847,12 @@ format("// Extension range [$start$, $end$)\n"); format( "target = _extensions_._InternalSerialize(\n" - " $start$, $end$, target, stream);\n\n"); + "internal_default_instance(), $start$, $end$, target, stream);\n\n"); } void MessageGenerator::GenerateSerializeWithCachedSizesToArray( io::Printer* printer) { + if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); if (descriptor_->options().message_set_wire_format()) { // Special-case MessageSet. @@ -3390,7 +3862,8 @@ "const {\n" "$annotate_serialize$" " target = _extensions_." - "InternalSerializeMessageSetWithCachedSizesToArray(target, stream);\n"); + "InternalSerializeMessageSetWithCachedSizesToArray(\n" // + "internal_default_instance(), target, stream);\n"); std::map<std::string, std::string> vars; SetUnknownFieldsVariable(descriptor_, options_, &vars); format.AddMap(vars); @@ -3443,6 +3916,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( io::Printer* printer) { + if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); // If there are multiple fields in a row from the same oneof then we // coalesce them and emit a switch statement. This is more efficient @@ -3759,6 +4233,7 @@ } void MessageGenerator::GenerateByteSize(io::Printer* printer) { + if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); if (descriptor_->options().message_set_wire_format()) { @@ -3987,37 +4462,37 @@ format("total_size += _weak_field_map_.ByteSizeLong();\n"); } - format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n"); if (UseUnknownFieldSet(descriptor_->file(), options_)) { // We go out of our way to put the computation of the uncommon path of // unknown fields in tail position. This allows for better code generation // of this function for simple protos. format( - " return ::$proto_ns$::internal::ComputeUnknownFieldsSize(\n" - " _internal_metadata_, total_size, &_cached_size_);\n"); + "return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);\n"); } else { + format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n"); format(" total_size += $unknown_fields$.size();\n"); - } - format("}\n"); + format("}\n"); - // We update _cached_size_ even though this is a const method. Because - // const methods might be called concurrently this needs to be atomic - // operations or the program is undefined. In practice, since any concurrent - // writes will be writing the exact same value, normal writes will work on - // all common processors. We use a dedicated wrapper class to abstract away - // the underlying atomic. This makes it easier on platforms where even relaxed - // memory order might have perf impact to replace it with ordinary loads and - // stores. - format( - "int cached_size = ::$proto_ns$::internal::ToCachedSize(total_size);\n" - "SetCachedSize(cached_size);\n" - "return total_size;\n"); + // We update _cached_size_ even though this is a const method. Because + // const methods might be called concurrently this needs to be atomic + // operations or the program is undefined. In practice, since any + // concurrent writes will be writing the exact same value, normal writes + // will work on all common processors. We use a dedicated wrapper class to + // abstract away the underlying atomic. This makes it easier on platforms + // where even relaxed memory order might have perf impact to replace it with + // ordinary loads and stores. + format( + "int cached_size = ::$proto_ns$::internal::ToCachedSize(total_size);\n" + "SetCachedSize(cached_size);\n" + "return total_size;\n"); + } format.Outdent(); format("}\n"); } void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { + if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); format("bool $classname$::IsInitialized() const {\n"); format.Indent();
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index 339d6e7..64af2bf 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -134,6 +134,7 @@ // Generate standard Message methods. void GenerateClear(io::Printer* printer); void GenerateOneofClear(io::Printer* printer); + void GenerateVerify(io::Printer* printer); void GenerateSerializeWithCachedSizes(io::Printer* printer); void GenerateSerializeWithCachedSizesToArray(io::Printer* printer); void GenerateSerializeWithCachedSizesBody(io::Printer* printer); @@ -177,6 +178,7 @@ bool copy_constructor) const; size_t HasBitsSize() const; + size_t InlinedStringDonatedSize() const; int HasBitIndex(const FieldDescriptor* a) const; int HasByteIndex(const FieldDescriptor* a) const; int HasWordIndex(const FieldDescriptor* a) const; @@ -196,6 +198,13 @@ std::vector<const FieldDescriptor*> optimized_order_; std::vector<int> has_bit_indices_; int max_has_bit_index_; + + // A map from field index to inlined_string index. For non-inlined-string + // fields, the element is -1. + std::vector<int> inlined_string_indices_; + // The count of inlined_string fields in the message. + int max_inlined_string_index_; + std::vector<const EnumGenerator*> enum_generators_; std::vector<const ExtensionGenerator*> extension_generators_; int num_required_fields_;
diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h index 2e97c3d..57cef2f 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h
@@ -33,6 +33,7 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__ #define GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__ +#include <set> #include <string> namespace google { @@ -49,6 +50,11 @@ kLiteRuntime, }; +struct FieldListenerOptions { + bool inject_field_listener_events = false; + std::set<std::string> forbidden_field_listener_events; +}; + // Generator options (see generator.cc for a description of each): struct Options { std::string dllexport_decl; @@ -64,6 +70,8 @@ bool opensource_runtime = false; bool annotate_accessor = false; bool unused_field_stripping = false; + bool profile_driven_inline_string = false; + bool force_inline_string = false; std::string runtime_include_base; int num_cc_files = 0; std::string annotation_pragma_name; @@ -74,7 +82,7 @@ kTCTableGuarded, kTCTableAlways } tctable_mode = kTCTableNever; - bool inject_field_listener_events = false; + FieldListenerOptions field_listener_options; bool eagerly_verified_lazy = false; bool force_eagerly_verified_lazy = false; };
diff --git a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc index 6886b4f..3991d12 100644 --- a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
@@ -30,7 +30,9 @@ #include <google/protobuf/compiler/cpp/cpp_parse_function_generator.h> +#include <algorithm> #include <limits> +#include <string> #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/wire_format.h> @@ -64,16 +66,6 @@ return ctype == FieldOptions::STRING || ctype == FieldOptions::CORD; } -bool IsTcTableEnabled(const Options& options) { - return options.tctable_mode == Options::kTCTableAlways; -} -bool IsTcTableGuarded(const Options& options) { - return options.tctable_mode == Options::kTCTableGuarded; -} -bool IsTcTableDisabled(const Options& options) { - return options.tctable_mode == Options::kTCTableNever; -} - int TagSize(uint32_t field_number) { if (field_number < 16) return 1; GOOGLE_CHECK_LT(field_number, (1 << 14)) @@ -81,22 +73,38 @@ return 2; } +const char* CodedTagType(int tag_size) { + return tag_size == 1 ? "uint8_t" : "uint16_t"; +} + const char* TagType(const FieldDescriptor* field) { return CodedTagType(TagSize(field->number())); } -std::string MessageParseFunctionName(const FieldDescriptor* field, - const Options& options) { - std::string name = - "::" + ProtobufNamespace(options) + "::internal::TcParserBase::"; - if (field->is_repeated()) { - name.append("Repeated"); - } else { - name.append("Singular"); +std::string TcParserBaseName(const Options& options) { + return StrCat("::", ProtobufNamespace(options), + "::internal::TcParserBase::"); +} + +std::string MessageTcParseFunctionName(const FieldDescriptor* field, + const Options& options) { + if (field->message_type()->field_count() == 0 || + !HasGeneratedMethods(field->message_type()->file(), options)) { + // For files with `option optimize_for = CODE_SIZE`, or which derive from + // `ZeroFieldsBase`, we need to call the `_InternalParse` function, because + // there is no generated tailcall function. For tailcall parsing, this is + // done by helpers in TcParserBase. + return StrCat(TcParserBaseName(options), + (field->is_repeated() ? "Repeated" : "Singular"), + "ParseMessage<", + QualifiedClassName(field->message_type()), // + ", ", TagType(field), ">"); } - name.append("ParseMessage<" + QualifiedClassName(field->message_type()) + - ", " + TagType(field) + ">"); - return name; + // This matches macros in generated_message_tctable_impl.h: + return StrCat("PROTOBUF_TC_PARSE_", + (field->is_repeated() ? "REPEATED" : "SINGULAR"), + TagSize(field->number()), "(", + QualifiedClassName(field->message_type()), ")"); } std::string FieldParseFunctionName(const FieldDescriptor* field, @@ -105,10 +113,6 @@ } // namespace -const char* CodedTagType(int tag_size) { - return tag_size == 1 ? "uint8_t" : "uint16_t"; -} - TailCallTableInfo::TailCallTableInfo(const Descriptor* descriptor, const Options& options, const std::vector<int>& has_bit_indices, @@ -139,9 +143,9 @@ // Anything difficult slow path: if (field->is_map()) continue; if (field->real_containing_oneof()) continue; - if (field->options().lazy()) continue; if (field->options().weak()) continue; if (IsImplicitWeakField(field, options, scc_analyzer)) continue; + if (IsLazy(field, options, scc_analyzer)) continue; // The largest tag that can be read by the tailcall parser is two bytes // when varint-coded. This allows 14 bits for the numeric tag value: @@ -189,7 +193,7 @@ switch (field->type()) { case FieldDescriptor::TYPE_MESSAGE: - name = MessageParseFunctionName(field, options); + name = MessageTcParseFunctionName(field, options); break; case FieldDescriptor::TYPE_FIXED64: @@ -230,16 +234,6 @@ fast_path_fields[idx].field = field; } - // Construct a mask of has-bits for required fields numbered <= 32. - has_hasbits_required_mask = 0; - for (auto field : FieldRange(descriptor)) { - if (field->is_required()) { - int idx = has_bit_indices[field->index()]; - if (idx >= 32) continue; - has_hasbits_required_mask |= 1u << idx; - } - } - // If there are no fallback fields, and at most one extension range, the // parser can use a generic fallback function. Otherwise, a message-specific // fallback routine is needed. @@ -249,15 +243,17 @@ ParseFunctionGenerator::ParseFunctionGenerator( const Descriptor* descriptor, int max_has_bit_index, - const std::vector<int>& has_bit_indices, const Options& options, + const std::vector<int>& has_bit_indices, + const std::vector<int>& inlined_string_indices, const Options& options, MessageSCCAnalyzer* scc_analyzer, const std::map<std::string, std::string>& vars) : descriptor_(descriptor), scc_analyzer_(scc_analyzer), options_(options), variables_(vars), + inlined_string_indices_(inlined_string_indices), num_hasbits_(max_has_bit_index) { - if (IsTcTableGuarded(options_) || IsTcTableEnabled(options_)) { + if (should_generate_tctable()) { tc_table_info_.reset(new TailCallTableInfo(descriptor_, options_, has_bit_indices, scc_analyzer)); } @@ -268,28 +264,46 @@ void ParseFunctionGenerator::GenerateMethodDecls(io::Printer* printer) { Formatter format(printer, variables_); - if (IsTcTableGuarded(options_)) { - format.Outdent(); - format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); - format.Indent(); - } - if (IsTcTableGuarded(options_) || IsTcTableEnabled(options_)) { - if (tc_table_info_->use_generated_fallback) { - format( - "static const char* Tct_ParseFallback(\n" - " ::$proto_ns$::MessageLite *msg, const char *ptr,\n" - " ::$proto_ns$::internal::ParseContext *ctx,\n" - " const ::$proto_ns$::internal::TailCallParseTableBase *table,\n" - " uint64_t hasbits, ::$proto_ns$::internal::TcFieldData data);\n" - "inline const char* Tct_FallbackImpl(\n" - " const char* ptr, ::$proto_ns$::internal::ParseContext* ctx,\n" - " const void*, $uint64$ hasbits);\n"); + if (should_generate_tctable()) { + auto declare_function = [&format](const char* name, + const std::string& guard) { + if (!guard.empty()) { + format.Outdent(); + format("#if $1$\n", guard); + format.Indent(); + } + format("static const char* $1$(PROTOBUF_TC_PARAM_DECL);\n", name); + if (!guard.empty()) { + format.Outdent(); + format("#endif // $1$\n", guard); + format.Indent(); + } + }; + if (should_generate_guarded_tctable()) { + format.Outdent(); + format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); + format.Indent(); } - } - if (IsTcTableGuarded(options_)) { - format.Outdent(); - format("#endif\n"); - format.Indent(); + format("// The Tct_* functions are internal to the protobuf runtime:\n"); + // These guards are defined in port_def.inc: + declare_function("Tct_ParseS1", "PROTOBUF_TC_STATIC_PARSE_SINGULAR1"); + declare_function("Tct_ParseS2", "PROTOBUF_TC_STATIC_PARSE_SINGULAR2"); + declare_function("Tct_ParseR1", "PROTOBUF_TC_STATIC_PARSE_REPEATED1"); + declare_function("Tct_ParseR2", "PROTOBUF_TC_STATIC_PARSE_REPEATED2"); + if (tc_table_info_->use_generated_fallback) { + format.Outdent(); + format( + " private:\n" + " "); + declare_function("Tct_ParseFallback", ""); + format(" public:\n"); + format.Indent(); + } + if (should_generate_guarded_tctable()) { + format.Outdent(); + format("#endif\n"); + format.Indent(); + } } format( "const char* _InternalParse(const char* ptr, " @@ -298,8 +312,10 @@ void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) { Formatter format(printer, variables_); + bool need_parse_function = true; if (descriptor_->options().message_set_wire_format()) { // Special-case MessageSet. + need_parse_function = false; format( "const char* $classname$::_InternalParse(const char* ptr,\n" " ::$proto_ns$::internal::ParseContext* ctx) {\n" @@ -307,85 +323,157 @@ " return _extensions_.ParseMessageSet(ptr, \n" " internal_default_instance(), &_internal_metadata_, ctx);\n" "}\n"); + } + if (!should_generate_tctable()) { + if (need_parse_function) { + GenerateLoopingParseFunction(format); + } return; } - if (IsTcTableGuarded(options_)) { + if (should_generate_guarded_tctable()) { format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n"); } - if (IsTcTableGuarded(options_) || IsTcTableEnabled(options_)) { - format( - "const char* $classname$::_InternalParse(\n" - " const char* ptr, ::$proto_ns$::internal::ParseContext* ctx) {\n" - " return ::$proto_ns$::internal::TcParser<$1$>::ParseLoop(\n" - " this, ptr, ctx, &_table_.header);\n" - "}\n" - "\n", - tc_table_info_->table_size_log2); - if (tc_table_info_->use_generated_fallback) { - GenerateTailcallFallbackFunction(format); + if (need_parse_function) { + GenerateTailcallParseFunction(format); + } + if (tc_table_info_->use_generated_fallback) { + GenerateTailcallFallbackFunction(format); + } + GenerateTailcallFieldParseFunctions(format); + if (should_generate_guarded_tctable()) { + if (need_parse_function) { + format("\n#else // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n"); + GenerateLoopingParseFunction(format); } - } - if (IsTcTableGuarded(options_)) { - format("\n#else // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n"); - } - if (IsTcTableGuarded(options_) || IsTcTableDisabled(options_)) { - GenerateLoopingParseFunction(format); - } - if (IsTcTableGuarded(options_)) { format("\n#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); } } +bool ParseFunctionGenerator::should_generate_tctable() const { + if (options_.tctable_mode == Options::kTCTableNever) { + return false; + } + return true; +} + +void ParseFunctionGenerator::GenerateTailcallParseFunction(Formatter& format) { + GOOGLE_CHECK(should_generate_tctable()); + + // Generate an `_InternalParse` that starts the tail-calling loop. + format( + "const char* $classname$::_InternalParse(\n" + " const char* ptr, ::$proto_ns$::internal::ParseContext* ctx) {\n" + "$annotate_deserialize$" + " ptr = ::$proto_ns$::internal::TcParser<$1$>::ParseLoop(\n" + " this, ptr, ctx, &_table_.header);\n", + tc_table_info_->table_size_log2); + format( + " return ptr;\n" + "}\n\n"); +} + void ParseFunctionGenerator::GenerateTailcallFallbackFunction( Formatter& format) { + GOOGLE_CHECK(should_generate_tctable()); format( "const char* $classname$::Tct_ParseFallback(PROTOBUF_TC_PARAM_DECL) {\n" - " return static_cast<$classname$*>(msg)->Tct_FallbackImpl(ptr, ctx, " - "table, hasbits);\n" - "}\n\n"); - - format( - "const char* $classname$::Tct_FallbackImpl(const char* ptr, " - "::$proto_ns$::internal::ParseContext* ctx, const void*, " - "$uint64$ hasbits) {\n" "#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) return nullptr\n"); format.Indent(); + format("auto* typed_msg = static_cast<$classname$*>(msg);\n"); if (num_hasbits_ > 0) { // Sync hasbits - format("_has_bits_[0] = hasbits;\n"); + format("typed_msg->_has_bits_[0] = hasbits;\n"); } - format.Set("has_bits", "_has_bits_"); - format.Set("continue", "goto success"); + format.Set("msg", "typed_msg->"); + format.Set("this", "typed_msg"); + format.Set("has_bits", "typed_msg->_has_bits_"); + format.Set("next_tag", "goto next_tag"); GenerateParseIterationBody(format, descriptor_, tc_table_info_->fallback_fields); format.Outdent(); - format("success:\n"); - format(" return ptr;\n"); format( + "next_tag:\n" + "message_done:\n" + " return ptr;\n" "#undef CHK_\n" "}\n"); } +void ParseFunctionGenerator::GenerateTailcallFieldParseFunctions( + Formatter& format) { + GOOGLE_CHECK(should_generate_tctable()); + // There are four cases where a tailcall target are needed for messages: + // {singular, repeated} x {1, 2}-byte tag + struct { + const char* type; + int size; + } const kTagLayouts[] = { + {"uint8_t", 1}, + {"uint16_t", 2}, + }; + // Singular: + for (const auto& layout : kTagLayouts) { + // Guard macros are defined in port_def.inc. + format( + "#if PROTOBUF_TC_STATIC_PARSE_SINGULAR$1$\n" + "const char* $classname$::Tct_ParseS$1$(PROTOBUF_TC_PARAM_DECL) {\n" + " if (PROTOBUF_PREDICT_FALSE(data.coded_tag<$2$>() != 0))\n" + " PROTOBUF_MUSTTAIL " + "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n" + " ptr += $1$;\n" + " hasbits |= (uint64_t{1} << data.hasbit_idx());\n" + " ::$proto_ns$::internal::TcParserBase::SyncHasbits" + "(msg, hasbits, table);\n" + " auto& field = ::$proto_ns$::internal::TcParserBase::" + "RefAt<$classtype$*>(msg, data.offset());\n" + " if (field == nullptr)\n" + " field = CreateMaybeMessage<$classtype$>(ctx->data().arena);\n" + " return ctx->ParseMessage(field, ptr);\n" + "}\n" + "#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR$1$\n", + layout.size, layout.type); + } + // Repeated: + for (const auto& layout : kTagLayouts) { + // Guard macros are defined in port_def.inc. + format( + "#if PROTOBUF_TC_STATIC_PARSE_REPEATED$1$\n" + "const char* $classname$::Tct_ParseR$1$(PROTOBUF_TC_PARAM_DECL) {\n" + " if (PROTOBUF_PREDICT_FALSE(data.coded_tag<$2$>() != 0)) {\n" + " PROTOBUF_MUSTTAIL " + "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n" + " }\n" + " ptr += $1$;\n" + " auto& field = ::$proto_ns$::internal::TcParserBase::RefAt<" + "::$proto_ns$::RepeatedPtrField<$classname$>>(msg, data.offset());\n" + " ::$proto_ns$::internal::TcParserBase::SyncHasbits" + "(msg, hasbits, table);\n" + " ptr = ctx->ParseMessage(field.Add(), ptr);\n" + " return ptr;\n" + "}\n" + "#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED$1$\n", + layout.size, layout.type); + } +} + void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) { - if (descriptor_->options().message_set_wire_format()) { + if (!should_generate_tctable()) { return; } Formatter format(printer, variables_); - if (IsTcTableGuarded(options_)) { + if (should_generate_guarded_tctable()) { format.Outdent(); format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); format.Indent(); } - if (IsTcTableGuarded(options_) || IsTcTableEnabled(options_)) { - format( - "static const ::$proto_ns$::internal::TailCallParseTable<$1$>\n" - " _table_;\n", - tc_table_info_->table_size_log2); - } - if (IsTcTableGuarded(options_)) { + format( + "static const ::$proto_ns$::internal::TailCallParseTable<$1$>\n" + " _table_;\n", + tc_table_info_->table_size_log2); + if (should_generate_guarded_tctable()) { format.Outdent(); format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); format.Indent(); @@ -393,17 +481,15 @@ } void ParseFunctionGenerator::GenerateDataDefinitions(io::Printer* printer) { - if (descriptor_->options().message_set_wire_format()) { + if (!should_generate_tctable()) { return; } Formatter format(printer, variables_); - if (IsTcTableGuarded(options_)) { + if (should_generate_guarded_tctable()) { format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); } - if (IsTcTableGuarded(options_) || IsTcTableEnabled(options_)) { - GenerateTailCallTable(format); - } - if (IsTcTableGuarded(options_)) { + GenerateTailCallTable(format); + if (should_generate_guarded_tctable()) { format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); } } @@ -415,6 +501,8 @@ "$annotate_deserialize$" "#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure\n"); format.Indent(); + format.Set("msg", ""); + format.Set("this", "this"); int hasbits_size = 0; if (num_hasbits_ > 0) { hasbits_size = (num_hasbits_ + 31) / 32; @@ -427,7 +515,7 @@ } else { format.Set("has_bits", "_has_bits_"); } - format.Set("continue", "continue"); + format.Set("next_tag", "continue"); format("while (!ctx->Done(&ptr)) {\n"); format.Indent(); @@ -438,26 +526,26 @@ format("} // while\n"); format.Outdent(); - format("success:\n"); + format("message_done:\n"); if (hasbits_size) format(" _has_bits_.Or(has_bits);\n"); format( " return ptr;\n" "failure:\n" " ptr = nullptr;\n" - " goto success;\n" + " goto message_done;\n" "#undef CHK_\n" "}\n"); } void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { + GOOGLE_CHECK(should_generate_tctable()); // All entries without a fast-path parsing function need a fallback. std::string fallback; if (tc_table_info_->use_generated_fallback) { fallback = ClassName(descriptor_) + "::Tct_ParseFallback"; } else { - fallback = "::" + ProtobufNamespace(options_) + - "::internal::TcParserBase::GenericFallback"; + fallback = TcParserBaseName(options_) + "GenericFallback"; if (GetOptimizeFor(descriptor_->file(), options_) == FileOptions::LITE_RUNTIME) { fallback += "Lite"; @@ -493,10 +581,8 @@ format("0, 0, 0, // no _extensions_\n"); } format( - "$1$, // has_bits_required_mask\n" - "&$2$._instance,\n" - "$3$ // fallback\n", - tc_table_info_->has_hasbits_required_mask, + "&$1$._instance,\n" + "$2$ // fallback\n", DefaultInstanceName(descriptor_, options_), fallback); format.Outdent(); format("}, {\n"); @@ -536,13 +622,25 @@ "::" + MakeDefaultName(field) + ".get()"; format( "if (arena != nullptr) {\n" - " ptr = ctx->ReadArenaString(ptr, &$1$_, arena);\n" + " ptr = ctx->ReadArenaString(ptr, &$msg$$name$_, arena"); + if (IsStringInlined(field, options_)) { + GOOGLE_DCHECK(!inlined_string_indices_.empty()); + int inlined_string_index = inlined_string_indices_[field->index()]; + GOOGLE_DCHECK_GE(inlined_string_index, 0); + format( + ", $msg$_internal_$name$_donated(), &_inlined_string_donated_[$1$], " + "~0x$2$u", + inlined_string_index / 32, + strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8)); + } + format( + ");\n" "} else {\n" " ptr = ::$proto_ns$::internal::InlineGreedyStringParser(" - "$1$_.MutableNoArenaNoDefault(&$2$), ptr, ctx);\n" + "$msg$$name$_.MutableNoArenaNoDefault(&$1$), ptr, ctx);\n" "}\n" - "const std::string* str = &$1$_.Get(); (void)str;\n", - FieldName(field), default_string); + "const std::string* str = &$msg$$name$_.Get(); (void)str;\n", + default_string); } void ParseFunctionGenerator::GenerateStrings(Formatter& format, @@ -560,24 +658,24 @@ !field->real_containing_oneof() && ctype == FieldOptions::STRING) { GenerateArenaString(format, field); } else { - std::string name; + std::string parser_name; switch (ctype) { case FieldOptions::STRING: - name = "GreedyStringParser"; + parser_name = "GreedyStringParser"; break; case FieldOptions::CORD: - name = "CordParser"; + parser_name = "CordParser"; break; case FieldOptions::STRING_PIECE: - name = "StringPieceParser"; + parser_name = "StringPieceParser"; break; } format( - "auto str = $1$$2$_$3$();\n" - "ptr = ::$proto_ns$::internal::Inline$4$(str, ptr, ctx);\n", + "auto str = $msg$$1$$2$_$name$();\n" + "ptr = ::$proto_ns$::internal::Inline$3$(str, ptr, ctx);\n", HasInternalAccessors(ctype) ? "_internal_" : "", field->is_repeated() && !field->is_packable() ? "add" : "mutable", - FieldName(field), name); + parser_name); } if (!check_utf8) return; // return if this is a bytes field auto level = GetUtf8CheckMode(field, options_); @@ -614,24 +712,20 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, const FieldDescriptor* field) { if (field->is_packable()) { - std::string enum_validator; if (field->type() == FieldDescriptor::TYPE_ENUM && !HasPreservingUnknownEnumSemantics(field)) { - enum_validator = - StrCat(", ", QualifiedClassName(field->enum_type(), options_), - "_IsValid, &_internal_metadata_, ", field->number()); + std::string enum_type = QualifiedClassName(field->enum_type(), options_); format( "ptr = " "::$proto_ns$::internal::Packed$1$Parser<$unknown_fields_type$>(" - "_internal_mutable_$2$(), ptr, ctx$3$);\n", - DeclaredTypeMethodName(field->type()), FieldName(field), - enum_validator); + "$msg$_internal_mutable_$name$(), ptr, ctx, $2$_IsValid, " + "&$msg$_internal_metadata_, $3$);\n", + DeclaredTypeMethodName(field->type()), enum_type, field->number()); } else { format( "ptr = ::$proto_ns$::internal::Packed$1$Parser(" - "_internal_mutable_$2$(), ptr, ctx$3$);\n", - DeclaredTypeMethodName(field->type()), FieldName(field), - enum_validator); + "$msg$_internal_mutable_$name$(), ptr, ctx);\n", + DeclaredTypeMethodName(field->type())); } } else { auto field_type = field->type(); @@ -651,61 +745,59 @@ !HasPreservingUnknownEnumSemantics(field)) { format( "auto object = " - "::$proto_ns$::internal::InitEnumParseWrapper<$unknown_" - "fields_type$>(" - "&$1$_, $2$_IsValid, $3$, &_internal_metadata_);\n" + "::$proto_ns$::internal::InitEnumParseWrapper<" + "$unknown_fields_type$>(&$msg$$name$_, $1$_IsValid, " + "$2$, &$msg$_internal_metadata_);\n" "ptr = ctx->ParseMessage(&object, ptr);\n", - FieldName(field), QualifiedClassName(val->enum_type()), + QualifiedClassName(val->enum_type(), options_), field->number()); } else { - format("ptr = ctx->ParseMessage(&$1$_, ptr);\n", FieldName(field)); + format("ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n"); } } else if (IsLazy(field, options_, scc_analyzer_)) { if (field->real_containing_oneof()) { format( - "if (!_internal_has_$1$()) {\n" - " clear_$2$();\n" - " $2$_.$1$_ = ::$proto_ns$::Arena::CreateMessage<\n" + "if (!$msg$_internal_has_$name$()) {\n" + " $msg$clear_$1$();\n" + " $msg$$1$_.$name$_ = ::$proto_ns$::Arena::CreateMessage<\n" " ::$proto_ns$::internal::LazyField>(" - "GetArenaForAllocation());\n" - " set_has_$1$();\n" + "$msg$GetArenaForAllocation());\n" + " $msg$set_has_$name$();\n" "}\n" - "ptr = ctx->ParseMessage($2$_.$1$_, ptr);\n", - FieldName(field), field->containing_oneof()->name()); + "ptr = ctx->ParseMessage($msg$$1$_.$name$_, ptr);\n", + field->containing_oneof()->name()); } else if (HasHasbit(field)) { format( - "_Internal::set_has_$1$(&$has_bits$);\n" - "ptr = ctx->ParseMessage(&$1$_, ptr);\n", - FieldName(field)); + "_Internal::set_has_$name$(&$has_bits$);\n" + "ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n"); } else { - format("ptr = ctx->ParseMessage(&$1$_, ptr);\n", FieldName(field)); + format("ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n"); } } else if (IsImplicitWeakField(field, options_, scc_analyzer_)) { if (!field->is_repeated()) { format( - "ptr = ctx->ParseMessage(_Internal::mutable_$1$(this), " - "ptr);\n", - FieldName(field)); + "ptr = ctx->ParseMessage(_Internal::mutable_$name$($this$), " + "ptr);\n"); } else { format( - "ptr = ctx->ParseMessage($1$_.AddWeak(reinterpret_cast<const " - "::$proto_ns$::MessageLite*>($2$::_$3$_default_instance_ptr_)" + "ptr = ctx->ParseMessage($msg$$name$_.AddWeak(" + "reinterpret_cast<const ::$proto_ns$::MessageLite*>($1$ptr_)" "), ptr);\n", - FieldName(field), Namespace(field->message_type(), options_), - ClassName(field->message_type())); + QualifiedDefaultInstanceName(field->message_type(), options_)); } } else if (IsWeak(field, options_)) { format( "{\n" " auto* default_ = &reinterpret_cast<const Message&>($1$);\n" - " ptr = ctx->ParseMessage(_weak_field_map_.MutableMessage($2$," - " default_), ptr);\n" + " ptr = ctx->ParseMessage($msg$_weak_field_map_.MutableMessage(" + "$2$, default_), ptr);\n" "}\n", QualifiedDefaultInstanceName(field->message_type(), options_), field->number()); } else { - format("ptr = ctx->ParseMessage(_internal_$1$_$2$(), ptr);\n", - field->is_repeated() ? "add" : "mutable", FieldName(field)); + format( + "ptr = ctx->ParseMessage($msg$_internal_$mutable_field$(), " + "ptr);\n"); } break; } @@ -728,29 +820,39 @@ void ParseFunctionGenerator::GenerateFieldBody( Formatter& format, WireFormatLite::WireType wiretype, const FieldDescriptor* field) { + Formatter::SaveState formatter_state(&format); + format.AddMap( + {{"name", FieldName(field)}, + {"primitive_type", PrimitiveTypeName(options_, field->cpp_type())}}); + if (field->is_repeated()) { + format.AddMap({{"put_field", StrCat("add_", FieldName(field))}, + {"mutable_field", StrCat("add_", FieldName(field))}}); + } else { + format.AddMap( + {{"put_field", StrCat("set_", FieldName(field))}, + {"mutable_field", StrCat("mutable_", FieldName(field))}}); + } uint32_t tag = WireFormatLite::MakeTag(field->number(), wiretype); switch (wiretype) { case WireFormatLite::WIRETYPE_VARINT: { std::string type = PrimitiveTypeName(options_, field->cpp_type()); - std::string prefix = field->is_repeated() ? "add" : "set"; if (field->type() == FieldDescriptor::TYPE_ENUM) { + format.Set("enum_type", + QualifiedClassName(field->enum_type(), options_)); format( "$uint64$ val = ::$proto_ns$::internal::ReadVarint64(&ptr);\n" "CHK_(ptr);\n"); if (!HasPreservingUnknownEnumSemantics(field)) { - format("if (PROTOBUF_PREDICT_TRUE($1$_IsValid(val))) {\n", - QualifiedClassName(field->enum_type(), options_)); + format("if (PROTOBUF_PREDICT_TRUE($enum_type$_IsValid(val))) {\n"); format.Indent(); } - format("_internal_$1$_$2$(static_cast<$3$>(val));\n", prefix, - FieldName(field), - QualifiedClassName(field->enum_type(), options_)); + format("$msg$_internal_$put_field$(static_cast<$enum_type$>(val));\n"); if (!HasPreservingUnknownEnumSemantics(field)) { format.Outdent(); format( "} else {\n" " ::$proto_ns$::internal::WriteVarint(" - "$1$, val, mutable_unknown_fields());\n" + "$1$, val, $msg$mutable_unknown_fields());\n" "}\n", field->number()); } @@ -765,42 +867,38 @@ zigzag = "ZigZag"; } if (field->is_repeated() || field->real_containing_oneof()) { - std::string prefix = field->is_repeated() ? "add" : "set"; format( - "_internal_$1$_$2$(" - "::$proto_ns$::internal::ReadVarint$3$$4$(&ptr));\n" + "$msg$_internal_$put_field$(" + "::$proto_ns$::internal::ReadVarint$1$$2$(&ptr));\n" "CHK_(ptr);\n", - prefix, FieldName(field), zigzag, size); + zigzag, size); } else { if (HasHasbit(field)) { - format("_Internal::set_has_$1$(&$has_bits$);\n", FieldName(field)); + format("_Internal::set_has_$name$(&$has_bits$);\n"); } format( - "$1$_ = ::$proto_ns$::internal::ReadVarint$2$$3$(&ptr);\n" + "$msg$$name$_ = ::$proto_ns$::internal::ReadVarint$1$$2$(&ptr);\n" "CHK_(ptr);\n", - FieldName(field), zigzag, size); + zigzag, size); } } break; } case WireFormatLite::WIRETYPE_FIXED32: case WireFormatLite::WIRETYPE_FIXED64: { - std::string type = PrimitiveTypeName(options_, field->cpp_type()); if (field->is_repeated() || field->real_containing_oneof()) { - std::string prefix = field->is_repeated() ? "add" : "set"; format( - "_internal_$1$_$2$(" - "::$proto_ns$::internal::UnalignedLoad<$3$>(ptr));\n" - "ptr += sizeof($3$);\n", - prefix, FieldName(field), type); + "$msg$_internal_$put_field$(" + "::$proto_ns$::internal::UnalignedLoad<$primitive_type$>(ptr));\n" + "ptr += sizeof($primitive_type$);\n"); } else { if (HasHasbit(field)) { - format("_Internal::set_has_$1$(&$has_bits$);\n", FieldName(field)); + format("_Internal::set_has_$name$(&$has_bits$);\n"); } format( - "$1$_ = ::$proto_ns$::internal::UnalignedLoad<$2$>(ptr);\n" - "ptr += sizeof($2$);\n", - FieldName(field), type); + "$msg$$name$_ = " + "::$proto_ns$::internal::UnalignedLoad<$primitive_type$>(ptr);\n" + "ptr += sizeof($primitive_type$);\n"); } break; } @@ -811,9 +909,9 @@ } case WireFormatLite::WIRETYPE_START_GROUP: { format( - "ptr = ctx->ParseGroup(_internal_$1$_$2$(), ptr, $3$);\n" + "ptr = ctx->ParseGroup($msg$_internal_$mutable_field$(), ptr, $1$);\n" "CHK_(ptr);\n", - field->is_repeated() ? "add" : "mutable", FieldName(field), tag); + tag); break; } case WireFormatLite::WIRETYPE_END_GROUP: { @@ -845,14 +943,90 @@ return expected_tag; } +// These variables are used by the generated parse iteration, and must already +// be defined in the generated code: +// - `const char* ptr`: the input buffer. +// - `ParseContext* ctx`: the associated context for `ptr`. +// - implicit `this`: i.e., we must be in a non-static member function. +// +// The macro `CHK_(x)` must be defined. It should return an error condition if +// the macro parameter is false. +// +// Whenever an END_GROUP tag was read, or tag 0 was read, the generated code +// branches to the label `message_done`. +// +// These formatter variables are used: +// - `next_tag`: a single statement to begin parsing the next tag. +// +// At the end of the generated code, the enclosing function should proceed to +// parse the next tag in the stream. void ParseFunctionGenerator::GenerateParseIterationBody( Formatter& format, const Descriptor* descriptor, const std::vector<const FieldDescriptor*>& ordered_fields) { format( "$uint32$ tag;\n" "ptr = ::$proto_ns$::internal::ReadTag(ptr, &tag);\n"); - if (!ordered_fields.empty()) format("switch (tag >> 3) {\n"); + if (!ordered_fields.empty()) { + GenerateFieldSwitch(format, ordered_fields); + // Each field `case` only considers field number. Field numbers that are + // not defined in the message, or tags with an incompatible wire type, are + // considered "unusual" cases. They will be handled by the logic below. + format.Outdent(); + format("handle_unusual:\n"); + format.Indent(); + } + + // Unusual/extension/unknown case: + format( + "if ((tag == 0) || ((tag & 7) == 4)) {\n" + " CHK_(ptr);\n" + " ctx->SetLastTag(tag);\n" + " goto message_done;\n" + "}\n"); + if (IsMapEntryMessage(descriptor)) { + format("$next_tag$;\n"); + } else { + if (descriptor->extension_range_count() > 0) { + format("if ("); + for (int i = 0; i < descriptor->extension_range_count(); i++) { + const Descriptor::ExtensionRange* range = + descriptor->extension_range(i); + if (i > 0) format(" ||\n "); + + uint32_t start_tag = WireFormatLite::MakeTag( + range->start, static_cast<WireFormatLite::WireType>(0)); + uint32_t end_tag = WireFormatLite::MakeTag( + range->end, static_cast<WireFormatLite::WireType>(0)); + + if (range->end > FieldDescriptor::kMaxNumber) { + format("($1$u <= tag)", start_tag); + } else { + format("($1$u <= tag && tag < $2$u)", start_tag, end_tag); + } + } + format( + ") {\n" + " ptr = $msg$_extensions_.ParseField(tag, ptr, " + "internal_default_instance(), &$msg$_internal_metadata_, ctx);\n" + " CHK_(ptr != nullptr);\n" + " $next_tag$;\n" + "}\n"); + } + format( + "ptr = UnknownFieldParse(\n" + " tag,\n" + " $msg$_internal_metadata_.mutable_unknown_fields<" + "$unknown_fields_type$>(),\n" + " ptr, ctx);\n" + "CHK_(ptr != nullptr);\n"); + } +} + +void ParseFunctionGenerator::GenerateFieldSwitch( + Formatter& format, + const std::vector<const FieldDescriptor*>& ordered_fields) { + format("switch (tag >> 3) {\n"); format.Indent(); for (const auto* field : ordered_fields) { @@ -893,61 +1067,18 @@ field); format.Outdent(); } - format.Outdent(); format( - " } else goto handle_unusual;\n" - " $continue$;\n"); + "} else\n" + " goto handle_unusual;\n" + "$next_tag$;\n"); + format.Outdent(); } // for loop over ordered fields - // Default case - if (!ordered_fields.empty()) format("default: {\n"); - if (!ordered_fields.empty()) format("handle_unusual:\n"); format( - " if ((tag == 0) || ((tag & 7) == 4)) {\n" - " CHK_(ptr);\n" - " ctx->SetLastTag(tag);\n" - " goto success;\n" - " }\n"); - if (IsMapEntryMessage(descriptor)) { - format(" $continue$;\n"); - } else { - if (descriptor->extension_range_count() > 0) { - format("if ("); - for (int i = 0; i < descriptor->extension_range_count(); i++) { - const Descriptor::ExtensionRange* range = - descriptor->extension_range(i); - if (i > 0) format(" ||\n "); - - uint32_t start_tag = WireFormatLite::MakeTag( - range->start, static_cast<WireFormatLite::WireType>(0)); - uint32_t end_tag = WireFormatLite::MakeTag( - range->end, static_cast<WireFormatLite::WireType>(0)); - - if (range->end > FieldDescriptor::kMaxNumber) { - format("($1$u <= tag)", start_tag); - } else { - format("($1$u <= tag && tag < $2$u)", start_tag, end_tag); - } - } - format(") {\n"); - format( - " ptr = _extensions_.ParseField(tag, ptr,\n" - " internal_default_instance(), &_internal_metadata_, ctx);\n" - " CHK_(ptr != nullptr);\n" - " $continue$;\n" - "}\n"); - } - format( - " ptr = UnknownFieldParse(tag,\n" - " _internal_metadata_.mutable_unknown_fields<$unknown_" - "fields_type$>(),\n" - " ptr, ctx);\n" - " CHK_(ptr != nullptr);\n" - " $continue$;\n"); - } - if (!ordered_fields.empty()) format("}\n"); // default case + "default:\n" + " goto handle_unusual;\n"); format.Outdent(); - if (!ordered_fields.empty()) format("} // switch\n"); + format("} // switch\n"); } namespace { @@ -1137,31 +1268,30 @@ name.append(CodedTagType(tag_length_bytes)); - std::string tcpb = - StrCat(ProtobufNamespace(options), "::internal::TcParserBase"); - switch (type_format) { case TypeFormat::kVar64: case TypeFormat::kVar32: case TypeFormat::kBool: - name.append(StrCat(", ::", tcpb, "::kNoConversion")); + name.append( + StrCat(", ", TcParserBaseName(options), "kNoConversion")); break; case TypeFormat::kSInt64: case TypeFormat::kSInt32: - name.append(StrCat(", ::", tcpb, "::kZigZag")); + name.append(StrCat(", ", TcParserBaseName(options), "kZigZag")); break; case TypeFormat::kBytes: - name.append(StrCat(", ::", tcpb, "::kNoUtf8")); + name.append(StrCat(", ", TcParserBaseName(options), "kNoUtf8")); break; case TypeFormat::kString: - name.append(StrCat(", ::", tcpb, "::kUtf8")); + name.append(StrCat(", ", TcParserBaseName(options), "kUtf8")); break; case TypeFormat::kStringValidateOnly: - name.append(StrCat(", ::", tcpb, "::kUtf8ValidateOnly")); + name.append( + StrCat(", ", TcParserBaseName(options), "kUtf8ValidateOnly")); break; default:
diff --git a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h index 116353a..793e6ae 100644 --- a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h +++ b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h
@@ -76,6 +76,7 @@ public: ParseFunctionGenerator(const Descriptor* descriptor, int max_has_bit_index, const std::vector<int>& has_bit_indices, + const std::vector<int>& inlined_string_indices, const Options& options, MessageSCCAnalyzer* scc_analyzer, const std::map<std::string, std::string>& vars); @@ -93,9 +94,25 @@ void GenerateDataDefinitions(io::Printer* printer); private: + // Returns true if tailcall table code should be generated. + bool should_generate_tctable() const; + + // Returns true if tailcall table code should be generated, but inside an + // #ifdef guard. + bool should_generate_guarded_tctable() const { + return should_generate_tctable() && + options_.tctable_mode == Options::kTCTableGuarded; + } + + // Generates a tail-calling `_InternalParse` function. + void GenerateTailcallParseFunction(Formatter& format); + // Generates a fallback function for tailcall table-based parsing. void GenerateTailcallFallbackFunction(Formatter& format); + // Generates functions for parsing this message as a field. + void GenerateTailcallFieldParseFunctions(Formatter& format); + // Generates a looping `_InternalParse` function. void GenerateLoopingParseFunction(Formatter& format); @@ -123,18 +140,20 @@ Formatter& format, const Descriptor* descriptor, const std::vector<const FieldDescriptor*>& ordered_fields); + // Generates a `switch` statement to parse each of `ordered_fields`. + void GenerateFieldSwitch( + Formatter& format, + const std::vector<const FieldDescriptor*>& ordered_fields); + const Descriptor* descriptor_; MessageSCCAnalyzer* scc_analyzer_; const Options& options_; std::map<std::string, std::string> variables_; std::unique_ptr<TailCallTableInfo> tc_table_info_; + std::vector<int> inlined_string_indices_; int num_hasbits_; }; -// Returns the integer type that holds a tag of the given length (in bytes) when -// wire-encoded. -const char* CodedTagType(int tag_size); - enum class ParseCardinality { kSingular, kOneof,
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc index 9664586..ffccf08 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -209,10 +209,19 @@ Formatter format(printer, variables_); int fixed_size = FixedSize(descriptor_->type()); if (fixed_size == -1) { - format( - "total_size += $tag_size$ +\n" - " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n" - " this->_internal_$name$());\n"); + if (internal::WireFormat::TagSize(descriptor_->number(), + descriptor_->type()) == 1) { + // Adding one is very common and it turns out it can be done for + // free inside of WireFormatLite, so we can save an instruction here. + format( + "total_size += ::$proto_ns$::internal::WireFormatLite::" + "$declared_type$SizePlusOne(this->_internal_$name$());\n"); + } else { + format( + "total_size += $tag_size$ +\n" + " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n" + " this->_internal_$name$());\n"); + } } else { format("total_size += $tag_size$ + $fixed_size$;\n"); }
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 5c7bb68..be19310 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -104,7 +104,8 @@ StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor, const Options& options) - : FieldGenerator(descriptor, options) { + : FieldGenerator(descriptor, options), + inlined_(IsStringInlined(descriptor, options)) { SetStringVariables(descriptor, &variables_, options); } @@ -112,7 +113,14 @@ void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const { Formatter format(printer, variables_); - format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n"); + if (!inlined_) { + format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n"); + } else { + // `_init_inline_xxx` is used for initializing default instances. + format( + "::$proto_ns$::internal::InlinedStringField $name$_;\n" + "static std::true_type _init_inline_$name$_;\n"); + } } void StringFieldGenerator::GenerateStaticMembers(io::Printer* printer) const { @@ -172,8 +180,13 @@ "const std::string& _internal_$name$() const;\n" "inline PROTOBUF_ALWAYS_INLINE void " "_internal_set_$name$(const std::string& value);\n" - "std::string* _internal_mutable_$name$();\n" - "public:\n"); + "std::string* _internal_mutable_$name$();\n"); + if (inlined_) { + format( + "inline PROTOBUF_ALWAYS_INLINE bool _internal_$name$_donated() " + "const;\n"); + } + format("public:\n"); if (unknown_ctype) { format.Outdent(); @@ -196,16 +209,36 @@ } format( " return _internal_$name$();\n" - "}\n" - "template <typename ArgT0, typename... ArgT>\n" - "inline PROTOBUF_ALWAYS_INLINE\n" - "void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n" - " $set_hasbit$\n" - " $name$_.$setter$($default_value_tag$, static_cast<ArgT0 &&>(arg0)," - " args..., GetArenaForAllocation());\n" - "$annotate_set$" - " // @@protoc_insertion_point(field_set:$full_name$)\n" - "}\n" + "}\n"); + if (!inlined_) { + format( + "template <typename ArgT0, typename... ArgT>\n" + "inline PROTOBUF_ALWAYS_INLINE\n" + "void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n" + " $set_hasbit$\n" + " $name$_.$setter$($default_value_tag$, static_cast<ArgT0 &&>(arg0)," + " args..., GetArenaForAllocation());\n" + "$annotate_set$" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + "}\n"); + } else { + format( + "template <typename ArgT0, typename... ArgT>\n" + "inline PROTOBUF_ALWAYS_INLINE\n" + "void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n" + " $set_hasbit$\n" + " $name$_.$setter$(nullptr, static_cast<ArgT0 &&>(arg0)," + " args..., GetArenaForAllocation(), _internal_$name$_donated(), " + "&$donating_states_word$, $mask_for_undonate$);\n" + "$annotate_set$" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + "}\n" + "inline bool $classname$::_internal_$name$_donated() const {\n" + " bool value = $inlined_string_donated$\n" + " return value;\n" + "}\n"); + } + format( "inline std::string* $classname$::mutable_$name$() {\n" " std::string* _s = _internal_mutable_$name$();\n" "$annotate_mutable$" @@ -217,15 +250,34 @@ "}\n" "inline void $classname$::_internal_set_$name$(const std::string& " "value) {\n" - " $set_hasbit$\n" - " $name$_.Set($default_value_tag$, value, GetArenaForAllocation());\n" - "}\n"); + " $set_hasbit$\n"); + if (!inlined_) { + format( + " $name$_.Set($default_value_tag$, value, GetArenaForAllocation());\n" + "}\n"); + } else { + format( + " $name$_.Set(nullptr, value, GetArenaForAllocation(),\n" + " _internal_$name$_donated(), &$donating_states_word$, " + "$mask_for_undonate$);\n" + "}\n"); + } format( "inline std::string* $classname$::_internal_mutable_$name$() {\n" - " $set_hasbit$\n" - " return $name$_.Mutable($default_variable_or_tag$, " - "GetArenaForAllocation());\n" - "}\n" + " $set_hasbit$\n"); + if (!inlined_) { + format( + " return $name$_.Mutable($default_variable_or_tag$, " + "GetArenaForAllocation());\n" + "}\n"); + } else { + format( + " return $name$_.Mutable($default_variable_or_tag$, " + "GetArenaForAllocation(), _internal_$name$_donated(), " + "&$donating_states_word$, $mask_for_undonate$);\n" + "}\n"); + } + format( "inline std::string* $classname$::$release_name$() {\n" "$annotate_release$" " // @@protoc_insertion_point(field_release:$full_name$)\n"); @@ -235,9 +287,16 @@ " if (!_internal_has_$name$()) {\n" " return nullptr;\n" " }\n" - " $clear_hasbit$\n" - " return $name$_.ReleaseNonDefault($init_value$, " - "GetArenaForAllocation());\n"); + " $clear_hasbit$\n"); + if (!inlined_) { + format( + " return $name$_.ReleaseNonDefault($init_value$, " + "GetArenaForAllocation());\n"); + } else { + format( + " return $name$_.Release(nullptr, GetArenaForAllocation(), " + "_internal_$name$_donated());\n"); + } } else { format( " return $name$_.Release($init_value$, GetArenaForAllocation());\n"); @@ -250,9 +309,19 @@ " $set_hasbit$\n" " } else {\n" " $clear_hasbit$\n" - " }\n" - " $name$_.SetAllocated($init_value$, $name$,\n" - " GetArenaForAllocation());\n" + " }\n"); + if (!inlined_) { + format( + " $name$_.SetAllocated($init_value$, $name$,\n" + " GetArenaForAllocation());\n"); + } else { + // Currently, string fields with default value can't be inlined. + format( + " $name$_.SetAllocated(nullptr, $name$, GetArenaForAllocation(), " + "_internal_$name$_donated(), &$donating_states_word$, " + "$mask_for_undonate$);\n"); + } + format( "$annotate_set$" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" "}\n"); @@ -274,6 +343,7 @@ if (descriptor_->default_value_string().empty()) { format("$name$_.ClearToEmpty();\n"); } else { + GOOGLE_DCHECK(!inlined_); format( "$name$_.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n"); } @@ -292,6 +362,18 @@ // checks against the default variable. const bool must_be_present = HasHasbit(descriptor_); + if (inlined_ && must_be_present) { + // Calling mutable_$name$() gives us a string reference and sets the has bit + // for $name$ (in proto2). We may get here when the string field is inlined + // but the string's contents have not been changed by the user, so we cannot + // make an assertion about the contents of the string and could never make + // an assertion about the string instance. + // + // For non-inlined strings, we distinguish from non-default by comparing + // instances, rather than contents. + format("$DCHK$(!$name$_.IsDefault(nullptr));\n"); + } + if (descriptor_->default_value_string().empty()) { if (must_be_present) { format("$name$_.ClearNonDefaultToEmpty();\n"); @@ -314,16 +396,31 @@ void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format( - "::$proto_ns$::internal::ArenaStringPtr::InternalSwap(\n" - " $init_value$,\n" - " &$name$_, GetArenaForAllocation(),\n" - " &other->$name$_, other->GetArenaForAllocation()\n" - ");\n"); + if (!inlined_) { + format( + "::$proto_ns$::internal::ArenaStringPtr::InternalSwap(\n" + " $init_value$,\n" + " &$name$_, lhs_arena,\n" + " &other->$name$_, rhs_arena\n" + ");\n"); + } else { + // At this point, it's guaranteed that the two fields being swapped are on + // the same arena. + format( + "$name$_.Swap(&other->$name$_, nullptr, GetArenaForAllocation(), " + "_internal_$name$_donated(), other->_internal_$name$_donated(), " + "&$donating_states_word$, &(other->$donating_states_word$), " + "$mask_for_undonate$);\n"); + } } void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const { Formatter format(printer, variables_); + if (inlined_ && descriptor_->default_value_string().empty()) { + // Automatic initialization will construct the string. + return; + } + GOOGLE_DCHECK(!inlined_); format("$name$_.UnsafeSetDefault($init_value$);\n"); } @@ -340,10 +437,16 @@ format.Indent(); - // TODO(gpike): improve this - format( - "$name$_.Set($default_value_tag$, from._internal_$name$(), \n" - " GetArenaForAllocation());\n"); + if (!inlined_) { + format( + "$name$_.Set($default_value_tag$, from._internal_$name$(), \n" + " GetArenaForAllocation());\n"); + } else { + format( + "$name$_.Set(nullptr, from._internal_$name$(),\n" + " GetArenaForAllocation(), _internal_$name$_donated(), " + "&$donating_states_word$, $mask_for_undonate$);\n"); + } format.Outdent(); format("}\n"); @@ -351,6 +454,11 @@ void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { Formatter format(printer, variables_); + if (inlined_) { + // The destructor is automatically invoked. + return; + } + format("$name$_.DestroyNoArena($init_value$);\n"); } @@ -380,6 +488,10 @@ void StringFieldGenerator::GenerateConstinitInitializer( io::Printer* printer) const { Formatter format(printer, variables_); + if (inlined_) { + format("$name$_(nullptr, false)"); + return; + } if (descriptor_->default_value_string().empty()) { format("$name$_(&::$proto_ns$::internal::fixed_address_empty_string)"); } else {
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h index f35cff1..85689bb 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -66,8 +66,10 @@ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; void GenerateConstinitInitializer(io::Printer* printer) const override; + bool IsInlined() const override { return inlined_; } private: + bool inlined_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator); };
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.inc b/src/google/protobuf/compiler/cpp/cpp_unittest.inc index e929da2..24104db 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.inc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.inc
@@ -90,6 +90,8 @@ namespace cpp_unittest { +void DoNothing() {} + class MockErrorCollector : public MultiFileErrorCollector { public: MockErrorCollector() {}
diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc index dd442fe..f154f95 100644 --- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
@@ -569,9 +569,14 @@ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); printer->Print( variables_, + // NB: Do not use the "$name$_converter_" field; the usage of generics + // (and requisite upcasts to Object) prevent optimizations. Even + // without any optimizations, the below code is cheaper because it + // avoids boxing an int and a checkcast from the generics. "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" - " return $name$_converter_.convert($name$_.getInt(index));\n" + " $type$ result = $type$.forNumber($name$_.getInt(index));\n" + " return result == null ? $unknown$ : result;\n" "}\n"); printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) {
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 336a08f..ebd57a7 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -1457,7 +1457,7 @@ io::Printer* printer) const { printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> Unit): " + "inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> kotlin.Unit): " "$message$ " "=\n" " $message_kt$.Dsl._create($message$.newBuilder()).apply { block() " @@ -1482,7 +1482,7 @@ io::Printer* printer) const { printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "inline fun $message$.copy(block: $message_kt$.Dsl.() -> Unit): " + "inline fun $message$.copy(block: $message_kt$.Dsl.() -> kotlin.Unit): " "$message$ =\n" " $message_kt$.Dsl._create(this.toBuilder()).apply { block() " "}._build()\n",
diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc index 13f003b..8f93499 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc
@@ -780,7 +780,7 @@ io::Printer* printer) const { printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> Unit): " + "inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> kotlin.Unit): " "$message$ =\n" " $message_kt$.Dsl._create($message$.newBuilder()).apply { block() " "}._build()\n", @@ -803,7 +803,7 @@ void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers( io::Printer* printer) const { printer->Print( - "inline fun $message$.copy(block: $message_kt$.Dsl.() -> Unit): " + "inline fun $message$.copy(block: $message_kt$.Dsl.() -> kotlin.Unit): " "$message$ =\n" " $message_kt$.Dsl._create(this.toBuilder()).apply { block() " "}._build()\n",
diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index 1db96f8..cfd0e03 100644 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -1408,24 +1408,17 @@ // were the final one for a given filename. class FileDeduplicator { public: - explicit FileDeduplicator(const GeneratorOptions& options) - : error_on_conflict_(options.error_on_name_conflict) {} + explicit FileDeduplicator(const GeneratorOptions& options) {} // params: // filenames: a pair of {short filename, full filename} // (short filename don't have extra information, full filename // contains extra information) // desc: The Descriptor or SCC pointer or EnumDescriptor. - // error: The returned error information. bool AddFile(const std::pair<std::string, std::string> filenames, - const void* desc, std::string* error) { + const void* desc) { if (descs_by_shortname_.find(filenames.first) != descs_by_shortname_.end()) { - if (error_on_conflict_) { - *error = "Name conflict: file name " + filenames.first + - " would be generated by two descriptors"; - return false; - } // Change old pointer's actual name to full name. auto short_name_desc = descs_by_shortname_[filenames.first]; allowed_descs_actual_name_[short_name_desc] = @@ -1443,7 +1436,6 @@ } private: - bool error_on_conflict_; // The map that restores all the descs that are using short name as filename. std::map<std::string, const void*> descs_by_shortname_; // The final actual filename map. @@ -1537,8 +1529,7 @@ bool GenerateJspbAllowedMap(const GeneratorOptions& options, const std::vector<const FileDescriptor*>& files, std::map<const void*, std::string>* allowed_set, - SCCAnalyzer<DepsGenerator>* analyzer, - std::string* error) { + SCCAnalyzer<DepsGenerator>* analyzer) { std::vector<const FileDescriptor*> files_ordered; GenerateJspbFileOrder(files, &files_ordered); @@ -1553,7 +1544,7 @@ std::make_pair( GetMessagesFileName(options, analyzer->GetSCC(desc), false), GetMessagesFileName(options, analyzer->GetSCC(desc), true)), - analyzer->GetSCC(desc), error)) { + analyzer->GetSCC(desc))) { return false; } } @@ -1561,7 +1552,7 @@ const EnumDescriptor* desc = files_ordered[i]->enum_type(j); if (!dedup.AddFile(std::make_pair(GetEnumFileName(options, desc, false), GetEnumFileName(options, desc, true)), - desc, error)) { + desc)) { return false; } } @@ -1580,7 +1571,7 @@ std::make_pair( GetExtensionFileName(options, files_ordered[i], false), GetExtensionFileName(options, files_ordered[i], true)), - files_ordered[i], error)) { + files_ordered[i])) { return false; } } @@ -3473,12 +3464,10 @@ return false; } testonly = true; + } else if (options[i].first == "error_on_name_conflict") { - if (options[i].second != "") { - *error = "Unexpected option value for error_on_name_conflict"; - return false; - } - error_on_name_conflict = true; + GOOGLE_LOG(WARNING) << "Ignoring error_on_name_conflict option, this " + "will be removed in a future release"; } else if (options[i].first == "output_dir") { output_dir = options[i].second; } else if (options[i].first == "namespace_prefix") { @@ -3527,11 +3516,10 @@ if (import_style != kImportClosure && (add_require_for_enums || testonly || !library.empty() || - error_on_name_conflict || extension != ".js" || - one_output_file_per_input_file)) { + extension != ".js" || one_output_file_per_input_file)) { *error = - "The add_require_for_enums, testonly, library, error_on_name_conflict, " - "extension, and one_output_file_per_input_file options should only be " + "The add_require_for_enums, testonly, library, extension, and " + "one_output_file_per_input_file options should only be " "used for import_style=closure"; return false; } @@ -3766,8 +3754,7 @@ std::set<const Descriptor*> have_printed; SCCAnalyzer<DepsGenerator> analyzer; std::map<const void*, std::string> allowed_map; - if (!GenerateJspbAllowedMap(options, files, &allowed_map, &analyzer, - error)) { + if (!GenerateJspbAllowedMap(options, files, &allowed_map, &analyzer)) { return false; }
diff --git a/src/google/protobuf/compiler/js/js_generator.h b/src/google/protobuf/compiler/js/js_generator.h index e452020..cd9631a 100644 --- a/src/google/protobuf/compiler/js/js_generator.h +++ b/src/google/protobuf/compiler/js/js_generator.h
@@ -83,7 +83,6 @@ add_require_for_enums(false), testonly(false), library(""), - error_on_name_conflict(false), extension(".js"), one_output_file_per_input_file(false), annotate_code(false) {} @@ -119,8 +118,6 @@ // Create a library with name <name>_lib.js rather than a separate .js file // per type? std::string library; - // Error if there are two types that would generate the same output file? - bool error_on_name_conflict; // The extension to use for output file names. std::string extension; // Create a separate output file for each input file?
diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index e1dacae..a8e40cd 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc
@@ -175,6 +175,7 @@ return 1; } + std::string error_msg; CodeGeneratorResponse response;
diff --git a/src/google/protobuf/compiler/plugin.h b/src/google/protobuf/compiler/plugin.h index de581c1..7d1bf45 100644 --- a/src/google/protobuf/compiler/plugin.h +++ b/src/google/protobuf/compiler/plugin.h
@@ -78,6 +78,7 @@ PROTOC_EXPORT int PluginMain(int argc, char* argv[], const CodeGenerator* generator); + // Generates code using the given code generator. Returns true if the code // generation is successful. If the code generation fails, error_msg may be // populated to describe the failure cause.
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index f66f854..9f35b1c 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -89,6 +89,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::Version, major_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::Version, minor_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::Version, patch_), @@ -102,6 +103,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, file_to_generate_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, parameter_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, proto_file_), @@ -115,6 +117,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, insertion_point_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, content_), @@ -128,6 +131,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, error_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, supported_features_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, file_), @@ -136,10 +140,10 @@ ~0u, }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, 9, sizeof(PROTOBUF_NAMESPACE_ID::compiler::Version)}, - { 13, 22, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest)}, - { 26, 35, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)}, - { 39, 47, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)}, + { 0, 10, -1, sizeof(PROTOBUF_NAMESPACE_ID::compiler::Version)}, + { 14, 24, -1, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest)}, + { 28, 38, -1, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)}, + { 42, 51, -1, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -316,7 +320,8 @@ _Internal::set_has_major(&has_bits); major_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional int32 minor = 2; case 2: @@ -324,7 +329,8 @@ _Internal::set_has_minor(&has_bits); minor_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional int32 patch = 3; case 3: @@ -332,7 +338,8 @@ _Internal::set_has_patch(&has_bits); patch_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string suffix = 4; case 4: @@ -343,29 +350,30 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.Version.suffix"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -431,33 +439,21 @@ // optional int32 major = 1; if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_major()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_major()); } // optional int32 minor = 2; if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_minor()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_minor()); } // optional int32 patch = 3; if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_patch()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_patch()); } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Version::_class_data_ = { @@ -466,8 +462,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Version::GetClassData() const { return &_class_data_; } -void Version::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Version::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Version *>(to)->MergeFrom( static_cast<const Version &>(from)); } @@ -511,12 +507,14 @@ void Version::InternalSwap(Version* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &suffix_, GetArenaForAllocation(), - &other->suffix_, other->GetArenaForAllocation() + &suffix_, lhs_arena, + &other->suffix_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(Version, patch_) @@ -654,7 +652,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string parameter = 2; case 2: @@ -665,14 +664,16 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.parameter"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.compiler.Version compiler_version = 3; case 3: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 26)) { ptr = ctx->ParseMessage(_internal_mutable_compiler_version(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.FileDescriptorProto proto_file = 15; case 15: @@ -684,29 +685,30 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<122>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -801,13 +803,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorRequest::_class_data_ = { @@ -816,8 +812,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorRequest::GetClassData() const { return &_class_data_; } -void CodeGeneratorRequest::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void CodeGeneratorRequest::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<CodeGeneratorRequest *>(to)->MergeFrom( static_cast<const CodeGeneratorRequest &>(from)); } @@ -857,14 +853,16 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); file_to_generate_.InternalSwap(&other->file_to_generate_); proto_file_.InternalSwap(&other->proto_file_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ¶meter_, GetArenaForAllocation(), - &other->parameter_, other->GetArenaForAllocation() + ¶meter_, lhs_arena, + &other->parameter_, rhs_arena ); swap(compiler_version_, other->compiler_version_); } @@ -1013,7 +1011,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.name"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string insertion_point = 2; case 2: @@ -1024,7 +1023,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string content = 15; case 15: @@ -1035,36 +1035,38 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.content"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; case 16: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 130)) { ptr = ctx->ParseMessage(_internal_mutable_generated_code_info(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1160,13 +1162,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorResponse_File::_class_data_ = { @@ -1175,8 +1171,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorResponse_File::GetClassData() const { return &_class_data_; } -void CodeGeneratorResponse_File::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void CodeGeneratorResponse_File::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<CodeGeneratorResponse_File *>(to)->MergeFrom( static_cast<const CodeGeneratorResponse_File &>(from)); } @@ -1219,22 +1215,24 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &insertion_point_, GetArenaForAllocation(), - &other->insertion_point_, other->GetArenaForAllocation() + &insertion_point_, lhs_arena, + &other->insertion_point_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &content_, GetArenaForAllocation(), - &other->content_, other->GetArenaForAllocation() + &content_, lhs_arena, + &other->content_, rhs_arena ); swap(generated_code_info_, other->generated_code_info_); } @@ -1341,7 +1339,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.error"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional uint64 supported_features = 2; case 2: @@ -1349,7 +1348,8 @@ _Internal::set_has_supported_features(&has_bits); supported_features_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; case 15: @@ -1361,29 +1361,30 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<122>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1452,19 +1453,11 @@ // optional uint64 supported_features = 2; if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64Size( - this->_internal_supported_features()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64SizePlusOne(this->_internal_supported_features()); } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorResponse::_class_data_ = { @@ -1473,8 +1466,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorResponse::GetClassData() const { return &_class_data_; } -void CodeGeneratorResponse::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void CodeGeneratorResponse::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<CodeGeneratorResponse *>(to)->MergeFrom( static_cast<const CodeGeneratorResponse &>(from)); } @@ -1513,13 +1506,15 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); file_.InternalSwap(&other->file_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &error_, GetArenaForAllocation(), - &other->error_, other->GetArenaForAllocation() + &error_, lhs_arena, + &other->error_, rhs_arena ); swap(supported_features_, other->supported_features_); }
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index e1ede97..d230cd4 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -195,7 +195,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Version& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -396,7 +396,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const CodeGeneratorRequest& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -618,7 +618,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const CodeGeneratorResponse_File& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -834,7 +834,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const CodeGeneratorResponse& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final;
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index bedb5b3..408caf8 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc
@@ -35,6 +35,7 @@ #include <google/protobuf/descriptor.h> #include <algorithm> +#include <array> #include <functional> #include <limits> #include <map> @@ -75,7 +76,8 @@ namespace google { namespace protobuf { -struct Symbol { +class Symbol { + public: enum Type { NULL_SYMBOL, MESSAGE, @@ -83,69 +85,177 @@ ONEOF, ENUM, ENUM_VALUE, + ENUM_VALUE_OTHER_PARENT, SERVICE, METHOD, - PACKAGE - }; - Type type; - union { - const Descriptor* descriptor; - const FieldDescriptor* field_descriptor; - const OneofDescriptor* oneof_descriptor; - const EnumDescriptor* enum_descriptor; - const EnumValueDescriptor* enum_value_descriptor; - const ServiceDescriptor* service_descriptor; - const MethodDescriptor* method_descriptor; - const FileDescriptor* package_file_descriptor; + PACKAGE, + QUERY_KEY }; - inline Symbol() : type(NULL_SYMBOL) { descriptor = nullptr; } - inline bool IsNull() const { return type == NULL_SYMBOL; } - inline bool IsType() const { return type == MESSAGE || type == ENUM; } - inline bool IsAggregate() const { - return type == MESSAGE || type == PACKAGE || type == ENUM || - type == SERVICE; + Symbol() : ptr_(nullptr) {} + + // Every object we store derives from internal::SymbolBase, where we store the + // symbol type enum. + // Storing in the object can be done without using more space in most cases, + // while storing it in the Symbol type would require 8 bytes. +#define DEFINE_MEMBERS(TYPE, TYPE_CONSTANT, FIELD) \ + explicit Symbol(TYPE* value) : ptr_(value) { \ + value->symbol_type_ = TYPE_CONSTANT; \ + } \ + const TYPE* FIELD() const { \ + return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \ } -#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \ - inline explicit Symbol(const TYPE* value) { \ - type = TYPE_CONSTANT; \ - this->FIELD = value; \ + DEFINE_MEMBERS(Descriptor, MESSAGE, descriptor) + DEFINE_MEMBERS(FieldDescriptor, FIELD, field_descriptor) + DEFINE_MEMBERS(OneofDescriptor, ONEOF, oneof_descriptor) + DEFINE_MEMBERS(EnumDescriptor, ENUM, enum_descriptor) + DEFINE_MEMBERS(ServiceDescriptor, SERVICE, service_descriptor) + DEFINE_MEMBERS(MethodDescriptor, METHOD, method_descriptor) + + // We use a special node for FileDescriptor. + // It is potentially added to the table with multiple different names, so we + // need a separate place to put the name. + struct Package : internal::SymbolBase { + const std::string* name; + const FileDescriptor* file; + }; + DEFINE_MEMBERS(Package, PACKAGE, package_file_descriptor) + + // Enum values have two different parents. + // We use two different identitied for the same object to determine the two + // different insertions in the map. + static Symbol EnumValue(EnumValueDescriptor* value, int n) { + Symbol s; + internal::SymbolBase* ptr; + if (n == 0) { + ptr = static_cast<internal::SymbolBaseN<0>*>(value); + ptr->symbol_type_ = ENUM_VALUE; + } else { + ptr = static_cast<internal::SymbolBaseN<1>*>(value); + ptr->symbol_type_ = ENUM_VALUE_OTHER_PARENT; + } + s.ptr_ = ptr; + return s; } - CONSTRUCTOR(Descriptor, MESSAGE, descriptor) - CONSTRUCTOR(FieldDescriptor, FIELD, field_descriptor) - CONSTRUCTOR(OneofDescriptor, ONEOF, oneof_descriptor) - CONSTRUCTOR(EnumDescriptor, ENUM, enum_descriptor) - CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor) - CONSTRUCTOR(ServiceDescriptor, SERVICE, service_descriptor) - CONSTRUCTOR(MethodDescriptor, METHOD, method_descriptor) - CONSTRUCTOR(FileDescriptor, PACKAGE, package_file_descriptor) -#undef CONSTRUCTOR + const EnumValueDescriptor* enum_value_descriptor() const { + return type() == ENUM_VALUE + ? static_cast<const EnumValueDescriptor*>( + static_cast<const internal::SymbolBaseN<0>*>(ptr_)) + : type() == ENUM_VALUE_OTHER_PARENT + ? static_cast<const EnumValueDescriptor*>( + static_cast<const internal::SymbolBaseN<1>*>(ptr_)) + : nullptr; + } + + // Not a real symbol. + // Only used for heterogeneous lookups and never actually inserted in the + // tables. + struct QueryKey : internal::SymbolBase { + StringPiece name; + const void* parent; + }; + DEFINE_MEMBERS(QueryKey, QUERY_KEY, query_key); +#undef DEFINE_MEMBERS + + Type type() const { + return ptr_ == nullptr ? NULL_SYMBOL + : static_cast<Type>(ptr_->symbol_type_); + } + bool IsNull() const { return type() == NULL_SYMBOL; } + bool IsType() const { return type() == MESSAGE || type() == ENUM; } + bool IsAggregate() const { + return type() == MESSAGE || type() == PACKAGE || type() == ENUM || + type() == SERVICE; + } const FileDescriptor* GetFile() const { - switch (type) { - case NULL_SYMBOL: - return nullptr; + switch (type()) { case MESSAGE: - return descriptor->file(); + return descriptor()->file(); case FIELD: - return field_descriptor->file(); + return field_descriptor()->file(); case ONEOF: - return oneof_descriptor->containing_type()->file(); + return oneof_descriptor()->containing_type()->file(); case ENUM: - return enum_descriptor->file(); + return enum_descriptor()->file(); case ENUM_VALUE: - return enum_value_descriptor->type()->file(); + return enum_value_descriptor()->type()->file(); case SERVICE: - return service_descriptor->file(); + return service_descriptor()->file(); case METHOD: - return method_descriptor->service()->file(); + return method_descriptor()->service()->file(); case PACKAGE: - return package_file_descriptor; + return package_file_descriptor()->file; + default: + return nullptr; } - return nullptr; } + + StringPiece full_name() const { + switch (type()) { + case MESSAGE: + return descriptor()->full_name(); + case FIELD: + return field_descriptor()->full_name(); + case ONEOF: + return oneof_descriptor()->full_name(); + case ENUM: + return enum_descriptor()->full_name(); + case ENUM_VALUE: + return enum_value_descriptor()->full_name(); + case SERVICE: + return service_descriptor()->full_name(); + case METHOD: + return method_descriptor()->full_name(); + case PACKAGE: + return *package_file_descriptor()->name; + case QUERY_KEY: + return query_key()->name; + default: + GOOGLE_CHECK(false); + } + return ""; + } + + std::pair<const void*, StringPiece> parent_key() const { + const auto or_file = [&](const void* p) { return p ? p : GetFile(); }; + switch (type()) { + case MESSAGE: + return {or_file(descriptor()->containing_type()), descriptor()->name()}; + case FIELD: { + auto* field = field_descriptor(); + return {or_file(field->is_extension() ? field->extension_scope() + : field->containing_type()), + field->name()}; + } + case ONEOF: + return {oneof_descriptor()->containing_type(), + oneof_descriptor()->name()}; + case ENUM: + return {or_file(enum_descriptor()->containing_type()), + enum_descriptor()->name()}; + case ENUM_VALUE: + return {or_file(enum_value_descriptor()->type()->containing_type()), + enum_value_descriptor()->name()}; + case ENUM_VALUE_OTHER_PARENT: + return {enum_value_descriptor()->type(), + enum_value_descriptor()->name()}; + case SERVICE: + return {GetFile(), service_descriptor()->name()}; + case METHOD: + return {method_descriptor()->service(), method_descriptor()->name()}; + case QUERY_KEY: + return {query_key()->parent, query_key()->name}; + default: + GOOGLE_CHECK(false); + } + return {}; + } + + private: + const internal::SymbolBase* ptr_; }; const FieldDescriptor::CppType @@ -435,11 +545,31 @@ const Symbol kNullSymbol; -typedef HASH_MAP<StringPiece, Symbol, HASH_FXN<StringPiece>> - SymbolsByNameMap; +struct SymbolByFullNameHash { + size_t operator()(Symbol s) const { + return HASH_FXN<StringPiece>{}(s.full_name()); + } +}; +struct SymbolByFullNameEq { + bool operator()(Symbol a, Symbol b) const { + return a.full_name() == b.full_name(); + } +}; +using SymbolsByNameSet = + HASH_SET<Symbol, SymbolByFullNameHash, SymbolByFullNameEq>; -typedef HASH_MAP<PointerStringPair, Symbol, PointerStringPairHash> - SymbolsByParentMap; +struct SymbolByParentHash { + size_t operator()(Symbol s) const { + return PointerStringPairHash{}(s.parent_key()); + } +}; +struct SymbolByParentEq { + bool operator()(Symbol a, Symbol b) const { + return a.parent_key() == b.parent_key(); + } +}; +using SymbolsByParentSet = + HASH_SET<Symbol, SymbolByParentHash, SymbolByParentEq>; typedef HASH_MAP<StringPiece, const FileDescriptor*, HASH_FXN<StringPiece>> @@ -496,6 +626,403 @@ allowed_proto3_extendees->end(); } +// This bump allocator arena is optimized for the use case of this file. It is +// mostly optimized for memory usage, since these objects are expected to live +// for the entirety of the program. +// +// Some differences from other arenas: +// - It has a fixed number of non-trivial types it can hold. This allows +// tracking the allocations with a single byte. In contrast, google::protobuf::Arena +// uses 16 bytes per non-trivial object created. +// - It has some extra metadata for rollbacks. This is necessary for +// implementing the API below. This metadata is flushed at the end and would +// not cause persistent memory usage. +// - It tries to squeeze every byte of out the blocks. If an allocation is too +// large for the current block we move the block to a secondary area where we +// can still use it for smaller objects. This complicates rollback logic but +// makes it much more memory efficient. +// +// The allocation strategy is as follows: +// - Memory is allocated from the front, with a forced 8 byte alignment. +// - Metadata is allocated from the back, one byte per element. +// - The metadata encodes one of two things: +// * For types we want to track, the index into KnownTypes. +// * For raw memory blocks, the size of the block (in 8 byte increments +// to allow for a larger limit). +// - When the raw data is too large to represent in the metadata byte, we +// allocate this memory separately in the heap and store an OutOfLineAlloc +// object instead. These come from large array allocations and alike. +// +// Blocks are kept in 3 areas: +// - `current_` is the one we are currently allocating from. When we need to +// allocate a block that doesn't fit there, we make a new block and move the +// old `current_` to one of the areas below. +// - Blocks that have no more usable space left (ie less than 9 bytes) are +// stored in `full_blocks_`. +// - Blocks that have some usable space are categorized in +// `small_size_blocks_` depending on how much space they have left. +// See `kSmallSizes` to see which sizes we track. +// +class TableArena { + public: + // Allocate a block on `n` bytes, with no destructor information saved. + void* AllocateMemory(uint32_t n) { + uint32_t tag = SizeToRawTag(n) + kFirstRawTag; + if (tag > 255) { + // We can't fit the size, use an OutOfLineAlloc. + return Create<OutOfLineAlloc>(OutOfLineAlloc{::operator new(n), n})->ptr; + } + + return AllocRawInternal(n, static_cast<Tag>(tag)); + } + + // Allocate and construct an element of type `T` as if by + // `T(std::forward<Args>(args...))`. + // The object is registered for destruction, if its destructor is not trivial. + template <typename T, typename... Args> + T* Create(Args&&... args) { + static_assert(alignof(T) <= 8, ""); + return ::new (AllocRawInternal(sizeof(T), TypeTag<T>(KnownTypes{}))) + T(std::forward<Args>(args)...); + } + + TableArena() {} + + TableArena(const TableArena&) = delete; + TableArena& operator=(const TableArena&) = delete; + + ~TableArena() { + // Uncomment this to debug usage statistics of the arena blocks. + // PrintUsageInfo(); + + for (Block* list : GetLists()) { + while (list != nullptr) { + Block* b = list; + list = list->next; + b->VisitBlock(DestroyVisitor{}); + b->Destroy(); + } + } + } + + + // This function exists for debugging only. + // It can be called from the destructor to dump some info in the tests to + // inspect the usage of the arena. + void PrintUsageInfo() const { + const auto print_histogram = [](Block* b, int size) { + std::map<uint32_t, uint32_t> unused_space_count; + int count = 0; + for (; b != nullptr; b = b->next) { + ++unused_space_count[b->space_left()]; + ++count; + } + if (size > 0) { + fprintf(stderr, " Blocks `At least %d`", size); + } else { + fprintf(stderr, " Blocks `full`"); + } + fprintf(stderr, ": %d blocks.\n", count); + for (auto p : unused_space_count) { + fprintf(stderr, " space=%4u, count=%3u\n", p.first, p.second); + } + }; + + fprintf(stderr, "TableArena unused space histogram:\n"); + fprintf(stderr, " Current: %u\n", + current_ != nullptr ? current_->space_left() : 0); + print_histogram(full_blocks_, 0); + for (size_t i = 0; i < kSmallSizes.size(); ++i) { + print_histogram(small_size_blocks_[i], kSmallSizes[i]); + } + } + + // Current allocation count. + // This can be used for checkpointing. + size_t num_allocations() const { return num_allocations_; } + + // Rollback the latest allocations until we reach back to `checkpoint` + // num_allocations. + void RollbackTo(size_t checkpoint) { + while (num_allocations_ > checkpoint) { + GOOGLE_DCHECK(!rollback_info_.empty()); + auto& info = rollback_info_.back(); + Block* b = info.block; + + VisitAlloc(b->data(), &b->start_offset, &b->end_offset, DestroyVisitor{}, + KnownTypes{}); + if (--info.count == 0) { + rollback_info_.pop_back(); + } + --num_allocations_; + } + + // Reconstruct the lists and destroy empty blocks. + auto lists = GetLists(); + current_ = full_blocks_ = nullptr; + small_size_blocks_.fill(nullptr); + + for (Block* list : lists) { + while (list != nullptr) { + Block* b = list; + list = list->next; + + if (b->start_offset == 0) { + // This is empty, free it. + b->Destroy(); + } else { + RelocateToUsedList(b); + } + } + } + } + + // Clear all rollback information. Reduces memory usage. + // Trying to rollback past num_allocations() is now impossible. + void ClearRollbackData() { + rollback_info_.clear(); + rollback_info_.shrink_to_fit(); + } + + private: + static constexpr size_t RoundUp(size_t n) { return (n + 7) & ~7; } + + using Tag = unsigned char; + + void* AllocRawInternal(uint32_t size, Tag tag) { + GOOGLE_DCHECK_GT(size, 0); + size = RoundUp(size); + + Block* to_relocate = nullptr; + Block* to_use; + + for (size_t i = 0; i < kSmallSizes.size(); ++i) { + if (small_size_blocks_[i] != nullptr && size <= kSmallSizes[i]) { + to_use = to_relocate = PopBlock(small_size_blocks_[i]); + break; + } + } + + if (to_relocate != nullptr) { + // We found one in the loop. + } else if (current_ != nullptr && size + 1 <= current_->space_left()) { + to_use = current_; + } else { + // No space left anywhere, make a new block. + to_relocate = current_; + // For now we hardcode the size to one page. Note that the maximum we can + // allocate in the block according to the limits of Tag is less than 2k, + // so this can fit anything that Tag can represent. + constexpr size_t kBlockSize = 4096; + to_use = current_ = ::new (::operator new(kBlockSize)) Block(kBlockSize); + GOOGLE_DCHECK_GE(current_->space_left(), size + 1); + } + + ++num_allocations_; + if (!rollback_info_.empty() && rollback_info_.back().block == to_use) { + ++rollback_info_.back().count; + } else { + rollback_info_.push_back({to_use, 1}); + } + + void* p = to_use->Allocate(size, tag); + if (to_relocate != nullptr) { + RelocateToUsedList(to_relocate); + } + return p; + } + + static void OperatorDelete(void* p, size_t s) { +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + ::operator delete(p, s); +#else + ::operator delete(p); +#endif + } + + struct OutOfLineAlloc { + void* ptr; + uint32_t size; + }; + + template <typename... T> + struct TypeList { + static constexpr Tag kSize = static_cast<Tag>(sizeof...(T)); + }; + + template <typename T, typename Visitor> + static void RunVisitor(char* p, uint16_t* start, Visitor visit) { + *start -= RoundUp(sizeof(T)); + visit(reinterpret_cast<T*>(p + *start)); + } + + // Visit the allocation at the passed location. + // It updates start/end to be after the visited object. + // This allows visiting a whole block by calling the function in a loop. + template <typename Visitor, typename... T> + static void VisitAlloc(char* p, uint16_t* start, uint16_t* end, Visitor visit, + TypeList<T...>) { + const Tag tag = static_cast<Tag>(p[*end]); + if (tag >= kFirstRawTag) { + // Raw memory. Skip it. + *start -= TagToSize(tag); + } else { + using F = void (*)(char*, uint16_t*, Visitor); + static constexpr F kFuncs[] = {&RunVisitor<T, Visitor>...}; + kFuncs[tag](p, start, visit); + } + ++*end; + } + + template <typename U, typename... Ts> + static constexpr Tag TypeTag(TypeList<U, Ts...>) { + return 0; + } + + template < + typename U, typename T, typename... Ts, + typename = typename std::enable_if<!std::is_same<U, T>::value>::type> + static constexpr Tag TypeTag(TypeList<T, Ts...>) { + return 1 + TypeTag<U>(TypeList<Ts...>{}); + } + + template <typename U> + static constexpr Tag TypeTag(TypeList<>) { + static_assert(std::is_trivially_destructible<U>::value, ""); + return SizeToRawTag(sizeof(U)); + } + + using KnownTypes = + TypeList<OutOfLineAlloc, std::string, + // For name arrays + std::array<std::string, 2>, std::array<std::string, 3>, + std::array<std::string, 4>, std::array<std::string, 5>, + FileDescriptorTables, SourceCodeInfo, FileOptions, + MessageOptions, FieldOptions, ExtensionRangeOptions, + OneofOptions, EnumOptions, EnumValueOptions, ServiceOptions, + MethodOptions>; + static constexpr Tag kFirstRawTag = KnownTypes::kSize; + + + struct DestroyVisitor { + template <typename T> + void operator()(T* p) { + p->~T(); + } + void operator()(OutOfLineAlloc* p) { OperatorDelete(p->ptr, p->size); } + }; + + static uint32_t SizeToRawTag(size_t n) { return (RoundUp(n) / 8) - 1; } + + static uint32_t TagToSize(Tag tag) { + GOOGLE_DCHECK_GE(tag, kFirstRawTag); + return static_cast<uint32_t>(tag - kFirstRawTag + 1) * 8; + } + + struct Block { + uint16_t start_offset; + uint16_t end_offset; + uint16_t capacity; + Block* next; + + // `allocated_size` is the total size of the memory block allocated. + // The `Block` structure is constructed at the start and the rest of the + // memory is used as the payload of the `Block`. + explicit Block(uint32_t allocated_size) { + start_offset = 0; + end_offset = capacity = + reinterpret_cast<char*>(this) + allocated_size - data(); + next = nullptr; + } + + char* data() { + return reinterpret_cast<char*>(this) + RoundUp(sizeof(Block)); + } + + uint32_t memory_used() { + return data() + capacity - reinterpret_cast<char*>(this); + } + uint32_t space_left() const { return end_offset - start_offset; } + + void* Allocate(uint32_t n, Tag tag) { + GOOGLE_DCHECK_LE(n + 1, space_left()); + void* p = data() + start_offset; + start_offset += n; + data()[--end_offset] = tag; + return p; + } + + void Destroy() { OperatorDelete(this, memory_used()); } + + void PrependTo(Block*& list) { + next = list; + list = this; + } + + template <typename Visitor> + void VisitBlock(Visitor visit) { + for (uint16_t s = start_offset, e = end_offset; s != 0;) { + VisitAlloc(data(), &s, &e, visit, KnownTypes{}); + } + } + }; + + Block* PopBlock(Block*& list) { + Block* res = list; + list = list->next; + return res; + } + + void RelocateToUsedList(Block* to_relocate) { + if (current_ == nullptr) { + current_ = to_relocate; + current_->next = nullptr; + return; + } else if (current_->space_left() < to_relocate->space_left()) { + std::swap(current_, to_relocate); + current_->next = nullptr; + } + + for (int i = kSmallSizes.size(); --i >= 0;) { + if (to_relocate->space_left() >= 1 + kSmallSizes[i]) { + to_relocate->PrependTo(small_size_blocks_[i]); + return; + } + } + + to_relocate->PrependTo(full_blocks_); + } + + static constexpr std::array<uint8_t, 6> kSmallSizes = { + // Sizes for pointer arrays. + 8, 16, 24, 32, + // Sizes for string arrays (for descriptor names). + // The most common array sizes are 2 and 3. + 2 * sizeof(std::string), 3 * sizeof(std::string)}; + + // Helper function to iterate all lists. + std::array<Block*, 2 + kSmallSizes.size()> GetLists() const { + std::array<Block*, 2 + kSmallSizes.size()> res; + res[0] = current_; + res[1] = full_blocks_; + std::copy(small_size_blocks_.begin(), small_size_blocks_.end(), &res[2]); + return res; + } + + Block* current_ = nullptr; + std::array<Block*, kSmallSizes.size()> small_size_blocks_{}; + Block* full_blocks_ = nullptr; + + size_t num_allocations_ = 0; + struct RollbackInfo { + Block* block; + size_t count; + }; + std::vector<RollbackInfo> rollback_info_; +}; + +constexpr std::array<uint8_t, 6> TableArena::kSmallSizes; + } // anonymous namespace // =================================================================== @@ -619,14 +1146,31 @@ // Allocate a string which will be destroyed when the pool is destroyed. // The string is initialized to the given value for convenience. - std::string* AllocateString(StringPiece value); + const std::string* AllocateString(StringPiece value); - // Allocate empty string which will be destroyed when the pool is destroyed. - std::string* AllocateEmptyString(); + // Allocates an array of strings which will be destroyed when the pool is + // destroyed. The array is initialized with the input values. + template <typename... In> + const std::string* AllocateStringArray(In&&... values); - // Allocate a internal::call_once which will be destroyed when the pool is + struct FieldNamesResult { + std::string* array; + int lowercase_index; + int camelcase_index; + int json_index; + }; + // Allocate all 5 names of the field: + // name, full name, lowercase, camelcase and json. + // This function will dedup the strings when possible. + // The resulting array contains `name` at index 0, `full_name` at index 1 and + // the other 3 indices are specified in the result. + FieldNamesResult AllocateFieldNames(const std::string& name, + const std::string& scope, + const std::string* opt_json_name); + + // Allocate a LazyInitData which will be destroyed when the pool is // destroyed. - internal::once_flag* AllocateOnceDynamic(); + internal::LazyInitData* AllocateLazyInit(); // Allocate a protocol message object. Some older versions of GCC have // trouble understanding explicit template instantiations in some cases, so @@ -641,34 +1185,22 @@ private: // All other memory allocated in the pool. Must be first as other objects can // point into these. - std::vector<std::vector<char>> allocations_; - std::vector<std::unique_ptr<std::string>> strings_; - std::vector<std::unique_ptr<Message>> messages_; - std::vector<std::unique_ptr<internal::once_flag>> once_dynamics_; - std::vector<std::unique_ptr<FileDescriptorTables>> file_tables_; + TableArena arena_; - SymbolsByNameMap symbols_by_name_; + SymbolsByNameSet symbols_by_name_; FilesByNameMap files_by_name_; ExtensionsGroupedByDescriptorMap extensions_; struct CheckPoint { explicit CheckPoint(const Tables* tables) - : strings_before_checkpoint(tables->strings_.size()), - messages_before_checkpoint(tables->messages_.size()), - once_dynamics_before_checkpoint(tables->once_dynamics_.size()), - file_tables_before_checkpoint(tables->file_tables_.size()), - allocations_before_checkpoint(tables->allocations_.size()), + : arena_before_checkpoint(tables->arena_.num_allocations()), pending_symbols_before_checkpoint( tables->symbols_after_checkpoint_.size()), pending_files_before_checkpoint( tables->files_after_checkpoint_.size()), pending_extensions_before_checkpoint( tables->extensions_after_checkpoint_.size()) {} - int strings_before_checkpoint; - int messages_before_checkpoint; - int once_dynamics_before_checkpoint; - int file_tables_before_checkpoint; - int allocations_before_checkpoint; + int arena_before_checkpoint; int pending_symbols_before_checkpoint; int pending_files_before_checkpoint; int pending_extensions_before_checkpoint; @@ -703,13 +1235,9 @@ // ----------------------------------------------------------------- // Finding items. - // Find symbols. These return a null Symbol (symbol.IsNull() is true) - // if not found. + // Returns a null Symbol (symbol.IsNull() is true) if not found. inline Symbol FindNestedSymbol(const void* parent, StringPiece name) const; - inline Symbol FindNestedSymbolOfType(const void* parent, - StringPiece name, - const Symbol::Type type) const; // These return nullptr if not found. inline const FieldDescriptor* FindFieldByNumber(const Descriptor* parent, @@ -765,7 +1293,7 @@ const FileDescriptorTables* tables); void FieldsByCamelcaseNamesLazyInitInternal() const; - SymbolsByParentMap symbols_by_parent_; + SymbolsByParentSet symbols_by_parent_; mutable FieldsByNameMap fields_by_lowercase_name_; std::unique_ptr<FieldsByNameMap> fields_by_lowercase_name_tmp_; mutable internal::once_flag fields_by_lowercase_name_once_; @@ -834,6 +1362,7 @@ symbols_after_checkpoint_.clear(); files_after_checkpoint_.clear(); extensions_after_checkpoint_.clear(); + arena_.ClearRollbackData(); } } @@ -843,7 +1372,9 @@ for (size_t i = checkpoint.pending_symbols_before_checkpoint; i < symbols_after_checkpoint_.size(); i++) { - symbols_by_name_.erase(symbols_after_checkpoint_[i]); + Symbol::QueryKey name; + name.name = symbols_after_checkpoint_[i]; + symbols_by_name_.erase(Symbol(&name)); } for (size_t i = checkpoint.pending_files_before_checkpoint; i < files_after_checkpoint_.size(); i++) { @@ -860,41 +1391,26 @@ extensions_after_checkpoint_.resize( checkpoint.pending_extensions_before_checkpoint); - strings_.resize(checkpoint.strings_before_checkpoint); - messages_.resize(checkpoint.messages_before_checkpoint); - once_dynamics_.resize(checkpoint.once_dynamics_before_checkpoint); - file_tables_.resize(checkpoint.file_tables_before_checkpoint); - allocations_.resize(checkpoint.allocations_before_checkpoint); + arena_.RollbackTo(checkpoint.arena_before_checkpoint); checkpoints_.pop_back(); } // ------------------------------------------------------------------- inline Symbol DescriptorPool::Tables::FindSymbol(StringPiece key) const { - const Symbol* result = FindOrNull(symbols_by_name_, key); - if (result == nullptr) { - return kNullSymbol; - } else { - return *result; - } + Symbol::QueryKey name; + name.name = key; + auto it = symbols_by_name_.find(Symbol(&name)); + return it == symbols_by_name_.end() ? kNullSymbol : *it; } inline Symbol FileDescriptorTables::FindNestedSymbol( const void* parent, StringPiece name) const { - const Symbol* result = - FindOrNull(symbols_by_parent_, PointerStringPair(parent, name)); - if (result == nullptr) { - return kNullSymbol; - } else { - return *result; - } -} - -inline Symbol FileDescriptorTables::FindNestedSymbolOfType( - const void* parent, StringPiece name, const Symbol::Type type) const { - Symbol result = FindNestedSymbol(parent, name); - if (result.type != type) return kNullSymbol; - return result; + Symbol::QueryKey query; + query.name = name; + query.parent = parent; + auto it = symbols_by_parent_.find(Symbol(&query)); + return it == symbols_by_parent_.end() ? kNullSymbol : *it; } Symbol DescriptorPool::Tables::FindByNameHelper(const DescriptorPool* pool, @@ -1045,9 +1561,9 @@ DescriptorPool::Tables* tables = const_cast<DescriptorPool::Tables*>( DescriptorPool::generated_pool()->tables_.get()); EnumValueDescriptor* result = tables->Allocate<EnumValueDescriptor>(); - result->name_ = tables->AllocateString(enum_value_name); - result->full_name_ = - tables->AllocateString(parent->full_name() + "." + enum_value_name); + result->all_names_ = tables->AllocateStringArray( + enum_value_name, + StrCat(parent->full_name(), ".", enum_value_name)); result->number_ = number; result->type_ = parent; result->options_ = &EnumValueOptions::default_instance(); @@ -1076,7 +1592,8 @@ bool DescriptorPool::Tables::AddSymbol(const std::string& full_name, Symbol symbol) { - if (InsertIfNotPresent(&symbols_by_name_, full_name, symbol)) { + GOOGLE_DCHECK_EQ(full_name, symbol.full_name()); + if (symbols_by_name_.insert(symbol).second) { symbols_after_checkpoint_.push_back(full_name.c_str()); return true; } else { @@ -1087,8 +1604,9 @@ bool FileDescriptorTables::AddAliasUnderParent(const void* parent, const std::string& name, Symbol symbol) { - PointerStringPair by_parent_key(parent, name.c_str()); - return InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol); + GOOGLE_DCHECK_EQ(name, symbol.parent_key().second); + GOOGLE_DCHECK_EQ(parent, symbol.parent_key().first); + return symbols_by_parent_.insert(symbol).second; } bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) { @@ -1167,46 +1685,107 @@ return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count)); } -std::string* DescriptorPool::Tables::AllocateString(StringPiece value) { - std::string* result = new std::string(value); - strings_.emplace_back(result); +const std::string* DescriptorPool::Tables::AllocateString( + StringPiece value) { + return arena_.Create<std::string>(value); +} + +template <typename... In> +const std::string* DescriptorPool::Tables::AllocateStringArray(In&&... values) { + auto& array = *arena_.Create<std::array<std::string, sizeof...(In)>>(); + array = {{std::string(std::forward<In>(values))...}}; + return array.data(); +} + +DescriptorPool::Tables::FieldNamesResult +DescriptorPool::Tables::AllocateFieldNames(const std::string& name, + const std::string& scope, + const std::string* opt_json_name) { + std::string lowercase_name = name; + LowerString(&lowercase_name); + + std::string camelcase_name = ToCamelCase(name, /* lower_first = */ true); + std::string json_name; + if (opt_json_name != nullptr) { + json_name = *opt_json_name; + } else { + json_name = ToJsonName(name); + } + + const bool lower_eq_name = lowercase_name == name; + const bool camel_eq_name = camelcase_name == name; + const bool json_eq_name = json_name == name; + const bool json_eq_camel = json_name == camelcase_name; + + const int total_count = 2 + (lower_eq_name ? 0 : 1) + + (camel_eq_name ? 0 : 1) + + (json_eq_name || json_eq_camel ? 0 : 1); + FieldNamesResult result; + // We use std::array to allow handling of the destruction of the strings. + switch (total_count) { + case 2: + result.array = arena_.Create<std::array<std::string, 2>>()->data(); + break; + case 3: + result.array = arena_.Create<std::array<std::string, 3>>()->data(); + break; + case 4: + result.array = arena_.Create<std::array<std::string, 4>>()->data(); + break; + case 5: + result.array = arena_.Create<std::array<std::string, 5>>()->data(); + break; + } + + result.array[0] = name; + if (scope.empty()) { + result.array[1] = name; + } else { + result.array[1] = StrCat(scope, ".", name); + } + int index = 2; + if (lower_eq_name) { + result.lowercase_index = 0; + } else { + result.lowercase_index = index; + result.array[index++] = std::move(lowercase_name); + } + + if (camel_eq_name) { + result.camelcase_index = 0; + } else { + result.camelcase_index = index; + result.array[index++] = std::move(camelcase_name); + } + + if (json_eq_name) { + result.json_index = 0; + } else if (json_eq_camel) { + result.json_index = result.camelcase_index; + } else { + result.json_index = index; + result.array[index] = std::move(json_name); + } + return result; } -std::string* DescriptorPool::Tables::AllocateEmptyString() { - std::string* result = new std::string(); - strings_.emplace_back(result); - return result; -} - -internal::once_flag* DescriptorPool::Tables::AllocateOnceDynamic() { - internal::once_flag* result = new internal::once_flag(); - once_dynamics_.emplace_back(result); - return result; +internal::LazyInitData* DescriptorPool::Tables::AllocateLazyInit() { + return arena_.Create<internal::LazyInitData>(); } template <typename Type> Type* DescriptorPool::Tables::AllocateMessage(Type* /* dummy */) { - Type* result = new Type; - messages_.emplace_back(result); - return result; + return arena_.Create<Type>(); } FileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() { - FileDescriptorTables* result = new FileDescriptorTables; - file_tables_.emplace_back(result); - return result; + return arena_.Create<FileDescriptorTables>(); } void* DescriptorPool::Tables::AllocateBytes(int size) { - // TODO(kenton): Would it be worthwhile to implement this in some more - // sophisticated way? Probably not for the open source release, but for - // internal use we could easily plug in one of our existing memory pool - // allocators... if (size == 0) return nullptr; - - allocations_.emplace_back(size); - return allocations_.back().data(); + return arena_.AllocateMemory(size); } void FileDescriptorTables::BuildLocationsByPath( @@ -1407,60 +1986,54 @@ const Descriptor* DescriptorPool::FindMessageTypeByName( ConstStringParam name) const { - Symbol result = tables_->FindByNameHelper(this, name); - return (result.type == Symbol::MESSAGE) ? result.descriptor : nullptr; + return tables_->FindByNameHelper(this, name).descriptor(); } const FieldDescriptor* DescriptorPool::FindFieldByName( ConstStringParam name) const { - Symbol result = tables_->FindByNameHelper(this, name); - if (result.type == Symbol::FIELD && - !result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return nullptr; + if (const FieldDescriptor* field = + tables_->FindByNameHelper(this, name).field_descriptor()) { + if (!field->is_extension()) { + return field; + } } + return nullptr; } const FieldDescriptor* DescriptorPool::FindExtensionByName( ConstStringParam name) const { - Symbol result = tables_->FindByNameHelper(this, name); - if (result.type == Symbol::FIELD && result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return nullptr; + if (const FieldDescriptor* field = + tables_->FindByNameHelper(this, name).field_descriptor()) { + if (field->is_extension()) { + return field; + } } + return nullptr; } const OneofDescriptor* DescriptorPool::FindOneofByName( ConstStringParam name) const { - Symbol result = tables_->FindByNameHelper(this, name); - return (result.type == Symbol::ONEOF) ? result.oneof_descriptor : nullptr; + return tables_->FindByNameHelper(this, name).oneof_descriptor(); } const EnumDescriptor* DescriptorPool::FindEnumTypeByName( ConstStringParam name) const { - Symbol result = tables_->FindByNameHelper(this, name); - return (result.type == Symbol::ENUM) ? result.enum_descriptor : nullptr; + return tables_->FindByNameHelper(this, name).enum_descriptor(); } const EnumValueDescriptor* DescriptorPool::FindEnumValueByName( ConstStringParam name) const { - Symbol result = tables_->FindByNameHelper(this, name); - return (result.type == Symbol::ENUM_VALUE) ? result.enum_value_descriptor - : nullptr; + return tables_->FindByNameHelper(this, name).enum_value_descriptor(); } const ServiceDescriptor* DescriptorPool::FindServiceByName( ConstStringParam name) const { - Symbol result = tables_->FindByNameHelper(this, name); - return (result.type == Symbol::SERVICE) ? result.service_descriptor : nullptr; + return tables_->FindByNameHelper(this, name).service_descriptor(); } const MethodDescriptor* DescriptorPool::FindMethodByName( ConstStringParam name) const { - Symbol result = tables_->FindByNameHelper(this, name); - return (result.type == Symbol::METHOD) ? result.method_descriptor : nullptr; + return tables_->FindByNameHelper(this, name).method_descriptor(); } const FieldDescriptor* DescriptorPool::FindExtensionByNumber( @@ -1607,34 +2180,20 @@ } const FieldDescriptor* Descriptor::FindFieldByName(ConstStringParam key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); - if (!result.IsNull() && !result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return nullptr; - } + const FieldDescriptor* field = + file()->tables_->FindNestedSymbol(this, key).field_descriptor(); + return field != nullptr && !field->is_extension() ? field : nullptr; } const OneofDescriptor* Descriptor::FindOneofByName(ConstStringParam key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ONEOF); - if (!result.IsNull()) { - return result.oneof_descriptor; - } else { - return nullptr; - } + return file()->tables_->FindNestedSymbol(this, key).oneof_descriptor(); } const FieldDescriptor* Descriptor::FindExtensionByName( ConstStringParam key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); - if (!result.IsNull() && result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return nullptr; - } + const FieldDescriptor* field = + file()->tables_->FindNestedSymbol(this, key).field_descriptor(); + return field != nullptr && field->is_extension() ? field : nullptr; } const FieldDescriptor* Descriptor::FindExtensionByLowercaseName( @@ -1660,35 +2219,17 @@ } const Descriptor* Descriptor::FindNestedTypeByName(ConstStringParam key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); - if (!result.IsNull()) { - return result.descriptor; - } else { - return nullptr; - } + return file()->tables_->FindNestedSymbol(this, key).descriptor(); } const EnumDescriptor* Descriptor::FindEnumTypeByName( ConstStringParam key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); - if (!result.IsNull()) { - return result.enum_descriptor; - } else { - return nullptr; - } + return file()->tables_->FindNestedSymbol(this, key).enum_descriptor(); } const EnumValueDescriptor* Descriptor::FindEnumValueByName( ConstStringParam key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); - if (!result.IsNull()) { - return result.enum_value_descriptor; - } else { - return nullptr; - } + return file()->tables_->FindNestedSymbol(this, key).enum_value_descriptor(); } const FieldDescriptor* Descriptor::map_key() const { @@ -1705,13 +2246,7 @@ const EnumValueDescriptor* EnumDescriptor::FindValueByName( ConstStringParam key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); - if (!result.IsNull()) { - return result.enum_value_descriptor; - } else { - return nullptr; - } + return file()->tables_->FindNestedSymbol(this, key).enum_value_descriptor(); } const EnumValueDescriptor* EnumDescriptor::FindValueByNumber(int key) const { @@ -1725,64 +2260,34 @@ const MethodDescriptor* ServiceDescriptor::FindMethodByName( ConstStringParam key) const { - Symbol result = - file()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD); - if (!result.IsNull()) { - return result.method_descriptor; - } else { - return nullptr; - } + return file()->tables_->FindNestedSymbol(this, key).method_descriptor(); } const Descriptor* FileDescriptor::FindMessageTypeByName( ConstStringParam key) const { - Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); - if (!result.IsNull()) { - return result.descriptor; - } else { - return nullptr; - } + return tables_->FindNestedSymbol(this, key).descriptor(); } const EnumDescriptor* FileDescriptor::FindEnumTypeByName( ConstStringParam key) const { - Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); - if (!result.IsNull()) { - return result.enum_descriptor; - } else { - return nullptr; - } + return tables_->FindNestedSymbol(this, key).enum_descriptor(); } const EnumValueDescriptor* FileDescriptor::FindEnumValueByName( ConstStringParam key) const { - Symbol result = - tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); - if (!result.IsNull()) { - return result.enum_value_descriptor; - } else { - return nullptr; - } + return tables_->FindNestedSymbol(this, key).enum_value_descriptor(); } const ServiceDescriptor* FileDescriptor::FindServiceByName( ConstStringParam key) const { - Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE); - if (!result.IsNull()) { - return result.service_descriptor; - } else { - return nullptr; - } + return tables_->FindNestedSymbol(this, key).service_descriptor(); } const FieldDescriptor* FileDescriptor::FindExtensionByName( ConstStringParam key) const { - Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); - if (!result.IsNull() && result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return nullptr; - } + const FieldDescriptor* field = + tables_->FindNestedSymbol(this, key).field_descriptor(); + return field != nullptr && field->is_extension() ? field : nullptr; } const FieldDescriptor* FileDescriptor::FindExtensionByLowercaseName( @@ -1879,7 +2384,7 @@ Symbol symbol = tables_->FindSymbol(prefix); // If the symbol type is anything other than PACKAGE, then its complete // definition is already known. - if (!symbol.IsNull() && symbol.type != Symbol::PACKAGE) { + if (!symbol.IsNull() && symbol.type() != Symbol::PACKAGE) { return true; } } @@ -1968,16 +2473,16 @@ GOOGLE_CHECK(has_default_value()) << "No default value"; switch (cpp_type()) { case CPPTYPE_INT32: - return StrCat(default_value_int32()); + return StrCat(default_value_int32_t()); break; case CPPTYPE_INT64: - return StrCat(default_value_int64()); + return StrCat(default_value_int64_t()); break; case CPPTYPE_UINT32: - return StrCat(default_value_uint32()); + return StrCat(default_value_uint32_t()); break; case CPPTYPE_UINT64: - return StrCat(default_value_uint64()); + return StrCat(default_value_uint64_t()); break; case CPPTYPE_FLOAT: return SimpleFtoa(default_value_float()); @@ -2276,6 +2781,7 @@ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { std::string tmp; TextFormat::Printer printer; + printer.SetExpandAny(true); printer.SetInitialIndentLevel(depth + 1); printer.PrintFieldValueToString(options, field, repeated ? j : -1, &tmp); @@ -2954,7 +3460,7 @@ if (source_code_info_) { if (const SourceCodeInfo_Location* loc = tables_->GetSourceLocation(path, source_code_info_)) { - const RepeatedField<int32>& span = loc->span(); + const RepeatedField<int32_t>& span = loc->span(); if (span.size() == 3 || span.size() == 4) { out_location->start_line = span.Get(0); out_location->start_column = span.Get(1); @@ -3253,7 +3759,7 @@ // package to the symbol table (e.g. AddPackage("foo.bar", ...) will add // "foo.bar" and "foo" to the table). void AddPackage(const std::string& name, const Message& proto, - const FileDescriptor* file); + FileDescriptor* file); // Checks that the symbol name contains only alphanumeric characters and // underscores. Records an error otherwise. @@ -3287,11 +3793,12 @@ DescriptorT* descriptor, const std::vector<int>& options_path, const std::string& option_name); - // Allocate string on the string pool and initialize it to full proto name. + // Allocates an array of two strings, the first one is a copy of `proto_name`, + // and the second one is the full name. // Full proto name is "scope.proto_name" if scope is non-empty and // "proto_name" otherwise. - std::string* AllocateNameString(const std::string& scope, - const std::string& proto_name); + const std::string* AllocateNameStrings(const std::string& scope, + const std::string& proto_name); // These methods all have the same signature for the sake of the BUILD_ARRAY // macro, below. @@ -3419,13 +3926,13 @@ // Convenience functions to set an int field the right way, depending on // its wire type (a single int CppType can represent multiple wire types). - void SetInt32(int number, int32 value, FieldDescriptor::Type type, + void SetInt32(int number, int32_t value, FieldDescriptor::Type type, UnknownFieldSet* unknown_fields); - void SetInt64(int number, int64 value, FieldDescriptor::Type type, + void SetInt64(int number, int64_t value, FieldDescriptor::Type type, UnknownFieldSet* unknown_fields); - void SetUInt32(int number, uint32 value, FieldDescriptor::Type type, + void SetUInt32(int number, uint32_t value, FieldDescriptor::Type type, UnknownFieldSet* unknown_fields); - void SetUInt64(int number, uint64 value, FieldDescriptor::Type type, + void SetUInt64(int number, uint64_t value, FieldDescriptor::Type type, UnknownFieldSet* unknown_fields); // A helper function that adds an error at the specified location of the @@ -3440,7 +3947,11 @@ // A helper function that adds an error at the location of the option name // and returns false. bool AddNameError(const std::string& msg) { +#ifdef PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ + return true; +#else // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg); +#endif // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ } // A helper function that adds an error at the location of the option name @@ -3739,7 +4250,7 @@ return result; } - if (result.type == Symbol::PACKAGE) { + if (result.type() == Symbol::PACKAGE) { // Arg, this is overcomplicated. The symbol is a package name. It could // be that the package was defined in multiple files. result.GetFile() // returns the first file we saw that used this package. We've determined @@ -3882,24 +4393,23 @@ mutex_->AssertHeld(); } // Compute names. - const std::string* placeholder_full_name; - const std::string* placeholder_name; + StringPiece placeholder_full_name; + StringPiece placeholder_name; const std::string* placeholder_package; if (!ValidateQualifiedName(name)) return kNullSymbol; if (name[0] == '.') { // Fully-qualified. - placeholder_full_name = tables_->AllocateString(name.substr(1)); + placeholder_full_name = name.substr(1); } else { - placeholder_full_name = tables_->AllocateString(name); + placeholder_full_name = name; } - std::string::size_type dotpos = placeholder_full_name->find_last_of('.'); + std::string::size_type dotpos = placeholder_full_name.find_last_of('.'); if (dotpos != std::string::npos) { placeholder_package = - tables_->AllocateString(placeholder_full_name->substr(0, dotpos)); - placeholder_name = - tables_->AllocateString(placeholder_full_name->substr(dotpos + 1)); + tables_->AllocateString(placeholder_full_name.substr(0, dotpos)); + placeholder_name = placeholder_full_name.substr(dotpos + 1); } else { placeholder_package = &internal::GetEmptyString(); placeholder_name = placeholder_full_name; @@ -3907,7 +4417,7 @@ // Create the placeholders. FileDescriptor* placeholder_file = NewPlaceholderFileWithMutexHeld( - *placeholder_full_name + ".placeholder.proto"); + StrCat(placeholder_full_name, ".placeholder.proto")); placeholder_file->package_ = placeholder_package; if (placeholder_type == PLACEHOLDER_ENUM) { @@ -3917,8 +4427,8 @@ EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0]; memset(static_cast<void*>(placeholder_enum), 0, sizeof(*placeholder_enum)); - placeholder_enum->full_name_ = placeholder_full_name; - placeholder_enum->name_ = placeholder_name; + placeholder_enum->all_names_ = + tables_->AllocateStringArray(placeholder_name, placeholder_full_name); placeholder_enum->file_ = placeholder_file; placeholder_enum->options_ = &EnumOptions::default_instance(); placeholder_enum->is_placeholder_ = true; @@ -3932,13 +4442,11 @@ memset(static_cast<void*>(placeholder_value), 0, sizeof(*placeholder_value)); - placeholder_value->name_ = tables_->AllocateString("PLACEHOLDER_VALUE"); // Note that enum value names are siblings of their type, not children. - placeholder_value->full_name_ = - placeholder_package->empty() - ? placeholder_value->name_ - : tables_->AllocateString(*placeholder_package + - ".PLACEHOLDER_VALUE"); + placeholder_value->all_names_ = tables_->AllocateStringArray( + "PLACEHOLDER_VALUE", placeholder_package->empty() + ? "PLACEHOLDER_VALUE" + : *placeholder_package + ".PLACEHOLDER_VALUE"); placeholder_value->number_ = 0; placeholder_value->type_ = placeholder_enum; @@ -3953,8 +4461,8 @@ memset(static_cast<void*>(placeholder_message), 0, sizeof(*placeholder_message)); - placeholder_message->full_name_ = placeholder_full_name; - placeholder_message->name_ = placeholder_name; + placeholder_message->all_names_ = + tables_->AllocateStringArray(placeholder_name, placeholder_full_name); placeholder_message->file_ = placeholder_file; placeholder_message->options_ = &MessageOptions::default_instance(); placeholder_message->is_placeholder_ = true; @@ -3968,6 +4476,7 @@ // kMaxNumber + 1 because ExtensionRange::end is exclusive. placeholder_message->extension_ranges_->end = FieldDescriptor::kMaxNumber + 1; + placeholder_message->extension_ranges_->options_ = nullptr; } return Symbol(placeholder_message); @@ -4052,37 +4561,40 @@ } void DescriptorBuilder::AddPackage(const std::string& name, - const Message& proto, - const FileDescriptor* file) { + const Message& proto, FileDescriptor* file) { if (name.find('\0') != std::string::npos) { AddError(name, proto, DescriptorPool::ErrorCollector::NAME, "\"" + name + "\" contains null character."); return; } - if (tables_->AddSymbol(name, Symbol(file))) { - // Success. Also add parent package, if any. + + Symbol existing_symbol = tables_->FindSymbol(name); + // It's OK to redefine a package. + if (existing_symbol.IsNull()) { + auto* package = tables_->AllocateArray<Symbol::Package>(1); + // If the name is the package name, then it is already in the arena. + // If not, copy it there. It came from the call to AddPackage below. + package->name = + &name == &file->package() ? &name : tables_->AllocateString(name); + package->file = file; + tables_->AddSymbol(*package->name, Symbol(package)); + // Also add parent package, if any. std::string::size_type dot_pos = name.find_last_of('.'); if (dot_pos == std::string::npos) { // No parents. ValidateSymbolName(name, name, proto); } else { // Has parent. - std::string* parent_name = - tables_->AllocateString(name.substr(0, dot_pos)); - AddPackage(*parent_name, proto, file); + AddPackage(name.substr(0, dot_pos), proto, file); ValidateSymbolName(name.substr(dot_pos + 1), name, proto); } - } else { - Symbol existing_symbol = tables_->FindSymbol(name); - // It's OK to redefine a package. - if (existing_symbol.type != Symbol::PACKAGE) { - // Symbol seems to have been defined in a different file. - AddError(name, proto, DescriptorPool::ErrorCollector::NAME, - "\"" + name + - "\" is already defined (as something other than " - "a package) in file \"" + - existing_symbol.GetFile()->name() + "\"."); - } + } else if (existing_symbol.type() != Symbol::PACKAGE) { + // Symbol seems to have been defined in a different file. + AddError(name, proto, DescriptorPool::ErrorCollector::NAME, + "\"" + name + + "\" is already defined (as something other than " + "a package) in file \"" + + existing_symbol.GetFile()->name() + "\"."); } } @@ -4177,12 +4689,12 @@ if (!unknown_fields.empty()) { // Can not use options->GetDescriptor() which may case deadlock. Symbol msg_symbol = tables_->FindSymbol(option_name); - if (msg_symbol.type == Symbol::MESSAGE) { + if (msg_symbol.type() == Symbol::MESSAGE) { for (int i = 0; i < unknown_fields.field_count(); ++i) { assert_mutex_held(pool_); const FieldDescriptor* field = pool_->InternalFindExtensionByNumberNoLock( - msg_symbol.descriptor, unknown_fields.field(i).number()); + msg_symbol.descriptor(), unknown_fields.field(i).number()); if (field) { unused_dependency_.erase(field->file()); } @@ -4395,18 +4907,7 @@ result->dependency_count_ = proto.dependency_size(); result->dependencies_ = tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size()); - if (pool_->lazily_build_dependencies_) { - result->dependencies_once_ = tables_->AllocateOnceDynamic(); - result->dependencies_names_ = - tables_->AllocateArray<const std::string*>(proto.dependency_size()); - if (proto.dependency_size() > 0) { - memset(result->dependencies_names_, 0, - sizeof(*result->dependencies_names_) * proto.dependency_size()); - } - } else { - result->dependencies_once_ = nullptr; - result->dependencies_names_ = nullptr; - } + result->dependencies_once_ = nullptr; unused_dependency_.clear(); std::set<int> weak_deps; for (int i = 0; i < proto.weak_dependency_size(); ++i) { @@ -4452,7 +4953,17 @@ result->dependencies_[i] = dependency; if (pool_->lazily_build_dependencies_ && !dependency) { - result->dependencies_names_[i] = + if (result->dependencies_once_ == nullptr) { + result->dependencies_once_ = tables_->AllocateLazyInit(); + result->dependencies_once_->file.dependencies_names = + tables_->AllocateArray<const std::string*>(proto.dependency_size()); + if (proto.dependency_size() > 0) { + std::fill_n(result->dependencies_once_->file.dependencies_names, + proto.dependency_size(), nullptr); + } + } + + result->dependencies_once_->file.dependencies_names[i] = tables_->AllocateString(proto.dependency(i)); } } @@ -4570,16 +5081,14 @@ } -std::string* DescriptorBuilder::AllocateNameString( +const std::string* DescriptorBuilder::AllocateNameStrings( const std::string& scope, const std::string& proto_name) { - std::string* full_name; if (scope.empty()) { - full_name = tables_->AllocateString(proto_name); + return tables_->AllocateStringArray(proto_name, proto_name); } else { - full_name = tables_->AllocateEmptyString(); - *full_name = StrCat(scope, ".", proto_name); + return tables_->AllocateStringArray(proto_name, + StrCat(scope, ".", proto_name)); } - return full_name; } void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, @@ -4587,18 +5096,16 @@ Descriptor* result) { const std::string& scope = (parent == nullptr) ? file_->package() : parent->full_name(); - std::string* full_name = AllocateNameString(scope, proto.name()); - ValidateSymbolName(proto.name(), *full_name, proto); + result->all_names_ = AllocateNameStrings(scope, proto.name()); + ValidateSymbolName(proto.name(), result->full_name(), proto); - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; result->file_ = file_; result->containing_type_ = parent; result->is_placeholder_ = false; result->is_unqualified_placeholder_ = false; result->well_known_type_ = Descriptor::WELLKNOWNTYPE_UNSPECIFIED; - auto it = pool_->tables_->well_known_types_.find(*full_name); + auto it = pool_->tables_->well_known_types_.find(result->full_name()); if (it != pool_->tables_->well_known_types_.end()) { result->well_known_type_ = it->second; } @@ -4726,11 +5233,19 @@ bool is_extension) { const std::string& scope = (parent == nullptr) ? file_->package() : parent->full_name(); - std::string* full_name = AllocateNameString(scope, proto.name()); - ValidateSymbolName(proto.name(), *full_name, proto); - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; + // We allocate all names in a single array, and dedup them. + // We remember the indices for the potentially deduped values. + auto all_names = tables_->AllocateFieldNames( + proto.name(), scope, + proto.has_json_name() ? &proto.json_name() : nullptr); + result->all_names_ = all_names.array; + result->lowercase_name_index_ = all_names.lowercase_index; + result->camelcase_name_index_ = all_names.camelcase_index; + result->json_name_index_ = all_names.json_index; + + ValidateSymbolName(proto.name(), result->full_name(), proto); + result->file_ = file_; result->number_ = proto.number(); result->is_extension_ = is_extension; @@ -4744,31 +5259,7 @@ result->full_name()); } - // If .proto files follow the style guide then the name should already be - // lower-cased. If that's the case we can just reuse the string we - // already allocated rather than allocate a new one. - std::string lowercase_name(proto.name()); - LowerString(&lowercase_name); - if (lowercase_name == proto.name()) { - result->lowercase_name_ = result->name_; - } else { - result->lowercase_name_ = tables_->AllocateString(lowercase_name); - } - - // Don't bother with the above optimization for camel-case names since - // .proto files that follow the guide shouldn't be using names in this - // format, so the optimization wouldn't help much. - result->camelcase_name_ = - tables_->AllocateString(ToCamelCase(proto.name(), - /* lower_first = */ true)); - - if (proto.has_json_name()) { - result->has_json_name_ = true; - result->json_name_ = tables_->AllocateString(proto.json_name()); - } else { - result->has_json_name_ = false; - result->json_name_ = tables_->AllocateString(ToJsonName(proto.name())); - } + result->has_json_name_ = proto.has_json_name(); // Some compilers do not allow static_cast directly between two enum types, // so we must cast to int first. @@ -4796,10 +5287,8 @@ result->extension_scope_ = nullptr; result->message_type_ = nullptr; result->enum_type_ = nullptr; - result->type_name_ = nullptr; result->type_once_ = nullptr; result->default_value_enum_ = nullptr; - result->default_value_enum_name_ = nullptr; result->has_default_value_ = proto.has_default_value(); if (proto.has_default_value() && result->is_repeated()) { @@ -4813,19 +5302,19 @@ char* end_pos = nullptr; switch (result->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: - result->default_value_int32_ = + result->default_value_int32_t_ = strtol(proto.default_value().c_str(), &end_pos, 0); break; case FieldDescriptor::CPPTYPE_INT64: - result->default_value_int64_ = + result->default_value_int64_t_ = strto64(proto.default_value().c_str(), &end_pos, 0); break; case FieldDescriptor::CPPTYPE_UINT32: - result->default_value_uint32_ = + result->default_value_uint32_t_ = strtoul(proto.default_value().c_str(), &end_pos, 0); break; case FieldDescriptor::CPPTYPE_UINT64: - result->default_value_uint64_ = + result->default_value_uint64_t_ = strtou64(proto.default_value().c_str(), &end_pos, 0); break; case FieldDescriptor::CPPTYPE_FLOAT: @@ -4906,16 +5395,16 @@ // No explicit default value switch (result->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: - result->default_value_int32_ = 0; + result->default_value_int32_t_ = 0; break; case FieldDescriptor::CPPTYPE_INT64: - result->default_value_int64_ = 0; + result->default_value_int64_t_ = 0; break; case FieldDescriptor::CPPTYPE_UINT32: - result->default_value_uint32_ = 0; + result->default_value_uint32_t_ = 0; break; case FieldDescriptor::CPPTYPE_UINT64: - result->default_value_uint64_ = 0; + result->default_value_uint64_t_ = 0; break; case FieldDescriptor::CPPTYPE_FLOAT: result->default_value_float_ = 0.0f; @@ -5083,12 +5572,8 @@ void DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto, Descriptor* parent, OneofDescriptor* result) { - std::string* full_name = - AllocateNameString(parent->full_name(), proto.name()); - ValidateSymbolName(proto.name(), *full_name, proto); - - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; + result->all_names_ = AllocateNameStrings(parent->full_name(), proto.name()); + ValidateSymbolName(proto.name(), result->full_name(), proto); result->containing_type_ = parent; @@ -5178,11 +5663,9 @@ EnumDescriptor* result) { const std::string& scope = (parent == nullptr) ? file_->package() : parent->full_name(); - std::string* full_name = AllocateNameString(scope, proto.name()); - ValidateSymbolName(proto.name(), *full_name, proto); - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; + result->all_names_ = AllocateNameStrings(scope, proto.name()); + ValidateSymbolName(proto.name(), result->full_name(), proto); result->file_ = file_; result->containing_type_ = parent; result->is_placeholder_ = false; @@ -5272,20 +5755,20 @@ void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto, const EnumDescriptor* parent, EnumValueDescriptor* result) { - result->name_ = tables_->AllocateString(proto.name()); + // Note: full_name for enum values is a sibling to the parent's name, not a + // child of it. + std::string full_name; + size_t scope_len = parent->full_name().size() - parent->name().size(); + full_name.reserve(scope_len + proto.name().size()); + full_name.append(parent->full_name().data(), scope_len); + full_name.append(proto.name()); + + result->all_names_ = + tables_->AllocateStringArray(proto.name(), std::move(full_name)); result->number_ = proto.number(); result->type_ = parent; - // Note: full_name for enum values is a sibling to the parent's name, not a - // child of it. - std::string* full_name = tables_->AllocateEmptyString(); - size_t scope_len = parent->full_name_->size() - parent->name_->size(); - full_name->reserve(scope_len + result->name_->size()); - full_name->append(parent->full_name_->data(), scope_len); - full_name->append(*result->name_); - result->full_name_ = full_name; - - ValidateSymbolName(proto.name(), *full_name, proto); + ValidateSymbolName(proto.name(), result->full_name(), proto); // Copy options. result->options_ = nullptr; // Set to default_instance later if necessary. @@ -5300,14 +5783,14 @@ // parent->containing_type() as the value's parent. bool added_to_outer_scope = AddSymbol(result->full_name(), parent->containing_type(), result->name(), - proto, Symbol(result)); + proto, Symbol::EnumValue(result, 0)); // However, we also want to be able to search for values within a single // enum type, so we add it as a child of the enum type itself, too. // Note: This could fail, but if it does, the error has already been // reported by the above AddSymbol() call, so we ignore the return code. - bool added_to_inner_scope = - file_tables_->AddAliasUnderParent(parent, result->name(), Symbol(result)); + bool added_to_inner_scope = file_tables_->AddAliasUnderParent( + parent, result->name(), Symbol::EnumValue(result, 1)); if (added_to_inner_scope && !added_to_outer_scope) { // This value did not conflict with any values defined in the same enum, @@ -5343,12 +5826,9 @@ void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto, const void* /* dummy */, ServiceDescriptor* result) { - std::string* full_name = AllocateNameString(file_->package(), proto.name()); - ValidateSymbolName(proto.name(), *full_name, proto); - - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; + result->all_names_ = AllocateNameStrings(file_->package(), proto.name()); result->file_ = file_; + ValidateSymbolName(proto.name(), result->full_name(), proto); BUILD_ARRAY(proto, result, method, BuildMethod, result); @@ -5367,14 +5847,10 @@ void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto, const ServiceDescriptor* parent, MethodDescriptor* result) { - result->name_ = tables_->AllocateString(proto.name()); result->service_ = parent; + result->all_names_ = AllocateNameStrings(parent->full_name(), proto.name()); - std::string* full_name = - AllocateNameString(parent->full_name(), *result->name_); - result->full_name_ = full_name; - - ValidateSymbolName(proto.name(), *full_name, proto); + ValidateSymbolName(proto.name(), result->full_name(), proto); // These will be filled in when cross-linking. result->input_type_.Init(); @@ -5570,13 +6046,13 @@ DescriptorPool::ErrorCollector::EXTENDEE, proto.extendee()); return; - } else if (extendee.type != Symbol::MESSAGE) { + } else if (extendee.type() != Symbol::MESSAGE) { AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::EXTENDEE, "\"" + proto.extendee() + "\" is not a message type."); return; } - field->containing_type_ = extendee.descriptor; + field->containing_type_ = extendee.descriptor(); const Descriptor::ExtensionRange* extension_range = field->containing_type()->FindExtensionRangeContainingNumber( @@ -5637,10 +6113,10 @@ // Save the symbol names for later for lookup, and allocate the once // object needed for the accessors. std::string name = proto.type_name(); - field->type_once_ = tables_->AllocateOnceDynamic(); - field->type_name_ = tables_->AllocateString(name); + field->type_once_ = tables_->AllocateLazyInit(); + field->type_once_->field.type_name = tables_->AllocateString(name); if (proto.has_default_value()) { - field->default_value_enum_name_ = + field->type_once_->field.default_value_enum_name = tables_->AllocateString(proto.default_value()); } // AddFieldByNumber and AddExtension are done later in this function, @@ -5670,9 +6146,9 @@ if (!proto.has_type()) { // Choose field type based on symbol. - if (type.type == Symbol::MESSAGE) { + if (type.type() == Symbol::MESSAGE) { field->type_ = FieldDescriptor::TYPE_MESSAGE; - } else if (type.type == Symbol::ENUM) { + } else if (type.type() == Symbol::ENUM) { field->type_ = FieldDescriptor::TYPE_ENUM; } else { AddError(field->full_name(), proto, @@ -5683,13 +6159,13 @@ } if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (type.type != Symbol::MESSAGE) { + field->message_type_ = type.descriptor(); + if (field->message_type_ == nullptr) { AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, "\"" + proto.type_name() + "\" is not a message type."); return; } - field->message_type_ = type.descriptor; if (field->has_default_value()) { AddError(field->full_name(), proto, @@ -5697,13 +6173,13 @@ "Messages can't have default values."); } } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - if (type.type != Symbol::ENUM) { + field->enum_type_ = type.enum_descriptor(); + if (field->enum_type_ == nullptr) { AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, "\"" + proto.type_name() + "\" is not an enum type."); return; } - field->enum_type_ = type.enum_descriptor; if (field->enum_type()->is_placeholder_) { // We can't look up default values for placeholder types. We'll have @@ -5725,13 +6201,14 @@ // We can't just use field->enum_type()->FindValueByName() here // because that locks the pool's mutex, which we have already locked // at this point. - Symbol default_value = LookupSymbolNoPlaceholder( - proto.default_value(), field->enum_type()->full_name()); + const EnumValueDescriptor* default_value = + LookupSymbolNoPlaceholder(proto.default_value(), + field->enum_type()->full_name()) + .enum_value_descriptor(); - if (default_value.type == Symbol::ENUM_VALUE && - default_value.enum_value_descriptor->type() == - field->enum_type()) { - field->default_value_enum_ = default_value.enum_value_descriptor; + if (default_value != nullptr && + default_value->type() == field->enum_type()) { + field->default_value_enum_ = default_value; } else { AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::DEFAULT_VALUE, @@ -5859,12 +6336,12 @@ } else { method->input_type_.SetLazy(proto.input_type(), file_); } - } else if (input_type.type != Symbol::MESSAGE) { + } else if (input_type.type() != Symbol::MESSAGE) { AddError(method->full_name(), proto, DescriptorPool::ErrorCollector::INPUT_TYPE, "\"" + proto.input_type() + "\" is not a message type."); } else { - method->input_type_.Set(input_type.descriptor); + method->input_type_.Set(input_type.descriptor()); } Symbol output_type = @@ -5879,12 +6356,12 @@ } else { method->output_type_.SetLazy(proto.output_type(), file_); } - } else if (output_type.type != Symbol::MESSAGE) { + } else if (output_type.type() != Symbol::MESSAGE) { AddError(method->full_name(), proto, DescriptorPool::ErrorCollector::OUTPUT_TYPE, "\"" + proto.output_type() + "\" is not a message type."); } else { - method->output_type_.Set(output_type.descriptor); + method->output_type_.Set(output_type.descriptor()); } } @@ -6056,10 +6533,10 @@ VALIDATE_OPTIONS_FROM_ARRAY(message, enum_type, Enum); VALIDATE_OPTIONS_FROM_ARRAY(message, extension, Field); - const int64 max_extension_range = - static_cast<int64>(message->options().message_set_wire_format() - ? kint32max - : FieldDescriptor::kMaxNumber); + const int64_t max_extension_range = + static_cast<int64_t>(message->options().message_set_wire_format() + ? kint32max + : FieldDescriptor::kMaxNumber); for (int i = 0; i < message->extension_range_count(); ++i) { if (message->extension_range(i)->end > max_extension_range + 1) { AddError(message->full_name(), proto.extension_range(i), @@ -6497,9 +6974,8 @@ // the file that defines the option, not descriptor.proto itself. Symbol symbol = builder_->FindSymbolNotEnforcingDeps( options->GetDescriptor()->full_name()); - if (!symbol.IsNull() && symbol.type == Symbol::MESSAGE) { - options_descriptor = symbol.descriptor; - } else { + options_descriptor = symbol.descriptor(); + if (options_descriptor == nullptr) { // The options message's descriptor was not in the builder's pool, so use // the standard version from the generated pool. We're not holding the // generated pool's mutex, so we can search it the straightforward way. @@ -6535,9 +7011,7 @@ // mutex, and the latter method locks it again. symbol = builder_->LookupSymbol(name_part, options_to_interpret_->name_scope); - if (!symbol.IsNull() && symbol.type == Symbol::FIELD) { - field = symbol.field_descriptor; - } + field = symbol.field_descriptor(); // If we don't find the field then the field's descriptor was not in the // builder's pool, but there's no point in looking in the generated // pool. We require that you import the file that defines any extensions @@ -6708,7 +7182,7 @@ if (matched) { // see if this location is in the range to remove bool loc_matches = true; - if (loc->path_size() < static_cast<int64>(pathv.size())) { + if (loc->path_size() < static_cast<int64_t>(pathv.size())) { loc_matches = false; } else { for (size_t j = 0; j < pathv.size(); j++) { @@ -6851,7 +7325,7 @@ case FieldDescriptor::CPPTYPE_INT32: if (uninterpreted_option_->has_positive_int_value()) { if (uninterpreted_option_->positive_int_value() > - static_cast<uint64>(kint32max)) { + static_cast<uint64_t>(kint32max)) { return AddValueError("Value out of range for int32 option \"" + option_field->full_name() + "\"."); } else { @@ -6861,7 +7335,7 @@ } } else if (uninterpreted_option_->has_negative_int_value()) { if (uninterpreted_option_->negative_int_value() < - static_cast<int64>(kint32min)) { + static_cast<int64_t>(kint32min)) { return AddValueError("Value out of range for int32 option \"" + option_field->full_name() + "\"."); } else { @@ -6878,7 +7352,7 @@ case FieldDescriptor::CPPTYPE_INT64: if (uninterpreted_option_->has_positive_int_value()) { if (uninterpreted_option_->positive_int_value() > - static_cast<uint64>(kint64max)) { + static_cast<uint64_t>(kint64max)) { return AddValueError("Value out of range for int64 option \"" + option_field->full_name() + "\"."); } else { @@ -6962,7 +7436,7 @@ } case FieldDescriptor::CPPTYPE_BOOL: - uint64 value; + uint64_t value; if (!uninterpreted_option_->has_identifier_value()) { return AddValueError( "Value must be identifier for boolean option " @@ -7007,15 +7481,15 @@ // the pool's mutex, and the latter method locks it again. Symbol symbol = builder_->FindSymbolNotEnforcingDeps(fully_qualified_name); - if (!symbol.IsNull() && symbol.type == Symbol::ENUM_VALUE) { - if (symbol.enum_value_descriptor->type() != enum_type) { + if (auto* candicate_descriptor = symbol.enum_value_descriptor()) { + if (candicate_descriptor->type() != enum_type) { return AddValueError( "Enum type \"" + enum_type->full_name() + "\" has no value named \"" + value_name + "\" for option \"" + option_field->full_name() + "\". This appears to be a value from a sibling type."); } else { - enum_value = symbol.enum_value_descriptor; + enum_value = candicate_descriptor; } } } else { @@ -7032,11 +7506,11 @@ "option \"" + option_field->full_name() + "\"."); } else { - // Sign-extension is not a problem, since we cast directly from int32 to - // uint64, without first going through uint32. + // Sign-extension is not a problem, since we cast directly from int32_t + // to uint64_t, without first going through uint32_t. unknown_fields->AddVarint( option_field->number(), - static_cast<uint64>(static_cast<int64>(enum_value->number()))); + static_cast<uint64_t>(static_cast<int64_t>(enum_value->number()))); } break; } @@ -7076,8 +7550,7 @@ return nullptr; } assert_mutex_held(builder_->pool_); - Symbol result = builder_->FindSymbol(name); - return result.type == Symbol::MESSAGE ? result.descriptor : nullptr; + return builder_->FindSymbol(name).descriptor(); } const FieldDescriptor* FindExtension(Message* message, @@ -7086,12 +7559,11 @@ const Descriptor* descriptor = message->GetDescriptor(); Symbol result = builder_->LookupSymbolNoPlaceholder(name, descriptor->full_name()); - if (result.type == Symbol::FIELD && - result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else if (result.type == Symbol::MESSAGE && + if (auto* field = result.field_descriptor()) { + return field; + } else if (result.type() == Symbol::MESSAGE && descriptor->options().message_set_wire_format()) { - const Descriptor* foreign_type = result.descriptor; + const Descriptor* foreign_type = result.descriptor(); // The text format allows MessageSet items to be specified using // the type name, rather than the extension identifier. If the symbol // lookup returned a Message, and the enclosing Message has @@ -7180,16 +7652,16 @@ } void DescriptorBuilder::OptionInterpreter::SetInt32( - int number, int32 value, FieldDescriptor::Type type, + int number, int32_t value, FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { switch (type) { case FieldDescriptor::TYPE_INT32: - unknown_fields->AddVarint(number, - static_cast<uint64>(static_cast<int64>(value))); + unknown_fields->AddVarint( + number, static_cast<uint64_t>(static_cast<int64_t>(value))); break; case FieldDescriptor::TYPE_SFIXED32: - unknown_fields->AddFixed32(number, static_cast<uint32>(value)); + unknown_fields->AddFixed32(number, static_cast<uint32_t>(value)); break; case FieldDescriptor::TYPE_SINT32: @@ -7204,15 +7676,15 @@ } void DescriptorBuilder::OptionInterpreter::SetInt64( - int number, int64 value, FieldDescriptor::Type type, + int number, int64_t value, FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { switch (type) { case FieldDescriptor::TYPE_INT64: - unknown_fields->AddVarint(number, static_cast<uint64>(value)); + unknown_fields->AddVarint(number, static_cast<uint64_t>(value)); break; case FieldDescriptor::TYPE_SFIXED64: - unknown_fields->AddFixed64(number, static_cast<uint64>(value)); + unknown_fields->AddFixed64(number, static_cast<uint64_t>(value)); break; case FieldDescriptor::TYPE_SINT64: @@ -7227,15 +7699,15 @@ } void DescriptorBuilder::OptionInterpreter::SetUInt32( - int number, uint32 value, FieldDescriptor::Type type, + int number, uint32_t value, FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { switch (type) { case FieldDescriptor::TYPE_UINT32: - unknown_fields->AddVarint(number, static_cast<uint64>(value)); + unknown_fields->AddVarint(number, static_cast<uint64_t>(value)); break; case FieldDescriptor::TYPE_FIXED32: - unknown_fields->AddFixed32(number, static_cast<uint32>(value)); + unknown_fields->AddFixed32(number, static_cast<uint32_t>(value)); break; default: @@ -7245,7 +7717,7 @@ } void DescriptorBuilder::OptionInterpreter::SetUInt64( - int number, uint64 value, FieldDescriptor::Type type, + int number, uint64_t value, FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { switch (type) { case FieldDescriptor::TYPE_UINT64: @@ -7300,33 +7772,32 @@ // enum_type_, message_type_, and default_value_enum_ appropriately. void FieldDescriptor::InternalTypeOnceInit() const { GOOGLE_CHECK(file()->finished_building_ == true); - if (type_name_) { + if (type_once_->field.type_name) { Symbol result = file()->pool()->CrossLinkOnDemandHelper( - *type_name_, type_ == FieldDescriptor::TYPE_ENUM); - if (result.type == Symbol::MESSAGE) { + *type_once_->field.type_name, type_ == FieldDescriptor::TYPE_ENUM); + if (result.type() == Symbol::MESSAGE) { type_ = FieldDescriptor::TYPE_MESSAGE; - message_type_ = result.descriptor; - } else if (result.type == Symbol::ENUM) { + message_type_ = result.descriptor(); + } else if (result.type() == Symbol::ENUM) { type_ = FieldDescriptor::TYPE_ENUM; - enum_type_ = result.enum_descriptor; + enum_type_ = result.enum_descriptor(); } } if (enum_type_ && !default_value_enum_) { - if (default_value_enum_name_) { + if (type_once_->field.default_value_enum_name) { // Have to build the full name now instead of at CrossLink time, // because enum_type_ may not be known at the time. std::string name = enum_type_->full_name(); // Enum values reside in the same scope as the enum type. std::string::size_type last_dot = name.find_last_of('.'); if (last_dot != std::string::npos) { - name = name.substr(0, last_dot) + "." + *default_value_enum_name_; + name = name.substr(0, last_dot) + "." + + *type_once_->field.default_value_enum_name; } else { - name = *default_value_enum_name_; + name = *type_once_->field.default_value_enum_name; } Symbol result = file()->pool()->CrossLinkOnDemandHelper(name, true); - if (result.type == Symbol::ENUM_VALUE) { - default_value_enum_ = result.enum_value_descriptor; - } + default_value_enum_ = result.enum_value_descriptor(); } if (!default_value_enum_) { // We use the first defined value as the default @@ -7346,21 +7817,21 @@ // import building and cross linking of a field of a message. const Descriptor* FieldDescriptor::message_type() const { if (type_once_) { - internal::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this); + internal::call_once(type_once_->once, FieldDescriptor::TypeOnceInit, this); } return message_type_; } const EnumDescriptor* FieldDescriptor::enum_type() const { if (type_once_) { - internal::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this); + internal::call_once(type_once_->once, FieldDescriptor::TypeOnceInit, this); } return enum_type_; } const EnumValueDescriptor* FieldDescriptor::default_value_enum() const { if (type_once_) { - internal::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this); + internal::call_once(type_once_->once, FieldDescriptor::TypeOnceInit, this); } return default_value_enum_; } @@ -7376,9 +7847,10 @@ void FileDescriptor::InternalDependenciesOnceInit() const { GOOGLE_CHECK(finished_building_ == true); + auto* names = dependencies_once_->file.dependencies_names; for (int i = 0; i < dependency_count(); i++) { - if (dependencies_names_[i]) { - dependencies_[i] = pool_->FindFileByName(*dependencies_names_[i]); + if (names[i]) { + dependencies_[i] = pool_->FindFileByName(*names[i]); } } } @@ -7391,7 +7863,7 @@ if (dependencies_once_) { // Do once init for all indices, as it's unlikely only a single index would // be called, and saves on internal::call_once allocations. - internal::call_once(*dependencies_once_, + internal::call_once(dependencies_once_->once, FileDescriptor::DependenciesOnceInit, this); } return dependencies_[index]; @@ -7408,9 +7880,7 @@ namespace internal { void LazyDescriptor::Set(const Descriptor* descriptor) { - GOOGLE_CHECK(!name_); GOOGLE_CHECK(!once_); - GOOGLE_CHECK(!file_); descriptor_ = descriptor; } @@ -7418,31 +7888,32 @@ const FileDescriptor* file) { // verify Init() has been called and Set hasn't been called yet. GOOGLE_CHECK(!descriptor_); - GOOGLE_CHECK(!file_); - GOOGLE_CHECK(!name_); GOOGLE_CHECK(!once_); GOOGLE_CHECK(file && file->pool_); GOOGLE_CHECK(file->pool_->lazily_build_dependencies_); GOOGLE_CHECK(!file->finished_building_); - file_ = file; - name_ = file->pool_->tables_->AllocateString(name); - once_ = file->pool_->tables_->AllocateOnceDynamic(); + once_ = file->pool_->tables_->AllocateLazyInit(); + once_->descriptor.file = file; + once_->descriptor.name = file->pool_->tables_->AllocateString(name); } void LazyDescriptor::Once() { if (once_) { - internal::call_once(*once_, LazyDescriptor::OnceStatic, this); + internal::call_once(once_->once, LazyDescriptor::OnceStatic, this); } } void LazyDescriptor::OnceStatic(LazyDescriptor* lazy) { lazy->OnceInternal(); } void LazyDescriptor::OnceInternal() { - GOOGLE_CHECK(file_->finished_building_); - if (!descriptor_ && name_) { - Symbol result = file_->pool_->CrossLinkOnDemandHelper(*name_, false); - if (!result.IsNull() && result.type == Symbol::MESSAGE) { - descriptor_ = result.descriptor; + auto* file = once_->descriptor.file; + auto* name = once_->descriptor.name; + GOOGLE_CHECK(file->finished_building_); + if (!descriptor_ && name) { + auto* descriptor = + file->pool_->CrossLinkOnDemandHelper(*name, false).descriptor(); + if (descriptor != nullptr) { + descriptor_ = descriptor; } } }
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 0625b50..d2bf86e 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h
@@ -121,7 +121,7 @@ // Defined in descriptor.cc class DescriptorBuilder; class FileDescriptorTables; -struct Symbol; +class Symbol; // Defined in unknown_field_set.h. class UnknownField; @@ -182,15 +182,37 @@ // which is needed when a pool has lazily_build_dependencies_ set. // Must be instantiated as mutable in a descriptor. namespace internal { + +// Data required to do lazy initialization. +struct PROTOBUF_EXPORT LazyInitData { +#ifndef SWIG + internal::once_flag once; +#endif + struct Field { + const std::string* type_name; + const std::string* default_value_enum_name; + }; + struct Descriptor { + const std::string* name; + const FileDescriptor* file; + }; + struct File { + const std::string** dependencies_names; + }; + union { + Field field; + Descriptor descriptor; + File file; + }; +}; + class PROTOBUF_EXPORT LazyDescriptor { public: // Init function to be called at init time of a descriptor containing // a LazyDescriptor. void Init() { descriptor_ = nullptr; - name_ = nullptr; once_ = nullptr; - file_ = nullptr; } // Sets the value of the descriptor if it is known during the descriptor @@ -220,10 +242,22 @@ void Once(); const Descriptor* descriptor_; - const std::string* name_; - internal::once_flag* once_; - const FileDescriptor* file_; + LazyInitData* once_; }; + +class PROTOBUF_EXPORT SymbolBase { + private: + friend class google::protobuf::Symbol; + uint8_t symbol_type_; +}; + +// Some types have more than one SymbolBase because they have multiple +// identities in the table. We can't have duplicate direct bases, so we use this +// intermediate base to do so. +// See BuildEnumValue for details. +template <int N> +class PROTOBUF_EXPORT SymbolBaseN : public SymbolBase {}; + } // namespace internal // Describes a type of protocol message, or a particular group within a @@ -231,7 +265,7 @@ // Message::GetDescriptor(). Generated message classes also have a // static method called descriptor() which returns the type's descriptor. // Use DescriptorPool to construct your own descriptors. -class PROTOBUF_EXPORT Descriptor { +class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase { public: typedef DescriptorProto Proto; @@ -500,6 +534,7 @@ const FieldDescriptor* map_value() const; private: + friend class Symbol; typedef MessageOptions OptionsType; // Allows tests to test CopyTo(proto, true). @@ -524,8 +559,16 @@ // to this descriptor from the file root. void GetLocationPath(std::vector<int>* output) const; - const std::string* name_; - const std::string* full_name_; + // True if this is a placeholder for an unknown type. + bool is_placeholder_ : 1; + // True if this is a placeholder and the type name wasn't fully-qualified. + bool is_unqualified_placeholder_ : 1; + // Well known type. Stored as char to conserve space. + char well_known_type_; + int field_count_; + + // all_names_ = [name, full_name] + const std::string* all_names_; const FileDescriptor* file_; const Descriptor* containing_type_; const MessageOptions* options_; @@ -540,7 +583,6 @@ ReservedRange* reserved_ranges_; const std::string** reserved_names_; - int field_count_; int oneof_decl_count_; int real_oneof_decl_count_; int nested_type_count_; @@ -550,13 +592,6 @@ int reserved_range_count_; int reserved_name_count_; - // True if this is a placeholder for an unknown type. - bool is_placeholder_; - // True if this is a placeholder and the type name wasn't fully-qualified. - bool is_unqualified_placeholder_; - // Well known type. Stored as char to conserve space. - char well_known_type_; - // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate<Descriptor>() and AllocateArray<Descriptor>() in descriptor.cc // and update them to initialize the field. @@ -584,7 +619,7 @@ // - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber() or // DescriptorPool::FindExtensionByPrintableName(). // Use DescriptorPool to construct your own descriptors. -class PROTOBUF_EXPORT FieldDescriptor { +class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase { public: typedef FieldDescriptorProto Proto; @@ -727,16 +762,20 @@ // Get the field default value if cpp_type() == CPPTYPE_INT32. If no // explicit default was defined, the default is 0. - int32 default_value_int32() const; + int32_t default_value_int32_t() const; + int32_t default_value_int32() const { return default_value_int32_t(); } // Get the field default value if cpp_type() == CPPTYPE_INT64. If no // explicit default was defined, the default is 0. - int64 default_value_int64() const; + int64_t default_value_int64_t() const; + int64_t default_value_int64() const { return default_value_int64_t(); } // Get the field default value if cpp_type() == CPPTYPE_UINT32. If no // explicit default was defined, the default is 0. - uint32 default_value_uint32() const; + uint32_t default_value_uint32_t() const; + uint32_t default_value_uint32() const { return default_value_uint32_t(); } // Get the field default value if cpp_type() == CPPTYPE_UINT64. If no // explicit default was defined, the default is 0. - uint64 default_value_uint64() const; + uint64_t default_value_uint64_t() const; + uint64_t default_value_uint64() const { return default_value_uint64_t(); } // Get the field default value if cpp_type() == CPPTYPE_FLOAT. If no // explicit default was defined, the default is 0.0. float default_value_float() const; @@ -835,6 +874,7 @@ bool GetSourceLocation(SourceLocation* out_location) const; private: + friend class Symbol; typedef FieldOptions OptionsType; // Allows access to GetLocationPath for annotations. @@ -864,25 +904,34 @@ // Returns true if this is a map message type. bool is_map_message_type() const; - const std::string* name_; - const std::string* full_name_; - const std::string* lowercase_name_; - const std::string* camelcase_name_; - // If has_json_name_ is true, it's the value specified by the user. - // Otherwise, it has the same value as camelcase_name_. - const std::string* json_name_; - const FileDescriptor* file_; - internal::once_flag* type_once_; - static void TypeOnceInit(const FieldDescriptor* to_init); - void InternalTypeOnceInit() const; - mutable Type type_; - Label label_; bool has_default_value_; bool proto3_optional_; // Whether the user has specified the json_name field option in the .proto // file. bool has_json_name_; bool is_extension_; + + // Actually a `Type`, but stored as uint8_t to save space. + mutable uint8_t type_; + // Actually a `Label` but stored as uint8_t to save space. + uint8_t label_; + + // Logically: + // all_names_ = [name, full_name, lower, camel, json] + // However: + // duplicates will be omitted, so lower/camel/json might be in the same + // position. + // We store the true offset for each name here, and the bit width must be + // large enough to account for the worst case where all names are present. + uint8_t lowercase_name_index_ : 2; + uint8_t camelcase_name_index_ : 2; + uint8_t json_name_index_ : 3; + const std::string* all_names_; + const FileDescriptor* file_; + + internal::LazyInitData* type_once_; + static void TypeOnceInit(const FieldDescriptor* to_init); + void InternalTypeOnceInit() const; int number_; int index_in_oneof_; const Descriptor* containing_type_; @@ -891,17 +940,15 @@ mutable const Descriptor* message_type_; mutable const EnumDescriptor* enum_type_; const FieldOptions* options_; - const std::string* type_name_; - const std::string* default_value_enum_name_; // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate<FieldDescriptor>() and AllocateArray<FieldDescriptor>() in // descriptor.cc and update them to initialize the field. union { - int32 default_value_int32_; - int64 default_value_int64_; - uint32 default_value_uint32_; - uint64 default_value_uint64_; + int32_t default_value_int32_t_; + int64_t default_value_int64_t_; + uint32_t default_value_uint32_t_; + uint64_t default_value_uint64_t_; float default_value_float_; double default_value_double_; bool default_value_bool_; @@ -930,7 +977,7 @@ // Describes a oneof defined in a message type. -class PROTOBUF_EXPORT OneofDescriptor { +class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase { public: typedef OneofDescriptorProto Proto; @@ -974,6 +1021,7 @@ bool GetSourceLocation(SourceLocation* out_location) const; private: + friend class Symbol; typedef OneofOptions OptionsType; // Allows access to GetLocationPath for annotations. @@ -988,10 +1036,11 @@ // to this descriptor from the file root. void GetLocationPath(std::vector<int>* output) const; - const std::string* name_; - const std::string* full_name_; - const Descriptor* containing_type_; int field_count_; + + // all_names_ = [name, full_name] + const std::string* all_names_; + const Descriptor* containing_type_; const FieldDescriptor** fields_; const OneofOptions* options_; @@ -1009,7 +1058,7 @@ // Describes an enum type defined in a .proto file. To get the EnumDescriptor // for a generated enum type, call TypeName_descriptor(). Use DescriptorPool // to construct your own descriptors. -class PROTOBUF_EXPORT EnumDescriptor { +class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase { public: typedef EnumDescriptorProto Proto; @@ -1101,6 +1150,7 @@ bool GetSourceLocation(SourceLocation* out_location) const; private: + friend class Symbol; typedef EnumOptions OptionsType; // Allows access to GetLocationPath for annotations. @@ -1126,18 +1176,18 @@ // to this descriptor from the file root. void GetLocationPath(std::vector<int>* output) const; - const std::string* name_; - const std::string* full_name_; - const FileDescriptor* file_; - const Descriptor* containing_type_; - const EnumOptions* options_; - // True if this is a placeholder for an unknown type. bool is_placeholder_; // True if this is a placeholder and the type name wasn't fully-qualified. bool is_unqualified_placeholder_; int value_count_; + + // all_names_ = [name, full_name] + const std::string* all_names_; + const FileDescriptor* file_; + const Descriptor* containing_type_; + const EnumOptions* options_; EnumValueDescriptor* values_; int reserved_range_count_; @@ -1166,7 +1216,8 @@ // for its type, then use EnumDescriptor::FindValueByName() or // EnumDescriptor::FindValueByNumber(). Use DescriptorPool to construct // your own descriptors. -class PROTOBUF_EXPORT EnumValueDescriptor { +class PROTOBUF_EXPORT EnumValueDescriptor : private internal::SymbolBaseN<0>, + private internal::SymbolBaseN<1> { public: typedef EnumValueDescriptorProto Proto; @@ -1209,6 +1260,7 @@ bool GetSourceLocation(SourceLocation* out_location) const; private: + friend class Symbol; typedef EnumValueOptions OptionsType; // Allows access to GetLocationPath for annotations. @@ -1223,9 +1275,9 @@ // to this descriptor from the file root. void GetLocationPath(std::vector<int>* output) const; - const std::string* name_; - const std::string* full_name_; int number_; + // all_names_ = [name, full_name] + const std::string* all_names_; const EnumDescriptor* type_; const EnumValueOptions* options_; // IMPORTANT: If you add a new field, make sure to search for all instances @@ -1244,7 +1296,7 @@ // Describes an RPC service. Use DescriptorPool to construct your own // descriptors. -class PROTOBUF_EXPORT ServiceDescriptor { +class PROTOBUF_EXPORT ServiceDescriptor : private internal::SymbolBase { public: typedef ServiceDescriptorProto Proto; @@ -1289,6 +1341,7 @@ bool GetSourceLocation(SourceLocation* out_location) const; private: + friend class Symbol; typedef ServiceOptions OptionsType; // Allows access to GetLocationPath for annotations. @@ -1303,8 +1356,8 @@ // to this descriptor from the file root. void GetLocationPath(std::vector<int>* output) const; - const std::string* name_; - const std::string* full_name_; + // all_names_ = [name, full_name] + const std::string* all_names_; const FileDescriptor* file_; const ServiceOptions* options_; MethodDescriptor* methods_; @@ -1326,7 +1379,7 @@ // a service, first get its ServiceDescriptor, then call // ServiceDescriptor::FindMethodByName(). Use DescriptorPool to construct your // own descriptors. -class PROTOBUF_EXPORT MethodDescriptor { +class PROTOBUF_EXPORT MethodDescriptor : private internal::SymbolBase { public: typedef MethodDescriptorProto Proto; @@ -1375,6 +1428,7 @@ bool GetSourceLocation(SourceLocation* out_location) const; private: + friend class Symbol; typedef MethodOptions OptionsType; // Allows access to GetLocationPath for annotations. @@ -1389,14 +1443,14 @@ // to this descriptor from the file root. void GetLocationPath(std::vector<int>* output) const; - const std::string* name_; - const std::string* full_name_; + bool client_streaming_; + bool server_streaming_; + // all_names_ = [name, full_name] + const std::string* all_names_; const ServiceDescriptor* service_; mutable internal::LazyDescriptor input_type_; mutable internal::LazyDescriptor output_type_; const MethodOptions* options_; - bool client_streaming_; - bool server_streaming_; // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate<MethodDescriptor>() and AllocateArray<MethodDescriptor>() in // descriptor.cc and update them to initialize the field. @@ -1554,7 +1608,7 @@ const std::string* name_; const std::string* package_; const DescriptorPool* pool_; - internal::once_flag* dependencies_once_; + internal::LazyInitData* dependencies_once_; static void DependenciesOnceInit(const FileDescriptor* to_init); void InternalDependenciesOnceInit() const; @@ -1565,17 +1619,18 @@ int message_type_count_; int enum_type_count_; int service_count_; - int extension_count_; - Syntax syntax_; - bool is_placeholder_; + bool is_placeholder_; // Indicates the FileDescriptor is completed building. Used to verify // that type accessor functions that can possibly build a dependent file // aren't called during the process of building the file. bool finished_building_; + // Actually a `Syntax` but stored as uint8_t to save space. + uint8_t syntax_; + // This one is here to fill the padding. + int extension_count_; mutable const FileDescriptor** dependencies_; - const std::string** dependencies_names_; int* public_dependencies_; int* weak_dependencies_; Descriptor* message_types_; @@ -1988,6 +2043,11 @@ #define PROTOBUF_DEFINE_STRING_ACCESSOR(CLASS, FIELD) \ inline const std::string& CLASS::FIELD() const { return *FIELD##_; } +// Name and full name are stored in a single array to save space. +#define PROTOBUF_DEFINE_NAME_ACCESSOR(CLASS) \ + inline const std::string& CLASS::name() const { return all_names_[0]; } \ + inline const std::string& CLASS::full_name() const { return all_names_[1]; } + // Arrays take an index parameter, obviously. #define PROTOBUF_DEFINE_ARRAY_ACCESSOR(CLASS, FIELD, TYPE) \ inline TYPE CLASS::FIELD(int index) const { return FIELD##s_ + index; } @@ -1995,8 +2055,7 @@ #define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \ inline const TYPE& CLASS::options() const { return *options_; } -PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, full_name) +PROTOBUF_DEFINE_NAME_ACCESSOR(Descriptor) PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*) PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*) @@ -2025,15 +2084,10 @@ PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions) PROTOBUF_DEFINE_ACCESSOR(Descriptor, is_placeholder, bool) -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name) -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, json_name) -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, lowercase_name) -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, camelcase_name) +PROTOBUF_DEFINE_NAME_ACCESSOR(FieldDescriptor) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_oneof, const OneofDescriptor*) @@ -2042,23 +2096,21 @@ PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_json_name, bool) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32, int32) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64, int64) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32, uint32) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64, uint64) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32_t, int32_t) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64_t, int64_t) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32_t, uint32_t) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64_t, uint64_t) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float, float) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool, bool) PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string) -PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, full_name) +PROTOBUF_DEFINE_NAME_ACCESSOR(OneofDescriptor) PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, containing_type, const Descriptor*) PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, field_count, int) PROTOBUF_DEFINE_OPTIONS_ACCESSOR(OneofDescriptor, OneofOptions) -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name) +PROTOBUF_DEFINE_NAME_ACCESSOR(EnumDescriptor) PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*) PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*) PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int) @@ -2071,22 +2123,19 @@ const EnumDescriptor::ReservedRange*) PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, reserved_name_count, int) -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, full_name) +PROTOBUF_DEFINE_NAME_ACCESSOR(EnumValueDescriptor) PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int) PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*) PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions) -PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, full_name) +PROTOBUF_DEFINE_NAME_ACCESSOR(ServiceDescriptor) PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*) PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int) PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method, const MethodDescriptor*) PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions) -PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name) +PROTOBUF_DEFINE_NAME_ACCESSOR(MethodDescriptor) PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*) PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions) PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, client_streaming, bool) @@ -2164,11 +2213,27 @@ return *reserved_names_[index]; } +inline const std::string& FieldDescriptor::lowercase_name() const { + return all_names_[lowercase_name_index_]; +} + +inline const std::string& FieldDescriptor::camelcase_name() const { + return all_names_[camelcase_name_index_]; +} + +inline const std::string& FieldDescriptor::json_name() const { + return all_names_[json_name_index_]; +} + +inline FieldDescriptor::Label FieldDescriptor::label() const { + return static_cast<Label>(label_); +} + inline FieldDescriptor::Type FieldDescriptor::type() const { if (type_once_) { - internal::call_once(*type_once_, &FieldDescriptor::TypeOnceInit, this); + internal::call_once(type_once_->once, &FieldDescriptor::TypeOnceInit, this); } - return type_; + return static_cast<Type>(type_); } inline bool FieldDescriptor::is_required() const { @@ -2309,7 +2374,9 @@ return dependency(weak_dependencies_[index]); } -inline FileDescriptor::Syntax FileDescriptor::syntax() const { return syntax_; } +inline FileDescriptor::Syntax FileDescriptor::syntax() const { + return static_cast<Syntax>(syntax_); +} // Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because fields_ is actually an array // of pointers rather than the usual array of objects.
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 2e91b7c..6e2afc0 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc
@@ -459,12 +459,14 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileDescriptorSet, file_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _has_bits_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileDescriptorProto, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileDescriptorProto, package_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileDescriptorProto, dependency_), @@ -494,6 +496,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, start_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, end_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, options_), @@ -505,6 +508,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, start_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, end_), 0, @@ -514,6 +518,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::DescriptorProto, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::DescriptorProto, field_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::DescriptorProto, extension_), @@ -539,12 +544,14 @@ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _extensions_), ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, uninterpreted_option_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _has_bits_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, number_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, label_), @@ -572,6 +579,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, options_), 0, @@ -581,6 +589,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, start_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, end_), 0, @@ -590,6 +599,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, value_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, options_), @@ -605,6 +615,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, number_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, options_), @@ -616,6 +627,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, method_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, options_), @@ -627,6 +639,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, input_type_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, output_type_), @@ -644,6 +657,7 @@ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileOptions, _extensions_), ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileOptions, java_package_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileOptions, java_outer_classname_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileOptions, java_multiple_files_), @@ -691,6 +705,7 @@ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::MessageOptions, _extensions_), ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::MessageOptions, message_set_wire_format_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::MessageOptions, no_standard_descriptor_accessor_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::MessageOptions, deprecated_), @@ -706,6 +721,7 @@ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldOptions, _extensions_), ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldOptions, ctype_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldOptions, packed_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldOptions, jstype_), @@ -725,12 +741,14 @@ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::OneofOptions, _extensions_), ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::OneofOptions, uninterpreted_option_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumOptions, _has_bits_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumOptions, _internal_metadata_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumOptions, _extensions_), ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumOptions, allow_alias_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumOptions, deprecated_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumOptions, uninterpreted_option_), @@ -742,6 +760,7 @@ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumValueOptions, _extensions_), ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumValueOptions, deprecated_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumValueOptions, uninterpreted_option_), 0, @@ -751,6 +770,7 @@ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ServiceOptions, _extensions_), ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ServiceOptions, deprecated_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ServiceOptions, uninterpreted_option_), 0, @@ -760,6 +780,7 @@ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::MethodOptions, _extensions_), ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::MethodOptions, deprecated_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::MethodOptions, idempotency_level_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::MethodOptions, uninterpreted_option_), @@ -771,6 +792,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, name_part_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, is_extension_), 0, @@ -780,6 +802,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::UninterpretedOption, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::UninterpretedOption, identifier_value_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::UninterpretedOption, positive_int_value_), @@ -799,6 +822,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, path_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, span_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, leading_comments_), @@ -814,12 +838,14 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::SourceCodeInfo, location_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _has_bits_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, path_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, source_file_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, begin_), @@ -833,36 +859,37 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo, annotation_), }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(PROTOBUF_NAMESPACE_ID::FileDescriptorSet)}, - { 6, 23, sizeof(PROTOBUF_NAMESPACE_ID::FileDescriptorProto)}, - { 35, 43, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange)}, - { 46, 53, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange)}, - { 55, 70, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto)}, - { 80, -1, sizeof(PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions)}, - { 86, 102, sizeof(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto)}, - { 113, 120, sizeof(PROTOBUF_NAMESPACE_ID::OneofDescriptorProto)}, - { 122, 129, sizeof(PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange)}, - { 131, 141, sizeof(PROTOBUF_NAMESPACE_ID::EnumDescriptorProto)}, - { 146, 154, sizeof(PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto)}, - { 157, 165, sizeof(PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto)}, - { 168, 179, sizeof(PROTOBUF_NAMESPACE_ID::MethodDescriptorProto)}, - { 185, 211, sizeof(PROTOBUF_NAMESPACE_ID::FileOptions)}, - { 232, 242, sizeof(PROTOBUF_NAMESPACE_ID::MessageOptions)}, - { 247, 259, sizeof(PROTOBUF_NAMESPACE_ID::FieldOptions)}, - { 266, -1, sizeof(PROTOBUF_NAMESPACE_ID::OneofOptions)}, - { 272, 280, sizeof(PROTOBUF_NAMESPACE_ID::EnumOptions)}, - { 283, 290, sizeof(PROTOBUF_NAMESPACE_ID::EnumValueOptions)}, - { 292, 299, sizeof(PROTOBUF_NAMESPACE_ID::ServiceOptions)}, - { 301, 309, sizeof(PROTOBUF_NAMESPACE_ID::MethodOptions)}, - { 312, 319, sizeof(PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart)}, - { 321, 333, sizeof(PROTOBUF_NAMESPACE_ID::UninterpretedOption)}, - { 340, 350, sizeof(PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location)}, - { 355, -1, sizeof(PROTOBUF_NAMESPACE_ID::SourceCodeInfo)}, - { 361, 370, sizeof(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation)}, - { 374, -1, sizeof(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo)}, + { 0, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::FileDescriptorSet)}, + { 7, 25, -1, sizeof(PROTOBUF_NAMESPACE_ID::FileDescriptorProto)}, + { 37, 46, -1, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange)}, + { 49, 57, -1, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange)}, + { 59, 75, -1, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto)}, + { 85, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions)}, + { 92, 109, -1, sizeof(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto)}, + { 120, 128, -1, sizeof(PROTOBUF_NAMESPACE_ID::OneofDescriptorProto)}, + { 130, 138, -1, sizeof(PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange)}, + { 140, 151, -1, sizeof(PROTOBUF_NAMESPACE_ID::EnumDescriptorProto)}, + { 156, 165, -1, sizeof(PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto)}, + { 168, 177, -1, sizeof(PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto)}, + { 180, 192, -1, sizeof(PROTOBUF_NAMESPACE_ID::MethodDescriptorProto)}, + { 198, 225, -1, sizeof(PROTOBUF_NAMESPACE_ID::FileOptions)}, + { 246, 257, -1, sizeof(PROTOBUF_NAMESPACE_ID::MessageOptions)}, + { 262, 275, -1, sizeof(PROTOBUF_NAMESPACE_ID::FieldOptions)}, + { 282, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::OneofOptions)}, + { 289, 298, -1, sizeof(PROTOBUF_NAMESPACE_ID::EnumOptions)}, + { 301, 309, -1, sizeof(PROTOBUF_NAMESPACE_ID::EnumValueOptions)}, + { 311, 319, -1, sizeof(PROTOBUF_NAMESPACE_ID::ServiceOptions)}, + { 321, 330, -1, sizeof(PROTOBUF_NAMESPACE_ID::MethodOptions)}, + { 333, 341, -1, sizeof(PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart)}, + { 343, 356, -1, sizeof(PROTOBUF_NAMESPACE_ID::UninterpretedOption)}, + { 363, 374, -1, sizeof(PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location)}, + { 379, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::SourceCodeInfo)}, + { 386, 396, -1, sizeof(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation)}, + { 400, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -1305,28 +1332,29 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1367,13 +1395,7 @@ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileDescriptorSet::_class_data_ = { @@ -1382,8 +1404,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileDescriptorSet::GetClassData() const { return &_class_data_; } -void FileDescriptorSet::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void FileDescriptorSet::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<FileDescriptorSet *>(to)->MergeFrom( static_cast<const FileDescriptorSet &>(from)); } @@ -1599,7 +1621,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.name"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string package = 2; case 2: @@ -1610,7 +1633,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.package"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated string dependency = 3; case 3: @@ -1626,7 +1650,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.DescriptorProto message_type = 4; case 4: @@ -1638,7 +1663,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; case 5: @@ -1650,7 +1676,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.ServiceDescriptorProto service = 6; case 6: @@ -1662,7 +1689,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.FieldDescriptorProto extension = 7; case 7: @@ -1674,21 +1702,24 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<58>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.FileOptions options = 8; case 8: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 66)) { ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.SourceCodeInfo source_code_info = 9; case 9: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 74)) { ptr = ctx->ParseMessage(_internal_mutable_source_code_info(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated int32 public_dependency = 10; case 10: @@ -1703,7 +1734,8 @@ } else if (static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 82) { ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_public_dependency(), ptr, ctx); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated int32 weak_dependency = 11; case 11: @@ -1718,7 +1750,8 @@ } else if (static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 90) { ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_weak_dependency(), ptr, ctx); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string syntax = 12; case 12: @@ -1729,29 +1762,30 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.syntax"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1970,13 +2004,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileDescriptorProto::_class_data_ = { @@ -1985,8 +2013,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileDescriptorProto::GetClassData() const { return &_class_data_; } -void FileDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void FileDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<FileDescriptorProto *>(to)->MergeFrom( static_cast<const FileDescriptorProto &>(from)); } @@ -2046,6 +2074,8 @@ void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); dependency_.InternalSwap(&other->dependency_); @@ -2057,18 +2087,18 @@ weak_dependency_.InternalSwap(&other->weak_dependency_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &package_, GetArenaForAllocation(), - &other->package_, other->GetArenaForAllocation() + &package_, lhs_arena, + &other->package_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &syntax_, GetArenaForAllocation(), - &other->syntax_, other->GetArenaForAllocation() + &syntax_, lhs_arena, + &other->syntax_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(FileDescriptorProto, source_code_info_) @@ -2191,7 +2221,8 @@ _Internal::set_has_start(&has_bits); start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional int32 end = 2; case 2: @@ -2199,36 +2230,38 @@ _Internal::set_has_end(&has_bits); end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.ExtensionRangeOptions options = 3; case 3: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 26)) { ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -2286,26 +2319,16 @@ // optional int32 start = 1; if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_start()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_start()); } // optional int32 end = 2; if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_end()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end()); } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto_ExtensionRange::_class_data_ = { @@ -2314,8 +2337,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto_ExtensionRange::GetClassData() const { return &_class_data_; } -void DescriptorProto_ExtensionRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void DescriptorProto_ExtensionRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<DescriptorProto_ExtensionRange *>(to)->MergeFrom( static_cast<const DescriptorProto_ExtensionRange &>(from)); } @@ -2464,7 +2487,8 @@ _Internal::set_has_start(&has_bits); start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional int32 end = 2; case 2: @@ -2472,29 +2496,30 @@ _Internal::set_has_end(&has_bits); end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -2537,26 +2562,16 @@ if (cached_has_bits & 0x00000003u) { // optional int32 start = 1; if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_start()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_start()); } // optional int32 end = 2; if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_end()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end()); } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto_ReservedRange::_class_data_ = { @@ -2565,8 +2580,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto_ReservedRange::GetClassData() const { return &_class_data_; } -void DescriptorProto_ReservedRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void DescriptorProto_ReservedRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<DescriptorProto_ReservedRange *>(to)->MergeFrom( static_cast<const DescriptorProto_ReservedRange &>(from)); } @@ -2752,7 +2767,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.DescriptorProto.name"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.FieldDescriptorProto field = 2; case 2: @@ -2764,7 +2780,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.DescriptorProto nested_type = 3; case 3: @@ -2776,7 +2793,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; case 4: @@ -2788,7 +2806,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; case 5: @@ -2800,7 +2819,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.FieldDescriptorProto extension = 6; case 6: @@ -2812,14 +2832,16 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.MessageOptions options = 7; case 7: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 58)) { ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; case 8: @@ -2831,7 +2853,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<66>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; case 9: @@ -2843,7 +2866,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<74>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated string reserved_name = 10; case 10: @@ -2859,29 +2883,30 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<82>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -3066,13 +3091,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto::_class_data_ = { @@ -3081,8 +3100,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto::GetClassData() const { return &_class_data_; } -void DescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void DescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<DescriptorProto *>(to)->MergeFrom( static_cast<const DescriptorProto &>(from)); } @@ -3136,6 +3155,8 @@ void DescriptorProto::InternalSwap(DescriptorProto* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); field_.InternalSwap(&other->field_); @@ -3148,8 +3169,8 @@ reserved_name_.InternalSwap(&other->reserved_name_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); swap(options_, other->options_); } @@ -3236,34 +3257,34 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - if ((8000u <= tag)) { - ptr = _extensions_.ParseField(tag, ptr, - internal_default_instance(), &_internal_metadata_, ctx); - CHK_(ptr != nullptr); - continue; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -3283,7 +3304,7 @@ // Extension range [1000, 536870912) target = _extensions_._InternalSerialize( - 1000, 536870912, target, stream); + internal_default_instance(), 1000, 536870912, target, stream); if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( @@ -3310,13 +3331,7 @@ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ExtensionRangeOptions::_class_data_ = { @@ -3325,8 +3340,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ExtensionRangeOptions::GetClassData() const { return &_class_data_; } -void ExtensionRangeOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void ExtensionRangeOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<ExtensionRangeOptions *>(to)->MergeFrom( static_cast<const ExtensionRangeOptions &>(from)); } @@ -3565,7 +3580,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.name"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string extendee = 2; case 2: @@ -3576,7 +3592,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.extendee"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional int32 number = 3; case 3: @@ -3584,7 +3601,8 @@ _Internal::set_has_number(&has_bits); number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.FieldDescriptorProto.Label label = 4; case 4: @@ -3596,7 +3614,8 @@ } else { ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(4, val, mutable_unknown_fields()); } - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.FieldDescriptorProto.Type type = 5; case 5: @@ -3608,7 +3627,8 @@ } else { ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(5, val, mutable_unknown_fields()); } - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string type_name = 6; case 6: @@ -3619,7 +3639,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.type_name"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string default_value = 7; case 7: @@ -3630,14 +3651,16 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.default_value"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.FieldOptions options = 8; case 8: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 66)) { ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional int32 oneof_index = 9; case 9: @@ -3645,7 +3668,8 @@ _Internal::set_has_oneof_index(&has_bits); oneof_index_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string json_name = 10; case 10: @@ -3656,7 +3680,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.json_name"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool proto3_optional = 17; case 17: @@ -3664,29 +3689,30 @@ _Internal::set_has_proto3_optional(&has_bits); proto3_optional_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -3849,16 +3875,12 @@ // optional int32 number = 3; if (cached_has_bits & 0x00000040u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_number()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number()); } // optional int32 oneof_index = 9; if (cached_has_bits & 0x00000080u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_oneof_index()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_oneof_index()); } } @@ -3881,13 +3903,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldDescriptorProto::_class_data_ = { @@ -3896,8 +3912,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldDescriptorProto::GetClassData() const { return &_class_data_; } -void FieldDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void FieldDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<FieldDescriptorProto *>(to)->MergeFrom( static_cast<const FieldDescriptorProto &>(from)); } @@ -3968,32 +3984,34 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &extendee_, GetArenaForAllocation(), - &other->extendee_, other->GetArenaForAllocation() + &extendee_, lhs_arena, + &other->extendee_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &type_name_, GetArenaForAllocation(), - &other->type_name_, other->GetArenaForAllocation() + &type_name_, lhs_arena, + &other->type_name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &default_value_, GetArenaForAllocation(), - &other->default_value_, other->GetArenaForAllocation() + &default_value_, lhs_arena, + &other->default_value_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &json_name_, GetArenaForAllocation(), - &other->json_name_, other->GetArenaForAllocation() + &json_name_, lhs_arena, + &other->json_name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, proto3_optional_) @@ -4119,36 +4137,38 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.OneofDescriptorProto.name"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.OneofOptions options = 2; case 2: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) { ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -4210,13 +4230,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData OneofDescriptorProto::_class_data_ = { @@ -4225,8 +4239,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*OneofDescriptorProto::GetClassData() const { return &_class_data_; } -void OneofDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void OneofDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<OneofDescriptorProto *>(to)->MergeFrom( static_cast<const OneofDescriptorProto &>(from)); } @@ -4266,12 +4280,14 @@ void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); swap(options_, other->options_); } @@ -4371,7 +4387,8 @@ _Internal::set_has_start(&has_bits); start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional int32 end = 2; case 2: @@ -4379,29 +4396,30 @@ _Internal::set_has_end(&has_bits); end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -4444,26 +4462,16 @@ if (cached_has_bits & 0x00000003u) { // optional int32 start = 1; if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_start()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_start()); } // optional int32 end = 2; if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_end()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end()); } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumDescriptorProto_EnumReservedRange::_class_data_ = { @@ -4472,8 +4480,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumDescriptorProto_EnumReservedRange::GetClassData() const { return &_class_data_; } -void EnumDescriptorProto_EnumReservedRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void EnumDescriptorProto_EnumReservedRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<EnumDescriptorProto_EnumReservedRange *>(to)->MergeFrom( static_cast<const EnumDescriptorProto_EnumReservedRange &>(from)); } @@ -4644,7 +4652,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.EnumDescriptorProto.name"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.EnumValueDescriptorProto value = 2; case 2: @@ -4656,14 +4665,16 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.EnumOptions options = 3; case 3: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 26)) { ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; case 4: @@ -4675,7 +4686,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated string reserved_name = 5; case 5: @@ -4691,29 +4703,30 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -4823,13 +4836,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumDescriptorProto::_class_data_ = { @@ -4838,8 +4845,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumDescriptorProto::GetClassData() const { return &_class_data_; } -void EnumDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void EnumDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<EnumDescriptorProto *>(to)->MergeFrom( static_cast<const EnumDescriptorProto &>(from)); } @@ -4883,6 +4890,8 @@ void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); value_.InternalSwap(&other->value_); @@ -4890,8 +4899,8 @@ reserved_name_.InternalSwap(&other->reserved_name_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); swap(options_, other->options_); } @@ -5018,7 +5027,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.EnumValueDescriptorProto.name"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional int32 number = 2; case 2: @@ -5026,36 +5036,38 @@ _Internal::set_has_number(&has_bits); number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.EnumValueOptions options = 3; case 3: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 26)) { ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -5124,19 +5136,11 @@ // optional int32 number = 2; if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_number()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number()); } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValueDescriptorProto::_class_data_ = { @@ -5145,8 +5149,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValueDescriptorProto::GetClassData() const { return &_class_data_; } -void EnumValueDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void EnumValueDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<EnumValueDescriptorProto *>(to)->MergeFrom( static_cast<const EnumValueDescriptorProto &>(from)); } @@ -5190,12 +5194,14 @@ void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, number_) @@ -5322,7 +5328,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.ServiceDescriptorProto.name"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.MethodDescriptorProto method = 2; case 2: @@ -5334,36 +5341,38 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.ServiceOptions options = 3; case 3: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 26)) { ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -5440,13 +5449,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ServiceDescriptorProto::_class_data_ = { @@ -5455,8 +5458,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ServiceDescriptorProto::GetClassData() const { return &_class_data_; } -void ServiceDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void ServiceDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<ServiceDescriptorProto *>(to)->MergeFrom( static_cast<const ServiceDescriptorProto &>(from)); } @@ -5498,13 +5501,15 @@ void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); method_.InternalSwap(&other->method_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); swap(options_, other->options_); } @@ -5664,7 +5669,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.name"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string input_type = 2; case 2: @@ -5675,7 +5681,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.input_type"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string output_type = 3; case 3: @@ -5686,14 +5693,16 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.output_type"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.MethodOptions options = 4; case 4: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 34)) { ptr = ctx->ParseMessage(_internal_mutable_options(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool client_streaming = 5 [default = false]; case 5: @@ -5701,7 +5710,8 @@ _Internal::set_has_client_streaming(&has_bits); client_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool server_streaming = 6 [default = false]; case 6: @@ -5709,29 +5719,30 @@ _Internal::set_has_server_streaming(&has_bits); server_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -5849,13 +5860,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MethodDescriptorProto::_class_data_ = { @@ -5864,8 +5869,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MethodDescriptorProto::GetClassData() const { return &_class_data_; } -void MethodDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void MethodDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<MethodDescriptorProto *>(to)->MergeFrom( static_cast<const MethodDescriptorProto &>(from)); } @@ -5918,22 +5923,24 @@ void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &input_type_, GetArenaForAllocation(), - &other->input_type_, other->GetArenaForAllocation() + &input_type_, lhs_arena, + &other->input_type_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &output_type_, GetArenaForAllocation(), - &other->output_type_, other->GetArenaForAllocation() + &output_type_, lhs_arena, + &other->output_type_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, server_streaming_) @@ -6214,7 +6221,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.java_package"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string java_outer_classname = 8; case 8: @@ -6225,7 +6233,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.java_outer_classname"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; case 9: @@ -6237,7 +6246,8 @@ } else { ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(9, val, mutable_unknown_fields()); } - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool java_multiple_files = 10 [default = false]; case 10: @@ -6245,7 +6255,8 @@ _Internal::set_has_java_multiple_files(&has_bits); java_multiple_files_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string go_package = 11; case 11: @@ -6256,7 +6267,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.go_package"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool cc_generic_services = 16 [default = false]; case 16: @@ -6264,7 +6276,8 @@ _Internal::set_has_cc_generic_services(&has_bits); cc_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool java_generic_services = 17 [default = false]; case 17: @@ -6272,7 +6285,8 @@ _Internal::set_has_java_generic_services(&has_bits); java_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool py_generic_services = 18 [default = false]; case 18: @@ -6280,7 +6294,8 @@ _Internal::set_has_py_generic_services(&has_bits); py_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool java_generate_equals_and_hash = 20 [deprecated = true]; case 20: @@ -6288,7 +6303,8 @@ _Internal::set_has_java_generate_equals_and_hash(&has_bits); java_generate_equals_and_hash_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool deprecated = 23 [default = false]; case 23: @@ -6296,7 +6312,8 @@ _Internal::set_has_deprecated(&has_bits); deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool java_string_check_utf8 = 27 [default = false]; case 27: @@ -6304,7 +6321,8 @@ _Internal::set_has_java_string_check_utf8(&has_bits); java_string_check_utf8_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool cc_enable_arenas = 31 [default = true]; case 31: @@ -6312,7 +6330,8 @@ _Internal::set_has_cc_enable_arenas(&has_bits); cc_enable_arenas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string objc_class_prefix = 36; case 36: @@ -6323,7 +6342,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.objc_class_prefix"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string csharp_namespace = 37; case 37: @@ -6334,7 +6354,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.csharp_namespace"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string swift_prefix = 39; case 39: @@ -6345,7 +6366,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.swift_prefix"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string php_class_prefix = 40; case 40: @@ -6356,7 +6378,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.php_class_prefix"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string php_namespace = 41; case 41: @@ -6367,7 +6390,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.php_namespace"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool php_generic_services = 42 [default = false]; case 42: @@ -6375,7 +6399,8 @@ _Internal::set_has_php_generic_services(&has_bits); php_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string php_metadata_namespace = 44; case 44: @@ -6386,7 +6411,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.php_metadata_namespace"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string ruby_package = 45; case 45: @@ -6397,7 +6423,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.ruby_package"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: @@ -6409,35 +6436,35 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - if ((8000u <= tag)) { - ptr = _extensions_.ParseField(tag, ptr, - internal_default_instance(), &_internal_metadata_, ctx); - CHK_(ptr != nullptr); - continue; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -6619,7 +6646,7 @@ // Extension range [1000, 536870912) target = _extensions_._InternalSerialize( - 1000, 536870912, target, stream); + internal_default_instance(), 1000, 536870912, target, stream); if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( @@ -6774,13 +6801,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileOptions::_class_data_ = { @@ -6789,8 +6810,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileOptions::GetClassData() const { return &_class_data_; } -void FileOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void FileOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<FileOptions *>(to)->MergeFrom( static_cast<const FileOptions &>(from)); } @@ -6895,58 +6916,60 @@ void FileOptions::InternalSwap(FileOptions* other) { using std::swap; _extensions_.InternalSwap(&other->_extensions_); + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &java_package_, GetArenaForAllocation(), - &other->java_package_, other->GetArenaForAllocation() + &java_package_, lhs_arena, + &other->java_package_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &java_outer_classname_, GetArenaForAllocation(), - &other->java_outer_classname_, other->GetArenaForAllocation() + &java_outer_classname_, lhs_arena, + &other->java_outer_classname_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &go_package_, GetArenaForAllocation(), - &other->go_package_, other->GetArenaForAllocation() + &go_package_, lhs_arena, + &other->go_package_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &objc_class_prefix_, GetArenaForAllocation(), - &other->objc_class_prefix_, other->GetArenaForAllocation() + &objc_class_prefix_, lhs_arena, + &other->objc_class_prefix_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &csharp_namespace_, GetArenaForAllocation(), - &other->csharp_namespace_, other->GetArenaForAllocation() + &csharp_namespace_, lhs_arena, + &other->csharp_namespace_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &swift_prefix_, GetArenaForAllocation(), - &other->swift_prefix_, other->GetArenaForAllocation() + &swift_prefix_, lhs_arena, + &other->swift_prefix_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &php_class_prefix_, GetArenaForAllocation(), - &other->php_class_prefix_, other->GetArenaForAllocation() + &php_class_prefix_, lhs_arena, + &other->php_class_prefix_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &php_namespace_, GetArenaForAllocation(), - &other->php_namespace_, other->GetArenaForAllocation() + &php_namespace_, lhs_arena, + &other->php_namespace_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &php_metadata_namespace_, GetArenaForAllocation(), - &other->php_metadata_namespace_, other->GetArenaForAllocation() + &php_metadata_namespace_, lhs_arena, + &other->php_metadata_namespace_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &ruby_package_, GetArenaForAllocation(), - &other->ruby_package_, other->GetArenaForAllocation() + &ruby_package_, lhs_arena, + &other->ruby_package_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(FileOptions, deprecated_) @@ -7062,7 +7085,8 @@ _Internal::set_has_message_set_wire_format(&has_bits); message_set_wire_format_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool no_standard_descriptor_accessor = 2 [default = false]; case 2: @@ -7070,7 +7094,8 @@ _Internal::set_has_no_standard_descriptor_accessor(&has_bits); no_standard_descriptor_accessor_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool deprecated = 3 [default = false]; case 3: @@ -7078,7 +7103,8 @@ _Internal::set_has_deprecated(&has_bits); deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool map_entry = 7; case 7: @@ -7086,7 +7112,8 @@ _Internal::set_has_map_entry(&has_bits); map_entry_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: @@ -7098,35 +7125,35 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - if ((8000u <= tag)) { - ptr = _extensions_.ParseField(tag, ptr, - internal_default_instance(), &_internal_metadata_, ctx); - CHK_(ptr != nullptr); - continue; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -7171,7 +7198,7 @@ // Extension range [1000, 536870912) target = _extensions_._InternalSerialize( - 1000, 536870912, target, stream); + internal_default_instance(), 1000, 536870912, target, stream); if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( @@ -7221,13 +7248,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MessageOptions::_class_data_ = { @@ -7236,8 +7257,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MessageOptions::GetClassData() const { return &_class_data_; } -void MessageOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void MessageOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<MessageOptions *>(to)->MergeFrom( static_cast<const MessageOptions &>(from)); } @@ -7417,7 +7438,8 @@ } else { ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(1, val, mutable_unknown_fields()); } - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool packed = 2; case 2: @@ -7425,7 +7447,8 @@ _Internal::set_has_packed(&has_bits); packed_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool deprecated = 3 [default = false]; case 3: @@ -7433,7 +7456,8 @@ _Internal::set_has_deprecated(&has_bits); deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool lazy = 5 [default = false]; case 5: @@ -7441,7 +7465,8 @@ _Internal::set_has_lazy(&has_bits); lazy_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; case 6: @@ -7453,7 +7478,8 @@ } else { ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(6, val, mutable_unknown_fields()); } - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool weak = 10 [default = false]; case 10: @@ -7461,7 +7487,8 @@ _Internal::set_has_weak(&has_bits); weak_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: @@ -7473,35 +7500,35 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - if ((8000u <= tag)) { - ptr = _extensions_.ParseField(tag, ptr, - internal_default_instance(), &_internal_metadata_, ctx); - CHK_(ptr != nullptr); - continue; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -7560,7 +7587,7 @@ // Extension range [1000, 536870912) target = _extensions_._InternalSerialize( - 1000, 536870912, target, stream); + internal_default_instance(), 1000, 536870912, target, stream); if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( @@ -7622,13 +7649,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldOptions::_class_data_ = { @@ -7637,8 +7658,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldOptions::GetClassData() const { return &_class_data_; } -void FieldOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void FieldOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<FieldOptions *>(to)->MergeFrom( static_cast<const FieldOptions &>(from)); } @@ -7789,34 +7810,34 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - if ((8000u <= tag)) { - ptr = _extensions_.ParseField(tag, ptr, - internal_default_instance(), &_internal_metadata_, ctx); - CHK_(ptr != nullptr); - continue; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -7836,7 +7857,7 @@ // Extension range [1000, 536870912) target = _extensions_._InternalSerialize( - 1000, 536870912, target, stream); + internal_default_instance(), 1000, 536870912, target, stream); if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( @@ -7863,13 +7884,7 @@ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData OneofOptions::_class_data_ = { @@ -7878,8 +7893,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*OneofOptions::GetClassData() const { return &_class_data_; } -void OneofOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void OneofOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<OneofOptions *>(to)->MergeFrom( static_cast<const OneofOptions &>(from)); } @@ -8017,7 +8032,8 @@ _Internal::set_has_allow_alias(&has_bits); allow_alias_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bool deprecated = 3 [default = false]; case 3: @@ -8025,7 +8041,8 @@ _Internal::set_has_deprecated(&has_bits); deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: @@ -8037,35 +8054,35 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - if ((8000u <= tag)) { - ptr = _extensions_.ParseField(tag, ptr, - internal_default_instance(), &_internal_metadata_, ctx); - CHK_(ptr != nullptr); - continue; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -8098,7 +8115,7 @@ // Extension range [1000, 536870912) target = _extensions_._InternalSerialize( - 1000, 536870912, target, stream); + internal_default_instance(), 1000, 536870912, target, stream); if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( @@ -8138,13 +8155,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumOptions::_class_data_ = { @@ -8153,8 +8164,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumOptions::GetClassData() const { return &_class_data_; } -void EnumOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void EnumOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<EnumOptions *>(to)->MergeFrom( static_cast<const EnumOptions &>(from)); } @@ -8299,7 +8310,8 @@ _Internal::set_has_deprecated(&has_bits); deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: @@ -8311,35 +8323,35 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - if ((8000u <= tag)) { - ptr = _extensions_.ParseField(tag, ptr, - internal_default_instance(), &_internal_metadata_, ctx); - CHK_(ptr != nullptr); - continue; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -8366,7 +8378,7 @@ // Extension range [1000, 536870912) target = _extensions_._InternalSerialize( - 1000, 536870912, target, stream); + internal_default_instance(), 1000, 536870912, target, stream); if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( @@ -8399,13 +8411,7 @@ total_size += 1 + 1; } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValueOptions::_class_data_ = { @@ -8414,8 +8420,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValueOptions::GetClassData() const { return &_class_data_; } -void EnumValueOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void EnumValueOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<EnumValueOptions *>(to)->MergeFrom( static_cast<const EnumValueOptions &>(from)); } @@ -8548,7 +8554,8 @@ _Internal::set_has_deprecated(&has_bits); deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: @@ -8560,35 +8567,35 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - if ((8000u <= tag)) { - ptr = _extensions_.ParseField(tag, ptr, - internal_default_instance(), &_internal_metadata_, ctx); - CHK_(ptr != nullptr); - continue; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -8615,7 +8622,7 @@ // Extension range [1000, 536870912) target = _extensions_._InternalSerialize( - 1000, 536870912, target, stream); + internal_default_instance(), 1000, 536870912, target, stream); if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( @@ -8648,13 +8655,7 @@ total_size += 2 + 1; } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ServiceOptions::_class_data_ = { @@ -8663,8 +8664,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ServiceOptions::GetClassData() const { return &_class_data_; } -void ServiceOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void ServiceOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<ServiceOptions *>(to)->MergeFrom( static_cast<const ServiceOptions &>(from)); } @@ -8810,7 +8811,8 @@ _Internal::set_has_deprecated(&has_bits); deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; case 34: @@ -8822,7 +8824,8 @@ } else { ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(34, val, mutable_unknown_fields()); } - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: @@ -8834,35 +8837,35 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - if ((8000u <= tag)) { - ptr = _extensions_.ParseField(tag, ptr, - internal_default_instance(), &_internal_metadata_, ctx); - CHK_(ptr != nullptr); - continue; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + if ((8000u <= tag)) { + ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx); + CHK_(ptr != nullptr); + continue; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -8896,7 +8899,7 @@ // Extension range [1000, 536870912) target = _extensions_._InternalSerialize( - 1000, 536870912, target, stream); + internal_default_instance(), 1000, 536870912, target, stream); if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( @@ -8937,13 +8940,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MethodOptions::_class_data_ = { @@ -8952,8 +8949,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MethodOptions::GetClassData() const { return &_class_data_; } -void MethodOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void MethodOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<MethodOptions *>(to)->MergeFrom( static_cast<const MethodOptions &>(from)); } @@ -9112,7 +9109,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.UninterpretedOption.NamePart.name_part"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // required bool is_extension = 2; case 2: @@ -9120,29 +9118,30 @@ _Internal::set_has_is_extension(&has_bits); is_extension_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -9215,13 +9214,7 @@ // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UninterpretedOption_NamePart::_class_data_ = { @@ -9230,8 +9223,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UninterpretedOption_NamePart::GetClassData() const { return &_class_data_; } -void UninterpretedOption_NamePart::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void UninterpretedOption_NamePart::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<UninterpretedOption_NamePart *>(to)->MergeFrom( static_cast<const UninterpretedOption_NamePart &>(from)); } @@ -9270,12 +9263,14 @@ void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_part_, GetArenaForAllocation(), - &other->name_part_, other->GetArenaForAllocation() + &name_part_, lhs_arena, + &other->name_part_, rhs_arena ); swap(is_extension_, other->is_extension_); } @@ -9426,7 +9421,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string identifier_value = 3; case 3: @@ -9437,7 +9433,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.UninterpretedOption.identifier_value"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional uint64 positive_int_value = 4; case 4: @@ -9445,7 +9442,8 @@ _Internal::set_has_positive_int_value(&has_bits); positive_int_value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional int64 negative_int_value = 5; case 5: @@ -9453,7 +9451,8 @@ _Internal::set_has_negative_int_value(&has_bits); negative_int_value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional double double_value = 6; case 6: @@ -9461,7 +9460,8 @@ _Internal::set_has_double_value(&has_bits); double_value_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<double>(ptr); ptr += sizeof(double); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional bytes string_value = 7; case 7: @@ -9469,7 +9469,8 @@ auto str = _internal_mutable_string_value(); ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string aggregate_value = 8; case 8: @@ -9480,29 +9481,30 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.UninterpretedOption.aggregate_value"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -9613,16 +9615,12 @@ // optional uint64 positive_int_value = 4; if (cached_has_bits & 0x00000008u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64Size( - this->_internal_positive_int_value()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64SizePlusOne(this->_internal_positive_int_value()); } // optional int64 negative_int_value = 5; if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->_internal_negative_int_value()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_negative_int_value()); } // optional double double_value = 6; @@ -9631,13 +9629,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UninterpretedOption::_class_data_ = { @@ -9646,8 +9638,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UninterpretedOption::GetClassData() const { return &_class_data_; } -void UninterpretedOption::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void UninterpretedOption::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<UninterpretedOption *>(to)->MergeFrom( static_cast<const UninterpretedOption &>(from)); } @@ -9699,23 +9691,25 @@ void UninterpretedOption::InternalSwap(UninterpretedOption* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); name_.InternalSwap(&other->name_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &identifier_value_, GetArenaForAllocation(), - &other->identifier_value_, other->GetArenaForAllocation() + &identifier_value_, lhs_arena, + &other->identifier_value_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &string_value_, GetArenaForAllocation(), - &other->string_value_, other->GetArenaForAllocation() + &string_value_, lhs_arena, + &other->string_value_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &aggregate_value_, GetArenaForAllocation(), - &other->aggregate_value_, other->GetArenaForAllocation() + &aggregate_value_, lhs_arena, + &other->aggregate_value_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(UninterpretedOption, double_value_) @@ -9841,7 +9835,8 @@ } else if (static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8) { _internal_add_path(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr)); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated int32 span = 2 [packed = true]; case 2: @@ -9851,7 +9846,8 @@ } else if (static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16) { _internal_add_span(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr)); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string leading_comments = 3; case 3: @@ -9862,7 +9858,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.leading_comments"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string trailing_comments = 4; case 4: @@ -9873,7 +9870,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.trailing_comments"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated string leading_detached_comments = 6; case 6: @@ -9889,29 +9887,30 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -10041,13 +10040,7 @@ } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceCodeInfo_Location::_class_data_ = { @@ -10056,8 +10049,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceCodeInfo_Location::GetClassData() const { return &_class_data_; } -void SourceCodeInfo_Location::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void SourceCodeInfo_Location::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<SourceCodeInfo_Location *>(to)->MergeFrom( static_cast<const SourceCodeInfo_Location &>(from)); } @@ -10097,6 +10090,8 @@ void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); path_.InternalSwap(&other->path_); @@ -10104,13 +10099,13 @@ leading_detached_comments_.InternalSwap(&other->leading_detached_comments_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &leading_comments_, GetArenaForAllocation(), - &other->leading_comments_, other->GetArenaForAllocation() + &leading_comments_, lhs_arena, + &other->leading_comments_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &trailing_comments_, GetArenaForAllocation(), - &other->trailing_comments_, other->GetArenaForAllocation() + &trailing_comments_, lhs_arena, + &other->trailing_comments_, rhs_arena ); } @@ -10193,28 +10188,29 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -10255,13 +10251,7 @@ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceCodeInfo::_class_data_ = { @@ -10270,8 +10260,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceCodeInfo::GetClassData() const { return &_class_data_; } -void SourceCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void SourceCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<SourceCodeInfo *>(to)->MergeFrom( static_cast<const SourceCodeInfo &>(from)); } @@ -10417,7 +10407,8 @@ } else if (static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8) { _internal_add_path(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr)); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional string source_file = 2; case 2: @@ -10428,7 +10419,8 @@ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.GeneratedCodeInfo.Annotation.source_file"); #endif // !NDEBUG CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional int32 begin = 3; case 3: @@ -10436,7 +10428,8 @@ _Internal::set_has_begin(&has_bits); begin_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // optional int32 end = 4; case 4: @@ -10444,29 +10437,30 @@ _Internal::set_has_end(&has_bits); end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: _has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -10550,26 +10544,16 @@ // optional int32 begin = 3; if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_begin()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_begin()); } // optional int32 end = 4; if (cached_has_bits & 0x00000004u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_end()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end()); } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData GeneratedCodeInfo_Annotation::_class_data_ = { @@ -10578,8 +10562,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GeneratedCodeInfo_Annotation::GetClassData() const { return &_class_data_; } -void GeneratedCodeInfo_Annotation::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void GeneratedCodeInfo_Annotation::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<GeneratedCodeInfo_Annotation *>(to)->MergeFrom( static_cast<const GeneratedCodeInfo_Annotation &>(from)); } @@ -10621,13 +10605,15 @@ void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); path_.InternalSwap(&other->path_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &source_file_, GetArenaForAllocation(), - &other->source_file_, other->GetArenaForAllocation() + &source_file_, lhs_arena, + &other->source_file_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, end_) @@ -10716,28 +10702,29 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -10778,13 +10765,7 @@ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData GeneratedCodeInfo::_class_data_ = { @@ -10793,8 +10774,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GeneratedCodeInfo::GetClassData() const { return &_class_data_; } -void GeneratedCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void GeneratedCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<GeneratedCodeInfo *>(to)->MergeFrom( static_cast<const GeneratedCodeInfo &>(from)); }
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index b72cdea..968b70c 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h
@@ -413,7 +413,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const FileDescriptorSet& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -568,7 +568,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const FileDescriptorProto& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -958,7 +958,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const DescriptorProto_ExtensionRange& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1144,7 +1144,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const DescriptorProto_ReservedRange& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1310,7 +1310,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const DescriptorProto& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1655,7 +1655,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const ExtensionRangeOptions& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1713,7 +1713,196 @@ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::UninterpretedOption >& uninterpreted_option() const; - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ExtensionRangeOptions) + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline PROTOBUF_MUST_USE_RESULT + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions) private: class _Internal; @@ -1813,7 +2002,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const FieldDescriptorProto& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -2238,7 +2427,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const OneofDescriptorProto& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -2414,7 +2603,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const EnumDescriptorProto_EnumReservedRange& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -2580,7 +2769,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const EnumDescriptorProto& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -2824,7 +3013,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const EnumValueDescriptorProto& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -3015,7 +3204,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const ServiceDescriptorProto& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -3211,7 +3400,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const MethodDescriptorProto& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -3457,7 +3646,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const FileOptions& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -3877,7 +4066,196 @@ void _internal_set_cc_enable_arenas(bool value); public: - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions) + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline PROTOBUF_MUST_USE_RESULT + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions) private: class _Internal; @@ -3998,7 +4376,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const MessageOptions& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -4112,7 +4490,196 @@ void _internal_set_map_entry(bool value); public: - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions) + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline PROTOBUF_MUST_USE_RESULT + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions) private: class _Internal; @@ -4217,7 +4784,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const FieldOptions& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -4423,7 +4990,196 @@ void _internal_set_jstype(PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value); public: - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions) + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline PROTOBUF_MUST_USE_RESULT + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions) private: class _Internal; @@ -4530,7 +5286,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const OneofOptions& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -4588,7 +5344,196 @@ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::UninterpretedOption >& uninterpreted_option() const; - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(OneofOptions) + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline PROTOBUF_MUST_USE_RESULT + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions) private: class _Internal; @@ -4688,7 +5633,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const EnumOptions& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -4774,7 +5719,196 @@ void _internal_set_deprecated(bool value); public: - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions) + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline PROTOBUF_MUST_USE_RESULT + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions) private: class _Internal; @@ -4877,7 +6011,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const EnumValueOptions& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -4949,7 +6083,196 @@ void _internal_set_deprecated(bool value); public: - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions) + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline PROTOBUF_MUST_USE_RESULT + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions) private: class _Internal; @@ -5051,7 +6374,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const ServiceOptions& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -5123,7 +6446,196 @@ void _internal_set_deprecated(bool value); public: - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions) + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline PROTOBUF_MUST_USE_RESULT + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions) private: class _Internal; @@ -5225,7 +6737,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const MethodOptions& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -5343,7 +6855,196 @@ void _internal_set_idempotency_level(PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value); public: - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions) + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline bool HasExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.Has(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void ClearExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + _extensions_.ClearExtension(id.number()); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline int ExtensionSize( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _extensions_.ExtensionSize(id.number()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, + id.default_value()); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Mutable(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::ConstType value) { + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, + &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void UnsafeArenaSetAllocatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Singular::MutableType value) { + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, + value, &_extensions_); + + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline PROTOBUF_MUST_USE_RESULT + typename _proto_TypeTraits::Singular::MutableType + ReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::Release(id.number(), _field_type, + &_extensions_); + } + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Singular::MutableType + UnsafeArenaReleaseExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, + &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) const { + + return _proto_TypeTraits::Get(id.number(), _extensions_, index); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index) { + + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void SetExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + int index, typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + typename _proto_TypeTraits::Repeated::MutableType to_add = + _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + + return to_add; + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline void AddExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id, + typename _proto_TypeTraits::Repeated::ConstType value) { + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, + &_extensions_); + + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& + GetRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const { + + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + } + + template <typename _proto_TypeTraits, + ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, + bool _is_packed> + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* + MutableRepeatedExtension( + const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< + MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) { + + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, + _is_packed, &_extensions_); + } + // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions) private: class _Internal; @@ -5446,7 +7147,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const UninterpretedOption_NamePart& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -5620,7 +7321,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const UninterpretedOption& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -5883,7 +7584,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const SourceCodeInfo_Location& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -6135,7 +7836,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const SourceCodeInfo& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -6292,7 +7993,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const GeneratedCodeInfo_Annotation& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -6503,7 +8204,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const GeneratedCodeInfo& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final;
diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc index 5f53cd1..b101dd2 100644 --- a/src/google/protobuf/descriptor_database.cc +++ b/src/google/protobuf/descriptor_database.cc
@@ -587,10 +587,10 @@ // Optimization: The name should be the first field in the encoded message. // Try to just read it directly. - io::CodedInputStream input(static_cast<const uint8*>(encoded_file.first), + io::CodedInputStream input(static_cast<const uint8_t*>(encoded_file.first), encoded_file.second); - const uint32 kNameTag = internal::WireFormatLite::MakeTag( + const uint32_t kNameTag = internal::WireFormatLite::MakeTag( FileDescriptorProto::kNameFieldNumber, internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index a7e5db2..b98e7f7 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc
@@ -56,6 +56,7 @@ #include <google/protobuf/dynamic_message.h> #include <google/protobuf/text_format.h> #include <google/protobuf/stubs/strutil.h> +#include <gmock/gmock.h> #include <google/protobuf/testing/googletest.h> #include <gtest/gtest.h> #include <google/protobuf/stubs/logging.h> @@ -723,6 +724,8 @@ AddField(message4, "field_name6", 6, FieldDescriptorProto::LABEL_OPTIONAL, FieldDescriptorProto::TYPE_INT32) ->set_json_name("@type"); + AddField(message4, "fieldname7", 7, FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); // Build the descriptors and get the pointers. foo_file_ = pool_.BuildFile(foo_file); @@ -814,6 +817,46 @@ EXPECT_TRUE(message2_->containing_type() == nullptr); } +TEST_F(DescriptorTest, FieldNamesDedup) { + const auto collect_unique_names = [](const FieldDescriptor* field) { + std::set<std::string> names{field->name(), field->lowercase_name(), + field->camelcase_name(), field->json_name()}; + // Verify that we have the same number of string objects as we have string + // values. That is, duplicate names use the same std::string object. + // This is for memory efficiency. + EXPECT_EQ(names.size(), (std::set<const std::string*>{ + &field->name(), &field->lowercase_name(), + &field->camelcase_name(), &field->json_name()} + .size())) + << testing::PrintToString(names); + return names; + }; + + using testing::ElementsAre; + // field_name1 + EXPECT_THAT(collect_unique_names(message4_->field(0)), + ElementsAre("fieldName1", "field_name1")); + // fieldName2 + EXPECT_THAT(collect_unique_names(message4_->field(1)), + ElementsAre("fieldName2", "fieldname2")); + // FieldName3 + EXPECT_THAT(collect_unique_names(message4_->field(2)), + ElementsAre("FieldName3", "fieldName3", "fieldname3")); + // _field_name4 + EXPECT_THAT(collect_unique_names(message4_->field(3)), + ElementsAre("FieldName4", "_field_name4", "fieldName4")); + // FIELD_NAME5 + EXPECT_THAT( + collect_unique_names(message4_->field(4)), + ElementsAre("FIELDNAME5", "FIELD_NAME5", "fIELDNAME5", "field_name5")); + // field_name6, with json name @type + EXPECT_THAT(collect_unique_names(message4_->field(5)), + ElementsAre("@type", "fieldName6", "field_name6")); + // fieldname7 + EXPECT_THAT(collect_unique_names(message4_->field(6)), + ElementsAre("fieldname7")); +} + TEST_F(DescriptorTest, FieldsByIndex) { ASSERT_EQ(4, message_->field_count()); EXPECT_EQ(foo_, message_->field(0)); @@ -913,33 +956,36 @@ DescriptorProto proto; message4_->CopyTo(&proto); - ASSERT_EQ(6, proto.field_size()); + ASSERT_EQ(7, proto.field_size()); EXPECT_FALSE(proto.field(0).has_json_name()); EXPECT_FALSE(proto.field(1).has_json_name()); EXPECT_FALSE(proto.field(2).has_json_name()); EXPECT_FALSE(proto.field(3).has_json_name()); EXPECT_FALSE(proto.field(4).has_json_name()); EXPECT_EQ("@type", proto.field(5).json_name()); + EXPECT_FALSE(proto.field(6).has_json_name()); proto.Clear(); CopyWithJsonName(message4_, &proto); - ASSERT_EQ(6, proto.field_size()); + ASSERT_EQ(7, proto.field_size()); EXPECT_EQ("fieldName1", proto.field(0).json_name()); EXPECT_EQ("fieldName2", proto.field(1).json_name()); EXPECT_EQ("FieldName3", proto.field(2).json_name()); EXPECT_EQ("FieldName4", proto.field(3).json_name()); EXPECT_EQ("FIELDNAME5", proto.field(4).json_name()); EXPECT_EQ("@type", proto.field(5).json_name()); + EXPECT_EQ("fieldname7", proto.field(6).json_name()); // Test generated descriptor. const Descriptor* generated = protobuf_unittest::TestJsonName::descriptor(); - ASSERT_EQ(6, generated->field_count()); + ASSERT_EQ(7, generated->field_count()); EXPECT_EQ("fieldName1", generated->field(0)->json_name()); EXPECT_EQ("fieldName2", generated->field(1)->json_name()); EXPECT_EQ("FieldName3", generated->field(2)->json_name()); EXPECT_EQ("FieldName4", generated->field(3)->json_name()); EXPECT_EQ("FIELDNAME5", generated->field(4)->json_name()); EXPECT_EQ("@type", generated->field(5)->json_name()); + EXPECT_EQ("fieldname7", generated->field(6)->json_name()); } TEST_F(DescriptorTest, FieldFile) { @@ -1858,6 +1904,7 @@ // repeated TestEnum foo_enum = 19; // } // message Bar { + // optional int32 non_ext_int32 = 1; // extend Foo { // optional Qux foo_message = 30; // repeated Qux foo_group = 39; // (but internally set to TYPE_GROUP) @@ -1883,6 +1930,8 @@ ->set_type_name("Baz"); DescriptorProto* bar = AddMessage(&foo_file, "Bar"); + AddField(bar, "non_ext_int32", 1, FieldDescriptorProto::LABEL_OPTIONAL, + FieldDescriptorProto::TYPE_INT32); AddNestedExtension(bar, "Foo", "foo_message", 30, FieldDescriptorProto::LABEL_OPTIONAL, FieldDescriptorProto::TYPE_MESSAGE) @@ -1995,6 +2044,15 @@ EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == nullptr); } +TEST_F(ExtensionDescriptorTest, FieldVsExtension) { + EXPECT_EQ(foo_->FindFieldByName("foo_message"), nullptr); + EXPECT_EQ(bar_->FindFieldByName("foo_message"), nullptr); + EXPECT_NE(bar_->FindFieldByName("non_ext_int32"), nullptr); + EXPECT_EQ(foo_->FindExtensionByName("foo_message"), nullptr); + EXPECT_NE(bar_->FindExtensionByName("foo_message"), nullptr); + EXPECT_EQ(bar_->FindExtensionByName("non_ext_int32"), nullptr); +} + TEST_F(ExtensionDescriptorTest, FindExtensionByPrintableName) { EXPECT_TRUE(pool_.FindExtensionByPrintableName(foo_, "no_such_extension") == nullptr);
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index 2f02356..94c1f0a 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc
@@ -41,11 +41,12 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Duration, seconds_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Duration, nanos_), }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(PROTOBUF_NAMESPACE_ID::Duration)}, + { 0, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Duration)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -150,35 +151,37 @@ if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { seconds_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // int32 nanos = 2; case 2: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { nanos_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -218,25 +221,15 @@ // int64 seconds = 1; if (this->_internal_seconds() != 0) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->_internal_seconds()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_seconds()); } // int32 nanos = 2; if (this->_internal_nanos() != 0) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_nanos()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_nanos()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Duration::_class_data_ = { @@ -245,8 +238,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Duration::GetClassData() const { return &_class_data_; } -void Duration::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Duration::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Duration *>(to)->MergeFrom( static_cast<const Duration &>(from)); }
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 7a5caa0..b7bd056 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h
@@ -142,7 +142,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Duration& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final;
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index 0bfb94a..a8b4a2c 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc
@@ -55,8 +55,8 @@ // // Note on memory allocation: This module often calls "operator new()" // to allocate untyped memory, rather than calling something like -// "new uint8[]". This is because "operator new()" means "Give me some -// space which I can use as I please." while "new uint8[]" means "Give +// "new uint8_t[]". This is because "operator new()" means "Give me some +// space which I can use as I please." while "new uint8_t[]" means "Give // me an array of 8-bit integers.". In practice, the later may return // a pointer that is not aligned correctly for general use. I believe // Item 8 of "More Effective C++" discusses this in more detail, though @@ -100,6 +100,14 @@ // =================================================================== // Some helper tables and functions... +class DynamicMessageReflectionHelper { + public: + static bool IsLazyField(const Reflection* reflection, + const FieldDescriptor* field) { + return reflection->IsLazyField(field); + } +}; + namespace { bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); } @@ -132,13 +140,13 @@ if (field->label() == FD::LABEL_REPEATED) { switch (field->cpp_type()) { case FD::CPPTYPE_INT32: - return sizeof(RepeatedField<int32>); + return sizeof(RepeatedField<int32_t>); case FD::CPPTYPE_INT64: - return sizeof(RepeatedField<int64>); + return sizeof(RepeatedField<int64_t>); case FD::CPPTYPE_UINT32: - return sizeof(RepeatedField<uint32>); + return sizeof(RepeatedField<uint32_t>); case FD::CPPTYPE_UINT64: - return sizeof(RepeatedField<uint64>); + return sizeof(RepeatedField<uint64_t>); case FD::CPPTYPE_DOUBLE: return sizeof(RepeatedField<double>); case FD::CPPTYPE_FLOAT: @@ -165,13 +173,13 @@ } else { switch (field->cpp_type()) { case FD::CPPTYPE_INT32: - return sizeof(int32); + return sizeof(int32_t); case FD::CPPTYPE_INT64: - return sizeof(int64); + return sizeof(int64_t); case FD::CPPTYPE_UINT32: - return sizeof(uint32); + return sizeof(uint32_t); case FD::CPPTYPE_UINT64: - return sizeof(uint64); + return sizeof(uint64_t); case FD::CPPTYPE_DOUBLE: return sizeof(double); case FD::CPPTYPE_FLOAT: @@ -200,8 +208,8 @@ inline int DivideRoundingUp(int i, int j) { return (i + (j - 1)) / j; } -static const int kSafeAlignment = sizeof(uint64); -static const int kMaxOneofUnionSize = sizeof(uint64); +static const int kSafeAlignment = sizeof(uint64_t); +static const int kMaxOneofUnionSize = sizeof(uint64_t); inline int AlignTo(int offset, int alignment) { return DivideRoundingUp(offset, alignment) * alignment; @@ -270,13 +278,26 @@ bool is_prototype() const; + inline int OffsetValue(int v, FieldDescriptor::Type type) const { + if (type == FieldDescriptor::TYPE_MESSAGE) { + return v & ~0x1u; + } + return v; + } + inline void* OffsetToPointer(int offset) { - return reinterpret_cast<uint8*>(this) + offset; + return reinterpret_cast<uint8_t*>(this) + offset; } inline const void* OffsetToPointer(int offset) const { - return reinterpret_cast<const uint8*>(this) + offset; + return reinterpret_cast<const uint8_t*>(this) + offset; } + void* MutableRaw(int i); + void* MutableExtensionsRaw(); + void* MutableWeakFieldMapRaw(); + void* MutableOneofCaseRaw(int i); + void* MutableOneofFieldRaw(const FieldDescriptor* f); + const DynamicMessageFactory::TypeInfo* type_info_; mutable std::atomic<int> cached_byte_size_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage); @@ -295,8 +316,8 @@ // Warning: The order in which the following pointers are defined is // important (the prototype must be deleted *before* the offsets). - std::unique_ptr<uint32[]> offsets; - std::unique_ptr<uint32[]> has_bits_indices; + std::unique_ptr<uint32_t[]> offsets; + std::unique_ptr<uint32_t[]> has_bits_indices; std::unique_ptr<const Reflection> reflection; // Don't use a unique_ptr to hold the prototype: the destructor for // DynamicMessage needs to know whether it is the prototype, and does so by @@ -325,7 +346,7 @@ bool lock_factory) : type_info_(type_info), cached_byte_size_(0) { // The prototype in type_info has to be set before creating the prototype - // instance on memory. e.g., message Foo { map<int32, Foo> a = 1; }. When + // instance on memory. e.g., message Foo { map<int32_t, Foo> a = 1; }. When // creating prototype for Foo, prototype of the map entry will also be // created, which needs the address of the prototype of Foo (the value in // map). To break the cyclic dependency, we have to assign the address of @@ -334,6 +355,26 @@ SharedCtor(lock_factory); } +void* DynamicMessage::MutableRaw(int i) { + return OffsetToPointer( + OffsetValue(type_info_->offsets[i], type_info_->type->field(i)->type())); +} +void* DynamicMessage::MutableExtensionsRaw() { + return OffsetToPointer(type_info_->extensions_offset); +} +void* DynamicMessage::MutableWeakFieldMapRaw() { + return OffsetToPointer(type_info_->weak_field_map_offset); +} +void* DynamicMessage::MutableOneofCaseRaw(int i) { + return OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32_t) * i); +} +void* DynamicMessage::MutableOneofFieldRaw(const FieldDescriptor* f) { + return OffsetToPointer( + OffsetValue(type_info_->offsets[type_info_->type->field_count() + + f->containing_oneof()->index()], + f->type())); +} + void DynamicMessage::SharedCtor(bool lock_factory) { // We need to call constructors for various fields manually and set // default values where appropriate. We use placement new to call @@ -349,17 +390,15 @@ int oneof_count = 0; for (int i = 0; i < descriptor->oneof_decl_count(); ++i) { if (descriptor->oneof_decl(i)->is_synthetic()) continue; - new (OffsetToPointer(type_info_->oneof_case_offset + - sizeof(uint32) * oneof_count++)) uint32(0); + new (MutableOneofCaseRaw(oneof_count++)) uint32_t{0}; } if (type_info_->extensions_offset != -1) { - new (OffsetToPointer(type_info_->extensions_offset)) - ExtensionSet(GetArenaForAllocation()); + new (MutableExtensionsRaw()) ExtensionSet(GetArenaForAllocation()); } for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); - void* field_ptr = OffsetToPointer(type_info_->offsets[i]); + void* field_ptr = MutableRaw(i); if (InRealOneof(field)) { continue; } @@ -373,10 +412,10 @@ } \ break; - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(BOOL, bool); @@ -384,7 +423,7 @@ case FieldDescriptor::CPPTYPE_ENUM: if (!field->is_repeated()) { - new (field_ptr) int(field->default_value_enum()->number()); + new (field_ptr) int{field->default_value_enum()->number()}; } else { new (field_ptr) RepeatedField<int>(GetArenaForAllocation()); } @@ -480,9 +519,7 @@ _internal_metadata_.Delete<UnknownFieldSet>(); if (type_info_->extensions_offset != -1) { - reinterpret_cast<ExtensionSet*>( - OffsetToPointer(type_info_->extensions_offset)) - ->~ExtensionSet(); + reinterpret_cast<ExtensionSet*>(MutableExtensionsRaw())->~ExtensionSet(); } // We need to manually run the destructors for repeated fields and strings, @@ -496,13 +533,9 @@ for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); if (InRealOneof(field)) { - void* field_ptr = - OffsetToPointer(type_info_->oneof_case_offset + - sizeof(uint32) * field->containing_oneof()->index()); - if (*(reinterpret_cast<const int32*>(field_ptr)) == field->number()) { - field_ptr = OffsetToPointer( - type_info_->offsets[descriptor->field_count() + - field->containing_oneof()->index()]); + void* field_ptr = MutableOneofCaseRaw(field->containing_oneof()->index()); + if (*(reinterpret_cast<const int32_t*>(field_ptr)) == field->number()) { + field_ptr = MutableOneofFieldRaw(field); if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { switch (field->options().ctype()) { default: @@ -523,7 +556,7 @@ } continue; } - void* field_ptr = OffsetToPointer(type_info_->offsets[i]); + void* field_ptr = MutableRaw(i); if (field->is_repeated()) { switch (field->cpp_type()) { @@ -533,10 +566,10 @@ ->~RepeatedField<LOWERCASE>(); \ break - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(BOOL, bool); @@ -598,10 +631,10 @@ // Cross-link default messages. for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); - void* field_ptr = OffsetToPointer(type_info_->offsets[i]); if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !field->options().weak() && !InRealOneof(field) && !field->is_repeated()) { + void* field_ptr = MutableRaw(i); // For fields with message types, we need to cross-link with the // prototype for the field's type. // For singular fields, the field is just a pointer which should @@ -695,7 +728,7 @@ } // Compute size and offsets. - uint32* offsets = new uint32[type->field_count() + real_oneof_count]; + uint32_t* offsets = new uint32_t[type->field_count() + real_oneof_count]; type_info->offsets.reset(offsets); // Decide all field offsets by packing in order. @@ -713,10 +746,10 @@ // At least one field in the message requires a hasbit, so allocate // hasbits. type_info->has_bits_offset = size; - uint32* has_bits_indices = new uint32[type->field_count()]; + uint32_t* has_bits_indices = new uint32_t[type->field_count()]; for (int i = 0; i < type->field_count(); i++) { // Initialize to -1, fields that need a hasbit will overwrite. - has_bits_indices[i] = static_cast<uint32>(-1); + has_bits_indices[i] = static_cast<uint32_t>(-1); } type_info->has_bits_indices.reset(has_bits_indices); } @@ -725,15 +758,15 @@ } if (max_hasbit > 0) { - int has_bits_array_size = DivideRoundingUp(max_hasbit, bitsizeof(uint32)); - size += has_bits_array_size * sizeof(uint32); + int has_bits_array_size = DivideRoundingUp(max_hasbit, bitsizeof(uint32_t)); + size += has_bits_array_size * sizeof(uint32_t); size = AlignOffset(size); } // The oneof_case, if any. It is an array of uint32s. if (real_oneof_count > 0) { type_info->oneof_case_offset = size; - size += real_oneof_count * sizeof(uint32); + size += real_oneof_count * sizeof(uint32_t); size = AlignOffset(size); }
diff --git a/src/google/protobuf/dynamic_message.h b/src/google/protobuf/dynamic_message.h index b85e00f..d0af57c 100644 --- a/src/google/protobuf/dynamic_message.h +++ b/src/google/protobuf/dynamic_message.h
@@ -182,23 +182,23 @@ return first < second; } case FieldDescriptor::CPPTYPE_INT32: { - int32 first = reflection->GetInt32(*a, field_); - int32 second = reflection->GetInt32(*b, field_); + int32_t first = reflection->GetInt32(*a, field_); + int32_t second = reflection->GetInt32(*b, field_); return first < second; } case FieldDescriptor::CPPTYPE_INT64: { - int64 first = reflection->GetInt64(*a, field_); - int64 second = reflection->GetInt64(*b, field_); + int64_t first = reflection->GetInt64(*a, field_); + int64_t second = reflection->GetInt64(*b, field_); return first < second; } case FieldDescriptor::CPPTYPE_UINT32: { - uint32 first = reflection->GetUInt32(*a, field_); - uint32 second = reflection->GetUInt32(*b, field_); + uint32_t first = reflection->GetUInt32(*a, field_); + uint32_t second = reflection->GetUInt32(*b, field_); return first < second; } case FieldDescriptor::CPPTYPE_UINT64: { - uint64 first = reflection->GetUInt64(*a, field_); - uint64 second = reflection->GetUInt64(*b, field_); + uint64_t first = reflection->GetUInt64(*a, field_); + uint64_t second = reflection->GetUInt64(*b, field_); return first < second; } case FieldDescriptor::CPPTYPE_STRING: {
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc index 96ee74a..126587b 100644 --- a/src/google/protobuf/empty.pb.cc +++ b/src/google/protobuf/empty.pb.cc
@@ -39,9 +39,10 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(PROTOBUF_NAMESPACE_ID::Empty)}, + { 0, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Empty)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -78,144 +79,30 @@ Empty::Empty(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) - : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { - SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } + : ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase(arena, is_message_owned) { // @@protoc_insertion_point(arena_constructor:google.protobuf.Empty) } Empty::Empty(const Empty& from) - : ::PROTOBUF_NAMESPACE_ID::Message() { + : ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase() { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); // @@protoc_insertion_point(copy_constructor:google.protobuf.Empty) } -void Empty::SharedCtor() { -} -Empty::~Empty() { - // @@protoc_insertion_point(destructor:google.protobuf.Empty) - if (GetArenaForAllocation() != nullptr) return; - SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); -} -inline void Empty::SharedDtor() { - GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); -} -void Empty::ArenaDtor(void* object) { - Empty* _this = reinterpret_cast< Empty* >(object); - (void)_this; -} -void Empty::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} -void Empty::SetCachedSize(int size) const { - _cached_size_.Set(size); -} - -void Empty::Clear() { -// @@protoc_insertion_point(message_clear_start:google.protobuf.Empty) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); -} - -const char* Empty::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - while (!ctx->Done(&ptr)) { - ::PROTOBUF_NAMESPACE_ID::uint32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } // while -success: - return ptr; -failure: - ptr = nullptr; - goto success; -#undef CHK_ -} - -::PROTOBUF_NAMESPACE_ID::uint8* Empty::_InternalSerialize( - ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { - // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Empty) - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); - } - // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Empty) - return target; -} - -size_t Empty::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Empty) - size_t total_size = 0; - - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Empty::_class_data_ = { - ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, - Empty::MergeImpl + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyImpl, + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeImpl, }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Empty::GetClassData() const { return &_class_data_; } -void Empty::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { - static_cast<Empty *>(to)->MergeFrom( - static_cast<const Empty &>(from)); -} -void Empty::MergeFrom(const Empty& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Empty) - GOOGLE_DCHECK_NE(&from, this); - ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; - (void) cached_has_bits; - _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); -} -void Empty::CopyFrom(const Empty& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Empty) - if (&from == this) return; - Clear(); - MergeFrom(from); -} -bool Empty::IsInitialized() const { - return true; -} - -void Empty::InternalSwap(Empty* other) { - using std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); -} ::PROTOBUF_NAMESPACE_ID::Metadata Empty::GetMetadata() const { return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index 64a3bde..84d914d 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h
@@ -66,10 +66,9 @@ // =================================================================== class PROTOBUF_EXPORT Empty final : - public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ { + public ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase /* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ { public: inline Empty() : Empty(nullptr) {} - ~Empty() override; explicit constexpr Empty(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Empty(const Empty& from); @@ -137,27 +136,15 @@ Empty* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { return CreateMaybeMessage<Empty>(arena); } - using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; - void CopyFrom(const Empty& from); - using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; - void MergeFrom(const Empty& from); - private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + using ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyFrom; + inline void CopyFrom(const Empty& from) { + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyImpl(this, from); + } + using ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeFrom; + void MergeFrom(const Empty& from) { + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeImpl(this, from); + } public: - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize( - ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } - - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const final; - void InternalSwap(Empty* other); friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { return "google.protobuf.Empty"; @@ -166,8 +153,6 @@ explicit Empty(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_;
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index bad23a6..2d5ca21 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc
@@ -35,8 +35,9 @@ #include <google/protobuf/extension_set.h> #include <tuple> -#include <unordered_map> +#include <unordered_set> #include <utility> + #include <google/protobuf/stubs/common.h> #include <google/protobuf/extension_set_inl.h> #include <google/protobuf/parse_context.h> @@ -84,39 +85,53 @@ } // Registry stuff. -struct ExtensionHasher { - std::size_t operator()(const std::pair<const MessageLite*, int>& p) const { - return std::hash<const MessageLite*>{}(p.first) ^ - std::hash<int>{}(p.second); + +// Note that we cannot use hetererogeneous lookup for std containers since we +// need to support C++11. +struct ExtensionEq { + bool operator()(const ExtensionInfo& lhs, const ExtensionInfo& rhs) const { + return lhs.message == rhs.message && lhs.number == rhs.number; } }; -typedef std::unordered_map<std::pair<const MessageLite*, int>, ExtensionInfo, - ExtensionHasher> - ExtensionRegistry; +struct ExtensionHasher { + std::size_t operator()(const ExtensionInfo& info) const { + return std::hash<const MessageLite*>{}(info.message) ^ + std::hash<int>{}(info.number); + } +}; + +using ExtensionRegistry = + std::unordered_set<ExtensionInfo, ExtensionHasher, ExtensionEq>; static const ExtensionRegistry* global_registry = nullptr; // This function is only called at startup, so there is no need for thread- // safety. -void Register(const MessageLite* containing_type, int number, - ExtensionInfo info) { +void Register(const ExtensionInfo& info) { static auto local_static_registry = OnShutdownDelete(new ExtensionRegistry); global_registry = local_static_registry; - if (!InsertIfNotPresent(local_static_registry, - std::make_pair(containing_type, number), info)) { + if (!InsertIfNotPresent(local_static_registry, info)) { GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \"" - << containing_type->GetTypeName() << "\", field number " - << number << "."; + << info.message->GetTypeName() << "\", field number " + << info.number << "."; } } -const ExtensionInfo* FindRegisteredExtension(const MessageLite* containing_type, +const ExtensionInfo* FindRegisteredExtension(const MessageLite* extendee, int number) { - return global_registry == nullptr - ? nullptr - : FindOrNull(*global_registry, - std::make_pair(containing_type, number)); + if (!global_registry) return nullptr; + + ExtensionInfo info; + info.message = extendee; + info.number = number; + + auto it = global_registry->find(info); + if (it == global_registry->end()) { + return nullptr; + } else { + return &*it; + } } } // namespace @@ -124,8 +139,7 @@ ExtensionFinder::~ExtensionFinder() {} bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) { - const ExtensionInfo* extension = - FindRegisteredExtension(containing_type_, number); + const ExtensionInfo* extension = FindRegisteredExtension(extendee_, number); if (extension == NULL) { return false; } else { @@ -134,14 +148,14 @@ } } -void ExtensionSet::RegisterExtension(const MessageLite* containing_type, - int number, FieldType type, - bool is_repeated, bool is_packed) { +void ExtensionSet::RegisterExtension(const MessageLite* extendee, int number, + FieldType type, bool is_repeated, + bool is_packed) { GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM); GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE); GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP); - ExtensionInfo info(type, is_repeated, is_packed); - Register(containing_type, number, info); + ExtensionInfo info(extendee, number, type, is_repeated, is_packed); + Register(info); } static bool CallNoArgValidityFunc(const void* arg, int number) { @@ -157,27 +171,27 @@ return ((EnumValidityFunc*)arg)(number); } -void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type, +void ExtensionSet::RegisterEnumExtension(const MessageLite* extendee, int number, FieldType type, bool is_repeated, bool is_packed, EnumValidityFunc* is_valid) { GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM); - ExtensionInfo info(type, is_repeated, is_packed); + ExtensionInfo info(extendee, number, type, is_repeated, is_packed); info.enum_validity_check.func = CallNoArgValidityFunc; // See comment in CallNoArgValidityFunc() about why we use a c-style cast. info.enum_validity_check.arg = (void*)is_valid; - Register(containing_type, number, info); + Register(info); } -void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type, +void ExtensionSet::RegisterMessageExtension(const MessageLite* extendee, int number, FieldType type, bool is_repeated, bool is_packed, const MessageLite* prototype) { GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE || type == WireFormatLite::TYPE_GROUP); - ExtensionInfo info(type, is_repeated, is_packed); + ExtensionInfo info(extendee, number, type, is_repeated, is_packed); info.message_info = {prototype}; - Register(containing_type, number, info); + Register(info); } // =================================================================== @@ -204,7 +218,7 @@ } void ExtensionSet::DeleteFlatMap(const ExtensionSet::KeyValue* flat, - uint16 flat_capacity) { + uint16_t flat_capacity) { #ifdef __cpp_sized_deallocation // Arena::CreateArray already requires a trivially destructible type, but // ensure this constraint is not violated in the future. @@ -220,7 +234,7 @@ } // Defined in extension_set_heavy.cc. -// void ExtensionSet::AppendToList(const Descriptor* containing_type, +// void ExtensionSet::AppendToList(const Descriptor* extendee, // const DescriptorPool* pool, // vector<const FieldDescriptor*>* output) const @@ -293,6 +307,17 @@ } \ } \ \ + const LOWERCASE& ExtensionSet::GetRef##CAMELCASE( \ + int number, const LOWERCASE& default_value) const { \ + const Extension* extension = FindOrNull(number); \ + if (extension == NULL || extension->is_cleared) { \ + return default_value; \ + } else { \ + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, UPPERCASE); \ + return extension->LOWERCASE##_value; \ + } \ + } \ + \ void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \ LOWERCASE value, \ const FieldDescriptor* descriptor) { \ @@ -317,6 +342,14 @@ return extension->repeated_##LOWERCASE##_value->Get(index); \ } \ \ + const LOWERCASE& ExtensionSet::GetRefRepeated##CAMELCASE(int number, \ + int index) const { \ + const Extension* extension = FindOrNull(number); \ + GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty)."; \ + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \ + return extension->repeated_##LOWERCASE##_value->Get(index); \ + } \ + \ void ExtensionSet::SetRepeated##CAMELCASE(int number, int index, \ LOWERCASE value) { \ Extension* extension = FindOrNull(number); \ @@ -344,10 +377,10 @@ extension->repeated_##LOWERCASE##_value->Add(value); \ } -PRIMITIVE_ACCESSORS(INT32, int32, Int32) -PRIMITIVE_ACCESSORS(INT64, int64, Int64) -PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32) -PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64) +PRIMITIVE_ACCESSORS(INT32, int32_t, Int32) +PRIMITIVE_ACCESSORS(INT64, int64_t, Int64) +PRIMITIVE_ACCESSORS(UINT32, uint32_t, UInt32) +PRIMITIVE_ACCESSORS(UINT64, uint64_t, UInt64) PRIMITIVE_ACCESSORS(FLOAT, float, Float) PRIMITIVE_ACCESSORS(DOUBLE, double, Double) PRIMITIVE_ACCESSORS(BOOL, bool, Bool) @@ -362,7 +395,7 @@ } // We assume that all the RepeatedField<>* pointers have the same // size and alignment within the anonymous union in Extension. - return extension->repeated_int32_value; + return extension->repeated_int32_t_value; } void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type, @@ -380,20 +413,20 @@ switch (WireFormatLite::FieldTypeToCppType( static_cast<WireFormatLite::FieldType>(field_type))) { case WireFormatLite::CPPTYPE_INT32: - extension->repeated_int32_value = - Arena::CreateMessage<RepeatedField<int32>>(arena_); + extension->repeated_int32_t_value = + Arena::CreateMessage<RepeatedField<int32_t>>(arena_); break; case WireFormatLite::CPPTYPE_INT64: - extension->repeated_int64_value = - Arena::CreateMessage<RepeatedField<int64>>(arena_); + extension->repeated_int64_t_value = + Arena::CreateMessage<RepeatedField<int64_t>>(arena_); break; case WireFormatLite::CPPTYPE_UINT32: - extension->repeated_uint32_value = - Arena::CreateMessage<RepeatedField<uint32>>(arena_); + extension->repeated_uint32_t_value = + Arena::CreateMessage<RepeatedField<uint32_t>>(arena_); break; case WireFormatLite::CPPTYPE_UINT64: - extension->repeated_uint64_value = - Arena::CreateMessage<RepeatedField<uint64>>(arena_); + extension->repeated_uint64_t_value = + Arena::CreateMessage<RepeatedField<uint64_t>>(arena_); break; case WireFormatLite::CPPTYPE_DOUBLE: extension->repeated_double_value = @@ -424,7 +457,7 @@ // We assume that all the RepeatedField<>* pointers have the same // size and alignment within the anonymous union in Extension. - return extension->repeated_int32_value; + return extension->repeated_int32_t_value; } // Compatible version using old call signature. Does not create extensions when @@ -434,7 +467,7 @@ GOOGLE_CHECK(extension != NULL) << "Extension not found."; // We assume that all the RepeatedField<>* pointers have the same // size and alignment within the anonymous union in Extension. - return extension->repeated_int32_value; + return extension->repeated_int32_t_value; } // ------------------------------------------------------------------- @@ -451,6 +484,18 @@ } } +const int& ExtensionSet::GetRefEnum(int number, + const int& default_value) const { + const Extension* extension = FindOrNull(number); + if (extension == nullptr || extension->is_cleared) { + // Not present. Return the default value. + return default_value; + } else { + GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, ENUM); + return extension->enum_value; + } +} + void ExtensionSet::SetEnum(int number, FieldType type, int value, const FieldDescriptor* descriptor) { Extension* extension; @@ -467,14 +512,21 @@ int ExtensionSet::GetRepeatedEnum(int number, int index) const { const Extension* extension = FindOrNull(number); - GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty)."; + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM); + return extension->repeated_enum_value->Get(index); +} + +const int& ExtensionSet::GetRefRepeatedEnum(int number, int index) const { + const Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM); return extension->repeated_enum_value->Get(index); } void ExtensionSet::SetRepeatedEnum(int number, int index, int value) { Extension* extension = FindOrNull(number); - GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty)."; + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM); extension->repeated_enum_value->Set(index, value); } @@ -616,10 +668,8 @@ ClearExtension(number); return; } -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT GOOGLE_DCHECK(message->GetOwningArena() == nullptr || message->GetOwningArena() == arena_); -#endif // PROTOBUF_INTERNAL_USE_MUST_USE_RESULT Arena* message_arena = message->GetOwningArena(); Extension* extension; if (MaybeNewExtension(number, descriptor, &extension)) { @@ -796,16 +846,16 @@ switch (cpp_type(extension->type)) { case WireFormatLite::CPPTYPE_INT32: - extension->repeated_int32_value->RemoveLast(); + extension->repeated_int32_t_value->RemoveLast(); break; case WireFormatLite::CPPTYPE_INT64: - extension->repeated_int64_value->RemoveLast(); + extension->repeated_int64_t_value->RemoveLast(); break; case WireFormatLite::CPPTYPE_UINT32: - extension->repeated_uint32_value->RemoveLast(); + extension->repeated_uint32_t_value->RemoveLast(); break; case WireFormatLite::CPPTYPE_UINT64: - extension->repeated_uint64_value->RemoveLast(); + extension->repeated_uint64_t_value->RemoveLast(); break; case WireFormatLite::CPPTYPE_FLOAT: extension->repeated_float_value->RemoveLast(); @@ -836,6 +886,14 @@ return extension->repeated_message_value->ReleaseLast(); } +MessageLite* ExtensionSet::UnsafeArenaReleaseLast(int number) { + Extension* extension = FindOrNull(number); + GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; + GOOGLE_DCHECK(extension->is_repeated); + GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE); + return extension->repeated_message_value->UnsafeArenaReleaseLast(); +} + void ExtensionSet::SwapElements(int number, int index1, int index2) { Extension* extension = FindOrNull(number); GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty)."; @@ -843,16 +901,16 @@ switch (cpp_type(extension->type)) { case WireFormatLite::CPPTYPE_INT32: - extension->repeated_int32_value->SwapElements(index1, index2); + extension->repeated_int32_t_value->SwapElements(index1, index2); break; case WireFormatLite::CPPTYPE_INT64: - extension->repeated_int64_value->SwapElements(index1, index2); + extension->repeated_int64_t_value->SwapElements(index1, index2); break; case WireFormatLite::CPPTYPE_UINT32: - extension->repeated_uint32_value->SwapElements(index1, index2); + extension->repeated_uint32_t_value->SwapElements(index1, index2); break; case WireFormatLite::CPPTYPE_UINT64: - extension->repeated_uint64_value->SwapElements(index1, index2); + extension->repeated_uint64_t_value->SwapElements(index1, index2); break; case WireFormatLite::CPPTYPE_FLOAT: extension->repeated_float_value->SwapElements(index1, index2); @@ -947,10 +1005,10 @@ *other_extension.repeated_##LOWERCASE##_value); \ break; - HANDLE_TYPE(INT32, int32, RepeatedField<int32>); - HANDLE_TYPE(INT64, int64, RepeatedField<int64>); - HANDLE_TYPE(UINT32, uint32, RepeatedField<uint32>); - HANDLE_TYPE(UINT64, uint64, RepeatedField<uint64>); + HANDLE_TYPE(INT32, int32_t, RepeatedField<int32_t>); + HANDLE_TYPE(INT64, int64_t, RepeatedField<int64_t>); + HANDLE_TYPE(UINT32, uint32_t, RepeatedField<uint32_t>); + HANDLE_TYPE(UINT64, uint64_t, RepeatedField<uint64_t>); HANDLE_TYPE(FLOAT, float, RepeatedField<float>); HANDLE_TYPE(DOUBLE, double, RepeatedField<double>); HANDLE_TYPE(BOOL, bool, RepeatedField<bool>); @@ -991,10 +1049,10 @@ other_extension.descriptor); \ break; - HANDLE_TYPE(INT32, int32, Int32); - HANDLE_TYPE(INT64, int64, Int64); - HANDLE_TYPE(UINT32, uint32, UInt32); - HANDLE_TYPE(UINT64, uint64, UInt64); + HANDLE_TYPE(INT32, int32_t, Int32); + HANDLE_TYPE(INT64, int64_t, Int64); + HANDLE_TYPE(UINT32, uint32_t, UInt32); + HANDLE_TYPE(UINT64, uint64_t, UInt64); HANDLE_TYPE(FLOAT, float, Float); HANDLE_TYPE(DOUBLE, double, Double); HANDLE_TYPE(BOOL, bool, Bool); @@ -1158,7 +1216,7 @@ return true; } -bool ExtensionSet::FindExtensionInfoFromTag(uint32 tag, +bool ExtensionSet::FindExtensionInfoFromTag(uint32_t tag, ExtensionFinder* extension_finder, int* field_number, ExtensionInfo* extension, @@ -1172,7 +1230,7 @@ bool ExtensionSet::FindExtensionInfoFromFieldNumber( int wire_type, int field_number, ExtensionFinder* extension_finder, - ExtensionInfo* extension, bool* was_packed_on_wire) { + ExtensionInfo* extension, bool* was_packed_on_wire) const { if (!extension_finder->Find(field_number, extension)) { return false; } @@ -1192,7 +1250,7 @@ return expected_wire_type == wire_type; } -bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, +bool ExtensionSet::ParseField(uint32_t tag, io::CodedInputStream* input, ExtensionFinder* extension_finder, FieldSkipper* field_skipper) { int number; @@ -1207,11 +1265,11 @@ } } -const char* ExtensionSet::ParseField(uint64 tag, const char* ptr, - const MessageLite* containing_type, +const char* ExtensionSet::ParseField(uint64_t tag, const char* ptr, + const MessageLite* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx) { - GeneratedExtensionFinder finder(containing_type); + GeneratedExtensionFinder finder(extendee); int number = tag >> 3; bool was_packed_on_wire; ExtensionInfo extension; @@ -1225,9 +1283,9 @@ } const char* ExtensionSet::ParseMessageSetItem( - const char* ptr, const MessageLite* containing_type, + const char* ptr, const MessageLite* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx) { - return ParseMessageSetItemTmpl<MessageLite, std::string>(ptr, containing_type, + return ParseMessageSetItemTmpl<MessageLite, std::string>(ptr, extendee, metadata, ctx); } @@ -1239,7 +1297,7 @@ // Explicitly not read extension.is_packed, instead check whether the field // was encoded in packed form on the wire. if (was_packed_on_wire) { - uint32 size; + uint32_t size; if (!input->ReadVarint32(&size)) return false; io::CodedInputStream::Limit limit = input->PushLimit(size); @@ -1257,16 +1315,16 @@ } \ break - HANDLE_TYPE(INT32, Int32, int32); - HANDLE_TYPE(INT64, Int64, int64); - HANDLE_TYPE(UINT32, UInt32, uint32); - HANDLE_TYPE(UINT64, UInt64, uint64); - HANDLE_TYPE(SINT32, Int32, int32); - HANDLE_TYPE(SINT64, Int64, int64); - HANDLE_TYPE(FIXED32, UInt32, uint32); - HANDLE_TYPE(FIXED64, UInt64, uint64); - HANDLE_TYPE(SFIXED32, Int32, int32); - HANDLE_TYPE(SFIXED64, Int64, int64); + HANDLE_TYPE(INT32, Int32, int32_t); + HANDLE_TYPE(INT64, Int64, int64_t); + HANDLE_TYPE(UINT32, UInt32, uint32_t); + HANDLE_TYPE(UINT64, UInt64, uint64_t); + HANDLE_TYPE(SINT32, Int32, int32_t); + HANDLE_TYPE(SINT64, Int64, int64_t); + HANDLE_TYPE(FIXED32, UInt32, uint32_t); + HANDLE_TYPE(FIXED64, UInt64, uint64_t); + HANDLE_TYPE(SFIXED32, Int32, int32_t); + HANDLE_TYPE(SFIXED64, Int64, int64_t); HANDLE_TYPE(FLOAT, Float, float); HANDLE_TYPE(DOUBLE, Double, double); HANDLE_TYPE(BOOL, Bool, bool); @@ -1316,16 +1374,16 @@ } \ } break - HANDLE_TYPE(INT32, Int32, int32); - HANDLE_TYPE(INT64, Int64, int64); - HANDLE_TYPE(UINT32, UInt32, uint32); - HANDLE_TYPE(UINT64, UInt64, uint64); - HANDLE_TYPE(SINT32, Int32, int32); - HANDLE_TYPE(SINT64, Int64, int64); - HANDLE_TYPE(FIXED32, UInt32, uint32); - HANDLE_TYPE(FIXED64, UInt64, uint64); - HANDLE_TYPE(SFIXED32, Int32, int32); - HANDLE_TYPE(SFIXED64, Int64, int64); + HANDLE_TYPE(INT32, Int32, int32_t); + HANDLE_TYPE(INT64, Int64, int64_t); + HANDLE_TYPE(UINT32, UInt32, uint32_t); + HANDLE_TYPE(UINT64, UInt64, uint64_t); + HANDLE_TYPE(SINT32, Int32, int32_t); + HANDLE_TYPE(SINT64, Int64, int64_t); + HANDLE_TYPE(FIXED32, UInt32, uint32_t); + HANDLE_TYPE(FIXED64, UInt64, uint64_t); + HANDLE_TYPE(SFIXED32, Int32, int32_t); + HANDLE_TYPE(SFIXED64, Int64, int64_t); HANDLE_TYPE(FLOAT, Float, float); HANDLE_TYPE(DOUBLE, Double, double); HANDLE_TYPE(BOOL, Bool, bool); @@ -1404,18 +1462,18 @@ return true; } -bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, - const MessageLite* containing_type) { +bool ExtensionSet::ParseField(uint32_t tag, io::CodedInputStream* input, + const MessageLite* extendee) { FieldSkipper skipper; - GeneratedExtensionFinder finder(containing_type); + GeneratedExtensionFinder finder(extendee); return ParseField(tag, input, &finder, &skipper); } -bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, - const MessageLite* containing_type, +bool ExtensionSet::ParseField(uint32_t tag, io::CodedInputStream* input, + const MessageLite* extendee, io::CodedOutputStream* unknown_fields) { CodedOutputStreamFieldSkipper skipper(unknown_fields); - GeneratedExtensionFinder finder(containing_type); + GeneratedExtensionFinder finder(extendee); return ParseField(tag, input, &finder, &skipper); } @@ -1423,7 +1481,7 @@ ExtensionFinder* extension_finder, FieldSkipper* field_skipper) { while (true) { - const uint32 tag = input->ReadTag(); + const uint32_t tag = input->ReadTag(); switch (tag) { case 0: return true; @@ -1451,7 +1509,7 @@ extension_finder, field_skipper); } - bool SkipField(uint32 tag, io::CodedInputStream* input) { + bool SkipField(uint32_t tag, io::CodedInputStream* input) { return field_skipper->SkipField(input, tag); } @@ -1465,24 +1523,24 @@ } bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, - const MessageLite* containing_type, + const MessageLite* extendee, std::string* unknown_fields) { io::StringOutputStream zcis(unknown_fields); io::CodedOutputStream output(&zcis); CodedOutputStreamFieldSkipper skipper(&output); - GeneratedExtensionFinder finder(containing_type); + GeneratedExtensionFinder finder(extendee); return ParseMessageSetLite(input, &finder, &skipper); } -uint8* ExtensionSet::_InternalSerializeImpl( - int start_field_number, int end_field_number, uint8* target, - io::EpsCopyOutputStream* stream) const { +uint8_t* ExtensionSet::_InternalSerializeImpl( + const MessageLite* extendee, int start_field_number, int end_field_number, + uint8_t* target, io::EpsCopyOutputStream* stream) const { if (PROTOBUF_PREDICT_FALSE(is_large())) { const auto& end = map_.large->end(); for (auto it = map_.large->lower_bound(start_field_number); it != end && it->first < end_field_number; ++it) { target = it->second.InternalSerializeFieldWithCachedSizesToArray( - it->first, target, stream); + extendee, this, it->first, target, stream); } return target; } @@ -1491,16 +1549,19 @@ flat_begin(), end, start_field_number, KeyValue::FirstComparator()); it != end && it->first < end_field_number; ++it) { target = it->second.InternalSerializeFieldWithCachedSizesToArray( - it->first, target, stream); + extendee, this, it->first, target, stream); } return target; } -uint8* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray( - uint8* target, io::EpsCopyOutputStream* stream) const { - ForEach([&target, stream](int number, const Extension& ext) { +uint8_t* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray( + const MessageLite* extendee, uint8_t* target, + io::EpsCopyOutputStream* stream) const { + const ExtensionSet* extension_set = this; + ForEach([&target, extendee, stream, extension_set](int number, + const Extension& ext) { target = ext.InternalSerializeMessageSetItemWithCachedSizesToArray( - number, target, stream); + extendee, extension_set, number, target, stream); }); return target; } @@ -1536,10 +1597,10 @@ repeated_##LOWERCASE##_value->Clear(); \ break - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(BOOL, bool); @@ -1587,12 +1648,12 @@ } \ break - HANDLE_TYPE(INT32, Int32, int32); - HANDLE_TYPE(INT64, Int64, int64); - HANDLE_TYPE(UINT32, UInt32, uint32); - HANDLE_TYPE(UINT64, UInt64, uint64); - HANDLE_TYPE(SINT32, SInt32, int32); - HANDLE_TYPE(SINT64, SInt64, int64); + HANDLE_TYPE(INT32, Int32, int32_t); + HANDLE_TYPE(INT64, Int64, int64_t); + HANDLE_TYPE(UINT32, UInt32, uint32_t); + HANDLE_TYPE(UINT64, UInt64, uint64_t); + HANDLE_TYPE(SINT32, SInt32, int32_t); + HANDLE_TYPE(SINT64, SInt64, int64_t); HANDLE_TYPE(ENUM, Enum, enum); #undef HANDLE_TYPE @@ -1602,10 +1663,10 @@ result += WireFormatLite::k##CAMELCASE##Size * \ FromIntSize(repeated_##LOWERCASE##_value->size()); \ break - HANDLE_TYPE(FIXED32, Fixed32, uint32); - HANDLE_TYPE(FIXED64, Fixed64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE(FIXED32, Fixed32, uint32_t); + HANDLE_TYPE(FIXED64, Fixed64, uint64_t); + HANDLE_TYPE(SFIXED32, SFixed32, int32_t); + HANDLE_TYPE(SFIXED64, SFixed64, int64_t); HANDLE_TYPE(FLOAT, Float, float); HANDLE_TYPE(DOUBLE, Double, double); HANDLE_TYPE(BOOL, Bool, bool); @@ -1638,12 +1699,12 @@ } \ break - HANDLE_TYPE(INT32, Int32, int32); - HANDLE_TYPE(INT64, Int64, int64); - HANDLE_TYPE(UINT32, UInt32, uint32); - HANDLE_TYPE(UINT64, UInt64, uint64); - HANDLE_TYPE(SINT32, SInt32, int32); - HANDLE_TYPE(SINT64, SInt64, int64); + HANDLE_TYPE(INT32, Int32, int32_t); + HANDLE_TYPE(INT64, Int64, int64_t); + HANDLE_TYPE(UINT32, UInt32, uint32_t); + HANDLE_TYPE(UINT64, UInt64, uint64_t); + HANDLE_TYPE(SINT32, SInt32, int32_t); + HANDLE_TYPE(SINT64, SInt64, int64_t); HANDLE_TYPE(STRING, String, string); HANDLE_TYPE(BYTES, Bytes, string); HANDLE_TYPE(ENUM, Enum, enum); @@ -1657,10 +1718,10 @@ result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \ FromIntSize(repeated_##LOWERCASE##_value->size()); \ break - HANDLE_TYPE(FIXED32, Fixed32, uint32); - HANDLE_TYPE(FIXED64, Fixed64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE(FIXED32, Fixed32, uint32_t); + HANDLE_TYPE(FIXED64, Fixed64, uint64_t); + HANDLE_TYPE(SFIXED32, SFixed32, int32_t); + HANDLE_TYPE(SFIXED64, SFixed64, int64_t); HANDLE_TYPE(FLOAT, Float, float); HANDLE_TYPE(DOUBLE, Double, double); HANDLE_TYPE(BOOL, Bool, bool); @@ -1675,12 +1736,12 @@ result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \ break - HANDLE_TYPE(INT32, Int32, int32_value); - HANDLE_TYPE(INT64, Int64, int64_value); - HANDLE_TYPE(UINT32, UInt32, uint32_value); - HANDLE_TYPE(UINT64, UInt64, uint64_value); - HANDLE_TYPE(SINT32, SInt32, int32_value); - HANDLE_TYPE(SINT64, SInt64, int64_value); + HANDLE_TYPE(INT32, Int32, int32_t_value); + HANDLE_TYPE(INT64, Int64, int64_t_value); + HANDLE_TYPE(UINT32, UInt32, uint32_t_value); + HANDLE_TYPE(UINT64, UInt64, uint64_t_value); + HANDLE_TYPE(SINT32, SInt32, int32_t_value); + HANDLE_TYPE(SINT64, SInt64, int64_t_value); HANDLE_TYPE(STRING, String, *string_value); HANDLE_TYPE(BYTES, Bytes, *string_value); HANDLE_TYPE(ENUM, Enum, enum_value); @@ -1722,10 +1783,10 @@ case WireFormatLite::CPPTYPE_##UPPERCASE: \ return repeated_##LOWERCASE##_value->size() - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(BOOL, bool); @@ -1749,10 +1810,10 @@ delete repeated_##LOWERCASE##_value; \ break - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(BOOL, bool); @@ -1807,16 +1868,15 @@ void ExtensionSet::LazyMessageExtension::UnusedKeyMethod() {} const ExtensionSet::Extension* ExtensionSet::FindOrNull(int key) const { - if (PROTOBUF_PREDICT_FALSE(is_large())) { + if (flat_size_ == 0) { + return nullptr; + } else if (PROTOBUF_PREDICT_TRUE(!is_large())) { + auto it = std::lower_bound(flat_begin(), flat_end() - 1, key, + KeyValue::FirstComparator()); + return it->first == key ? &it->second : nullptr; + } else { return FindOrNullInLargeMap(key); } - const KeyValue* end = flat_end(); - const KeyValue* it = - std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator()); - if (it != end && it->first == key) { - return &it->second; - } - return NULL; } const ExtensionSet::Extension* ExtensionSet::FindOrNullInLargeMap( @@ -1830,25 +1890,14 @@ } ExtensionSet::Extension* ExtensionSet::FindOrNull(int key) { - if (PROTOBUF_PREDICT_FALSE(is_large())) { - return FindOrNullInLargeMap(key); - } - KeyValue* end = flat_end(); - KeyValue* it = - std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator()); - if (it != end && it->first == key) { - return &it->second; - } - return NULL; + const auto* const_this = this; + return const_cast<ExtensionSet::Extension*>(const_this->FindOrNull(key)); } ExtensionSet::Extension* ExtensionSet::FindOrNullInLargeMap(int key) { - assert(is_large()); - LargeMap::iterator it = map_.large->find(key); - if (it != map_.large->end()) { - return &it->second; - } - return NULL; + const auto* const_this = this; + return const_cast<ExtensionSet::Extension*>( + const_this->FindOrNullInLargeMap(key)); } std::pair<ExtensionSet::Extension*, bool> ExtensionSet::Insert(int key) { @@ -1895,6 +1944,8 @@ for (const KeyValue* it = begin; it != end; ++it) { hint = new_map.large->insert(hint, {it->first, it->second}); } + flat_size_ = static_cast<uint16_t>(-1); + GOOGLE_DCHECK(is_large()); } else { new_map.flat = Arena::CreateArray<KeyValue>(arena_, new_flat_capacity); std::copy(begin, end, new_map.flat); @@ -1908,7 +1959,7 @@ } // static -constexpr uint16 ExtensionSet::kMaximumFlatCapacity; +constexpr uint16_t ExtensionSet::kMaximumFlatCapacity; void ExtensionSet::Erase(int key) { if (PROTOBUF_PREDICT_FALSE(is_large())) { @@ -1938,8 +1989,9 @@ return instance; } -uint8* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray( - int number, uint8* target, io::EpsCopyOutputStream* stream) const { +uint8_t* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray( + const MessageLite* extendee, const ExtensionSet* extension_set, int number, + uint8_t* target, io::EpsCopyOutputStream* stream) const { if (is_repeated) { if (is_packed) { if (cached_size == 0) return target; @@ -1959,16 +2011,16 @@ } \ break - HANDLE_TYPE(INT32, Int32, int32); - HANDLE_TYPE(INT64, Int64, int64); - HANDLE_TYPE(UINT32, UInt32, uint32); - HANDLE_TYPE(UINT64, UInt64, uint64); - HANDLE_TYPE(SINT32, SInt32, int32); - HANDLE_TYPE(SINT64, SInt64, int64); - HANDLE_TYPE(FIXED32, Fixed32, uint32); - HANDLE_TYPE(FIXED64, Fixed64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE(INT32, Int32, int32_t); + HANDLE_TYPE(INT64, Int64, int64_t); + HANDLE_TYPE(UINT32, UInt32, uint32_t); + HANDLE_TYPE(UINT64, UInt64, uint64_t); + HANDLE_TYPE(SINT32, SInt32, int32_t); + HANDLE_TYPE(SINT64, SInt64, int64_t); + HANDLE_TYPE(FIXED32, Fixed32, uint32_t); + HANDLE_TYPE(FIXED64, Fixed64, uint64_t); + HANDLE_TYPE(SFIXED32, SFixed32, int32_t); + HANDLE_TYPE(SFIXED64, SFixed64, int64_t); HANDLE_TYPE(FLOAT, Float, float); HANDLE_TYPE(DOUBLE, Double, double); HANDLE_TYPE(BOOL, Bool, bool); @@ -1993,16 +2045,16 @@ } \ break - HANDLE_TYPE(INT32, Int32, int32); - HANDLE_TYPE(INT64, Int64, int64); - HANDLE_TYPE(UINT32, UInt32, uint32); - HANDLE_TYPE(UINT64, UInt64, uint64); - HANDLE_TYPE(SINT32, SInt32, int32); - HANDLE_TYPE(SINT64, SInt64, int64); - HANDLE_TYPE(FIXED32, Fixed32, uint32); - HANDLE_TYPE(FIXED64, Fixed64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE(INT32, Int32, int32_t); + HANDLE_TYPE(INT64, Int64, int64_t); + HANDLE_TYPE(UINT32, UInt32, uint32_t); + HANDLE_TYPE(UINT64, UInt64, uint64_t); + HANDLE_TYPE(SINT32, SInt32, int32_t); + HANDLE_TYPE(SINT64, SInt64, int64_t); + HANDLE_TYPE(FIXED32, Fixed32, uint32_t); + HANDLE_TYPE(FIXED64, Fixed64, uint64_t); + HANDLE_TYPE(SFIXED32, SFixed32, int32_t); + HANDLE_TYPE(SFIXED64, SFixed64, int64_t); HANDLE_TYPE(FLOAT, Float, float); HANDLE_TYPE(DOUBLE, Double, double); HANDLE_TYPE(BOOL, Bool, bool); @@ -2041,16 +2093,16 @@ target = WireFormatLite::Write##CAMELCASE##ToArray(number, VALUE, target); \ break - HANDLE_TYPE(INT32, Int32, int32_value); - HANDLE_TYPE(INT64, Int64, int64_value); - HANDLE_TYPE(UINT32, UInt32, uint32_value); - HANDLE_TYPE(UINT64, UInt64, uint64_value); - HANDLE_TYPE(SINT32, SInt32, int32_value); - HANDLE_TYPE(SINT64, SInt64, int64_value); - HANDLE_TYPE(FIXED32, Fixed32, uint32_value); - HANDLE_TYPE(FIXED64, Fixed64, uint64_value); - HANDLE_TYPE(SFIXED32, SFixed32, int32_value); - HANDLE_TYPE(SFIXED64, SFixed64, int64_value); + HANDLE_TYPE(INT32, Int32, int32_t_value); + HANDLE_TYPE(INT64, Int64, int64_t_value); + HANDLE_TYPE(UINT32, UInt32, uint32_t_value); + HANDLE_TYPE(UINT64, UInt64, uint64_t_value); + HANDLE_TYPE(SINT32, SInt32, int32_t_value); + HANDLE_TYPE(SINT64, SInt64, int64_t_value); + HANDLE_TYPE(FIXED32, Fixed32, uint32_t_value); + HANDLE_TYPE(FIXED64, Fixed64, uint64_t_value); + HANDLE_TYPE(SFIXED32, SFixed32, int32_t_value); + HANDLE_TYPE(SFIXED64, SFixed64, int64_t_value); HANDLE_TYPE(FLOAT, Float, float_value); HANDLE_TYPE(DOUBLE, Double, double_value); HANDLE_TYPE(BOOL, Bool, bool_value); @@ -2071,8 +2123,10 @@ break; case WireFormatLite::TYPE_MESSAGE: if (is_lazy) { - target = - lazymessage_value->WriteMessageToArray(number, target, stream); + const auto* prototype = + extension_set->GetPrototypeForLazyMessage(extendee, number); + target = lazymessage_value->WriteMessageToArray(prototype, number, + target, stream); } else { target = stream->EnsureSpace(target); target = WireFormatLite::InternalWriteMessage(number, *message_value, @@ -2084,13 +2138,28 @@ return target; } -uint8* +const MessageLite* ExtensionSet::GetPrototypeForLazyMessage( + const MessageLite* extendee, int number) const { + GeneratedExtensionFinder finder(extendee); + bool was_packed_on_wire = false; + ExtensionInfo extension_info; + if (!FindExtensionInfoFromFieldNumber( + WireFormatLite::WireType::WIRETYPE_LENGTH_DELIMITED, number, &finder, + &extension_info, &was_packed_on_wire)) { + return nullptr; + } + return extension_info.message_info.prototype; +} + +uint8_t* ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray( - int number, uint8* target, io::EpsCopyOutputStream* stream) const { + const MessageLite* extendee, const ExtensionSet* extension_set, int number, + uint8_t* target, io::EpsCopyOutputStream* stream) const { if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { // Not a valid MessageSet extension, but serialize it the normal way. GOOGLE_LOG(WARNING) << "Invalid message set extension."; - return InternalSerializeFieldWithCachedSizesToArray(number, target, stream); + return InternalSerializeFieldWithCachedSizesToArray(extendee, extension_set, + number, target, stream); } if (is_cleared) return target; @@ -2104,8 +2173,10 @@ WireFormatLite::kMessageSetTypeIdNumber, number, target); // Write message. if (is_lazy) { + const auto* prototype = + extension_set->GetPrototypeForLazyMessage(extendee, number); target = lazymessage_value->WriteMessageToArray( - WireFormatLite::kMessageSetMessageNumber, target, stream); + prototype, WireFormatLite::kMessageSetMessageNumber, target, stream); } else { target = WireFormatLite::InternalWriteMessage( WireFormatLite::kMessageSetMessageNumber, *message_value, target,
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index e3d1669..9389273 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h
@@ -85,7 +85,7 @@ // #include wire_format_lite.h. Also, ensures that we use only one byte to // store these values, which is important to keep the layout of // ExtensionSet::Extension small. -typedef uint8 FieldType; +typedef uint8_t FieldType; // A function which, given an integer value, returns true if the number // matches one of the defined values for the corresponding enum type. This @@ -99,12 +99,18 @@ // Information about a registered extension. struct ExtensionInfo { inline ExtensionInfo() {} - inline ExtensionInfo(FieldType type_param, bool isrepeated, bool ispacked) - : type(type_param), + inline ExtensionInfo(const MessageLite* extendee, int param_number, + FieldType type_param, bool isrepeated, bool ispacked) + : message(extendee), + number(param_number), + type(type_param), is_repeated(isrepeated), is_packed(ispacked), descriptor(NULL) {} + const MessageLite* message; + int number; + FieldType type; bool is_repeated; bool is_packed; @@ -143,15 +149,15 @@ // files which have been compiled into the binary. class PROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder { public: - GeneratedExtensionFinder(const MessageLite* containing_type) - : containing_type_(containing_type) {} + explicit GeneratedExtensionFinder(const MessageLite* extendee) + : extendee_(extendee) {} ~GeneratedExtensionFinder() override {} // Returns true and fills in *output if found, otherwise returns false. bool Find(int number, ExtensionInfo* output) override; private: - const MessageLite* containing_type_; + const MessageLite* extendee_; }; // A FieldSkipper used for parsing MessageSet. @@ -182,24 +188,22 @@ // to look up extensions for parsed field numbers. Note that dynamic parsing // does not use ParseField(); only protocol-compiler-generated parsing // methods do. - static void RegisterExtension(const MessageLite* containing_type, int number, + static void RegisterExtension(const MessageLite* extendee, int number, FieldType type, bool is_repeated, bool is_packed); - static void RegisterEnumExtension(const MessageLite* containing_type, - int number, FieldType type, - bool is_repeated, bool is_packed, - EnumValidityFunc* is_valid); - static void RegisterMessageExtension(const MessageLite* containing_type, - int number, FieldType type, - bool is_repeated, bool is_packed, + static void RegisterEnumExtension(const MessageLite* extendee, int number, + FieldType type, bool is_repeated, + bool is_packed, EnumValidityFunc* is_valid); + static void RegisterMessageExtension(const MessageLite* extendee, int number, + FieldType type, bool is_repeated, + bool is_packed, const MessageLite* prototype); // ================================================================= // Add all fields which are currently present to the given vector. This // is useful to implement Reflection::ListFields(). - void AppendToList(const Descriptor* containing_type, - const DescriptorPool* pool, + void AppendToList(const Descriptor* extendee, const DescriptorPool* pool, std::vector<const FieldDescriptor*>* output) const; // ================================================================= @@ -240,10 +244,10 @@ // singular fields ------------------------------------------------- - int32 GetInt32(int number, int32 default_value) const; - int64 GetInt64(int number, int64 default_value) const; - uint32 GetUInt32(int number, uint32 default_value) const; - uint64 GetUInt64(int number, uint64 default_value) const; + int32_t GetInt32(int number, int32_t default_value) const; + int64_t GetInt64(int number, int64_t default_value) const; + uint32_t GetUInt32(int number, uint32_t default_value) const; + uint64_t GetUInt64(int number, uint64_t default_value) const; float GetFloat(int number, float default_value) const; double GetDouble(int number, double default_value) const; bool GetBool(int number, bool default_value) const; @@ -259,10 +263,10 @@ // the extension lives in the same pool as the descriptor for the containing // type. #define desc const FieldDescriptor* descriptor // avoid line wrapping - void SetInt32(int number, FieldType type, int32 value, desc); - void SetInt64(int number, FieldType type, int64 value, desc); - void SetUInt32(int number, FieldType type, uint32 value, desc); - void SetUInt64(int number, FieldType type, uint64 value, desc); + void SetInt32(int number, FieldType type, int32_t value, desc); + void SetInt64(int number, FieldType type, int64_t value, desc); + void SetUInt32(int number, FieldType type, uint32_t value, desc); + void SetUInt64(int number, FieldType type, uint64_t value, desc); void SetFloat(int number, FieldType type, float value, desc); void SetDouble(int number, FieldType type, double value, desc); void SetBool(int number, FieldType type, bool value, desc); @@ -312,10 +316,10 @@ // (E.g.: borg/clients/internal/proto1/proto2_reflection.cc.) void* MutableRawRepeatedField(int number); - int32 GetRepeatedInt32(int number, int index) const; - int64 GetRepeatedInt64(int number, int index) const; - uint32 GetRepeatedUInt32(int number, int index) const; - uint64 GetRepeatedUInt64(int number, int index) const; + int32_t GetRepeatedInt32(int number, int index) const; + int64_t GetRepeatedInt64(int number, int index) const; + uint32_t GetRepeatedUInt32(int number, int index) const; + uint64_t GetRepeatedUInt64(int number, int index) const; float GetRepeatedFloat(int number, int index) const; double GetRepeatedDouble(int number, int index) const; bool GetRepeatedBool(int number, int index) const; @@ -323,10 +327,10 @@ const std::string& GetRepeatedString(int number, int index) const; const MessageLite& GetRepeatedMessage(int number, int index) const; - void SetRepeatedInt32(int number, int index, int32 value); - void SetRepeatedInt64(int number, int index, int64 value); - void SetRepeatedUInt32(int number, int index, uint32 value); - void SetRepeatedUInt64(int number, int index, uint64 value); + void SetRepeatedInt32(int number, int index, int32_t value); + void SetRepeatedInt64(int number, int index, int64_t value); + void SetRepeatedUInt32(int number, int index, uint32_t value); + void SetRepeatedUInt64(int number, int index, uint64_t value); void SetRepeatedFloat(int number, int index, float value); void SetRepeatedDouble(int number, int index, double value); void SetRepeatedBool(int number, int index, bool value); @@ -336,10 +340,10 @@ MessageLite* MutableRepeatedMessage(int number, int index); #define desc const FieldDescriptor* descriptor // avoid line wrapping - void AddInt32(int number, FieldType type, bool packed, int32 value, desc); - void AddInt64(int number, FieldType type, bool packed, int64 value, desc); - void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc); - void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc); + void AddInt32(int number, FieldType type, bool packed, int32_t value, desc); + void AddInt64(int number, FieldType type, bool packed, int64_t value, desc); + void AddUInt32(int number, FieldType type, bool packed, uint32_t value, desc); + void AddUInt64(int number, FieldType type, bool packed, uint64_t value, desc); void AddFloat(int number, FieldType type, bool packed, float value, desc); void AddDouble(int number, FieldType type, bool packed, double value, desc); void AddBool(int number, FieldType type, bool packed, bool value, desc); @@ -352,10 +356,13 @@ MessageFactory* factory); void AddAllocatedMessage(const FieldDescriptor* descriptor, MessageLite* new_entry); + void UnsafeArenaAddAllocatedMessage(const FieldDescriptor* descriptor, + MessageLite* new_entry); #undef desc void RemoveLast(int number); PROTOBUF_MUST_USE_RESULT MessageLite* ReleaseLast(int number); + MessageLite* UnsafeArenaReleaseLast(int number); void SwapElements(int number, int index1, int index2); // ----------------------------------------------------------------- @@ -377,49 +384,47 @@ // Parses a single extension from the input. The input should start out // positioned immediately after the tag. - bool ParseField(uint32 tag, io::CodedInputStream* input, + bool ParseField(uint32_t tag, io::CodedInputStream* input, ExtensionFinder* extension_finder, FieldSkipper* field_skipper); // Specific versions for lite or full messages (constructs the appropriate - // FieldSkipper automatically). |containing_type| is the default + // FieldSkipper automatically). |extendee| is the default // instance for the containing message; it is used only to look up the // extension by number. See RegisterExtension(), above. Unlike the other // methods of ExtensionSet, this only works for generated message types -- // it looks up extensions registered using RegisterExtension(). - bool ParseField(uint32 tag, io::CodedInputStream* input, - const MessageLite* containing_type); - bool ParseField(uint32 tag, io::CodedInputStream* input, - const Message* containing_type, - UnknownFieldSet* unknown_fields); - bool ParseField(uint32 tag, io::CodedInputStream* input, - const MessageLite* containing_type, + bool ParseField(uint32_t tag, io::CodedInputStream* input, + const MessageLite* extendee); + bool ParseField(uint32_t tag, io::CodedInputStream* input, + const Message* extendee, UnknownFieldSet* unknown_fields); + bool ParseField(uint32_t tag, io::CodedInputStream* input, + const MessageLite* extendee, io::CodedOutputStream* unknown_fields); // Lite parser - const char* ParseField(uint64 tag, const char* ptr, - const MessageLite* containing_type, + const char* ParseField(uint64_t tag, const char* ptr, + const MessageLite* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx); // Full parser - const char* ParseField(uint64 tag, const char* ptr, - const Message* containing_type, + const char* ParseField(uint64_t tag, const char* ptr, const Message* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx); template <typename Msg> - const char* ParseMessageSet(const char* ptr, const Msg* containing_type, + const char* ParseMessageSet(const char* ptr, const Msg* extendee, InternalMetadata* metadata, internal::ParseContext* ctx) { struct MessageSetItem { const char* _InternalParse(const char* ptr, ParseContext* ctx) { - return me->ParseMessageSetItem(ptr, containing_type, metadata, ctx); + return me->ParseMessageSetItem(ptr, extendee, metadata, ctx); } ExtensionSet* me; - const Msg* containing_type; + const Msg* extendee; InternalMetadata* metadata; - } item{this, containing_type, metadata}; + } item{this, extendee, metadata}; while (!ctx->Done(&ptr)) { - uint32 tag; + uint32_t tag; ptr = ReadTag(ptr, &tag); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); if (tag == WireFormatLite::kMessageSetItemStartTag) { @@ -430,7 +435,7 @@ ctx->SetLastTag(tag); return ptr; } - ptr = ParseField(tag, ptr, containing_type, metadata, ctx); + ptr = ParseField(tag, ptr, extendee, metadata, ctx); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); } } @@ -448,21 +453,21 @@ // Specific versions for lite or full messages (constructs the appropriate // FieldSkipper automatically). - bool ParseMessageSet(io::CodedInputStream* input, - const MessageLite* containing_type, + bool ParseMessageSet(io::CodedInputStream* input, const MessageLite* extendee, std::string* unknown_fields); - bool ParseMessageSet(io::CodedInputStream* input, - const Message* containing_type, + bool ParseMessageSet(io::CodedInputStream* input, const Message* extendee, UnknownFieldSet* unknown_fields); // Write all extension fields with field numbers in the range // [start_field_number, end_field_number) // to the output stream, using the cached sizes computed when ByteSize() was // last called. Note that the range bounds are inclusive-exclusive. - void SerializeWithCachedSizes(int start_field_number, int end_field_number, + void SerializeWithCachedSizes(const MessageLite* extendee, + int start_field_number, int end_field_number, io::CodedOutputStream* output) const { - output->SetCur(_InternalSerialize(start_field_number, end_field_number, - output->Cur(), output->EpsCopy())); + output->SetCur(_InternalSerialize(extendee, start_field_number, + end_field_number, output->Cur(), + output->EpsCopy())); } // Same as SerializeWithCachedSizes, but without any bounds checking. @@ -470,32 +475,37 @@ // serialized extensions. // // Returns a pointer past the last written byte. - uint8* _InternalSerialize(int start_field_number, int end_field_number, - uint8* target, - io::EpsCopyOutputStream* stream) const { + + uint8_t* _InternalSerialize(const MessageLite* extendee, + int start_field_number, int end_field_number, + uint8_t* target, + io::EpsCopyOutputStream* stream) const { if (flat_size_ == 0) { assert(!is_large()); return target; } - return _InternalSerializeImpl(start_field_number, end_field_number, target, - stream); + return _InternalSerializeImpl(extendee, start_field_number, + end_field_number, target, stream); } // Like above but serializes in MessageSet format. - void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const { + void SerializeMessageSetWithCachedSizes(const MessageLite* extendee, + io::CodedOutputStream* output) const { output->SetCur(InternalSerializeMessageSetWithCachedSizesToArray( - output->Cur(), output->EpsCopy())); + extendee, output->Cur(), output->EpsCopy())); } - uint8* InternalSerializeMessageSetWithCachedSizesToArray( - uint8* target, io::EpsCopyOutputStream* stream) const; + uint8_t* InternalSerializeMessageSetWithCachedSizesToArray( + const MessageLite* extendee, uint8_t* target, + io::EpsCopyOutputStream* stream) const; // For backward-compatibility, versions of two of the above methods that // serialize deterministically iff SetDefaultSerializationDeterministic() // has been called. - uint8* SerializeWithCachedSizesToArray(int start_field_number, - int end_field_number, - uint8* target) const; - uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const; + uint8_t* SerializeWithCachedSizesToArray(int start_field_number, + int end_field_number, + uint8_t* target) const; + uint8_t* SerializeMessageSetWithCachedSizesToArray( + const MessageLite* extendee, uint8_t* target) const; // Returns the total serialized size of all the extensions. size_t ByteSize() const; @@ -520,10 +530,40 @@ int SpaceUsedExcludingSelf() const; private: + template <typename Type> + friend class PrimitiveTypeTraits; + + template <typename Type> + friend class RepeatedPrimitiveTypeTraits; + + template <typename Type, bool IsValid(int)> + friend class EnumTypeTraits; + + template <typename Type, bool IsValid(int)> + friend class RepeatedEnumTypeTraits; + + const int32_t& GetRefInt32(int number, const int32_t& default_value) const; + const int64_t& GetRefInt64(int number, const int64_t& default_value) const; + const uint32_t& GetRefUInt32(int number, const uint32_t& default_value) const; + const uint64_t& GetRefUInt64(int number, const uint64_t& default_value) const; + const float& GetRefFloat(int number, const float& default_value) const; + const double& GetRefDouble(int number, const double& default_value) const; + const bool& GetRefBool(int number, const bool& default_value) const; + const int& GetRefEnum(int number, const int& default_value) const; + const int32_t& GetRefRepeatedInt32(int number, int index) const; + const int64_t& GetRefRepeatedInt64(int number, int index) const; + const uint32_t& GetRefRepeatedUInt32(int number, int index) const; + const uint64_t& GetRefRepeatedUInt64(int number, int index) const; + const float& GetRefRepeatedFloat(int number, int index) const; + const double& GetRefRepeatedDouble(int number, int index) const; + const bool& GetRefRepeatedBool(int number, int index) const; + const int& GetRefRepeatedEnum(int number, int index) const; + // Implementation of _InternalSerialize for non-empty map_. - uint8* _InternalSerializeImpl(int start_field_number, int end_field_number, - uint8* target, - io::EpsCopyOutputStream* stream) const; + uint8_t* _InternalSerializeImpl(const MessageLite* extendee, + int start_field_number, int end_field_number, + uint8_t* target, + io::EpsCopyOutputStream* stream) const; // Interface of a lazily parsed singular message extension. class PROTOBUF_EXPORT LazyMessageExtension { public: @@ -554,8 +594,9 @@ virtual bool ReadMessage(const MessageLite& prototype, io::CodedInputStream* input) = 0; virtual const char* _InternalParse(const char* ptr, ParseContext* ctx) = 0; - virtual uint8* WriteMessageToArray( - int number, uint8* target, io::EpsCopyOutputStream* stream) const = 0; + virtual uint8_t* WriteMessageToArray( + const MessageLite* prototype, int number, uint8_t* target, + io::EpsCopyOutputStream* stream) const = 0; private: virtual void UnusedKeyMethod(); // Dummy key method to avoid weak vtable. @@ -566,10 +607,10 @@ // The order of these fields packs Extension into 24 bytes when using 8 // byte alignment. Consider this when adding or removing fields here. union { - int32 int32_value; - int64 int64_value; - uint32 uint32_value; - uint64 uint64_value; + int32_t int32_t_value; + int64_t int64_t_value; + uint32_t uint32_t_value; + uint64_t uint64_t_value; float float_value; double double_value; bool bool_value; @@ -578,10 +619,10 @@ MessageLite* message_value; LazyMessageExtension* lazymessage_value; - RepeatedField<int32>* repeated_int32_value; - RepeatedField<int64>* repeated_int64_value; - RepeatedField<uint32>* repeated_uint32_value; - RepeatedField<uint64>* repeated_uint64_value; + RepeatedField<int32_t>* repeated_int32_t_value; + RepeatedField<int64_t>* repeated_int64_t_value; + RepeatedField<uint32_t>* repeated_uint32_t_value; + RepeatedField<uint64_t>* repeated_uint64_t_value; RepeatedField<float>* repeated_float_value; RepeatedField<double>* repeated_double_value; RepeatedField<bool>* repeated_bool_value; @@ -622,10 +663,12 @@ const FieldDescriptor* descriptor; // Some helper methods for operations on a single Extension. - uint8* InternalSerializeFieldWithCachedSizesToArray( - int number, uint8* target, io::EpsCopyOutputStream* stream) const; - uint8* InternalSerializeMessageSetItemWithCachedSizesToArray( - int number, uint8* target, io::EpsCopyOutputStream* stream) const; + uint8_t* InternalSerializeFieldWithCachedSizesToArray( + const MessageLite* extendee, const ExtensionSet* extension_set, + int number, uint8_t* target, io::EpsCopyOutputStream* stream) const; + uint8_t* InternalSerializeMessageSetItemWithCachedSizesToArray( + const MessageLite* extendee, const ExtensionSet* extension_set, + int number, uint8_t* target, io::EpsCopyOutputStream* stream) const; size_t ByteSize(int number) const; size_t MessageSetItemByteSize(int number) const; void Clear(); @@ -678,8 +721,8 @@ // Grows the flat_capacity_. // If flat_capacity_ > kMaximumFlatCapacity, converts to LargeMap. void GrowCapacity(size_t minimum_new_capacity); - static constexpr uint16 kMaximumFlatCapacity = 256; - bool is_large() const { return flat_capacity_ > kMaximumFlatCapacity; } + static constexpr uint16_t kMaximumFlatCapacity = 256; + bool is_large() const { return static_cast<int16_t>(flat_size_) < 0; } // Removes a key from the ExtensionSet. void Erase(int key); @@ -723,7 +766,7 @@ // Note to support packed repeated field compatibility, it also fills whether // the tag on wire is packed, which can be different from // extension->is_packed (whether packed=true is specified). - bool FindExtensionInfoFromTag(uint32 tag, ExtensionFinder* extension_finder, + bool FindExtensionInfoFromTag(uint32_t tag, ExtensionFinder* extension_finder, int* field_number, ExtensionInfo* extension, bool* was_packed_on_wire); @@ -734,7 +777,12 @@ bool FindExtensionInfoFromFieldNumber(int wire_type, int field_number, ExtensionFinder* extension_finder, ExtensionInfo* extension, - bool* was_packed_on_wire); + bool* was_packed_on_wire) const; + + // Find the prototype for a LazyMessage from the extension registry. Returns + // null if the extension is not found. + const MessageLite* GetPrototypeForLazyMessage(const MessageLite* extendee, + int number) const; // Parses a single extension from the input. The input should start out // positioned immediately after the wire tag. This method is called in @@ -772,36 +820,33 @@ ExtensionFinder* extension_finder, MessageSetFieldSkipper* field_skipper); - bool FindExtension(int wire_type, uint32 field, - const MessageLite* containing_type, + bool FindExtension(int wire_type, uint32_t field, const MessageLite* extendee, const internal::ParseContext* /*ctx*/, ExtensionInfo* extension, bool* was_packed_on_wire) { - GeneratedExtensionFinder finder(containing_type); + GeneratedExtensionFinder finder(extendee); return FindExtensionInfoFromFieldNumber(wire_type, field, &finder, extension, was_packed_on_wire); } - inline bool FindExtension(int wire_type, uint32 field, - const Message* containing_type, + inline bool FindExtension(int wire_type, uint32_t field, + const Message* extendee, const internal::ParseContext* ctx, ExtensionInfo* extension, bool* was_packed_on_wire); // Used for MessageSet only - const char* ParseFieldMaybeLazily(uint64 tag, const char* ptr, - const MessageLite* containing_type, + const char* ParseFieldMaybeLazily(uint64_t tag, const char* ptr, + const MessageLite* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx) { // Lite MessageSet doesn't implement lazy. - return ParseField(tag, ptr, containing_type, metadata, ctx); + return ParseField(tag, ptr, extendee, metadata, ctx); } - const char* ParseFieldMaybeLazily(uint64 tag, const char* ptr, - const Message* containing_type, + const char* ParseFieldMaybeLazily(uint64_t tag, const char* ptr, + const Message* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx); - const char* ParseMessageSetItem(const char* ptr, - const MessageLite* containing_type, + const char* ParseMessageSetItem(const char* ptr, const MessageLite* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx); - const char* ParseMessageSetItem(const char* ptr, - const Message* containing_type, + const char* ParseMessageSetItem(const char* ptr, const Message* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx); @@ -813,8 +858,7 @@ const char* ptr, internal::ParseContext* ctx); template <typename Msg, typename T> - const char* ParseMessageSetItemTmpl(const char* ptr, - const Msg* containing_type, + const char* ParseMessageSetItemTmpl(const char* ptr, const Msg* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx); @@ -850,8 +894,8 @@ // Manual memory-management: // map_.flat is an allocated array of flat_capacity_ elements. // [map_.flat, map_.flat + flat_size_) is the currently-in-use prefix. - uint16 flat_capacity_; - uint16 flat_size_; + uint16_t flat_capacity_; + uint16_t flat_size_; // negative int16_t(flat_size_) indicates is_large() union AllocatedData { KeyValue* flat; @@ -860,7 +904,7 @@ LargeMap* large; } map_; - static void DeleteFlatMap(const KeyValue* flat, uint16 flat_capacity); + static void DeleteFlatMap(const KeyValue* flat, uint16_t flat_capacity); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet); }; @@ -937,7 +981,7 @@ // For example, if "foo" is an extension of type "optional int32", then if you // try to write code like: // my_message.MutableExtension(foo) -// you will get a compile error because PrimitiveTypeTraits<int32> does not +// you will get a compile error because PrimitiveTypeTraits<int32_t> does not // have a "Mutable()" method. // ------------------------------------------------------------------- @@ -955,6 +999,9 @@ static inline ConstType Get(int number, const ExtensionSet& set, ConstType default_value); + + static inline const ConstType* GetPtr(int number, const ExtensionSet& set, + const ConstType& default_value); static inline void Set(int number, FieldType field_type, ConstType value, ExtensionSet* set); template <typename ExtendeeT> @@ -974,6 +1021,10 @@ typedef RepeatedField<Type> RepeatedFieldType; static inline Type Get(int number, const ExtensionSet& set, int index); + static inline const Type* GetPtr(int number, const ExtensionSet& set, + int index); + static inline const RepeatedField<ConstType>* GetRepeatedPtr( + int number, const ExtensionSet& set); static inline void Set(int number, int index, Type value, ExtensionSet* set); static inline void Add(int number, FieldType field_type, bool is_packed, Type value, ExtensionSet* set); @@ -998,10 +1049,10 @@ template <typename Type> friend class RepeatedPrimitiveTypeTraits; static const RepeatedPrimitiveDefaults* default_instance(); - RepeatedField<int32> default_repeated_field_int32_; - RepeatedField<int64> default_repeated_field_int64_; - RepeatedField<uint32> default_repeated_field_uint32_; - RepeatedField<uint64> default_repeated_field_uint64_; + RepeatedField<int32_t> default_repeated_field_int32_t_; + RepeatedField<int64_t> default_repeated_field_int64_t_; + RepeatedField<uint32_t> default_repeated_field_uint32_t_; + RepeatedField<uint64_t> default_repeated_field_uint64_t_; RepeatedField<double> default_repeated_field_double_; RepeatedField<float> default_repeated_field_float_; RepeatedField<bool> default_repeated_field_bool_; @@ -1014,6 +1065,11 @@ return set.Get##METHOD(number, default_value); \ } \ template <> \ + inline const TYPE* PrimitiveTypeTraits<TYPE>::GetPtr( \ + int number, const ExtensionSet& set, const TYPE& default_value) { \ + return &set.GetRef##METHOD(number, default_value); \ + } \ + template <> \ inline void PrimitiveTypeTraits<TYPE>::Set(int number, FieldType field_type, \ TYPE value, ExtensionSet* set) { \ set->Set##METHOD(number, field_type, value, NULL); \ @@ -1025,6 +1081,11 @@ return set.GetRepeated##METHOD(number, index); \ } \ template <> \ + inline const TYPE* RepeatedPrimitiveTypeTraits<TYPE>::GetPtr( \ + int number, const ExtensionSet& set, int index) { \ + return &set.GetRefRepeated##METHOD(number, index); \ + } \ + template <> \ inline void RepeatedPrimitiveTypeTraits<TYPE>::Set( \ int number, int index, TYPE value, ExtensionSet* set) { \ set->SetRepeated##METHOD(number, index, value); \ @@ -1049,6 +1110,12 @@ set.GetRawRepeatedField(number, GetDefaultRepeatedField())); \ } \ template <> \ + inline const RepeatedField<TYPE>* \ + RepeatedPrimitiveTypeTraits<TYPE>::GetRepeatedPtr(int number, \ + const ExtensionSet& set) { \ + return &GetRepeated(number, set); \ + } \ + template <> \ inline RepeatedField<TYPE>* \ RepeatedPrimitiveTypeTraits<TYPE>::MutableRepeated( \ int number, FieldType field_type, bool is_packed, ExtensionSet* set) { \ @@ -1056,10 +1123,10 @@ set->MutableRawRepeatedField(number, field_type, is_packed, NULL)); \ } -PROTOBUF_DEFINE_PRIMITIVE_TYPE(int32, Int32) -PROTOBUF_DEFINE_PRIMITIVE_TYPE(int64, Int64) -PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32) -PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(int32_t, Int32) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(int64_t, Int64) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32_t, UInt32) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64_t, UInt64) PROTOBUF_DEFINE_PRIMITIVE_TYPE(float, Float) PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double) PROTOBUF_DEFINE_PRIMITIVE_TYPE(bool, Bool) @@ -1080,6 +1147,10 @@ ConstType default_value) { return set.GetString(number, default_value); } + static inline const std::string* GetPtr(int number, const ExtensionSet& set, + ConstType default_value) { + return &Get(number, set, default_value); + } static inline void Set(int number, FieldType field_type, const std::string& value, ExtensionSet* set) { set->SetString(number, field_type, value, NULL); @@ -1107,6 +1178,14 @@ int index) { return set.GetRepeatedString(number, index); } + static inline const std::string* GetPtr(int number, const ExtensionSet& set, + int index) { + return &Get(number, set, index); + } + static inline const RepeatedPtrField<std::string>* GetRepeatedPtr( + int number, const ExtensionSet& set) { + return &GetRepeated(number, set); + } static inline void Set(int number, int index, const std::string& value, ExtensionSet* set) { set->SetRepeatedString(number, index, value); @@ -1163,6 +1242,11 @@ ConstType default_value) { return static_cast<Type>(set.GetEnum(number, default_value)); } + static inline const ConstType* GetPtr(int number, const ExtensionSet& set, + const ConstType& default_value) { + return reinterpret_cast<const Type*>( + &set.GetRefEnum(number, default_value)); + } static inline void Set(int number, FieldType field_type, ConstType value, ExtensionSet* set) { GOOGLE_DCHECK(IsValid(value)); @@ -1187,6 +1271,11 @@ static inline ConstType Get(int number, const ExtensionSet& set, int index) { return static_cast<Type>(set.GetRepeatedEnum(number, index)); } + static inline const ConstType* GetPtr(int number, const ExtensionSet& set, + int index) { + return reinterpret_cast<const Type*>( + &set.GetRefRepeatedEnum(number, index)); + } static inline void Set(int number, int index, ConstType value, ExtensionSet* set) { GOOGLE_DCHECK(IsValid(value)); @@ -1206,7 +1295,10 @@ return *reinterpret_cast<const RepeatedField<Type>*>( set.GetRawRepeatedField(number, GetDefaultRepeatedField())); } - + static inline const RepeatedField<Type>* GetRepeatedPtr( + int number, const ExtensionSet& set) { + return &GetRepeated(number, set); + } static inline RepeatedField<Type>* MutableRepeated(int number, FieldType field_type, bool is_packed, @@ -1220,10 +1312,10 @@ // RepeatedField<int>. We need to be able to instantiate global static // objects to return as default (empty) repeated fields on non-existent // extensions. We would not be able to know a-priori all of the enum types - // (values of |Type|) to instantiate all of these, so we just re-use int32's - // default repeated field object. + // (values of |Type|) to instantiate all of these, so we just re-use + // int32_t's default repeated field object. return reinterpret_cast<const RepeatedField<Type>*>( - RepeatedPrimitiveTypeTraits<int32>::GetDefaultRepeatedField()); + RepeatedPrimitiveTypeTraits<int32_t>::GetDefaultRepeatedField()); } template <typename ExtendeeT> static void Register(int number, FieldType type, bool is_packed) { @@ -1249,6 +1341,11 @@ ConstType default_value) { return static_cast<const Type&>(set.GetMessage(number, default_value)); } + static inline std::nullptr_t GetPtr(int number, const ExtensionSet& set, + ConstType default_value) { + // Cannot be implemented because of forward declared messages? + return nullptr; + } static inline MutableType Mutable(int number, FieldType field_type, ExtensionSet* set) { return static_cast<Type*>(set->MutableMessage( @@ -1282,7 +1379,7 @@ } }; -// forward declaration +// forward declaration. class RepeatedMessageGenericTypeTraits; template <typename Type> @@ -1297,6 +1394,16 @@ static inline ConstType Get(int number, const ExtensionSet& set, int index) { return static_cast<const Type&>(set.GetRepeatedMessage(number, index)); } + static inline std::nullptr_t GetPtr(int number, const ExtensionSet& set, + int index) { + // Cannot be implemented because of forward declared messages? + return nullptr; + } + static inline std::nullptr_t GetRepeatedPtr(int number, + const ExtensionSet& set) { + // Cannot be implemented because of forward declared messages? + return nullptr; + } static inline MutableType Mutable(int number, int index, ExtensionSet* set) { return static_cast<Type*>(set->MutableRepeatedMessage(number, index)); } @@ -1347,7 +1454,7 @@ // optional int32 bar = 1234; // } // then "bar" will be defined in C++ as: -// ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32>, 5, false> bar(1234); +// ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32_t>, 5, false> bar(1234); // // Note that we could, in theory, supply the field number as a template // parameter, and thus make an instance of ExtensionIdentifier have no @@ -1378,6 +1485,10 @@ TypeTraits::template Register<ExtendeeType>(number, field_type, is_packed); } + typename TypeTraits::ConstType const& default_value_ref() const { + return default_value_; + } + private: const int number_; typename TypeTraits::ConstType default_value_; @@ -1386,190 +1497,6 @@ // ------------------------------------------------------------------- // Generated accessors -// This macro should be expanded in the context of a generated type which -// has extensions. -// -// We use "_proto_TypeTraits" as a type name below because "TypeTraits" -// causes problems if the class has a nested message or enum type with that -// name and "_TypeTraits" is technically reserved for the C++ library since -// it starts with an underscore followed by a capital letter. -// -// For similar reason, we use "_field_type" and "_is_packed" as parameter names -// below, so that "field_type" and "is_packed" can be used as field names. -#define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME) \ - /* Has, Size, Clear */ \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline bool HasExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \ - return _extensions_.Has(id.number()); \ - } \ - \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline void ClearExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ - _extensions_.ClearExtension(id.number()); \ - } \ - \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline int ExtensionSize( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \ - return _extensions_.ExtensionSize(id.number()); \ - } \ - \ - /* Singular accessors */ \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline typename _proto_TypeTraits::Singular::ConstType GetExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \ - return _proto_TypeTraits::Get(id.number(), _extensions_, \ - id.default_value()); \ - } \ - \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ - return _proto_TypeTraits::Mutable(id.number(), _field_type, \ - &_extensions_); \ - } \ - \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline void SetExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ - typename _proto_TypeTraits::Singular::ConstType value) { \ - _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); \ - } \ - \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline void SetAllocatedExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ - typename _proto_TypeTraits::Singular::MutableType value) { \ - _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, \ - &_extensions_); \ - } \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline void UnsafeArenaSetAllocatedExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ - typename _proto_TypeTraits::Singular::MutableType value) { \ - _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, \ - value, &_extensions_); \ - } \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline PROTOBUF_MUST_USE_RESULT \ - typename _proto_TypeTraits::Singular::MutableType \ - ReleaseExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ - return _proto_TypeTraits::Release(id.number(), _field_type, \ - &_extensions_); \ - } \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline typename _proto_TypeTraits::Singular::MutableType \ - UnsafeArenaReleaseExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ - return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, \ - &_extensions_); \ - } \ - \ - /* Repeated accessors */ \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ - int index) const { \ - return _proto_TypeTraits::Get(id.number(), _extensions_, index); \ - } \ - \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ - int index) { \ - return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); \ - } \ - \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline void SetExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ - int index, typename _proto_TypeTraits::Repeated::ConstType value) { \ - _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); \ - } \ - \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ - return _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); \ - } \ - \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline void AddExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ - typename _proto_TypeTraits::Repeated::ConstType value) { \ - _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, \ - &_extensions_); \ - } \ - \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& \ - GetRepeatedExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \ - return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); \ - } \ - \ - template <typename _proto_TypeTraits, \ - ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \ - bool _is_packed> \ - inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* \ - MutableRepeatedExtension( \ - const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< \ - CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ - return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, \ - _is_packed, &_extensions_); \ - } - } // namespace internal // Call this function to ensure that this extensions's reflection is linked into
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index 76ac076..375be1e 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc
@@ -35,8 +35,6 @@ // Contains methods defined in extension_set.h which cannot be part of the // lite library because they use descriptors or reflection. -#include <google/protobuf/extension_set.h> - #include <google/protobuf/stubs/casts.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/extension_set_inl.h> @@ -44,7 +42,9 @@ #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/zero_copy_stream_impl_lite.h> #include <google/protobuf/descriptor.h> +#include <google/protobuf/extension_set.h> #include <google/protobuf/message.h> +#include <google/protobuf/message_lite.h> #include <google/protobuf/repeated_field.h> #include <google/protobuf/unknown_field_set.h> #include <google/protobuf/wire_format.h> @@ -62,16 +62,16 @@ public: explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields) : UnknownFieldSetFieldSkipper(unknown_fields) {} - virtual ~MessageSetFieldSkipper() {} + ~MessageSetFieldSkipper() override {} virtual bool SkipMessageSetField(io::CodedInputStream* input, int field_number); }; bool MessageSetFieldSkipper::SkipMessageSetField(io::CodedInputStream* input, int field_number) { - uint32 length; + uint32_t length; if (!input->ReadVarint32(&length)) return false; - if (unknown_fields_ == NULL) { + if (unknown_fields_ == nullptr) { return input->Skip(length); } else { return input->ReadString(unknown_fields_->AddLengthDelimited(field_number), @@ -116,7 +116,7 @@ // initialized, so they might not even be constructed until // AppendToList() is called. - if (ext.descriptor == NULL) { + if (ext.descriptor == nullptr) { output->push_back(pool->FindExtensionByNumber(containing_type, number)); } else { output->push_back(ext.descriptor); @@ -150,7 +150,7 @@ const Descriptor* message_type, MessageFactory* factory) const { const Extension* extension = FindOrNull(number); - if (extension == NULL || extension->is_cleared) { + if (extension == nullptr || extension->is_cleared) { // Not present. Return the default value. return *factory->GetPrototype(message_type); } else { @@ -193,20 +193,20 @@ MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor, MessageFactory* factory) { Extension* extension = FindOrNull(descriptor->number()); - if (extension == NULL) { + if (extension == nullptr) { // Not present. Return NULL. - return NULL; + return nullptr; } else { GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); - MessageLite* ret = NULL; + MessageLite* ret = nullptr; if (extension->is_lazy) { ret = extension->lazymessage_value->ReleaseMessage( *factory->GetPrototype(descriptor->message_type())); - if (arena_ == NULL) { + if (arena_ == nullptr) { delete extension->lazymessage_value; } } else { - if (arena_ != NULL) { + if (arena_ != nullptr) { ret = extension->message_value->New(); ret->CheckTypeAndMergeFrom(*extension->message_value); } else { @@ -221,16 +221,16 @@ MessageLite* ExtensionSet::UnsafeArenaReleaseMessage( const FieldDescriptor* descriptor, MessageFactory* factory) { Extension* extension = FindOrNull(descriptor->number()); - if (extension == NULL) { + if (extension == nullptr) { // Not present. Return NULL. - return NULL; + return nullptr; } else { GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); - MessageLite* ret = NULL; + MessageLite* ret = nullptr; if (extension->is_lazy) { ret = extension->lazymessage_value->UnsafeArenaReleaseMessage( *factory->GetPrototype(descriptor->message_type())); - if (arena_ == NULL) { + if (arena_ == nullptr) { delete extension->lazymessage_value; } } else { @@ -266,11 +266,11 @@ reinterpret_cast<internal::RepeatedPtrFieldBase*>( extension->repeated_message_value) ->AddFromCleared<GenericTypeHandler<MessageLite> >(); - if (result == NULL) { + if (result == nullptr) { const MessageLite* prototype; - if (extension->repeated_message_value->size() == 0) { + if (extension->repeated_message_value->empty()) { prototype = factory->GetPrototype(descriptor->message_type()); - GOOGLE_CHECK(prototype != NULL); + GOOGLE_CHECK(prototype != nullptr); } else { prototype = &extension->repeated_message_value->Get(0); } @@ -287,15 +287,22 @@ extension->repeated_message_value->AddAllocated(new_entry); } +void ExtensionSet::UnsafeArenaAddAllocatedMessage( + const FieldDescriptor* descriptor, MessageLite* new_entry) { + Extension* extension = MaybeNewRepeatedExtension(descriptor); + + extension->repeated_message_value->UnsafeArenaAddAllocated(new_entry); +} + static bool ValidateEnumUsingDescriptor(const void* arg, int number) { return reinterpret_cast<const EnumDescriptor*>(arg)->FindValueByNumber( - number) != NULL; + number) != nullptr; } bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) { const FieldDescriptor* extension = pool_->FindExtensionByNumber(containing_type_, number); - if (extension == NULL) { + if (extension == nullptr) { return false; } else { output->type = extension->type(); @@ -318,7 +325,7 @@ } -bool ExtensionSet::FindExtension(int wire_type, uint32 field, +bool ExtensionSet::FindExtension(int wire_type, uint32_t field, const Message* containing_type, const internal::ParseContext* ctx, ExtensionInfo* extension, @@ -340,7 +347,7 @@ return true; } -const char* ExtensionSet::ParseField(uint64 tag, const char* ptr, +const char* ExtensionSet::ParseField(uint64_t tag, const char* ptr, const Message* containing_type, internal::InternalMetadata* metadata, internal::ParseContext* ctx) { @@ -357,7 +364,7 @@ } const char* ExtensionSet::ParseFieldMaybeLazily( - uint64 tag, const char* ptr, const Message* containing_type, + uint64_t tag, const char* ptr, const Message* containing_type, internal::InternalMetadata* metadata, internal::ParseContext* ctx) { return ParseField(tag, ptr, containing_type, metadata, ctx); } @@ -369,11 +376,11 @@ metadata, ctx); } -bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, +bool ExtensionSet::ParseField(uint32_t tag, io::CodedInputStream* input, const Message* containing_type, UnknownFieldSet* unknown_fields) { UnknownFieldSetFieldSkipper skipper(unknown_fields); - if (input->GetExtensionPool() == NULL) { + if (input->GetExtensionPool() == nullptr) { GeneratedExtensionFinder finder(containing_type); return ParseField(tag, input, &finder, &skipper); } else { @@ -388,7 +395,7 @@ const Message* containing_type, UnknownFieldSet* unknown_fields) { MessageSetFieldSkipper skipper(unknown_fields); - if (input->GetExtensionPool() == NULL) { + if (input->GetExtensionPool() == nullptr) { GeneratedExtensionFinder finder(containing_type); return ParseMessageSet(input, &finder, &skipper); } else { @@ -426,10 +433,10 @@ repeated_##LOWERCASE##_value->SpaceUsedExcludingSelfLong(); \ break - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(BOOL, bool); @@ -469,12 +476,13 @@ return total_size; } -uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray( - uint8* target) const { +uint8_t* ExtensionSet::SerializeMessageSetWithCachedSizesToArray( + const MessageLite* extendee, uint8_t* target) const { io::EpsCopyOutputStream stream( target, MessageSetByteSize(), io::CodedOutputStream::IsDefaultSerializationDeterministic()); - return InternalSerializeMessageSetWithCachedSizesToArray(target, &stream); + return InternalSerializeMessageSetWithCachedSizesToArray(extendee, target, + &stream); } bool ExtensionSet::ParseFieldMaybeLazily( @@ -490,7 +498,7 @@ ExtensionFinder* extension_finder, MessageSetFieldSkipper* field_skipper) { while (true) { - const uint32 tag = input->ReadTag(); + const uint32_t tag = input->ReadTag(); switch (tag) { case 0: return true; @@ -518,7 +526,7 @@ extension_finder, field_skipper); } - bool SkipField(uint32 tag, io::CodedInputStream* input) { + bool SkipField(uint32_t tag, io::CodedInputStream* input) { return field_skipper->SkipField(input, tag); }
diff --git a/src/google/protobuf/extension_set_inl.h b/src/google/protobuf/extension_set_inl.h index 074784b..291990f 100644 --- a/src/google/protobuf/extension_set_inl.h +++ b/src/google/protobuf/extension_set_inl.h
@@ -83,7 +83,7 @@ switch (extension.type) { #define HANDLE_VARINT_TYPE(UPPERCASE, CPP_CAMELCASE) \ case WireFormatLite::TYPE_##UPPERCASE: { \ - uint64 value; \ + uint64_t value; \ ptr = VarintParse(ptr, &value); \ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); \ if (extension.is_repeated) { \ @@ -103,7 +103,7 @@ #undef HANDLE_VARINT_TYPE #define HANDLE_SVARINT_TYPE(UPPERCASE, CPP_CAMELCASE, SIZE) \ case WireFormatLite::TYPE_##UPPERCASE: { \ - uint64 val; \ + uint64_t val; \ ptr = VarintParse(ptr, &val); \ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); \ auto value = WireFormatLite::ZigZagDecode##SIZE(val); \ @@ -132,16 +132,16 @@ } \ } break - HANDLE_FIXED_TYPE(FIXED32, UInt32, uint32); - HANDLE_FIXED_TYPE(FIXED64, UInt64, uint64); - HANDLE_FIXED_TYPE(SFIXED32, Int32, int32); - HANDLE_FIXED_TYPE(SFIXED64, Int64, int64); + HANDLE_FIXED_TYPE(FIXED32, UInt32, uint32_t); + HANDLE_FIXED_TYPE(FIXED64, UInt64, uint64_t); + HANDLE_FIXED_TYPE(SFIXED32, Int32, int32_t); + HANDLE_FIXED_TYPE(SFIXED64, Int64, int64_t); HANDLE_FIXED_TYPE(FLOAT, Float, float); HANDLE_FIXED_TYPE(DOUBLE, Double, double); #undef HANDLE_FIXED_TYPE case WireFormatLite::TYPE_ENUM: { - uint64 val; + uint64_t val; ptr = VarintParse(ptr, &val); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); int value = val; @@ -181,7 +181,7 @@ : MutableMessage(number, WireFormatLite::TYPE_GROUP, *extension.message_info.prototype, extension.descriptor); - uint32 tag = (number << 3) + WireFormatLite::WIRETYPE_START_GROUP; + uint32_t tag = (number << 3) + WireFormatLite::WIRETYPE_START_GROUP; return ctx->ParseGroup(value, ptr, tag); } @@ -203,22 +203,22 @@ template <typename Msg, typename T> const char* ExtensionSet::ParseMessageSetItemTmpl( - const char* ptr, const Msg* containing_type, - internal::InternalMetadata* metadata, internal::ParseContext* ctx) { + const char* ptr, const Msg* extendee, internal::InternalMetadata* metadata, + internal::ParseContext* ctx) { std::string payload; - uint32 type_id = 0; + uint32_t type_id = 0; bool payload_read = false; while (!ctx->Done(&ptr)) { - uint32 tag = static_cast<uint8>(*ptr++); + uint32_t tag = static_cast<uint8_t>(*ptr++); if (tag == WireFormatLite::kMessageSetTypeIdTag) { - uint64 tmp; + uint64_t tmp; ptr = ParseBigVarint(ptr, &tmp); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); type_id = tmp; if (payload_read) { ExtensionInfo extension; bool was_packed_on_wire; - if (!FindExtension(2, type_id, containing_type, ctx, &extension, + if (!FindExtension(2, type_id, extendee, ctx, &extension, &was_packed_on_wire)) { WriteLengthDelimited(type_id, payload, metadata->mutable_unknown_fields<T>()); @@ -245,12 +245,12 @@ } } else if (tag == WireFormatLite::kMessageSetMessageTag) { if (type_id != 0) { - ptr = ParseFieldMaybeLazily(static_cast<uint64>(type_id) * 8 + 2, ptr, - containing_type, metadata, ctx); + ptr = ParseFieldMaybeLazily(static_cast<uint64_t>(type_id) * 8 + 2, ptr, + extendee, metadata, ctx); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr); type_id = 0; } else { - int32 size = ReadSize(&ptr); + int32_t size = ReadSize(&ptr); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); ptr = ctx->ReadString(ptr, size, &payload); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); @@ -262,7 +262,7 @@ ctx->SetLastTag(tag); return ptr; } - ptr = ParseField(tag, ptr, containing_type, metadata, ctx); + ptr = ParseField(tag, ptr, extendee, metadata, ctx); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); } }
diff --git a/src/google/protobuf/field_access_listener.cc b/src/google/protobuf/field_access_listener.cc index 56e175a..52913ce 100644 --- a/src/google/protobuf/field_access_listener.cc +++ b/src/google/protobuf/field_access_listener.cc
@@ -29,24 +29,3 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <google/protobuf/field_access_listener.h> - -#include <google/protobuf/stubs/once.h> - -namespace google { -namespace protobuf { - -internal::once_flag FieldAccessListener::register_once_ = {}; -FieldAccessListener* FieldAccessListener::field_listener_ = nullptr; - -FieldAccessListener* FieldAccessListener::GetListener() { - return field_listener_; -} - -void FieldAccessListener::RegisterListener(FieldAccessListener* listener) { - // TODO(danilak): Add a GOOGLE_DCHECK for message_injector_ to be nullptr and update - // tests. - internal::call_once(register_once_, [&] { field_listener_ = listener; }); -} - -} // namespace protobuf -} // namespace google
diff --git a/src/google/protobuf/field_access_listener.h b/src/google/protobuf/field_access_listener.h index 660ad73..47422e6 100644 --- a/src/google/protobuf/field_access_listener.h +++ b/src/google/protobuf/field_access_listener.h
@@ -32,215 +32,141 @@ #define GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__ #include <cstddef> -#include <functional> -#include <string> -#include <type_traits> -#include <utility> -#include <vector> #include <google/protobuf/stubs/common.h> -#include <google/protobuf/arenastring.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/map.h> -#include <google/protobuf/stubs/once.h> -#include <google/protobuf/repeated_field.h> +#include <google/protobuf/message_lite.h> namespace google { namespace protobuf { -namespace internal { -template <typename T> -struct ResolvedType { - using type = T; + +// A default/no-op implementation of message hooks. +// +// See go/statically-dispatched-message-hooks for details. +template <typename Proto> +struct NoOpAccessListener { + // Number of fields are provided at compile time for the trackers to be able + // to have stack allocated bitmaps for the fields. This is useful for + // performance critical trackers. This is also to avoid cyclic dependencies + // if the number of fields is needed. + static constexpr int kFields = Proto::_kInternalFieldNumber; + // Default constructor is called during the static global initialization of + // the program. + // We provide a pointer to extract the name of the proto not to get cyclic + // dependencies on GetDescriptor() and OnGetMetadata() calls. If you want + // to differentiate the protos during the runtime before the start of the + // program, use this functor to get its name. We either way need it for + // LITE_RUNTIME protos as they don't have descriptors at all. + explicit NoOpAccessListener(StringPiece (*name_extractor)()) {} + // called repeatedly during serialization/deserialization/ByteSize of + // Reflection as: + // AccessListener<MessageT>::OnSerialize(this); + static void OnSerialize(const MessageLite* msg) {} + static void OnDeserialize(const MessageLite* msg) {} + static void OnByteSize(const MessageLite* msg) {} + static void OnMergeFrom(const MessageLite* to, const MessageLite* from) {} + + // NOTE: This function can be called pre-main. Make sure it does not make + // the state of the listener invalid. + static void OnGetMetadata() {} + + // called from accessors as: + // AccessListener<MessageT>::On$operation(this, &field_storage_); + // If you need to override this with type, in your hook implementation + // introduce + // template <int kFieldNum, typename T> + // static void On$operation(const MessageLite* msg, + // const T* field) {} + // And overloads for std::nullptr_t for incomplete types such as Messages, + // Maps. Extract them using reflection if you need. Consequently, second + // argument can be null pointer. + // For an example, see proto_hooks/testing/memory_test_field_listener.h + // And argument template deduction will deduce the type itself without + // changing the generated code. + + // add_<field>(f) + template <int kFieldNum> + static void OnAdd(const MessageLite* msg, const void* field) {} + + // add_<field>() + template <int kFieldNum> + static void OnAddMutable(const MessageLite* msg, const void* field) {} + + // <field>() and <repeated_field>(i) + template <int kFieldNum> + static void OnGet(const MessageLite* msg, const void* field) {} + + // clear_<field>() + template <int kFieldNum> + static void OnClear(const MessageLite* msg, const void* field) {} + + // has_<field>() + template <int kFieldNum> + static void OnHas(const MessageLite* msg, const void* field) {} + + // <repeated_field>() + template <int kFieldNum> + static void OnList(const MessageLite* msg, const void* field) {} + + // mutable_<field>() + template <int kFieldNum> + static void OnMutable(const MessageLite* msg, const void* field) {} + + // mutable_<repeated_field>() + template <int kFieldNum> + static void OnMutableList(const MessageLite* msg, const void* field) {} + + // release_<field>() + template <int kFieldNum> + static void OnRelease(const MessageLite* msg, const void* field) {} + + // set_<field>() and set_<repeated_field>(i) + template <int kFieldNum> + static void OnSet(const MessageLite* msg, const void* field) {} + + // <repeated_field>_size() + template <int kFieldNum> + static void OnSize(const MessageLite* msg, const void* field) {} + + static void OnHasExtension(const MessageLite* msg, int extension_tag, + const void* field) {} + // TODO(b/190614678): Support clear in the proto compiler. + static void OnClearExtension(const MessageLite* msg, int extension_tag, + const void* field) {} + static void OnExtensionSize(const MessageLite* msg, int extension_tag, + const void* field) {} + static void OnGetExtension(const MessageLite* msg, int extension_tag, + const void* field) {} + static void OnMutableExtension(const MessageLite* msg, int extension_tag, + const void* field) {} + static void OnSetExtension(const MessageLite* msg, int extension_tag, + const void* field) {} + static void OnReleaseExtension(const MessageLite* msg, int extension_tag, + const void* field) {} + static void OnAddExtension(const MessageLite* msg, int extension_tag, + const void* field) {} + static void OnAddMutableExtension(const MessageLite* msg, int extension_tag, + const void* field) {} + static void OnListExtension(const MessageLite* msg, int extension_tag, + const void* field) {} + static void OnMutableListExtension(const MessageLite* msg, int extension_tag, + const void* field) {} }; -} // namespace internal -// Tracks the events of field accesses for all protos -// that are built with --inject_field_listener_events. This is a global -// interface which you must implement yourself and register with -// RegisterListener() function. All events consist of Descriptors, -// FieldAccessTypes and the underlying storage for tracking the memory which is -// accessed where possible and makes sense. Users are responsible for the -// implementations to be thread safe. -class FieldAccessListener { - public: - FieldAccessListener() = default; - virtual ~FieldAccessListener() = default; - - // The memory annotations of the proto fields that are touched by the - // accessors. They are returned as if the operation completes. - struct DataAnnotation { - DataAnnotation() = default; - DataAnnotation(const void* other_address, size_t other_size) - : address(other_address), size(other_size) {} - const void* address = nullptr; - size_t size = 0; - }; - using AddressInfo = std::vector<DataAnnotation>; - using AddressInfoExtractor = std::function<AddressInfo()>; - - enum class FieldAccessType { - kAdd, // add_<field>(f) - kAddMutable, // add_<field>() - kGet, // <field>() and <repeated_field>(i) - kClear, // clear_<field>() - kHas, // has_<field>() - kList, // <repeated_field>() - kMutable, // mutable_<field>() - kMutableList, // mutable_<repeated_field>() - kRelease, // release_<field>() - kSet, // set_<field>() and set_<repeated_field>(i) - kSize, // <repeated_field>_size() - }; - - static FieldAccessListener* GetListener(); - - // Registers the field listener, can be called only once, |listener| must - // outlive all proto accesses (in most cases, the lifetime of the program). - static void RegisterListener(FieldAccessListener* listener); - - // All field accessors noted in FieldAccessType have this call. - // |extractor| extracts the address info from the field - virtual void OnFieldAccess(const AddressInfoExtractor& extractor, - const FieldDescriptor* descriptor, - FieldAccessType access_type) = 0; - - // Side effect calls. - virtual void OnDeserializationAccess(const Message* message) = 0; - virtual void OnSerializationAccess(const Message* message) = 0; - virtual void OnReflectionAccess(const Descriptor* descriptor) = 0; - virtual void OnByteSizeAccess(const Message* message) = 0; - // We can probably add more if we need to, like {Merge,Copy}{From}Access. - - // Extracts all the addresses from the underlying fields. - template <typename T> - AddressInfo ExtractFieldInfo(const T* field_value); - - - private: - template <typename T> - AddressInfo ExtractFieldInfoSpecific(const T* field_value, - internal::ResolvedType<T>); - - AddressInfo ExtractFieldInfoSpecific(const Message* field_value, - internal::ResolvedType<Message>); - - AddressInfo ExtractFieldInfoSpecific(const std::string* field_value, - internal::ResolvedType<std::string>); - - AddressInfo ExtractFieldInfoSpecific( - const internal::ArenaStringPtr* field_value, - internal::ResolvedType<internal::ArenaStringPtr>); - - template <typename T> - AddressInfo ExtractFieldInfoSpecific( - const RepeatedField<T>* field_value, - internal::ResolvedType<RepeatedField<T>>); - - template <typename T> - AddressInfo ExtractFieldInfoSpecific( - const RepeatedPtrField<T>* field_value, - internal::ResolvedType<RepeatedPtrField<T>>); - - template <typename K, typename V> - AddressInfo ExtractFieldInfoSpecific(const Map<K, V>* field_value, - internal::ResolvedType<Map<K, V>>); - - static internal::once_flag register_once_; - static FieldAccessListener* field_listener_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldAccessListener); -}; - -template <typename T> -inline FieldAccessListener::AddressInfo FieldAccessListener::ExtractFieldInfo( - const T* field_value) { - return ExtractFieldInfoSpecific(field_value, internal::ResolvedType<T>()); -} - - -template <typename T> -inline FieldAccessListener::AddressInfo -FieldAccessListener::ExtractFieldInfoSpecific(const T* field_value, - internal::ResolvedType<T>) { - static_assert(std::is_trivial<T>::value, - "This overload should be chosen only for trivial types"); - return FieldAccessListener::AddressInfo{FieldAccessListener::DataAnnotation( - static_cast<const void*>(field_value), sizeof(*field_value))}; -} - -inline FieldAccessListener::AddressInfo -FieldAccessListener::ExtractFieldInfoSpecific( - const std::string* field_value, internal::ResolvedType<std::string>) { - return FieldAccessListener::AddressInfo{FieldAccessListener::DataAnnotation( - static_cast<const void*>(field_value->c_str()), field_value->length())}; -} - -inline FieldAccessListener::AddressInfo -FieldAccessListener::ExtractFieldInfoSpecific( - const internal::ArenaStringPtr* field_value, - internal::ResolvedType<internal::ArenaStringPtr>) { - return FieldAccessListener::ExtractFieldInfoSpecific( - field_value->GetPointer(), internal::ResolvedType<std::string>()); -} - -template <typename T> -inline FieldAccessListener::AddressInfo -FieldAccessListener::ExtractFieldInfoSpecific( - const RepeatedField<T>* field_value, - internal::ResolvedType<RepeatedField<T>>) { - // TODO(jianzhouzh): This can cause data races. Synchronize this if needed. - FieldAccessListener::AddressInfo address_info; - address_info.reserve(field_value->size()); - for (int i = 0, ie = field_value->size(); i < ie; ++i) { - auto sub = ExtractFieldInfoSpecific(&field_value->Get(i), - internal::ResolvedType<T>()); - address_info.insert(address_info.end(), sub.begin(), sub.end()); - } - return address_info; -} - -template <typename T> -inline FieldAccessListener::AddressInfo -FieldAccessListener::ExtractFieldInfoSpecific( - const RepeatedPtrField<T>* field_value, - internal::ResolvedType<RepeatedPtrField<T>>) { - FieldAccessListener::AddressInfo address_info; - // TODO(jianzhouzh): This can cause data races. Synchronize this if needed. - address_info.reserve(field_value->size()); - for (int i = 0, ie = field_value->size(); i < ie; ++i) { - auto sub = ExtractFieldInfoSpecific(&field_value->Get(i), - internal::ResolvedType<T>()); - address_info.insert(address_info.end(), sub.begin(), sub.end()); - } - return address_info; -} - -template <typename K, typename V> -inline FieldAccessListener::AddressInfo -FieldAccessListener::ExtractFieldInfoSpecific( - const Map<K, V>* field_value, internal::ResolvedType<Map<K, V>>) { - // TODO(jianzhouzh): This can cause data races. Synchronize this if needed. - FieldAccessListener::AddressInfo address_info; - address_info.reserve(field_value->size()); - for (auto it = field_value->begin(); it != field_value->end(); ++it) { - auto sub_first = - ExtractFieldInfoSpecific(&it->first, internal::ResolvedType<K>()); - auto sub_second = - ExtractFieldInfoSpecific(&it->second, internal::ResolvedType<V>()); - address_info.insert(address_info.end(), sub_first.begin(), sub_first.end()); - address_info.insert(address_info.end(), sub_second.begin(), - sub_second.end()); - } - return address_info; -} - -inline FieldAccessListener::AddressInfo -FieldAccessListener::ExtractFieldInfoSpecific(const Message* field_value, - internal::ResolvedType<Message>) { - // TODO(jianzhouzh): implement and adjust all annotations in the compiler. - return {}; -} } // namespace protobuf } // namespace google +#ifndef REPLACE_PROTO_LISTENER_IMPL +namespace google { +namespace protobuf { +template <class T> +using AccessListener = NoOpAccessListener<T>; +} // namespace protobuf +} // namespace google +#else +// You can put your implementations of hooks/listeners here. +// All hooks are subject to approval by protobuf-team@. + +#endif // !REPLACE_PROTO_LISTENER_IMPL + #endif // GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index d073936..988dd34 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc
@@ -40,10 +40,11 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldMask, paths_), }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(PROTOBUF_NAMESPACE_ID::FieldMask)}, + { 0, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::FieldMask)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -148,28 +149,29 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -213,13 +215,7 @@ paths_.Get(i)); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldMask::_class_data_ = { @@ -228,8 +224,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldMask::GetClassData() const { return &_class_data_; } -void FieldMask::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void FieldMask::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<FieldMask *>(to)->MergeFrom( static_cast<const FieldMask &>(from)); }
diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index 2c690fa..a46011a 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h
@@ -142,7 +142,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const FieldMask& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final;
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index f50352f..a77d04f 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc
@@ -43,6 +43,7 @@ #include <google/protobuf/descriptor.h> #include <google/protobuf/extension_set.h> #include <google/protobuf/generated_message_util.h> +#include <google/protobuf/inlined_string_field.h> #include <google/protobuf/map_field.h> #include <google/protobuf/map_field_inl.h> #include <google/protobuf/stubs/mutex.h> @@ -61,6 +62,7 @@ using google::protobuf::internal::ExtensionSet; using google::protobuf::internal::GenericTypeHandler; using google::protobuf::internal::GetEmptyString; +using google::protobuf::internal::InlinedStringField; using google::protobuf::internal::InternalMetadata; using google::protobuf::internal::LazyField; using google::protobuf::internal::MapFieldBase; @@ -256,6 +258,10 @@ schema_.IsEagerlyVerifiedLazyField(field)); } +bool Reflection::IsInlined(const FieldDescriptor* field) const { + return schema_.IsFieldInlined(field); +} + size_t Reflection::SpaceUsedLong(const Message& message) const { // object_size_ already includes the in-memory representation of each field // in the message, so we only need to account for additional memory used by @@ -277,10 +283,10 @@ .SpaceUsedExcludingSelfLong(); \ break - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(BOOL, bool); @@ -332,6 +338,13 @@ switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { + if (IsInlined(field)) { + const std::string* ptr = + &GetField<InlinedStringField>(message, field).GetNoArena(); + total_size += StringSpaceUsedExcludingSelfLong(*ptr); + break; + } + const std::string* ptr = GetField<ArenaStringPtr>(message, field).GetPointer(); @@ -370,6 +383,71 @@ return total_size; } +namespace { + +template <bool unsafe_shallow_swap> +struct OneofFieldMover { + template <typename FromType, typename ToType> + void operator()(const FieldDescriptor* field, FromType* from, ToType* to) { + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + to->SetInt32(from->GetInt32()); + break; + case FieldDescriptor::CPPTYPE_INT64: + to->SetInt64(from->GetInt64()); + break; + case FieldDescriptor::CPPTYPE_UINT32: + to->SetUint32(from->GetUint32()); + break; + case FieldDescriptor::CPPTYPE_UINT64: + to->SetUint64(from->GetUint64()); + break; + case FieldDescriptor::CPPTYPE_FLOAT: + to->SetFloat(from->GetFloat()); + break; + case FieldDescriptor::CPPTYPE_DOUBLE: + to->SetDouble(from->GetDouble()); + break; + case FieldDescriptor::CPPTYPE_BOOL: + to->SetBool(from->GetBool()); + break; + case FieldDescriptor::CPPTYPE_ENUM: + to->SetEnum(from->GetEnum()); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + if (!unsafe_shallow_swap) { + to->SetMessage(from->GetMessage()); + } else { + to->UnsafeSetMessage(from->UnsafeGetMessage()); + } + break; + case FieldDescriptor::CPPTYPE_STRING: + if (!unsafe_shallow_swap) { + to->SetString(from->GetString()); + break; + } + switch (field->options().ctype()) { + default: + case FieldOptions::STRING: { + to->SetArenaStringPtr(from->GetArenaStringPtr()); + break; + } + } + break; + default: + GOOGLE_LOG(FATAL) << "unimplemented type: " << field->cpp_type(); + } + if (unsafe_shallow_swap) { + // Not clearing oneof case after move may cause unwanted "ClearOneof" + // where the residual message or string value is deleted and causes + // use-after-free (only for unsafe swap). + from->ClearOneofCase(); + } + } +}; + +} // namespace + namespace internal { class SwapFieldHelper { @@ -380,6 +458,14 @@ const FieldDescriptor* field); template <bool unsafe_shallow_swap> + static void SwapInlinedStrings(const Reflection* r, Message* lhs, + Message* rhs, const FieldDescriptor* field); + + template <bool unsafe_shallow_swap> + static void SwapNonInlinedStrings(const Reflection* r, Message* lhs, + Message* rhs, const FieldDescriptor* field); + + template <bool unsafe_shallow_swap> static void SwapStringField(const Reflection* r, Message* lhs, Message* rhs, const FieldDescriptor* field); @@ -421,21 +507,61 @@ } template <bool unsafe_shallow_swap> +void SwapFieldHelper::SwapInlinedStrings(const Reflection* r, Message* lhs, + Message* rhs, + const FieldDescriptor* field) { + // Inlined string field. + Arena* lhs_arena = lhs->GetArenaForAllocation(); + Arena* rhs_arena = rhs->GetArenaForAllocation(); + auto* lhs_string = r->MutableRaw<InlinedStringField>(lhs, field); + auto* rhs_string = r->MutableRaw<InlinedStringField>(rhs, field); + const uint32 index = r->schema_.InlinedStringIndex(field); + uint32* lhs_state = &r->MutableInlinedStringDonatedArray(lhs)[index / 32]; + uint32* rhs_state = &r->MutableInlinedStringDonatedArray(rhs)[index / 32]; + const uint32 mask = ~(static_cast<uint32>(1) << (index % 32)); + if (unsafe_shallow_swap || lhs_arena == rhs_arena) { + lhs_string->Swap(rhs_string, /*default_value=*/nullptr, lhs_arena, + r->IsInlinedStringDonated(*lhs, field), + r->IsInlinedStringDonated(*rhs, field), + /*donating_states=*/lhs_state, rhs_state, mask); + } else { + const std::string temp = lhs_string->Get(); + lhs_string->Set(nullptr, rhs_string->Get(), lhs_arena, + r->IsInlinedStringDonated(*lhs, field), lhs_state, mask); + rhs_string->Set(nullptr, temp, rhs_arena, + r->IsInlinedStringDonated(*rhs, field), rhs_state, mask); + } +} + +template <bool unsafe_shallow_swap> +void SwapFieldHelper::SwapNonInlinedStrings(const Reflection* r, Message* lhs, + Message* rhs, + const FieldDescriptor* field) { + ArenaStringPtr* lhs_string = r->MutableRaw<ArenaStringPtr>(lhs, field); + ArenaStringPtr* rhs_string = r->MutableRaw<ArenaStringPtr>(rhs, field); + if (unsafe_shallow_swap) { + ArenaStringPtr::UnsafeShallowSwap(lhs_string, rhs_string); + } else { + SwapFieldHelper::SwapArenaStringPtr( + r->DefaultRaw<ArenaStringPtr>(field).GetPointer(), // + lhs_string, lhs->GetArenaForAllocation(), // + rhs_string, rhs->GetArenaForAllocation()); + } +} + +template <bool unsafe_shallow_swap> void SwapFieldHelper::SwapStringField(const Reflection* r, Message* lhs, Message* rhs, const FieldDescriptor* field) { switch (field->options().ctype()) { default: case FieldOptions::STRING: { - ArenaStringPtr* lhs_string = r->MutableRaw<ArenaStringPtr>(lhs, field); - ArenaStringPtr* rhs_string = r->MutableRaw<ArenaStringPtr>(rhs, field); - if (unsafe_shallow_swap) { - ArenaStringPtr::UnsafeShallowSwap(lhs_string, rhs_string); + if (r->IsInlined(field)) { + SwapFieldHelper::SwapInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs, + field); } else { - SwapFieldHelper::SwapArenaStringPtr( - r->DefaultRaw<ArenaStringPtr>(field).GetPointer(), // - lhs_string, lhs->GetArenaForAllocation(), // - rhs_string, rhs->GetArenaForAllocation()); + SwapFieldHelper::SwapNonInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs, + field); } break; } @@ -550,10 +676,10 @@ ->Swap(MutableRaw<RepeatedField<TYPE> >(message2, field)); \ break; - SWAP_ARRAYS(INT32, int32); - SWAP_ARRAYS(INT64, int64); - SWAP_ARRAYS(UINT32, uint32); - SWAP_ARRAYS(UINT64, uint64); + SWAP_ARRAYS(INT32, int32_t); + SWAP_ARRAYS(INT64, int64_t); + SWAP_ARRAYS(UINT32, uint32_t); + SWAP_ARRAYS(UINT64, uint64_t); SWAP_ARRAYS(FLOAT, float); SWAP_ARRAYS(DOUBLE, double); SWAP_ARRAYS(BOOL, bool); @@ -580,10 +706,10 @@ *MutableRaw<TYPE>(message2, field)); \ break; - SWAP_VALUES(INT32, int32); - SWAP_VALUES(INT64, int64); - SWAP_VALUES(UINT32, uint32); - SWAP_VALUES(UINT64, uint64); + SWAP_VALUES(INT32, int32_t); + SWAP_VALUES(INT64, int64_t); + SWAP_VALUES(UINT32, uint32_t); + SWAP_VALUES(UINT64, uint64_t); SWAP_VALUES(FLOAT, float); SWAP_VALUES(DOUBLE, double); SWAP_VALUES(BOOL, bool); @@ -607,9 +733,6 @@ void Reflection::UnsafeShallowSwapField(Message* message1, Message* message2, const FieldDescriptor* field) const { - GOOGLE_DCHECK_EQ(message1->GetArenaForAllocation(), - message2->GetArenaForAllocation()); - if (!field->is_repeated()) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { internal::SwapFieldHelper::SwapMessageField<true>(this, message1, @@ -630,10 +753,10 @@ ->InternalSwap(MutableRaw<RepeatedField<TYPE>>(message2, field)); \ break; - SHALLOW_SWAP_ARRAYS(INT32, int32); - SHALLOW_SWAP_ARRAYS(INT64, int64); - SHALLOW_SWAP_ARRAYS(UINT32, uint32); - SHALLOW_SWAP_ARRAYS(UINT64, uint64); + SHALLOW_SWAP_ARRAYS(INT32, int32_t); + SHALLOW_SWAP_ARRAYS(INT64, int64_t); + SHALLOW_SWAP_ARRAYS(UINT32, uint32_t); + SHALLOW_SWAP_ARRAYS(UINT64, uint64_t); SHALLOW_SWAP_ARRAYS(FLOAT, float); SHALLOW_SWAP_ARRAYS(DOUBLE, double); SHALLOW_SWAP_ARRAYS(BOOL, bool); @@ -654,158 +777,130 @@ } } -void Reflection::SwapOneofField(Message* message1, Message* message2, +// Swaps oneof field between lhs and rhs. If unsafe_shallow_swap is true, it +// directly swaps oneof values; otherwise, it may involve copy/delete. Note that +// two messages may have different oneof cases. So, it has to be done in three +// steps (i.e. lhs -> temp, rhs -> lhs, temp -> rhs). +template <bool unsafe_shallow_swap> +void Reflection::SwapOneofField(Message* lhs, Message* rhs, const OneofDescriptor* oneof_descriptor) const { + // Wraps a local variable to temporarily store oneof value. + struct LocalVarWrapper { +#define LOCAL_VAR_ACCESSOR(type, var, name) \ + type Get##name() const { return oneof_val.type_##var; } \ + void Set##name(type v) { oneof_val.type_##var = v; } + + LOCAL_VAR_ACCESSOR(int32_t, int32, Int32); + LOCAL_VAR_ACCESSOR(int64_t, int64, Int64); + LOCAL_VAR_ACCESSOR(uint32_t, uint32, Uint32); + LOCAL_VAR_ACCESSOR(uint64_t, uint64, Uint64); + LOCAL_VAR_ACCESSOR(float, float, Float); + LOCAL_VAR_ACCESSOR(double, double, Double); + LOCAL_VAR_ACCESSOR(bool, bool, Bool); + LOCAL_VAR_ACCESSOR(int, enum, Enum); + LOCAL_VAR_ACCESSOR(Message*, message, Message); + LOCAL_VAR_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr); + const std::string& GetString() const { return string_val; } + void SetString(const std::string& v) { string_val = v; } + Message* UnsafeGetMessage() const { return GetMessage(); } + void UnsafeSetMessage(Message* v) { SetMessage(v); } + void ClearOneofCase() {} + + union { + int32_t type_int32; + int64_t type_int64; + uint32_t type_uint32; + uint64_t type_uint64; + float type_float; + double type_double; + bool type_bool; + int type_enum; + Message* type_message; + internal::ArenaStringPtr type_arena_string_ptr; + } oneof_val; + + // std::string cannot be in union. + std::string string_val; + }; + + // Wraps a message pointer to read and write a field. + struct MessageWrapper { +#define MESSAGE_FIELD_ACCESSOR(type, var, name) \ + type Get##name() const { \ + return reflection->GetField<type>(*message, field); \ + } \ + void Set##name(type v) { reflection->SetField<type>(message, field, v); } + + MESSAGE_FIELD_ACCESSOR(int32_t, int32, Int32); + MESSAGE_FIELD_ACCESSOR(int64_t, int64, Int64); + MESSAGE_FIELD_ACCESSOR(uint32_t, uint32, Uint32); + MESSAGE_FIELD_ACCESSOR(uint64_t, uint64, Uint64); + MESSAGE_FIELD_ACCESSOR(float, float, Float); + MESSAGE_FIELD_ACCESSOR(double, double, Double); + MESSAGE_FIELD_ACCESSOR(bool, bool, Bool); + MESSAGE_FIELD_ACCESSOR(int, enum, Enum); + MESSAGE_FIELD_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr); + std::string GetString() const { + return reflection->GetString(*message, field); + } + void SetString(const std::string& v) { + reflection->SetString(message, field, v); + } + Message* GetMessage() const { + return reflection->ReleaseMessage(message, field); + } + void SetMessage(Message* v) { + reflection->SetAllocatedMessage(message, v, field); + } + Message* UnsafeGetMessage() const { + return reflection->UnsafeArenaReleaseMessage(message, field); + } + void UnsafeSetMessage(Message* v) { + reflection->UnsafeArenaSetAllocatedMessage(message, v, field); + } + void ClearOneofCase() { + *reflection->MutableOneofCase(message, field->containing_oneof()) = 0; + } + + const Reflection* reflection; + Message* message; + const FieldDescriptor* field; + }; + GOOGLE_DCHECK(!oneof_descriptor->is_synthetic()); - uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor); - uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor); + uint32 oneof_case_lhs = GetOneofCase(*lhs, oneof_descriptor); + uint32 oneof_case_rhs = GetOneofCase(*rhs, oneof_descriptor); - int32 temp_int32 = 0; - int64 temp_int64 = 0; - uint32 temp_uint32 = 0; - uint64 temp_uint64 = 0; - float temp_float = 0; - double temp_double = 0; - bool temp_bool = false; - int temp_int = 0; - Message* temp_message = nullptr; - std::string temp_string; - - // Stores message1's oneof field to a temp variable. - const FieldDescriptor* field1 = nullptr; - if (oneof_case1 > 0) { - field1 = descriptor_->FindFieldByNumber(oneof_case1); - // oneof_descriptor->field(oneof_case1); - switch (field1->cpp_type()) { -#define GET_TEMP_VALUE(CPPTYPE, TYPE) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - temp_##TYPE = GetField<TYPE>(*message1, field1); \ - break; - - GET_TEMP_VALUE(INT32, int32); - GET_TEMP_VALUE(INT64, int64); - GET_TEMP_VALUE(UINT32, uint32); - GET_TEMP_VALUE(UINT64, uint64); - GET_TEMP_VALUE(FLOAT, float); - GET_TEMP_VALUE(DOUBLE, double); - GET_TEMP_VALUE(BOOL, bool); - GET_TEMP_VALUE(ENUM, int); -#undef GET_TEMP_VALUE - case FieldDescriptor::CPPTYPE_MESSAGE: - temp_message = ReleaseMessage(message1, field1); - break; - - case FieldDescriptor::CPPTYPE_STRING: - temp_string = GetString(*message1, field1); - break; - - default: - GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type(); - } + LocalVarWrapper temp; + MessageWrapper lhs_wrapper, rhs_wrapper; + const FieldDescriptor* field_lhs = nullptr; + OneofFieldMover<unsafe_shallow_swap> mover; + // lhs --> temp + if (oneof_case_lhs > 0) { + field_lhs = descriptor_->FindFieldByNumber(oneof_case_lhs); + lhs_wrapper = {this, lhs, field_lhs}; + mover(field_lhs, &lhs_wrapper, &temp); + } + // rhs --> lhs + if (oneof_case_rhs > 0) { + const FieldDescriptor* f = descriptor_->FindFieldByNumber(oneof_case_rhs); + lhs_wrapper = {this, lhs, f}; + rhs_wrapper = {this, rhs, f}; + mover(f, &rhs_wrapper, &lhs_wrapper); + } else if (!unsafe_shallow_swap) { + ClearOneof(lhs, oneof_descriptor); + } + // temp --> rhs + if (oneof_case_lhs > 0) { + rhs_wrapper = {this, rhs, field_lhs}; + mover(field_lhs, &temp, &rhs_wrapper); + } else if (!unsafe_shallow_swap) { + ClearOneof(rhs, oneof_descriptor); } - // Sets message1's oneof field from the message2's oneof field. - if (oneof_case2 > 0) { - const FieldDescriptor* field2 = descriptor_->FindFieldByNumber(oneof_case2); - switch (field2->cpp_type()) { -#define SET_ONEOF_VALUE1(CPPTYPE, TYPE) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - SetField<TYPE>(message1, field2, GetField<TYPE>(*message2, field2)); \ - break; - - SET_ONEOF_VALUE1(INT32, int32); - SET_ONEOF_VALUE1(INT64, int64); - SET_ONEOF_VALUE1(UINT32, uint32); - SET_ONEOF_VALUE1(UINT64, uint64); - SET_ONEOF_VALUE1(FLOAT, float); - SET_ONEOF_VALUE1(DOUBLE, double); - SET_ONEOF_VALUE1(BOOL, bool); - SET_ONEOF_VALUE1(ENUM, int); -#undef SET_ONEOF_VALUE1 - case FieldDescriptor::CPPTYPE_MESSAGE: - SetAllocatedMessage(message1, ReleaseMessage(message2, field2), field2); - break; - - case FieldDescriptor::CPPTYPE_STRING: - SetString(message1, field2, GetString(*message2, field2)); - break; - - default: - GOOGLE_LOG(FATAL) << "Unimplemented type: " << field2->cpp_type(); - } - } else { - ClearOneof(message1, oneof_descriptor); - } - - // Sets message2's oneof field from the temp variable. - if (oneof_case1 > 0) { - switch (field1->cpp_type()) { -#define SET_ONEOF_VALUE2(CPPTYPE, TYPE) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - SetField<TYPE>(message2, field1, temp_##TYPE); \ - break; - - SET_ONEOF_VALUE2(INT32, int32); - SET_ONEOF_VALUE2(INT64, int64); - SET_ONEOF_VALUE2(UINT32, uint32); - SET_ONEOF_VALUE2(UINT64, uint64); - SET_ONEOF_VALUE2(FLOAT, float); - SET_ONEOF_VALUE2(DOUBLE, double); - SET_ONEOF_VALUE2(BOOL, bool); - SET_ONEOF_VALUE2(ENUM, int); -#undef SET_ONEOF_VALUE2 - case FieldDescriptor::CPPTYPE_MESSAGE: - SetAllocatedMessage(message2, temp_message, field1); - break; - - case FieldDescriptor::CPPTYPE_STRING: - SetString(message2, field1, temp_string); - break; - - default: - GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type(); - } - } else { - ClearOneof(message2, oneof_descriptor); - } -} - -void Reflection::UnsafeShallowSwapOneofField( - Message* message1, Message* message2, - const OneofDescriptor* oneof_descriptor) const { - GOOGLE_DCHECK_EQ(message1->GetArenaForAllocation(), - message2->GetArenaForAllocation()); - - uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor); - const FieldDescriptor* field1 = - oneof_case1 > 0 ? descriptor_->FindFieldByNumber(oneof_case1) : nullptr; - uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor); - const FieldDescriptor* field2 = - oneof_case2 > 0 ? descriptor_->FindFieldByNumber(oneof_case2) : nullptr; - - if ((field1 != nullptr && - field1->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) || - (field2 != nullptr && - field2->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)) { - // Fallback to SwapOneofField for non-message fields. - SwapOneofField(message1, message2, oneof_descriptor); - return; - } - - Message* temp_message = - oneof_case1 > 0 ? UnsafeArenaReleaseMessage(message1, field1) : nullptr; - - if (oneof_case2 > 0) { - UnsafeArenaSetAllocatedMessage( - message1, UnsafeArenaReleaseMessage(message2, field2), field2); - } else { - ClearOneof(message1, oneof_descriptor); - } - - if (oneof_case1 > 0) { - UnsafeArenaSetAllocatedMessage(message2, temp_message, field1); - } else { - ClearOneof(message2, oneof_descriptor); + if (unsafe_shallow_swap) { + *MutableOneofCase(lhs, oneof_descriptor) = oneof_case_rhs; + *MutableOneofCase(rhs, oneof_descriptor) = oneof_case_lhs; } } @@ -858,6 +953,9 @@ return; } + GOOGLE_DCHECK_EQ(message1->GetOwningArena(), message2->GetOwningArena()); + + // TODO(seongkim): use UnsafeArenaSwap() after some flight miles. for (int i = 0; i <= last_non_weak_field_index_; i++) { const FieldDescriptor* field = descriptor_->field(i); if (schema_.InRealOneof(field)) continue; @@ -868,15 +966,15 @@ for (int i = 0; i < oneof_decl_count; i++) { const OneofDescriptor* oneof = descriptor_->oneof_decl(i); if (!oneof->is_synthetic()) { - SwapOneofField(message1, message2, oneof); + SwapOneofField<false>(message1, message2, oneof); } } // Swapping bits need to happen after swapping fields, because the latter may // depend on the has bit information. if (schema_.HasHasbits()) { - uint32* has_bits1 = MutableHasBits(message1); - uint32* has_bits2 = MutableHasBits(message2); + uint32_t* has_bits1 = MutableHasBits(message1); + uint32_t* has_bits2 = MutableHasBits(message2); int fields_with_has_bits = 0; for (int i = 0; i < descriptor_->field_count(); i++) { @@ -927,6 +1025,9 @@ std::set<int> swapped_oneof; + GOOGLE_DCHECK(!unsafe_shallow_swap || message1->GetArenaForAllocation() == + message2->GetArenaForAllocation()); + for (const auto* field : fields) { CheckInvalidAccess(schema_, field); if (field->is_extension()) { @@ -945,12 +1046,8 @@ continue; } swapped_oneof.insert(oneof_index); - if (unsafe_shallow_swap) { - UnsafeShallowSwapOneofField(message1, message2, - field->containing_oneof()); - } else { - SwapOneofField(message1, message2, field->containing_oneof()); - } + SwapOneofField<unsafe_shallow_swap>(message1, message2, + field->containing_oneof()); } else { // Swap field. if (unsafe_shallow_swap) { @@ -981,6 +1078,13 @@ SwapFieldsImpl<true>(message1, message2, fields); } +void Reflection::UnsafeArenaSwapFields( + Message* lhs, Message* rhs, + const std::vector<const FieldDescriptor*>& fields) const { + GOOGLE_DCHECK_EQ(lhs->GetArenaForAllocation(), rhs->GetArenaForAllocation()); + UnsafeShallowSwapFields(lhs, rhs, fields); +} + // ------------------------------------------------------------------- bool Reflection::HasField(const Message& message, @@ -1000,6 +1104,52 @@ } } +void Reflection::UnsafeArenaSwap(Message* lhs, Message* rhs) const { + if (lhs == rhs) return; + + MutableInternalMetadata(lhs)->InternalSwap(MutableInternalMetadata(rhs)); + + for (int i = 0; i <= last_non_weak_field_index_; i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (schema_.InRealOneof(field)) continue; + if (schema_.IsFieldStripped(field)) continue; + UnsafeShallowSwapField(lhs, rhs, field); + } + const int oneof_decl_count = descriptor_->oneof_decl_count(); + for (int i = 0; i < oneof_decl_count; i++) { + const OneofDescriptor* oneof = descriptor_->oneof_decl(i); + if (!oneof->is_synthetic()) { + SwapOneofField<true>(lhs, rhs, oneof); + } + } + + // Swapping bits need to happen after swapping fields, because the latter may + // depend on the has bit information. + if (schema_.HasHasbits()) { + uint32* lhs_has_bits = MutableHasBits(lhs); + uint32* rhs_has_bits = MutableHasBits(rhs); + + int fields_with_has_bits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->is_repeated() || schema_.InRealOneof(field)) { + continue; + } + fields_with_has_bits++; + } + + int has_bits_size = (fields_with_has_bits + 31) / 32; + + for (int i = 0; i < has_bits_size; i++) { + std::swap(lhs_has_bits[i], rhs_has_bits[i]); + } + } + + if (schema_.HasExtensionSet()) { + MutableExtensionSet(lhs)->InternalSwap(MutableExtensionSet(rhs)); + } +} + int Reflection::FieldSize(const Message& message, const FieldDescriptor* field) const { USAGE_CHECK_MESSAGE_TYPE(FieldSize); @@ -1014,10 +1164,10 @@ case FieldDescriptor::CPPTYPE_##UPPERCASE: \ return GetRaw<RepeatedField<LOWERCASE> >(message, field).size() - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(BOOL, bool); @@ -1068,10 +1218,10 @@ *MutableRaw<TYPE>(message, field) = field->default_value_##TYPE(); \ break; - CLEAR_TYPE(INT32, int32); - CLEAR_TYPE(INT64, int64); - CLEAR_TYPE(UINT32, uint32); - CLEAR_TYPE(UINT64, uint64); + CLEAR_TYPE(INT32, int32_t); + CLEAR_TYPE(INT64, int64_t); + CLEAR_TYPE(UINT32, uint32_t); + CLEAR_TYPE(UINT64, uint64_t); CLEAR_TYPE(FLOAT, float); CLEAR_TYPE(DOUBLE, double); CLEAR_TYPE(BOOL, bool); @@ -1086,6 +1236,12 @@ switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { + if (IsInlined(field)) { + // Currently, string with default value can't be inlined. So we + // don't have to handle default value here. + MutableRaw<InlinedStringField>(message, field)->ClearToEmpty(); + break; + } const std::string* default_ptr = DefaultRaw<ArenaStringPtr>(field).GetPointer(); MutableRaw<ArenaStringPtr>(message, field) @@ -1098,7 +1254,7 @@ } case FieldDescriptor::CPPTYPE_MESSAGE: - if (schema_.HasBitIndex(field) == static_cast<uint32>(-1)) { + if (schema_.HasBitIndex(field) == static_cast<uint32_t>(-1)) { // Proto3 does not have has-bits and we need to set a message field // to nullptr in order to indicate its un-presence. if (message->GetArenaForAllocation() == nullptr) { @@ -1118,10 +1274,10 @@ MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \ break - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(BOOL, bool); @@ -1168,10 +1324,10 @@ MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \ break - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(BOOL, bool); @@ -1228,6 +1384,26 @@ #endif // !PROTOBUF_FORCE_COPY_IN_RELEASE } +Message* Reflection::UnsafeArenaReleaseLast( + Message* message, const FieldDescriptor* field) const { + USAGE_CHECK_ALL(UnsafeArenaReleaseLast, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + return static_cast<Message*>( + MutableExtensionSet(message)->UnsafeArenaReleaseLast(field->number())); + } else { + if (IsMapFieldInApi(field)) { + return MutableRaw<MapFieldBase>(message, field) + ->MutableRepeatedField() + ->UnsafeArenaReleaseLast<GenericTypeHandler<Message>>(); + } else { + return MutableRaw<RepeatedPtrFieldBase>(message, field) + ->UnsafeArenaReleaseLast<GenericTypeHandler<Message>>(); + } + } +} + void Reflection::SwapElements(Message* message, const FieldDescriptor* field, int index1, int index2) const { USAGE_CHECK_MESSAGE_TYPE(Swap); @@ -1244,10 +1420,10 @@ ->SwapElements(index1, index2); \ break - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(BOOL, bool); @@ -1278,10 +1454,10 @@ } }; -bool IsIndexInHasBitSet(const uint32* has_bit_set, uint32 has_bit_index) { +bool IsIndexInHasBitSet(const uint32_t* has_bit_set, uint32_t has_bit_index) { GOOGLE_DCHECK_NE(has_bit_index, ~0u); return ((has_bit_set[has_bit_index / 32] >> (has_bit_index % 32)) & - static_cast<uint32>(1)) != 0; + static_cast<uint32_t>(1)) != 0; } bool CreateUnknownEnumValues(const FileDescriptor* file) { @@ -1310,9 +1486,9 @@ // encapsulation because this function takes a noticeable about of CPU // fleetwide and properly allowing this optimization through public interfaces // seems more trouble than it is worth. - const uint32* const has_bits = + const uint32_t* const has_bits = schema_.HasHasbits() ? GetHasBits(message) : nullptr; - const uint32* const has_bits_indices = schema_.has_bit_indices_; + const uint32_t* const has_bits_indices = schema_.has_bit_indices_; output->reserve(descriptor_->field_count()); const int last_non_weak_field_index = last_non_weak_field_index_; for (int i = 0; i <= last_non_weak_field_index; i++) { @@ -1327,14 +1503,15 @@ } else { const OneofDescriptor* containing_oneof = field->containing_oneof(); if (schema_.InRealOneof(field)) { - const uint32* const oneof_case_array = GetConstPointerAtOffset<uint32>( - &message, schema_.oneof_case_offset_); + const uint32_t* const oneof_case_array = + GetConstPointerAtOffset<uint32_t>(&message, + schema_.oneof_case_offset_); // Equivalent to: HasOneofField(message, field) - if (static_cast<int64>(oneof_case_array[containing_oneof->index()]) == + if (static_cast<int64_t>(oneof_case_array[containing_oneof->index()]) == field->number()) { output->push_back(field); } - } else if (has_bits && has_bits_indices[i] != static_cast<uint32>(-1)) { + } else if (has_bits && has_bits_indices[i] != static_cast<uint32_t>(-1)) { CheckInvalidAccess(schema_, field); // Equivalent to: HasBit(message, field) if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) { @@ -1427,10 +1604,10 @@ } \ } -DEFINE_PRIMITIVE_ACCESSORS(Int32, int32, int32, INT32) -DEFINE_PRIMITIVE_ACCESSORS(Int64, int64, int64, INT64) -DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32) -DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64) +DEFINE_PRIMITIVE_ACCESSORS(Int32, int32_t, int32_t, INT32) +DEFINE_PRIMITIVE_ACCESSORS(Int64, int64_t, int64_t, INT64) +DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32_t, uint32_t, UINT32) +DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64_t, uint64_t, UINT64) DEFINE_PRIMITIVE_ACCESSORS(Float, float, float, FLOAT) DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE) DEFINE_PRIMITIVE_ACCESSORS(Bool, bool, bool, BOOL) @@ -1451,6 +1628,10 @@ switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { + if (IsInlined(field)) { + return GetField<InlinedStringField>(message, field).GetNoArena(); + } + if (auto* value = GetField<ArenaStringPtr>(message, field).GetPointer()) { return *value; @@ -1475,6 +1656,10 @@ switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { + if (IsInlined(field)) { + return GetField<InlinedStringField>(message, field).GetNoArena(); + } + if (auto* value = GetField<ArenaStringPtr>(message, field).GetPointer()) { return *value; @@ -1496,6 +1681,17 @@ switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { + if (IsInlined(field)) { + const uint32_t index = schema_.InlinedStringIndex(field); + uint32_t* states = + &MutableInlinedStringDonatedArray(message)[index / 32]; + uint32_t mask = ~(static_cast<uint32_t>(1) << (index % 32)); + MutableField<InlinedStringField>(message, field) + ->Set(nullptr, value, message->GetArenaForAllocation(), + IsInlinedStringDonated(*message, field), states, mask); + break; + } + // Oneof string fields are never set as a default instance. // We just need to pass some arbitrary default string to make it work. // This allows us to not have the real default accessible from @@ -1599,7 +1795,7 @@ const FieldDescriptor* field) const { USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM); - int32 value; + int32_t value; if (field->is_extension()) { value = GetExtensionSet(message).GetEnum( field->number(), field->default_value_enum()->number()); @@ -1838,6 +2034,7 @@ USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE); CheckInvalidAccess(schema_, field); + if (field->is_extension()) { MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage( field->number(), field->type(), field, sub_message); @@ -1868,10 +2065,8 @@ void Reflection::SetAllocatedMessage(Message* message, Message* sub_message, const FieldDescriptor* field) const { -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT - GOOGLE_DCHECK(sub_message->GetOwningArena() == nullptr || + GOOGLE_DCHECK(sub_message == nullptr || sub_message->GetOwningArena() == nullptr || sub_message->GetOwningArena() == message->GetArenaForAllocation()); -#endif // PROTOBUF_INTERNAL_USE_MUST_USE_RESULT CheckInvalidAccess(schema_, field); // If message and sub-message are in different memory ownership domains @@ -2051,6 +2246,27 @@ } } +void Reflection::UnsafeArenaAddAllocatedMessage(Message* message, + const FieldDescriptor* field, + Message* new_entry) const { + USAGE_CHECK_ALL(UnsafeArenaAddAllocatedMessage, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); + + if (field->is_extension()) { + MutableExtensionSet(message)->UnsafeArenaAddAllocatedMessage(field, + new_entry); + } else { + RepeatedPtrFieldBase* repeated = nullptr; + if (IsMapFieldInApi(field)) { + repeated = + MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField(); + } else { + repeated = MutableRaw<RepeatedPtrFieldBase>(message, field); + } + repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message>>(new_entry); + } +} + void* Reflection::MutableRawRepeatedField(Message* message, const FieldDescriptor* field, FieldDescriptor::CppType cpptype, @@ -2115,7 +2331,7 @@ const FieldDescriptor* field = oneof_descriptor->field(0); return HasField(message, field) ? field : nullptr; } - uint32 field_number = GetOneofCase(message, oneof_descriptor); + uint32_t field_number = GetOneofCase(message, oneof_descriptor); if (field_number == 0) { return nullptr; } @@ -2218,40 +2434,25 @@ } template <typename Type> -const Type& Reflection::GetRaw(const Message& message, - const FieldDescriptor* field) const { - GOOGLE_DCHECK(!schema_.InRealOneof(field) || HasOneofField(message, field)) - << "Field = " << field->full_name(); - return GetConstRefAtOffset<Type>(message, schema_.GetFieldOffset(field)); -} - -template <typename Type> Type* Reflection::MutableRaw(Message* message, const FieldDescriptor* field) const { return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field)); } -const uint32* Reflection::GetHasBits(const Message& message) const { +const uint32_t* Reflection::GetHasBits(const Message& message) const { GOOGLE_DCHECK(schema_.HasHasbits()); - return &GetConstRefAtOffset<uint32>(message, schema_.HasBitsOffset()); + return &GetConstRefAtOffset<uint32_t>(message, schema_.HasBitsOffset()); } -uint32* Reflection::MutableHasBits(Message* message) const { +uint32_t* Reflection::MutableHasBits(Message* message) const { GOOGLE_DCHECK(schema_.HasHasbits()); - return GetPointerAtOffset<uint32>(message, schema_.HasBitsOffset()); + return GetPointerAtOffset<uint32_t>(message, schema_.HasBitsOffset()); } -uint32 Reflection::GetOneofCase(const Message& message, - const OneofDescriptor* oneof_descriptor) const { - GOOGLE_DCHECK(!oneof_descriptor->is_synthetic()); - return GetConstRefAtOffset<uint32>( - message, schema_.GetOneofCaseOffset(oneof_descriptor)); -} - -uint32* Reflection::MutableOneofCase( +uint32_t* Reflection::MutableOneofCase( Message* message, const OneofDescriptor* oneof_descriptor) const { GOOGLE_DCHECK(!oneof_descriptor->is_synthetic()); - return GetPointerAtOffset<uint32>( + return GetPointerAtOffset<uint32_t>( message, schema_.GetOneofCaseOffset(oneof_descriptor)); } @@ -2276,11 +2477,31 @@ schema_.GetMetadataOffset()); } +const uint32_t* Reflection::GetInlinedStringDonatedArray( + const Message& message) const { + GOOGLE_DCHECK(schema_.HasInlinedString()); + return &GetConstRefAtOffset<uint32_t>(message, + schema_.InlinedStringDonatedOffset()); +} + +uint32_t* Reflection::MutableInlinedStringDonatedArray(Message* message) const { + GOOGLE_DCHECK(schema_.HasHasbits()); + return GetPointerAtOffset<uint32_t>(message, + schema_.InlinedStringDonatedOffset()); +} + +// Simple accessors for manipulating _inlined_string_donated_; +bool Reflection::IsInlinedStringDonated(const Message& message, + const FieldDescriptor* field) const { + return IsIndexInHasBitSet(GetInlinedStringDonatedArray(message), + schema_.InlinedStringIndex(field)); +} + // Simple accessors for manipulating has_bits_. bool Reflection::HasBit(const Message& message, const FieldDescriptor* field) const { GOOGLE_DCHECK(!field->options().weak()); - if (schema_.HasBitIndex(field) != static_cast<uint32>(-1)) { + if (schema_.HasBitIndex(field) != static_cast<uint32_t>(-1)) { return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field)); } @@ -2307,6 +2528,12 @@ case FieldDescriptor::CPPTYPE_STRING: switch (field->options().ctype()) { default: { + if (IsInlined(field)) { + return !GetField<InlinedStringField>(message, field) + .GetNoArena() + .empty(); + } + return GetField<ArenaStringPtr>(message, field).Get().size() > 0; } } @@ -2314,13 +2541,13 @@ case FieldDescriptor::CPPTYPE_BOOL: return GetRaw<bool>(message, field) != false; case FieldDescriptor::CPPTYPE_INT32: - return GetRaw<int32>(message, field) != 0; + return GetRaw<int32_t>(message, field) != 0; case FieldDescriptor::CPPTYPE_INT64: - return GetRaw<int64>(message, field) != 0; + return GetRaw<int64_t>(message, field) != 0; case FieldDescriptor::CPPTYPE_UINT32: - return GetRaw<uint32>(message, field) != 0; + return GetRaw<uint32_t>(message, field) != 0; case FieldDescriptor::CPPTYPE_UINT64: - return GetRaw<uint64>(message, field) != 0; + return GetRaw<uint64_t>(message, field) != 0; case FieldDescriptor::CPPTYPE_FLOAT: return GetRaw<float>(message, field) != 0.0; case FieldDescriptor::CPPTYPE_DOUBLE: @@ -2338,19 +2565,19 @@ void Reflection::SetBit(Message* message, const FieldDescriptor* field) const { GOOGLE_DCHECK(!field->options().weak()); - const uint32 index = schema_.HasBitIndex(field); - if (index == static_cast<uint32>(-1)) return; + const uint32_t index = schema_.HasBitIndex(field); + if (index == static_cast<uint32_t>(-1)) return; MutableHasBits(message)[index / 32] |= - (static_cast<uint32>(1) << (index % 32)); + (static_cast<uint32_t>(1) << (index % 32)); } void Reflection::ClearBit(Message* message, const FieldDescriptor* field) const { GOOGLE_DCHECK(!field->options().weak()); - const uint32 index = schema_.HasBitIndex(field); - if (index == static_cast<uint32>(-1)) return; + const uint32_t index = schema_.HasBitIndex(field); + if (index == static_cast<uint32_t>(-1)) return; MutableHasBits(message)[index / 32] &= - ~(static_cast<uint32>(1) << (index % 32)); + ~(static_cast<uint32_t>(1) << (index % 32)); } void Reflection::SwapBit(Message* message1, Message* message2, @@ -2380,12 +2607,6 @@ return (GetOneofCase(message, oneof_descriptor) > 0); } -bool Reflection::HasOneofField(const Message& message, - const FieldDescriptor* field) const { - return (GetOneofCase(message, field->containing_oneof()) == - static_cast<uint32>(field->number())); -} - void Reflection::SetOneofCase(Message* message, const FieldDescriptor* field) const { *MutableOneofCase(message, field->containing_oneof()) = field->number(); @@ -2407,7 +2628,7 @@ // TODO(jieluo): Consider to cache the unused object instead of deleting // it. It will be much faster if an application switches a lot from // a few oneof fields. Time/space tradeoff - uint32 oneof_case = GetOneofCase(*message, oneof_descriptor); + uint32_t oneof_case = GetOneofCase(*message, oneof_descriptor); if (oneof_case > 0) { const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case); if (message->GetArenaForAllocation() == nullptr) { @@ -2455,10 +2676,10 @@ MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \ } -HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1); -HANDLE_TYPE(int64, FieldDescriptor::CPPTYPE_INT64, -1); -HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1); -HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1); +HANDLE_TYPE(int32_t, FieldDescriptor::CPPTYPE_INT32, -1); +HANDLE_TYPE(int64_t, FieldDescriptor::CPPTYPE_INT64, -1); +HANDLE_TYPE(uint32_t, FieldDescriptor::CPPTYPE_UINT32, -1); +HANDLE_TYPE(uint64_t, FieldDescriptor::CPPTYPE_UINT64, -1); HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1); HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1); HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1); @@ -2560,7 +2781,7 @@ cpp_type == FieldDescriptor::CPPTYPE_INT32)) << "The type parameter T in RepeatedFieldRef<T> API doesn't match " << "the actual field type (for enums T should be the generated enum " - << "type or int32)."; + << "type or int32_t)."; if (message_type != nullptr) { GOOGLE_CHECK_EQ(message_type, field->message_type()); } @@ -2590,13 +2811,13 @@ // Helper function to transform migration schema into reflection schema. ReflectionSchema MigrationToReflectionSchema( - const Message* const* default_instance, const uint32* offsets, + const Message* const* default_instance, const uint32_t* offsets, MigrationSchema migration_schema) { ReflectionSchema result; result.default_instance_ = *default_instance; - // First 6 offsets are offsets to the special fields. The following offsets + // First 7 offsets are offsets to the special fields. The following offsets // are the proto fields. - result.offsets_ = offsets + migration_schema.offsets_index + 5; + result.offsets_ = offsets + migration_schema.offsets_index + 6; result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index; result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0]; result.metadata_offset_ = offsets[migration_schema.offsets_index + 1]; @@ -2604,6 +2825,10 @@ result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3]; result.object_size_ = migration_schema.object_size; result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4]; + result.inlined_string_donated_offset_ = + offsets[migration_schema.offsets_index + 5]; + result.inlined_string_indices_ = + offsets + migration_schema.inlined_string_indices_index; return result; } @@ -2616,7 +2841,7 @@ const EnumDescriptor** file_level_enum_descriptors, const MigrationSchema* schemas, const Message* const* default_instance_data, - const uint32* offsets) + const uint32_t* offsets) : factory_(factory), file_level_metadata_(file_level_metadata), file_level_enum_descriptors_(file_level_enum_descriptors), @@ -2657,7 +2882,7 @@ const EnumDescriptor** file_level_enum_descriptors_; const MigrationSchema* schemas_; const Message* const* default_instance_data_; - const uint32* offsets_; + const uint32_t* offsets_; }; namespace { @@ -2818,8 +3043,8 @@ RegisterAllTypesInternal(table->file_level_metadata, table->num_messages); } -void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag, - uint32 has_offset, +void UnknownFieldSetSerializer(const uint8_t* base, uint32_t offset, + uint32_t tag, uint32_t has_offset, io::CodedOutputStream* output) { const void* ptr = base + offset; const InternalMetadata* metadata = static_cast<const InternalMetadata*>(ptr);
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index 1771b474..6a570ff 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h
@@ -107,7 +107,7 @@ // message, or -1 if the message type has no extension // ranges. // oneof_case_offset: Offset in the message of an array of uint32s of -// size descriptor->oneof_decl_count(). Each uint32 +// size descriptor->oneof_decl_count(). Each uint32_t // indicates what field is set for each oneof. // object_size: The size of a message object of this type, as measured // by sizeof(). @@ -119,7 +119,7 @@ struct ReflectionSchema { public: // Size of a google::protobuf::Message object of this type. - uint32 GetObjectSize() const { return static_cast<uint32>(object_size_); } + uint32_t GetObjectSize() const { return static_cast<uint32_t>(object_size_); } bool InRealOneof(const FieldDescriptor* field) const { return field->containing_oneof() && @@ -128,13 +128,13 @@ // Offset of a non-oneof field. Getting a field offset is slightly more // efficient when we know statically that it is not a oneof field. - uint32 GetFieldOffsetNonOneof(const FieldDescriptor* field) const { + uint32_t GetFieldOffsetNonOneof(const FieldDescriptor* field) const { GOOGLE_DCHECK(!InRealOneof(field)); return OffsetValue(offsets_[field->index()], field->type()); } // Offset of any field. - uint32 GetFieldOffset(const FieldDescriptor* field) const { + uint32_t GetFieldOffset(const FieldDescriptor* field) const { if (InRealOneof(field)) { size_t offset = static_cast<size_t>(field->containing_type()->field_count() + @@ -145,42 +145,62 @@ } } - uint32 GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const { - return static_cast<uint32>(oneof_case_offset_) + - static_cast<uint32>(static_cast<size_t>(oneof_descriptor->index()) * - sizeof(uint32)); + bool IsFieldInlined(const FieldDescriptor* field) const { + return Inlined(offsets_[field->index()], field->type()); + } + + uint32_t GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const { + return static_cast<uint32_t>(oneof_case_offset_) + + static_cast<uint32_t>( + static_cast<size_t>(oneof_descriptor->index()) * + sizeof(uint32_t)); } bool HasHasbits() const { return has_bits_offset_ != -1; } // Bit index within the bit array of hasbits. Bit order is low-to-high. - uint32 HasBitIndex(const FieldDescriptor* field) const { - if (has_bits_offset_ == -1) return static_cast<uint32>(-1); + uint32_t HasBitIndex(const FieldDescriptor* field) const { + if (has_bits_offset_ == -1) return static_cast<uint32_t>(-1); GOOGLE_DCHECK(HasHasbits()); return has_bit_indices_[field->index()]; } // Byte offset of the hasbits array. - uint32 HasBitsOffset() const { + uint32_t HasBitsOffset() const { GOOGLE_DCHECK(HasHasbits()); - return static_cast<uint32>(has_bits_offset_); + return static_cast<uint32_t>(has_bits_offset_); + } + + bool HasInlinedString() const { return inlined_string_donated_offset_ != -1; } + + // Bit index within the bit array of _inlined_string_donated_. Bit order is + // low-to-high. + uint32_t InlinedStringIndex(const FieldDescriptor* field) const { + GOOGLE_DCHECK(HasInlinedString()); + return inlined_string_indices_[field->index()]; + } + + // Byte offset of the _inlined_string_donated_ array. + uint32_t InlinedStringDonatedOffset() const { + GOOGLE_DCHECK(HasInlinedString()); + return static_cast<uint32_t>(inlined_string_donated_offset_); } // The offset of the InternalMetadataWithArena member. // For Lite this will actually be an InternalMetadataWithArenaLite. // The schema doesn't contain enough information to distinguish between // these two cases. - uint32 GetMetadataOffset() const { - return static_cast<uint32>(metadata_offset_); + uint32_t GetMetadataOffset() const { + return static_cast<uint32_t>(metadata_offset_); } // Whether this message has an ExtensionSet. bool HasExtensionSet() const { return extensions_offset_ != -1; } // The offset of the ExtensionSet in this message. - uint32 GetExtensionSetOffset() const { + uint32_t GetExtensionSetOffset() const { GOOGLE_DCHECK(HasExtensionSet()); - return static_cast<uint32>(extensions_offset_); + return static_cast<uint32_t>(extensions_offset_); } // The off set of WeakFieldMap when the message contains weak fields. @@ -194,7 +214,7 @@ // Returns a pointer to the default value for this field. The size and type // of the underlying data depends on the field's type. const void* GetFieldDefault(const FieldDescriptor* field) const { - return reinterpret_cast<const uint8*>(default_instance_) + + return reinterpret_cast<const uint8_t*>(default_instance_) + OffsetValue(offsets_[field->index()], field->type()); } @@ -232,23 +252,37 @@ // ReflectionSchema schema = {a, b, c, d, e, ...}; // private: const Message* default_instance_; - const uint32* offsets_; - const uint32* has_bit_indices_; + const uint32_t* offsets_; + const uint32_t* has_bit_indices_; int has_bits_offset_; int metadata_offset_; int extensions_offset_; int oneof_case_offset_; int object_size_; int weak_field_map_offset_; + const uint32_t* inlined_string_indices_; + int inlined_string_donated_offset_; // We tag offset values to provide additional data about fields (such as - // "unused" or "lazy"). - static uint32 OffsetValue(uint32 v, FieldDescriptor::Type type) { - if (type == FieldDescriptor::TYPE_MESSAGE) { + // "unused" or "lazy" or "inlined"). + static uint32_t OffsetValue(uint32_t v, FieldDescriptor::Type type) { + if (type == FieldDescriptor::TYPE_MESSAGE || + type == FieldDescriptor::TYPE_STRING || + type == FieldDescriptor::TYPE_BYTES) { return v & 0x7FFFFFFEu; } return v & 0x7FFFFFFFu; } + + static bool Inlined(uint32_t v, FieldDescriptor::Type type) { + if (type == FieldDescriptor::TYPE_STRING || + type == FieldDescriptor::TYPE_BYTES) { + return (v & 1u) != 0u; + } else { + // Non string/byte fields are not inlined. + return false; + } + } }; // Structs that the code generator emits directly to describe a message. @@ -258,8 +292,9 @@ // EXPERIMENTAL: these are changing rapidly, and may completely disappear // or merge with ReflectionSchema. struct MigrationSchema { - int32 offsets_index; - int32 has_bit_indices_index; + int32_t offsets_index; + int32_t has_bit_indices_index; + int32_t inlined_string_indices_index; int object_size; }; @@ -278,7 +313,7 @@ int num_messages; const MigrationSchema* schemas; const Message* const* default_instances; - const uint32* offsets; + const uint32_t* offsets; // update the following descriptor arrays. Metadata* file_level_metadata; const EnumDescriptor** file_level_enum_descriptors; @@ -309,8 +344,9 @@ const Metadata& metadata); // These cannot be in lite so we put them in the reflection. -PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8* base, uint32 offset, - uint32 tag, uint32 has_offset, +PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8_t* base, + uint32_t offset, uint32_t tag, + uint32_t has_offset, io::CodedOutputStream* output); struct PROTOBUF_EXPORT AddDescriptorsRunner {
diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc index 0b6ed8e..a0c4ea5 100644 --- a/src/google/protobuf/generated_message_reflection_unittest.cc +++ b/src/google/protobuf/generated_message_reflection_unittest.cc
@@ -166,147 +166,185 @@ &reflection->GetMessage(message, F("optional_import_message"))); } -TEST(GeneratedMessageReflectionTest, Swap) { - unittest::TestAllTypes message1; - unittest::TestAllTypes message2; +class GeneratedMessageReflectionSwapTest : public testing::TestWithParam<bool> { + protected: + void Swap(const Reflection* reflection, Message* lhs, Message* rhs) { + if (GetParam()) { + reflection->UnsafeArenaSwap(lhs, rhs); + } else { + reflection->Swap(lhs, rhs); + } + } + void SwapFields(const Reflection* reflection, Message* lhs, Message* rhs, + const std::vector<const FieldDescriptor*>& fields) { + if (GetParam()) { + reflection->UnsafeArenaSwapFields(lhs, rhs, fields); + } else { + reflection->SwapFields(lhs, rhs, fields); + } + } +}; - TestUtil::SetAllFields(&message1); +// unsafe_shallow_swap: true -> UnsafeArena* API. +INSTANTIATE_TEST_SUITE_P(ReflectionSwap, GeneratedMessageReflectionSwapTest, + testing::Bool()); - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); +TEST_P(GeneratedMessageReflectionSwapTest, LhsSet) { + unittest::TestAllTypes lhs; + unittest::TestAllTypes rhs; - TestUtil::ExpectClear(message1); - TestUtil::ExpectAllFieldsSet(message2); + TestUtil::SetAllFields(&lhs); + + Swap(lhs.GetReflection(), &lhs, &rhs); + + TestUtil::ExpectClear(lhs); + TestUtil::ExpectAllFieldsSet(rhs); } -TEST(GeneratedMessageReflectionTest, SwapWithBothSet) { - unittest::TestAllTypes message1; - unittest::TestAllTypes message2; +TEST_P(GeneratedMessageReflectionSwapTest, BothSet) { + unittest::TestAllTypes lhs; + unittest::TestAllTypes rhs; - TestUtil::SetAllFields(&message1); - TestUtil::SetAllFields(&message2); - TestUtil::ModifyRepeatedFields(&message2); + TestUtil::SetAllFields(&lhs); + TestUtil::SetAllFields(&rhs); + TestUtil::ModifyRepeatedFields(&rhs); - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); + const Reflection* reflection = lhs.GetReflection(); + Swap(reflection, &lhs, &rhs); - TestUtil::ExpectRepeatedFieldsModified(message1); - TestUtil::ExpectAllFieldsSet(message2); + TestUtil::ExpectRepeatedFieldsModified(lhs); + TestUtil::ExpectAllFieldsSet(rhs); - message1.set_optional_int32(532819); + lhs.set_optional_int32(532819); - reflection->Swap(&message1, &message2); + Swap(reflection, &lhs, &rhs); - EXPECT_EQ(532819, message2.optional_int32()); + EXPECT_EQ(532819, rhs.optional_int32()); } -TEST(GeneratedMessageReflectionTest, SwapWithLhsCleared) { - unittest::TestAllTypes message1; - unittest::TestAllTypes message2; +TEST_P(GeneratedMessageReflectionSwapTest, LhsCleared) { + unittest::TestAllTypes lhs; + unittest::TestAllTypes rhs; - TestUtil::SetAllFields(&message1); + TestUtil::SetAllFields(&lhs); // For proto2 message, for message field, Clear only reset hasbits, but // doesn't delete the underlying field. - message1.Clear(); + lhs.Clear(); - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); + Swap(lhs.GetReflection(), &lhs, &rhs); - TestUtil::ExpectClear(message2); + TestUtil::ExpectClear(rhs); } -TEST(GeneratedMessageReflectionTest, SwapWithRhsCleared) { - unittest::TestAllTypes message1; - unittest::TestAllTypes message2; +TEST_P(GeneratedMessageReflectionSwapTest, RhsCleared) { + unittest::TestAllTypes lhs; + unittest::TestAllTypes rhs; - TestUtil::SetAllFields(&message2); + TestUtil::SetAllFields(&rhs); // For proto2 message, for message field, Clear only reset hasbits, but // doesn't delete the underlying field. - message2.Clear(); + rhs.Clear(); - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); + Swap(lhs.GetReflection(), &lhs, &rhs); - TestUtil::ExpectClear(message1); + TestUtil::ExpectClear(lhs); } -TEST(GeneratedMessageReflectionTest, SwapExtensions) { - unittest::TestAllExtensions message1; - unittest::TestAllExtensions message2; +TEST_P(GeneratedMessageReflectionSwapTest, Extensions) { + unittest::TestAllExtensions lhs; + unittest::TestAllExtensions rhs; - TestUtil::SetAllExtensions(&message1); + TestUtil::SetAllExtensions(&lhs); - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); + Swap(lhs.GetReflection(), &lhs, &rhs); - TestUtil::ExpectExtensionsClear(message1); - TestUtil::ExpectAllExtensionsSet(message2); + TestUtil::ExpectExtensionsClear(lhs); + TestUtil::ExpectAllExtensionsSet(rhs); } -TEST(GeneratedMessageReflectionTest, SwapUnknown) { - unittest::TestEmptyMessage message1, message2; +TEST_P(GeneratedMessageReflectionSwapTest, Unknown) { + unittest::TestEmptyMessage lhs, rhs; - message1.mutable_unknown_fields()->AddVarint(1234, 1); + lhs.mutable_unknown_fields()->AddVarint(1234, 1); - EXPECT_EQ(1, message1.unknown_fields().field_count()); - EXPECT_EQ(0, message2.unknown_fields().field_count()); - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); - EXPECT_EQ(0, message1.unknown_fields().field_count()); - EXPECT_EQ(1, message2.unknown_fields().field_count()); + EXPECT_EQ(1, lhs.unknown_fields().field_count()); + EXPECT_EQ(0, rhs.unknown_fields().field_count()); + Swap(lhs.GetReflection(), &lhs, &rhs); + EXPECT_EQ(0, lhs.unknown_fields().field_count()); + EXPECT_EQ(1, rhs.unknown_fields().field_count()); } -TEST(GeneratedMessageReflectionTest, SwapFields) { - unittest::TestAllTypes message1, message2; - message1.set_optional_double(12.3); - message1.mutable_repeated_int32()->Add(10); - message1.mutable_repeated_int32()->Add(20); +TEST_P(GeneratedMessageReflectionSwapTest, Oneof) { + unittest::TestOneof2 lhs, rhs; + TestUtil::SetOneof1(&lhs); - message2.set_optional_string("hello"); - message2.mutable_repeated_int64()->Add(30); + Swap(lhs.GetReflection(), &lhs, &rhs); + + TestUtil::ExpectOneofClear(lhs); + TestUtil::ExpectOneofSet1(rhs); +} + +TEST_P(GeneratedMessageReflectionSwapTest, OneofBothSet) { + unittest::TestOneof2 lhs, rhs; + TestUtil::SetOneof1(&lhs); + TestUtil::SetOneof2(&rhs); + + Swap(lhs.GetReflection(), &lhs, &rhs); + + TestUtil::ExpectOneofSet2(lhs); + TestUtil::ExpectOneofSet1(rhs); +} + +TEST_P(GeneratedMessageReflectionSwapTest, SwapFields) { + unittest::TestAllTypes lhs, rhs; + lhs.set_optional_double(12.3); + lhs.mutable_repeated_int32()->Add(10); + lhs.mutable_repeated_int32()->Add(20); + + rhs.set_optional_string("hello"); + rhs.mutable_repeated_int64()->Add(30); std::vector<const FieldDescriptor*> fields; - const Descriptor* descriptor = message1.GetDescriptor(); + const Descriptor* descriptor = lhs.GetDescriptor(); fields.push_back(descriptor->FindFieldByName("optional_double")); fields.push_back(descriptor->FindFieldByName("repeated_int32")); fields.push_back(descriptor->FindFieldByName("optional_string")); fields.push_back(descriptor->FindFieldByName("optional_uint64")); - const Reflection* reflection = message1.GetReflection(); - reflection->SwapFields(&message1, &message2, fields); + SwapFields(lhs.GetReflection(), &lhs, &rhs, fields); - EXPECT_FALSE(message1.has_optional_double()); - EXPECT_EQ(0, message1.repeated_int32_size()); - EXPECT_TRUE(message1.has_optional_string()); - EXPECT_EQ("hello", message1.optional_string()); - EXPECT_EQ(0, message1.repeated_int64_size()); - EXPECT_FALSE(message1.has_optional_uint64()); + EXPECT_FALSE(lhs.has_optional_double()); + EXPECT_EQ(0, lhs.repeated_int32_size()); + EXPECT_TRUE(lhs.has_optional_string()); + EXPECT_EQ("hello", lhs.optional_string()); + EXPECT_EQ(0, lhs.repeated_int64_size()); + EXPECT_FALSE(lhs.has_optional_uint64()); - EXPECT_TRUE(message2.has_optional_double()); - EXPECT_EQ(12.3, message2.optional_double()); - EXPECT_EQ(2, message2.repeated_int32_size()); - EXPECT_EQ(10, message2.repeated_int32(0)); - EXPECT_EQ(20, message2.repeated_int32(1)); - EXPECT_FALSE(message2.has_optional_string()); - EXPECT_EQ(1, message2.repeated_int64_size()); - EXPECT_FALSE(message2.has_optional_uint64()); + EXPECT_TRUE(rhs.has_optional_double()); + EXPECT_EQ(12.3, rhs.optional_double()); + EXPECT_EQ(2, rhs.repeated_int32_size()); + EXPECT_EQ(10, rhs.repeated_int32(0)); + EXPECT_EQ(20, rhs.repeated_int32(1)); + EXPECT_FALSE(rhs.has_optional_string()); + EXPECT_EQ(1, rhs.repeated_int64_size()); + EXPECT_FALSE(rhs.has_optional_uint64()); } -TEST(GeneratedMessageReflectionTest, SwapFieldsAll) { - unittest::TestAllTypes message1; - unittest::TestAllTypes message2; +TEST_P(GeneratedMessageReflectionSwapTest, SwapFieldsAll) { + unittest::TestAllTypes lhs; + unittest::TestAllTypes rhs; - TestUtil::SetAllFields(&message2); + TestUtil::SetAllFields(&rhs); std::vector<const FieldDescriptor*> fields; - const Reflection* reflection = message1.GetReflection(); - reflection->ListFields(message2, &fields); - reflection->SwapFields(&message1, &message2, fields); + const Reflection* reflection = lhs.GetReflection(); + reflection->ListFields(rhs, &fields); + SwapFields(reflection, &lhs, &rhs, fields); - TestUtil::ExpectAllFieldsSet(message1); - TestUtil::ExpectClear(message2); + TestUtil::ExpectAllFieldsSet(lhs); + TestUtil::ExpectClear(rhs); } TEST(GeneratedMessageReflectionTest, SwapFieldsAllOnDifferentArena) { @@ -476,29 +514,6 @@ unittest::repeated_foreign_message_extension)); } -TEST(GeneratedMessageReflectionTest, SwapOneof) { - unittest::TestOneof2 message1, message2; - TestUtil::SetOneof1(&message1); - - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); - - TestUtil::ExpectOneofClear(message1); - TestUtil::ExpectOneofSet1(message2); -} - -TEST(GeneratedMessageReflectionTest, SwapOneofBothSet) { - unittest::TestOneof2 message1, message2; - TestUtil::SetOneof1(&message1); - TestUtil::SetOneof2(&message2); - - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); - - TestUtil::ExpectOneofSet2(message1); - TestUtil::ExpectOneofSet1(message2); -} - TEST(GeneratedMessageReflectionTest, SwapFieldsOneof) { unittest::TestOneof2 message1, message2; TestUtil::SetOneof1(&message1);
diff --git a/src/google/protobuf/generated_message_table_driven.cc b/src/google/protobuf/generated_message_table_driven.cc index 56f1a6a..71ee647 100644 --- a/src/google/protobuf/generated_message_table_driven.cc +++ b/src/google/protobuf/generated_message_table_driven.cc
@@ -45,7 +45,7 @@ namespace { -UnknownFieldSet* MutableUnknownFields(MessageLite* msg, int64 arena_offset) { +UnknownFieldSet* MutableUnknownFields(MessageLite* msg, int64_t arena_offset) { return Raw<InternalMetadata>(msg, arena_offset) ->mutable_unknown_fields<UnknownFieldSet>(); }
diff --git a/src/google/protobuf/generated_message_table_driven.h b/src/google/protobuf/generated_message_table_driven.h index def4a1f..178a0c1 100644 --- a/src/google/protobuf/generated_message_table_driven.h +++ b/src/google/protobuf/generated_message_table_driven.h
@@ -73,19 +73,21 @@ TYPE_STRING_STRING_PIECE = 20, TYPE_BYTES_CORD = 21, TYPE_BYTES_STRING_PIECE = 22, - TYPE_MAP = 23, + TYPE_STRING_INLINED = 23, + TYPE_BYTES_INLINED = 24, + TYPE_MAP = 25, }; static_assert(TYPE_MAP < kRepeatedMask, "Invalid enum"); struct PROTOBUF_EXPORT FieldMetadata { - uint32 offset; // offset of this field in the struct - uint32 tag; // field * 8 + wire_type + uint32_t offset; // offset of this field in the struct + uint32_t tag; // field * 8 + wire_type // byte offset * 8 + bit_offset; // if the high bit is set then this is the byte offset of the oneof_case // for this field. - uint32 has_offset; - uint32 type; // the type of this field. + uint32_t has_offset; + uint32_t type; // the type of this field. const void* ptr; // auxiliary data // From the serializer point of view each fundamental type can occur in @@ -104,7 +106,8 @@ enum { kCordType = 19, kStringPieceType = 20, - kNumTypes = 20, + kInlinedType = 21, + kNumTypes = 21, kSpecial = kNumTypes * kNumTypeClasses, }; @@ -119,10 +122,10 @@ // Additional data, needed for some types, is stored in // AuxiliaryParseTableField. struct ParseTableField { - uint32 offset; + uint32_t offset; // The presence_index ordinarily represents a has_bit index, but for fields // inside a oneof it represents the index in _oneof_case_. - uint32 presence_index; + uint32_t presence_index; unsigned char normal_wiretype; unsigned char packed_wiretype; @@ -184,10 +187,10 @@ // TODO(ckennelly): Do something with this padding. // TODO(ckennelly): Vet these for sign extension. - int64 has_bits_offset; - int64 oneof_case_offset; - int64 extension_offset; - int64 arena_offset; + int64_t has_bits_offset; + int64_t oneof_case_offset; + int64_t extension_offset; + int64_t arena_offset; // ExplicitlyInitialized<T> -> T requires a reinterpret_cast, which prevents // the tables from being constructed as a constexpr. We use void to avoid @@ -243,9 +246,9 @@ const FieldMetadata* field_table; }; -PROTOBUF_EXPORT void SerializeInternal(const uint8* base, +PROTOBUF_EXPORT void SerializeInternal(const uint8_t* base, const FieldMetadata* table, - int32 num_fields, + int32_t num_fields, io::CodedOutputStream* output); inline void TableSerialize(const MessageLite& msg, @@ -253,24 +256,25 @@ io::CodedOutputStream* output) { const FieldMetadata* field_table = table->field_table; int num_fields = table->num_fields - 1; - const uint8* base = reinterpret_cast<const uint8*>(&msg); + const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg); // TODO(gerbens) This skips the first test if we could use the fast // array serialization path, we should make this // int cached_size = - // *reinterpret_cast<const int32*>(base + field_table->offset); + // *reinterpret_cast<const int32_t*>(base + field_table->offset); // SerializeWithCachedSize(msg, field_table + 1, num_fields, cached_size, ...) // But we keep conformance with the old way for now. SerializeInternal(base, field_table + 1, num_fields, output); } -PROTOBUF_EXPORT uint8* SerializeInternalToArray(const uint8* base, const FieldMetadata* table, - int32 num_fields, bool is_deterministic, - uint8* buffer); +PROTOBUF_EXPORT uint8_t* SerializeInternalToArray(const uint8_t* base, + const FieldMetadata* table, + int32_t num_fields, bool is_deterministic, + uint8_t* buffer); -inline uint8* TableSerializeToArray(const MessageLite& msg, - const SerializationTable* table, - bool is_deterministic, uint8* buffer) { - const uint8* base = reinterpret_cast<const uint8*>(&msg); +inline uint8_t* TableSerializeToArray(const MessageLite& msg, + const SerializationTable* table, + bool is_deterministic, uint8_t* buffer) { + const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg); const FieldMetadata* field_table = table->field_table + 1; int num_fields = table->num_fields - 1; return SerializeInternalToArray(base, field_table, num_fields, @@ -302,8 +306,8 @@ }; template <typename MapFieldType, const SerializationTable* table> -void MapFieldSerializer(const uint8* base, uint32 offset, uint32 tag, - uint32 has_offset, io::CodedOutputStream* output) { +void MapFieldSerializer(const uint8_t* base, uint32_t offset, uint32_t tag, + uint32_t has_offset, io::CodedOutputStream* output) { typedef MapEntryHelper<typename MapFieldType::EntryTypeTrait> Entry; typedef typename MapFieldType::MapType::const_iterator Iter; @@ -318,7 +322,7 @@ Entry map_entry(*it); output->WriteVarint32(tag); output->WriteVarint32(map_entry._cached_size_); - SerializeInternal(reinterpret_cast<const uint8*>(&map_entry), + SerializeInternal(reinterpret_cast<const uint8_t*>(&map_entry), t->field_table, t->num_fields, output); } } else { @@ -331,7 +335,7 @@ for (int i = 0; i < v.size(); i++) { output->WriteVarint32(tag); output->WriteVarint32(v[i]._cached_size_); - SerializeInternal(reinterpret_cast<const uint8*>(&v[i]), t->field_table, + SerializeInternal(reinterpret_cast<const uint8_t*>(&v[i]), t->field_table, t->num_fields, output); } }
diff --git a/src/google/protobuf/generated_message_table_driven_lite.cc b/src/google/protobuf/generated_message_table_driven_lite.cc index 02e6dac..42c3475 100644 --- a/src/google/protobuf/generated_message_table_driven_lite.cc +++ b/src/google/protobuf/generated_message_table_driven_lite.cc
@@ -43,7 +43,7 @@ namespace { -std::string* MutableUnknownFields(MessageLite* msg, int64 arena_offset) { +std::string* MutableUnknownFields(MessageLite* msg, int64_t arena_offset) { return Raw<InternalMetadata>(msg, arena_offset) ->mutable_unknown_fields<std::string>(); }
diff --git a/src/google/protobuf/generated_message_table_driven_lite.h b/src/google/protobuf/generated_message_table_driven_lite.h index 32cc16e..032dd0e 100644 --- a/src/google/protobuf/generated_message_table_driven_lite.h +++ b/src/google/protobuf/generated_message_table_driven_lite.h
@@ -35,6 +35,7 @@ #include <google/protobuf/extension_set.h> #include <google/protobuf/generated_message_table_driven.h> #include <google/protobuf/implicit_weak_message.h> +#include <google/protobuf/inlined_string_field.h> #include <google/protobuf/repeated_field.h> #include <google/protobuf/wire_format_lite.h> #include <type_traits> @@ -49,6 +50,7 @@ enum StringType { StringType_STRING = 0, + StringType_INLINED = 3 }; // Logically a superset of StringType, consisting of all field types that @@ -57,7 +59,8 @@ ProcessingType_STRING = 0, ProcessingType_CORD = 1, ProcessingType_STRING_PIECE = 2, - ProcessingType_MESSAGE = 3, + ProcessingType_INLINED = 3, + ProcessingType_MESSAGE = 4, }; enum Cardinality { @@ -67,17 +70,18 @@ }; template <typename Type> -inline Type* Raw(MessageLite* msg, int64 offset) { - return reinterpret_cast<Type*>(reinterpret_cast<uint8*>(msg) + offset); +inline Type* Raw(MessageLite* msg, int64_t offset) { + return reinterpret_cast<Type*>(reinterpret_cast<uint8_t*>(msg) + offset); } template <typename Type> -inline const Type* Raw(const MessageLite* msg, int64 offset) { - return reinterpret_cast<const Type*>(reinterpret_cast<const uint8*>(msg) + +inline const Type* Raw(const MessageLite* msg, int64_t offset) { + return reinterpret_cast<const Type*>(reinterpret_cast<const uint8_t*>(msg) + offset); } -inline ExtensionSet* GetExtensionSet(MessageLite* msg, int64 extension_offset) { +inline ExtensionSet* GetExtensionSet(MessageLite* msg, + int64_t extension_offset) { if (extension_offset == -1) { return NULL; } @@ -86,15 +90,17 @@ } template <typename Type> -inline Type* AddField(MessageLite* msg, int64 offset) { - static_assert(std::is_trivial<Type>::value, "Do not assign"); +inline Type* AddField(MessageLite* msg, int64_t offset) { + static_assert(std::is_trivial<Type>::value || + std::is_same<Type, InlinedStringField>::value, + "Do not assign"); RepeatedField<Type>* repeated = Raw<RepeatedField<Type>>(msg, offset); return repeated->Add(); } template <> -inline std::string* AddField<std::string>(MessageLite* msg, int64 offset) { +inline std::string* AddField<std::string>(MessageLite* msg, int64_t offset) { RepeatedPtrField<std::string>* repeated = Raw<RepeatedPtrField<std::string>>(msg, offset); return repeated->Add(); @@ -102,35 +108,35 @@ template <typename Type> -inline void AddField(MessageLite* msg, int64 offset, Type value) { +inline void AddField(MessageLite* msg, int64_t offset, Type value) { static_assert(std::is_trivial<Type>::value, "Do not assign"); *AddField<Type>(msg, offset) = value; } -inline void SetBit(uint32* has_bits, uint32 has_bit_index) { +inline void SetBit(uint32_t* has_bits, uint32_t has_bit_index) { GOOGLE_DCHECK(has_bits != nullptr); - uint32 mask = static_cast<uint32>(1u) << (has_bit_index % 32); + uint32_t mask = static_cast<uint32_t>(1u) << (has_bit_index % 32); has_bits[has_bit_index / 32u] |= mask; } template <typename Type> -inline Type* MutableField(MessageLite* msg, uint32* has_bits, - uint32 has_bit_index, int64 offset) { +inline Type* MutableField(MessageLite* msg, uint32_t* has_bits, + uint32_t has_bit_index, int64_t offset) { SetBit(has_bits, has_bit_index); return Raw<Type>(msg, offset); } template <typename Type> -inline void SetField(MessageLite* msg, uint32* has_bits, uint32 has_bit_index, - int64 offset, Type value) { +inline void SetField(MessageLite* msg, uint32_t* has_bits, + uint32_t has_bit_index, int64_t offset, Type value) { static_assert(std::is_trivial<Type>::value, "Do not assign"); *MutableField<Type>(msg, has_bits, has_bit_index, offset) = value; } template <typename Type> -inline void SetOneofField(MessageLite* msg, uint32* oneof_case, - uint32 oneof_case_index, int64 offset, +inline void SetOneofField(MessageLite* msg, uint32_t* oneof_case, + uint32_t oneof_case_index, int64_t offset, int field_number, Type value) { oneof_case[oneof_case_index] = field_number; *Raw<Type>(msg, offset) = value; @@ -153,6 +159,11 @@ ->Destroy(ArenaStringPtr::EmptyDefault{}, arena); break; + case TYPE_STRING_INLINED: + case TYPE_BYTES_INLINED: + Raw<InlinedStringField>(msg, field.offset)->DestroyNoArena(NULL); + break; + default: // No cleanup needed. break; @@ -167,9 +178,10 @@ // _oneof_case_ array. template <ProcessingType field_type> inline void ResetOneofField(const ParseTable& table, int field_number, - Arena* arena, MessageLite* msg, uint32* oneof_case, - int64 offset, const void* default_ptr) { - if (static_cast<int64>(*oneof_case) == field_number) { + Arena* arena, MessageLite* msg, + uint32_t* oneof_case, int64_t offset, + const void* default_ptr) { + if (static_cast<int64_t>(*oneof_case) == field_number) { // The oneof is already set to the right type, so there is no need to clear // it. return; @@ -185,6 +197,10 @@ Raw<ArenaStringPtr>(msg, offset) ->UnsafeSetDefault(static_cast<const std::string*>(default_ptr)); break; + case ProcessingType_INLINED: + new (Raw<InlinedStringField>(msg, offset)) + InlinedStringField(*static_cast<const std::string*>(default_ptr)); + break; case ProcessingType_MESSAGE: MessageLite** submessage = Raw<MessageLite*>(msg, offset); const MessageLite* prototype = @@ -197,8 +213,8 @@ template <typename UnknownFieldHandler, Cardinality cardinality, bool is_string_type, StringType ctype> static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg, - Arena* arena, uint32* has_bits, - uint32 has_bit_index, int64 offset, + Arena* arena, uint32_t* has_bits, + uint32_t has_bit_index, int64_t offset, const void* default_ptr, const char* field_name) { StringPiece utf8_string_data; @@ -209,6 +225,30 @@ #endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED switch (ctype) { + case StringType_INLINED: { + std::string* value = nullptr; + switch (cardinality) { + case Cardinality_SINGULAR: { + // TODO(ckennelly): Is this optimal? + InlinedStringField* s = MutableField<InlinedStringField>( + msg, has_bits, has_bit_index, offset); + value = s->UnsafeMutablePointer(); + } break; + case Cardinality_REPEATED: { + value = AddField<std::string>(msg, offset); + } break; + case Cardinality_ONEOF: { + InlinedStringField* s = Raw<InlinedStringField>(msg, offset); + value = s->UnsafeMutablePointer(); + } break; + } + GOOGLE_DCHECK(value != nullptr); + if (PROTOBUF_PREDICT_FALSE(!WireFormatLite::ReadString(input, value))) { + return false; + } + utf8_string_data = *value; + break; + } case StringType_STRING: { switch (cardinality) { case Cardinality_SINGULAR: { @@ -260,8 +300,8 @@ template <typename UnknownFieldHandler, Cardinality cardinality> inline bool HandleEnum(const ParseTable& table, io::CodedInputStream* input, - MessageLite* msg, uint32* presence, - uint32 presence_index, int64 offset, uint32 tag, + MessageLite* msg, uint32_t* presence, + uint32_t presence_index, int64_t offset, uint32_t tag, int field_number) { int value; if (PROTOBUF_PREDICT_FALSE( @@ -326,7 +366,7 @@ } }; -template <typename UnknownFieldHandler, uint32 kMaxTag> +template <typename UnknownFieldHandler, uint32_t kMaxTag> bool MergePartialFromCodedStreamInlined(MessageLite* msg, const ParseTable& table, io::CodedInputStream* input) { @@ -335,11 +375,11 @@ // // TODO(ckennelly): Make this a compile-time parameter with templates. GOOGLE_DCHECK_GE(table.has_bits_offset, 0); - uint32* has_bits = Raw<uint32>(msg, table.has_bits_offset); + uint32_t* has_bits = Raw<uint32_t>(msg, table.has_bits_offset); GOOGLE_DCHECK(has_bits != NULL); while (true) { - uint32 tag = input->ReadTagWithCutoffNoLastTag(kMaxTag).first; + uint32_t tag = input->ReadTagWithCutoffNoLastTag(kMaxTag).first; const WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); const int field_number = WireFormatLite::GetTagFieldNumber(tag); @@ -367,8 +407,8 @@ const ParseTableField* data = table.fields + field_number; // TODO(ckennelly): Avoid sign extension - const int64 presence_index = data->presence_index; - const int64 offset = data->offset; + const int64_t presence_index = data->presence_index; + const int64_t offset = data->offset; const unsigned char processing_type = data->processing_type; if (data->normal_wiretype == static_cast<unsigned char>(wire_type)) { @@ -394,7 +434,7 @@ break; \ } \ case (WireFormatLite::TYPE_##TYPE) | kOneofMask: { \ - uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset); \ + uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset); \ CPPTYPE value; \ if (PROTOBUF_PREDICT_FALSE( \ (!WireFormatLite::ReadPrimitive< \ @@ -408,17 +448,17 @@ break; \ } - HANDLE_TYPE(INT32, int32) - HANDLE_TYPE(INT64, int64) - HANDLE_TYPE(SINT32, int32) - HANDLE_TYPE(SINT64, int64) - HANDLE_TYPE(UINT32, uint32) - HANDLE_TYPE(UINT64, uint64) + HANDLE_TYPE(INT32, int32_t) + HANDLE_TYPE(INT64, int64_t) + HANDLE_TYPE(SINT32, int32_t) + HANDLE_TYPE(SINT64, int64_t) + HANDLE_TYPE(UINT32, uint32_t) + HANDLE_TYPE(UINT64, uint64_t) - HANDLE_TYPE(FIXED32, uint32) - HANDLE_TYPE(FIXED64, uint64) - HANDLE_TYPE(SFIXED32, int32) - HANDLE_TYPE(SFIXED64, int64) + HANDLE_TYPE(FIXED32, uint32_t) + HANDLE_TYPE(FIXED64, uint64_t) + HANDLE_TYPE(SFIXED32, int32_t) + HANDLE_TYPE(SFIXED64, int64_t) HANDLE_TYPE(FLOAT, float) HANDLE_TYPE(DOUBLE, double) @@ -442,13 +482,30 @@ } break; } + case TYPE_BYTES_INLINED: +#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case TYPE_STRING_INLINED: +#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + { + Arena* const arena = msg->GetArena(); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + + if (PROTOBUF_PREDICT_FALSE( + (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR, + false, StringType_INLINED>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, nullptr)))) { + return false; + } + break; + } case WireFormatLite::TYPE_BYTES | kOneofMask: #ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED case WireFormatLite::TYPE_STRING | kOneofMask: #endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED { Arena* const arena = msg->GetArena(); - uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset); + uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset); const void* default_ptr = table.aux[field_number].strings.default_ptr; ResetOneofField<ProcessingType_STRING>( @@ -465,8 +522,10 @@ break; } case (WireFormatLite::TYPE_BYTES) | kRepeatedMask: + case TYPE_BYTES_INLINED | kRepeatedMask: #ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED case (WireFormatLite::TYPE_STRING) | kRepeatedMask: + case TYPE_STRING_INLINED | kRepeatedMask: #endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED { Arena* const arena = msg->GetArena(); @@ -496,6 +555,7 @@ } break; } + case TYPE_STRING_INLINED | kRepeatedMask: case (WireFormatLite::TYPE_STRING) | kRepeatedMask: { Arena* const arena = msg->GetArena(); const void* default_ptr = table.aux[field_number].strings.default_ptr; @@ -512,7 +572,7 @@ } case (WireFormatLite::TYPE_STRING) | kOneofMask: { Arena* const arena = msg->GetArena(); - uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset); + uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset); const void* default_ptr = table.aux[field_number].strings.default_ptr; const char* field_name = table.aux[field_number].strings.field_name; @@ -549,7 +609,7 @@ break; } case WireFormatLite::TYPE_ENUM | kOneofMask: { - uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset); + uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset); if (PROTOBUF_PREDICT_FALSE( (!HandleEnum<UnknownFieldHandler, Cardinality_ONEOF>( table, input, msg, oneof_case, presence_index, offset, @@ -639,7 +699,7 @@ } case WireFormatLite::TYPE_MESSAGE | kOneofMask: { Arena* const arena = msg->GetArena(); - uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset); + uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset); MessageLite** submsg_holder = Raw<MessageLite*>(msg, offset); ResetOneofField<ProcessingType_MESSAGE>( table, field_number, arena, msg, oneof_case + presence_index, @@ -653,6 +713,22 @@ break; } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case TYPE_STRING_INLINED: { + Arena* const arena = msg->GetArena(); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + const char* field_name = table.aux[field_number].strings.field_name; + + if (PROTOBUF_PREDICT_FALSE( + (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR, + true, StringType_INLINED>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, field_name)))) { + return false; + } + break; + } +#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED case TYPE_MAP: { if (PROTOBUF_PREDICT_FALSE(!(*table.aux[field_number].maps.parse_map)( input, Raw<void>(msg, offset)))) { @@ -675,6 +751,8 @@ GOOGLE_DCHECK_NE(processing_type, kRepeatedMask); GOOGLE_DCHECK_EQ(0, processing_type & kOneofMask); + GOOGLE_DCHECK_NE(TYPE_BYTES_INLINED | kRepeatedMask, processing_type); + GOOGLE_DCHECK_NE(TYPE_STRING_INLINED | kRepeatedMask, processing_type); // Mask out kRepeatedMask bit, allowing the jump table to be smaller. switch (static_cast<WireFormatLite::FieldType>(processing_type ^ @@ -690,17 +768,17 @@ break; \ } - HANDLE_PACKED_TYPE(INT32, int32, Int32) - HANDLE_PACKED_TYPE(INT64, int64, Int64) - HANDLE_PACKED_TYPE(SINT32, int32, Int32) - HANDLE_PACKED_TYPE(SINT64, int64, Int64) - HANDLE_PACKED_TYPE(UINT32, uint32, UInt32) - HANDLE_PACKED_TYPE(UINT64, uint64, UInt64) + HANDLE_PACKED_TYPE(INT32, int32_t, Int32) + HANDLE_PACKED_TYPE(INT64, int64_t, Int64) + HANDLE_PACKED_TYPE(SINT32, int32_t, Int32) + HANDLE_PACKED_TYPE(SINT64, int64_t, Int64) + HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32) + HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64) - HANDLE_PACKED_TYPE(FIXED32, uint32, UInt32) - HANDLE_PACKED_TYPE(FIXED64, uint64, UInt64) - HANDLE_PACKED_TYPE(SFIXED32, int32, Int32) - HANDLE_PACKED_TYPE(SFIXED64, int64, Int64) + HANDLE_PACKED_TYPE(FIXED32, uint32_t, UInt32) + HANDLE_PACKED_TYPE(FIXED64, uint64_t, UInt64) + HANDLE_PACKED_TYPE(SFIXED32, int32_t, Int32) + HANDLE_PACKED_TYPE(SFIXED64, int64_t, Int64) HANDLE_PACKED_TYPE(FLOAT, float, Float) HANDLE_PACKED_TYPE(DOUBLE, double, Double) @@ -712,7 +790,7 @@ // InternalMetadata) when all inputs in the repeated series // are valid, we implement our own parser rather than call // WireFormat::ReadPackedEnumPreserveUnknowns. - uint32 length; + uint32_t length; if (PROTOBUF_PREDICT_FALSE(!input->ReadVarint32(&length))) { return false; } @@ -785,8 +863,8 @@ msg, table, input); } else { return MergePartialFromCodedStreamInlined< - UnknownFieldHandler, std::numeric_limits<uint32>::max()>(msg, table, - input); + UnknownFieldHandler, std::numeric_limits<uint32_t>::max()>(msg, table, + input); } }
diff --git a/src/google/protobuf/generated_message_tctable_decl.h b/src/google/protobuf/generated_message_tctable_decl.h index 9d2bc40d..d294caa 100644 --- a/src/google/protobuf/generated_message_tctable_decl.h +++ b/src/google/protobuf/generated_message_tctable_decl.h
@@ -41,6 +41,9 @@ #include <google/protobuf/parse_context.h> #include <google/protobuf/message_lite.h> +// Must come last: +#include <google/protobuf/port_def.inc> + namespace google { namespace protobuf { namespace internal { @@ -52,7 +55,10 @@ : data(static_cast<uint64_t>(offset) << 48 | static_cast<uint64_t>(hasbit_idx) << 16 | coded_tag) {} - uint16_t coded_tag() const { return static_cast<uint16_t>(data); } + template <typename TagType = uint16_t> + TagType coded_tag() const { + return static_cast<TagType>(data); + } uint8_t hasbit_idx() const { return static_cast<uint8_t>(data >> 16); } uint16_t offset() const { return static_cast<uint16_t>(data >> 48); } @@ -62,19 +68,21 @@ struct TailCallParseTableBase; // TailCallParseFunc is the function pointer type used in the tailcall table. -typedef const char* (*TailCallParseFunc)(MessageLite* msg, const char* ptr, - ParseContext* ctx, - const TailCallParseTableBase* table, - uint64_t hasbits, TcFieldData data); +typedef const char* (*TailCallParseFunc)(PROTOBUF_TC_PARAM_DECL); + +#if defined(_MSC_VER) && !defined(_WIN64) +#pragma warning(push) +// TailCallParseTableBase is intentionally overaligned on 32 bit targets. +#pragma warning(disable : 4324) +#endif // Base class for message-level table with info for the tail-call parser. -struct TailCallParseTableBase { +struct alignas(uint64_t) TailCallParseTableBase { // Common attributes for message layout: uint16_t has_bits_offset; uint16_t extension_offset; uint32_t extension_range_low; uint32_t extension_range_high; - uint32_t has_bits_required_mask; const MessageLite* default_instance; // Handler for fields which are not handled by table dispatch. @@ -93,6 +101,10 @@ } }; +#if defined(_MSC_VER) && !defined(_WIN64) +#pragma warning(pop) +#endif + static_assert(sizeof(TailCallParseTableBase::FieldEntry) <= 16, "Field entry is too big."); @@ -120,4 +132,6 @@ } // namespace protobuf } // namespace google +#include <google/protobuf/port_undef.inc> + #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__
diff --git a/src/google/protobuf/generated_message_tctable_impl.h b/src/google/protobuf/generated_message_tctable_impl.h index 07879bd..aec2eed 100644 --- a/src/google/protobuf/generated_message_tctable_impl.h +++ b/src/google/protobuf/generated_message_tctable_impl.h
@@ -53,20 +53,46 @@ namespace internal { -// PROTOBUF_TC_PARAM_DECL are the parameters for tailcall functions. +// PROTOBUF_TC_PARAM_DECL are the parameters for tailcall functions, it is +// defined in port_def.inc. // // Note that this is performance sensitive: changing the parameters will change // the registers used by the ABI calling convention, which subsequently affects // register selection logic inside the function. -#define PROTOBUF_TC_PARAM_DECL \ - ::google::protobuf::MessageLite *msg, const char *ptr, \ - ::google::protobuf::internal::ParseContext *ctx, \ - const ::google::protobuf::internal::TailCallParseTableBase *table, \ - uint64_t hasbits, ::google::protobuf::internal::TcFieldData data // PROTOBUF_TC_PARAM_PASS passes values to match PROTOBUF_TC_PARAM_DECL. #define PROTOBUF_TC_PARAM_PASS msg, ptr, ctx, table, hasbits, data +// PROTOBUF_TC_PARSE_* decide which function is used to parse message-typed +// fields. The guard macros are defined in port_def.inc. +#if PROTOBUF_TC_STATIC_PARSE_SINGULAR1 +#define PROTOBUF_TC_PARSE_SINGULAR1(MESSAGE) MESSAGE::Tct_ParseS1 +#else +#define PROTOBUF_TC_PARSE_SINGULAR1(MESSAGE) \ + ::google::protobuf::internal::TcParserBase::SingularParseMessage<MESSAGE, uint8_t> +#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR1 + +#if PROTOBUF_TC_STATIC_PARSE_SINGULAR2 +#define PROTOBUF_TC_PARSE_SINGULAR2(MESSAGE) MESSAGE::Tct_ParseS2 +#else +#define PROTOBUF_TC_PARSE_SINGULAR2(MESSAGE) \ + ::google::protobuf::internal::TcParserBase::SingularParseMessage<MESSAGE, uint16_t> +#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR2 + +#if PROTOBUF_TC_STATIC_PARSE_REPEATED1 +#define PROTOBUF_TC_PARSE_REPEATED1(MESSAGE) MESSAGE::Tct_ParseR1 +#else +#define PROTOBUF_TC_PARSE_REPEATED1(MESSAGE) \ + ::google::protobuf::internal::TcParserBase::RepeatedParseMessage<MESSAGE, uint8_t> +#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED1 + +#if PROTOBUF_TC_STATIC_PARSE_REPEATED2 +#define PROTOBUF_TC_PARSE_REPEATED2(MESSAGE) MESSAGE::Tct_ParseR2 +#else +#define PROTOBUF_TC_PARSE_REPEATED2(MESSAGE) \ + ::google::protobuf::internal::TcParserBase::RepeatedParseMessage<MESSAGE, uint16_t> +#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED2 + class TcParserBase { public: static const char* GenericFallback(PROTOBUF_TC_PARAM_DECL); @@ -75,7 +101,7 @@ template <typename FieldType, typename TagType> PROTOBUF_NOINLINE static const char* SingularParseMessage( PROTOBUF_TC_PARAM_DECL) { - if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { return table->fallback(PROTOBUF_TC_PARAM_PASS); } ptr += sizeof(TagType); @@ -96,7 +122,7 @@ template <typename FieldType, typename TagType> PROTOBUF_NOINLINE static const char* RepeatedParseMessage( PROTOBUF_TC_PARAM_DECL) { - if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { return table->fallback(PROTOBUF_TC_PARAM_PASS); } ptr += sizeof(TagType); @@ -123,7 +149,6 @@ template <typename TagType, Utf8Type utf8> static const char* RepeatedString(PROTOBUF_TC_PARAM_DECL); - protected: template <typename T> static T& RefAt(void* x, size_t offset) { T* target = reinterpret_cast<T*>(static_cast<char*>(x) + offset); @@ -141,6 +166,7 @@ } } + protected: static inline PROTOBUF_ALWAYS_INLINE const char* Return( PROTOBUF_TC_PARAM_DECL) { SyncHasbits(msg, hasbits, table);
diff --git a/src/google/protobuf/generated_message_tctable_impl.inc b/src/google/protobuf/generated_message_tctable_impl.inc index e6e5dd5..f1eaff9 100644 --- a/src/google/protobuf/generated_message_tctable_impl.inc +++ b/src/google/protobuf/generated_message_tctable_impl.inc
@@ -30,226 +30,124 @@ // clang-format off #ifdef PROTOBUF_TCT_SOURCE -template const char* TcParser<1>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<1>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<2>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<3>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<4>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParser<5>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::PackedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); -template const char* TcParserBase::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); +#define PROTOBUF_TCT_EXTERN #else -extern template const char* TcParser<1>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<1>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<2>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<3>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<4>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParser<5>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::PackedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); -extern template const char* TcParserBase::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); +#define PROTOBUF_TCT_EXTERN extern #endif +PROTOBUF_TCT_EXTERN template const char *TcParser<1>::ParseLoop(PROTOBUF_NAMESPACE_ID::MessageLite*, char const*, PROTOBUF_NAMESPACE_ID::internal::ParseContext*, PROTOBUF_NAMESPACE_ID::internal::TailCallParseTableBase const*); +PROTOBUF_TCT_EXTERN template const char *TcParser<2>::ParseLoop(PROTOBUF_NAMESPACE_ID::MessageLite*, char const*, PROTOBUF_NAMESPACE_ID::internal::ParseContext*, PROTOBUF_NAMESPACE_ID::internal::TailCallParseTableBase const*); +PROTOBUF_TCT_EXTERN template const char *TcParser<3>::ParseLoop(PROTOBUF_NAMESPACE_ID::MessageLite*, char const*, PROTOBUF_NAMESPACE_ID::internal::ParseContext*, PROTOBUF_NAMESPACE_ID::internal::TailCallParseTableBase const*); +PROTOBUF_TCT_EXTERN template const char *TcParser<4>::ParseLoop(PROTOBUF_NAMESPACE_ID::MessageLite*, char const*, PROTOBUF_NAMESPACE_ID::internal::ParseContext*, PROTOBUF_NAMESPACE_ID::internal::TailCallParseTableBase const*); +PROTOBUF_TCT_EXTERN template const char *TcParser<5>::ParseLoop(PROTOBUF_NAMESPACE_ID::MessageLite*, char const*, PROTOBUF_NAMESPACE_ID::internal::ParseContext*, PROTOBUF_NAMESPACE_ID::internal::TailCallParseTableBase const*); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kZigZag>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<1>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<2>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<3>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<4>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParser<5>::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::PackedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoConversion>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kNoUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); +PROTOBUF_TCT_EXTERN template const char* TcParserBase::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParserBase::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL); +#undef PROTOBUF_TCT_EXTERN // clang-format on
diff --git a/src/google/protobuf/generated_message_tctable_lite.cc b/src/google/protobuf/generated_message_tctable_lite.cc index f8a09f4..fedb07b 100644 --- a/src/google/protobuf/generated_message_tctable_lite.cc +++ b/src/google/protobuf/generated_message_tctable_lite.cc
@@ -53,7 +53,7 @@ // Offset returns the address `offset` bytes after `base`. inline void* Offset(void* base, uint32_t offset) { - return static_cast<uint8*>(base) + offset; + return static_cast<uint8_t*>(base) + offset; } // InvertPacked changes tag bits from the given wire type to length @@ -73,7 +73,7 @@ template <uint32_t kPowerOf2> template <typename LayoutType, typename TagType> const char* TcParser<kPowerOf2>::SingularFixed(PROTOBUF_TC_PARAM_DECL) { - if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { return table->fallback(PROTOBUF_TC_PARAM_PASS); } ptr += sizeof(TagType); // Consume tag @@ -86,13 +86,13 @@ template <typename LayoutType, typename TagType> const char* TcParserBase::RepeatedFixed(PROTOBUF_TC_PARAM_DECL) { - if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { // Check if the field can be parsed as packed repeated: constexpr WireFormatLite::WireType fallback_wt = sizeof(LayoutType) == 4 ? WireFormatLite::WIRETYPE_FIXED32 : WireFormatLite::WIRETYPE_FIXED64; InvertPacked<fallback_wt>(data); - if (static_cast<TagType>(data.coded_tag()) == 0) { + if (data.coded_tag<TagType>() == 0) { return PackedFixed<LayoutType, TagType>(PROTOBUF_TC_PARAM_PASS); } else { return table->fallback(PROTOBUF_TC_PARAM_PASS); @@ -117,13 +117,13 @@ template <typename LayoutType, typename TagType> const char* TcParserBase::PackedFixed(PROTOBUF_TC_PARAM_DECL) { - if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { // Try parsing as non-packed repeated: constexpr WireFormatLite::WireType fallback_wt = sizeof(LayoutType) == 4 ? WireFormatLite::WIRETYPE_FIXED32 : WireFormatLite::WIRETYPE_FIXED64; InvertPacked<fallback_wt>(data); - if (static_cast<TagType>(data.coded_tag()) == 0) { + if (data.coded_tag<TagType>() == 0) { return RepeatedFixed<LayoutType, TagType>(PROTOBUF_TC_PARAM_PASS); } else { return table->fallback(PROTOBUF_TC_PARAM_PASS); @@ -273,13 +273,31 @@ } } +template <typename FieldType, TcParserBase::VarintDecode = + TcParserBase::VarintDecode::kNoConversion> +FieldType ZigZagDecodeHelper(uint64_t value) { + return static_cast<FieldType>(value); +} + +template <> +int32_t ZigZagDecodeHelper<int32_t, TcParserBase::VarintDecode::kZigZag>( + uint64_t value) { + return WireFormatLite::ZigZagDecode32(value); +} + +template <> +int64_t ZigZagDecodeHelper<int64_t, TcParserBase::VarintDecode::kZigZag>( + uint64_t value) { + return WireFormatLite::ZigZagDecode64(value); +} + } // namespace template <uint32_t kPowerOf2> template <typename FieldType, typename TagType, TcParserBase::VarintDecode zigzag> const char* TcParser<kPowerOf2>::SingularVarint(PROTOBUF_TC_PARAM_DECL) { - if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { return table->fallback(PROTOBUF_TC_PARAM_PASS); } ptr += sizeof(TagType); // Consume tag @@ -289,8 +307,8 @@ if (ptr == nullptr) { return Error(PROTOBUF_TC_PARAM_PASS); } - RefAt<FieldType>(msg, data.offset()) = static_cast<FieldType>( - zigzag ? google::protobuf::internal::WireFormatLite::ZigZagDecode64(tmp) : tmp); + RefAt<FieldType>(msg, data.offset()) = + ZigZagDecodeHelper<FieldType, zigzag>(tmp); PROTOBUF_MUSTTAIL return TailCall(PROTOBUF_TC_PARAM_PASS); } @@ -298,10 +316,10 @@ TcParserBase::VarintDecode zigzag> PROTOBUF_NOINLINE const char* TcParserBase::RepeatedVarint( PROTOBUF_TC_PARAM_DECL) { - if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { // Try parsing as non-packed repeated: InvertPacked<WireFormatLite::WIRETYPE_VARINT>(data); - if (static_cast<TagType>(data.coded_tag()) == 0) { + if (data.coded_tag<TagType>() == 0) { return PackedVarint<FieldType, TagType, zigzag>(PROTOBUF_TC_PARAM_PASS); } else { return table->fallback(PROTOBUF_TC_PARAM_PASS); @@ -316,8 +334,7 @@ if (ptr == nullptr) { return Error(PROTOBUF_TC_PARAM_PASS); } - field.Add(zigzag ? google::protobuf::internal::WireFormatLite::ZigZagDecode64(tmp) - : tmp); + field.Add(ZigZagDecodeHelper<FieldType, zigzag>(tmp)); if (!ctx->DataAvailable(ptr)) { break; } @@ -329,9 +346,9 @@ TcParserBase::VarintDecode zigzag> PROTOBUF_NOINLINE const char* TcParserBase::PackedVarint( PROTOBUF_TC_PARAM_DECL) { - if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { InvertPacked<WireFormatLite::WIRETYPE_VARINT>(data); - if (static_cast<TagType>(data.coded_tag()) == 0) { + if (data.coded_tag<TagType>() == 0) { return RepeatedVarint<FieldType, TagType, zigzag>(PROTOBUF_TC_PARAM_PASS); } else { return table->fallback(PROTOBUF_TC_PARAM_PASS); @@ -380,7 +397,7 @@ template <typename TagType, TcParserBase::Utf8Type utf8> const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL) { - if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { return table->fallback(PROTOBUF_TC_PARAM_PASS); } ptr += sizeof(TagType); @@ -411,7 +428,7 @@ template <typename TagType, TcParserBase::Utf8Type utf8> const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL) { - if (PROTOBUF_PREDICT_FALSE(static_cast<TagType>(data.coded_tag()) != 0)) { + if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) { return table->fallback(PROTOBUF_TC_PARAM_PASS); } auto expected_tag = UnalignedLoad<TagType>(ptr);
diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index 605fa98..cbe771e 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc
@@ -119,93 +119,93 @@ static void Serialize(const void* ptr, io::CodedOutputStream* output) { WireFormatLite::WriteBoolNoTag(Get<bool>(ptr), output); } - static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { return WireFormatLite::WriteBoolNoTagToArray(Get<Type>(ptr), buffer); } }; template <> struct PrimitiveTypeHelper<WireFormatLite::TYPE_INT32> { - typedef int32 Type; + typedef int32_t Type; static void Serialize(const void* ptr, io::CodedOutputStream* output) { - WireFormatLite::WriteInt32NoTag(Get<int32>(ptr), output); + WireFormatLite::WriteInt32NoTag(Get<int32_t>(ptr), output); } - static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { return WireFormatLite::WriteInt32NoTagToArray(Get<Type>(ptr), buffer); } }; template <> struct PrimitiveTypeHelper<WireFormatLite::TYPE_SINT32> { - typedef int32 Type; + typedef int32_t Type; static void Serialize(const void* ptr, io::CodedOutputStream* output) { - WireFormatLite::WriteSInt32NoTag(Get<int32>(ptr), output); + WireFormatLite::WriteSInt32NoTag(Get<int32_t>(ptr), output); } - static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { return WireFormatLite::WriteSInt32NoTagToArray(Get<Type>(ptr), buffer); } }; template <> struct PrimitiveTypeHelper<WireFormatLite::TYPE_UINT32> { - typedef uint32 Type; + typedef uint32_t Type; static void Serialize(const void* ptr, io::CodedOutputStream* output) { - WireFormatLite::WriteUInt32NoTag(Get<uint32>(ptr), output); + WireFormatLite::WriteUInt32NoTag(Get<uint32_t>(ptr), output); } - static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { return WireFormatLite::WriteUInt32NoTagToArray(Get<Type>(ptr), buffer); } }; template <> struct PrimitiveTypeHelper<WireFormatLite::TYPE_INT64> { - typedef int64 Type; + typedef int64_t Type; static void Serialize(const void* ptr, io::CodedOutputStream* output) { - WireFormatLite::WriteInt64NoTag(Get<int64>(ptr), output); + WireFormatLite::WriteInt64NoTag(Get<int64_t>(ptr), output); } - static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { return WireFormatLite::WriteInt64NoTagToArray(Get<Type>(ptr), buffer); } }; template <> struct PrimitiveTypeHelper<WireFormatLite::TYPE_SINT64> { - typedef int64 Type; + typedef int64_t Type; static void Serialize(const void* ptr, io::CodedOutputStream* output) { - WireFormatLite::WriteSInt64NoTag(Get<int64>(ptr), output); + WireFormatLite::WriteSInt64NoTag(Get<int64_t>(ptr), output); } - static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { return WireFormatLite::WriteSInt64NoTagToArray(Get<Type>(ptr), buffer); } }; template <> struct PrimitiveTypeHelper<WireFormatLite::TYPE_UINT64> { - typedef uint64 Type; + typedef uint64_t Type; static void Serialize(const void* ptr, io::CodedOutputStream* output) { - WireFormatLite::WriteUInt64NoTag(Get<uint64>(ptr), output); + WireFormatLite::WriteUInt64NoTag(Get<uint64_t>(ptr), output); } - static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { return WireFormatLite::WriteUInt64NoTagToArray(Get<Type>(ptr), buffer); } }; template <> struct PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED32> { - typedef uint32 Type; + typedef uint32_t Type; static void Serialize(const void* ptr, io::CodedOutputStream* output) { - WireFormatLite::WriteFixed32NoTag(Get<uint32>(ptr), output); + WireFormatLite::WriteFixed32NoTag(Get<uint32_t>(ptr), output); } - static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { return WireFormatLite::WriteFixed32NoTagToArray(Get<Type>(ptr), buffer); } }; template <> struct PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> { - typedef uint64 Type; + typedef uint64_t Type; static void Serialize(const void* ptr, io::CodedOutputStream* output) { - WireFormatLite::WriteFixed64NoTag(Get<uint64>(ptr), output); + WireFormatLite::WriteFixed64NoTag(Get<uint64_t>(ptr), output); } - static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { return WireFormatLite::WriteFixed64NoTagToArray(Get<Type>(ptr), buffer); } }; @@ -217,12 +217,12 @@ template <> struct PrimitiveTypeHelper<WireFormatLite::TYPE_SFIXED32> : PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED32> { - typedef int32 Type; + typedef int32_t Type; }; template <> struct PrimitiveTypeHelper<WireFormatLite::TYPE_SFIXED64> : PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> { - typedef int64 Type; + typedef int64_t Type; }; template <> struct PrimitiveTypeHelper<WireFormatLite::TYPE_FLOAT> @@ -243,7 +243,7 @@ output->WriteVarint32(value.size()); output->WriteRawMaybeAliased(value.data(), value.size()); } - static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + static uint8_t* SerializeToArray(const void* ptr, uint8_t* buffer) { const Type& value = *static_cast<const Type*>(ptr); return io::CodedOutputStream::WriteStringWithSizeToArray(value, buffer); } @@ -254,6 +254,10 @@ : PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> {}; +template <> +struct PrimitiveTypeHelper<FieldMetadata::kInlinedType> + : PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> {}; + // We want to serialize to both CodedOutputStream and directly into byte arrays // without duplicating the code. In fact we might want extra output channels in // the future. @@ -266,12 +270,12 @@ } template <typename O> -void WriteTagTo(uint32 tag, O* output) { +void WriteTagTo(uint32_t tag, O* output) { SerializeTo<WireFormatLite::TYPE_UINT32>(&tag, output); } template <typename O> -void WriteLengthTo(uint32 length, O* output) { +void WriteLengthTo(uint32_t length, O* output) { SerializeTo<WireFormatLite::TYPE_UINT32>(&length, output); } @@ -285,7 +289,7 @@ // Specialization for writing into a plain array struct ArrayOutput { - uint8* ptr; + uint8_t* ptr; bool is_deterministic; }; @@ -312,17 +316,17 @@ // Helper to branch to fast path if possible void SerializeMessageDispatch(const MessageLite& msg, const FieldMetadata* field_table, int num_fields, - int32 cached_size, + int32_t cached_size, io::CodedOutputStream* output) { - const uint8* base = reinterpret_cast<const uint8*>(&msg); + const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg); SerializeInternal(base, field_table, num_fields, output); } // Helper to branch to fast path if possible void SerializeMessageDispatch(const MessageLite& msg, const FieldMetadata* field_table, int num_fields, - int32 cached_size, ArrayOutput* output) { - const uint8* base = reinterpret_cast<const uint8*>(&msg); + int32_t cached_size, ArrayOutput* output) { + const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg); output->ptr = SerializeInternalToArray(base, field_table, num_fields, output->is_deterministic, output->ptr); } @@ -341,8 +345,9 @@ return; } const FieldMetadata* field_table = table->field_table; - const uint8* base = reinterpret_cast<const uint8*>(msg); - int cached_size = *reinterpret_cast<const int32*>(base + field_table->offset); + const uint8_t* base = reinterpret_cast<const uint8_t*>(msg); + int cached_size = + *reinterpret_cast<const int32_t*>(base + field_table->offset); WriteLengthTo(cached_size, output); int num_fields = table->num_fields - 1; SerializeMessageDispatch(*msg, field_table + 1, num_fields, cached_size, @@ -361,8 +366,9 @@ return; } const FieldMetadata* field_table = table->field_table; - const uint8* base = reinterpret_cast<const uint8*>(msg); - int cached_size = *reinterpret_cast<const int32*>(base + field_table->offset); + const uint8_t* base = reinterpret_cast<const uint8_t*>(msg); + int cached_size = + *reinterpret_cast<const int32_t*>(base + field_table->offset); int num_fields = table->num_fields - 1; SerializeMessageDispatch(*msg, field_table + 1, num_fields, cached_size, output); @@ -412,6 +418,15 @@ } }; +template <> +struct SingularFieldHelper<FieldMetadata::kInlinedType> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + WriteTagTo(md.tag, output); + SerializeTo<FieldMetadata::kInlinedType>(&Get<std::string>(field), output); + } +}; + template <int type> struct RepeatedFieldHelper { template <typename O> @@ -484,6 +499,10 @@ }; +template <> +struct RepeatedFieldHelper<FieldMetadata::kInlinedType> + : RepeatedFieldHelper<WireFormatLite::TYPE_STRING> {}; + template <int type> struct PackedFieldHelper { template <typename O> @@ -493,7 +512,7 @@ if (array.empty()) return; WriteTagTo(md.tag, output); int cached_size = - Get<int>(static_cast<const uint8*>(field) + sizeof(RepeatedField<T>)); + Get<int>(static_cast<const uint8_t*>(field) + sizeof(RepeatedField<T>)); WriteLengthTo(cached_size, output); for (int i = 0; i < array.size(); i++) { SerializeTo<type>(&array[i], output); @@ -519,6 +538,9 @@ template <> struct PackedFieldHelper<WireFormatLite::TYPE_MESSAGE> : PackedFieldHelper<WireFormatLite::TYPE_STRING> {}; +template <> +struct PackedFieldHelper<FieldMetadata::kInlinedType> + : PackedFieldHelper<WireFormatLite::TYPE_STRING> {}; template <int type> struct OneOfFieldHelper { @@ -529,6 +551,15 @@ }; +template <> +struct OneOfFieldHelper<FieldMetadata::kInlinedType> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + SingularFieldHelper<FieldMetadata::kInlinedType>::Serialize( + Get<const std::string*>(field), md, output); + } +}; + void SerializeNotImplemented(int field) { GOOGLE_LOG(FATAL) << "Not implemented field number " << field; } @@ -569,6 +600,11 @@ } +template <> +bool IsNull<FieldMetadata::kInlinedType>(const void* ptr) { + return static_cast<const std::string*>(ptr)->empty(); +} + #define SERIALIZERS_FOR_TYPE(type) \ case SERIALIZE_TABLE_OP(type, FieldMetadata::kPresence): \ if (!IsPresent(base, field_metadata.has_offset)) continue; \ @@ -590,13 +626,13 @@ OneOfFieldHelper<type>::Serialize(ptr, field_metadata, output); \ break -void SerializeInternal(const uint8* base, +void SerializeInternal(const uint8_t* base, const FieldMetadata* field_metadata_table, - int32 num_fields, io::CodedOutputStream* output) { + int32_t num_fields, io::CodedOutputStream* output) { SpecialSerializer func = nullptr; for (int i = 0; i < num_fields; i++) { const FieldMetadata& field_metadata = field_metadata_table[i]; - const uint8* ptr = base + field_metadata.offset; + const uint8_t* ptr = base + field_metadata.offset; switch (field_metadata.type) { SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_DOUBLE); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FLOAT); @@ -616,6 +652,7 @@ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64); + SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType); // Special cases case FieldMetadata::kSpecial: @@ -631,16 +668,16 @@ } } -uint8* SerializeInternalToArray(const uint8* base, - const FieldMetadata* field_metadata_table, - int32 num_fields, bool is_deterministic, - uint8* buffer) { +uint8_t* SerializeInternalToArray(const uint8_t* base, + const FieldMetadata* field_metadata_table, + int32_t num_fields, bool is_deterministic, + uint8_t* buffer) { ArrayOutput array_output = {buffer, is_deterministic}; ArrayOutput* output = &array_output; SpecialSerializer func = nullptr; for (int i = 0; i < num_fields; i++) { const FieldMetadata& field_metadata = field_metadata_table[i]; - const uint8* ptr = base + field_metadata.offset; + const uint8_t* ptr = base + field_metadata.offset; switch (field_metadata.type) { SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_DOUBLE); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FLOAT); @@ -660,6 +697,7 @@ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64); + SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType); // Special cases case FieldMetadata::kSpecial: { io::ArrayOutputStream array_stream(array_output.ptr, INT_MAX); @@ -680,14 +718,15 @@ } #undef SERIALIZERS_FOR_TYPE -void ExtensionSerializer(const uint8* ptr, uint32 offset, uint32 tag, - uint32 has_offset, io::CodedOutputStream* output) { +void ExtensionSerializer(const MessageLite* extendee, const uint8_t* ptr, + uint32_t offset, uint32_t tag, uint32_t has_offset, + io::CodedOutputStream* output) { reinterpret_cast<const ExtensionSet*>(ptr + offset) - ->SerializeWithCachedSizes(tag, has_offset, output); + ->SerializeWithCachedSizes(extendee, tag, has_offset, output); } -void UnknownFieldSerializerLite(const uint8* ptr, uint32 offset, uint32 tag, - uint32 has_offset, +void UnknownFieldSerializerLite(const uint8_t* ptr, uint32_t offset, + uint32_t tag, uint32_t has_offset, io::CodedOutputStream* output) { output->WriteString( reinterpret_cast<const InternalMetadata*>(ptr + offset) @@ -721,9 +760,7 @@ GOOGLE_DCHECK(Arena::InternalHelper<MessageLite>::GetOwningArena(submessage) == submessage_arena); GOOGLE_DCHECK(message_arena != submessage_arena); -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT GOOGLE_DCHECK_EQ(submessage_arena, nullptr); -#endif // PROTOBUF_INTERNAL_USE_MUST_USE_RESULT if (message_arena != NULL && submessage_arena == NULL) { message_arena->Own(submessage); return submessage;
diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 94c6c29..336234c 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h
@@ -132,27 +132,28 @@ return true; } -inline bool IsPresent(const void* base, uint32 hasbit) { - const uint32* has_bits_array = static_cast<const uint32*>(base); +inline bool IsPresent(const void* base, uint32_t hasbit) { + const uint32_t* has_bits_array = static_cast<const uint32_t*>(base); return (has_bits_array[hasbit / 32] & (1u << (hasbit & 31))) != 0; } -inline bool IsOneofPresent(const void* base, uint32 offset, uint32 tag) { - const uint32* oneof = - reinterpret_cast<const uint32*>(static_cast<const uint8*>(base) + offset); +inline bool IsOneofPresent(const void* base, uint32_t offset, uint32_t tag) { + const uint32_t* oneof = reinterpret_cast<const uint32_t*>( + static_cast<const uint8_t*>(base) + offset); return *oneof == tag >> 3; } -typedef void (*SpecialSerializer)(const uint8* base, uint32 offset, uint32 tag, - uint32 has_offset, +typedef void (*SpecialSerializer)(const uint8_t* base, uint32_t offset, + uint32_t tag, uint32_t has_offset, io::CodedOutputStream* output); -PROTOBUF_EXPORT void ExtensionSerializer(const uint8* base, uint32 offset, - uint32 tag, uint32 has_offset, +PROTOBUF_EXPORT void ExtensionSerializer(const MessageLite* extendee, + const uint8_t* ptr, uint32_t offset, + uint32_t tag, uint32_t has_offset, io::CodedOutputStream* output); -PROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8* base, - uint32 offset, uint32 tag, - uint32 has_offset, +PROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8_t* base, + uint32_t offset, uint32_t tag, + uint32_t has_offset, io::CodedOutputStream* output); PROTOBUF_EXPORT MessageLite* DuplicateIfNonNullInternal(MessageLite* message);
diff --git a/src/google/protobuf/has_bits.h b/src/google/protobuf/has_bits.h index 66d3cd4..acbca68 100644 --- a/src/google/protobuf/has_bits.h +++ b/src/google/protobuf/has_bits.h
@@ -53,11 +53,11 @@ memset(has_bits_, 0, sizeof(has_bits_)); } - PROTOBUF_NDEBUG_INLINE uint32& operator[](int index) { + PROTOBUF_NDEBUG_INLINE uint32_t& operator[](int index) { return has_bits_[index]; } - PROTOBUF_NDEBUG_INLINE const uint32& operator[](int index) const { + PROTOBUF_NDEBUG_INLINE const uint32_t& operator[](int index) const { return has_bits_[index]; } @@ -76,7 +76,7 @@ bool empty() const; private: - uint32 has_bits_[doublewords]; + uint32_t has_bits_[doublewords]; }; template <>
diff --git a/src/google/protobuf/implicit_weak_message.h b/src/google/protobuf/implicit_weak_message.h index bfa6a81..561e472 100644 --- a/src/google/protobuf/implicit_weak_message.h +++ b/src/google/protobuf/implicit_weak_message.h
@@ -80,8 +80,8 @@ size_t ByteSizeLong() const override { return data_.size(); } - uint8* _InternalSerialize(uint8* target, - io::EpsCopyOutputStream* stream) const final { + uint8_t* _InternalSerialize(uint8_t* target, + io::EpsCopyOutputStream* stream) const final { return stream->WriteRaw(data_.data(), static_cast<int>(data_.size()), target); }
diff --git a/src/google/protobuf/inlined_string_field.cc b/src/google/protobuf/inlined_string_field.cc new file mode 100644 index 0000000..0d16869 --- /dev/null +++ b/src/google/protobuf/inlined_string_field.cc
@@ -0,0 +1,110 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/inlined_string_field.h> + +#include <google/protobuf/parse_context.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/message_lite.h> + +// clang-format off +#include <google/protobuf/port_def.inc> +// clang-format on + +namespace google { +namespace protobuf { +namespace internal { + + +std::string* InlinedStringField::Mutable(const LazyString& /*default_value*/, + Arena* arena, bool donated, + uint32_t* donating_states, + uint32_t mask) { + if (arena == nullptr || !donated) { + return UnsafeMutablePointer(); + } + return MutableSlow(arena, donated, donating_states, mask); +} + +std::string* InlinedStringField::Mutable(ArenaStringPtr::EmptyDefault, + Arena* arena, bool donated, + uint32_t* donating_states, + uint32_t mask) { + if (arena == nullptr || !donated) { + return UnsafeMutablePointer(); + } + return MutableSlow(arena, donated, donating_states, mask); +} + +std::string* InlinedStringField::MutableSlow(::google::protobuf::Arena* arena, + bool donated, + uint32_t* donating_states, + uint32_t mask) { + return UnsafeMutablePointer(); +} + +void InlinedStringField::SetAllocated(const std::string* default_value, + std::string* value, Arena* arena, + bool donated, uint32_t* donating_states, + uint32_t mask) { + SetAllocatedNoArena(default_value, value); +} + +void InlinedStringField::Set(const std::string* default_value, + std::string&& value, Arena* arena, bool donated, + uint32_t* donating_states, uint32_t mask) { + SetNoArena(default_value, std::move(value)); +} + +std::string* InlinedStringField::Release(const std::string* default_value, + Arena* arena, bool donated) { + if (arena == nullptr && !donated) { + return ReleaseNonDefaultNoArena(default_value); + } + return ReleaseNonDefault(default_value, arena); +} + +std::string* InlinedStringField::ReleaseNonDefault( + const std::string* default_value, Arena* arena) { + return ReleaseNonDefaultNoArena(default_value); +} + +void InlinedStringField::ClearToDefault(const LazyString& default_value, + Arena* arena, bool donated) { + (void)arena; + get_mutable()->assign(default_value.get()); +} + + +} // namespace internal +} // namespace protobuf +} // namespace google
diff --git a/src/google/protobuf/inlined_string_field.h b/src/google/protobuf/inlined_string_field.h new file mode 100644 index 0000000..9f45511 --- /dev/null +++ b/src/google/protobuf/inlined_string_field.h
@@ -0,0 +1,379 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__ +#define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__ + +#include <string> +#include <utility> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/port.h> +#include <google/protobuf/stubs/strutil.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + +namespace google { +namespace protobuf { + +class Arena; + +namespace internal { + +// InlinedStringField wraps a std::string instance and exposes an API similar to +// ArenaStringPtr's wrapping of a std::string* instance. +// +// default_value parameters are taken for consistency with ArenaStringPtr, but +// are not used for most methods. With inlining, these should be removed from +// the generated binary. +// +// InlinedStringField has a donating mechanism that allows string buffer +// allocated on arena. A string is donated means both the string container and +// the data buffer are on arena. The donating mechanism here is similar to the +// one in ArenaStringPtr with some differences: +// +// When an InlinedStringField is constructed, the donating state is true. This +// is because the string container is directly stored in the message on the +// arena: +// +// Construction: donated=true +// Arena: +// +-----------------------+ +// |Message foo: | +// | +-------------------+ | +// | |InlinedStringField:| | +// | | +-----+ | | +// | | | | | | | | +// | | +-----+ | | +// | +-------------------+ | +// +-----------------------+ +// +// When lvalue Set is called, the donating state is still true. String data will +// be allocated on the arena: +// +// Lvalue Set: donated=true +// Arena: +// +-----------------------+ +// |Message foo: | +// | +-------------------+ | +// | |InlinedStringField:| | +// | | +-----+ | | +// | | | | | | | | +// | | +|----+ | | +// | +--|----------------+ | +// | V | +// | +----------------+ | +// | |'f','o','o',... | | +// | +----------------+ | +// +-----------------------+ +// +// Some operations will undonate a donated string, including: Mutable, +// SetAllocated, Rvalue Set, and Swap with a non-donated string. +// +// For more details of the donating states transitions, go/pd-inlined-string. +class PROTOBUF_EXPORT InlinedStringField { + public: + InlinedStringField() { Init(); } + inline void Init() { new (get_mutable()) std::string(); } + // Add the dummy parameter just to make InlinedStringField(nullptr) + // unambiguous. + constexpr InlinedStringField( + const ExplicitlyConstructed<std::string>* /*default_value*/, + bool /*dummy*/) + : value_{} {} + explicit InlinedStringField(const std::string& default_value); + explicit InlinedStringField(Arena* arena); + ~InlinedStringField() { Destruct(); } + + // Lvalue Set. To save space, we pack the donating states of multiple + // InlinedStringFields into an uint32_t `donating_states`. The `mask` + // indicates the position of the bit for this InlinedStringField. `donated` is + // whether this field is donated. + // + // The caller should guarantee that: + // + // `donated == ((donating_states & ~mask) != 0)` + // + // This method never changes the `donating_states`. + void Set(const std::string* default_value, ConstStringParam value, + Arena* arena, bool donated, uint32_t* /*donating_states*/, + uint32_t /*mask*/) { + (void)arena; + (void)donated; + SetNoArena(default_value, value); + } + + // Rvalue Set. If this field is donated, this method will undonate this field + // by mutating the `donating_states` according to `mask`. + void Set(const std::string* default_value, std::string&& value, Arena* arena, + bool donated, uint32_t* donating_states, uint32_t mask); + + template <typename FirstParam> + void Set(FirstParam p1, const char* str, ::google::protobuf::Arena* arena, bool donated, + uint32_t* donating_states, uint32_t mask) { + Set(p1, ConstStringParam(str), arena, donated, donating_states, mask); + } + + template <typename FirstParam> + void Set(FirstParam p1, const char* str, size_t size, ::google::protobuf::Arena* arena, + bool donated, uint32_t* donating_states, uint32_t mask) { + ConstStringParam sp{str, size}; // for string_view and `const string &` + Set(p1, sp, arena, donated, donating_states, mask); + } + + template <typename FirstParam, typename RefWrappedType> + void Set(FirstParam p1, + std::reference_wrapper<RefWrappedType> const_string_ref, + ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states, + uint32_t mask) { + Set(p1, const_string_ref.get(), arena, donated, donating_states, mask); + } + + template <typename FirstParam, typename SecondParam> + void SetBytes(FirstParam p1, SecondParam&& p2, ::google::protobuf::Arena* arena, + bool donated, uint32_t* donating_states, uint32_t mask) { + Set(p1, static_cast<SecondParam&&>(p2), arena, donated, donating_states, + mask); + } + + template <typename FirstParam> + void SetBytes(FirstParam p1, const void* str, size_t size, + ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states, + uint32_t mask) { + // Must work whether ConstStringParam is string_view or `const string &` + ConstStringParam sp{static_cast<const char*>(str), size}; + Set(p1, sp, arena, donated, donating_states, mask); + } + + PROTOBUF_NDEBUG_INLINE void SetNoArena(const std::string* default_value, + StringPiece value); + PROTOBUF_NDEBUG_INLINE void SetNoArena(const std::string* default_value, + std::string&& value); + + // Basic accessors. + PROTOBUF_NDEBUG_INLINE const std::string& Get() const { return GetNoArena(); } + PROTOBUF_NDEBUG_INLINE const std::string& GetNoArena() const; + + // Mutable returns a std::string* instance that is heap-allocated. If this + // field is donated, this method undonates this field by mutating the + // `donating_states` according to `mask`, and copies the content of the + // original string to the returning string. + std::string* Mutable(const LazyString& default_value, Arena* arena, + bool donated, uint32_t* donating_states, uint32_t mask); + std::string* Mutable(ArenaStringPtr::EmptyDefault, Arena* arena, bool donated, + uint32_t* donating_states, uint32_t mask); + + // Release returns a std::string* instance that is heap-allocated and is not + // Own()'d by any arena. If the field is not set, this returns NULL. The + // caller retains ownership. Clears this field back to NULL state. Used to + // implement release_<field>() methods on generated classes. + PROTOBUF_MUST_USE_RESULT std::string* Release( + const std::string* default_value, Arena* arena, bool donated); + PROTOBUF_MUST_USE_RESULT std::string* ReleaseNonDefault( + const std::string* default_value, Arena* arena); + std::string* ReleaseNonDefaultNoArena(const std::string* default_value); + + // Takes a std::string that is heap-allocated, and takes ownership. The + // std::string's destructor is registered with the arena. Used to implement + // set_allocated_<field> in generated classes. + // + // If this field is donated, this method undonates this field by mutating the + // `donating_states` according to `mask`. + void SetAllocated(const std::string* default_value, std::string* value, + Arena* arena, bool donated, uint32_t* donating_states, + uint32_t mask); + + void SetAllocatedNoArena(const std::string* default_value, + std::string* value); + + // When one of `this` and `from` is donated and the other is not donated, this + // method will undonate the donated one and swap the two heap-allocated + // strings. + PROTOBUF_NDEBUG_INLINE void Swap(InlinedStringField* from, + const std::string* default_value, + Arena* arena, bool donated, + bool from_donated, uint32_t* donating_states, + uint32_t* from_donating_states, + uint32_t mask); + + // Frees storage (if not on an arena). + PROTOBUF_NDEBUG_INLINE void Destroy(const std::string* default_value, + Arena* arena) { + if (arena == nullptr) { + DestroyNoArena(default_value); + } + } + PROTOBUF_NDEBUG_INLINE void DestroyNoArena(const std::string* default_value); + + // Clears content, but keeps allocated std::string, to avoid the overhead of + // heap operations. After this returns, the content (as seen by the user) will + // always be the empty std::string. + PROTOBUF_NDEBUG_INLINE void ClearToEmpty() { ClearNonDefaultToEmpty(); } + PROTOBUF_NDEBUG_INLINE void ClearNonDefaultToEmpty() { + get_mutable()->clear(); + } + + // Clears content, but keeps allocated std::string if arena != NULL, to avoid + // the overhead of heap operations. After this returns, the content (as seen + // by the user) will always be equal to |default_value|. + void ClearToDefault(const LazyString& default_value, Arena* arena, + bool donated); + + // Returns a mutable pointer, but doesn't initialize the string to the + // default value. + PROTOBUF_NDEBUG_INLINE std::string* MutableNoArenaNoDefault( + const std::string* /*default_value*/); + + // Generated code / reflection only! Returns a mutable pointer to the string. + PROTOBUF_NDEBUG_INLINE std::string* UnsafeMutablePointer(); + + // InlinedStringField doesn't have things like the `default_value` pointer in + // ArenaStringPtr. + bool IsDefault(const std::string* /*default_value*/) const { return false; } + + private: + void Destruct() { get_mutable()->~basic_string(); } + + PROTOBUF_NDEBUG_INLINE std::string* get_mutable(); + PROTOBUF_NDEBUG_INLINE const std::string* get_const() const; + + alignas(std::string) char value_[sizeof(std::string)]; + + std::string* MutableSlow(::google::protobuf::Arena* arena, bool donated, + uint32_t* donating_states, uint32_t mask); + + + // When constructed in an Arena, we want our destructor to be skipped. + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; +}; + +inline std::string* InlinedStringField::get_mutable() { + return reinterpret_cast<std::string*>(&value_); +} + +inline const std::string* InlinedStringField::get_const() const { + return reinterpret_cast<const std::string*>(&value_); +} + +inline InlinedStringField::InlinedStringField( + const std::string& default_value) { + new (get_mutable()) std::string(default_value); +} + +inline InlinedStringField::InlinedStringField(Arena* /*arena*/) { Init(); } + +inline const std::string& InlinedStringField::GetNoArena() const { + return *get_const(); +} + +inline void InlinedStringField::SetAllocatedNoArena( + const std::string* /*default_value*/, std::string* value) { + if (value == nullptr) { + // Currently, inlined string field can't have non empty default. + get_mutable()->clear(); + } else { + get_mutable()->assign(std::move(*value)); + delete value; + } +} + +inline void InlinedStringField::DestroyNoArena(const std::string*) { + // This is invoked from the generated message's ArenaDtor, which is used to + // clean up objects not allocated on the Arena. + this->~InlinedStringField(); +} + +inline std::string* InlinedStringField::ReleaseNonDefaultNoArena( + const std::string* /*default_value*/) { + // Currently, inlined string field can't have non empty default. + auto* released = new std::string(); + get_mutable()->swap(*released); + return released; +} + +inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/, + StringPiece value) { + get_mutable()->assign(value.data(), value.length()); +} + +inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/, + std::string&& value) { + get_mutable()->assign(std::move(value)); +} + +inline void InlinedStringField::Swap( + InlinedStringField* from, const std::string* /*default_value*/, + Arena* arena, bool donated, bool from_donated, uint32_t* donating_states, + uint32_t* from_donating_states, uint32_t mask) { +#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE + // If one is donated and the other is not, undonate the donated one. + if (donated && !from_donated) { + MutableSlow(arena, donated, donating_states, mask); + } else if (!donated && from_donated) { + from->MutableSlow(arena, from_donated, from_donating_states, mask); + } + // Then, swap the two undonated strings. +#else + (void)arena; + (void)donated; + (void)from_donated; + (void)donating_states; + (void)from_donating_states; + (void)mask; +#endif + get_mutable()->swap(*from->get_mutable()); +} + +inline std::string* InlinedStringField::MutableNoArenaNoDefault( + const std::string*) { + return get_mutable(); +} + +inline std::string* InlinedStringField::UnsafeMutablePointer() { + return get_mutable(); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
diff --git a/src/google/protobuf/inlined_string_field_unittest.cc b/src/google/protobuf/inlined_string_field_unittest.cc new file mode 100644 index 0000000..52affbd --- /dev/null +++ b/src/google/protobuf/inlined_string_field_unittest.cc
@@ -0,0 +1,286 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/inlined_string_field.h> + +#include <algorithm> +#include <cstdlib> +#include <cstring> +#include <memory> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/arenastring.h> +#include <gtest/gtest.h> +#include <google/protobuf/stubs/strutil.h> + + +namespace google { +namespace protobuf { + +using internal::ArenaStringPtr; +using internal::InlinedStringField; + +static std::string WrapString(const char* value) { return value; } + +namespace { + +const uint32 kMask = ~0x00000001u; +const uint32 kMask1 = ~0x00000004u; +const uint32 kMask2 = ~0x00000020u; + +TEST(InlinedStringFieldTest, SetOnHeap) { + InlinedStringField field; + uint32 donating_states = 0; + const std::string kDefaultValue = "default"; + field.Set(&kDefaultValue, WrapString("Test short"), nullptr, false, + &donating_states, kMask); + EXPECT_EQ(std::string("Test short"), field.Get()); + field.Set(&kDefaultValue, WrapString("Test long long long long value"), + nullptr, false, &donating_states, kMask); + EXPECT_EQ(std::string("Test long long long long value"), field.Get()); +} + +TEST(InlinedStringFieldTest, SetRvalueOnHeap) { + InlinedStringField field; + uint32 donating_states = 0; + std::string string_moved = "Moved long long long long string 1"; + field.Set(nullptr, std::move(string_moved), nullptr, false, &donating_states, + kMask); + EXPECT_EQ("Moved long long long long string 1", field.Get()); + EXPECT_EQ(donating_states & ~kMask1, 0); +} + +TEST(InlinedStringFieldTest, UnsafeMutablePointerThenRelease) { + InlinedStringField field; + const std::string kDefaultValue = "default"; + std::string* mut = field.UnsafeMutablePointer(); + // The address of inlined string doesn't change behind the scene. + EXPECT_EQ(mut, field.UnsafeMutablePointer()); + EXPECT_EQ(mut, &field.Get()); + EXPECT_EQ(std::string(""), *mut); + *mut = "Test long long long long value"; // ensure string allocates + EXPECT_EQ(std::string("Test long long long long value"), field.Get()); + + std::string* released = field.ReleaseNonDefaultNoArena(&kDefaultValue); + EXPECT_EQ("Test long long long long value", *released); + // Default value is ignored. + EXPECT_EQ("", field.Get()); + delete released; +} + +// When donating mechanism is enabled: +// - Initially, the string is donated. +// - After lvalue Set: the string is still donated. +// - After Mutable: the string is undonated. The data buffer of the string is a +// new buffer on the heap. +TEST(InlinedStringFieldTest, ArenaSetThenMutable) { + Arena arena; + auto* field_arena = Arena::CreateMessage<InlinedStringField>(&arena); + uint32 donating_states = ~0u; + const std::string kDefaultValue = "default"; + field_arena->Set(&kDefaultValue, WrapString("Test short"), &arena, + /*donated=*/true, &donating_states, kMask1); + EXPECT_EQ(std::string("Test short"), field_arena->Get()); + field_arena->Set(&kDefaultValue, "Test long long long long value", &arena, + /*donated=*/(donating_states & ~kMask1) != 0, + &donating_states, kMask1); + EXPECT_EQ(std::string("Test long long long long value"), field_arena->Get()); +#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE + EXPECT_NE(donating_states & ~kMask1, 0); // donate. +#endif + + const std::string* old_string = &field_arena->Get(); + const char* old_data = old_string->data(); + (void)old_data; + std::string* mut = field_arena->Mutable( + ArenaStringPtr::EmptyDefault{}, &arena, + /*donated=*/(donating_states & ~kMask1) != 0, &donating_states, kMask1); + EXPECT_EQ(old_string, mut); +#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE + EXPECT_EQ(donating_states & ~kMask1, 0); + EXPECT_NE(old_data, mut->data()); // The data buffer of the mutated string is + // a new buffer on the heap. +#endif + *mut = "Test an even longer long long long long value"; + EXPECT_EQ(std::string("Test an even longer long long long long value"), + field_arena->Get()); + EXPECT_EQ(&field_arena->Get(), mut); +} + +// Release doesn't change the donating state. +// When donating mechanism is enabled: +// - Initially, the string is donated. +// - Then lvalue Set: the string is still donated. +// - Then Release: the string is cleared, and still donated. +// - Then Mutable: the string is undonated. +// - Then Release: the string is still undonated. +TEST(InlinedStringFieldTest, ArenaRelease) { + Arena arena; + auto* field_arena = Arena::CreateMessage<InlinedStringField>(&arena); + uint32 donating_states = ~0u; + const std::string kDefaultValue = "default"; + field_arena->Set(&kDefaultValue, WrapString("Test short"), &arena, + /*donated=*/true, &donating_states, kMask1); + std::string* released = field_arena->Release( + &kDefaultValue, &arena, /*donated=*/(donating_states & ~kMask1) != 0); + EXPECT_EQ("Test short", *released); + EXPECT_EQ("", field_arena->Get()); + EXPECT_NE(released, &field_arena->Get()); +#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE + EXPECT_NE(donating_states & ~kMask1, 0); // still donated. +#endif + delete released; + + std::string* mut = field_arena->Mutable( + ArenaStringPtr::EmptyDefault{}, &arena, + /*donated=*/(donating_states & ~kMask1) != 0u, &donating_states, kMask1); + *mut = "Test long long long long value"; + std::string* released2 = + field_arena->Release(&kDefaultValue, &arena, + /*donated=*/(donating_states & ~kMask1) != 0); + EXPECT_EQ("Test long long long long value", *released2); + EXPECT_EQ("", field_arena->Get()); +#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE + EXPECT_EQ(donating_states & ~kMask1, 0); // undonated. +#endif + delete released2; +} + +// Rvalue Set always undoantes a donated string. +TEST(InlinedStringFieldTest, SetRvalueArena) { + Arena arena; + auto* field1_arena = Arena::CreateMessage<InlinedStringField>(&arena); + auto* field2_arena = Arena::CreateMessage<InlinedStringField>(&arena); + uint32 donating_states = ~0u; + const std::string kDefaultValue = "default"; + + std::string string_moved = "Moved long long long long string 1"; + field1_arena->Set(nullptr, std::move(string_moved), &arena, true, + &donating_states, kMask1); + EXPECT_EQ("Moved long long long long string 1", field1_arena->Get()); +#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE + EXPECT_EQ(donating_states & ~kMask1, 0); // Undonate. +#endif + + field2_arena->Set(nullptr, std::string("string 2 on heap"), &arena, true, + &donating_states, kMask); + EXPECT_EQ("string 2 on heap", field2_arena->Get()); +#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE + EXPECT_EQ(donating_states & ~kMask, 0); // Undonated. +#endif +} + +// Tests SetAllocated for non-arena string fields and arena string fields. +TEST(InlinedStringFieldTest, SetAllocated) { + InlinedStringField field; + Arena arena; + auto* field1_arena = Arena::CreateMessage<InlinedStringField>(&arena); + auto* field2_arena = Arena::CreateMessage<InlinedStringField>(&arena); + uint32 donating_states = ~0u; + const std::string kDefaultValue = "default"; + + // The string in field is on heap. + field.Set(&kDefaultValue, WrapString("String on heap"), nullptr, false, + &donating_states, kMask); + auto* allocated = new std::string("Allocated string on heap"); + field.SetAllocatedNoArena(&kDefaultValue, allocated); + EXPECT_EQ("Allocated string on heap", field.Get()); + + // The string in field1_arena is on arena (aka. donated). + field1_arena->Set(&kDefaultValue, WrapString("String 1 on arena"), &arena, + true, &donating_states, kMask1); + *field1_arena->Mutable(ArenaStringPtr::EmptyDefault{}, &arena, + (donating_states & ~kMask1) != 0, &donating_states, + kMask1) = "Mutated string 1 is now on heap long long"; + // After Mutable, the string is undonated. + allocated = new std::string("Allocated string on heap long long long"); + field1_arena->SetAllocated(&kDefaultValue, allocated, &arena, + (donating_states & ~kMask1) != 0, &donating_states, + kMask1); + EXPECT_EQ("Allocated string on heap long long long", field1_arena->Get()); +#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE + EXPECT_EQ(donating_states & ~kMask1, 0); // Still undonated. +#endif + + // The string in field2_arena is on arena (aka. donated). + field2_arena->Set(&kDefaultValue, WrapString("String 2 on arena long long"), + &arena, true, &donating_states, + kMask2); // Still donated. + allocated = new std::string("Allocated string on heap long long long 2"); + field2_arena->SetAllocated(&kDefaultValue, allocated, &arena, true, + &donating_states, kMask2); + EXPECT_EQ("Allocated string on heap long long long 2", field2_arena->Get()); +#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE + EXPECT_EQ(donating_states & ~kMask2, 0); // Undonated. +#endif +} + +// Tests Swap for non-arena string fields and arena string fields. +TEST(InlinedStringFieldTest, Swap) { + // Swap should only be called when the from and to are on the same arena. + InlinedStringField field1; + InlinedStringField field2; + uint32 donating_states = 0; + Arena arena; + auto* field1_arena = Arena::CreateMessage<InlinedStringField>(&arena); + auto* field2_arena = Arena::CreateMessage<InlinedStringField>(&arena); + uint32 donating_states_1 = ~0u; + uint32 donating_states_2 = ~0u; + const std::string kDefaultValue = "default"; + + const std::string& string1_heap = "String 1 on heap"; + const std::string& string2_heap = "String 2 on heap long long long long"; + const std::string& string1_arena = "String 1 on arena"; + const std::string& string2_arena = "String 2 on arena long long long long"; + field1.SetNoArena(&kDefaultValue, string1_heap); + field2.SetNoArena(&kDefaultValue, string2_heap); + field1_arena->Set(&kDefaultValue, string1_arena, &arena, true, + &donating_states_1, kMask1); + field2_arena->Set(&kDefaultValue, string2_arena, &arena, true, + &donating_states_2, kMask1); + + field1.Swap(&field2, &kDefaultValue, nullptr, false, false, &donating_states, + &donating_states_2, kMask); + field1_arena->Swap(field2_arena, &kDefaultValue, &arena, true, true, + &donating_states_1, &donating_states_2, kMask1); + EXPECT_EQ(field1.Get(), string2_heap); + EXPECT_EQ(field2.Get(), string1_heap); + EXPECT_EQ(field1_arena->Get(), string2_arena); + EXPECT_EQ(field2_arena->Get(), string1_arena); +} + +} // namespace +} // namespace protobuf +} // namespace google
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index a318da4..1b80068 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc
@@ -151,7 +151,7 @@ } CodedInputStream::Limit CodedInputStream::ReadLengthAndPushLimit() { - uint32 length; + uint32_t length; return PushLimit(ReadVarint32(&length) ? length : 0); } @@ -243,7 +243,7 @@ while ((current_buffer_size = BufferSize()) < size) { // Reading past end of buffer. Copy what we have, then refresh. memcpy(buffer, buffer_, current_buffer_size); - buffer = reinterpret_cast<uint8*>(buffer) + current_buffer_size; + buffer = reinterpret_cast<uint8_t*>(buffer) + current_buffer_size; size -= current_buffer_size; Advance(current_buffer_size); if (!Refresh()) return false; @@ -308,11 +308,11 @@ } -bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) { - uint8 bytes[sizeof(*value)]; +bool CodedInputStream::ReadLittleEndian32Fallback(uint32_t* value) { + uint8_t bytes[sizeof(*value)]; - const uint8* ptr; - if (BufferSize() >= static_cast<int64>(sizeof(*value))) { + const uint8_t* ptr; + if (BufferSize() >= static_cast<int64_t>(sizeof(*value))) { // Fast path: Enough bytes in the buffer to read directly. ptr = buffer_; Advance(sizeof(*value)); @@ -325,11 +325,11 @@ return true; } -bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) { - uint8 bytes[sizeof(*value)]; +bool CodedInputStream::ReadLittleEndian64Fallback(uint64_t* value) { + uint8_t bytes[sizeof(*value)]; - const uint8* ptr; - if (BufferSize() >= static_cast<int64>(sizeof(*value))) { + const uint8_t* ptr; + if (BufferSize() >= static_cast<int64_t>(sizeof(*value))) { // Fast path: Enough bytes in the buffer to read directly. ptr = buffer_; Advance(sizeof(*value)); @@ -348,11 +348,11 @@ // compile time, compiler can generate optimal code. For example, instead of // subtracting 0x80 at each iteration, it subtracts properly shifted mask once. template <size_t N> -const uint8* DecodeVarint64KnownSize(const uint8* buffer, uint64* value) { +const uint8_t* DecodeVarint64KnownSize(const uint8_t* buffer, uint64_t* value) { GOOGLE_DCHECK_GT(N, 0); - uint64 result = static_cast<uint64>(buffer[N - 1]) << (7 * (N - 1)); + uint64_t result = static_cast<uint64_t>(buffer[N - 1]) << (7 * (N - 1)); for (size_t i = 0, offset = 0; i < N - 1; i++, offset += 7) { - result += static_cast<uint64>(buffer[i] - 0x80) << offset; + result += static_cast<uint64_t>(buffer[i] - 0x80) << offset; } *value = result; return buffer + N; @@ -363,18 +363,18 @@ // part is buffer + (number of bytes read). This function is always inlined, // so returning a pair is costless. PROTOBUF_ALWAYS_INLINE -::std::pair<bool, const uint8*> ReadVarint32FromArray(uint32 first_byte, - const uint8* buffer, - uint32* value); -inline ::std::pair<bool, const uint8*> ReadVarint32FromArray( - uint32 first_byte, const uint8* buffer, uint32* value) { +::std::pair<bool, const uint8_t*> ReadVarint32FromArray(uint32_t first_byte, + const uint8_t* buffer, + uint32_t* value); +inline ::std::pair<bool, const uint8_t*> ReadVarint32FromArray( + uint32_t first_byte, const uint8_t* buffer, uint32_t* value) { // Fast path: We have enough bytes left in the buffer to guarantee that // this read won't cross the end, so we can skip the checks. GOOGLE_DCHECK_EQ(*buffer, first_byte); GOOGLE_DCHECK_EQ(first_byte & 0x80, 0x80) << first_byte; - const uint8* ptr = buffer; - uint32 b; - uint32 result = first_byte - 0x80; + const uint8_t* ptr = buffer; + uint32_t b; + uint32_t result = first_byte - 0x80; ++ptr; // We just processed the first byte. Move on to the second. b = *(ptr++); result += b << 7; @@ -409,14 +409,14 @@ return std::make_pair(true, ptr); } -PROTOBUF_ALWAYS_INLINE::std::pair<bool, const uint8*> ReadVarint64FromArray( - const uint8* buffer, uint64* value); -inline ::std::pair<bool, const uint8*> ReadVarint64FromArray( - const uint8* buffer, uint64* value) { +PROTOBUF_ALWAYS_INLINE::std::pair<bool, const uint8_t*> ReadVarint64FromArray( + const uint8_t* buffer, uint64_t* value); +inline ::std::pair<bool, const uint8_t*> ReadVarint64FromArray( + const uint8_t* buffer, uint64_t* value) { // Assumes varint64 is at least 2 bytes. GOOGLE_DCHECK_GE(buffer[0], 128); - const uint8* next; + const uint8_t* next; if (buffer[1] < 128) { next = DecodeVarint64KnownSize<2>(buffer, value); } else if (buffer[2] < 128) { @@ -446,23 +446,23 @@ } // namespace -bool CodedInputStream::ReadVarint32Slow(uint32* value) { +bool CodedInputStream::ReadVarint32Slow(uint32_t* value) { // Directly invoke ReadVarint64Fallback, since we already tried to optimize // for one-byte varints. - std::pair<uint64, bool> p = ReadVarint64Fallback(); - *value = static_cast<uint32>(p.first); + std::pair<uint64_t, bool> p = ReadVarint64Fallback(); + *value = static_cast<uint32_t>(p.first); return p.second; } -int64 CodedInputStream::ReadVarint32Fallback(uint32 first_byte_or_zero) { +int64_t CodedInputStream::ReadVarint32Fallback(uint32_t first_byte_or_zero) { if (BufferSize() >= kMaxVarintBytes || // Optimization: We're also safe if the buffer is non-empty and it ends // with a byte that would terminate a varint. (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { GOOGLE_DCHECK_NE(first_byte_or_zero, 0) << "Caller should provide us with *buffer_ when buffer is non-empty"; - uint32 temp; - ::std::pair<bool, const uint8*> p = + uint32_t temp; + ::std::pair<bool, const uint8_t*> p = ReadVarint32FromArray(first_byte_or_zero, buffer_, &temp); if (!p.first) return -1; buffer_ = p.second; @@ -471,16 +471,16 @@ // Really slow case: we will incur the cost of an extra function call here, // but moving this out of line reduces the size of this function, which // improves the common case. In micro benchmarks, this is worth about 10-15% - uint32 temp; - return ReadVarint32Slow(&temp) ? static_cast<int64>(temp) : -1; + uint32_t temp; + return ReadVarint32Slow(&temp) ? static_cast<int64_t>(temp) : -1; } } int CodedInputStream::ReadVarintSizeAsIntSlow() { // Directly invoke ReadVarint64Fallback, since we already tried to optimize // for one-byte varints. - std::pair<uint64, bool> p = ReadVarint64Fallback(); - if (!p.second || p.first > static_cast<uint64>(INT_MAX)) return -1; + std::pair<uint64_t, bool> p = ReadVarint64Fallback(); + if (!p.second || p.first > static_cast<uint64_t>(INT_MAX)) return -1; return p.first; } @@ -489,9 +489,9 @@ // Optimization: We're also safe if the buffer is non-empty and it ends // with a byte that would terminate a varint. (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { - uint64 temp; - ::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp); - if (!p.first || temp > static_cast<uint64>(INT_MAX)) return -1; + uint64_t temp; + ::std::pair<bool, const uint8_t*> p = ReadVarint64FromArray(buffer_, &temp); + if (!p.first || temp > static_cast<uint64_t>(INT_MAX)) return -1; buffer_ = p.second; return temp; } else { @@ -502,7 +502,7 @@ } } -uint32 CodedInputStream::ReadTagSlow() { +uint32_t CodedInputStream::ReadTagSlow() { if (buffer_ == buffer_end_) { // Call refresh. if (!Refresh()) { @@ -523,12 +523,12 @@ // For the slow path, just do a 64-bit read. Try to optimize for one-byte tags // again, since we have now refreshed the buffer. - uint64 result = 0; + uint64_t result = 0; if (!ReadVarint64(&result)) return 0; - return static_cast<uint32>(result); + return static_cast<uint32_t>(result); } -uint32 CodedInputStream::ReadTagFallback(uint32 first_byte_or_zero) { +uint32_t CodedInputStream::ReadTagFallback(uint32_t first_byte_or_zero) { const int buf_size = BufferSize(); if (buf_size >= kMaxVarintBytes || // Optimization: We're also safe if the buffer is non-empty and it ends @@ -539,8 +539,8 @@ ++buffer_; return 0; } - uint32 tag; - ::std::pair<bool, const uint8*> p = + uint32_t tag; + ::std::pair<bool, const uint8_t*> p = ReadVarint32FromArray(first_byte_or_zero, buffer_, &tag); if (!p.first) { return 0; @@ -565,13 +565,13 @@ } } -bool CodedInputStream::ReadVarint64Slow(uint64* value) { +bool CodedInputStream::ReadVarint64Slow(uint64_t* value) { // Slow path: This read might cross the end of the buffer, so we // need to check and refresh the buffer if and when it does. - uint64 result = 0; + uint64_t result = 0; int count = 0; - uint32 b; + uint32_t b; do { if (count == kMaxVarintBytes) { @@ -585,7 +585,7 @@ } } b = *buffer_; - result |= static_cast<uint64>(b & 0x7F) << (7 * count); + result |= static_cast<uint64_t>(b & 0x7F) << (7 * count); Advance(1); ++count; } while (b & 0x80); @@ -594,20 +594,20 @@ return true; } -std::pair<uint64, bool> CodedInputStream::ReadVarint64Fallback() { +std::pair<uint64_t, bool> CodedInputStream::ReadVarint64Fallback() { if (BufferSize() >= kMaxVarintBytes || // Optimization: We're also safe if the buffer is non-empty and it ends // with a byte that would terminate a varint. (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { - uint64 temp; - ::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp); + uint64_t temp; + ::std::pair<bool, const uint8_t*> p = ReadVarint64FromArray(buffer_, &temp); if (!p.first) { return std::make_pair(0, false); } buffer_ = p.second; return std::make_pair(temp, true); } else { - uint64 temp; + uint64_t temp; bool success = ReadVarint64Slow(&temp); return std::make_pair(temp, success); } @@ -633,7 +633,7 @@ const void* void_buffer; int buffer_size; if (NextNonEmpty(input_, &void_buffer, &buffer_size)) { - buffer_ = reinterpret_cast<const uint8*>(void_buffer); + buffer_ = reinterpret_cast<const uint8_t*>(void_buffer); buffer_end_ = buffer_ + buffer_size; GOOGLE_CHECK_GE(buffer_size, 0); @@ -670,7 +670,7 @@ aliasing_enabled_ = enabled && stream_->AllowsAliasing(); } -int64 EpsCopyOutputStream::ByteCount(uint8* ptr) const { +int64_t EpsCopyOutputStream::ByteCount(uint8_t* ptr) const { // Calculate the current offset relative to the end of the stream buffer. int delta = (end_ - ptr) + (buffer_end_ ? 0 : kSlopBytes); return stream_->ByteCount() - delta; @@ -679,7 +679,7 @@ // Flushes what's written out to the underlying ZeroCopyOutputStream buffers. // Returns the size remaining in the buffer and sets buffer_end_ to the start // of the remaining buffer, ie. [buffer_end_, buffer_end_ + return value) -int EpsCopyOutputStream::Flush(uint8* ptr) { +int EpsCopyOutputStream::Flush(uint8_t* ptr) { while (buffer_end_ && ptr > end_) { int overrun = ptr - end_; GOOGLE_DCHECK(!had_error_); @@ -701,7 +701,7 @@ return s; } -uint8* EpsCopyOutputStream::Trim(uint8* ptr) { +uint8_t* EpsCopyOutputStream::Trim(uint8_t* ptr) { if (had_error_) return ptr; int s = Flush(ptr); if (s) stream_->BackUp(s); @@ -711,14 +711,14 @@ } -uint8* EpsCopyOutputStream::FlushAndResetBuffer(uint8* ptr) { +uint8_t* EpsCopyOutputStream::FlushAndResetBuffer(uint8_t* ptr) { if (had_error_) return buffer_; int s = Flush(ptr); if (had_error_) return buffer_; return SetInitialBuffer(buffer_end_, s); } -bool EpsCopyOutputStream::Skip(int count, uint8** pp) { +bool EpsCopyOutputStream::Skip(int count, uint8_t** pp) { if (count < 0) return false; if (had_error_) { *pp = buffer_; @@ -737,12 +737,12 @@ return false; } } - *pp = SetInitialBuffer(static_cast<uint8*>(data) + count, size - count); + *pp = SetInitialBuffer(static_cast<uint8_t*>(data) + count, size - count); return true; } bool EpsCopyOutputStream::GetDirectBufferPointer(void** data, int* size, - uint8** pp) { + uint8_t** pp) { if (had_error_) { *pp = buffer_; return false; @@ -763,8 +763,8 @@ return true; } -uint8* EpsCopyOutputStream::GetDirectBufferForNBytesAndAdvance(int size, - uint8** pp) { +uint8_t* EpsCopyOutputStream::GetDirectBufferForNBytesAndAdvance(int size, + uint8_t** pp) { if (had_error_) { *pp = buffer_; return nullptr; @@ -784,13 +784,13 @@ } } -uint8* EpsCopyOutputStream::Next() { +uint8_t* EpsCopyOutputStream::Next() { GOOGLE_DCHECK(!had_error_); // NOLINT if (PROTOBUF_PREDICT_FALSE(stream_ == nullptr)) return Error(); if (buffer_end_) { // We're in the patch buffer and need to fill up the previous buffer. std::memcpy(buffer_end_, buffer_, end_ - buffer_); - uint8* ptr; + uint8_t* ptr; int size; do { void* data; @@ -799,7 +799,7 @@ // able to write. return Error(); } - ptr = static_cast<uint8*>(data); + ptr = static_cast<uint8_t*>(data); } while (size == 0); if (PROTOBUF_PREDICT_TRUE(size > kSlopBytes)) { std::memcpy(ptr, end_, kSlopBytes); @@ -822,7 +822,7 @@ } } -uint8* EpsCopyOutputStream::EnsureSpaceFallback(uint8* ptr) { +uint8_t* EpsCopyOutputStream::EnsureSpaceFallback(uint8_t* ptr) { do { if (PROTOBUF_PREDICT_FALSE(had_error_)) return buffer_; int overrun = ptr - end_; @@ -834,13 +834,13 @@ return ptr; } -uint8* EpsCopyOutputStream::WriteRawFallback(const void* data, int size, - uint8* ptr) { +uint8_t* EpsCopyOutputStream::WriteRawFallback(const void* data, int size, + uint8_t* ptr) { int s = GetSize(ptr); while (s < size) { std::memcpy(ptr, data, s); size -= s; - data = static_cast<const uint8*>(data) + s; + data = static_cast<const uint8_t*>(data) + s; ptr = EnsureSpaceFallback(ptr + s); s = GetSize(ptr); } @@ -848,8 +848,8 @@ return ptr + size; } -uint8* EpsCopyOutputStream::WriteAliasedRaw(const void* data, int size, - uint8* ptr) { +uint8_t* EpsCopyOutputStream::WriteAliasedRaw(const void* data, int size, + uint8_t* ptr) { if (size < GetSize(ptr) ) { return WriteRaw(data, size, ptr); @@ -861,13 +861,13 @@ } #ifndef PROTOBUF_LITTLE_ENDIAN -uint8* EpsCopyOutputStream::WriteRawLittleEndian32(const void* data, int size, - uint8* ptr) { - auto p = static_cast<const uint8*>(data); +uint8_t* EpsCopyOutputStream::WriteRawLittleEndian32(const void* data, int size, + uint8_t* ptr) { + auto p = static_cast<const uint8_t*>(data); auto end = p + size; while (end - p >= kSlopBytes) { ptr = EnsureSpace(ptr); - uint32 buffer[4]; + uint32_t buffer[4]; static_assert(sizeof(buffer) == kSlopBytes, "Buffer must be kSlopBytes"); std::memcpy(buffer, p, kSlopBytes); p += kSlopBytes; @@ -876,7 +876,7 @@ } while (p < end) { ptr = EnsureSpace(ptr); - uint32 buffer; + uint32_t buffer; std::memcpy(&buffer, p, 4); p += 4; ptr = CodedOutputStream::WriteLittleEndian32ToArray(buffer, ptr); @@ -884,13 +884,13 @@ return ptr; } -uint8* EpsCopyOutputStream::WriteRawLittleEndian64(const void* data, int size, - uint8* ptr) { - auto p = static_cast<const uint8*>(data); +uint8_t* EpsCopyOutputStream::WriteRawLittleEndian64(const void* data, int size, + uint8_t* ptr) { + auto p = static_cast<const uint8_t*>(data); auto end = p + size; while (end - p >= kSlopBytes) { ptr = EnsureSpace(ptr); - uint64 buffer[2]; + uint64_t buffer[2]; static_assert(sizeof(buffer) == kSlopBytes, "Buffer must be kSlopBytes"); std::memcpy(buffer, p, kSlopBytes); p += kSlopBytes; @@ -899,7 +899,7 @@ } while (p < end) { ptr = EnsureSpace(ptr); - uint64 buffer; + uint64_t buffer; std::memcpy(&buffer, p, 8); p += 8; ptr = CodedOutputStream::WriteLittleEndian64ToArray(buffer, ptr); @@ -909,19 +909,19 @@ #endif -uint8* EpsCopyOutputStream::WriteStringMaybeAliasedOutline(uint32 num, +uint8_t* EpsCopyOutputStream::WriteStringMaybeAliasedOutline(uint32_t num, const std::string& s, - uint8* ptr) { + uint8_t* ptr) { ptr = EnsureSpace(ptr); - uint32 size = s.size(); + uint32_t size = s.size(); ptr = WriteLengthDelim(num, size, ptr); return WriteRawMaybeAliased(s.data(), size, ptr); } -uint8* EpsCopyOutputStream::WriteStringOutline(uint32 num, const std::string& s, - uint8* ptr) { +uint8_t* EpsCopyOutputStream::WriteStringOutline(uint32_t num, const std::string& s, + uint8_t* ptr) { ptr = EnsureSpace(ptr); - uint32 size = s.size(); + uint32_t size = s.size(); ptr = WriteLengthDelim(num, size, ptr); return WriteRaw(s.data(), size, ptr); } @@ -944,28 +944,28 @@ CodedOutputStream::~CodedOutputStream() { Trim(); } -uint8* CodedOutputStream::WriteStringWithSizeToArray(const std::string& str, - uint8* target) { +uint8_t* CodedOutputStream::WriteStringWithSizeToArray(const std::string& str, + uint8_t* target) { GOOGLE_DCHECK_LE(str.size(), kuint32max); target = WriteVarint32ToArray(str.size(), target); return WriteStringToArray(str, target); } -uint8* CodedOutputStream::WriteVarint32ToArrayOutOfLineHelper(uint32 value, - uint8* target) { +uint8_t* CodedOutputStream::WriteVarint32ToArrayOutOfLineHelper(uint32_t value, + uint8_t* target) { GOOGLE_DCHECK_GE(value, 0x80); - target[0] |= static_cast<uint8>(0x80); + target[0] |= static_cast<uint8_t>(0x80); value >>= 7; - target[1] = static_cast<uint8>(value); + target[1] = static_cast<uint8_t>(value); if (value < 0x80) { return target + 2; } target += 2; do { // Turn on continuation bit in the byte we just wrote. - target[-1] |= static_cast<uint8>(0x80); + target[-1] |= static_cast<uint8_t>(0x80); value >>= 7; - *target = static_cast<uint8>(value); + *target = static_cast<uint8_t>(value); ++target; } while (value >= 0x80); return target;
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h index 30dc91a..40896e7 100644 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h
@@ -75,7 +75,7 @@ // return; // } // -// uint32 size; +// uint32_t size; // coded_input->ReadVarint32(&size); // // char* text = new char[size + 1]; @@ -194,7 +194,7 @@ // Create a CodedInputStream that reads from the given flat array. This is // faster than using an ArrayInputStream. PushLimit(size) is implied by // this constructor. - explicit CodedInputStream(const uint8* buffer, int size); + explicit CodedInputStream(const uint8_t* buffer, int size); // Destroy the CodedInputStream and position the underlying // ZeroCopyInputStream at the first unread byte. If an error occurred while @@ -233,25 +233,25 @@ // Read a 32-bit little-endian integer. - bool ReadLittleEndian32(uint32* value); + bool ReadLittleEndian32(uint32_t* value); // Read a 64-bit little-endian integer. - bool ReadLittleEndian64(uint64* value); + bool ReadLittleEndian64(uint64_t* value); // These methods read from an externally provided buffer. The caller is // responsible for ensuring that the buffer has sufficient space. // Read a 32-bit little-endian integer. - static const uint8* ReadLittleEndian32FromArray(const uint8* buffer, - uint32* value); + static const uint8_t* ReadLittleEndian32FromArray(const uint8_t* buffer, + uint32_t* value); // Read a 64-bit little-endian integer. - static const uint8* ReadLittleEndian64FromArray(const uint8* buffer, - uint64* value); + static const uint8_t* ReadLittleEndian64FromArray(const uint8_t* buffer, + uint64_t* value); // Read an unsigned integer with Varint encoding, truncating to 32 bits. // Reading a 32-bit value is equivalent to reading a 64-bit one and casting - // it to uint32, but may be more efficient. - bool ReadVarint32(uint32* value); + // it to uint32_t, but may be more efficient. + bool ReadVarint32(uint32_t* value); // Read an unsigned integer with Varint encoding. - bool ReadVarint64(uint64* value); + bool ReadVarint64(uint64_t* value); // Reads a varint off the wire into an "int". This should be used for reading // sizes off the wire (sizes of strings, submessages, bytes fields, etc). @@ -272,11 +272,11 @@ // Always inline because this is only called in one place per parse loop // but it is called for every iteration of said loop, so it should be fast. // GCC doesn't want to inline this by default. - PROTOBUF_ALWAYS_INLINE uint32 ReadTag() { + PROTOBUF_ALWAYS_INLINE uint32_t ReadTag() { return last_tag_ = ReadTagNoLastTag(); } - PROTOBUF_ALWAYS_INLINE uint32 ReadTagNoLastTag(); + PROTOBUF_ALWAYS_INLINE uint32_t ReadTagNoLastTag(); // This usually a faster alternative to ReadTag() when cutoff is a manifest // constant. It does particularly well for cutoff >= 127. The first part @@ -287,14 +287,14 @@ // because that can arise in several ways, and for best performance we want // to avoid an extra "is tag == 0?" check here.) PROTOBUF_ALWAYS_INLINE - std::pair<uint32, bool> ReadTagWithCutoff(uint32 cutoff) { - std::pair<uint32, bool> result = ReadTagWithCutoffNoLastTag(cutoff); + std::pair<uint32_t, bool> ReadTagWithCutoff(uint32_t cutoff) { + std::pair<uint32_t, bool> result = ReadTagWithCutoffNoLastTag(cutoff); last_tag_ = result.first; return result; } PROTOBUF_ALWAYS_INLINE - std::pair<uint32, bool> ReadTagWithCutoffNoLastTag(uint32 cutoff); + std::pair<uint32_t, bool> ReadTagWithCutoffNoLastTag(uint32_t cutoff); // Usually returns true if calling ReadVarint32() now would produce the given // value. Will always return false if ReadVarint32() would not return the @@ -303,7 +303,7 @@ // parameter. // Always inline because this collapses to a small number of instructions // when given a constant parameter, but GCC doesn't want to inline by default. - PROTOBUF_ALWAYS_INLINE bool ExpectTag(uint32 expected); + PROTOBUF_ALWAYS_INLINE bool ExpectTag(uint32_t expected); // Like above, except this reads from the specified buffer. The caller is // responsible for ensuring that the buffer is large enough to read a varint @@ -313,7 +313,8 @@ // Returns a pointer beyond the expected tag if it was found, or NULL if it // was not. PROTOBUF_ALWAYS_INLINE - static const uint8* ExpectTagFromArray(const uint8* buffer, uint32 expected); + static const uint8_t* ExpectTagFromArray(const uint8_t* buffer, + uint32_t expected); // Usually returns true if no more bytes can be read. Always returns false // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent @@ -332,8 +333,8 @@ // of the enclosing message. The enclosing message would like to check that // tag to make sure it had the right number, so it calls LastTagWas() on // return from the embedded parser to check. - bool LastTagWas(uint32 expected); - void SetLastTag(uint32 tag) { last_tag_ = tag; } + bool LastTagWas(uint32_t expected); + void SetLastTag(uint32_t tag) { last_tag_ = tag; } // When parsing message (but NOT a group), this method must be called // immediately after MergeFromCodedStream() returns (if it returns true) @@ -536,8 +537,8 @@ private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream); - const uint8* buffer_; - const uint8* buffer_end_; // pointer to the end of the buffer. + const uint8_t* buffer_; + const uint8_t* buffer_end_; // pointer to the end of the buffer. ZeroCopyInputStream* input_; int total_bytes_read_; // total bytes read from input_, including // the current buffer @@ -547,7 +548,7 @@ int overflow_bytes_; // LastTagWas() stuff. - uint32 last_tag_; // result of last ReadTag() or ReadTagWithCutoff(). + uint32_t last_tag_; // result of last ReadTag() or ReadTagWithCutoff(). // This is set true by ReadTag{Fallback/Slow}() if it is called when exactly // at EOF, or by ExpectAtEnd() when it returns true. This happens when we @@ -615,22 +616,22 @@ // message crosses multiple buffers. Note: ReadVarint32Fallback() and // ReadVarint64Fallback() are called frequently and generally not inlined, so // they have been optimized to avoid "out" parameters. The former returns -1 - // if it fails and the uint32 it read otherwise. The latter has a bool + // if it fails and the uint32_t it read otherwise. The latter has a bool // indicating success or failure as part of its return type. - int64 ReadVarint32Fallback(uint32 first_byte_or_zero); + int64_t ReadVarint32Fallback(uint32_t first_byte_or_zero); int ReadVarintSizeAsIntFallback(); - std::pair<uint64, bool> ReadVarint64Fallback(); - bool ReadVarint32Slow(uint32* value); - bool ReadVarint64Slow(uint64* value); + std::pair<uint64_t, bool> ReadVarint64Fallback(); + bool ReadVarint32Slow(uint32_t* value); + bool ReadVarint64Slow(uint64_t* value); int ReadVarintSizeAsIntSlow(); - bool ReadLittleEndian32Fallback(uint32* value); - bool ReadLittleEndian64Fallback(uint64* value); + bool ReadLittleEndian32Fallback(uint32_t* value); + bool ReadLittleEndian64Fallback(uint64_t* value); // Fallback/slow methods for reading tags. These do not update last_tag_, // but will set legitimate_message_end_ if we are at the end of the input // stream. - uint32 ReadTagFallback(uint32 first_byte_or_zero); - uint32 ReadTagSlow(); + uint32_t ReadTagFallback(uint32_t first_byte_or_zero); + uint32_t ReadTagSlow(); bool ReadStringFallback(std::string* buffer, int size); // Return the size of the buffer. @@ -656,7 +657,7 @@ // Initialize from a stream. EpsCopyOutputStream(ZeroCopyOutputStream* stream, bool deterministic, - uint8** pp) + uint8_t** pp) : end_(buffer_), stream_(stream), is_serialization_deterministic_(deterministic) { @@ -667,33 +668,33 @@ // pointed to the end of the array. When using this the total size is already // known, so no need to maintain the slop region. EpsCopyOutputStream(void* data, int size, bool deterministic) - : end_(static_cast<uint8*>(data) + size), + : end_(static_cast<uint8_t*>(data) + size), buffer_end_(nullptr), stream_(nullptr), is_serialization_deterministic_(deterministic) {} // Initialize from stream but with the first buffer already given (eager). EpsCopyOutputStream(void* data, int size, ZeroCopyOutputStream* stream, - bool deterministic, uint8** pp) + bool deterministic, uint8_t** pp) : stream_(stream), is_serialization_deterministic_(deterministic) { *pp = SetInitialBuffer(data, size); } // Flush everything that's written into the underlying ZeroCopyOutputStream // and trims the underlying stream to the location of ptr. - uint8* Trim(uint8* ptr); + uint8_t* Trim(uint8_t* ptr); // After this it's guaranteed you can safely write kSlopBytes to ptr. This // will never fail! The underlying stream can produce an error. Use HadError // to check for errors. - PROTOBUF_MUST_USE_RESULT uint8* EnsureSpace(uint8* ptr) { + PROTOBUF_MUST_USE_RESULT uint8_t* EnsureSpace(uint8_t* ptr) { if (PROTOBUF_PREDICT_FALSE(ptr >= end_)) { return EnsureSpaceFallback(ptr); } return ptr; } - uint8* WriteRaw(const void* data, int size, uint8* ptr) { + uint8_t* WriteRaw(const void* data, int size, uint8_t* ptr) { if (PROTOBUF_PREDICT_FALSE(end_ - ptr < size)) { return WriteRawFallback(data, size, ptr); } @@ -704,7 +705,7 @@ // aliasing the buffer (ie. not copying the data). The caller is responsible // to make sure the buffer is alive for the duration of the // ZeroCopyOutputStream. - uint8* WriteRawMaybeAliased(const void* data, int size, uint8* ptr) { + uint8_t* WriteRawMaybeAliased(const void* data, int size, uint8_t* ptr) { if (aliasing_enabled_) { return WriteAliasedRaw(data, size, ptr); } else { @@ -713,78 +714,78 @@ } - uint8* WriteStringMaybeAliased(uint32 num, const std::string& s, uint8* ptr) { + uint8_t* WriteStringMaybeAliased(uint32_t num, const std::string& s, uint8_t* ptr) { std::ptrdiff_t size = s.size(); if (PROTOBUF_PREDICT_FALSE( size >= 128 || end_ - ptr + 16 - TagSize(num << 3) - 1 < size)) { return WriteStringMaybeAliasedOutline(num, s, ptr); } ptr = UnsafeVarint((num << 3) | 2, ptr); - *ptr++ = static_cast<uint8>(size); + *ptr++ = static_cast<uint8_t>(size); std::memcpy(ptr, s.data(), size); return ptr + size; } - uint8* WriteBytesMaybeAliased(uint32 num, const std::string& s, uint8* ptr) { + uint8_t* WriteBytesMaybeAliased(uint32_t num, const std::string& s, uint8_t* ptr) { return WriteStringMaybeAliased(num, s, ptr); } template <typename T> - PROTOBUF_ALWAYS_INLINE uint8* WriteString(uint32 num, const T& s, - uint8* ptr) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteString(uint32_t num, const T& s, + uint8_t* ptr) { std::ptrdiff_t size = s.size(); if (PROTOBUF_PREDICT_FALSE( size >= 128 || end_ - ptr + 16 - TagSize(num << 3) - 1 < size)) { return WriteStringOutline(num, s, ptr); } ptr = UnsafeVarint((num << 3) | 2, ptr); - *ptr++ = static_cast<uint8>(size); + *ptr++ = static_cast<uint8_t>(size); std::memcpy(ptr, s.data(), size); return ptr + size; } template <typename T> - uint8* WriteBytes(uint32 num, const T& s, uint8* ptr) { + uint8_t* WriteBytes(uint32_t num, const T& s, uint8_t* ptr) { return WriteString(num, s, ptr); } template <typename T> - PROTOBUF_ALWAYS_INLINE uint8* WriteInt32Packed(int num, const T& r, int size, - uint8* ptr) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteInt32Packed(int num, const T& r, int size, + uint8_t* ptr) { return WriteVarintPacked(num, r, size, ptr, Encode64); } template <typename T> - PROTOBUF_ALWAYS_INLINE uint8* WriteUInt32Packed(int num, const T& r, int size, - uint8* ptr) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteUInt32Packed(int num, const T& r, int size, + uint8_t* ptr) { return WriteVarintPacked(num, r, size, ptr, Encode32); } template <typename T> - PROTOBUF_ALWAYS_INLINE uint8* WriteSInt32Packed(int num, const T& r, int size, - uint8* ptr) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteSInt32Packed(int num, const T& r, int size, + uint8_t* ptr) { return WriteVarintPacked(num, r, size, ptr, ZigZagEncode32); } template <typename T> - PROTOBUF_ALWAYS_INLINE uint8* WriteInt64Packed(int num, const T& r, int size, - uint8* ptr) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteInt64Packed(int num, const T& r, int size, + uint8_t* ptr) { return WriteVarintPacked(num, r, size, ptr, Encode64); } template <typename T> - PROTOBUF_ALWAYS_INLINE uint8* WriteUInt64Packed(int num, const T& r, int size, - uint8* ptr) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteUInt64Packed(int num, const T& r, int size, + uint8_t* ptr) { return WriteVarintPacked(num, r, size, ptr, Encode64); } template <typename T> - PROTOBUF_ALWAYS_INLINE uint8* WriteSInt64Packed(int num, const T& r, int size, - uint8* ptr) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteSInt64Packed(int num, const T& r, int size, + uint8_t* ptr) { return WriteVarintPacked(num, r, size, ptr, ZigZagEncode64); } template <typename T> - PROTOBUF_ALWAYS_INLINE uint8* WriteEnumPacked(int num, const T& r, int size, - uint8* ptr) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteEnumPacked(int num, const T& r, int size, + uint8_t* ptr) { return WriteVarintPacked(num, r, size, ptr, Encode64); } template <typename T> - PROTOBUF_ALWAYS_INLINE uint8* WriteFixedPacked(int num, const T& r, - uint8* ptr) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteFixedPacked(int num, const T& r, + uint8_t* ptr) { ptr = EnsureSpace(ptr); constexpr auto element_size = sizeof(typename T::value_type); auto size = r.size() * element_size; @@ -820,34 +821,34 @@ // The number of bytes written to the stream at position ptr, relative to the // stream's overall position. - int64 ByteCount(uint8* ptr) const; + int64_t ByteCount(uint8_t* ptr) const; private: - uint8* end_; - uint8* buffer_end_ = buffer_; - uint8 buffer_[2 * kSlopBytes]; + uint8_t* end_; + uint8_t* buffer_end_ = buffer_; + uint8_t buffer_[2 * kSlopBytes]; ZeroCopyOutputStream* stream_; bool had_error_ = false; bool aliasing_enabled_ = false; // See EnableAliasing(). bool is_serialization_deterministic_; - uint8* EnsureSpaceFallback(uint8* ptr); - inline uint8* Next(); - int Flush(uint8* ptr); - std::ptrdiff_t GetSize(uint8* ptr) const { + uint8_t* EnsureSpaceFallback(uint8_t* ptr); + inline uint8_t* Next(); + int Flush(uint8_t* ptr); + std::ptrdiff_t GetSize(uint8_t* ptr) const { GOOGLE_DCHECK(ptr <= end_ + kSlopBytes); // NOLINT return end_ + kSlopBytes - ptr; } - uint8* Error() { + uint8_t* Error() { had_error_ = true; // We use the patch buffer to always guarantee space to write to. end_ = buffer_ + kSlopBytes; return buffer_; } - static constexpr int TagSize(uint32 tag) { + static constexpr int TagSize(uint32_t tag) { return (tag < (1 << 7)) ? 1 : (tag < (1 << 14)) ? 2 : (tag < (1 << 21)) ? 3 @@ -855,28 +856,28 @@ : 5; } - PROTOBUF_ALWAYS_INLINE uint8* WriteTag(uint32 num, uint32 wt, uint8* ptr) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteTag(uint32_t num, uint32_t wt, uint8_t* ptr) { GOOGLE_DCHECK(ptr < end_); // NOLINT return UnsafeVarint((num << 3) | wt, ptr); } - PROTOBUF_ALWAYS_INLINE uint8* WriteLengthDelim(int num, uint32 size, - uint8* ptr) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteLengthDelim(int num, uint32_t size, + uint8_t* ptr) { ptr = WriteTag(num, 2, ptr); return UnsafeWriteSize(size, ptr); } - uint8* WriteRawFallback(const void* data, int size, uint8* ptr); + uint8_t* WriteRawFallback(const void* data, int size, uint8_t* ptr); - uint8* WriteAliasedRaw(const void* data, int size, uint8* ptr); + uint8_t* WriteAliasedRaw(const void* data, int size, uint8_t* ptr); - uint8* WriteStringMaybeAliasedOutline(uint32 num, const std::string& s, - uint8* ptr); - uint8* WriteStringOutline(uint32 num, const std::string& s, uint8* ptr); + uint8_t* WriteStringMaybeAliasedOutline(uint32_t num, const std::string& s, + uint8_t* ptr); + uint8_t* WriteStringOutline(uint32_t num, const std::string& s, uint8_t* ptr); template <typename T, typename E> - PROTOBUF_ALWAYS_INLINE uint8* WriteVarintPacked(int num, const T& r, int size, - uint8* ptr, const E& encode) { + PROTOBUF_ALWAYS_INLINE uint8_t* WriteVarintPacked(int num, const T& r, int size, + uint8_t* ptr, const E& encode) { ptr = EnsureSpace(ptr); ptr = WriteLengthDelim(num, size, ptr); auto it = r.data(); @@ -888,65 +889,65 @@ return ptr; } - static uint32 Encode32(uint32 v) { return v; } - static uint64 Encode64(uint64 v) { return v; } - static uint32 ZigZagEncode32(int32 v) { - return (static_cast<uint32>(v) << 1) ^ static_cast<uint32>(v >> 31); + static uint32_t Encode32(uint32_t v) { return v; } + static uint64_t Encode64(uint64_t v) { return v; } + static uint32_t ZigZagEncode32(int32_t v) { + return (static_cast<uint32_t>(v) << 1) ^ static_cast<uint32_t>(v >> 31); } - static uint64 ZigZagEncode64(int64 v) { - return (static_cast<uint64>(v) << 1) ^ static_cast<uint64>(v >> 63); + static uint64_t ZigZagEncode64(int64_t v) { + return (static_cast<uint64_t>(v) << 1) ^ static_cast<uint64_t>(v >> 63); } template <typename T> - PROTOBUF_ALWAYS_INLINE static uint8* UnsafeVarint(T value, uint8* ptr) { + PROTOBUF_ALWAYS_INLINE static uint8_t* UnsafeVarint(T value, uint8_t* ptr) { static_assert(std::is_unsigned<T>::value, "Varint serialization must be unsigned"); - ptr[0] = static_cast<uint8>(value); + ptr[0] = static_cast<uint8_t>(value); if (value < 0x80) { return ptr + 1; } // Turn on continuation bit in the byte we just wrote. - ptr[0] |= static_cast<uint8>(0x80); + ptr[0] |= static_cast<uint8_t>(0x80); value >>= 7; - ptr[1] = static_cast<uint8>(value); + ptr[1] = static_cast<uint8_t>(value); if (value < 0x80) { return ptr + 2; } ptr += 2; do { // Turn on continuation bit in the byte we just wrote. - ptr[-1] |= static_cast<uint8>(0x80); + ptr[-1] |= static_cast<uint8_t>(0x80); value >>= 7; - *ptr = static_cast<uint8>(value); + *ptr = static_cast<uint8_t>(value); ++ptr; } while (value >= 0x80); return ptr; } - PROTOBUF_ALWAYS_INLINE static uint8* UnsafeWriteSize(uint32 value, - uint8* ptr) { + PROTOBUF_ALWAYS_INLINE static uint8_t* UnsafeWriteSize(uint32_t value, + uint8_t* ptr) { while (PROTOBUF_PREDICT_FALSE(value >= 0x80)) { - *ptr = static_cast<uint8>(value | 0x80); + *ptr = static_cast<uint8_t>(value | 0x80); value >>= 7; ++ptr; } - *ptr++ = static_cast<uint8>(value); + *ptr++ = static_cast<uint8_t>(value); return ptr; } template <int S> - uint8* WriteRawLittleEndian(const void* data, int size, uint8* ptr); + uint8_t* WriteRawLittleEndian(const void* data, int size, uint8_t* ptr); #ifndef PROTOBUF_LITTLE_ENDIAN - uint8* WriteRawLittleEndian32(const void* data, int size, uint8* ptr); - uint8* WriteRawLittleEndian64(const void* data, int size, uint8* ptr); + uint8_t* WriteRawLittleEndian32(const void* data, int size, uint8_t* ptr); + uint8_t* WriteRawLittleEndian64(const void* data, int size, uint8_t* ptr); #endif // These methods are for CodedOutputStream. Ideally they should be private // but to match current behavior of CodedOutputStream as close as possible // we allow it some functionality. public: - uint8* SetInitialBuffer(void* data, int size) { - auto ptr = static_cast<uint8*>(data); + uint8_t* SetInitialBuffer(void* data, int size) { + auto ptr = static_cast<uint8_t*>(data); if (size > kSlopBytes) { end_ = ptr + size - kSlopBytes; buffer_end_ = nullptr; @@ -961,28 +962,28 @@ private: // Needed by CodedOutputStream HadError. HadError needs to flush the patch // buffers to ensure there is no error as of yet. - uint8* FlushAndResetBuffer(uint8*); + uint8_t* FlushAndResetBuffer(uint8_t*); // The following functions mimic the old CodedOutputStream behavior as close // as possible. They flush the current state to the stream, behave as // the old CodedOutputStream and then return to normal operation. - bool Skip(int count, uint8** pp); - bool GetDirectBufferPointer(void** data, int* size, uint8** pp); - uint8* GetDirectBufferForNBytesAndAdvance(int size, uint8** pp); + bool Skip(int count, uint8_t** pp); + bool GetDirectBufferPointer(void** data, int* size, uint8_t** pp); + uint8_t* GetDirectBufferForNBytesAndAdvance(int size, uint8_t** pp); friend class CodedOutputStream; }; template <> -inline uint8* EpsCopyOutputStream::WriteRawLittleEndian<1>(const void* data, +inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<1>(const void* data, int size, - uint8* ptr) { + uint8_t* ptr) { return WriteRaw(data, size, ptr); } template <> -inline uint8* EpsCopyOutputStream::WriteRawLittleEndian<4>(const void* data, +inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<4>(const void* data, int size, - uint8* ptr) { + uint8_t* ptr) { #ifdef PROTOBUF_LITTLE_ENDIAN return WriteRaw(data, size, ptr); #else @@ -990,9 +991,9 @@ #endif } template <> -inline uint8* EpsCopyOutputStream::WriteRawLittleEndian<8>(const void* data, +inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<8>(const void* data, int size, - uint8* ptr) { + uint8_t* ptr) { #ifdef PROTOBUF_LITTLE_ENDIAN return WriteRaw(data, size, ptr); #else @@ -1028,7 +1029,7 @@ // CodedOutputStream::VarintSize32(strlen(text)) + // strlen(text); // -// uint8* buffer = +// uint8_t* buffer = // coded_output->GetDirectBufferForNBytesAndAdvance(coded_size); // if (buffer != nullptr) { // // The output stream has enough space in the buffer: write directly to @@ -1100,7 +1101,7 @@ // there are not enough bytes available, returns NULL. The return pointer is // invalidated as soon as any other non-const method of CodedOutputStream // is called. - inline uint8* GetDirectBufferForNBytesAndAdvance(int size) { + inline uint8_t* GetDirectBufferForNBytesAndAdvance(int size) { return impl_.GetDirectBufferForNBytesAndAdvance(size, &cur_); } @@ -1116,72 +1117,77 @@ // copy loops. Since this gets called by every field with string or bytes // type, inlining may lead to a significant amount of code bloat, with only a // minor performance gain. - static uint8* WriteRawToArray(const void* buffer, int size, uint8* target); + static uint8_t* WriteRawToArray(const void* buffer, int size, uint8_t* target); // Equivalent to WriteRaw(str.data(), str.size()). void WriteString(const std::string& str); // Like WriteString() but writing directly to the target array. - static uint8* WriteStringToArray(const std::string& str, uint8* target); + static uint8_t* WriteStringToArray(const std::string& str, uint8_t* target); // Write the varint-encoded size of str followed by str. - static uint8* WriteStringWithSizeToArray(const std::string& str, - uint8* target); + static uint8_t* WriteStringWithSizeToArray(const std::string& str, + uint8_t* target); // Write a 32-bit little-endian integer. - void WriteLittleEndian32(uint32 value) { + void WriteLittleEndian32(uint32_t value) { cur_ = impl_.EnsureSpace(cur_); SetCur(WriteLittleEndian32ToArray(value, Cur())); } // Like WriteLittleEndian32() but writing directly to the target array. - static uint8* WriteLittleEndian32ToArray(uint32 value, uint8* target); + static uint8_t* WriteLittleEndian32ToArray(uint32_t value, uint8_t* target); // Write a 64-bit little-endian integer. - void WriteLittleEndian64(uint64 value) { + void WriteLittleEndian64(uint64_t value) { cur_ = impl_.EnsureSpace(cur_); SetCur(WriteLittleEndian64ToArray(value, Cur())); } // Like WriteLittleEndian64() but writing directly to the target array. - static uint8* WriteLittleEndian64ToArray(uint64 value, uint8* target); + static uint8_t* WriteLittleEndian64ToArray(uint64_t value, uint8_t* target); // Write an unsigned integer with Varint encoding. Writing a 32-bit value - // is equivalent to casting it to uint64 and writing it as a 64-bit value, + // is equivalent to casting it to uint64_t and writing it as a 64-bit value, // but may be more efficient. - void WriteVarint32(uint32 value); + void WriteVarint32(uint32_t value); // Like WriteVarint32() but writing directly to the target array. - static uint8* WriteVarint32ToArray(uint32 value, uint8* target); + static uint8_t* WriteVarint32ToArray(uint32_t value, uint8_t* target); // Like WriteVarint32() but writing directly to the target array, and with the // less common-case paths being out of line rather than inlined. - static uint8* WriteVarint32ToArrayOutOfLine(uint32 value, uint8* target); + static uint8_t* WriteVarint32ToArrayOutOfLine(uint32_t value, uint8_t* target); // Write an unsigned integer with Varint encoding. - void WriteVarint64(uint64 value); + void WriteVarint64(uint64_t value); // Like WriteVarint64() but writing directly to the target array. - static uint8* WriteVarint64ToArray(uint64 value, uint8* target); + static uint8_t* WriteVarint64ToArray(uint64_t value, uint8_t* target); // Equivalent to WriteVarint32() except when the value is negative, // in which case it must be sign-extended to a full 10 bytes. - void WriteVarint32SignExtended(int32 value); + void WriteVarint32SignExtended(int32_t value); // Like WriteVarint32SignExtended() but writing directly to the target array. - static uint8* WriteVarint32SignExtendedToArray(int32 value, uint8* target); + static uint8_t* WriteVarint32SignExtendedToArray(int32_t value, uint8_t* target); // This is identical to WriteVarint32(), but optimized for writing tags. // In particular, if the input is a compile-time constant, this method // compiles down to a couple instructions. // Always inline because otherwise the aforementioned optimization can't work, // but GCC by default doesn't want to inline this. - void WriteTag(uint32 value); + void WriteTag(uint32_t value); // Like WriteTag() but writing directly to the target array. PROTOBUF_ALWAYS_INLINE - static uint8* WriteTagToArray(uint32 value, uint8* target); + static uint8_t* WriteTagToArray(uint32_t value, uint8_t* target); // Returns the number of bytes needed to encode the given value as a varint. - static size_t VarintSize32(uint32 value); + static size_t VarintSize32(uint32_t value); // Returns the number of bytes needed to encode the given value as a varint. - static size_t VarintSize64(uint64 value); + static size_t VarintSize64(uint64_t value); // If negative, 10 bytes. Otherwise, same as VarintSize32(). - static size_t VarintSize32SignExtended(int32 value); + static size_t VarintSize32SignExtended(int32_t value); + + // Same as above, plus one. The additional one comes at no compute cost. + static size_t VarintSize32PlusOne(uint32_t value); + static size_t VarintSize64PlusOne(uint64_t value); + static size_t VarintSize32SignExtendedPlusOne(int32_t value); // Compile-time equivalent of VarintSize32(). - template <uint32 Value> + template <uint32_t Value> struct StaticVarintSize32 { static const size_t value = (Value < (1 << 7)) ? 1 : (Value < (1 << 14)) ? 2 @@ -1244,14 +1250,14 @@ template <typename Func> void Serialize(const Func& func); - uint8* Cur() const { return cur_; } - void SetCur(uint8* ptr) { cur_ = ptr; } + uint8_t* Cur() const { return cur_; } + void SetCur(uint8_t* ptr) { cur_ = ptr; } EpsCopyOutputStream* EpsCopy() { return &impl_; } private: EpsCopyOutputStream impl_; - uint8* cur_; - int64 start_count_; + uint8_t* cur_; + int64_t start_count_; static std::atomic<bool> default_serialization_deterministic_; // See above. Other projects may use "friend" to allow them to call this. @@ -1266,7 +1272,7 @@ default_serialization_deterministic_.store(true, std::memory_order_relaxed); } // REQUIRES: value >= 0x80, and that (value & 7f) has been written to *target. - static uint8* WriteVarint32ToArrayOutOfLineHelper(uint32 value, uint8* target); + static uint8_t* WriteVarint32ToArrayOutOfLineHelper(uint32_t value, uint8_t* target); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream); }; @@ -1274,8 +1280,8 @@ // The vast majority of varints are only one byte. These inline // methods optimize for that case. -inline bool CodedInputStream::ReadVarint32(uint32* value) { - uint32 v = 0; +inline bool CodedInputStream::ReadVarint32(uint32_t* value) { + uint32_t v = 0; if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) { v = *buffer_; if (v < 0x80) { @@ -1284,18 +1290,18 @@ return true; } } - int64 result = ReadVarint32Fallback(v); - *value = static_cast<uint32>(result); + int64_t result = ReadVarint32Fallback(v); + *value = static_cast<uint32_t>(result); return result >= 0; } -inline bool CodedInputStream::ReadVarint64(uint64* value) { +inline bool CodedInputStream::ReadVarint64(uint64_t* value) { if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { *value = *buffer_; Advance(1); return true; } - std::pair<uint64, bool> p = ReadVarint64Fallback(); + std::pair<uint64_t, bool> p = ReadVarint64Fallback(); *value = p.first; return p.second; } @@ -1314,40 +1320,40 @@ } // static -inline const uint8* CodedInputStream::ReadLittleEndian32FromArray( - const uint8* buffer, uint32* value) { +inline const uint8_t* CodedInputStream::ReadLittleEndian32FromArray( + const uint8_t* buffer, uint32_t* value) { #if defined(PROTOBUF_LITTLE_ENDIAN) memcpy(value, buffer, sizeof(*value)); return buffer + sizeof(*value); #else - *value = (static_cast<uint32>(buffer[0])) | - (static_cast<uint32>(buffer[1]) << 8) | - (static_cast<uint32>(buffer[2]) << 16) | - (static_cast<uint32>(buffer[3]) << 24); + *value = (static_cast<uint32_t>(buffer[0])) | + (static_cast<uint32_t>(buffer[1]) << 8) | + (static_cast<uint32_t>(buffer[2]) << 16) | + (static_cast<uint32_t>(buffer[3]) << 24); return buffer + sizeof(*value); #endif } // static -inline const uint8* CodedInputStream::ReadLittleEndian64FromArray( - const uint8* buffer, uint64* value) { +inline const uint8_t* CodedInputStream::ReadLittleEndian64FromArray( + const uint8_t* buffer, uint64_t* value) { #if defined(PROTOBUF_LITTLE_ENDIAN) memcpy(value, buffer, sizeof(*value)); return buffer + sizeof(*value); #else - uint32 part0 = (static_cast<uint32>(buffer[0])) | - (static_cast<uint32>(buffer[1]) << 8) | - (static_cast<uint32>(buffer[2]) << 16) | - (static_cast<uint32>(buffer[3]) << 24); - uint32 part1 = (static_cast<uint32>(buffer[4])) | - (static_cast<uint32>(buffer[5]) << 8) | - (static_cast<uint32>(buffer[6]) << 16) | - (static_cast<uint32>(buffer[7]) << 24); - *value = static_cast<uint64>(part0) | (static_cast<uint64>(part1) << 32); + uint32_t part0 = (static_cast<uint32_t>(buffer[0])) | + (static_cast<uint32_t>(buffer[1]) << 8) | + (static_cast<uint32_t>(buffer[2]) << 16) | + (static_cast<uint32_t>(buffer[3]) << 24); + uint32_t part1 = (static_cast<uint32_t>(buffer[4])) | + (static_cast<uint32_t>(buffer[5]) << 8) | + (static_cast<uint32_t>(buffer[6]) << 16) | + (static_cast<uint32_t>(buffer[7]) << 24); + *value = static_cast<uint64_t>(part0) | (static_cast<uint64_t>(part1) << 32); return buffer + sizeof(*value); #endif } -inline bool CodedInputStream::ReadLittleEndian32(uint32* value) { +inline bool CodedInputStream::ReadLittleEndian32(uint32_t* value) { #if defined(PROTOBUF_LITTLE_ENDIAN) if (PROTOBUF_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) { buffer_ = ReadLittleEndian32FromArray(buffer_, value); @@ -1360,7 +1366,7 @@ #endif } -inline bool CodedInputStream::ReadLittleEndian64(uint64* value) { +inline bool CodedInputStream::ReadLittleEndian64(uint64_t* value) { #if defined(PROTOBUF_LITTLE_ENDIAN) if (PROTOBUF_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) { buffer_ = ReadLittleEndian64FromArray(buffer_, value); @@ -1373,8 +1379,8 @@ #endif } -inline uint32 CodedInputStream::ReadTagNoLastTag() { - uint32 v = 0; +inline uint32_t CodedInputStream::ReadTagNoLastTag() { + uint32_t v = 0; if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) { v = *buffer_; if (v < 0x80) { @@ -1386,20 +1392,20 @@ return v; } -inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoffNoLastTag( - uint32 cutoff) { +inline std::pair<uint32_t, bool> CodedInputStream::ReadTagWithCutoffNoLastTag( + uint32_t cutoff) { // In performance-sensitive code we can expect cutoff to be a compile-time // constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at // compile time. - uint32 first_byte_or_zero = 0; + uint32_t first_byte_or_zero = 0; if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) { // Hot case: buffer_ non_empty, buffer_[0] in [1, 128). // TODO(gpike): Is it worth rearranging this? E.g., if the number of fields // is large enough then is it better to check for the two-byte case first? first_byte_or_zero = buffer_[0]; - if (static_cast<int8>(buffer_[0]) > 0) { - const uint32 kMax1ByteVarint = 0x7f; - uint32 tag = buffer_[0]; + if (static_cast<int8_t>(buffer_[0]) > 0) { + const uint32_t kMax1ByteVarint = 0x7f; + uint32_t tag = buffer_[0]; Advance(1); return std::make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff); } @@ -1408,8 +1414,8 @@ // first byte and the second byte. if (cutoff >= 0x80 && PROTOBUF_PREDICT_TRUE(buffer_ + 1 < buffer_end_) && PROTOBUF_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) { - const uint32 kMax2ByteVarint = (0x7f << 7) + 0x7f; - uint32 tag = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80); + const uint32_t kMax2ByteVarint = (0x7f << 7) + 0x7f; + uint32_t tag = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80); Advance(2); // It might make sense to test for tag == 0 now, but it is so rare that // that we don't bother. A varint-encoded 0 should be one byte unless @@ -1422,11 +1428,11 @@ } } // Slow path - const uint32 tag = ReadTagFallback(first_byte_or_zero); - return std::make_pair(tag, static_cast<uint32>(tag - 1) < cutoff); + const uint32_t tag = ReadTagFallback(first_byte_or_zero); + return std::make_pair(tag, static_cast<uint32_t>(tag - 1) < cutoff); } -inline bool CodedInputStream::LastTagWas(uint32 expected) { +inline bool CodedInputStream::LastTagWas(uint32_t expected) { return last_tag_ == expected; } @@ -1434,7 +1440,7 @@ return legitimate_message_end_; } -inline bool CodedInputStream::ExpectTag(uint32 expected) { +inline bool CodedInputStream::ExpectTag(uint32_t expected) { if (expected < (1 << 7)) { if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] == expected) { @@ -1445,8 +1451,8 @@ } } else if (expected < (1 << 14)) { if (PROTOBUF_PREDICT_TRUE(BufferSize() >= 2) && - buffer_[0] == static_cast<uint8>(expected | 0x80) && - buffer_[1] == static_cast<uint8>(expected >> 7)) { + buffer_[0] == static_cast<uint8_t>(expected | 0x80) && + buffer_[1] == static_cast<uint8_t>(expected >> 7)) { Advance(2); return true; } else { @@ -1458,15 +1464,15 @@ } } -inline const uint8* CodedInputStream::ExpectTagFromArray(const uint8* buffer, - uint32 expected) { +inline const uint8_t* CodedInputStream::ExpectTagFromArray(const uint8_t* buffer, + uint32_t expected) { if (expected < (1 << 7)) { if (buffer[0] == expected) { return buffer + 1; } } else if (expected < (1 << 14)) { - if (buffer[0] == static_cast<uint8>(expected | 0x80) && - buffer[1] == static_cast<uint8>(expected >> 7)) { + if (buffer[0] == static_cast<uint8_t>(expected | 0x80) && + buffer[1] == static_cast<uint8_t>(expected >> 7)) { return buffer + 2; } } @@ -1556,7 +1562,7 @@ Refresh(); } -inline CodedInputStream::CodedInputStream(const uint8* buffer, int size) +inline CodedInputStream::CodedInputStream(const uint8_t* buffer, int size) : buffer_(buffer), buffer_end_(buffer + size), input_(nullptr), @@ -1592,14 +1598,14 @@ return SkipFallback(count, original_buffer_size); } -inline uint8* CodedOutputStream::WriteVarint32ToArray(uint32 value, - uint8* target) { +inline uint8_t* CodedOutputStream::WriteVarint32ToArray(uint32_t value, + uint8_t* target) { return EpsCopyOutputStream::UnsafeVarint(value, target); } -inline uint8* CodedOutputStream::WriteVarint32ToArrayOutOfLine(uint32 value, - uint8* target) { - target[0] = static_cast<uint8>(value); +inline uint8_t* CodedOutputStream::WriteVarint32ToArrayOutOfLine( + uint32_t value, uint8_t* target) { + target[0] = static_cast<uint8_t>(value); if (value < 0x80) { return target + 1; } else { @@ -1607,95 +1613,110 @@ } } -inline uint8* CodedOutputStream::WriteVarint64ToArray(uint64 value, - uint8* target) { +inline uint8_t* CodedOutputStream::WriteVarint64ToArray(uint64_t value, + uint8_t* target) { return EpsCopyOutputStream::UnsafeVarint(value, target); } -inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) { - WriteVarint64(static_cast<uint64>(value)); +inline void CodedOutputStream::WriteVarint32SignExtended(int32_t value) { + WriteVarint64(static_cast<uint64_t>(value)); } -inline uint8* CodedOutputStream::WriteVarint32SignExtendedToArray( - int32 value, uint8* target) { - return WriteVarint64ToArray(static_cast<uint64>(value), target); +inline uint8_t* CodedOutputStream::WriteVarint32SignExtendedToArray( + int32_t value, uint8_t* target) { + return WriteVarint64ToArray(static_cast<uint64_t>(value), target); } -inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value, - uint8* target) { +inline uint8_t* CodedOutputStream::WriteLittleEndian32ToArray(uint32_t value, + uint8_t* target) { #if defined(PROTOBUF_LITTLE_ENDIAN) memcpy(target, &value, sizeof(value)); #else - target[0] = static_cast<uint8>(value); - target[1] = static_cast<uint8>(value >> 8); - target[2] = static_cast<uint8>(value >> 16); - target[3] = static_cast<uint8>(value >> 24); + target[0] = static_cast<uint8_t>(value); + target[1] = static_cast<uint8_t>(value >> 8); + target[2] = static_cast<uint8_t>(value >> 16); + target[3] = static_cast<uint8_t>(value >> 24); #endif return target + sizeof(value); } -inline uint8* CodedOutputStream::WriteLittleEndian64ToArray(uint64 value, - uint8* target) { +inline uint8_t* CodedOutputStream::WriteLittleEndian64ToArray(uint64_t value, + uint8_t* target) { #if defined(PROTOBUF_LITTLE_ENDIAN) memcpy(target, &value, sizeof(value)); #else - uint32 part0 = static_cast<uint32>(value); - uint32 part1 = static_cast<uint32>(value >> 32); + uint32_t part0 = static_cast<uint32_t>(value); + uint32_t part1 = static_cast<uint32_t>(value >> 32); - target[0] = static_cast<uint8>(part0); - target[1] = static_cast<uint8>(part0 >> 8); - target[2] = static_cast<uint8>(part0 >> 16); - target[3] = static_cast<uint8>(part0 >> 24); - target[4] = static_cast<uint8>(part1); - target[5] = static_cast<uint8>(part1 >> 8); - target[6] = static_cast<uint8>(part1 >> 16); - target[7] = static_cast<uint8>(part1 >> 24); + target[0] = static_cast<uint8_t>(part0); + target[1] = static_cast<uint8_t>(part0 >> 8); + target[2] = static_cast<uint8_t>(part0 >> 16); + target[3] = static_cast<uint8_t>(part0 >> 24); + target[4] = static_cast<uint8_t>(part1); + target[5] = static_cast<uint8_t>(part1 >> 8); + target[6] = static_cast<uint8_t>(part1 >> 16); + target[7] = static_cast<uint8_t>(part1 >> 24); #endif return target + sizeof(value); } -inline void CodedOutputStream::WriteVarint32(uint32 value) { +inline void CodedOutputStream::WriteVarint32(uint32_t value) { cur_ = impl_.EnsureSpace(cur_); SetCur(WriteVarint32ToArray(value, Cur())); } -inline void CodedOutputStream::WriteVarint64(uint64 value) { +inline void CodedOutputStream::WriteVarint64(uint64_t value) { cur_ = impl_.EnsureSpace(cur_); SetCur(WriteVarint64ToArray(value, Cur())); } -inline void CodedOutputStream::WriteTag(uint32 value) { WriteVarint32(value); } +inline void CodedOutputStream::WriteTag(uint32_t value) { + WriteVarint32(value); +} -inline uint8* CodedOutputStream::WriteTagToArray(uint32 value, uint8* target) { +inline uint8_t* CodedOutputStream::WriteTagToArray(uint32_t value, + uint8_t* target) { return WriteVarint32ToArray(value, target); } -inline size_t CodedOutputStream::VarintSize32(uint32 value) { +inline size_t CodedOutputStream::VarintSize32(uint32_t value) { // This computes value == 0 ? 1 : floor(log2(value)) / 7 + 1 // Use an explicit multiplication to implement the divide of // a number in the 1..31 range. // Explicit OR 0x1 to avoid calling Bits::Log2FloorNonZero(0), which is // undefined. - uint32 log2value = Bits::Log2FloorNonZero(value | 0x1); + uint32_t log2value = Bits::Log2FloorNonZero(value | 0x1); return static_cast<size_t>((log2value * 9 + 73) / 64); } -inline size_t CodedOutputStream::VarintSize64(uint64 value) { +inline size_t CodedOutputStream::VarintSize32PlusOne(uint32_t value) { + // Same as above, but one more. + uint32_t log2value = Bits::Log2FloorNonZero(value | 0x1); + return static_cast<size_t>((log2value * 9 + 73 + 64) / 64); +} + +inline size_t CodedOutputStream::VarintSize64(uint64_t value) { // This computes value == 0 ? 1 : floor(log2(value)) / 7 + 1 // Use an explicit multiplication to implement the divide of // a number in the 1..63 range. // Explicit OR 0x1 to avoid calling Bits::Log2FloorNonZero(0), which is // undefined. - uint32 log2value = Bits::Log2FloorNonZero64(value | 0x1); + uint32_t log2value = Bits::Log2FloorNonZero64(value | 0x1); return static_cast<size_t>((log2value * 9 + 73) / 64); } -inline size_t CodedOutputStream::VarintSize32SignExtended(int32 value) { - if (value < 0) { - return 10; // TODO(kenton): Make this a symbolic constant. - } else { - return VarintSize32(static_cast<uint32>(value)); - } +inline size_t CodedOutputStream::VarintSize64PlusOne(uint64_t value) { + // Same as above, but one more. + uint32_t log2value = Bits::Log2FloorNonZero64(value | 0x1); + return static_cast<size_t>((log2value * 9 + 73 + 64) / 64); +} + +inline size_t CodedOutputStream::VarintSize32SignExtended(int32_t value) { + return VarintSize64(static_cast<uint64_t>(int64_t{value})); +} + +inline size_t CodedOutputStream::VarintSize32SignExtendedPlusOne(int32_t value) { + return VarintSize64PlusOne(static_cast<uint64_t>(int64_t{value})); } inline void CodedOutputStream::WriteString(const std::string& str) { @@ -1707,14 +1728,14 @@ cur_ = impl_.WriteRawMaybeAliased(data, size, cur_); } -inline uint8* CodedOutputStream::WriteRawToArray(const void* data, int size, - uint8* target) { +inline uint8_t* CodedOutputStream::WriteRawToArray(const void* data, int size, + uint8_t* target) { memcpy(target, data, size); return target + size; } -inline uint8* CodedOutputStream::WriteStringToArray(const std::string& str, - uint8* target) { +inline uint8_t* CodedOutputStream::WriteStringToArray(const std::string& str, + uint8_t* target) { return WriteRawToArray(str.data(), static_cast<int>(str.size()), target); }
diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc index ad6bb5f..2f1d26f 100644 --- a/src/google/protobuf/io/gzip_stream.cc +++ b/src/google/protobuf/io/gzip_stream.cc
@@ -186,7 +186,7 @@ return ok; } int64_t GzipInputStream::ByteCount() const { - int64 ret = byte_count_ + zcontext_.total_out; + int64_t ret = byte_count_ + zcontext_.total_out; if (zcontext_.next_out != NULL && output_position_ != NULL) { ret += reinterpret_cast<uintptr_t>(zcontext_.next_out) - reinterpret_cast<uintptr_t>(output_position_);
diff --git a/src/google/protobuf/io/gzip_stream.h b/src/google/protobuf/io/gzip_stream.h index cc704b9..f0283e8 100644 --- a/src/google/protobuf/io/gzip_stream.h +++ b/src/google/protobuf/io/gzip_stream.h
@@ -96,7 +96,7 @@ void* output_buffer_; void* output_position_; size_t output_buffer_length_; - int64 byte_count_; + int64_t byte_count_; int Inflate(int flush); void DoNextOutput(const void** data, int* size);
diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc index 129b488..6a48673 100644 --- a/src/google/protobuf/io/tokenizer.cc +++ b/src/google/protobuf/io/tokenizer.cc
@@ -860,8 +860,8 @@ // are given is text that the tokenizer actually parsed as a token // of the given type. -bool Tokenizer::ParseInteger(const std::string& text, uint64 max_value, - uint64* output) { +bool Tokenizer::ParseInteger(const std::string& text, uint64_t max_value, + uint64_t* output) { // Sadly, we can't just use strtoul() since it is only 32-bit and strtoull() // is non-standard. I hate the C standard library. :( @@ -880,7 +880,7 @@ } } - uint64 result = 0; + uint64_t result = 0; for (; *ptr != '\0'; ptr++) { int digit = DigitValue(*ptr); if (digit < 0 || digit >= base) { @@ -888,7 +888,7 @@ // token, but Tokenizer still think it's integer. return false; } - if (static_cast<uint64>(digit) > max_value || + if (static_cast<uint64_t>(digit) > max_value || result > (max_value - digit) / base) { // Overflow. return false; @@ -929,8 +929,8 @@ // Helper to append a Unicode code point to a string as UTF8, without bringing // in any external dependencies. -static void AppendUTF8(uint32 code_point, std::string* output) { - uint32 tmp = 0; +static void AppendUTF8(uint32_t code_point, std::string* output) { + uint32_t tmp = 0; int len = 0; if (code_point <= 0x7f) { tmp = code_point; @@ -960,7 +960,7 @@ // Try to read <len> hex digits from ptr, and stuff the numeric result into // *result. Returns true if that many digits were successfully consumed. -static bool ReadHexDigits(const char* ptr, int len, uint32* result) { +static bool ReadHexDigits(const char* ptr, int len, uint32_t* result) { *result = 0; if (len == 0) return false; for (const char* end = ptr + len; ptr < end; ++ptr) { @@ -975,22 +975,22 @@ // surrogate. These numbers are in a reserved range of Unicode code points, so // if we encounter such a pair we know how to parse it and convert it into a // single code point. -static const uint32 kMinHeadSurrogate = 0xd800; -static const uint32 kMaxHeadSurrogate = 0xdc00; -static const uint32 kMinTrailSurrogate = 0xdc00; -static const uint32 kMaxTrailSurrogate = 0xe000; +static const uint32_t kMinHeadSurrogate = 0xd800; +static const uint32_t kMaxHeadSurrogate = 0xdc00; +static const uint32_t kMinTrailSurrogate = 0xdc00; +static const uint32_t kMaxTrailSurrogate = 0xe000; -static inline bool IsHeadSurrogate(uint32 code_point) { +static inline bool IsHeadSurrogate(uint32_t code_point) { return (code_point >= kMinHeadSurrogate) && (code_point < kMaxHeadSurrogate); } -static inline bool IsTrailSurrogate(uint32 code_point) { +static inline bool IsTrailSurrogate(uint32_t code_point) { return (code_point >= kMinTrailSurrogate) && (code_point < kMaxTrailSurrogate); } // Combine a head and trail surrogate into a single Unicode code point. -static uint32 AssembleUTF16(uint32 head_surrogate, uint32 trail_surrogate) { +static uint32_t AssembleUTF16(uint32_t head_surrogate, uint32_t trail_surrogate) { GOOGLE_DCHECK(IsHeadSurrogate(head_surrogate)); GOOGLE_DCHECK(IsTrailSurrogate(trail_surrogate)); return 0x10000 + (((head_surrogate - kMinHeadSurrogate) << 10) | @@ -1008,7 +1008,7 @@ // to parse that sequence. On success, returns a pointer to the first char // beyond that sequence, and fills in *code_point. On failure, returns ptr // itself. -static const char* FetchUnicodePoint(const char* ptr, uint32* code_point) { +static const char* FetchUnicodePoint(const char* ptr, uint32_t* code_point) { const char* p = ptr; // Fetch the code point. const int len = UnicodeLength(*p++); @@ -1020,7 +1020,7 @@ // "trail surrogate," and together they form a UTF-16 pair which decodes into // a single Unicode point. Trail surrogates may only use \u, not \U. if (IsHeadSurrogate(*code_point) && *p == '\\' && *(p + 1) == 'u') { - uint32 trail_surrogate; + uint32_t trail_surrogate; if (ReadHexDigits(p + 2, 4, &trail_surrogate) && IsTrailSurrogate(trail_surrogate)) { *code_point = AssembleUTF16(*code_point, trail_surrogate); @@ -1092,7 +1092,7 @@ output->push_back(static_cast<char>(code)); } else if (*ptr == 'u' || *ptr == 'U') { - uint32 unicode; + uint32_t unicode; const char* end = FetchUnicodePoint(ptr, &unicode); if (end == ptr) { // Failure: Just dump out what we saw, don't try to parse it.
diff --git a/src/google/protobuf/io/tokenizer.h b/src/google/protobuf/io/tokenizer.h index 3be00f1..ac23c2e 100644 --- a/src/google/protobuf/io/tokenizer.h +++ b/src/google/protobuf/io/tokenizer.h
@@ -217,8 +217,8 @@ // result. If the text is not from a Token of type TYPE_INTEGER originally // parsed by a Tokenizer, the result is undefined (possibly an assert // failure). - static bool ParseInteger(const std::string& text, uint64 max_value, - uint64* output); + static bool ParseInteger(const std::string& text, uint64_t max_value, + uint64_t* output); // Options ---------------------------------------------------------
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc index 52617e9..0986ea2 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl.cc
@@ -103,7 +103,13 @@ close_on_delete_(false), is_closed_(false), errno_(0), - previous_seek_failed_(false) {} + previous_seek_failed_(false) { +#ifndef _MSC_VER + int flags = fcntl(file_, F_GETFL); + flags &= ~O_NONBLOCK; + fcntl(file_, F_SETFL, flags); +#endif +} FileInputStream::CopyingFileInputStream::~CopyingFileInputStream() { if (close_on_delete_) { @@ -210,7 +216,7 @@ GOOGLE_CHECK(!is_closed_); int total_written = 0; - const uint8* buffer_base = reinterpret_cast<const uint8*>(buffer); + const uint8_t* buffer_base = reinterpret_cast<const uint8_t*>(buffer); while (total_written < size) { int bytes; @@ -332,12 +338,12 @@ while (stream_count_ > 0) { // Assume that ByteCount() can be used to find out how much we actually // skipped when Skip() fails. - int64 target_byte_count = streams_[0]->ByteCount() + count; + int64_t target_byte_count = streams_[0]->ByteCount() + count; if (streams_[0]->Skip(count)) return true; // Hit the end of the stream. Figure out how many more bytes we still have // to skip. - int64 final_byte_count = streams_[0]->ByteCount(); + int64_t final_byte_count = streams_[0]->ByteCount(); GOOGLE_DCHECK_LT(final_byte_count, target_byte_count); count = target_byte_count - final_byte_count;
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h index 0206e38..e6ba902 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.h +++ b/src/google/protobuf/io/zero_copy_stream_impl.h
@@ -311,7 +311,7 @@ // decremented. ZeroCopyInputStream* const* streams_; int stream_count_; - int64 bytes_retired_; // Bytes read from previous streams. + int64_t bytes_retired_; // Bytes read from previous streams. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream); };
diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc index 0eeeb0e..dc4b1e9 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
@@ -56,7 +56,7 @@ // =================================================================== ArrayInputStream::ArrayInputStream(const void* data, int size, int block_size) - : data_(reinterpret_cast<const uint8*>(data)), + : data_(reinterpret_cast<const uint8_t*>(data)), size_(size), block_size_(block_size > 0 ? block_size : size), position_(0), @@ -103,7 +103,7 @@ // =================================================================== ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size) - : data_(reinterpret_cast<uint8*>(data)), + : data_(reinterpret_cast<uint8_t*>(data)), size_(size), block_size_(block_size > 0 ? block_size : size), position_(0), @@ -284,7 +284,7 @@ void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() { if (buffer_.get() == NULL) { - buffer_.reset(new uint8[buffer_size_]); + buffer_.reset(new uint8_t[buffer_size_]); } } @@ -394,7 +394,7 @@ void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() { if (buffer_ == NULL) { - buffer_.reset(new uint8[buffer_size_]); + buffer_.reset(new uint8_t[buffer_size_]); } } @@ -406,7 +406,7 @@ // =================================================================== LimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input, - int64 limit) + int64_t limit) : input_(input), limit_(limit) { prior_bytes_read_ = input_->ByteCount(); }
diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h index cfe81d2..9ee3691 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
@@ -84,7 +84,7 @@ private: - const uint8* const data_; // The byte array. + const uint8_t* const data_; // The byte array. const int size_; // Total size of the array. const int block_size_; // How many bytes to return at a time. @@ -116,7 +116,7 @@ int64_t ByteCount() const override; private: - uint8* const data_; // The byte array. + uint8_t* const data_; // The byte array. const int size_; // Total size of the array. const int block_size_; // How many bytes to return at a time. @@ -236,11 +236,11 @@ // The current position of copying_stream_, relative to the point where // we started reading. - int64 position_; + int64_t position_; // Data is read into this buffer. It may be NULL if no buffer is currently // in use. Otherwise, it points to an array of size buffer_size_. - std::unique_ptr<uint8[]> buffer_; + std::unique_ptr<uint8_t[]> buffer_; const int buffer_size_; // Number of valid bytes currently in the buffer (i.e. the size last @@ -327,11 +327,11 @@ // The current position of copying_stream_, relative to the point where // we started writing. - int64 position_; + int64_t position_; // Data is written from this buffer. It may be NULL if no buffer is // currently in use. Otherwise, it points to an array of size buffer_size_. - std::unique_ptr<uint8[]> buffer_; + std::unique_ptr<uint8_t[]> buffer_; const int buffer_size_; // Number of valid bytes currently in the buffer (i.e. the size last @@ -348,7 +348,7 @@ // a particular byte count. class PROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream { public: - LimitingInputStream(ZeroCopyInputStream* input, int64 limit); + LimitingInputStream(ZeroCopyInputStream* input, int64_t limit); ~LimitingInputStream() override; // implements ZeroCopyInputStream ---------------------------------- @@ -360,8 +360,8 @@ private: ZeroCopyInputStream* input_; - int64 limit_; // Decreases as we go, becomes negative if we overshoot. - int64 prior_bytes_read_; // Bytes read on underlying stream at construction + int64_t limit_; // Decreases as we go, becomes negative if we overshoot. + int64_t prior_bytes_read_; // Bytes read on underlying stream at construction GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream); };
diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc index cc53949..822115e 100644 --- a/src/google/protobuf/io/zero_copy_stream_unittest.cc +++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -46,8 +46,11 @@ // "parametized tests" so that one set of tests can be used on all the // implementations. +#include <chrono> +#include <thread> #ifndef _MSC_VER +#include <sys/socket.h> #include <unistd.h> #endif #include <errno.h> @@ -117,7 +120,7 @@ int WriteStuff(ZeroCopyOutputStream* output); // Reads text from an input stream and expects it to match what // WriteStuff() writes. - void ReadStuff(ZeroCopyInputStream* input); + void ReadStuff(ZeroCopyInputStream* input, bool read_eof = true); // Similar to WriteStuff, but performs more sophisticated testing. int WriteStuffLarge(ZeroCopyOutputStream* output); @@ -228,7 +231,7 @@ // Reads text from an input stream and expects it to match what WriteStuff() // writes. -void IoTest::ReadStuff(ZeroCopyInputStream* input) { +void IoTest::ReadStuff(ZeroCopyInputStream* input, bool read_eof) { ReadString(input, "Hello world!\n"); ReadString(input, "Some text. "); ReadString(input, "Blah "); @@ -240,8 +243,10 @@ EXPECT_EQ(input->ByteCount(), 68); - uint8 byte; - EXPECT_EQ(ReadFromInput(input, &byte, 1), 0); + if (read_eof) { + uint8 byte; + EXPECT_EQ(ReadFromInput(input, &byte, 1), 0); + } } int IoTest::WriteStuffLarge(ZeroCopyOutputStream* output) { @@ -759,6 +764,67 @@ } } +#ifndef _MSC_VER +// This tests the FileInputStream with a non blocking file. It opens a pipe in +// non blocking mode, then starts reading it. The writing thread starts writing +// 100ms after that. +TEST_F(IoTest, NonBlockingFileIo) { + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + int fd[2]; + ASSERT_EQ(pipe2(fd, O_NONBLOCK), 0); + + std::mutex go_write; + go_write.lock(); + + bool done_reading = false; + + std::thread write_thread([this, fd, &go_write, i]() { + go_write.lock(); + go_write.unlock(); + FileOutputStream output(fd[1], kBlockSizes[i]); + WriteStuff(&output); + EXPECT_EQ(0, output.GetErrno()); + }); + + std::thread read_thread([this, fd, &done_reading, j]() { + FileInputStream input(fd[0], kBlockSizes[j]); + ReadStuff(&input, false /* read_eof */); + done_reading = true; + close(fd[0]); + close(fd[1]); + EXPECT_EQ(0, input.GetErrno()); + }); + + // Sleeping is not necessary but makes the next expectation relevant: the + // reading thread waits for the data to be available before returning. + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + EXPECT_FALSE(done_reading); + go_write.unlock(); + write_thread.join(); + read_thread.join(); + EXPECT_TRUE(done_reading); + } + } +} + +TEST_F(IoTest, BlockingFileIoWithTimeout) { + int fd[2]; + + for (int i = 0; i < kBlockSizeCount; i++) { + ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, fd), 0); + struct timeval tv { + .tv_sec = 0, .tv_usec = 5000 + }; + ASSERT_EQ(setsockopt(fd[0], SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)), 0); + FileInputStream input(fd[0], kBlockSizes[i]); + uint8 byte; + EXPECT_EQ(ReadFromInput(&input, &byte, 1), 0); + EXPECT_EQ(EAGAIN, input.GetErrno()); + } +} +#endif + #if HAVE_ZLIB TEST_F(IoTest, GzipFileIo) { std::string filename = TestTempDir() + "/zero_copy_stream_test_file";
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index df84e1e..361d1fc 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h
@@ -118,7 +118,7 @@ return static_cast<pointer>(::operator new(n * sizeof(value_type))); } else { return reinterpret_cast<pointer>( - Arena::CreateArray<uint8>(arena_, n * sizeof(value_type))); + Arena::CreateArray<uint8_t>(arena_, n * sizeof(value_type))); } } @@ -698,21 +698,18 @@ p = FindHelper(k); } const size_type b = p.second; // bucket number - Node* node; // If K is not key_type, make the conversion to key_type explicit. using TypeToInit = typename std::conditional< std::is_same<typename std::decay<K>::type, key_type>::value, K&&, key_type>::type; - if (alloc_.arena() == nullptr) { - node = new Node{value_type(static_cast<TypeToInit>(std::forward<K>(k))), - nullptr}; - } else { - node = Alloc<Node>(1); - Arena::CreateInArenaStorage( - const_cast<Key*>(&node->kv.first), alloc_.arena(), - static_cast<TypeToInit>(std::forward<K>(k))); - Arena::CreateInArenaStorage(&node->kv.second, alloc_.arena()); - } + Node* node = Alloc<Node>(1); + // Even when arena is nullptr, CreateInArenaStorage is still used to + // ensure the arena of submessage will be consistent. Otherwise, + // submessage may have its own arena when message-owned arena is enabled. + Arena::CreateInArenaStorage(const_cast<Key*>(&node->kv.first), + alloc_.arena(), + static_cast<TypeToInit>(std::forward<K>(k))); + Arena::CreateInArenaStorage(&node->kv.second, alloc_.arena()); iterator result = InsertUnique(b, node); ++num_elements_; @@ -1026,12 +1023,12 @@ size_type BucketNumber(const K& k) const { // We xor the hash value against the random seed so that we effectively // have a random hash function. - uint64 h = hash_function()(k) ^ seed_; + uint64_t h = hash_function()(k) ^ seed_; // We use the multiplication method to determine the bucket number from // the hash value. The constant kPhi (suggested by Knuth) is roughly // (sqrt(5) - 1) / 2 * 2^64. - constexpr uint64 kPhi = uint64{0x9e3779b97f4a7c15}; + constexpr uint64_t kPhi = uint64_t{0x9e3779b97f4a7c15}; return ((kPhi * h) >> 32) & (num_buckets_ - 1); } @@ -1085,9 +1082,9 @@ size_type s = reinterpret_cast<uintptr_t>(this) >> 12; #if defined(__x86_64__) && defined(__GNUC__) && \ !defined(GOOGLE_PROTOBUF_NO_RDTSC) - uint32 hi, lo; + uint32_t hi, lo; asm volatile("rdtsc" : "=a"(lo), "=d"(hi)); - s += ((static_cast<uint64>(hi) << 32) | lo); + s += ((static_cast<uint64_t>(hi) << 32) | lo); #endif return s; }
diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index 87bc000..2aec2d4 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h
@@ -78,8 +78,8 @@ // field. // // cpp type | proto type | in-memory type | MapEntry accessor type -// int32 TYPE_INT32 int32 int32 -// int32 TYPE_FIXED32 int32 int32 +// int32_t TYPE_INT32 int32_t int32_t +// int32_t TYPE_FIXED32 int32_t int32_t // string TYPE_STRING ArenaStringPtr string // FooEnum TYPE_ENUM int int // FooMessage TYPE_MESSAGE FooMessage* FooMessage
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index 609d025..7dd50e2 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/src/google/protobuf/map_entry_lite.h
@@ -107,9 +107,9 @@ static const int kKeyFieldNumber = 1; static const int kValueFieldNumber = 2; - static uint8* InternalSerialize(int field_number, const Key& key, - const Value& value, uint8* ptr, - io::EpsCopyOutputStream* stream) { + static uint8_t* InternalSerialize(int field_number, const Key& key, + const Value& value, uint8_t* ptr, + io::EpsCopyOutputStream* stream) { ptr = stream->EnsureSpace(ptr); ptr = WireFormatLite::WriteTagToArray( field_number, WireFormatLite::WIRETYPE_LENGTH_DELIMITED, ptr); @@ -125,7 +125,7 @@ size_t inner_length = 2 + KeyTypeHandler::ByteSize(key) + ValueTypeHandler::ByteSize(value); return inner_length + io::CodedOutputStream::VarintSize32( - static_cast<uint32>(inner_length)); + static_cast<uint32_t>(inner_length)); } static int GetCachedSize(const Key& key, const Value& value) { @@ -167,9 +167,9 @@ static const int kValueFieldNumber = 2; // Constants for field tag. - static const uint8 kKeyTag = + static const uint8_t kKeyTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kKeyFieldNumber, KeyTypeHandler::kWireType); - static const uint8 kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( + static const uint8_t kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( kValueFieldNumber, ValueTypeHandler::kWireType); static const size_t kTagSize = 1; @@ -229,7 +229,7 @@ const char* _InternalParse(const char* ptr, ParseContext* ctx) final { while (!ctx->Done(&ptr)) { - uint32 tag; + uint32_t tag; ptr = ReadTag(ptr, &tag); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); if (tag == kKeyTag) { @@ -263,8 +263,8 @@ return size; } - ::google::protobuf::uint8* _InternalSerialize(::google::protobuf::uint8* ptr, - io::EpsCopyOutputStream* stream) const override { + ::uint8_t* _InternalSerialize( + ::uint8_t* ptr, io::EpsCopyOutputStream* stream) const override { ptr = KeyTypeHandler::Write(kKeyFieldNumber, key(), ptr, stream); return ValueTypeHandler::Write(kValueFieldNumber, value(), ptr, stream); } @@ -422,7 +422,8 @@ template <typename UnknownType> const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx, - bool (*is_valid)(int), uint32 field_num, + bool (*is_valid)(int), + uint32_t field_num, InternalMetadata* metadata) { auto entry = NewEntry(); ptr = entry->_InternalParse(ptr, ctx); @@ -500,7 +501,7 @@ public: // Needed for constructing tables KeyOnMemory key_; ValueOnMemory value_; - uint32 _has_bits_[1]; + uint32_t _has_bits_[1]; private: friend class ::PROTOBUF_NAMESPACE_ID::Arena; @@ -641,8 +642,8 @@ // The proto compiler generates the offsets in this struct as if this was // a regular message. This way the table driven code barely notices it's // dealing with a map field. - uint32 _has_bits_; // NOLINT - uint32 _cached_size_; // NOLINT + uint32_t _has_bits_; // NOLINT + uint32_t _cached_size_; // NOLINT KeyOnMemory key_; // NOLINT ValueOnMemory value_; // NOLINT };
diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc index d94b278..1581caf 100644 --- a/src/google/protobuf/map_field.cc +++ b/src/google/protobuf/map_field.cc
@@ -236,15 +236,15 @@ map_val->SetValue(value); \ break; \ } - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(BOOL, bool); HANDLE_TYPE(STRING, std::string); - HANDLE_TYPE(ENUM, int32); + HANDLE_TYPE(ENUM, int32_t); #undef HANDLE_TYPE case FieldDescriptor::CPPTYPE_MESSAGE: { const Message& message = @@ -543,15 +543,15 @@ map_val.SetValue(value); \ break; \ } - HANDLE_TYPE(INT32, int32, Int32); - HANDLE_TYPE(INT64, int64, Int64); - HANDLE_TYPE(UINT32, uint32, UInt32); - HANDLE_TYPE(UINT64, uint64, UInt64); + HANDLE_TYPE(INT32, int32_t, Int32); + HANDLE_TYPE(INT64, int64_t, Int64); + HANDLE_TYPE(UINT32, uint32_t, UInt32); + HANDLE_TYPE(UINT64, uint64_t, UInt64); HANDLE_TYPE(DOUBLE, double, Double); HANDLE_TYPE(FLOAT, float, Float); HANDLE_TYPE(BOOL, bool, Bool); HANDLE_TYPE(STRING, std::string, String); - HANDLE_TYPE(ENUM, int32, EnumValue); + HANDLE_TYPE(ENUM, int32_t, EnumValue); #undef HANDLE_TYPE case FieldDescriptor::CPPTYPE_MESSAGE: { const Message& message = reflection->GetMessage(*it, val_des); @@ -586,15 +586,15 @@ size += sizeof(TYPE) * map_size; \ break; \ } - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(BOOL, bool); HANDLE_TYPE(STRING, std::string); - HANDLE_TYPE(ENUM, int32); + HANDLE_TYPE(ENUM, int32_t); #undef HANDLE_TYPE case FieldDescriptor::CPPTYPE_MESSAGE: { while (it != map_.end()) {
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 7f52cc7..6668441 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h
@@ -95,19 +95,19 @@ return type_; } - void SetInt64Value(int64 value) { + void SetInt64Value(int64_t value) { SetType(FieldDescriptor::CPPTYPE_INT64); val_.int64_value_ = value; } - void SetUInt64Value(uint64 value) { + void SetUInt64Value(uint64_t value) { SetType(FieldDescriptor::CPPTYPE_UINT64); val_.uint64_value_ = value; } - void SetInt32Value(int32 value) { + void SetInt32Value(int32_t value) { SetType(FieldDescriptor::CPPTYPE_INT32); val_.int32_value_ = value; } - void SetUInt32Value(uint32 value) { + void SetUInt32Value(uint32_t value) { SetType(FieldDescriptor::CPPTYPE_UINT32); val_.uint32_value_ = value; } @@ -120,19 +120,19 @@ *val_.string_value_.get_mutable() = std::move(val); } - int64 GetInt64Value() const { + int64_t GetInt64Value() const { TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapKey::GetInt64Value"); return val_.int64_value_; } - uint64 GetUInt64Value() const { + uint64_t GetUInt64Value() const { TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapKey::GetUInt64Value"); return val_.uint64_value_; } - int32 GetInt32Value() const { + int32_t GetInt32Value() const { TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapKey::GetInt32Value"); return val_.int32_value_; } - uint32 GetUInt32Value() const { + uint32_t GetUInt32Value() const { TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapKey::GetUInt32Value"); return val_.uint32_value_; } @@ -242,10 +242,10 @@ union KeyValue { KeyValue() {} internal::ExplicitlyConstructed<std::string> string_value_; - int64 int64_value_; - int32 int32_value_; - uint64 uint64_value_; - uint32 uint32_value_; + int64_t int64_value_; + int32_t int32_value_; + uint64_t uint64_value_; + uint32_t uint32_value_; bool bool_value_; } val_; @@ -591,7 +591,7 @@ } template <typename UnknownType> const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx, - bool (*is_valid)(int), uint32 field_num, + bool (*is_valid)(int), uint32_t field_num, InternalMetadata* metadata) { return impl_.template ParseWithEnumValidation<UnknownType>( ptr, ctx, is_valid, field_num, metadata); @@ -682,25 +682,25 @@ public: MapValueConstRef() : data_(nullptr), type_() {} - int64 GetInt64Value() const { + int64_t GetInt64Value() const { TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueConstRef::GetInt64Value"); - return *reinterpret_cast<int64*>(data_); + return *reinterpret_cast<int64_t*>(data_); } - uint64 GetUInt64Value() const { + uint64_t GetUInt64Value() const { TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueConstRef::GetUInt64Value"); - return *reinterpret_cast<uint64*>(data_); + return *reinterpret_cast<uint64_t*>(data_); } - int32 GetInt32Value() const { + int32_t GetInt32Value() const { TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueConstRef::GetInt32Value"); - return *reinterpret_cast<int32*>(data_); + return *reinterpret_cast<int32_t*>(data_); } - uint32 GetUInt32Value() const { + uint32_t GetUInt32Value() const { TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueConstRef::GetUInt32Value"); - return *reinterpret_cast<uint32*>(data_); + return *reinterpret_cast<uint32_t*>(data_); } bool GetBoolValue() const { TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueConstRef::GetBoolValue"); @@ -774,21 +774,21 @@ public: MapValueRef() {} - void SetInt64Value(int64 value) { + void SetInt64Value(int64_t value) { TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::SetInt64Value"); - *reinterpret_cast<int64*>(data_) = value; + *reinterpret_cast<int64_t*>(data_) = value; } - void SetUInt64Value(uint64 value) { + void SetUInt64Value(uint64_t value) { TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::SetUInt64Value"); - *reinterpret_cast<uint64*>(data_) = value; + *reinterpret_cast<uint64_t*>(data_) = value; } - void SetInt32Value(int32 value) { + void SetInt32Value(int32_t value) { TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::SetInt32Value"); - *reinterpret_cast<int32*>(data_) = value; + *reinterpret_cast<int32_t*>(data_) = value; } - void SetUInt32Value(uint32 value) { + void SetUInt32Value(uint32_t value) { TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::SetUInt32Value"); - *reinterpret_cast<uint32*>(data_) = value; + *reinterpret_cast<uint32_t*>(data_) = value; } void SetBoolValue(bool value) { TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::SetBoolValue"); @@ -829,15 +829,15 @@ delete reinterpret_cast<TYPE*>(data_); \ break; \ } - HANDLE_TYPE(INT32, int32); - HANDLE_TYPE(INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(INT32, int32_t); + HANDLE_TYPE(INT64, int64_t); + HANDLE_TYPE(UINT32, uint32_t); + HANDLE_TYPE(UINT64, uint64_t); HANDLE_TYPE(DOUBLE, double); HANDLE_TYPE(FLOAT, float); HANDLE_TYPE(BOOL, bool); HANDLE_TYPE(STRING, std::string); - HANDLE_TYPE(ENUM, int32); + HANDLE_TYPE(ENUM, int32_t); HANDLE_TYPE(MESSAGE, Message); #undef HANDLE_TYPE }
diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h index a42b4fc..35231b2 100644 --- a/src/google/protobuf/map_field_inl.h +++ b/src/google/protobuf/map_field_inl.h
@@ -49,19 +49,19 @@ template <typename T> T UnwrapMapKey(const MapKey& map_key); template <> -inline int32 UnwrapMapKey<int32>(const MapKey& map_key) { +inline int32_t UnwrapMapKey<int32_t>(const MapKey& map_key) { return map_key.GetInt32Value(); } template <> -inline uint32 UnwrapMapKey<uint32>(const MapKey& map_key) { +inline uint32_t UnwrapMapKey<uint32_t>(const MapKey& map_key) { return map_key.GetUInt32Value(); } template <> -inline int64 UnwrapMapKey<int64>(const MapKey& map_key) { +inline int64_t UnwrapMapKey<int64_t>(const MapKey& map_key) { return map_key.GetInt64Value(); } template <> -inline uint64 UnwrapMapKey<uint64>(const MapKey& map_key) { +inline uint64_t UnwrapMapKey<uint64_t>(const MapKey& map_key) { return map_key.GetUInt64Value(); } template <> @@ -77,19 +77,19 @@ template <typename T> inline void SetMapKey(MapKey* map_key, const T& value); template <> -inline void SetMapKey<int32>(MapKey* map_key, const int32& value) { +inline void SetMapKey<int32_t>(MapKey* map_key, const int32_t& value) { map_key->SetInt32Value(value); } template <> -inline void SetMapKey<uint32>(MapKey* map_key, const uint32& value) { +inline void SetMapKey<uint32_t>(MapKey* map_key, const uint32_t& value) { map_key->SetUInt32Value(value); } template <> -inline void SetMapKey<int64>(MapKey* map_key, const int64& value) { +inline void SetMapKey<int64_t>(MapKey* map_key, const int64_t& value) { map_key->SetInt64Value(value); } template <> -inline void SetMapKey<uint64>(MapKey* map_key, const uint64& value) { +inline void SetMapKey<uint64_t>(MapKey* map_key, const uint64_t& value) { map_key->SetUInt64Value(value); } template <>
diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h index 46658d4..2a32106 100644 --- a/src/google/protobuf/map_field_lite.h +++ b/src/google/protobuf/map_field_lite.h
@@ -106,7 +106,7 @@ template <typename UnknownType> const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx, - bool (*is_valid)(int), uint32 field_num, + bool (*is_valid)(int), uint32_t field_num, InternalMetadata* metadata) { typename Derived::template Parser<MapFieldLite, Map<Key, T>> parser(this); return parser.template ParseWithEnumValidation<UnknownType>( @@ -129,7 +129,7 @@ } T* map_field; bool (*is_valid)(int); - uint32 field_num; + uint32_t field_num; InternalMetadata* metadata; }; @@ -138,7 +138,7 @@ // generated code template <typename UnknownType, typename T> EnumParseWrapper<UnknownType, T> InitEnumParseWrapper( - T* map_field, bool (*is_valid)(int), uint32 field_num, + T* map_field, bool (*is_valid)(int), uint32_t field_num, InternalMetadata* metadata) { return EnumParseWrapper<UnknownType, T>{map_field, is_valid, field_num, metadata};
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index d8067f7..c9be28b 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc
@@ -28,3783 +28,33 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// A hack to include windows.h first, which ensures the GetMessage macro can -// be undefined when we include <google/protobuf/stubs/common.h> -#if defined(_MSC_VER) -#define _WINSOCKAPI_ // to avoid re-definition in WinSock2.h -#define NOMINMAX // to avoid defining min/max macros -#include <windows.h> -#endif // _WIN32 - -#include <algorithm> -#include <map> -#include <memory> -#include <random> -#include <set> -#include <sstream> -#include <unordered_map> -#include <unordered_set> -#include <vector> - -#include <google/protobuf/stubs/logging.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/stringprintf.h> -#include <google/protobuf/testing/file.h> -#include <google/protobuf/arena_test_util.h> #include <google/protobuf/map_proto2_unittest.pb.h> -#include <google/protobuf/map_test_util.h> #include <google/protobuf/map_unittest.pb.h> -#include <google/protobuf/test_util.h> +#include <google/protobuf/reflection_tester.h> #include <google/protobuf/test_util2.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor_database.h> -#include <google/protobuf/dynamic_message.h> -#include <google/protobuf/map.h> -#include <google/protobuf/map_field_inl.h> -#include <google/protobuf/message.h> -#include <google/protobuf/reflection.h> -#include <google/protobuf/reflection_ops.h> -#include <google/protobuf/text_format.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/util/message_differencer.h> -#include <google/protobuf/util/time_util.h> -#include <gmock/gmock.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> -#include <google/protobuf/stubs/casts.h> -#include <google/protobuf/stubs/substitute.h> +#define BRIDGE_UNITTEST ::google::protobuf::bridge_unittest +#define UNITTEST ::protobuf_unittest +#define UNITTEST_IMPORT ::protobuf_unittest_import +#define UNITTEST_PACKAGE_NAME "protobuf_unittest" + +// Must include after defining UNITTEST, etc. +// clang-format off +#include <google/protobuf/test_util.inc> +#include <google/protobuf/map_test_util.inc> +#include <google/protobuf/map_test.inc> +// clang-format on + // Must be included last. #include <google/protobuf/port_def.inc> namespace google { namespace protobuf { - -using unittest::ForeignMessage; -using unittest::TestAllTypes; -using unittest::TestMap; -using unittest::TestRecursiveMapMessage; - -namespace internal { - -void MapTestForceDeterministic() { - io::CodedOutputStream::SetDefaultSerializationDeterministic(); -} - -namespace { - -// Map API Test ===================================================== - -class MapImplTest : public ::testing::Test { - protected: - MapImplTest() - : map_ptr_(new Map<int32, int32>()), - map_(*map_ptr_), - const_map_(*map_ptr_) { - EXPECT_TRUE(map_.empty()); - EXPECT_EQ(0, map_.size()); - } - - void ExpectSingleElement(int32 key, int32 value) { - EXPECT_FALSE(map_.empty()); - EXPECT_EQ(1, map_.size()); - ExpectElement(key, value); - } - - void ExpectElements(const std::map<int32, int32>& map) { - EXPECT_FALSE(map_.empty()); - EXPECT_EQ(map.size(), map_.size()); - for (std::map<int32, int32>::const_iterator it = map.begin(); - it != map.end(); ++it) { - ExpectElement(it->first, it->second); - } - } - - void ExpectElement(int32 key, int32 value) { - // Test map size is correct. - EXPECT_EQ(value, map_[key]); - EXPECT_EQ(1, map_.count(key)); - EXPECT_TRUE(map_.contains(key)); - - // Check mutable at and find work correctly. - EXPECT_EQ(value, map_.at(key)); - Map<int32, int32>::iterator it = map_.find(key); - - // iterator dereferenceable - EXPECT_EQ(key, (*it).first); - EXPECT_EQ(value, (*it).second); - EXPECT_EQ(key, it->first); - EXPECT_EQ(value, it->second); - - // iterator mutable - ((*it).second) = value + 1; - EXPECT_EQ(value + 1, map_[key]); - ((*it).second) = value; - EXPECT_EQ(value, map_[key]); - - it->second = value + 1; - EXPECT_EQ(value + 1, map_[key]); - it->second = value; - EXPECT_EQ(value, map_[key]); - - // copy constructor - Map<int32, int32>::iterator it_copy = it; - EXPECT_EQ(key, it_copy->first); - EXPECT_EQ(value, it_copy->second); - - // Immutable API ================================================ - - // Check immutable at and find work correctly. - EXPECT_EQ(value, const_map_.at(key)); - Map<int32, int32>::const_iterator const_it = const_map_.find(key); - - // iterator dereferenceable - EXPECT_EQ(key, (*const_it).first); - EXPECT_EQ(value, (*const_it).second); - EXPECT_EQ(key, const_it->first); - EXPECT_EQ(value, const_it->second); - - // copy constructor - Map<int32, int32>::const_iterator const_it_copy = const_it; - EXPECT_EQ(key, const_it_copy->first); - EXPECT_EQ(value, const_it_copy->second); - } - - std::unique_ptr<Map<int32, int32> > map_ptr_; - Map<int32, int32>& map_; - const Map<int32, int32>& const_map_; -}; - -TEST_F(MapImplTest, OperatorBracket) { - int32 key = 0; - int32 value1 = 100; - int32 value2 = 101; - - EXPECT_EQ(0, map_[key]); - - map_[key] = value1; - ExpectSingleElement(key, value1); - - map_[key] = value2; - ExpectSingleElement(key, value2); -} - -struct MoveTestKey { - MoveTestKey(int data, int* copies) : data(data), copies(copies) {} - - MoveTestKey(const MoveTestKey& other) - : data(other.data), copies(other.copies) { - ++*copies; - } - - MoveTestKey(MoveTestKey&& other) noexcept - : data(other.data), copies(other.copies) {} - - friend bool operator==(const MoveTestKey& lhs, const MoveTestKey& rhs) { - return lhs.data == rhs.data; - } - friend bool operator<(const MoveTestKey& lhs, const MoveTestKey& rhs) { - return lhs.data < rhs.data; - } - - int data; - int* copies; -}; - -} // namespace -} // namespace internal -} // namespace protobuf -} // namespace google - -namespace std { - -template <> // NOLINT -struct hash<google::protobuf::internal::MoveTestKey> { - size_t operator()(const google::protobuf::internal::MoveTestKey& key) const { - return hash<int>{}(key.data); - } -}; -} // namespace std - -namespace google { -namespace protobuf { namespace internal { namespace { -TEST_F(MapImplTest, OperatorBracketRValue) { - Arena arena; - for (Arena* arena_to_use : {&arena, static_cast<Arena*>(nullptr)}) { - int copies = 0; - Map<MoveTestKey, int> map(arena_to_use); - MoveTestKey key1(1, &copies); - EXPECT_EQ(copies, 0); - map[key1] = 0; - EXPECT_EQ(copies, 1); - map[MoveTestKey(2, &copies)] = 2; - EXPECT_EQ(copies, 1); - } -} - -TEST_F(MapImplTest, OperatorBracketNonExist) { - int32 key = 0; - int32 default_value = 0; - - EXPECT_EQ(default_value, map_[key]); - ExpectSingleElement(key, default_value); -} - -TEST_F(MapImplTest, MutableAt) { - int32 key = 0; - int32 value1 = 100; - int32 value2 = 101; - - map_[key] = value1; - ExpectSingleElement(key, value1); - - map_.at(key) = value2; - ExpectSingleElement(key, value2); -} - -#ifdef PROTOBUF_HAS_DEATH_TEST - -TEST_F(MapImplTest, MutableAtNonExistDeathTest) { - EXPECT_DEATH(map_.at(0), ""); -} - -TEST_F(MapImplTest, ImmutableAtNonExistDeathTest) { - EXPECT_DEATH(const_map_.at(0), ""); -} - -TEST_F(MapImplTest, UsageErrors) { - MapKey key; - key.SetInt64Value(1); - EXPECT_DEATH(key.GetUInt64Value(), - "Protocol Buffer map usage error:\n" - "MapKey::GetUInt64Value type does not match\n" - " Expected : uint64\n" - " Actual : int64"); - - MapValueRef value; - EXPECT_DEATH( - value.SetFloatValue(0.1), - "Protocol Buffer map usage error:\n" - "MapValue[Const]*Ref::type MapValue[Const]*Ref is not initialized."); -} - -#endif // PROTOBUF_HAS_DEATH_TEST - -TEST_F(MapImplTest, MapKeyAssignment) { - MapKey from, to; - from.SetStringValue("abc"); - to = from; - EXPECT_EQ("abc", to.GetStringValue()); -} - -TEST_F(MapImplTest, CountNonExist) { EXPECT_EQ(0, map_.count(0)); } - -TEST_F(MapImplTest, ContainNotExist) { EXPECT_FALSE(map_.contains(0)); } - -TEST_F(MapImplTest, ImmutableContainNotExist) { - EXPECT_FALSE(const_map_.contains(0)); -} - -TEST_F(MapImplTest, MutableFindNonExist) { - EXPECT_TRUE(map_.end() == map_.find(0)); -} - -TEST_F(MapImplTest, ImmutableFindNonExist) { - EXPECT_TRUE(const_map_.end() == const_map_.find(0)); -} - -TEST_F(MapImplTest, ConstEnd) { - EXPECT_TRUE(const_map_.end() == const_map_.cend()); -} - -TEST_F(MapImplTest, GetReferenceFromIterator) { - for (int i = 0; i < 10; i++) { - map_[i] = i; - } - - for (Map<int32, int32>::const_iterator it = map_.cbegin(); - it != map_.cend();) { - Map<int32, int32>::const_reference entry = *it++; - EXPECT_EQ(entry.first, entry.second); - } - - for (Map<int32, int32>::const_iterator it = const_map_.begin(); - it != const_map_.end();) { - Map<int32, int32>::const_reference entry = *it++; - EXPECT_EQ(entry.first, entry.second); - } - - for (Map<int32, int32>::iterator it = map_.begin(); it != map_.end();) { - Map<int32, int32>::reference entry = *it++; - EXPECT_EQ(entry.first + 1, ++entry.second); - } -} - -TEST_F(MapImplTest, IteratorBasic) { - map_[0] = 0; - - // Default constructible (per forward iterator requirements). - Map<int, int>::const_iterator cit; - Map<int, int>::iterator it; - - it = map_.begin(); - cit = it; // Converts to const_iterator - - // Can compare between them. - EXPECT_TRUE(it == cit); - EXPECT_FALSE(cit != it); - - // Pre increment. - EXPECT_FALSE(it == ++cit); - - // Post increment. - EXPECT_FALSE(it++ == cit); - EXPECT_TRUE(it == cit); -} - -template <typename Iterator> -static int64 median(Iterator i0, Iterator i1) { - std::vector<int64> v(i0, i1); - std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end()); - return v[v.size() / 2]; -} - -static int64 Now() { - return util::TimeUtil::TimestampToNanoseconds( - util::TimeUtil::GetCurrentTime()); -} - -// Arbitrary odd integers for creating test data. -static int k0 = 812398771; -static int k1 = 1312938717; -static int k2 = 1321555333; - -// A naive begin() implementation will cause begin() to get slower and slower -// if one erases elements at the "front" of the hash map, and we'd like to -// avoid that, as std::unordered_map does. -TEST_F(MapImplTest, BeginIsFast) { - if (true) return; // TODO(gpike): make this less flaky and re-enable it. - Map<int32, int32> map; - const int kTestSize = 250000; - // Create a random-looking map of size n. Use non-negative integer keys. - uint32 frog = 123983; - int last_key = 0; - int counter = 0; - while (map.size() < kTestSize) { - frog *= static_cast<uint32>(k0); - frog ^= frog >> 17; - frog += counter++; - last_key = - static_cast<int>(frog) >= 0 ? static_cast<int>(frog) : last_key ^ 1; - GOOGLE_DCHECK_GE(last_key, 0); - map[last_key] = last_key ^ 1; - } - std::vector<int64> times; - // We're going to do map.erase(map.begin()) over and over again. But, - // just in case one iteration is fast compared to the granularity of - // our time keeping, we measure kChunkSize iterations per outer-loop iter. - const int kChunkSize = 1000; - GOOGLE_CHECK_EQ(kTestSize % kChunkSize, 0); - do { - const int64 start = Now(); - for (int i = 0; i < kChunkSize; i++) { - map.erase(map.begin()); - } - const int64 end = Now(); - if (end > start) { - times.push_back(end - start); - } - } while (!map.empty()); - if (times.size() < .99 * kTestSize / kChunkSize) { - GOOGLE_LOG(WARNING) << "Now() isn't helping us measure time"; - return; - } - int64 x0 = median(times.begin(), times.begin() + 9); - int64 x1 = median(times.begin() + times.size() - 9, times.end()); - GOOGLE_LOG(INFO) << "x0=" << x0 << ", x1=" << x1; - // x1 will greatly exceed x0 if the code we just executed took O(n^2) time. - // And we'll probably time out and never get here. So, this test is - // intentionally loose: we check that x0 and x1 are within a factor of 8. - EXPECT_GE(x1, x0 / 8); - EXPECT_GE(x0, x1 / 8); -} - -// Try to create kTestSize keys that will land in just a few buckets, and -// time the insertions, to get a rough estimate of whether an O(n^2) worst case -// was triggered. This test is a hacky, but probably better than nothing. -TEST_F(MapImplTest, HashFlood) { - const int kTestSize = 1024; // must be a power of 2 - std::set<int> s; - for (int i = 0; s.size() < kTestSize; i++) { - if ((map_.hash_function()(i) & (kTestSize - 1)) < 3) { - s.insert(i); - } - } - // Create hash table with kTestSize entries that hash flood a table with - // 1024 (or 512 or 2048 or ...) entries. This assumes that map_ uses powers - // of 2 for table sizes, and that it's sufficient to "flood" with respect to - // the low bits of the output of map_.hash_function(). - std::vector<int64> times; - std::set<int>::iterator it = s.begin(); - int count = 0; - do { - const int64 start = Now(); - map_[*it] = 0; - const int64 end = Now(); - if (end > start) { - times.push_back(end - start); - } - ++count; - ++it; - } while (it != s.end()); - if (times.size() < .99 * count) return; - int64 x0 = median(times.begin(), times.begin() + 9); - int64 x1 = median(times.begin() + times.size() - 9, times.end()); - // x1 will greatly exceed x0 if the code we just executed took O(n^2) time. - // But we want to allow O(n log n). A factor of 20 should be generous enough. - EXPECT_LE(x1, x0 * 20); -} - -TEST_F(MapImplTest, CopyIteratorStressTest) { - std::vector<Map<int32, int32>::iterator> v; - const int kIters = 1e5; - for (uint32 i = 0; i < kIters; i++) { - int32 key = (3 + i * (5 + i * (-8 + i * (62 + i)))) & 0x77777777; - map_[key] = i; - v.push_back(map_.find(key)); - } - for (std::vector<Map<int32, int32>::iterator>::const_iterator it = v.begin(); - it != v.end(); it++) { - Map<int32, int32>::iterator i = *it; - ASSERT_EQ(i->first, (*it)->first); - ASSERT_EQ(i->second, (*it)->second); - } -} - -template <typename T, typename U> -static void TestValidityForAllKeysExcept(int key_to_avoid, const T& check_map, - const U& map) { - typedef typename U::value_type value_type; // a key-value pair - for (typename U::const_iterator it = map.begin(); it != map.end(); ++it) { - const int key = it->first; - if (key == key_to_avoid) continue; - // All iterators relevant to this key, whether old (from check_map) or new, - // must point to the same memory. So, test pointer equality here. - const value_type* check_val = &*check_map.find(key)->second; - EXPECT_EQ(check_val, &*it); - EXPECT_EQ(check_val, &*map.find(key)); - } -} - -// EXPECT i0 and i1 to be the same. Advancing them should have the same effect, -// too. -template <typename Iter> -static void TestEqualIterators(Iter i0, Iter i1, Iter end) { - const int kMaxAdvance = 10; - for (int i = 0; i < kMaxAdvance; i++) { - EXPECT_EQ(i0 == end, i1 == end); - if (i0 == end) return; - EXPECT_EQ(&*i0, &*i1) << "iter " << i; - ++i0; - ++i1; - } -} - -template <typename IteratorType> -static void TestOldVersusNewIterator(int skip, Map<int, int>* m) { - const int initial_size = m->size(); - IteratorType it = m->begin(); - for (int i = 0; i < skip && it != m->end(); it++, i++) { - } - if (it == m->end()) return; - const IteratorType old = it; - GOOGLE_LOG(INFO) << "skip=" << skip << ", old->first=" << old->first; - const int target_size = - initial_size < 100 ? initial_size * 5 : initial_size * 5 / 4; - for (int i = 0; m->size() <= target_size; i++) { - (*m)[i] = 0; - } - // Iterator 'old' should still work just fine despite the growth of *m. - const IteratorType after_growth = m->find(old->first); - TestEqualIterators<IteratorType>(old, after_growth, m->end()); - - // Now shrink the number of elements. Do this with a mix of erases and - // inserts to increase the chance that the hashtable will resize to a lower - // number of buckets. (But, in any case, the test is still useful.) - for (int i = 0; i < 2 * (target_size - initial_size); i++) { - if (i != old->first) { - m->erase(i); - } - if (((i ^ m->begin()->first) & 15) == 0) { - (*m)[i * 342] = i; - } - } - // Now, the table has grown and shrunk; test again. - TestEqualIterators<IteratorType>(old, m->find(old->first), m->end()); - TestEqualIterators<IteratorType>(old, after_growth, m->end()); -} - -// Create and test an n-element Map, with emphasis on iterator correctness. -static void StressTestIterators(int n) { - GOOGLE_LOG(INFO) << "StressTestIterators " << n; - GOOGLE_CHECK_GT(n, 0); - // Create a random-looking map of size n. Use non-negative integer keys. - Map<int, int> m; - uint32 frog = 123987 + n; - int last_key = 0; - int counter = 0; - while (m.size() < n) { - frog *= static_cast<uint32>(k0); - frog ^= frog >> 17; - frog += counter++; - last_key = - static_cast<int>(frog) >= 0 ? static_cast<int>(frog) : last_key ^ 1; - GOOGLE_DCHECK_GE(last_key, 0); - m[last_key] = last_key ^ 1; - } - // Test it. - ASSERT_EQ(n, m.size()); - // Create maps of pointers and iterators. - // These should remain valid even if we modify m. - std::unordered_map<int, Map<int, int>::value_type*> mp(n); - std::unordered_map<int, Map<int, int>::iterator> mi(n); - for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it) { - mp[it->first] = &*it; - mi[it->first] = it; - } - ASSERT_EQ(m.size(), mi.size()); - ASSERT_EQ(m.size(), mp.size()); - m.erase(last_key); - ASSERT_EQ(n - 1, m.size()); - TestValidityForAllKeysExcept(last_key, mp, m); - TestValidityForAllKeysExcept(last_key, mi, m); - - m[last_key] = 0; - ASSERT_EQ(n, m.size()); - // Test old iterator vs new iterator, with table modification in between. - TestOldVersusNewIterator<Map<int, int>::const_iterator>(n % 3, &m); - TestOldVersusNewIterator<Map<int, int>::iterator>(n % (1 + (n / 40)), &m); - // Finally, ensure erase(iterator) doesn't reorder anything, because that is - // what its documentation says. - m[last_key] = m[last_key ^ 999] = 0; - std::vector<Map<int, int>::iterator> v; - v.reserve(m.size()); - int position_of_last_key = 0; - for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it) { - if (it->first == last_key) { - position_of_last_key = v.size(); - } - v.push_back(it); - } - ASSERT_EQ(m.size(), v.size()); - const Map<int, int>::iterator erase_result = m.erase(m.find(last_key)); - int index = 0; - for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it, ++index) { - if (index == position_of_last_key) { - EXPECT_EQ(&*erase_result, &*v[++index]); - } - ASSERT_EQ(&*it, &*v[index]); - } -} - -TEST_F(MapImplTest, IteratorInvalidation) { - // Create a set of pseudo-random sizes to test. -#ifndef NDEBUG - const int kMaxSizeToTest = 100 * 1000; -#else - const int kMaxSizeToTest = 1000 * 1000; -#endif - std::set<int> s; - int n = kMaxSizeToTest; - unsigned int frog = k1 + n; - while (n > 1 && s.size() < 25) { - s.insert(n); - n = static_cast<int>(n * 100 / (101.0 + (frog & 63))); - frog *= k2; - frog ^= frog >> 17; - } - // Ensure we test a few small sizes. - s.insert(1); - s.insert(2); - s.insert(3); - // Now, the real work. - for (std::set<int>::iterator i = s.begin(); i != s.end(); ++i) { - StressTestIterators(*i); - } -} - -// Test that erase() revalidates iterators. -TEST_F(MapImplTest, EraseRevalidates) { - map_[3] = map_[13] = map_[20] = 0; - const int initial_size = map_.size(); - EXPECT_EQ(3, initial_size); - std::vector<Map<int, int>::iterator> v; - for (Map<int, int>::iterator it = map_.begin(); it != map_.end(); ++it) { - v.push_back(it); - } - EXPECT_EQ(initial_size, v.size()); - for (int i = 0; map_.size() <= initial_size * 20; i++) { - map_[i] = 0; - } - const int larger_size = map_.size(); - // We've greatly increased the size of the map, so it is highly likely that - // the following will corrupt m if erase() doesn't properly revalidate - // iterators passed to it. Finishing this routine without crashing indicates - // success. - for (int i = 0; i < v.size(); i++) { - map_.erase(v[i]); - } - EXPECT_EQ(larger_size - v.size(), map_.size()); -} - -template <typename T> -bool IsConstHelper(T& /*t*/) { // NOLINT. We want to catch non-const refs here. - return false; -} -template <typename T> -bool IsConstHelper(const T& /*t*/) { - return true; -} - -TEST_F(MapImplTest, IteratorConstness) { - map_[0] = 0; - EXPECT_TRUE(IsConstHelper(*map_.cbegin())); - EXPECT_TRUE(IsConstHelper(*const_map_.begin())); - EXPECT_FALSE(IsConstHelper(*map_.begin())); -} - -bool IsForwardIteratorHelper(std::forward_iterator_tag /*tag*/) { return true; } - -TEST_F(MapImplTest, IteratorCategory) { - EXPECT_TRUE(IsForwardIteratorHelper( - std::iterator_traits<Map<int, int>::iterator>::iterator_category())); - EXPECT_TRUE(IsForwardIteratorHelper( - std::iterator_traits< - Map<int, int>::const_iterator>::iterator_category())); -} - -TEST_F(MapImplTest, InsertSingle) { - int32 key = 0; - int32 value1 = 100; - int32 value2 = 101; - - // Insert a non-existed key. - std::pair<Map<int32, int32>::iterator, bool> result1 = - map_.insert(Map<int32, int32>::value_type(key, value1)); - ExpectSingleElement(key, value1); - - Map<int32, int32>::iterator it1 = result1.first; - EXPECT_EQ(key, it1->first); - EXPECT_EQ(value1, it1->second); - EXPECT_TRUE(result1.second); - - // Insert an existed key. - std::pair<Map<int32, int32>::iterator, bool> result2 = - map_.insert(Map<int32, int32>::value_type(key, value2)); - ExpectSingleElement(key, value1); - - Map<int32, int32>::iterator it2 = result2.first; - EXPECT_TRUE(it1 == it2); - EXPECT_FALSE(result2.second); -} - -TEST_F(MapImplTest, InsertByIterator) { - int32 key1 = 0; - int32 key2 = 1; - int32 value1a = 100; - int32 value1b = 101; - int32 value2a = 200; - int32 value2b = 201; - - std::map<int32, int32> map1; - map1[key1] = value1a; - map1[key2] = value2a; - - map_.insert(map1.begin(), map1.end()); - ExpectElements(map1); - - std::map<int32, int32> map2; - map2[key1] = value1b; - map2[key2] = value2b; - - map_.insert(map2.begin(), map2.end()); - ExpectElements(map1); -} - -TEST_F(MapImplTest, InsertByInitializerList) { - map_.insert({{1, 100}, {2, 200}}); - ExpectElements({{1, 100}, {2, 200}}); - - map_.insert({{2, 201}, {3, 301}}); - ExpectElements({{1, 100}, {2, 200}, {3, 301}}); -} - -TEST_F(MapImplTest, EraseSingleByKey) { - int32 key = 0; - int32 value = 100; - - map_[key] = value; - ExpectSingleElement(key, value); - - // Erase an existing key. - EXPECT_EQ(1, map_.erase(key)); - EXPECT_TRUE(map_.empty()); - EXPECT_EQ(0, map_.size()); - EXPECT_TRUE(map_.end() == map_.find(key)); - EXPECT_TRUE(map_.begin() == map_.end()); - - // Erase a non-existing key. - EXPECT_EQ(0, map_.erase(key)); -} - -TEST_F(MapImplTest, EraseMutipleByKey) { - // erase in one specific order to trigger corner cases - for (int i = 0; i < 5; i++) { - map_[i] = i; - } - - map_.erase(0); - EXPECT_EQ(4, map_.size()); - EXPECT_TRUE(map_.end() == map_.find(0)); - - map_.erase(1); - EXPECT_EQ(3, map_.size()); - EXPECT_TRUE(map_.end() == map_.find(1)); - - map_.erase(3); - EXPECT_EQ(2, map_.size()); - EXPECT_TRUE(map_.end() == map_.find(3)); - - map_.erase(4); - EXPECT_EQ(1, map_.size()); - EXPECT_TRUE(map_.end() == map_.find(4)); - - map_.erase(2); - EXPECT_EQ(0, map_.size()); - EXPECT_TRUE(map_.end() == map_.find(2)); -} - -TEST_F(MapImplTest, EraseSingleByIterator) { - int32 key = 0; - int32 value = 100; - - map_[key] = value; - ExpectSingleElement(key, value); - - Map<int32, int32>::iterator it = map_.find(key); - map_.erase(it); - EXPECT_TRUE(map_.empty()); - EXPECT_EQ(0, map_.size()); - EXPECT_TRUE(map_.end() == map_.find(key)); - EXPECT_TRUE(map_.begin() == map_.end()); -} - -TEST_F(MapImplTest, ValidIteratorAfterErase) { - for (int i = 0; i < 10; i++) { - map_[i] = i; - } - - int count = 0; - - for (Map<int32, int32>::iterator it = map_.begin(); it != map_.end();) { - count++; - if (it->first % 2 == 1) { - map_.erase(it++); - } else { - ++it; - } - } - - EXPECT_EQ(10, count); - EXPECT_EQ(5, map_.size()); -} - -TEST_F(MapImplTest, EraseByIterator) { - int32 key1 = 0; - int32 key2 = 1; - int32 value1 = 100; - int32 value2 = 101; - - std::map<int32, int32> map; - map[key1] = value1; - map[key2] = value2; - - map_.insert(map.begin(), map.end()); - ExpectElements(map); - - map_.erase(map_.begin(), map_.end()); - EXPECT_TRUE(map_.empty()); - EXPECT_EQ(0, map_.size()); - EXPECT_TRUE(map_.end() == map_.find(key1)); - EXPECT_TRUE(map_.end() == map_.find(key2)); - EXPECT_TRUE(map_.begin() == map_.end()); -} - -TEST_F(MapImplTest, Clear) { - int32 key = 0; - int32 value = 100; - - map_[key] = value; - ExpectSingleElement(key, value); - - map_.clear(); - - EXPECT_TRUE(map_.empty()); - EXPECT_EQ(0, map_.size()); - EXPECT_TRUE(map_.end() == map_.find(key)); - EXPECT_TRUE(map_.begin() == map_.end()); -} - -static void CopyConstructorHelper(Arena* arena, Map<int32, int32>* m) { - int32 key1 = 0; - int32 key2 = 1; - int32 value1 = 100; - int32 value2 = 101; - - std::map<int32, int32> map; - map[key1] = value1; - map[key2] = value2; - - m->insert(map.begin(), map.end()); - - Map<int32, int32> other(*m); - - EXPECT_EQ(2, other.size()); - EXPECT_EQ(value1, other.at(key1)); - EXPECT_EQ(value2, other.at(key2)); -} - -TEST_F(MapImplTest, CopyConstructorWithArena) { - Arena a; - CopyConstructorHelper(&a, &map_); -} - -TEST_F(MapImplTest, CopyConstructorWithoutArena) { - CopyConstructorHelper(NULL, &map_); -} - -TEST_F(MapImplTest, IterConstructor) { - int32 key1 = 0; - int32 key2 = 1; - int32 value1 = 100; - int32 value2 = 101; - - std::map<int32, int32> map; - map[key1] = value1; - map[key2] = value2; - - Map<int32, int32> new_map(map.begin(), map.end()); - - EXPECT_EQ(2, new_map.size()); - EXPECT_EQ(value1, new_map.at(key1)); - EXPECT_EQ(value2, new_map.at(key2)); -} - -TEST_F(MapImplTest, Assigner) { - int32 key1 = 0; - int32 key2 = 1; - int32 value1 = 100; - int32 value2 = 101; - - std::map<int32, int32> map; - map[key1] = value1; - map[key2] = value2; - - map_.insert(map.begin(), map.end()); - - Map<int32, int32> other; - int32 key_other = 123; - int32 value_other = 321; - other[key_other] = value_other; - EXPECT_EQ(1, other.size()); - - other = map_; - - EXPECT_EQ(2, other.size()); - EXPECT_EQ(value1, other.at(key1)); - EXPECT_EQ(value2, other.at(key2)); - EXPECT_TRUE(other.find(key_other) == other.end()); - - // Self assign - other = *&other; // Avoid -Wself-assign. - EXPECT_EQ(2, other.size()); - EXPECT_EQ(value1, other.at(key1)); - EXPECT_EQ(value2, other.at(key2)); -} - -TEST_F(MapImplTest, Rehash) { - const int test_size = 50; - std::map<int32, int32> reference_map; - for (int i = 0; i < test_size; i++) { - reference_map[i] = i; - } - for (int i = 0; i < test_size; i++) { - map_[i] = reference_map[i]; - EXPECT_EQ(reference_map[i], map_[i]); - } - for (int i = 0; i < test_size; i++) { - map_.erase(i); - EXPECT_TRUE(map_.end() == map_.find(i)); - } - EXPECT_TRUE(map_.empty()); -} - -TEST_F(MapImplTest, EqualRange) { - int key = 100, key_missing = 101; - map_[key] = 100; - - std::pair<Map<int32, int32>::iterator, Map<int32, int32>::iterator> range = - map_.equal_range(key); - EXPECT_TRUE(map_.find(key) == range.first); - EXPECT_TRUE(++map_.find(key) == range.second); - - range = map_.equal_range(key_missing); - EXPECT_TRUE(map_.end() == range.first); - EXPECT_TRUE(map_.end() == range.second); - - std::pair<Map<int32, int32>::const_iterator, - Map<int32, int32>::const_iterator> - const_range = const_map_.equal_range(key); - EXPECT_TRUE(const_map_.find(key) == const_range.first); - EXPECT_TRUE(++const_map_.find(key) == const_range.second); - - const_range = const_map_.equal_range(key_missing); - EXPECT_TRUE(const_map_.end() == const_range.first); - EXPECT_TRUE(const_map_.end() == const_range.second); -} - -TEST_F(MapImplTest, ConvertToStdMap) { - map_[100] = 101; - std::map<int32, int32> std_map(map_.begin(), map_.end()); - EXPECT_EQ(1, std_map.size()); - EXPECT_EQ(101, std_map[100]); -} - -TEST_F(MapImplTest, ConvertToStdVectorOfPairs) { - map_[100] = 101; - std::vector<std::pair<int32, int32> > std_vec(map_.begin(), map_.end()); - EXPECT_EQ(1, std_vec.size()); - EXPECT_EQ(100, std_vec[0].first); - EXPECT_EQ(101, std_vec[0].second); -} - -TEST_F(MapImplTest, SwapBasic) { - Map<int32, int32> another; - map_[9398] = 41999; - another[9398] = 41999; - another[8070] = 42056; - another.swap(map_); - EXPECT_THAT(another, - testing::UnorderedElementsAre(testing::Pair(9398, 41999))); - EXPECT_THAT(map_, testing::UnorderedElementsAre(testing::Pair(8070, 42056), - testing::Pair(9398, 41999))); -} - -TEST_F(MapImplTest, SwapArena) { - Arena arena1, arena2; - Map<int32, int32> m1(&arena1); - Map<int32, int32> m2(&arena2); - map_[9398] = 41999; - m1[9398] = 41999; - m1[8070] = 42056; - m2[10244] = 10247; - m2[8070] = 42056; - m1.swap(map_); - EXPECT_THAT(m1, testing::UnorderedElementsAre(testing::Pair(9398, 41999))); - EXPECT_THAT(map_, testing::UnorderedElementsAre(testing::Pair(8070, 42056), - testing::Pair(9398, 41999))); - m2.swap(m1); - EXPECT_THAT(m1, testing::UnorderedElementsAre(testing::Pair(8070, 42056), - testing::Pair(10244, 10247))); - EXPECT_THAT(m2, testing::UnorderedElementsAre(testing::Pair(9398, 41999))); -} - -TEST_F(MapImplTest, CopyAssignMapIterator) { - TestMap message; - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.SetMapFieldsViaMapReflection(&message); - MapIterator it1 = reflection_tester.MapBegin(&message, "map_int32_int32"); - MapIterator it2 = reflection_tester.MapEnd(&message, "map_int32_int32"); - it2 = it1; - EXPECT_EQ(it1.GetKey().GetInt32Value(), it2.GetKey().GetInt32Value()); -} - -TEST_F(MapImplTest, SpaceUsed) { - constexpr size_t kMinCap = 8; - - Map<int32, int32> m; - // An newly constructed map should have no space used. - EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), 0); - - size_t capacity = kMinCap; - for (int i = 0; i < 100; ++i) { - m[i]; - static constexpr double kMaxLoadFactor = .75; - if (m.size() >= capacity * kMaxLoadFactor) { - capacity *= 2; - } - EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), - sizeof(void*) * capacity + - m.size() * sizeof(std::pair<std::pair<int32, int32>, void*>)); - } - - // Test string, and non-scalar keys. - Map<std::string, int32> m2; - std::string str = "Some arbitrarily large string"; - m2[str] = 1; - EXPECT_EQ(m2.SpaceUsedExcludingSelfLong(), - sizeof(void*) * kMinCap + - sizeof(std::pair<std::pair<std::string, int32>, void*>) + - internal::StringSpaceUsedExcludingSelfLong(str)); - - // Test messages, and non-scalar values. - Map<int32, TestAllTypes> m3; - m3[0].set_optional_string(str); - EXPECT_EQ(m3.SpaceUsedExcludingSelfLong(), - sizeof(void*) * kMinCap + - sizeof(std::pair<std::pair<int32, TestAllTypes>, void*>) + - m3[0].SpaceUsedLong() - sizeof(m3[0])); -} - -// Attempts to verify that a map with keys a and b has a random ordering. This -// function returns true if it succeeds in observing both possible orderings. -bool MapOrderingIsRandom(int a, int b) { - bool saw_a_first = false; - bool saw_b_first = false; - - for (int i = 0; i < 50; ++i) { - Map<int32, int32> m; - m[a] = 0; - m[b] = 0; - int32 first_element = m.begin()->first; - if (first_element == a) saw_a_first = true; - if (first_element == b) saw_b_first = true; - if (saw_a_first && saw_b_first) { - return true; - } - } - - return false; -} - -// This test verifies that the iteration order is reasonably random even for -// small maps. Currently we only have sufficient randomness for debug builds and -// builds where we can use the RDTSC instruction, so we only test for those -// builds. -#if defined(__x86_64__) && defined(__GNUC__) && \ - !defined(GOOGLE_PROTOBUF_NO_RDTSC) -TEST_F(MapImplTest, RandomOrdering) { - for (int i = 0; i < 10; ++i) { - for (int j = i + 1; j < 10; ++j) { - EXPECT_TRUE(MapOrderingIsRandom(i, j)) - << "Map with keys " << i << " and " << j - << " has deterministic ordering"; - } - } -} -#endif - -template <typename Key> -void TestTransparent(const Key& key, const Key& miss_key) { - Map<std::string, int> m; - const auto& cm = m; - - m.insert({"ABC", 1}); - - const auto abc_it = m.begin(); - - m.insert({"DEF", 2}); - - using testing::Pair; - using testing::UnorderedElementsAre; - - EXPECT_EQ(m.at(key), 1); - EXPECT_EQ(cm.at(key), 1); - -#ifdef PROTOBUF_HAS_DEATH_TEST - EXPECT_DEATH(m.at(miss_key), ""); - EXPECT_DEATH(cm.at(miss_key), ""); -#endif // PROTOBUF_HAS_DEATH_TEST - - EXPECT_EQ(m.count(key), 1); - EXPECT_EQ(cm.count(key), 1); - EXPECT_EQ(m.count(miss_key), 0); - EXPECT_EQ(cm.count(miss_key), 0); - - EXPECT_EQ(m.find(key), abc_it); - EXPECT_EQ(cm.find(key), abc_it); - EXPECT_EQ(m.find(miss_key), m.end()); - EXPECT_EQ(cm.find(miss_key), cm.end()); - - EXPECT_TRUE(m.contains(key)); - EXPECT_TRUE(cm.contains(key)); - EXPECT_FALSE(m.contains(miss_key)); - EXPECT_FALSE(cm.contains(miss_key)); - - EXPECT_THAT(m.equal_range(key), Pair(abc_it, std::next(abc_it))); - EXPECT_THAT(cm.equal_range(key), Pair(abc_it, std::next(abc_it))); - EXPECT_THAT(m.equal_range(miss_key), Pair(m.end(), m.end())); - EXPECT_THAT(cm.equal_range(miss_key), Pair(m.end(), m.end())); - - EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 1), Pair("DEF", 2))); - EXPECT_EQ(m.erase(key), 1); - EXPECT_THAT(m, UnorderedElementsAre(Pair("DEF", 2))); - EXPECT_EQ(m.erase(key), 0); - EXPECT_EQ(m.erase(miss_key), 0); - EXPECT_THAT(m, UnorderedElementsAre(Pair("DEF", 2))); - - m[key]; - EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 0), Pair("DEF", 2))); - m[key] = 1; - EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 1), Pair("DEF", 2))); -} - -TEST_F(MapImplTest, TransparentLookupForString) { - TestTransparent("ABC", "LKJ"); - TestTransparent(std::string("ABC"), std::string("LKJ")); -#if defined(__cpp_lib_string_view) - TestTransparent(std::string_view("ABC"), std::string_view("LKJ")); -#endif // defined(__cpp_lib_string_view) - - // std::reference_wrapper - std::string abc = "ABC", lkj = "LKJ"; - TestTransparent(std::ref(abc), std::ref(lkj)); - TestTransparent(std::cref(abc), std::cref(lkj)); -} - -TEST_F(MapImplTest, ConstInit) { - PROTOBUF_CONSTINIT static Map<int, int> map; // NOLINT - EXPECT_TRUE(map.empty()); -} - -// Map Field Reflection Test ======================================== - -static int Func(int i, int j) { return i * j; } - -static std::string StrFunc(int i, int j) { return StrCat(Func(i, j)); } - -static int Int(const std::string& value) { - int result = 0; - std::istringstream(value) >> result; - return result; -} - -} // namespace - -// This class is a friend, so no anonymous namespace. -class MapFieldReflectionTest : public testing::Test { - protected: - typedef FieldDescriptor FD; - - int MapSize(const Reflection* reflection, const FieldDescriptor* field, - const Message& message) { - return reflection->MapSize(message, field); - } -}; - -namespace { - -TEST_F(MapFieldReflectionTest, RegularFields) { - TestMap message; - const Reflection* refl = message.GetReflection(); - const Descriptor* desc = message.GetDescriptor(); - - Map<int32, int32>* map_int32_int32 = message.mutable_map_int32_int32(); - Map<int32, double>* map_int32_double = message.mutable_map_int32_double(); - Map<std::string, std::string>* map_string_string = - message.mutable_map_string_string(); - Map<int32, ForeignMessage>* map_int32_foreign_message = - message.mutable_map_int32_foreign_message(); - - for (int i = 0; i < 10; ++i) { - (*map_int32_int32)[i] = Func(i, 1); - (*map_int32_double)[i] = Func(i, 2); - (*map_string_string)[StrFunc(i, 1)] = StrFunc(i, 5); - (*map_int32_foreign_message)[i].set_c(Func(i, 6)); - } - - // Get FieldDescriptors for all the fields of interest. - const FieldDescriptor* fd_map_int32_int32 = - desc->FindFieldByName("map_int32_int32"); - const FieldDescriptor* fd_map_int32_double = - desc->FindFieldByName("map_int32_double"); - const FieldDescriptor* fd_map_string_string = - desc->FindFieldByName("map_string_string"); - const FieldDescriptor* fd_map_int32_foreign_message = - desc->FindFieldByName("map_int32_foreign_message"); - - const FieldDescriptor* fd_map_int32_in32_key = - fd_map_int32_int32->message_type()->FindFieldByName("key"); - const FieldDescriptor* fd_map_int32_in32_value = - fd_map_int32_int32->message_type()->FindFieldByName("value"); - const FieldDescriptor* fd_map_int32_double_key = - fd_map_int32_double->message_type()->FindFieldByName("key"); - const FieldDescriptor* fd_map_int32_double_value = - fd_map_int32_double->message_type()->FindFieldByName("value"); - const FieldDescriptor* fd_map_string_string_key = - fd_map_string_string->message_type()->FindFieldByName("key"); - const FieldDescriptor* fd_map_string_string_value = - fd_map_string_string->message_type()->FindFieldByName("value"); - const FieldDescriptor* fd_map_int32_foreign_message_key = - fd_map_int32_foreign_message->message_type()->FindFieldByName("key"); - const FieldDescriptor* fd_map_int32_foreign_message_value = - fd_map_int32_foreign_message->message_type()->FindFieldByName("value"); - - // Get RepeatedPtrField objects for all fields of interest. - const RepeatedPtrField<Message>& mf_int32_int32 = - refl->GetRepeatedPtrField<Message>(message, fd_map_int32_int32); - const RepeatedPtrField<Message>& mf_int32_double = - refl->GetRepeatedPtrField<Message>(message, fd_map_int32_double); - const RepeatedPtrField<Message>& mf_string_string = - refl->GetRepeatedPtrField<Message>(message, fd_map_string_string); - const RepeatedPtrField<Message>& mf_int32_foreign_message = - refl->GetRepeatedPtrField<Message>(message, fd_map_int32_foreign_message); - - // Get mutable RepeatedPtrField objects for all fields of interest. - RepeatedPtrField<Message>* mmf_int32_int32 = - refl->MutableRepeatedPtrField<Message>(&message, fd_map_int32_int32); - RepeatedPtrField<Message>* mmf_int32_double = - refl->MutableRepeatedPtrField<Message>(&message, fd_map_int32_double); - RepeatedPtrField<Message>* mmf_string_string = - refl->MutableRepeatedPtrField<Message>(&message, fd_map_string_string); - RepeatedPtrField<Message>* mmf_int32_foreign_message = - refl->MutableRepeatedPtrField<Message>(&message, - fd_map_int32_foreign_message); - - // Make sure we can do gets through the RepeatedPtrField objects. - for (int i = 0; i < 10; ++i) { - { - // Check gets through const objects. - const Message& message_int32_int32 = mf_int32_int32.Get(i); - int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32( - message_int32_int32, fd_map_int32_in32_key); - int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32( - message_int32_int32, fd_map_int32_in32_value); - EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1)); - - const Message& message_int32_double = mf_int32_double.Get(i); - int32 key_int32_double = message_int32_double.GetReflection()->GetInt32( - message_int32_double, fd_map_int32_double_key); - double value_int32_double = - message_int32_double.GetReflection()->GetDouble( - message_int32_double, fd_map_int32_double_value); - EXPECT_EQ(value_int32_double, Func(key_int32_double, 2)); - - const Message& message_string_string = mf_string_string.Get(i); - std::string key_string_string = - message_string_string.GetReflection()->GetString( - message_string_string, fd_map_string_string_key); - std::string value_string_string = - message_string_string.GetReflection()->GetString( - message_string_string, fd_map_string_string_value); - EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5)); - - const Message& message_int32_message = mf_int32_foreign_message.Get(i); - int32 key_int32_message = message_int32_message.GetReflection()->GetInt32( - message_int32_message, fd_map_int32_foreign_message_key); - const ForeignMessage& value_int32_message = - down_cast<const ForeignMessage&>( - message_int32_message.GetReflection()->GetMessage( - message_int32_message, fd_map_int32_foreign_message_value)); - EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6)); - } - - { - // Check gets through mutable objects. - const Message& message_int32_int32 = mmf_int32_int32->Get(i); - int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32( - message_int32_int32, fd_map_int32_in32_key); - int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32( - message_int32_int32, fd_map_int32_in32_value); - EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1)); - - const Message& message_int32_double = mmf_int32_double->Get(i); - int32 key_int32_double = message_int32_double.GetReflection()->GetInt32( - message_int32_double, fd_map_int32_double_key); - double value_int32_double = - message_int32_double.GetReflection()->GetDouble( - message_int32_double, fd_map_int32_double_value); - EXPECT_EQ(value_int32_double, Func(key_int32_double, 2)); - - const Message& message_string_string = mmf_string_string->Get(i); - std::string key_string_string = - message_string_string.GetReflection()->GetString( - message_string_string, fd_map_string_string_key); - std::string value_string_string = - message_string_string.GetReflection()->GetString( - message_string_string, fd_map_string_string_value); - EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5)); - - const Message& message_int32_message = mmf_int32_foreign_message->Get(i); - int32 key_int32_message = message_int32_message.GetReflection()->GetInt32( - message_int32_message, fd_map_int32_foreign_message_key); - const ForeignMessage& value_int32_message = - down_cast<const ForeignMessage&>( - message_int32_message.GetReflection()->GetMessage( - message_int32_message, fd_map_int32_foreign_message_value)); - EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6)); - } - } - - // Do sets through the RepeatedPtrField objects. - for (int i = 0; i < 10; i++) { - { - Message* message_int32_int32 = mmf_int32_int32->Mutable(i); - int32 key_int32_int32 = message_int32_int32->GetReflection()->GetInt32( - *message_int32_int32, fd_map_int32_in32_key); - message_int32_int32->GetReflection()->SetInt32(message_int32_int32, - fd_map_int32_in32_value, - Func(key_int32_int32, -1)); - - Message* message_int32_double = mmf_int32_double->Mutable(i); - int32 key_int32_double = message_int32_double->GetReflection()->GetInt32( - *message_int32_double, fd_map_int32_double_key); - message_int32_double->GetReflection()->SetDouble( - message_int32_double, fd_map_int32_double_value, - Func(key_int32_double, -2)); - - Message* message_string_string = mmf_string_string->Mutable(i); - std::string key_string_string = - message_string_string->GetReflection()->GetString( - *message_string_string, fd_map_string_string_key); - message_string_string->GetReflection()->SetString( - message_string_string, fd_map_string_string_value, - StrFunc(Int(key_string_string), -5)); - - Message* message_int32_message = mmf_int32_foreign_message->Mutable(i); - int32 key_int32_message = - message_int32_message->GetReflection()->GetInt32( - *message_int32_message, fd_map_int32_foreign_message_key); - ForeignMessage* value_int32_message = down_cast<ForeignMessage*>( - message_int32_message->GetReflection()->MutableMessage( - message_int32_message, fd_map_int32_foreign_message_value)); - value_int32_message->set_c(Func(key_int32_message, -6)); - } - } - - // Check gets through mutable objects. - for (int i = 0; i < 10; i++) { - EXPECT_EQ(Func(i, -1), message.map_int32_int32().at(i)); - EXPECT_EQ(Func(i, -2), message.map_int32_double().at(i)); - EXPECT_EQ(StrFunc(i, -5), message.map_string_string().at(StrFunc(i, 1))); - EXPECT_EQ(Func(i, -6), message.map_int32_foreign_message().at(i).c()); - } -} - -TEST_F(MapFieldReflectionTest, RepeatedFieldRefForRegularFields) { - TestMap message; - const Reflection* refl = message.GetReflection(); - const Descriptor* desc = message.GetDescriptor(); - - Map<int32, int32>* map_int32_int32 = message.mutable_map_int32_int32(); - Map<int32, double>* map_int32_double = message.mutable_map_int32_double(); - Map<std::string, std::string>* map_string_string = - message.mutable_map_string_string(); - Map<int32, ForeignMessage>* map_int32_foreign_message = - message.mutable_map_int32_foreign_message(); - - for (int i = 0; i < 10; ++i) { - (*map_int32_int32)[i] = Func(i, 1); - (*map_int32_double)[i] = Func(i, 2); - (*map_string_string)[StrFunc(i, 1)] = StrFunc(i, 5); - (*map_int32_foreign_message)[i].set_c(Func(i, 6)); - } - - // Get FieldDescriptors for all the fields of interest. - const FieldDescriptor* fd_map_int32_int32 = - desc->FindFieldByName("map_int32_int32"); - const FieldDescriptor* fd_map_int32_double = - desc->FindFieldByName("map_int32_double"); - const FieldDescriptor* fd_map_string_string = - desc->FindFieldByName("map_string_string"); - const FieldDescriptor* fd_map_int32_foreign_message = - desc->FindFieldByName("map_int32_foreign_message"); - - const FieldDescriptor* fd_map_int32_in32_key = - fd_map_int32_int32->message_type()->FindFieldByName("key"); - const FieldDescriptor* fd_map_int32_in32_value = - fd_map_int32_int32->message_type()->FindFieldByName("value"); - const FieldDescriptor* fd_map_int32_double_key = - fd_map_int32_double->message_type()->FindFieldByName("key"); - const FieldDescriptor* fd_map_int32_double_value = - fd_map_int32_double->message_type()->FindFieldByName("value"); - const FieldDescriptor* fd_map_string_string_key = - fd_map_string_string->message_type()->FindFieldByName("key"); - const FieldDescriptor* fd_map_string_string_value = - fd_map_string_string->message_type()->FindFieldByName("value"); - const FieldDescriptor* fd_map_int32_foreign_message_key = - fd_map_int32_foreign_message->message_type()->FindFieldByName("key"); - const FieldDescriptor* fd_map_int32_foreign_message_value = - fd_map_int32_foreign_message->message_type()->FindFieldByName("value"); - - // Get RepeatedFieldRef objects for all fields of interest. - const RepeatedFieldRef<Message> mf_int32_int32 = - refl->GetRepeatedFieldRef<Message>(message, fd_map_int32_int32); - const RepeatedFieldRef<Message> mf_int32_double = - refl->GetRepeatedFieldRef<Message>(message, fd_map_int32_double); - const RepeatedFieldRef<Message> mf_string_string = - refl->GetRepeatedFieldRef<Message>(message, fd_map_string_string); - const RepeatedFieldRef<Message> mf_int32_foreign_message = - refl->GetRepeatedFieldRef<Message>(message, fd_map_int32_foreign_message); - - // Get mutable RepeatedFieldRef objects for all fields of interest. - const MutableRepeatedFieldRef<Message> mmf_int32_int32 = - refl->GetMutableRepeatedFieldRef<Message>(&message, fd_map_int32_int32); - const MutableRepeatedFieldRef<Message> mmf_int32_double = - refl->GetMutableRepeatedFieldRef<Message>(&message, fd_map_int32_double); - const MutableRepeatedFieldRef<Message> mmf_string_string = - refl->GetMutableRepeatedFieldRef<Message>(&message, fd_map_string_string); - const MutableRepeatedFieldRef<Message> mmf_int32_foreign_message = - refl->GetMutableRepeatedFieldRef<Message>(&message, - fd_map_int32_foreign_message); - - // Get entry default instances - std::unique_ptr<Message> entry_int32_int32( - MessageFactory::generated_factory() - ->GetPrototype(fd_map_int32_int32->message_type()) - ->New(message.GetArena())); - std::unique_ptr<Message> entry_int32_double( - MessageFactory::generated_factory() - ->GetPrototype(fd_map_int32_double->message_type()) - ->New(message.GetArena())); - std::unique_ptr<Message> entry_string_string( - MessageFactory::generated_factory() - ->GetPrototype(fd_map_string_string->message_type()) - ->New(message.GetArena())); - std::unique_ptr<Message> entry_int32_foreign_message( - MessageFactory::generated_factory() - ->GetPrototype(fd_map_int32_foreign_message->message_type()) - ->New(message.GetArena())); - - EXPECT_EQ(10, mf_int32_int32.size()); - EXPECT_EQ(10, mmf_int32_int32.size()); - EXPECT_EQ(10, mf_int32_double.size()); - EXPECT_EQ(10, mmf_int32_double.size()); - EXPECT_EQ(10, mf_string_string.size()); - EXPECT_EQ(10, mmf_string_string.size()); - EXPECT_EQ(10, mf_int32_foreign_message.size()); - EXPECT_EQ(10, mmf_int32_foreign_message.size()); - - EXPECT_FALSE(mf_int32_int32.empty()); - EXPECT_FALSE(mmf_int32_int32.empty()); - EXPECT_FALSE(mf_int32_double.empty()); - EXPECT_FALSE(mmf_int32_double.empty()); - EXPECT_FALSE(mf_string_string.empty()); - EXPECT_FALSE(mmf_string_string.empty()); - EXPECT_FALSE(mf_int32_foreign_message.empty()); - EXPECT_FALSE(mmf_int32_foreign_message.empty()); - - // Make sure we can do gets through the RepeatedFieldRef objects. - for (int i = 0; i < 10; ++i) { - { - // Check gets through const objects. - const Message& message_int32_int32 = - mf_int32_int32.Get(i, entry_int32_int32.get()); - int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32( - message_int32_int32, fd_map_int32_in32_key); - int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32( - message_int32_int32, fd_map_int32_in32_value); - EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1)); - - const Message& message_int32_double = - mf_int32_double.Get(i, entry_int32_double.get()); - int32 key_int32_double = message_int32_double.GetReflection()->GetInt32( - message_int32_double, fd_map_int32_double_key); - double value_int32_double = - message_int32_double.GetReflection()->GetDouble( - message_int32_double, fd_map_int32_double_value); - EXPECT_EQ(value_int32_double, Func(key_int32_double, 2)); - - const Message& message_string_string = - mf_string_string.Get(i, entry_string_string.get()); - std::string key_string_string = - message_string_string.GetReflection()->GetString( - message_string_string, fd_map_string_string_key); - std::string value_string_string = - message_string_string.GetReflection()->GetString( - message_string_string, fd_map_string_string_value); - EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5)); - - const Message& message_int32_message = - mf_int32_foreign_message.Get(i, entry_int32_foreign_message.get()); - int32 key_int32_message = message_int32_message.GetReflection()->GetInt32( - message_int32_message, fd_map_int32_foreign_message_key); - const ForeignMessage& value_int32_message = - down_cast<const ForeignMessage&>( - message_int32_message.GetReflection()->GetMessage( - message_int32_message, fd_map_int32_foreign_message_value)); - EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6)); - } - - { - // Check gets through mutable objects. - const Message& message_int32_int32 = - mmf_int32_int32.Get(i, entry_int32_int32.get()); - int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32( - message_int32_int32, fd_map_int32_in32_key); - int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32( - message_int32_int32, fd_map_int32_in32_value); - EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1)); - - const Message& message_int32_double = - mmf_int32_double.Get(i, entry_int32_double.get()); - int32 key_int32_double = message_int32_double.GetReflection()->GetInt32( - message_int32_double, fd_map_int32_double_key); - double value_int32_double = - message_int32_double.GetReflection()->GetDouble( - message_int32_double, fd_map_int32_double_value); - EXPECT_EQ(value_int32_double, Func(key_int32_double, 2)); - - const Message& message_string_string = - mmf_string_string.Get(i, entry_string_string.get()); - std::string key_string_string = - message_string_string.GetReflection()->GetString( - message_string_string, fd_map_string_string_key); - std::string value_string_string = - message_string_string.GetReflection()->GetString( - message_string_string, fd_map_string_string_value); - EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5)); - - const Message& message_int32_message = - mmf_int32_foreign_message.Get(i, entry_int32_foreign_message.get()); - int32 key_int32_message = message_int32_message.GetReflection()->GetInt32( - message_int32_message, fd_map_int32_foreign_message_key); - const ForeignMessage& value_int32_message = - down_cast<const ForeignMessage&>( - message_int32_message.GetReflection()->GetMessage( - message_int32_message, fd_map_int32_foreign_message_value)); - EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6)); - } - } - - // Make sure we can do sets through the RepeatedFieldRef objects. - for (int i = 0; i < 10; i++) { - const Message& message_int32_int32 = - mmf_int32_int32.Get(i, entry_int32_int32.get()); - int key = message_int32_int32.GetReflection()->GetInt32( - message_int32_int32, fd_map_int32_in32_key); - - entry_int32_int32->GetReflection()->SetInt32( - entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(0), - key); - entry_int32_int32->GetReflection()->SetInt32( - entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(1), - Func(key, -1)); - entry_int32_double->GetReflection()->SetInt32( - entry_int32_double.get(), fd_map_int32_double->message_type()->field(0), - key); - entry_int32_double->GetReflection()->SetDouble( - entry_int32_double.get(), fd_map_int32_double->message_type()->field(1), - Func(key, -2)); - entry_string_string->GetReflection()->SetString( - entry_string_string.get(), - fd_map_string_string->message_type()->field(0), StrFunc(key, 1)); - entry_string_string->GetReflection()->SetString( - entry_string_string.get(), - fd_map_string_string->message_type()->field(1), StrFunc(key, -5)); - entry_int32_foreign_message->GetReflection()->SetInt32( - entry_int32_foreign_message.get(), - fd_map_int32_foreign_message->message_type()->field(0), key); - Message* value_message = - entry_int32_foreign_message->GetReflection()->MutableMessage( - entry_int32_foreign_message.get(), - fd_map_int32_foreign_message->message_type()->field(1)); - value_message->GetReflection()->SetInt32( - value_message, value_message->GetDescriptor()->FindFieldByName("c"), - Func(key, -6)); - - mmf_int32_int32.Set(i, *entry_int32_int32); - mmf_int32_double.Set(i, *entry_int32_double); - mmf_string_string.Set(i, *entry_string_string); - mmf_int32_foreign_message.Set(i, *entry_int32_foreign_message); - } - - for (int i = 0; i < 10; i++) { - EXPECT_EQ(Func(i, -1), message.map_int32_int32().at(i)); - EXPECT_EQ(Func(i, -2), message.map_int32_double().at(i)); - EXPECT_EQ(StrFunc(i, -5), message.map_string_string().at(StrFunc(i, 1))); - EXPECT_EQ(Func(i, -6), message.map_int32_foreign_message().at(i).c()); - } - - // Test iterators. - { - int index = 0; - std::unordered_map<int32, int32> result; - for (RepeatedFieldRef<Message>::iterator it = mf_int32_int32.begin(); - it != mf_int32_int32.end(); ++it) { - const Message& message = *it; - int32 key = - message.GetReflection()->GetInt32(message, fd_map_int32_in32_key); - int32 value = - message.GetReflection()->GetInt32(message, fd_map_int32_in32_value); - result[key] = value; - ++index; - } - EXPECT_EQ(10, index); - for (std::unordered_map<int32, int32>::const_iterator it = result.begin(); - it != result.end(); ++it) { - EXPECT_EQ(message.map_int32_int32().at(it->first), it->second); - } - } - - { - int index = 0; - std::unordered_map<int32, double> result; - for (RepeatedFieldRef<Message>::iterator it = mf_int32_double.begin(); - it != mf_int32_double.end(); ++it) { - const Message& message = *it; - int32 key = - message.GetReflection()->GetInt32(message, fd_map_int32_double_key); - double value = message.GetReflection()->GetDouble( - message, fd_map_int32_double_value); - result[key] = value; - ++index; - } - EXPECT_EQ(10, index); - for (std::unordered_map<int32, double>::const_iterator it = result.begin(); - it != result.end(); ++it) { - EXPECT_EQ(message.map_int32_double().at(it->first), it->second); - } - } - - { - int index = 0; - std::unordered_map<std::string, std::string> result; - for (RepeatedFieldRef<Message>::iterator it = mf_string_string.begin(); - it != mf_string_string.end(); ++it) { - const Message& message = *it; - std::string key = - message.GetReflection()->GetString(message, fd_map_string_string_key); - std::string value = message.GetReflection()->GetString( - message, fd_map_string_string_value); - result[key] = value; - ++index; - } - EXPECT_EQ(10, index); - for (std::unordered_map<std::string, std::string>::const_iterator it = - result.begin(); - it != result.end(); ++it) { - EXPECT_EQ(message.map_string_string().at(it->first), it->second); - } - } - - { - int index = 0; - std::map<int32, ForeignMessage> result; - for (RepeatedFieldRef<Message>::iterator it = - mf_int32_foreign_message.begin(); - it != mf_int32_foreign_message.end(); ++it) { - const Message& message = *it; - int32 key = message.GetReflection()->GetInt32( - message, fd_map_int32_foreign_message_key); - const ForeignMessage& sub_message = - down_cast<const ForeignMessage&>(message.GetReflection()->GetMessage( - message, fd_map_int32_foreign_message_value)); - result[key].MergeFrom(sub_message); - ++index; - } - EXPECT_EQ(10, index); - for (std::map<int32, ForeignMessage>::const_iterator it = result.begin(); - it != result.end(); ++it) { - EXPECT_EQ(message.map_int32_foreign_message().at(it->first).c(), - it->second.c()); - } - } - - // Test MutableRepeatedFieldRef::Add() - entry_int32_int32->GetReflection()->SetInt32( - entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(0), - 4321); - entry_int32_int32->GetReflection()->SetInt32( - entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(1), - 1234); - mmf_int32_int32.Add(*entry_int32_int32); - EXPECT_EQ(1234, message.map_int32_int32().at(4321)); - - entry_int32_double->GetReflection()->SetInt32( - entry_int32_double.get(), fd_map_int32_double->message_type()->field(0), - 4321); - entry_int32_double->GetReflection()->SetDouble( - entry_int32_double.get(), fd_map_int32_double->message_type()->field(1), - 1234.0); - mmf_int32_double.Add(*entry_int32_double); - EXPECT_EQ(1234.0, message.map_int32_double().at(4321)); - - entry_string_string->GetReflection()->SetString( - entry_string_string.get(), fd_map_string_string->message_type()->field(0), - "4321"); - entry_string_string->GetReflection()->SetString( - entry_string_string.get(), fd_map_string_string->message_type()->field(1), - "1234"); - mmf_string_string.Add(*entry_string_string); - EXPECT_EQ("1234", message.map_string_string().at("4321")); - - entry_int32_foreign_message->GetReflection()->SetInt32( - entry_int32_foreign_message.get(), - fd_map_int32_foreign_message->message_type()->field(0), 4321); - Message* value_message = - entry_int32_foreign_message->GetReflection()->MutableMessage( - entry_int32_foreign_message.get(), - fd_map_int32_foreign_message->message_type()->field(1)); - ForeignMessage foreign_message; - foreign_message.set_c(1234); - value_message->CopyFrom(foreign_message); - - mmf_int32_foreign_message.Add(*entry_int32_foreign_message); - EXPECT_EQ(1234, message.map_int32_foreign_message().at(4321).c()); - - // Test Reflection::AddAllocatedMessage - Message* free_entry_string_string = - MessageFactory::generated_factory() - ->GetPrototype(fd_map_string_string->message_type()) - ->New(); - entry_string_string->GetReflection()->SetString( - free_entry_string_string, fd_map_string_string->message_type()->field(0), - "4321"); - entry_string_string->GetReflection()->SetString( - free_entry_string_string, fd_map_string_string->message_type()->field(1), - "1234"); - refl->AddAllocatedMessage(&message, fd_map_string_string, - free_entry_string_string); - - // Test MutableRepeatedFieldRef::RemoveLast() - mmf_int32_int32.RemoveLast(); - mmf_int32_double.RemoveLast(); - mmf_string_string.RemoveLast(); - mmf_int32_foreign_message.RemoveLast(); - EXPECT_EQ(10, message.map_int32_int32().size()); - EXPECT_EQ(10, message.map_int32_double().size()); - EXPECT_EQ(11, message.map_string_string().size()); - EXPECT_EQ(10, message.map_int32_foreign_message().size()); - - // Test MutableRepeatedFieldRef::SwapElements() - { - const Message& message0a = mmf_int32_int32.Get(0, entry_int32_int32.get()); - int32 int32_value0a = - message0a.GetReflection()->GetInt32(message0a, fd_map_int32_in32_value); - const Message& message9a = mmf_int32_int32.Get(9, entry_int32_int32.get()); - int32 int32_value9a = - message9a.GetReflection()->GetInt32(message9a, fd_map_int32_in32_value); - - mmf_int32_int32.SwapElements(0, 9); - - const Message& message0b = mmf_int32_int32.Get(0, entry_int32_int32.get()); - int32 int32_value0b = - message0b.GetReflection()->GetInt32(message0b, fd_map_int32_in32_value); - const Message& message9b = mmf_int32_int32.Get(9, entry_int32_int32.get()); - int32 int32_value9b = - message9b.GetReflection()->GetInt32(message9b, fd_map_int32_in32_value); - - EXPECT_EQ(int32_value9a, int32_value0b); - EXPECT_EQ(int32_value0a, int32_value9b); - } - - { - const Message& message0a = - mmf_int32_double.Get(0, entry_int32_double.get()); - double double_value0a = message0a.GetReflection()->GetDouble( - message0a, fd_map_int32_double_value); - const Message& message9a = - mmf_int32_double.Get(9, entry_int32_double.get()); - double double_value9a = message9a.GetReflection()->GetDouble( - message9a, fd_map_int32_double_value); - - mmf_int32_double.SwapElements(0, 9); - - const Message& message0b = - mmf_int32_double.Get(0, entry_int32_double.get()); - double double_value0b = message0b.GetReflection()->GetDouble( - message0b, fd_map_int32_double_value); - const Message& message9b = - mmf_int32_double.Get(9, entry_int32_double.get()); - double double_value9b = message9b.GetReflection()->GetDouble( - message9b, fd_map_int32_double_value); - - EXPECT_EQ(double_value9a, double_value0b); - EXPECT_EQ(double_value0a, double_value9b); - } - - { - const Message& message0a = - mmf_string_string.Get(0, entry_string_string.get()); - std::string string_value0a = message0a.GetReflection()->GetString( - message0a, fd_map_string_string_value); - const Message& message9a = - mmf_string_string.Get(9, entry_string_string.get()); - std::string string_value9a = message9a.GetReflection()->GetString( - message9a, fd_map_string_string_value); - - mmf_string_string.SwapElements(0, 9); - - const Message& message0b = - mmf_string_string.Get(0, entry_string_string.get()); - std::string string_value0b = message0b.GetReflection()->GetString( - message0b, fd_map_string_string_value); - const Message& message9b = - mmf_string_string.Get(9, entry_string_string.get()); - std::string string_value9b = message9b.GetReflection()->GetString( - message9b, fd_map_string_string_value); - - EXPECT_EQ(string_value9a, string_value0b); - EXPECT_EQ(string_value0a, string_value9b); - } - - { - const Message& message0a = - mmf_int32_foreign_message.Get(0, entry_int32_foreign_message.get()); - const ForeignMessage& sub_message0a = - down_cast<const ForeignMessage&>(message0a.GetReflection()->GetMessage( - message0a, fd_map_int32_foreign_message_value)); - int32 int32_value0a = sub_message0a.c(); - const Message& message9a = - mmf_int32_foreign_message.Get(9, entry_int32_foreign_message.get()); - const ForeignMessage& sub_message9a = - down_cast<const ForeignMessage&>(message9a.GetReflection()->GetMessage( - message9a, fd_map_int32_foreign_message_value)); - int32 int32_value9a = sub_message9a.c(); - - mmf_int32_foreign_message.SwapElements(0, 9); - - const Message& message0b = - mmf_int32_foreign_message.Get(0, entry_int32_foreign_message.get()); - const ForeignMessage& sub_message0b = - down_cast<const ForeignMessage&>(message0b.GetReflection()->GetMessage( - message0b, fd_map_int32_foreign_message_value)); - int32 int32_value0b = sub_message0b.c(); - const Message& message9b = - mmf_int32_foreign_message.Get(9, entry_int32_foreign_message.get()); - const ForeignMessage& sub_message9b = - down_cast<const ForeignMessage&>(message9b.GetReflection()->GetMessage( - message9b, fd_map_int32_foreign_message_value)); - int32 int32_value9b = sub_message9b.c(); - - EXPECT_EQ(int32_value9a, int32_value0b); - EXPECT_EQ(int32_value0a, int32_value9b); - } - - // TODO(b/181148674): After supporting arena agnostic delete or let map entry - // handle heap allocation, this could be removed. - if (message.GetArena() != nullptr) { - entry_int32_int32.release(); - entry_int32_double.release(); - entry_string_string.release(); - entry_int32_foreign_message.release(); - } -} - -TEST_F(MapFieldReflectionTest, RepeatedFieldRefMergeFromAndSwap) { - // Set-up message content. - TestMap m0, m1, m2; - for (int i = 0; i < 10; ++i) { - (*m0.mutable_map_int32_int32())[i] = Func(i, 1); - (*m0.mutable_map_int32_double())[i] = Func(i, 2); - (*m0.mutable_map_string_string())[StrFunc(i, 1)] = StrFunc(i, 5); - (*m0.mutable_map_int32_foreign_message())[i].set_c(Func(i, 6)); - (*m1.mutable_map_int32_int32())[i + 10] = Func(i, 11); - (*m1.mutable_map_int32_double())[i + 10] = Func(i, 12); - (*m1.mutable_map_string_string())[StrFunc(i + 10, 1)] = StrFunc(i, 15); - (*m1.mutable_map_int32_foreign_message())[i + 10].set_c(Func(i, 16)); - (*m2.mutable_map_int32_int32())[i + 20] = Func(i, 21); - (*m2.mutable_map_int32_double())[i + 20] = Func(i, 22); - (*m2.mutable_map_string_string())[StrFunc(i + 20, 1)] = StrFunc(i, 25); - (*m2.mutable_map_int32_foreign_message())[i + 20].set_c(Func(i, 26)); - } - - const Reflection* refl = m0.GetReflection(); - const Descriptor* desc = m0.GetDescriptor(); - - // Get FieldDescriptors for all the fields of interest. - const FieldDescriptor* fd_map_int32_int32 = - desc->FindFieldByName("map_int32_int32"); - const FieldDescriptor* fd_map_int32_double = - desc->FindFieldByName("map_int32_double"); - const FieldDescriptor* fd_map_string_string = - desc->FindFieldByName("map_string_string"); - const FieldDescriptor* fd_map_int32_foreign_message = - desc->FindFieldByName("map_int32_foreign_message"); - - // Get MutableRepeatedFieldRef objects for all fields of interest. - const MutableRepeatedFieldRef<Message> mmf_int32_int32 = - refl->GetMutableRepeatedFieldRef<Message>(&m0, fd_map_int32_int32); - const MutableRepeatedFieldRef<Message> mmf_int32_double = - refl->GetMutableRepeatedFieldRef<Message>(&m0, fd_map_int32_double); - const MutableRepeatedFieldRef<Message> mmf_string_string = - refl->GetMutableRepeatedFieldRef<Message>(&m0, fd_map_string_string); - const MutableRepeatedFieldRef<Message> mmf_int32_foreign_message = - refl->GetMutableRepeatedFieldRef<Message>(&m0, - fd_map_int32_foreign_message); - - // Test MutableRepeatedRef::CopyFrom - mmf_int32_int32.CopyFrom( - refl->GetRepeatedFieldRef<Message>(m1, fd_map_int32_int32)); - mmf_int32_double.CopyFrom( - refl->GetRepeatedFieldRef<Message>(m1, fd_map_int32_double)); - mmf_string_string.CopyFrom( - refl->GetRepeatedFieldRef<Message>(m1, fd_map_string_string)); - mmf_int32_foreign_message.CopyFrom( - refl->GetRepeatedFieldRef<Message>(m1, fd_map_int32_foreign_message)); - - for (int i = 0; i < 10; ++i) { - EXPECT_EQ(Func(i, 11), m0.map_int32_int32().at(i + 10)); - EXPECT_EQ(Func(i, 12), m0.map_int32_double().at(i + 10)); - EXPECT_EQ(StrFunc(i, 15), m0.map_string_string().at(StrFunc(i + 10, 1))); - EXPECT_EQ(Func(i, 16), m0.map_int32_foreign_message().at(i + 10).c()); - } - - // Test MutableRepeatedRef::MergeFrom - mmf_int32_int32.MergeFrom( - refl->GetRepeatedFieldRef<Message>(m2, fd_map_int32_int32)); - mmf_int32_double.MergeFrom( - refl->GetRepeatedFieldRef<Message>(m2, fd_map_int32_double)); - mmf_string_string.MergeFrom( - refl->GetRepeatedFieldRef<Message>(m2, fd_map_string_string)); - mmf_int32_foreign_message.MergeFrom( - refl->GetRepeatedFieldRef<Message>(m2, fd_map_int32_foreign_message)); - for (int i = 0; i < 10; ++i) { - EXPECT_EQ(Func(i, 21), m0.map_int32_int32().at(i + 20)); - EXPECT_EQ(Func(i, 22), m0.map_int32_double().at(i + 20)); - EXPECT_EQ(StrFunc(i, 25), m0.map_string_string().at(StrFunc(i + 20, 1))); - EXPECT_EQ(Func(i, 26), m0.map_int32_foreign_message().at(i + 20).c()); - } - - // Test MutableRepeatedRef::Swap - // Swap between m0 and m2. - mmf_int32_int32.Swap( - refl->GetMutableRepeatedFieldRef<Message>(&m2, fd_map_int32_int32)); - mmf_int32_double.Swap( - refl->GetMutableRepeatedFieldRef<Message>(&m2, fd_map_int32_double)); - mmf_string_string.Swap( - refl->GetMutableRepeatedFieldRef<Message>(&m2, fd_map_string_string)); - mmf_int32_foreign_message.Swap(refl->GetMutableRepeatedFieldRef<Message>( - &m2, fd_map_int32_foreign_message)); - for (int i = 0; i < 10; ++i) { - // Check the content of m0. - EXPECT_EQ(Func(i, 21), m0.map_int32_int32().at(i + 20)); - EXPECT_EQ(Func(i, 22), m0.map_int32_double().at(i + 20)); - EXPECT_EQ(StrFunc(i, 25), m0.map_string_string().at(StrFunc(i + 20, 1))); - EXPECT_EQ(Func(i, 26), m0.map_int32_foreign_message().at(i + 20).c()); - - // Check the content of m2. - EXPECT_EQ(Func(i, 11), m2.map_int32_int32().at(i + 10)); - EXPECT_EQ(Func(i, 12), m2.map_int32_double().at(i + 10)); - EXPECT_EQ(StrFunc(i, 15), m2.map_string_string().at(StrFunc(i + 10, 1))); - EXPECT_EQ(Func(i, 16), m2.map_int32_foreign_message().at(i + 10).c()); - EXPECT_EQ(Func(i, 21), m2.map_int32_int32().at(i + 20)); - EXPECT_EQ(Func(i, 22), m2.map_int32_double().at(i + 20)); - EXPECT_EQ(StrFunc(i, 25), m2.map_string_string().at(StrFunc(i + 20, 1))); - EXPECT_EQ(Func(i, 26), m2.map_int32_foreign_message().at(i + 20).c()); - } - - // TODO(teboring): add test for duplicated key -} - -TEST_F(MapFieldReflectionTest, MapSizeWithDuplicatedKey) { - // Dynamic Message - { - DynamicMessageFactory factory; - std::unique_ptr<Message> message( - factory.GetPrototype(unittest::TestMap::descriptor())->New()); - const Reflection* reflection = message->GetReflection(); - const FieldDescriptor* field = - unittest::TestMap::descriptor()->FindFieldByName("map_int32_int32"); - - Message* entry1 = reflection->AddMessage(message.get(), field); - Message* entry2 = reflection->AddMessage(message.get(), field); - - const Reflection* entry_reflection = entry1->GetReflection(); - const FieldDescriptor* key_field = - entry1->GetDescriptor()->FindFieldByName("key"); - entry_reflection->SetInt32(entry1, key_field, 1); - entry_reflection->SetInt32(entry2, key_field, 1); - - EXPECT_EQ(2, reflection->FieldSize(*message, field)); - EXPECT_EQ(1, MapSize(reflection, field, *message)); - EXPECT_EQ(2, reflection->FieldSize(*message, field)); - } - - // Generated Message - { - unittest::TestMap message; - const Reflection* reflection = message.GetReflection(); - const FieldDescriptor* field = - message.GetDescriptor()->FindFieldByName("map_int32_int32"); - - Message* entry1 = reflection->AddMessage(&message, field); - Message* entry2 = reflection->AddMessage(&message, field); - - const Reflection* entry_reflection = entry1->GetReflection(); - const FieldDescriptor* key_field = - entry1->GetDescriptor()->FindFieldByName("key"); - entry_reflection->SetInt32(entry1, key_field, 1); - entry_reflection->SetInt32(entry2, key_field, 1); - - EXPECT_EQ(2, reflection->FieldSize(message, field)); - EXPECT_EQ(1, MapSize(reflection, field, message)); - } -} - -TEST_F(MapFieldReflectionTest, UninitializedEntry) { - unittest::TestRequiredMessageMap message; - const Reflection* reflection = message.GetReflection(); - const FieldDescriptor* field = - message.GetDescriptor()->FindFieldByName("map_field"); - auto entry = reflection->AddMessage(&message, field); - EXPECT_FALSE(entry->IsInitialized()); - EXPECT_FALSE(message.IsInitialized()); -} - -class MyMapEntry - : public internal::MapEntry<MyMapEntry, ::google::protobuf::int32, ::google::protobuf::int32, - internal::WireFormatLite::TYPE_INT32, - internal::WireFormatLite::TYPE_INT32> { - public: - constexpr MyMapEntry() {} - MyMapEntry(Arena*) { std::abort(); } - Metadata GetMetadata() const override { std::abort(); } - static bool ValidateKey(void*) { return true; } - static bool ValidateValue(void*) { return true; } -}; - -class MyMapEntryLite - : public internal::MapEntryLite<MyMapEntryLite, ::google::protobuf::int32, ::google::protobuf::int32, - internal::WireFormatLite::TYPE_INT32, - internal::WireFormatLite::TYPE_INT32> { - public: - constexpr MyMapEntryLite() {} - explicit MyMapEntryLite(Arena*) { std::abort(); } - static bool ValidateKey(void*) { return true; } - static bool ValidateValue(void*) { return true; } -}; - -TEST(MapEntryTest, ConstInit) { - // This verifies that `MapEntry`, `MapEntryLite` and `MapEntryImpl` can be - // constant initialized. - PROTOBUF_CONSTINIT static MyMapEntry entry{}; - EXPECT_NE(entry.SpaceUsed(), 0); - - PROTOBUF_CONSTINIT static MyMapEntryLite entry_lite{}; // NOLINT - EXPECT_TRUE(entry_lite.IsInitialized()); -} - -// Generated Message Test =========================================== - -TEST(GeneratedMapFieldTest, Accessors) { - unittest::TestMap message; - - MapTestUtil::SetMapFields(&message); - MapTestUtil::ExpectMapFieldsSet(message); - - MapTestUtil::ModifyMapFields(&message); - MapTestUtil::ExpectMapFieldsModified(message); -} - -TEST(GeneratedMapFieldTest, SetMapFieldsInitialized) { - unittest::TestMap message; - - MapTestUtil::SetMapFieldsInitialized(&message); - MapTestUtil::ExpectMapFieldsSetInitialized(message); -} - -TEST(GeneratedMapFieldTest, Proto2SetMapFieldsInitialized) { - unittest::TestEnumMap message; - EXPECT_EQ(unittest::PROTO2_MAP_ENUM_FOO, - (*message.mutable_known_map_field())[0]); -} - -TEST(GeneratedMapFieldTest, Clear) { - unittest::TestMap message; - - MapTestUtil::SetMapFields(&message); - message.Clear(); - MapTestUtil::ExpectClear(message); -} - -TEST(GeneratedMapFieldTest, ClearMessageMap) { - unittest::TestMessageMap message; - - // Creates a TestAllTypes with default value - TestUtil::ExpectClear((*message.mutable_map_int32_message())[0]); -} - -TEST(GeneratedMapFieldTest, CopyFrom) { - unittest::TestMap message1, message2; - - MapTestUtil::SetMapFields(&message1); - message2.CopyFrom(message1); - MapTestUtil::ExpectMapFieldsSet(message2); - - // Copying from self should be a no-op. - message2.CopyFrom(message2); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -TEST(GeneratedMapFieldTest, CopyFromMessageMap) { - unittest::TestMessageMap message1, message2; - - (*message1.mutable_map_int32_message())[0].add_repeated_int32(100); - (*message2.mutable_map_int32_message())[0].add_repeated_int32(101); - - message1.CopyFrom(message2); - - // Checks repeated field is overwritten. - EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size()); - EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0)); -} - -TEST(GeneratedMapFieldTest, SwapWithEmpty) { - unittest::TestMap message1, message2; - - MapTestUtil::SetMapFields(&message1); - MapTestUtil::ExpectMapFieldsSet(message1); - MapTestUtil::ExpectClear(message2); - - message1.Swap(&message2); - MapTestUtil::ExpectMapFieldsSet(message2); - MapTestUtil::ExpectClear(message1); -} - -TEST(GeneratedMapFieldTest, SwapWithSelf) { - unittest::TestMap message; - - MapTestUtil::SetMapFields(&message); - MapTestUtil::ExpectMapFieldsSet(message); - - message.Swap(&message); - MapTestUtil::ExpectMapFieldsSet(message); -} - -TEST(GeneratedMapFieldTest, SwapWithOther) { - unittest::TestMap message1, message2; - - MapTestUtil::SetMapFields(&message1); - MapTestUtil::SetMapFields(&message2); - MapTestUtil::ModifyMapFields(&message2); - - message1.Swap(&message2); - MapTestUtil::ExpectMapFieldsModified(message1); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -TEST(GeneratedMapFieldTest, CopyConstructor) { - unittest::TestMap message1; - MapTestUtil::SetMapFields(&message1); - - unittest::TestMap message2(message1); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -TEST(GeneratedMapFieldTest, CopyAssignmentOperator) { - unittest::TestMap message1; - MapTestUtil::SetMapFields(&message1); - - unittest::TestMap message2; - message2 = message1; - MapTestUtil::ExpectMapFieldsSet(message2); - - // Make sure that self-assignment does something sane. - message2.operator=(message2); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || PROTOBUF_RTTI -TEST(GeneratedMapFieldTest, UpcastCopyFrom) { - // Test the CopyFrom method that takes in the generic const Message& - // parameter. - unittest::TestMap message1, message2; - - MapTestUtil::SetMapFields(&message1); - - const Message* source = implicit_cast<const Message*>(&message1); - message2.CopyFrom(*source); - - MapTestUtil::ExpectMapFieldsSet(message2); -} -#endif - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - -TEST(GeneratedMapFieldTest, CopyFromDynamicMessage) { - // Test copying from a DynamicMessage, which must fall back to using - // reflection. - unittest::TestMap message2; - - // Construct a new version of the dynamic message via the factory. - DynamicMessageFactory factory; - std::unique_ptr<Message> message1; - message1.reset(factory.GetPrototype(unittest::TestMap::descriptor())->New()); - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.SetMapFieldsViaReflection(message1.get()); - reflection_tester.ExpectMapFieldsSetViaReflection(*message1); - reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get()); - message2.CopyFrom(*message1); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -TEST(GeneratedMapFieldTest, CopyFromDynamicMessageMapReflection) { - unittest::TestMap message2; - - // Construct a new version of the dynamic message via the factory. - DynamicMessageFactory factory; - std::unique_ptr<Message> message1; - message1.reset(factory.GetPrototype(unittest::TestMap::descriptor())->New()); - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.SetMapFieldsViaMapReflection(message1.get()); - reflection_tester.ExpectMapFieldsSetViaReflection(*message1); - reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get()); - message2.CopyFrom(*message1); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -TEST(GeneratedMapFieldTest, DynamicMessageMergeFromDynamicMessage) { - // Construct two dynamic message and sets via map reflection. - DynamicMessageFactory factory; - std::unique_ptr<Message> message1; - message1.reset(factory.GetPrototype(unittest::TestMap::descriptor())->New()); - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.SetMapFieldsViaMapReflection(message1.get()); - - // message2 is created by same factory. - std::unique_ptr<Message> message2; - message2.reset(factory.GetPrototype(unittest::TestMap::descriptor())->New()); - reflection_tester.SetMapFieldsViaMapReflection(message2.get()); - - // message3 is created by different factory. - DynamicMessageFactory factory3; - std::unique_ptr<Message> message3; - message3.reset(factory3.GetPrototype(unittest::TestMap::descriptor())->New()); - reflection_tester.SetMapFieldsViaMapReflection(message3.get()); - - message2->MergeFrom(*message1); - message3->MergeFrom(*message1); - - // Test MergeFrom does not sync to repeated fields and - // there is no duplicate keys in text format. - std::string output1, output2, output3; - TextFormat::PrintToString(*message1, &output1); - TextFormat::PrintToString(*message2, &output2); - TextFormat::PrintToString(*message3, &output3); - EXPECT_EQ(output1, output2); - EXPECT_EQ(output1, output3); -} - -TEST(GeneratedMapFieldTest, DynamicMessageCopyFrom) { - // Test copying to a DynamicMessage, which must fall back to using reflection. - unittest::TestMap message2; - MapTestUtil::SetMapFields(&message2); - - // Construct a new version of the dynamic message via the factory. - DynamicMessageFactory factory; - std::unique_ptr<Message> message1; - message1.reset(factory.GetPrototype(unittest::TestMap::descriptor())->New()); - - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - message1->MergeFrom(message2); - reflection_tester.ExpectMapFieldsSetViaReflection(*message1); - reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get()); -} - -TEST(GeneratedMapFieldTest, DynamicMessageCopyFromMapReflection) { - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - unittest::TestMap message2; - reflection_tester.SetMapFieldsViaMapReflection(&message2); - - // Construct a dynamic message via the factory. - DynamicMessageFactory factory; - std::unique_ptr<Message> message1; - message1.reset(factory.GetPrototype(unittest::TestMap::descriptor())->New()); - - message1->MergeFrom(message2); - reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get()); - reflection_tester.ExpectMapFieldsSetViaReflection(*message1); -} - -TEST(GeneratedMapFieldTest, SyncDynamicMapWithRepeatedField) { - // Construct a dynamic message via the factory. - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - DynamicMessageFactory factory; - std::unique_ptr<Message> message; - message.reset(factory.GetPrototype(unittest::TestMap::descriptor())->New()); - reflection_tester.SetMapFieldsViaReflection(message.get()); - reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message.get()); - reflection_tester.ExpectMapFieldsSetViaReflection(*message); -} - -#endif // !PROTOBUF_TEST_NO_DESCRIPTORS - -TEST(GeneratedMapFieldTest, NonEmptyMergeFrom) { - unittest::TestMap message1, message2; - - MapTestUtil::SetMapFields(&message1); - - // This field will test merging into an empty spot. - (*message2.mutable_map_int32_int32())[1] = 1; - message1.mutable_map_int32_int32()->erase(1); - - // This tests overwriting. - (*message2.mutable_map_int32_double())[1] = 1; - (*message1.mutable_map_int32_double())[1] = 2; - - message1.MergeFrom(message2); - MapTestUtil::ExpectMapFieldsSet(message1); - - // Test reflection MergeFrom does not sync to repeated field - // and there is no duplicated keys. - MapTestUtil::SetMapFields(&message1); - MapTestUtil::SetMapFields(&message2); - - message2.MergeFrom(message1); - - std::string output1, output2; - TextFormat::PrintToString(message1, &output1); - TextFormat::PrintToString(message2, &output2); - EXPECT_EQ(output1, output2); -} - -TEST(GeneratedMapFieldTest, MergeFromMessageMap) { - unittest::TestMessageMap message1, message2; - - (*message1.mutable_map_int32_message())[0].add_repeated_int32(100); - (*message2.mutable_map_int32_message())[0].add_repeated_int32(101); - - message1.MergeFrom(message2); - - // Checks repeated field is overwritten. - EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size()); - EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0)); -} - -// Test the generated SerializeWithCachedSizesToArray() -TEST(GeneratedMapFieldTest, SerializationToArray) { - unittest::TestMap message1, message2; - std::string data; - MapTestUtil::SetMapFields(&message1); - size_t size = message1.ByteSizeLong(); - data.resize(size); - uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data)); - uint8* end = message1.SerializeWithCachedSizesToArray(start); - EXPECT_EQ(size, end - start); - EXPECT_TRUE(message2.ParseFromString(data)); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -// Test the generated SerializeWithCachedSizes() -TEST(GeneratedMapFieldTest, SerializationToStream) { - unittest::TestMap message1, message2; - MapTestUtil::SetMapFields(&message1); - size_t size = message1.ByteSizeLong(); - std::string data; - data.resize(size); - { - // Allow the output stream to buffer only one byte at a time. - io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - message1.SerializeWithCachedSizes(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - } - EXPECT_TRUE(message2.ParseFromString(data)); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -TEST(GeneratedMapFieldTest, ParseFailsIfMalformed) { - unittest::TestMapSubmessage o, p; - auto m = o.mutable_test_map()->mutable_map_int32_foreign_message(); - (*m)[0].set_c(-1); - std::string serialized; - EXPECT_TRUE(o.SerializeToString(&serialized)); - - // Should parse correctly. - EXPECT_TRUE(p.ParseFromString(serialized)); - - // Overwriting the last byte to 0xFF results in malformed wire. - serialized[serialized.size() - 1] = 0xFF; - EXPECT_FALSE(p.ParseFromString(serialized)); -} - - -TEST(GeneratedMapFieldTest, SameTypeMaps) { - const Descriptor* map1 = unittest::TestSameTypeMap::descriptor() - ->FindFieldByName("map1") - ->message_type(); - const Descriptor* map2 = unittest::TestSameTypeMap::descriptor() - ->FindFieldByName("map2") - ->message_type(); - - const Message* map1_entry = - MessageFactory::generated_factory()->GetPrototype(map1); - const Message* map2_entry = - MessageFactory::generated_factory()->GetPrototype(map2); - - EXPECT_EQ(map1, map1_entry->GetDescriptor()); - EXPECT_EQ(map2, map2_entry->GetDescriptor()); -} - -TEST(GeneratedMapFieldTest, Proto2UnknownEnum) { - unittest::TestEnumMapPlusExtra from; - (*from.mutable_known_map_field())[0] = unittest::E_PROTO2_MAP_ENUM_FOO; - (*from.mutable_unknown_map_field())[0] = unittest::E_PROTO2_MAP_ENUM_EXTRA; - std::string data; - from.SerializeToString(&data); - - unittest::TestEnumMap to; - EXPECT_TRUE(to.ParseFromString(data)); - EXPECT_EQ(0, to.unknown_map_field().size()); - const UnknownFieldSet& unknown_field_set = - to.GetReflection()->GetUnknownFields(to); - EXPECT_EQ(1, unknown_field_set.field_count()); - EXPECT_EQ(1, to.known_map_field().size()); - EXPECT_EQ(unittest::PROTO2_MAP_ENUM_FOO, to.known_map_field().at(0)); - - data.clear(); - from.Clear(); - to.SerializeToString(&data); - EXPECT_TRUE(from.ParseFromString(data)); - EXPECT_EQ(0, from.GetReflection()->GetUnknownFields(from).field_count()); - EXPECT_EQ(1, from.known_map_field().size()); - EXPECT_EQ(unittest::E_PROTO2_MAP_ENUM_FOO, from.known_map_field().at(0)); - EXPECT_EQ(1, from.unknown_map_field().size()); - EXPECT_EQ(unittest::E_PROTO2_MAP_ENUM_EXTRA, from.unknown_map_field().at(0)); -} - -TEST(GeneratedMapFieldTest, StandardWireFormat) { - unittest::TestMap message; - std::string data = "\x0A\x04\x08\x01\x10\x01"; - - EXPECT_TRUE(message.ParseFromString(data)); - EXPECT_EQ(1, message.map_int32_int32().size()); - EXPECT_EQ(1, message.map_int32_int32().at(1)); -} - -TEST(GeneratedMapFieldTest, UnorderedWireFormat) { - unittest::TestMap message; - - // put value before key in wire format - std::string data = "\x0A\x04\x10\x01\x08\x02"; - - EXPECT_TRUE(message.ParseFromString(data)); - EXPECT_EQ(1, message.map_int32_int32().size()); - ASSERT_NE(message.map_int32_int32().find(2), message.map_int32_int32().end()); - EXPECT_EQ(1, message.map_int32_int32().at(2)); -} - -TEST(GeneratedMapFieldTest, DuplicatedKeyWireFormat) { - unittest::TestMap message; - - // Two key fields in wire format - std::string data = "\x0A\x06\x08\x01\x08\x02\x10\x01"; - - EXPECT_TRUE(message.ParseFromString(data)); - EXPECT_EQ(1, message.map_int32_int32().size()); - EXPECT_EQ(1, message.map_int32_int32().at(2)); - - // A similar test, but with a map from int to a message type. - // Again, we want to be sure that the "second one wins" when - // there are two separate entries with the same key. - const int key = 99; - unittest::TestRequiredMessageMap map_message; - unittest::TestRequired with_dummy4; - with_dummy4.set_a(0); - with_dummy4.set_b(0); - with_dummy4.set_c(0); - with_dummy4.set_dummy4(11); - (*map_message.mutable_map_field())[key] = with_dummy4; - std::string s = map_message.SerializeAsString(); - unittest::TestRequired with_dummy5; - with_dummy5.set_a(0); - with_dummy5.set_b(0); - with_dummy5.set_c(0); - with_dummy5.set_dummy5(12); - (*map_message.mutable_map_field())[key] = with_dummy5; - std::string both = s + map_message.SerializeAsString(); - // We don't expect a merge now. The "second one wins." - ASSERT_TRUE(map_message.ParseFromString(both)); - ASSERT_EQ(1, map_message.map_field().size()); - ASSERT_EQ(1, map_message.map_field().count(key)); - EXPECT_EQ(0, map_message.map_field().find(key)->second.a()); - EXPECT_EQ(0, map_message.map_field().find(key)->second.b()); - EXPECT_EQ(0, map_message.map_field().find(key)->second.c()); - EXPECT_FALSE(map_message.map_field().find(key)->second.has_dummy4()); - ASSERT_TRUE(map_message.map_field().find(key)->second.has_dummy5()); - EXPECT_EQ(12, map_message.map_field().find(key)->second.dummy5()); -} - -// Exhaustive combinations of keys, values, and junk in any order. -// This re-tests some of the things tested above, but if it fails -// it's more work to determine what went wrong, so it isn't necessarily -// bad that we have the simpler tests too. -TEST(GeneratedMapFieldTest, KeysValuesUnknownsWireFormat) { - unittest::TestMap message; - const int kMaxNumKeysAndValuesAndJunk = 4; - const char kKeyTag = 0x08; - const char kValueTag = 0x10; - const char kJunkTag = 0x20; - for (int items = 0; items <= kMaxNumKeysAndValuesAndJunk; items++) { - std::string data = "\x0A"; - // Encode length of what will follow. - data.push_back(items * 2); - static const int kBitsOfIPerItem = 4; - static const int mask = (1 << kBitsOfIPerItem) - 1; - // Each iteration of the following is a test. It uses i as bit vector - // encoding the keys and values to put in the wire format. - for (int i = 0; i < (1 << (items * kBitsOfIPerItem)); i++) { - std::string wire_format = data; - int expected_key = 0; - int expected_value = 0; - for (int k = i, j = 0; j < items; j++, k >>= kBitsOfIPerItem) { - bool is_key = k & 0x1; - bool is_value = !is_key && (k & 0x2); - wire_format.push_back(is_key ? kKeyTag - : is_value ? kValueTag : kJunkTag); - char c = static_cast<char>(k & mask) >> 2; // One char after the tag. - wire_format.push_back(c); - if (is_key) expected_key = static_cast<int>(c); - if (is_value) expected_value = static_cast<int>(c); - bool res = message.ParseFromString(wire_format); - bool expect_success = true; - // Unfortunately the old map parser accepts malformed input, the new - // parser accepts only correct input. - if (j != items - 1) expect_success = false; - if (expect_success) { - ASSERT_TRUE(res); - ASSERT_EQ(1, message.map_int32_int32().size()); - ASSERT_EQ(expected_key, message.map_int32_int32().begin()->first); - ASSERT_EQ(expected_value, message.map_int32_int32().begin()->second); - } else { - ASSERT_FALSE(res); - } - } - } - } -} - -TEST(GeneratedMapFieldTest, DuplicatedValueWireFormat) { - unittest::TestMap message; - - // Two value fields in wire format - std::string data = "\x0A\x06\x08\x01\x10\x01\x10\x02"; - - EXPECT_TRUE(message.ParseFromString(data)); - EXPECT_EQ(1, message.map_int32_int32().size()); - EXPECT_EQ(2, message.map_int32_int32().at(1)); -} - -TEST(GeneratedMapFieldTest, MissedKeyWireFormat) { - unittest::TestMap message; - - // No key field in wire format - std::string data = "\x0A\x02\x10\x01"; - - EXPECT_TRUE(message.ParseFromString(data)); - EXPECT_EQ(1, message.map_int32_int32().size()); - ASSERT_NE(message.map_int32_int32().find(0), message.map_int32_int32().end()); - EXPECT_EQ(1, message.map_int32_int32().at(0)); -} - -TEST(GeneratedMapFieldTest, MissedValueWireFormat) { - unittest::TestMap message; - - // No value field in wire format - std::string data = "\x0A\x02\x08\x01"; - - EXPECT_TRUE(message.ParseFromString(data)); - EXPECT_EQ(1, message.map_int32_int32().size()); - ASSERT_NE(message.map_int32_int32().find(1), message.map_int32_int32().end()); - EXPECT_EQ(0, message.map_int32_int32().at(1)); -} - -TEST(GeneratedMapFieldTest, MissedValueTextFormat) { - unittest::TestMap message; - - // No value field in text format - std::string text = - "map_int32_foreign_message {\n" - " key: 1234567890\n" - "}"; - - EXPECT_TRUE(TextFormat::ParseFromString(text, &message)); - EXPECT_EQ(1, message.map_int32_foreign_message().size()); - EXPECT_EQ(11, message.ByteSizeLong()); -} - -TEST(GeneratedMapFieldTest, UnknownFieldWireFormat) { - unittest::TestMap message; - - // Unknown field in wire format - std::string data = "\x0A\x06\x08\x02\x10\x03\x18\x01"; - - EXPECT_TRUE(message.ParseFromString(data)); - EXPECT_EQ(1, message.map_int32_int32().size()); - EXPECT_EQ(3, message.map_int32_int32().at(2)); -} - -TEST(GeneratedMapFieldTest, CorruptedWireFormat) { - unittest::TestMap message; - - // corrupted data in wire format - std::string data = "\x0A\x06\x08\x02\x11\x03"; - - EXPECT_FALSE(message.ParseFromString(data)); -} - -TEST(GeneratedMapFieldTest, IsInitialized) { - unittest::TestRequiredMessageMap map_message; - - // Add an uninitialized message. - (*map_message.mutable_map_field())[0]; - EXPECT_FALSE(map_message.IsInitialized()); - - // Initialize uninitialized message - (*map_message.mutable_map_field())[0].set_a(0); - (*map_message.mutable_map_field())[0].set_b(0); - (*map_message.mutable_map_field())[0].set_c(0); - EXPECT_TRUE(map_message.IsInitialized()); -} - -TEST(GeneratedMapFieldTest, SpaceUsed) { - unittest::TestRequiredMessageMap map_message; - const size_t initial = map_message.SpaceUsed(); - const size_t space_used_message = unittest::TestRequired().SpaceUsed(); - - auto& m = *map_message.mutable_map_field(); - constexpr int kNumValues = 100; - for (int i = 0; i < kNumValues; ++i) { - m[i]; - } - - // The exact value will depend on internal state, like collisions, - // so we can't predict it. But we can predict a lower bound. - size_t lower_bound = - initial + kNumValues * (space_used_message + sizeof(int32) + - /* Node::next */ sizeof(void*) + - /* table entry */ sizeof(void*)); - - EXPECT_LE(lower_bound, map_message.SpaceUsed()); -} - -TEST(GeneratedMapFieldTest, MessagesMustMerge) { - unittest::TestRequiredMessageMap map_message; - - unittest::TestRequired with_dummy4; - with_dummy4.set_a(97); - with_dummy4.set_b(91); - with_dummy4.set_dummy4(98); - EXPECT_FALSE(with_dummy4.IsInitialized()); - (*map_message.mutable_map_field())[0] = with_dummy4; - EXPECT_FALSE(map_message.IsInitialized()); - - unittest::TestRequired with_dummy5; - with_dummy5.set_b(0); - with_dummy5.set_c(33); - with_dummy5.set_dummy5(99); - EXPECT_FALSE(with_dummy5.IsInitialized()); - (*map_message.mutable_map_field())[0] = with_dummy5; - EXPECT_FALSE(map_message.IsInitialized()); - - // The wire format of MapEntry is straightforward (*) and can be manually - // constructed to force merging of two uninitialized messages that would - // result in an initialized message. - // - // (*) http://google3/net/proto2/internal/map_test.cc?l=2433&rcl=310012028 - std::string dummy4_s = with_dummy4.SerializePartialAsString(); - std::string dummy5_s = with_dummy5.SerializePartialAsString(); - int payload_size = dummy4_s.size() + dummy5_s.size(); - // Makes sure the payload size fits into one byte. - ASSERT_LT(payload_size, 128); - - std::string s(6, 0); - char* p = &s[0]; - *p++ = WireFormatLite::MakeTag(1, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - // Length: 2B for key tag & val and 2B for val tag and length of the following - // payload. - *p++ = 4 + payload_size; - *p++ = WireFormatLite::MakeTag(1, WireFormatLite::WIRETYPE_VARINT); - *p++ = 0; - *p++ = WireFormatLite::MakeTag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - *p++ = payload_size; - StrAppend(&s, dummy4_s, dummy5_s); - - // Test key then value then value. - int key = 0; - ASSERT_TRUE(map_message.ParseFromString(s)); - ASSERT_EQ(1, map_message.map_field().size()); - ASSERT_EQ(1, map_message.map_field().count(key)); - EXPECT_EQ(97, map_message.map_field().find(key)->second.a()); - EXPECT_EQ(0, map_message.map_field().find(key)->second.b()); - EXPECT_EQ(33, map_message.map_field().find(key)->second.c()); - EXPECT_EQ(98, map_message.map_field().find(key)->second.dummy4()); - EXPECT_EQ(99, map_message.map_field().find(key)->second.dummy5()); - - // Test key then value then value then key. - s.push_back(s[2]); // Copy the key's tag. - key = 19; - s.push_back(key); // Second key is 19 instead of 0. - s[1] += 2; // Adjust encoded size. - ASSERT_TRUE(map_message.ParseFromString(s)); - ASSERT_EQ(1, map_message.map_field().size()); - ASSERT_EQ(1, map_message.map_field().count(key)); - EXPECT_EQ(97, map_message.map_field().find(key)->second.a()); - EXPECT_EQ(0, map_message.map_field().find(key)->second.b()); - EXPECT_EQ(33, map_message.map_field().find(key)->second.c()); - EXPECT_EQ(98, map_message.map_field().find(key)->second.dummy4()); - EXPECT_EQ(99, map_message.map_field().find(key)->second.dummy5()); -} - -// Generated Message Reflection Test ================================ - -TEST(GeneratedMapFieldReflectionTest, SpaceUsed) { - unittest::TestMap message; - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.SetMapFieldsViaReflection(&message); - - EXPECT_LT(0, message.GetReflection()->SpaceUsedLong(message)); -} - -TEST(GeneratedMapFieldReflectionTest, Accessors) { - // Set every field to a unique value then go back and check all those - // values. - unittest::TestMap message; - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.SetMapFieldsViaReflection(&message); - MapTestUtil::ExpectMapFieldsSet(message); - reflection_tester.ExpectMapFieldsSetViaReflection(message); - reflection_tester.ExpectMapFieldsSetViaReflectionIterator(&message); - - reflection_tester.ModifyMapFieldsViaReflection(&message); - MapTestUtil::ExpectMapFieldsModified(message); -} - -TEST(GeneratedMapFieldReflectionTest, Swap) { - unittest::TestMap message1; - unittest::TestMap message2; - - MapTestUtil::SetMapFields(&message1); - - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); - - MapTestUtil::ExpectClear(message1); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -TEST(GeneratedMapFieldReflectionTest, SwapWithBothSet) { - unittest::TestMap message1; - unittest::TestMap message2; - - MapTestUtil::SetMapFields(&message1); - MapTestUtil::SetMapFields(&message2); - MapTestUtil::ModifyMapFields(&message2); - - const Reflection* reflection = message1.GetReflection(); - reflection->Swap(&message1, &message2); - - MapTestUtil::ExpectMapFieldsModified(message1); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -TEST(GeneratedMapFieldReflectionTest, SwapFields) { - unittest::TestMap message1; - unittest::TestMap message2; - - MapTestUtil::SetMapFields(&message2); - - std::vector<const FieldDescriptor*> fields; - const Reflection* reflection = message1.GetReflection(); - reflection->ListFields(message2, &fields); - reflection->SwapFields(&message1, &message2, fields); - - MapTestUtil::ExpectMapFieldsSet(message1); - MapTestUtil::ExpectClear(message2); -} - -TEST(GeneratedMapFieldReflectionTest, ClearField) { - unittest::TestMap message; - MapTestUtil::SetMapFields(&message); - MapTestUtil::ExpectMapFieldsSet(message); - - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.ClearMapFieldsViaReflection(&message); - reflection_tester.ExpectClearViaReflection(message); - reflection_tester.ExpectClearViaReflectionIterator(&message); -} - -TEST(GeneratedMapFieldReflectionTest, RemoveLast) { - unittest::TestMap message; - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - - MapTestUtil::SetMapFields(&message); - MapTestUtil::ExpectMapsSize(message, 2); - std::vector<const Message*> expected_entries = - MapTestUtil::GetMapEntries(message, 0); - - reflection_tester.RemoveLastMapsViaReflection(&message); - - MapTestUtil::ExpectMapsSize(message, 1); - std::vector<const Message*> remained_entries = - MapTestUtil::GetMapEntries(message, 0); - EXPECT_TRUE(expected_entries == remained_entries); -} - -TEST(GeneratedMapFieldReflectionTest, ReleaseLast) { - unittest::TestMap message; - const Descriptor* descriptor = message.GetDescriptor(); - MapReflectionTester reflection_tester(descriptor); - - MapTestUtil::SetMapFields(&message); - - MapTestUtil::ExpectMapsSize(message, 2); - - reflection_tester.ReleaseLastMapsViaReflection(&message); - - MapTestUtil::ExpectMapsSize(message, 1); - - // Now test that we actually release the right message. - message.Clear(); - MapTestUtil::SetMapFields(&message); - - MapTestUtil::ExpectMapsSize(message, 2); - std::vector<const Message*> expect_last = - MapTestUtil::GetMapEntries(message, 1); - std::vector<const Message*> release_last = - MapTestUtil::GetMapEntriesFromRelease(&message); - MapTestUtil::ExpectMapsSize(message, 1); - EXPECT_TRUE(expect_last == release_last); - for (std::vector<const Message*>::iterator it = release_last.begin(); - it != release_last.end(); ++it) { - delete *it; - } -} - -TEST(GeneratedMapFieldReflectionTest, SwapElements) { - unittest::TestMap message; - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - - MapTestUtil::SetMapFields(&message); - - // Get pointers of map entries at their original position - std::vector<const Message*> entries0 = MapTestUtil::GetMapEntries(message, 0); - std::vector<const Message*> entries1 = MapTestUtil::GetMapEntries(message, 1); - - // Swap the first time. - reflection_tester.SwapMapsViaReflection(&message); - - // Get pointer of map entry after swap once. - std::vector<const Message*> entries0_once = - MapTestUtil::GetMapEntries(message, 0); - std::vector<const Message*> entries1_once = - MapTestUtil::GetMapEntries(message, 1); - - // Test map entries are swapped. - MapTestUtil::ExpectMapsSize(message, 2); - EXPECT_TRUE(entries0 == entries1_once); - EXPECT_TRUE(entries1 == entries0_once); - - // Swap the second time. - reflection_tester.SwapMapsViaReflection(&message); - - // Get pointer of map entry after swap once. - std::vector<const Message*> entries0_twice = - MapTestUtil::GetMapEntries(message, 0); - std::vector<const Message*> entries1_twice = - MapTestUtil::GetMapEntries(message, 1); - - // Test map entries are swapped back. - MapTestUtil::ExpectMapsSize(message, 2); - EXPECT_TRUE(entries0 == entries0_twice); - EXPECT_TRUE(entries1 == entries1_twice); -} - -TEST(GeneratedMapFieldReflectionTest, MutableUnknownFields) { - unittest::TestMap message; - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.MutableUnknownFieldsOfMapFieldsViaReflection(&message); -} - -TEST(GeneratedMapFieldReflectionTest, EmbedProto2Message) { - unittest::TestMessageMap message; - - const FieldDescriptor* map_field = - unittest::TestMessageMap::descriptor()->FindFieldByName( - "map_int32_message"); - const FieldDescriptor* value = - map_field->message_type()->FindFieldByName("value"); - - Message* entry_message = - message.GetReflection()->AddMessage(&message, map_field); - EXPECT_EQ( - &entry_message->GetReflection()->GetMessage(*entry_message, value), - reinterpret_cast<const Message*>(&TestAllTypes::default_instance())); - - Message* proto2_message = - entry_message->GetReflection()->MutableMessage(entry_message, value); - EXPECT_EQ(unittest::TestAllTypes::descriptor(), - proto2_message->GetDescriptor()); - ASSERT_EQ(1, message.map_int32_message().size()); -} - -TEST(GeneratedMapFieldReflectionTest, MergeFromClearMapEntry) { - unittest::TestMap message; - const FieldDescriptor* map_field = - unittest::TestMap::descriptor()->FindFieldByName("map_int32_int32"); - const FieldDescriptor* key = - map_field->message_type()->FindFieldByName("key"); - const FieldDescriptor* value = - map_field->message_type()->FindFieldByName("value"); - - Message* entry_message1 = - message.GetReflection()->AddMessage(&message, map_field); - EXPECT_FALSE(entry_message1->GetReflection()->HasField(*entry_message1, key)); - EXPECT_FALSE( - entry_message1->GetReflection()->HasField(*entry_message1, value)); - - Message* entry_message2 = - message.GetReflection()->AddMessage(&message, map_field); - EXPECT_FALSE(entry_message2->GetReflection()->HasField(*entry_message2, key)); - EXPECT_FALSE( - entry_message2->GetReflection()->HasField(*entry_message2, value)); - - entry_message1->MergeFrom(*entry_message2); - EXPECT_FALSE(entry_message1->GetReflection()->HasField(*entry_message1, key)); - EXPECT_FALSE( - entry_message1->GetReflection()->HasField(*entry_message1, value)); -} - -TEST(GeneratedMapFieldReflectionTest, MapEntryClear) { - unittest::TestMap message; - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.MutableUnknownFieldsOfMapFieldsViaReflection(&message); -} - -TEST(GeneratedMapFieldReflectionTest, Proto2MapEntryClear) { - unittest::TestEnumMap message; - const Descriptor* descriptor = message.GetDescriptor(); - const FieldDescriptor* field_descriptor = - descriptor->FindFieldByName("known_map_field"); - const FieldDescriptor* value_descriptor = - field_descriptor->message_type()->FindFieldByName("value"); - Message* sub_message = - message.GetReflection()->AddMessage(&message, field_descriptor); - EXPECT_EQ(0, sub_message->GetReflection()->GetEnumValue(*sub_message, - value_descriptor)); -} - -// Map Reflection API Test ========================================= - -TEST(GeneratedMapFieldReflectionTest, SetViaMapReflection) { - unittest::TestMap message; - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.SetMapFieldsViaMapReflection(&message); - reflection_tester.ExpectMapFieldsSetViaReflection(message); - reflection_tester.ExpectMapFieldsSetViaReflectionIterator(&message); -} - -// Dynamic Message Test ============================================= - -class MapFieldInDynamicMessageTest : public testing::Test { - protected: - const DescriptorPool* pool_; - DynamicMessageFactory factory_; - const Descriptor* map_descriptor_; - const Descriptor* recursive_map_descriptor_; - const Message* map_prototype_; - - MapFieldInDynamicMessageTest() - : pool_(DescriptorPool::generated_pool()), factory_(pool_) {} - - virtual void SetUp() { - map_descriptor_ = pool_->FindMessageTypeByName("protobuf_unittest.TestMap"); - recursive_map_descriptor_ = - pool_->FindMessageTypeByName("protobuf_unittest.TestRecursiveMapMessage"); - ASSERT_TRUE(map_descriptor_ != NULL); - ASSERT_TRUE(recursive_map_descriptor_ != NULL); - map_prototype_ = factory_.GetPrototype(map_descriptor_); - } -}; - -TEST_F(MapFieldInDynamicMessageTest, MapIndependentOffsets) { - // Check that all fields have independent offsets by setting each - // one to a unique value then checking that they all still have those - // unique values (i.e. they don't stomp each other). - std::unique_ptr<Message> message(map_prototype_->New()); - MapReflectionTester reflection_tester(map_descriptor_); - - reflection_tester.SetMapFieldsViaReflection(message.get()); - reflection_tester.ExpectMapFieldsSetViaReflection(*message); -} - -TEST_F(MapFieldInDynamicMessageTest, DynamicMapReflection) { - // Check that map fields work properly. - std::unique_ptr<Message> message(map_prototype_->New()); - - // Check set functions. - MapReflectionTester reflection_tester(map_descriptor_); - reflection_tester.SetMapFieldsViaMapReflection(message.get()); - reflection_tester.ExpectMapFieldsSetViaReflection(*message); -} - -TEST_F(MapFieldInDynamicMessageTest, MapSpaceUsed) { - // Test that SpaceUsedLong() works properly - - // Since we share the implementation with generated messages, we don't need - // to test very much here. Just make sure it appears to be working. - - std::unique_ptr<Message> message(map_prototype_->New()); - MapReflectionTester reflection_tester(map_descriptor_); - - int initial_space_used = message->SpaceUsedLong(); - - reflection_tester.SetMapFieldsViaReflection(message.get()); - EXPECT_LT(initial_space_used, message->SpaceUsedLong()); -} - -TEST_F(MapFieldInDynamicMessageTest, RecursiveMap) { - TestRecursiveMapMessage from; - (*from.mutable_a())[""]; - std::string data = from.SerializeAsString(); - std::unique_ptr<Message> to( - factory_.GetPrototype(recursive_map_descriptor_)->New()); - ASSERT_TRUE(to->ParseFromString(data)); -} - -TEST_F(MapFieldInDynamicMessageTest, MapValueReferernceValidAfterSerialize) { - std::unique_ptr<Message> message(map_prototype_->New()); - MapReflectionTester reflection_tester(map_descriptor_); - reflection_tester.SetMapFieldsViaMapReflection(message.get()); - - // Get value reference before serialization, so that we know the value is from - // map. - MapKey map_key; - MapValueRef map_val; - map_key.SetInt32Value(0); - reflection_tester.GetMapValueViaMapReflection( - message.get(), "map_int32_foreign_message", map_key, &map_val); - Message* submsg = map_val.MutableMessageValue(); - - // In previous implementation, calling SerializeToString will cause syncing - // from map to repeated field, which will invalidate the submsg we previously - // got. - std::string data; - message->SerializeToString(&data); - - const Reflection* submsg_reflection = submsg->GetReflection(); - const Descriptor* submsg_desc = submsg->GetDescriptor(); - const FieldDescriptor* submsg_field = submsg_desc->FindFieldByName("c"); - submsg_reflection->SetInt32(submsg, submsg_field, 128); - - message->SerializeToString(&data); - TestMap to; - to.ParseFromString(data); - EXPECT_EQ(128, to.map_int32_foreign_message().at(0).c()); -} - -TEST_F(MapFieldInDynamicMessageTest, MapEntryReferernceValidAfterSerialize) { - std::unique_ptr<Message> message(map_prototype_->New()); - MapReflectionTester reflection_tester(map_descriptor_); - reflection_tester.SetMapFieldsViaReflection(message.get()); - - // Get map entry before serialization, so that we know the it is from - // repeated field. - Message* map_entry = reflection_tester.GetMapEntryViaReflection( - message.get(), "map_int32_foreign_message", 0); - const Reflection* map_entry_reflection = map_entry->GetReflection(); - const Descriptor* map_entry_desc = map_entry->GetDescriptor(); - const FieldDescriptor* value_field = map_entry_desc->FindFieldByName("value"); - Message* submsg = - map_entry_reflection->MutableMessage(map_entry, value_field); - - // In previous implementation, calling SerializeToString will cause syncing - // from repeated field to map, which will invalidate the map_entry we - // previously got. - std::string data; - message->SerializeToString(&data); - - const Reflection* submsg_reflection = submsg->GetReflection(); - const Descriptor* submsg_desc = submsg->GetDescriptor(); - const FieldDescriptor* submsg_field = submsg_desc->FindFieldByName("c"); - submsg_reflection->SetInt32(submsg, submsg_field, 128); - - message->SerializeToString(&data); - TestMap to; - to.ParseFromString(data); - EXPECT_EQ(128, to.map_int32_foreign_message().at(0).c()); -} - -// ReflectionOps Test =============================================== - -TEST(ReflectionOpsForMapFieldTest, MapSanityCheck) { - unittest::TestMap message; - - MapTestUtil::SetMapFields(&message); - MapTestUtil::ExpectMapFieldsSet(message); -} - -TEST(ReflectionOpsForMapFieldTest, MapCopy) { - unittest::TestMap message, message2; - - MapTestUtil::SetMapFields(&message); - - ReflectionOps::Copy(message, &message2); - - MapTestUtil::ExpectMapFieldsSet(message2); - - // Copying from self should be a no-op. - ReflectionOps::Copy(message2, &message2); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -TEST(ReflectionOpsForMapFieldTest, MergeMap) { - // Note: Copy is implemented in terms of Merge() so technically the Copy - // test already tested most of this. - - unittest::TestMap message, message2; - - MapTestUtil::SetMapFields(&message); - - ReflectionOps::Merge(message2, &message); - - MapTestUtil::ExpectMapFieldsSet(message); -} - -TEST(ReflectionOpsForMapFieldTest, ClearMap) { - unittest::TestMap message; - - MapTestUtil::SetMapFields(&message); - - ReflectionOps::Clear(&message); - - MapTestUtil::ExpectClear(message); -} - -TEST(ReflectionOpsForMapFieldTest, MapDiscardUnknownFields) { - unittest::TestMap message; - MapTestUtil::SetMapFields(&message); - - // Set some unknown fields in message. - message.GetReflection()->MutableUnknownFields(&message)->AddVarint(123456, - 654321); - - // Discard them. - ReflectionOps::DiscardUnknownFields(&message); - MapTestUtil::ExpectMapFieldsSet(message); - - EXPECT_EQ(0, - message.GetReflection()->GetUnknownFields(message).field_count()); -} - -TEST(ReflectionOpsForMapFieldTest, IsInitialized) { - unittest::TestRequiredMessageMap map_message; - - // Add an uninitialized message. - (*map_message.mutable_map_field())[0]; - EXPECT_FALSE(ReflectionOps::IsInitialized(map_message)); - - // Initialize uninitialized message - (*map_message.mutable_map_field())[0].set_a(0); - (*map_message.mutable_map_field())[0].set_b(0); - (*map_message.mutable_map_field())[0].set_c(0); - EXPECT_TRUE(ReflectionOps::IsInitialized(map_message)); -} - -// Wire Format Test ================================================= - -TEST(WireFormatForMapFieldTest, ParseMap) { - unittest::TestMap source, dest; - std::string data; - - // Serialize using the generated code. - MapTestUtil::SetMapFields(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - MapTestUtil::ExpectMapFieldsSet(dest); -} - -TEST(WireFormatForMapFieldTest, MapByteSize) { - unittest::TestMap message; - MapTestUtil::SetMapFields(&message); - - EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); - message.Clear(); - EXPECT_EQ(0, message.ByteSizeLong()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatForMapFieldTest, SerializeMap) { - unittest::TestMap message; - std::string generated_data; - std::string dynamic_data; - - MapTestUtil::SetMapFields(&message); - - // Serialize using the generated code. - { - message.ByteSizeLong(); - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message.SerializeWithCachedSizes(&output); - ASSERT_FALSE(output.HadError()); - } - - // Serialize using WireFormat. - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - size_t size = WireFormat::ByteSize(message); - WireFormat::SerializeWithCachedSizes(message, size, &output); - ASSERT_FALSE(output.HadError()); - } - - // Should parse to the same message. - EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); - EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); -} - -TEST(WireFormatForMapFieldTest, SerializeMapDynamicMessage) { - DynamicMessageFactory factory; - std::unique_ptr<Message> dynamic_message; - dynamic_message.reset( - factory.GetPrototype(unittest::TestMap::descriptor())->New()); - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.SetMapFieldsViaReflection(dynamic_message.get()); - reflection_tester.ExpectMapFieldsSetViaReflection(*dynamic_message); - - unittest::TestMap generated_message; - MapTestUtil::SetMapFields(&generated_message); - MapTestUtil::ExpectMapFieldsSet(generated_message); - - std::string generated_data; - std::string dynamic_data; - - // Serialize. - generated_message.SerializeToString(&generated_data); - dynamic_message->SerializeToString(&dynamic_data); - - // Because map serialization doesn't guarantee order, we just compare - // serialized size here. This is enough to tell dynamic message doesn't miss - // anything in serialization. - EXPECT_TRUE(dynamic_data.size() == generated_data.size()); -} - -TEST(WireFormatForMapFieldTest, MapByteSizeDynamicMessage) { - DynamicMessageFactory factory; - std::unique_ptr<Message> dynamic_message; - dynamic_message.reset( - factory.GetPrototype(unittest::TestMap::descriptor())->New()); - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.SetMapFieldsViaReflection(dynamic_message.get()); - reflection_tester.ExpectMapFieldsSetViaReflection(*dynamic_message); - std::string expected_serialized_data; - dynamic_message->SerializeToString(&expected_serialized_data); - int expected_size = expected_serialized_data.size(); - EXPECT_EQ(dynamic_message->ByteSizeLong(), expected_size); - - std::unique_ptr<Message> message2; - message2.reset(factory.GetPrototype(unittest::TestMap::descriptor())->New()); - reflection_tester.SetMapFieldsViaMapReflection(message2.get()); - - const FieldDescriptor* field = - unittest::TestMap::descriptor()->FindFieldByName("map_int32_int32"); - const Reflection* reflection = dynamic_message->GetReflection(); - - // Force the map field to mark with STATE_MODIFIED_REPEATED - reflection->RemoveLast(dynamic_message.get(), field); - dynamic_message->MergeFrom(*message2); - dynamic_message->MergeFrom(*message2); - // The map field is marked as STATE_MODIFIED_REPEATED, ByteSizeLong() will use - // repeated field which have duplicate keys to calculate. - size_t duplicate_size = dynamic_message->ByteSizeLong(); - EXPECT_TRUE(duplicate_size > expected_size); - std::string duplicate_serialized_data; - dynamic_message->SerializeToString(&duplicate_serialized_data); - EXPECT_EQ(dynamic_message->ByteSizeLong(), duplicate_serialized_data.size()); - - // Force the map field to mark with map CLEAN - EXPECT_EQ(reflection_tester.MapSize(*dynamic_message, "map_int32_int32"), 2); - // The map field is marked as CLEAN, ByteSizeLong() will use map which do not - // have duplicate keys to calculate. - int size = dynamic_message->ByteSizeLong(); - EXPECT_EQ(expected_size, size); - - // Protobuf used to have a bug for serialize when map it marked CLEAN. It used - // repeated field to calculate ByteSizeLong but use map to serialize the real - // data, thus the ByteSizeLong may bigger than real serialized size. A crash - // might be happen at SerializeToString(). Or an "unexpected end group" - // warning was raised at parse back if user use SerializeWithCachedSizes() - // which avoids size check at serialize. - std::string serialized_data; - dynamic_message->SerializeToString(&serialized_data); - EXPECT_EQ(serialized_data, expected_serialized_data); - dynamic_message->ParseFromString(serialized_data); -} - -TEST(WireFormatForMapFieldTest, MapParseHelpers) { - std::string data; - - { - // Set up. - protobuf_unittest::TestMap message; - MapTestUtil::SetMapFields(&message); - message.SerializeToString(&data); - } - - { - // Test ParseFromString. - protobuf_unittest::TestMap message; - EXPECT_TRUE(message.ParseFromString(data)); - MapTestUtil::ExpectMapFieldsSet(message); - } - - { - // Test ParseFromIstream. - protobuf_unittest::TestMap message; - std::stringstream stream(data); - EXPECT_TRUE(message.ParseFromIstream(&stream)); - EXPECT_TRUE(stream.eof()); - MapTestUtil::ExpectMapFieldsSet(message); - } - - { - // Test ParseFromBoundedZeroCopyStream. - std::string data_with_junk(data); - data_with_junk.append("some junk on the end"); - io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size()); - protobuf_unittest::TestMap message; - EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size())); - MapTestUtil::ExpectMapFieldsSet(message); - } - - { - // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if - // EOF is reached before the expected number of bytes. - io::ArrayInputStream stream(data.data(), data.size()); - protobuf_unittest::TestAllTypes message; - EXPECT_FALSE( - message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1)); - } -} - -// Deterministic Serialization Test ========================================== - -template <typename T> -static std::string DeterministicSerializationWithSerializePartialToCodedStream( - const T& t) { - const size_t size = t.ByteSizeLong(); - std::string result(size, '\0'); - io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size); - io::CodedOutputStream output_stream(&array_stream); - output_stream.SetSerializationDeterministic(true); - t.SerializePartialToCodedStream(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - return result; -} - -template <typename T> -static std::string DeterministicSerializationWithSerializeToCodedStream( - const T& t) { - const size_t size = t.ByteSizeLong(); - std::string result(size, '\0'); - io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size); - io::CodedOutputStream output_stream(&array_stream); - output_stream.SetSerializationDeterministic(true); - t.SerializeToCodedStream(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - return result; -} - -template <typename T> -static std::string DeterministicSerialization(const T& t) { - const size_t size = t.ByteSizeLong(); - std::string result(size, '\0'); - io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size); - { - io::CodedOutputStream output_stream(&array_stream); - output_stream.SetSerializationDeterministic(true); - t.SerializeWithCachedSizes(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - } - EXPECT_EQ(result, DeterministicSerializationWithSerializeToCodedStream(t)); - EXPECT_EQ(result, - DeterministicSerializationWithSerializePartialToCodedStream(t)); - return result; -} - -// Helper for MapSerializationTest. Return a 7-bit ASCII string. -static std::string ConstructKey(uint64 n) { - std::string s(n % static_cast<uint64>(9), '\0'); - if (s.empty()) { - return StrCat(n); - } else { - while (n != 0) { - s[n % s.size()] = (n >> 10) & 0x7f; - n /= 888; - } - return s; - } -} - -TEST(MapSerializationTest, Deterministic) { - const int kIters = 25; - protobuf_unittest::TestMaps t; - protobuf_unittest::TestIntIntMap inner; - (*inner.mutable_m())[0] = (*inner.mutable_m())[10] = - (*inner.mutable_m())[-200] = 0; - uint64 frog = 9; - const uint64 multiplier = 0xa29cd16f; - for (int i = 0; i < kIters; i++) { - const int32 i32 = static_cast<int32>(frog & 0xffffffff); - const uint32 u32 = static_cast<uint32>(i32) * 91919; - const int64 i64 = static_cast<int64>(frog); - const uint64 u64 = frog * static_cast<uint64>(187321); - const bool b = i32 > 0; - const std::string s = ConstructKey(frog); - (*inner.mutable_m())[i] = i32; - (*t.mutable_m_int32())[i32] = (*t.mutable_m_sint32())[i32] = - (*t.mutable_m_sfixed32())[i32] = inner; - (*t.mutable_m_uint32())[u32] = (*t.mutable_m_fixed32())[u32] = inner; - (*t.mutable_m_int64())[i64] = (*t.mutable_m_sint64())[i64] = - (*t.mutable_m_sfixed64())[i64] = inner; - (*t.mutable_m_uint64())[u64] = (*t.mutable_m_fixed64())[u64] = inner; - (*t.mutable_m_bool())[b] = inner; - (*t.mutable_m_string())[s] = inner; - (*t.mutable_m_string())[s + std::string(1 << (u32 % static_cast<uint32>(9)), - b)] = inner; - inner.mutable_m()->erase(i); - frog = frog * multiplier + i; - frog ^= (frog >> 41); - } - - // Verifies if two consecutive calls to deterministic serialization produce - // the same bytes. Deterministic serialization means the same serialization - // bytes in the same binary. - const std::string s1 = DeterministicSerialization(t); - const std::string s2 = DeterministicSerialization(t); - EXPECT_EQ(s1, s2); - - protobuf_unittest::TestMaps u; - EXPECT_TRUE(u.ParseFromString(s1)); - EXPECT_TRUE(util::MessageDifferencer::Equals(u, t)); -} - -TEST(MapSerializationTest, DeterministicSubmessage) { - protobuf_unittest::TestSubmessageMaps p; - protobuf_unittest::TestMaps t; - const std::string filename = "golden_message_maps"; - std::string golden; - GOOGLE_CHECK_OK(File::GetContents( - TestUtil::GetTestDataPath("net/proto2/internal/testdata/" + filename), - &golden, true)); - t.ParseFromString(golden); - *(p.mutable_m()) = t; - std::vector<std::string> v; - // Use multiple attempts to increase the chance of a failure if something is - // buggy. For example, each separate copy of a map might use a different - // randomly-chosen hash function. - const int kAttempts = 10; - for (int i = 0; i < kAttempts; i++) { - protobuf_unittest::TestSubmessageMaps q(p); - ASSERT_EQ(DeterministicSerialization(q), DeterministicSerialization(p)); - } -} - -// Text Format Test ================================================= - -TEST(TextFormatMapTest, SerializeAndParse) { - unittest::TestMap source; - unittest::TestMap dest; - MapTestUtil::SetMapFields(&source); - std::string output; - - // Test compact ASCII - TextFormat::Printer printer; - printer.PrintToString(source, &output); - TextFormat::Parser parser; - EXPECT_TRUE(parser.ParseFromString(output, &dest)); - MapTestUtil::ExpectMapFieldsSet(dest); -} - -TEST(TextFormatMapTest, DynamicMessage) { - TestMap prototype; - DynamicMessageFactory factory; - std::unique_ptr<Message> message( - factory.GetPrototype(prototype.GetDescriptor())->New()); - MapReflectionTester tester(message->GetDescriptor()); - tester.SetMapFieldsViaReflection(message.get()); - - std::string expected_text; - GOOGLE_CHECK_OK( - File::GetContents(TestUtil::GetTestDataPath("net/proto2/internal/" - "testdata/map_test_data.txt"), - &expected_text, true)); - - CleanStringLineEndings(&expected_text, false); - EXPECT_EQ(message->DebugString(), expected_text); -} - -TEST(TextFormatMapTest, Sorted) { - unittest::TestMap message; - MapReflectionTester tester(message.GetDescriptor()); - tester.SetMapFieldsViaReflection(&message); - - std::string expected_text; - GOOGLE_CHECK_OK( - File::GetContents(TestUtil::GetTestDataPath("net/proto2/internal/" - "testdata/map_test_data.txt"), - &expected_text, true)); - - CleanStringLineEndings(&expected_text, false); - EXPECT_EQ(message.DebugString(), expected_text); - - // Test again on the reverse order. - unittest::TestMap message2; - tester.SetMapFieldsViaReflection(&message2); - tester.SwapMapsViaReflection(&message2); - EXPECT_EQ(message2.DebugString(), expected_text); -} - -TEST(TextFormatMapTest, ParseCorruptedString) { - std::string serialized_message; - GOOGLE_CHECK_OK( - File::GetContents(TestUtil::GetTestDataPath( - "net/proto2/internal/testdata/golden_message_maps"), - &serialized_message, true)); - protobuf_unittest::TestMaps message; - GOOGLE_CHECK(message.ParseFromString(serialized_message)); - TestParseCorruptedString<protobuf_unittest::TestMaps, true>(message); - TestParseCorruptedString<protobuf_unittest::TestMaps, false>(message); -} - -// Previously, serializing to text format will disable iterator from generated -// API. Now, the iterator can be still used even after serializing to text -// format. -TEST(TextFormatMapTest, NoDisableIterator) { - unittest::TestMap source; - (*source.mutable_map_int32_int32())[1] = 1; - - // Get iterator. - Map<int32, int32>::iterator iter = source.mutable_map_int32_int32()->find(1); - - // Serialize message to text format, which will invalidate the previous - // iterator previously. - std::string output; - TextFormat::Printer printer; - printer.PrintToString(source, &output); - - // Modify map via the iterator (invalidated in previous implementation.). - iter->second = 2; - - // In previous implementation, the new change won't be reflected in text - // format, because the previous iterator has been invalidated. - output.clear(); - printer.PrintToString(source, &output); - std::string expected = - "map_int32_int32 {\n" - " key: 1\n" - " value: 2\n" - "}\n"; - EXPECT_EQ(output, expected); -} - -// Previously, serializing to text format will disable iterator from reflection -// API. -TEST(TextFormatMapTest, NoDisableReflectionIterator) { - unittest::TestMap source; - (*source.mutable_map_int32_int32())[1] = 1; - - // Get iterator. This will also sync internal repeated field with map inside - // of MapField. - const Reflection* reflection = source.GetReflection(); - const FieldDescriptor* field_desc = - source.GetDescriptor()->FindFieldByName("map_int32_int32"); - RepeatedPtrField<Message>* map_field = - reflection->MutableRepeatedPtrField<Message>(&source, field_desc); - RepeatedPtrField<Message>::iterator iter = map_field->begin(); - - // Serialize message to text format, which will invalidate the previous - // iterator previously. - std::string output; - TextFormat::Printer printer; - printer.PrintToString(source, &output); - - // Modify map via the iterator (invalidated in previous implementation.). - const Reflection* map_entry_reflection = iter->GetReflection(); - const FieldDescriptor* value_field_desc = - iter->GetDescriptor()->FindFieldByName("value"); - map_entry_reflection->SetInt32(&(*iter), value_field_desc, 2); - GOOGLE_LOG(INFO) << iter->DebugString(); - - // In previous implementation, the new change won't be reflected in text - // format, because the previous iterator has been invalidated. - output.clear(); - printer.PrintToString(source, &output); - std::string expected = - "map_int32_int32 {\n" - " key: 1\n" - " value: 2\n" - "}\n"; - EXPECT_EQ(output, expected); -} - - -// arena support ================================================= -TEST(ArenaTest, ParsingAndSerializingNoHeapAllocation) { - // Allocate a large initial block to avoid mallocs during hooked test. - std::vector<char> arena_block(128 * 1024); - ArenaOptions options; - options.initial_block = &arena_block[0]; - options.initial_block_size = arena_block.size(); - Arena arena(options); - std::string data; - data.reserve(128 * 1024); - - { - // TODO(teboring): Enable no heap check when ArenaStringPtr is used in map. - // NoHeapChecker no_heap; - - unittest::TestArenaMap* from = - Arena::CreateMessage<unittest::TestArenaMap>(&arena); - MapTestUtil::SetArenaMapFields(from); - from->SerializeToString(&data); - - unittest::TestArenaMap* to = - Arena::CreateMessage<unittest::TestArenaMap>(&arena); - to->ParseFromString(data); - MapTestUtil::ExpectArenaMapFieldsSet(*to); - } -} - -// Use text format parsing and serializing to test reflection api. -TEST(ArenaTest, ReflectionInTextFormat) { - Arena arena; - std::string data; - - TextFormat::Printer printer; - TextFormat::Parser parser; - - unittest::TestArenaMap* from = - Arena::CreateMessage<unittest::TestArenaMap>(&arena); - unittest::TestArenaMap* to = - Arena::CreateMessage<unittest::TestArenaMap>(&arena); - - MapTestUtil::SetArenaMapFields(from); - printer.PrintToString(*from, &data); - - EXPECT_TRUE(parser.ParseFromString(data, to)); - MapTestUtil::ExpectArenaMapFieldsSet(*to); -} - -// Make sure the memory allocated for string in map is deallocated. -TEST(ArenaTest, StringMapNoLeak) { - Arena arena; - unittest::TestArenaMap* message = - Arena::CreateMessage<unittest::TestArenaMap>(&arena); - std::string data; - // String with length less than 16 will not be allocated from heap. - int original_capacity = data.capacity(); - while (data.capacity() <= original_capacity) { - data.append("a"); - } - (*message->mutable_map_string_string())[data] = data; - // We rely on heap checkers to detect memory leak for us. - ASSERT_FALSE(message == NULL); -} - -TEST(ArenaTest, IsInitialized) { - // Allocate a large initial polluted block. - std::vector<char> arena_block(128 * 1024); - std::fill(arena_block.begin(), arena_block.end(), '\xff'); - - ArenaOptions options; - options.initial_block = &arena_block[0]; - options.initial_block_size = arena_block.size(); - Arena arena(options); - - unittest::TestArenaMap* message = - Arena::CreateMessage<unittest::TestArenaMap>(&arena); - EXPECT_EQ(0, (*message->mutable_map_int32_int32())[0]); -} - -TEST(ArenaTest, DynamicMapFieldOnArena) { - Arena arena; - unittest::TestMap message2; - - DynamicMessageFactory factory; - Message* message1 = - factory.GetPrototype(unittest::TestMap::descriptor())->New(&arena); - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - reflection_tester.SetMapFieldsViaReflection(message1); - reflection_tester.ExpectMapFieldsSetViaReflection(*message1); - reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1); - message2.CopyFrom(*message1); - MapTestUtil::ExpectMapFieldsSet(message2); -} - -TEST(ArenaTest, DynamicMapFieldOnArenaMemoryLeak) { - auto* desc = unittest::TestMap::descriptor(); - auto* field = desc->FindFieldByName("map_int32_int32"); - - Arena arena; - DynamicMessageFactory factory; - auto* message = factory.GetPrototype(desc)->New(&arena); - auto* reflection = message->GetReflection(); - reflection->AddMessage(message, field); - - // Force internal syncing, which initializes the mutex. - MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); - int size = reflection_tester.MapSize(*message, "map_int32_int32"); - EXPECT_EQ(size, 1); -} - -TEST(MoveTest, MoveConstructorWorks) { - Map<int32, TestAllTypes> original_map; - original_map[42].mutable_optional_nested_message()->set_bb(42); - original_map[43].mutable_optional_nested_message()->set_bb(43); - const auto* nested_msg42_ptr = &original_map[42].optional_nested_message(); - const auto* nested_msg43_ptr = &original_map[43].optional_nested_message(); - - Map<int32, TestAllTypes> moved_to_map(std::move(original_map)); - EXPECT_TRUE(original_map.empty()); - EXPECT_EQ(2, moved_to_map.size()); - EXPECT_EQ(42, moved_to_map[42].optional_nested_message().bb()); - EXPECT_EQ(43, moved_to_map[43].optional_nested_message().bb()); - // This test takes advantage of the fact that pointers are swapped, so there - // should be pointer stability. - EXPECT_EQ(nested_msg42_ptr, &moved_to_map[42].optional_nested_message()); - EXPECT_EQ(nested_msg43_ptr, &moved_to_map[43].optional_nested_message()); -} - -TEST(MoveTest, MoveAssignmentWorks) { - Map<int32, TestAllTypes> original_map; - original_map[42].mutable_optional_nested_message()->set_bb(42); - original_map[43].mutable_optional_nested_message()->set_bb(43); - const auto* nested_msg42_ptr = &original_map[42].optional_nested_message(); - const auto* nested_msg43_ptr = &original_map[43].optional_nested_message(); - Map<int32, TestAllTypes> moved_to_map = std::move(original_map); - EXPECT_TRUE(original_map.empty()); - EXPECT_EQ(2, moved_to_map.size()); - EXPECT_EQ(42, moved_to_map[42].optional_nested_message().bb()); - EXPECT_EQ(43, moved_to_map[43].optional_nested_message().bb()); - // This test takes advantage of the fact that pointers are swapped, so there - // should be pointer stability. - EXPECT_EQ(nested_msg42_ptr, &moved_to_map[42].optional_nested_message()); - EXPECT_EQ(nested_msg43_ptr, &moved_to_map[43].optional_nested_message()); -} } // namespace
diff --git a/src/google/protobuf/map_test.inc b/src/google/protobuf/map_test.inc new file mode 100644 index 0000000..4e8304f --- /dev/null +++ b/src/google/protobuf/map_test.inc
@@ -0,0 +1,3852 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A hack to include windows.h first, which ensures the GetMessage macro can +// be undefined when we include <google/protobuf/stubs/common.h> +#if defined(_MSC_VER) +#define _WINSOCKAPI_ // to avoid re-definition in WinSock2.h +#define NOMINMAX // to avoid defining min/max macros +#include <windows.h> +#endif // _WIN32 + +#include <algorithm> +#include <map> +#include <memory> +#include <random> +#include <set> +#include <sstream> +#include <unordered_map> +#include <unordered_set> +#include <vector> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/testing/file.h> +#include <google/protobuf/arena_test_util.h> +#include <google/protobuf/test_util2.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/tokenizer.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor_database.h> +#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/map.h> +#include <google/protobuf/map_field_inl.h> +#include <google/protobuf/message.h> +#include <google/protobuf/reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/text_format.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/util/message_differencer.h> +#include <google/protobuf/util/time_util.h> +#include <gmock/gmock.h> +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/substitute.h> + + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +using UNITTEST::ForeignMessage; +using UNITTEST::TestAllTypes; +using UNITTEST::TestMap; +using UNITTEST::TestRecursiveMapMessage; + +namespace internal { + +void MapTestForceDeterministic() { + io::CodedOutputStream::SetDefaultSerializationDeterministic(); +} + +namespace { + +// Map API Test ===================================================== + +class MapImplTest : public ::testing::Test { + protected: + MapImplTest() + : map_ptr_(new Map<int32, int32>()), + map_(*map_ptr_), + const_map_(*map_ptr_) { + EXPECT_TRUE(map_.empty()); + EXPECT_EQ(0, map_.size()); + } + + void ExpectSingleElement(int32 key, int32 value) { + EXPECT_FALSE(map_.empty()); + EXPECT_EQ(1, map_.size()); + ExpectElement(key, value); + } + + void ExpectElements(const std::map<int32, int32>& map) { + EXPECT_FALSE(map_.empty()); + EXPECT_EQ(map.size(), map_.size()); + for (std::map<int32, int32>::const_iterator it = map.begin(); + it != map.end(); ++it) { + ExpectElement(it->first, it->second); + } + } + + void ExpectElement(int32 key, int32 value) { + // Test map size is correct. + EXPECT_EQ(value, map_[key]); + EXPECT_EQ(1, map_.count(key)); + EXPECT_TRUE(map_.contains(key)); + + // Check mutable at and find work correctly. + EXPECT_EQ(value, map_.at(key)); + Map<int32, int32>::iterator it = map_.find(key); + + // iterator dereferenceable + EXPECT_EQ(key, (*it).first); + EXPECT_EQ(value, (*it).second); + EXPECT_EQ(key, it->first); + EXPECT_EQ(value, it->second); + + // iterator mutable + ((*it).second) = value + 1; + EXPECT_EQ(value + 1, map_[key]); + ((*it).second) = value; + EXPECT_EQ(value, map_[key]); + + it->second = value + 1; + EXPECT_EQ(value + 1, map_[key]); + it->second = value; + EXPECT_EQ(value, map_[key]); + + // copy constructor + Map<int32, int32>::iterator it_copy = it; + EXPECT_EQ(key, it_copy->first); + EXPECT_EQ(value, it_copy->second); + + // Immutable API ================================================ + + // Check immutable at and find work correctly. + EXPECT_EQ(value, const_map_.at(key)); + Map<int32, int32>::const_iterator const_it = const_map_.find(key); + + // iterator dereferenceable + EXPECT_EQ(key, (*const_it).first); + EXPECT_EQ(value, (*const_it).second); + EXPECT_EQ(key, const_it->first); + EXPECT_EQ(value, const_it->second); + + // copy constructor + Map<int32, int32>::const_iterator const_it_copy = const_it; + EXPECT_EQ(key, const_it_copy->first); + EXPECT_EQ(value, const_it_copy->second); + } + + std::unique_ptr<Map<int32, int32> > map_ptr_; + Map<int32, int32>& map_; + const Map<int32, int32>& const_map_; +}; + +TEST_F(MapImplTest, OperatorBracket) { + int32 key = 0; + int32 value1 = 100; + int32 value2 = 101; + + EXPECT_EQ(0, map_[key]); + + map_[key] = value1; + ExpectSingleElement(key, value1); + + map_[key] = value2; + ExpectSingleElement(key, value2); +} + +struct MoveTestKey { + MoveTestKey(int data, int* copies) : data(data), copies(copies) {} + + MoveTestKey(const MoveTestKey& other) + : data(other.data), copies(other.copies) { + ++*copies; + } + + MoveTestKey(MoveTestKey&& other) noexcept + : data(other.data), copies(other.copies) {} + + friend bool operator==(const MoveTestKey& lhs, const MoveTestKey& rhs) { + return lhs.data == rhs.data; + } + friend bool operator<(const MoveTestKey& lhs, const MoveTestKey& rhs) { + return lhs.data < rhs.data; + } + + int data; + int* copies; +}; + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google + +namespace std { + +template <> // NOLINT +struct hash<google::protobuf::internal::MoveTestKey> { + size_t operator()(const google::protobuf::internal::MoveTestKey& key) const { + return hash<int>{}(key.data); + } +}; +} // namespace std + +namespace google { +namespace protobuf { +namespace internal { +namespace { + +TEST_F(MapImplTest, OperatorBracketRValue) { + Arena arena; + for (Arena* arena_to_use : {&arena, static_cast<Arena*>(nullptr)}) { + int copies = 0; + Map<MoveTestKey, int> map(arena_to_use); + MoveTestKey key1(1, &copies); + EXPECT_EQ(copies, 0); + map[key1] = 0; + EXPECT_EQ(copies, 1); + map[MoveTestKey(2, &copies)] = 2; + EXPECT_EQ(copies, 1); + } +} + +TEST_F(MapImplTest, OperatorBracketNonExist) { + int32 key = 0; + int32 default_value = 0; + + EXPECT_EQ(default_value, map_[key]); + ExpectSingleElement(key, default_value); +} + +TEST_F(MapImplTest, MutableAt) { + int32 key = 0; + int32 value1 = 100; + int32 value2 = 101; + + map_[key] = value1; + ExpectSingleElement(key, value1); + + map_.at(key) = value2; + ExpectSingleElement(key, value2); +} + +#ifdef PROTOBUF_HAS_DEATH_TEST + +TEST_F(MapImplTest, MutableAtNonExistDeathTest) { + EXPECT_DEATH(map_.at(0), ""); +} + +TEST_F(MapImplTest, ImmutableAtNonExistDeathTest) { + EXPECT_DEATH(const_map_.at(0), ""); +} + +TEST_F(MapImplTest, UsageErrors) { + MapKey key; + key.SetInt64Value(1); + EXPECT_DEATH(key.GetUInt64Value(), + "Protocol Buffer map usage error:\n" + "MapKey::GetUInt64Value type does not match\n" + " Expected : uint64\n" + " Actual : int64"); + + MapValueRef value; + EXPECT_DEATH( + value.SetFloatValue(0.1), + "Protocol Buffer map usage error:\n" + "MapValue[Const]*Ref::type MapValue[Const]*Ref is not initialized."); +} + +#endif // PROTOBUF_HAS_DEATH_TEST + +TEST_F(MapImplTest, MapKeyAssignment) { + MapKey from, to; + from.SetStringValue("abc"); + to = from; + EXPECT_EQ("abc", to.GetStringValue()); +} + +TEST_F(MapImplTest, CountNonExist) { EXPECT_EQ(0, map_.count(0)); } + +TEST_F(MapImplTest, ContainNotExist) { EXPECT_FALSE(map_.contains(0)); } + +TEST_F(MapImplTest, ImmutableContainNotExist) { + EXPECT_FALSE(const_map_.contains(0)); +} + +TEST_F(MapImplTest, MutableFindNonExist) { + EXPECT_TRUE(map_.end() == map_.find(0)); +} + +TEST_F(MapImplTest, ImmutableFindNonExist) { + EXPECT_TRUE(const_map_.end() == const_map_.find(0)); +} + +TEST_F(MapImplTest, ConstEnd) { + EXPECT_TRUE(const_map_.end() == const_map_.cend()); +} + +TEST_F(MapImplTest, GetReferenceFromIterator) { + for (int i = 0; i < 10; i++) { + map_[i] = i; + } + + for (Map<int32, int32>::const_iterator it = map_.cbegin(); + it != map_.cend();) { + Map<int32, int32>::const_reference entry = *it++; + EXPECT_EQ(entry.first, entry.second); + } + + for (Map<int32, int32>::const_iterator it = const_map_.begin(); + it != const_map_.end();) { + Map<int32, int32>::const_reference entry = *it++; + EXPECT_EQ(entry.first, entry.second); + } + + for (Map<int32, int32>::iterator it = map_.begin(); it != map_.end();) { + Map<int32, int32>::reference entry = *it++; + EXPECT_EQ(entry.first + 1, ++entry.second); + } +} + +TEST_F(MapImplTest, IteratorBasic) { + map_[0] = 0; + + // Default constructible (per forward iterator requirements). + Map<int, int>::const_iterator cit; + Map<int, int>::iterator it; + + it = map_.begin(); + cit = it; // Converts to const_iterator + + // Can compare between them. + EXPECT_TRUE(it == cit); + EXPECT_FALSE(cit != it); + + // Pre increment. + EXPECT_FALSE(it == ++cit); + + // Post increment. + EXPECT_FALSE(it++ == cit); + EXPECT_TRUE(it == cit); +} + +template <typename Iterator> +static int64 median(Iterator i0, Iterator i1) { + std::vector<int64> v(i0, i1); + std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end()); + return v[v.size() / 2]; +} + +static int64 Now() { + return util::TimeUtil::TimestampToNanoseconds( + util::TimeUtil::GetCurrentTime()); +} + +// Arbitrary odd integers for creating test data. +static int k0 = 812398771; +static int k1 = 1312938717; +static int k2 = 1321555333; + +// A naive begin() implementation will cause begin() to get slower and slower +// if one erases elements at the "front" of the hash map, and we'd like to +// avoid that, as std::unordered_map does. +TEST_F(MapImplTest, BeginIsFast) { + if (true) return; // TODO(gpike): make this less flaky and re-enable it. + Map<int32, int32> map; + const int kTestSize = 250000; + // Create a random-looking map of size n. Use non-negative integer keys. + uint32 frog = 123983; + int last_key = 0; + int counter = 0; + while (map.size() < kTestSize) { + frog *= static_cast<uint32>(k0); + frog ^= frog >> 17; + frog += counter++; + last_key = + static_cast<int>(frog) >= 0 ? static_cast<int>(frog) : last_key ^ 1; + GOOGLE_DCHECK_GE(last_key, 0); + map[last_key] = last_key ^ 1; + } + std::vector<int64> times; + // We're going to do map.erase(map.begin()) over and over again. But, + // just in case one iteration is fast compared to the granularity of + // our time keeping, we measure kChunkSize iterations per outer-loop iter. + const int kChunkSize = 1000; + GOOGLE_CHECK_EQ(kTestSize % kChunkSize, 0); + do { + const int64 start = Now(); + for (int i = 0; i < kChunkSize; i++) { + map.erase(map.begin()); + } + const int64 end = Now(); + if (end > start) { + times.push_back(end - start); + } + } while (!map.empty()); + if (times.size() < .99 * kTestSize / kChunkSize) { + GOOGLE_LOG(WARNING) << "Now() isn't helping us measure time"; + return; + } + int64 x0 = median(times.begin(), times.begin() + 9); + int64 x1 = median(times.begin() + times.size() - 9, times.end()); + GOOGLE_LOG(INFO) << "x0=" << x0 << ", x1=" << x1; + // x1 will greatly exceed x0 if the code we just executed took O(n^2) time. + // And we'll probably time out and never get here. So, this test is + // intentionally loose: we check that x0 and x1 are within a factor of 8. + EXPECT_GE(x1, x0 / 8); + EXPECT_GE(x0, x1 / 8); +} + +// Try to create kTestSize keys that will land in just a few buckets, and +// time the insertions, to get a rough estimate of whether an O(n^2) worst case +// was triggered. This test is a hacky, but probably better than nothing. +TEST_F(MapImplTest, HashFlood) { + const int kTestSize = 1024; // must be a power of 2 + std::set<int> s; + for (int i = 0; s.size() < kTestSize; i++) { + if ((map_.hash_function()(i) & (kTestSize - 1)) < 3) { + s.insert(i); + } + } + // Create hash table with kTestSize entries that hash flood a table with + // 1024 (or 512 or 2048 or ...) entries. This assumes that map_ uses powers + // of 2 for table sizes, and that it's sufficient to "flood" with respect to + // the low bits of the output of map_.hash_function(). + std::vector<int64> times; + std::set<int>::iterator it = s.begin(); + int count = 0; + do { + const int64 start = Now(); + map_[*it] = 0; + const int64 end = Now(); + if (end > start) { + times.push_back(end - start); + } + ++count; + ++it; + } while (it != s.end()); + if (times.size() < .99 * count) return; + int64 x0 = median(times.begin(), times.begin() + 9); + int64 x1 = median(times.begin() + times.size() - 9, times.end()); + // x1 will greatly exceed x0 if the code we just executed took O(n^2) time. + // But we want to allow O(n log n). A factor of 20 should be generous enough. + EXPECT_LE(x1, x0 * 20); +} + +TEST_F(MapImplTest, CopyIteratorStressTest) { + std::vector<Map<int32, int32>::iterator> v; + const int kIters = 1e5; + for (uint32 i = 0; i < kIters; i++) { + int32 key = (3 + i * (5 + i * (-8 + i * (62 + i)))) & 0x77777777; + map_[key] = i; + v.push_back(map_.find(key)); + } + for (std::vector<Map<int32, int32>::iterator>::const_iterator it = v.begin(); + it != v.end(); it++) { + Map<int32, int32>::iterator i = *it; + ASSERT_EQ(i->first, (*it)->first); + ASSERT_EQ(i->second, (*it)->second); + } +} + +template <typename T, typename U> +static void TestValidityForAllKeysExcept(int key_to_avoid, const T& check_map, + const U& map) { + typedef typename U::value_type value_type; // a key-value pair + for (typename U::const_iterator it = map.begin(); it != map.end(); ++it) { + const int key = it->first; + if (key == key_to_avoid) continue; + // All iterators relevant to this key, whether old (from check_map) or new, + // must point to the same memory. So, test pointer equality here. + const value_type* check_val = &*check_map.find(key)->second; + EXPECT_EQ(check_val, &*it); + EXPECT_EQ(check_val, &*map.find(key)); + } +} + +// EXPECT i0 and i1 to be the same. Advancing them should have the same effect, +// too. +template <typename Iter> +static void TestEqualIterators(Iter i0, Iter i1, Iter end) { + const int kMaxAdvance = 10; + for (int i = 0; i < kMaxAdvance; i++) { + EXPECT_EQ(i0 == end, i1 == end); + if (i0 == end) return; + EXPECT_EQ(&*i0, &*i1) << "iter " << i; + ++i0; + ++i1; + } +} + +template <typename IteratorType> +static void TestOldVersusNewIterator(int skip, Map<int, int>* m) { + const int initial_size = m->size(); + IteratorType it = m->begin(); + for (int i = 0; i < skip && it != m->end(); it++, i++) { + } + if (it == m->end()) return; + const IteratorType old = it; + GOOGLE_LOG(INFO) << "skip=" << skip << ", old->first=" << old->first; + const int target_size = + initial_size < 100 ? initial_size * 5 : initial_size * 5 / 4; + for (int i = 0; m->size() <= target_size; i++) { + (*m)[i] = 0; + } + // Iterator 'old' should still work just fine despite the growth of *m. + const IteratorType after_growth = m->find(old->first); + TestEqualIterators<IteratorType>(old, after_growth, m->end()); + + // Now shrink the number of elements. Do this with a mix of erases and + // inserts to increase the chance that the hashtable will resize to a lower + // number of buckets. (But, in any case, the test is still useful.) + for (int i = 0; i < 2 * (target_size - initial_size); i++) { + if (i != old->first) { + m->erase(i); + } + if (((i ^ m->begin()->first) & 15) == 0) { + (*m)[i * 342] = i; + } + } + // Now, the table has grown and shrunk; test again. + TestEqualIterators<IteratorType>(old, m->find(old->first), m->end()); + TestEqualIterators<IteratorType>(old, after_growth, m->end()); +} + +// Create and test an n-element Map, with emphasis on iterator correctness. +static void StressTestIterators(int n) { + GOOGLE_LOG(INFO) << "StressTestIterators " << n; + GOOGLE_CHECK_GT(n, 0); + // Create a random-looking map of size n. Use non-negative integer keys. + Map<int, int> m; + uint32 frog = 123987 + n; + int last_key = 0; + int counter = 0; + while (m.size() < n) { + frog *= static_cast<uint32>(k0); + frog ^= frog >> 17; + frog += counter++; + last_key = + static_cast<int>(frog) >= 0 ? static_cast<int>(frog) : last_key ^ 1; + GOOGLE_DCHECK_GE(last_key, 0); + m[last_key] = last_key ^ 1; + } + // Test it. + ASSERT_EQ(n, m.size()); + // Create maps of pointers and iterators. + // These should remain valid even if we modify m. + std::unordered_map<int, Map<int, int>::value_type*> mp(n); + std::unordered_map<int, Map<int, int>::iterator> mi(n); + for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it) { + mp[it->first] = &*it; + mi[it->first] = it; + } + ASSERT_EQ(m.size(), mi.size()); + ASSERT_EQ(m.size(), mp.size()); + m.erase(last_key); + ASSERT_EQ(n - 1, m.size()); + TestValidityForAllKeysExcept(last_key, mp, m); + TestValidityForAllKeysExcept(last_key, mi, m); + + m[last_key] = 0; + ASSERT_EQ(n, m.size()); + // Test old iterator vs new iterator, with table modification in between. + TestOldVersusNewIterator<Map<int, int>::const_iterator>(n % 3, &m); + TestOldVersusNewIterator<Map<int, int>::iterator>(n % (1 + (n / 40)), &m); + // Finally, ensure erase(iterator) doesn't reorder anything, because that is + // what its documentation says. + m[last_key] = m[last_key ^ 999] = 0; + std::vector<Map<int, int>::iterator> v; + v.reserve(m.size()); + int position_of_last_key = 0; + for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it) { + if (it->first == last_key) { + position_of_last_key = v.size(); + } + v.push_back(it); + } + ASSERT_EQ(m.size(), v.size()); + const Map<int, int>::iterator erase_result = m.erase(m.find(last_key)); + int index = 0; + for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it, ++index) { + if (index == position_of_last_key) { + EXPECT_EQ(&*erase_result, &*v[++index]); + } + ASSERT_EQ(&*it, &*v[index]); + } +} + +TEST_F(MapImplTest, IteratorInvalidation) { + // Create a set of pseudo-random sizes to test. +#ifndef NDEBUG + const int kMaxSizeToTest = 100 * 1000; +#else + const int kMaxSizeToTest = 1000 * 1000; +#endif + std::set<int> s; + int n = kMaxSizeToTest; + unsigned int frog = k1 + n; + while (n > 1 && s.size() < 25) { + s.insert(n); + n = static_cast<int>(n * 100 / (101.0 + (frog & 63))); + frog *= k2; + frog ^= frog >> 17; + } + // Ensure we test a few small sizes. + s.insert(1); + s.insert(2); + s.insert(3); + // Now, the real work. + for (std::set<int>::iterator i = s.begin(); i != s.end(); ++i) { + StressTestIterators(*i); + } +} + +// Test that erase() revalidates iterators. +TEST_F(MapImplTest, EraseRevalidates) { + map_[3] = map_[13] = map_[20] = 0; + const int initial_size = map_.size(); + EXPECT_EQ(3, initial_size); + std::vector<Map<int, int>::iterator> v; + for (Map<int, int>::iterator it = map_.begin(); it != map_.end(); ++it) { + v.push_back(it); + } + EXPECT_EQ(initial_size, v.size()); + for (int i = 0; map_.size() <= initial_size * 20; i++) { + map_[i] = 0; + } + const int larger_size = map_.size(); + // We've greatly increased the size of the map, so it is highly likely that + // the following will corrupt m if erase() doesn't properly revalidate + // iterators passed to it. Finishing this routine without crashing indicates + // success. + for (int i = 0; i < v.size(); i++) { + map_.erase(v[i]); + } + EXPECT_EQ(larger_size - v.size(), map_.size()); +} + +template <typename T> +bool IsConstHelper(T& /*t*/) { // NOLINT. We want to catch non-const refs here. + return false; +} +template <typename T> +bool IsConstHelper(const T& /*t*/) { + return true; +} + +TEST_F(MapImplTest, IteratorConstness) { + map_[0] = 0; + EXPECT_TRUE(IsConstHelper(*map_.cbegin())); + EXPECT_TRUE(IsConstHelper(*const_map_.begin())); + EXPECT_FALSE(IsConstHelper(*map_.begin())); +} + +bool IsForwardIteratorHelper(std::forward_iterator_tag /*tag*/) { return true; } + +TEST_F(MapImplTest, IteratorCategory) { + EXPECT_TRUE(IsForwardIteratorHelper( + std::iterator_traits<Map<int, int>::iterator>::iterator_category())); + EXPECT_TRUE(IsForwardIteratorHelper( + std::iterator_traits< + Map<int, int>::const_iterator>::iterator_category())); +} + +TEST_F(MapImplTest, InsertSingle) { + int32 key = 0; + int32 value1 = 100; + int32 value2 = 101; + + // Insert a non-existed key. + std::pair<Map<int32, int32>::iterator, bool> result1 = + map_.insert(Map<int32, int32>::value_type(key, value1)); + ExpectSingleElement(key, value1); + + Map<int32, int32>::iterator it1 = result1.first; + EXPECT_EQ(key, it1->first); + EXPECT_EQ(value1, it1->second); + EXPECT_TRUE(result1.second); + + // Insert an existed key. + std::pair<Map<int32, int32>::iterator, bool> result2 = + map_.insert(Map<int32, int32>::value_type(key, value2)); + ExpectSingleElement(key, value1); + + Map<int32, int32>::iterator it2 = result2.first; + EXPECT_TRUE(it1 == it2); + EXPECT_FALSE(result2.second); +} + +TEST_F(MapImplTest, InsertByIterator) { + int32 key1 = 0; + int32 key2 = 1; + int32 value1a = 100; + int32 value1b = 101; + int32 value2a = 200; + int32 value2b = 201; + + std::map<int32, int32> map1; + map1[key1] = value1a; + map1[key2] = value2a; + + map_.insert(map1.begin(), map1.end()); + ExpectElements(map1); + + std::map<int32, int32> map2; + map2[key1] = value1b; + map2[key2] = value2b; + + map_.insert(map2.begin(), map2.end()); + ExpectElements(map1); +} + +TEST_F(MapImplTest, InsertByInitializerList) { + map_.insert({{1, 100}, {2, 200}}); + ExpectElements({{1, 100}, {2, 200}}); + + map_.insert({{2, 201}, {3, 301}}); + ExpectElements({{1, 100}, {2, 200}, {3, 301}}); +} + +TEST_F(MapImplTest, EraseSingleByKey) { + int32 key = 0; + int32 value = 100; + + map_[key] = value; + ExpectSingleElement(key, value); + + // Erase an existing key. + EXPECT_EQ(1, map_.erase(key)); + EXPECT_TRUE(map_.empty()); + EXPECT_EQ(0, map_.size()); + EXPECT_TRUE(map_.end() == map_.find(key)); + EXPECT_TRUE(map_.begin() == map_.end()); + + // Erase a non-existing key. + EXPECT_EQ(0, map_.erase(key)); +} + +TEST_F(MapImplTest, EraseMutipleByKey) { + // erase in one specific order to trigger corner cases + for (int i = 0; i < 5; i++) { + map_[i] = i; + } + + map_.erase(0); + EXPECT_EQ(4, map_.size()); + EXPECT_TRUE(map_.end() == map_.find(0)); + + map_.erase(1); + EXPECT_EQ(3, map_.size()); + EXPECT_TRUE(map_.end() == map_.find(1)); + + map_.erase(3); + EXPECT_EQ(2, map_.size()); + EXPECT_TRUE(map_.end() == map_.find(3)); + + map_.erase(4); + EXPECT_EQ(1, map_.size()); + EXPECT_TRUE(map_.end() == map_.find(4)); + + map_.erase(2); + EXPECT_EQ(0, map_.size()); + EXPECT_TRUE(map_.end() == map_.find(2)); +} + +TEST_F(MapImplTest, EraseSingleByIterator) { + int32 key = 0; + int32 value = 100; + + map_[key] = value; + ExpectSingleElement(key, value); + + Map<int32, int32>::iterator it = map_.find(key); + map_.erase(it); + EXPECT_TRUE(map_.empty()); + EXPECT_EQ(0, map_.size()); + EXPECT_TRUE(map_.end() == map_.find(key)); + EXPECT_TRUE(map_.begin() == map_.end()); +} + +TEST_F(MapImplTest, ValidIteratorAfterErase) { + for (int i = 0; i < 10; i++) { + map_[i] = i; + } + + int count = 0; + + for (Map<int32, int32>::iterator it = map_.begin(); it != map_.end();) { + count++; + if (it->first % 2 == 1) { + map_.erase(it++); + } else { + ++it; + } + } + + EXPECT_EQ(10, count); + EXPECT_EQ(5, map_.size()); +} + +TEST_F(MapImplTest, EraseByIterator) { + int32 key1 = 0; + int32 key2 = 1; + int32 value1 = 100; + int32 value2 = 101; + + std::map<int32, int32> map; + map[key1] = value1; + map[key2] = value2; + + map_.insert(map.begin(), map.end()); + ExpectElements(map); + + map_.erase(map_.begin(), map_.end()); + EXPECT_TRUE(map_.empty()); + EXPECT_EQ(0, map_.size()); + EXPECT_TRUE(map_.end() == map_.find(key1)); + EXPECT_TRUE(map_.end() == map_.find(key2)); + EXPECT_TRUE(map_.begin() == map_.end()); +} + +TEST_F(MapImplTest, Clear) { + int32 key = 0; + int32 value = 100; + + map_[key] = value; + ExpectSingleElement(key, value); + + map_.clear(); + + EXPECT_TRUE(map_.empty()); + EXPECT_EQ(0, map_.size()); + EXPECT_TRUE(map_.end() == map_.find(key)); + EXPECT_TRUE(map_.begin() == map_.end()); +} + +static void CopyConstructorHelper(Arena* arena, Map<int32, int32>* m) { + int32 key1 = 0; + int32 key2 = 1; + int32 value1 = 100; + int32 value2 = 101; + + std::map<int32, int32> map; + map[key1] = value1; + map[key2] = value2; + + m->insert(map.begin(), map.end()); + + Map<int32, int32> other(*m); + + EXPECT_EQ(2, other.size()); + EXPECT_EQ(value1, other.at(key1)); + EXPECT_EQ(value2, other.at(key2)); +} + +TEST_F(MapImplTest, CopyConstructorWithArena) { + Arena a; + CopyConstructorHelper(&a, &map_); +} + +TEST_F(MapImplTest, CopyConstructorWithoutArena) { + CopyConstructorHelper(NULL, &map_); +} + +TEST_F(MapImplTest, IterConstructor) { + int32 key1 = 0; + int32 key2 = 1; + int32 value1 = 100; + int32 value2 = 101; + + std::map<int32, int32> map; + map[key1] = value1; + map[key2] = value2; + + Map<int32, int32> new_map(map.begin(), map.end()); + + EXPECT_EQ(2, new_map.size()); + EXPECT_EQ(value1, new_map.at(key1)); + EXPECT_EQ(value2, new_map.at(key2)); +} + +TEST_F(MapImplTest, Assigner) { + int32 key1 = 0; + int32 key2 = 1; + int32 value1 = 100; + int32 value2 = 101; + + std::map<int32, int32> map; + map[key1] = value1; + map[key2] = value2; + + map_.insert(map.begin(), map.end()); + + Map<int32, int32> other; + int32 key_other = 123; + int32 value_other = 321; + other[key_other] = value_other; + EXPECT_EQ(1, other.size()); + + other = map_; + + EXPECT_EQ(2, other.size()); + EXPECT_EQ(value1, other.at(key1)); + EXPECT_EQ(value2, other.at(key2)); + EXPECT_TRUE(other.find(key_other) == other.end()); + + // Self assign + other = *&other; // Avoid -Wself-assign. + EXPECT_EQ(2, other.size()); + EXPECT_EQ(value1, other.at(key1)); + EXPECT_EQ(value2, other.at(key2)); +} + +TEST_F(MapImplTest, Rehash) { + const int test_size = 50; + std::map<int32, int32> reference_map; + for (int i = 0; i < test_size; i++) { + reference_map[i] = i; + } + for (int i = 0; i < test_size; i++) { + map_[i] = reference_map[i]; + EXPECT_EQ(reference_map[i], map_[i]); + } + for (int i = 0; i < test_size; i++) { + map_.erase(i); + EXPECT_TRUE(map_.end() == map_.find(i)); + } + EXPECT_TRUE(map_.empty()); +} + +TEST_F(MapImplTest, EqualRange) { + int key = 100, key_missing = 101; + map_[key] = 100; + + std::pair<Map<int32, int32>::iterator, Map<int32, int32>::iterator> range = + map_.equal_range(key); + EXPECT_TRUE(map_.find(key) == range.first); + EXPECT_TRUE(++map_.find(key) == range.second); + + range = map_.equal_range(key_missing); + EXPECT_TRUE(map_.end() == range.first); + EXPECT_TRUE(map_.end() == range.second); + + std::pair<Map<int32, int32>::const_iterator, + Map<int32, int32>::const_iterator> + const_range = const_map_.equal_range(key); + EXPECT_TRUE(const_map_.find(key) == const_range.first); + EXPECT_TRUE(++const_map_.find(key) == const_range.second); + + const_range = const_map_.equal_range(key_missing); + EXPECT_TRUE(const_map_.end() == const_range.first); + EXPECT_TRUE(const_map_.end() == const_range.second); +} + +TEST_F(MapImplTest, ConvertToStdMap) { + map_[100] = 101; + std::map<int32, int32> std_map(map_.begin(), map_.end()); + EXPECT_EQ(1, std_map.size()); + EXPECT_EQ(101, std_map[100]); +} + +TEST_F(MapImplTest, ConvertToStdVectorOfPairs) { + map_[100] = 101; + std::vector<std::pair<int32, int32> > std_vec(map_.begin(), map_.end()); + EXPECT_EQ(1, std_vec.size()); + EXPECT_EQ(100, std_vec[0].first); + EXPECT_EQ(101, std_vec[0].second); +} + +TEST_F(MapImplTest, SwapBasic) { + Map<int32, int32> another; + map_[9398] = 41999; + another[9398] = 41999; + another[8070] = 42056; + another.swap(map_); + EXPECT_THAT(another, + testing::UnorderedElementsAre(testing::Pair(9398, 41999))); + EXPECT_THAT(map_, testing::UnorderedElementsAre(testing::Pair(8070, 42056), + testing::Pair(9398, 41999))); +} + +TEST_F(MapImplTest, SwapArena) { + Arena arena1, arena2; + Map<int32, int32> m1(&arena1); + Map<int32, int32> m2(&arena2); + map_[9398] = 41999; + m1[9398] = 41999; + m1[8070] = 42056; + m2[10244] = 10247; + m2[8070] = 42056; + m1.swap(map_); + EXPECT_THAT(m1, testing::UnorderedElementsAre(testing::Pair(9398, 41999))); + EXPECT_THAT(map_, testing::UnorderedElementsAre(testing::Pair(8070, 42056), + testing::Pair(9398, 41999))); + m2.swap(m1); + EXPECT_THAT(m1, testing::UnorderedElementsAre(testing::Pair(8070, 42056), + testing::Pair(10244, 10247))); + EXPECT_THAT(m2, testing::UnorderedElementsAre(testing::Pair(9398, 41999))); +} + +TEST_F(MapImplTest, CopyAssignMapIterator) { + TestMap message; + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaMapReflection(&message); + MapIterator it1 = reflection_tester.MapBegin(&message, "map_int32_int32"); + MapIterator it2 = reflection_tester.MapEnd(&message, "map_int32_int32"); + it2 = it1; + EXPECT_EQ(it1.GetKey().GetInt32Value(), it2.GetKey().GetInt32Value()); +} + +TEST_F(MapImplTest, SpaceUsed) { + constexpr size_t kMinCap = 8; + + Map<int32, int32> m; + // An newly constructed map should have no space used. + EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), 0); + + size_t capacity = kMinCap; + for (int i = 0; i < 100; ++i) { + m[i]; + static constexpr double kMaxLoadFactor = .75; + if (m.size() >= capacity * kMaxLoadFactor) { + capacity *= 2; + } + EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), + sizeof(void*) * capacity + + m.size() * sizeof(std::pair<std::pair<int32, int32>, void*>)); + } + + // Test string, and non-scalar keys. + Map<std::string, int32> m2; + std::string str = "Some arbitrarily large string"; + m2[str] = 1; + EXPECT_EQ(m2.SpaceUsedExcludingSelfLong(), + sizeof(void*) * kMinCap + + sizeof(std::pair<std::pair<std::string, int32>, void*>) + + internal::StringSpaceUsedExcludingSelfLong(str)); + + // Test messages, and non-scalar values. + Map<int32, TestAllTypes> m3; + m3[0].set_optional_string(str); + EXPECT_EQ(m3.SpaceUsedExcludingSelfLong(), + sizeof(void*) * kMinCap + + sizeof(std::pair<std::pair<int32, TestAllTypes>, void*>) + + m3[0].SpaceUsedLong() - sizeof(m3[0])); +} + +// Attempts to verify that a map with keys a and b has a random ordering. This +// function returns true if it succeeds in observing both possible orderings. +bool MapOrderingIsRandom(int a, int b) { + bool saw_a_first = false; + bool saw_b_first = false; + std::vector<Map<int32, int32>> v(50); + for (int i = 0; i < 50; ++i) { + Map<int32, int32>& m = v[i]; + m[a] = 0; + m[b] = 0; + int32 first_element = m.begin()->first; + if (first_element == a) saw_a_first = true; + if (first_element == b) saw_b_first = true; + if (saw_a_first && saw_b_first) { + return true; + } + } + return false; +} + +// This test verifies that the iteration order is reasonably random even for +// small maps. Currently we only have sufficient randomness for debug builds and +// builds where we can use the RDTSC instruction, so we only test for those +// builds. +#if defined(__x86_64__) && defined(__GNUC__) && \ + !defined(GOOGLE_PROTOBUF_NO_RDTSC) +TEST_F(MapImplTest, RandomOrdering) { + for (int i = 0; i < 10; ++i) { + for (int j = i + 1; j < 10; ++j) { + EXPECT_TRUE(MapOrderingIsRandom(i, j)) + << "Map with keys " << i << " and " << j + << " has deterministic ordering"; + } + } +} +#endif + +template <typename Key> +void TestTransparent(const Key& key, const Key& miss_key) { + Map<std::string, int> m; + const auto& cm = m; + + m.insert({"ABC", 1}); + + const auto abc_it = m.begin(); + + m.insert({"DEF", 2}); + + using testing::Pair; + using testing::UnorderedElementsAre; + + EXPECT_EQ(m.at(key), 1); + EXPECT_EQ(cm.at(key), 1); + +#ifdef PROTOBUF_HAS_DEATH_TEST + EXPECT_DEATH(m.at(miss_key), ""); + EXPECT_DEATH(cm.at(miss_key), ""); +#endif // PROTOBUF_HAS_DEATH_TEST + + EXPECT_EQ(m.count(key), 1); + EXPECT_EQ(cm.count(key), 1); + EXPECT_EQ(m.count(miss_key), 0); + EXPECT_EQ(cm.count(miss_key), 0); + + EXPECT_EQ(m.find(key), abc_it); + EXPECT_EQ(cm.find(key), abc_it); + EXPECT_EQ(m.find(miss_key), m.end()); + EXPECT_EQ(cm.find(miss_key), cm.end()); + + EXPECT_TRUE(m.contains(key)); + EXPECT_TRUE(cm.contains(key)); + EXPECT_FALSE(m.contains(miss_key)); + EXPECT_FALSE(cm.contains(miss_key)); + + EXPECT_THAT(m.equal_range(key), Pair(abc_it, std::next(abc_it))); + EXPECT_THAT(cm.equal_range(key), Pair(abc_it, std::next(abc_it))); + EXPECT_THAT(m.equal_range(miss_key), Pair(m.end(), m.end())); + EXPECT_THAT(cm.equal_range(miss_key), Pair(m.end(), m.end())); + + EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 1), Pair("DEF", 2))); + EXPECT_EQ(m.erase(key), 1); + EXPECT_THAT(m, UnorderedElementsAre(Pair("DEF", 2))); + EXPECT_EQ(m.erase(key), 0); + EXPECT_EQ(m.erase(miss_key), 0); + EXPECT_THAT(m, UnorderedElementsAre(Pair("DEF", 2))); + + m[key]; + EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 0), Pair("DEF", 2))); + m[key] = 1; + EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 1), Pair("DEF", 2))); +} + +TEST_F(MapImplTest, TransparentLookupForString) { + TestTransparent("ABC", "LKJ"); + TestTransparent(std::string("ABC"), std::string("LKJ")); +#if defined(__cpp_lib_string_view) + TestTransparent(std::string_view("ABC"), std::string_view("LKJ")); +#endif // defined(__cpp_lib_string_view) + + // std::reference_wrapper + std::string abc = "ABC", lkj = "LKJ"; + TestTransparent(std::ref(abc), std::ref(lkj)); + TestTransparent(std::cref(abc), std::cref(lkj)); +} + +TEST_F(MapImplTest, ConstInit) { + PROTOBUF_CONSTINIT static Map<int, int> map; // NOLINT + EXPECT_TRUE(map.empty()); +} + +// Map Field Reflection Test ======================================== + +static int Func(int i, int j) { return i * j; } + +static std::string StrFunc(int i, int j) { return StrCat(Func(i, j)); } + +static int Int(const std::string& value) { + int result = 0; + std::istringstream(value) >> result; + return result; +} + +} // namespace + +// This class is a friend, so no anonymous namespace. +class MapFieldReflectionTest : public testing::Test { + protected: + typedef FieldDescriptor FD; + + int MapSize(const Reflection* reflection, const FieldDescriptor* field, + const Message& message) { + return reflection->MapSize(message, field); + } +}; + +namespace { + +TEST_F(MapFieldReflectionTest, RegularFields) { + TestMap message; + const Reflection* refl = message.GetReflection(); + const Descriptor* desc = message.GetDescriptor(); + + Map<int32, int32>* map_int32_int32 = message.mutable_map_int32_int32(); + Map<int32, double>* map_int32_double = message.mutable_map_int32_double(); + Map<std::string, std::string>* map_string_string = + message.mutable_map_string_string(); + Map<int32, ForeignMessage>* map_int32_foreign_message = + message.mutable_map_int32_foreign_message(); + + for (int i = 0; i < 10; ++i) { + (*map_int32_int32)[i] = Func(i, 1); + (*map_int32_double)[i] = Func(i, 2); + (*map_string_string)[StrFunc(i, 1)] = StrFunc(i, 5); + (*map_int32_foreign_message)[i].set_c(Func(i, 6)); + } + + // Get FieldDescriptors for all the fields of interest. + const FieldDescriptor* fd_map_int32_int32 = + desc->FindFieldByName("map_int32_int32"); + const FieldDescriptor* fd_map_int32_double = + desc->FindFieldByName("map_int32_double"); + const FieldDescriptor* fd_map_string_string = + desc->FindFieldByName("map_string_string"); + const FieldDescriptor* fd_map_int32_foreign_message = + desc->FindFieldByName("map_int32_foreign_message"); + + const FieldDescriptor* fd_map_int32_in32_key = + fd_map_int32_int32->message_type()->FindFieldByName("key"); + const FieldDescriptor* fd_map_int32_in32_value = + fd_map_int32_int32->message_type()->FindFieldByName("value"); + const FieldDescriptor* fd_map_int32_double_key = + fd_map_int32_double->message_type()->FindFieldByName("key"); + const FieldDescriptor* fd_map_int32_double_value = + fd_map_int32_double->message_type()->FindFieldByName("value"); + const FieldDescriptor* fd_map_string_string_key = + fd_map_string_string->message_type()->FindFieldByName("key"); + const FieldDescriptor* fd_map_string_string_value = + fd_map_string_string->message_type()->FindFieldByName("value"); + const FieldDescriptor* fd_map_int32_foreign_message_key = + fd_map_int32_foreign_message->message_type()->FindFieldByName("key"); + const FieldDescriptor* fd_map_int32_foreign_message_value = + fd_map_int32_foreign_message->message_type()->FindFieldByName("value"); + + // Get RepeatedPtrField objects for all fields of interest. + const RepeatedPtrField<Message>& mf_int32_int32 = + refl->GetRepeatedPtrField<Message>(message, fd_map_int32_int32); + const RepeatedPtrField<Message>& mf_int32_double = + refl->GetRepeatedPtrField<Message>(message, fd_map_int32_double); + const RepeatedPtrField<Message>& mf_string_string = + refl->GetRepeatedPtrField<Message>(message, fd_map_string_string); + const RepeatedPtrField<Message>& mf_int32_foreign_message = + refl->GetRepeatedPtrField<Message>(message, fd_map_int32_foreign_message); + + // Get mutable RepeatedPtrField objects for all fields of interest. + RepeatedPtrField<Message>* mmf_int32_int32 = + refl->MutableRepeatedPtrField<Message>(&message, fd_map_int32_int32); + RepeatedPtrField<Message>* mmf_int32_double = + refl->MutableRepeatedPtrField<Message>(&message, fd_map_int32_double); + RepeatedPtrField<Message>* mmf_string_string = + refl->MutableRepeatedPtrField<Message>(&message, fd_map_string_string); + RepeatedPtrField<Message>* mmf_int32_foreign_message = + refl->MutableRepeatedPtrField<Message>(&message, + fd_map_int32_foreign_message); + + // Make sure we can do gets through the RepeatedPtrField objects. + for (int i = 0; i < 10; ++i) { + { + // Check gets through const objects. + const Message& message_int32_int32 = mf_int32_int32.Get(i); + int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32( + message_int32_int32, fd_map_int32_in32_key); + int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32( + message_int32_int32, fd_map_int32_in32_value); + EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1)); + + const Message& message_int32_double = mf_int32_double.Get(i); + int32 key_int32_double = message_int32_double.GetReflection()->GetInt32( + message_int32_double, fd_map_int32_double_key); + double value_int32_double = + message_int32_double.GetReflection()->GetDouble( + message_int32_double, fd_map_int32_double_value); + EXPECT_EQ(value_int32_double, Func(key_int32_double, 2)); + + const Message& message_string_string = mf_string_string.Get(i); + std::string key_string_string = + message_string_string.GetReflection()->GetString( + message_string_string, fd_map_string_string_key); + std::string value_string_string = + message_string_string.GetReflection()->GetString( + message_string_string, fd_map_string_string_value); + EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5)); + + const Message& message_int32_message = mf_int32_foreign_message.Get(i); + int32 key_int32_message = message_int32_message.GetReflection()->GetInt32( + message_int32_message, fd_map_int32_foreign_message_key); + const ForeignMessage& value_int32_message = + down_cast<const ForeignMessage&>( + message_int32_message.GetReflection()->GetMessage( + message_int32_message, fd_map_int32_foreign_message_value)); + EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6)); + } + + { + // Check gets through mutable objects. + const Message& message_int32_int32 = mmf_int32_int32->Get(i); + int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32( + message_int32_int32, fd_map_int32_in32_key); + int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32( + message_int32_int32, fd_map_int32_in32_value); + EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1)); + + const Message& message_int32_double = mmf_int32_double->Get(i); + int32 key_int32_double = message_int32_double.GetReflection()->GetInt32( + message_int32_double, fd_map_int32_double_key); + double value_int32_double = + message_int32_double.GetReflection()->GetDouble( + message_int32_double, fd_map_int32_double_value); + EXPECT_EQ(value_int32_double, Func(key_int32_double, 2)); + + const Message& message_string_string = mmf_string_string->Get(i); + std::string key_string_string = + message_string_string.GetReflection()->GetString( + message_string_string, fd_map_string_string_key); + std::string value_string_string = + message_string_string.GetReflection()->GetString( + message_string_string, fd_map_string_string_value); + EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5)); + + const Message& message_int32_message = mmf_int32_foreign_message->Get(i); + int32 key_int32_message = message_int32_message.GetReflection()->GetInt32( + message_int32_message, fd_map_int32_foreign_message_key); + const ForeignMessage& value_int32_message = + down_cast<const ForeignMessage&>( + message_int32_message.GetReflection()->GetMessage( + message_int32_message, fd_map_int32_foreign_message_value)); + EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6)); + } + } + + // Do sets through the RepeatedPtrField objects. + for (int i = 0; i < 10; i++) { + { + Message* message_int32_int32 = mmf_int32_int32->Mutable(i); + int32 key_int32_int32 = message_int32_int32->GetReflection()->GetInt32( + *message_int32_int32, fd_map_int32_in32_key); + message_int32_int32->GetReflection()->SetInt32(message_int32_int32, + fd_map_int32_in32_value, + Func(key_int32_int32, -1)); + + Message* message_int32_double = mmf_int32_double->Mutable(i); + int32 key_int32_double = message_int32_double->GetReflection()->GetInt32( + *message_int32_double, fd_map_int32_double_key); + message_int32_double->GetReflection()->SetDouble( + message_int32_double, fd_map_int32_double_value, + Func(key_int32_double, -2)); + + Message* message_string_string = mmf_string_string->Mutable(i); + std::string key_string_string = + message_string_string->GetReflection()->GetString( + *message_string_string, fd_map_string_string_key); + message_string_string->GetReflection()->SetString( + message_string_string, fd_map_string_string_value, + StrFunc(Int(key_string_string), -5)); + + Message* message_int32_message = mmf_int32_foreign_message->Mutable(i); + int32 key_int32_message = + message_int32_message->GetReflection()->GetInt32( + *message_int32_message, fd_map_int32_foreign_message_key); + ForeignMessage* value_int32_message = down_cast<ForeignMessage*>( + message_int32_message->GetReflection()->MutableMessage( + message_int32_message, fd_map_int32_foreign_message_value)); + value_int32_message->set_c(Func(key_int32_message, -6)); + } + } + + // Check gets through mutable objects. + for (int i = 0; i < 10; i++) { + EXPECT_EQ(Func(i, -1), message.map_int32_int32().at(i)); + EXPECT_EQ(Func(i, -2), message.map_int32_double().at(i)); + EXPECT_EQ(StrFunc(i, -5), message.map_string_string().at(StrFunc(i, 1))); + EXPECT_EQ(Func(i, -6), message.map_int32_foreign_message().at(i).c()); + } +} + +TEST_F(MapFieldReflectionTest, RepeatedFieldRefForRegularFields) { + TestMap message; + const Reflection* refl = message.GetReflection(); + const Descriptor* desc = message.GetDescriptor(); + + Map<int32, int32>* map_int32_int32 = message.mutable_map_int32_int32(); + Map<int32, double>* map_int32_double = message.mutable_map_int32_double(); + Map<std::string, std::string>* map_string_string = + message.mutable_map_string_string(); + Map<int32, ForeignMessage>* map_int32_foreign_message = + message.mutable_map_int32_foreign_message(); + + for (int i = 0; i < 10; ++i) { + (*map_int32_int32)[i] = Func(i, 1); + (*map_int32_double)[i] = Func(i, 2); + (*map_string_string)[StrFunc(i, 1)] = StrFunc(i, 5); + (*map_int32_foreign_message)[i].set_c(Func(i, 6)); + } + + // Get FieldDescriptors for all the fields of interest. + const FieldDescriptor* fd_map_int32_int32 = + desc->FindFieldByName("map_int32_int32"); + const FieldDescriptor* fd_map_int32_double = + desc->FindFieldByName("map_int32_double"); + const FieldDescriptor* fd_map_string_string = + desc->FindFieldByName("map_string_string"); + const FieldDescriptor* fd_map_int32_foreign_message = + desc->FindFieldByName("map_int32_foreign_message"); + + const FieldDescriptor* fd_map_int32_in32_key = + fd_map_int32_int32->message_type()->FindFieldByName("key"); + const FieldDescriptor* fd_map_int32_in32_value = + fd_map_int32_int32->message_type()->FindFieldByName("value"); + const FieldDescriptor* fd_map_int32_double_key = + fd_map_int32_double->message_type()->FindFieldByName("key"); + const FieldDescriptor* fd_map_int32_double_value = + fd_map_int32_double->message_type()->FindFieldByName("value"); + const FieldDescriptor* fd_map_string_string_key = + fd_map_string_string->message_type()->FindFieldByName("key"); + const FieldDescriptor* fd_map_string_string_value = + fd_map_string_string->message_type()->FindFieldByName("value"); + const FieldDescriptor* fd_map_int32_foreign_message_key = + fd_map_int32_foreign_message->message_type()->FindFieldByName("key"); + const FieldDescriptor* fd_map_int32_foreign_message_value = + fd_map_int32_foreign_message->message_type()->FindFieldByName("value"); + + // Get RepeatedFieldRef objects for all fields of interest. + const RepeatedFieldRef<Message> mf_int32_int32 = + refl->GetRepeatedFieldRef<Message>(message, fd_map_int32_int32); + const RepeatedFieldRef<Message> mf_int32_double = + refl->GetRepeatedFieldRef<Message>(message, fd_map_int32_double); + const RepeatedFieldRef<Message> mf_string_string = + refl->GetRepeatedFieldRef<Message>(message, fd_map_string_string); + const RepeatedFieldRef<Message> mf_int32_foreign_message = + refl->GetRepeatedFieldRef<Message>(message, fd_map_int32_foreign_message); + + // Get mutable RepeatedFieldRef objects for all fields of interest. + const MutableRepeatedFieldRef<Message> mmf_int32_int32 = + refl->GetMutableRepeatedFieldRef<Message>(&message, fd_map_int32_int32); + const MutableRepeatedFieldRef<Message> mmf_int32_double = + refl->GetMutableRepeatedFieldRef<Message>(&message, fd_map_int32_double); + const MutableRepeatedFieldRef<Message> mmf_string_string = + refl->GetMutableRepeatedFieldRef<Message>(&message, fd_map_string_string); + const MutableRepeatedFieldRef<Message> mmf_int32_foreign_message = + refl->GetMutableRepeatedFieldRef<Message>(&message, + fd_map_int32_foreign_message); + + // Get entry default instances + std::unique_ptr<Message> entry_int32_int32( + MessageFactory::generated_factory() + ->GetPrototype(fd_map_int32_int32->message_type()) + ->New(message.GetArena())); + std::unique_ptr<Message> entry_int32_double( + MessageFactory::generated_factory() + ->GetPrototype(fd_map_int32_double->message_type()) + ->New(message.GetArena())); + std::unique_ptr<Message> entry_string_string( + MessageFactory::generated_factory() + ->GetPrototype(fd_map_string_string->message_type()) + ->New(message.GetArena())); + std::unique_ptr<Message> entry_int32_foreign_message( + MessageFactory::generated_factory() + ->GetPrototype(fd_map_int32_foreign_message->message_type()) + ->New(message.GetArena())); + + EXPECT_EQ(10, mf_int32_int32.size()); + EXPECT_EQ(10, mmf_int32_int32.size()); + EXPECT_EQ(10, mf_int32_double.size()); + EXPECT_EQ(10, mmf_int32_double.size()); + EXPECT_EQ(10, mf_string_string.size()); + EXPECT_EQ(10, mmf_string_string.size()); + EXPECT_EQ(10, mf_int32_foreign_message.size()); + EXPECT_EQ(10, mmf_int32_foreign_message.size()); + + EXPECT_FALSE(mf_int32_int32.empty()); + EXPECT_FALSE(mmf_int32_int32.empty()); + EXPECT_FALSE(mf_int32_double.empty()); + EXPECT_FALSE(mmf_int32_double.empty()); + EXPECT_FALSE(mf_string_string.empty()); + EXPECT_FALSE(mmf_string_string.empty()); + EXPECT_FALSE(mf_int32_foreign_message.empty()); + EXPECT_FALSE(mmf_int32_foreign_message.empty()); + + // Make sure we can do gets through the RepeatedFieldRef objects. + for (int i = 0; i < 10; ++i) { + { + // Check gets through const objects. + const Message& message_int32_int32 = + mf_int32_int32.Get(i, entry_int32_int32.get()); + int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32( + message_int32_int32, fd_map_int32_in32_key); + int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32( + message_int32_int32, fd_map_int32_in32_value); + EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1)); + + const Message& message_int32_double = + mf_int32_double.Get(i, entry_int32_double.get()); + int32 key_int32_double = message_int32_double.GetReflection()->GetInt32( + message_int32_double, fd_map_int32_double_key); + double value_int32_double = + message_int32_double.GetReflection()->GetDouble( + message_int32_double, fd_map_int32_double_value); + EXPECT_EQ(value_int32_double, Func(key_int32_double, 2)); + + const Message& message_string_string = + mf_string_string.Get(i, entry_string_string.get()); + std::string key_string_string = + message_string_string.GetReflection()->GetString( + message_string_string, fd_map_string_string_key); + std::string value_string_string = + message_string_string.GetReflection()->GetString( + message_string_string, fd_map_string_string_value); + EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5)); + + const Message& message_int32_message = + mf_int32_foreign_message.Get(i, entry_int32_foreign_message.get()); + int32 key_int32_message = message_int32_message.GetReflection()->GetInt32( + message_int32_message, fd_map_int32_foreign_message_key); + const ForeignMessage& value_int32_message = + down_cast<const ForeignMessage&>( + message_int32_message.GetReflection()->GetMessage( + message_int32_message, fd_map_int32_foreign_message_value)); + EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6)); + } + + { + // Check gets through mutable objects. + const Message& message_int32_int32 = + mmf_int32_int32.Get(i, entry_int32_int32.get()); + int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32( + message_int32_int32, fd_map_int32_in32_key); + int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32( + message_int32_int32, fd_map_int32_in32_value); + EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1)); + + const Message& message_int32_double = + mmf_int32_double.Get(i, entry_int32_double.get()); + int32 key_int32_double = message_int32_double.GetReflection()->GetInt32( + message_int32_double, fd_map_int32_double_key); + double value_int32_double = + message_int32_double.GetReflection()->GetDouble( + message_int32_double, fd_map_int32_double_value); + EXPECT_EQ(value_int32_double, Func(key_int32_double, 2)); + + const Message& message_string_string = + mmf_string_string.Get(i, entry_string_string.get()); + std::string key_string_string = + message_string_string.GetReflection()->GetString( + message_string_string, fd_map_string_string_key); + std::string value_string_string = + message_string_string.GetReflection()->GetString( + message_string_string, fd_map_string_string_value); + EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5)); + + const Message& message_int32_message = + mmf_int32_foreign_message.Get(i, entry_int32_foreign_message.get()); + int32 key_int32_message = message_int32_message.GetReflection()->GetInt32( + message_int32_message, fd_map_int32_foreign_message_key); + const ForeignMessage& value_int32_message = + down_cast<const ForeignMessage&>( + message_int32_message.GetReflection()->GetMessage( + message_int32_message, fd_map_int32_foreign_message_value)); + EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6)); + } + } + + // Make sure we can do sets through the RepeatedFieldRef objects. + for (int i = 0; i < 10; i++) { + const Message& message_int32_int32 = + mmf_int32_int32.Get(i, entry_int32_int32.get()); + int key = message_int32_int32.GetReflection()->GetInt32( + message_int32_int32, fd_map_int32_in32_key); + + entry_int32_int32->GetReflection()->SetInt32( + entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(0), + key); + entry_int32_int32->GetReflection()->SetInt32( + entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(1), + Func(key, -1)); + entry_int32_double->GetReflection()->SetInt32( + entry_int32_double.get(), fd_map_int32_double->message_type()->field(0), + key); + entry_int32_double->GetReflection()->SetDouble( + entry_int32_double.get(), fd_map_int32_double->message_type()->field(1), + Func(key, -2)); + entry_string_string->GetReflection()->SetString( + entry_string_string.get(), + fd_map_string_string->message_type()->field(0), StrFunc(key, 1)); + entry_string_string->GetReflection()->SetString( + entry_string_string.get(), + fd_map_string_string->message_type()->field(1), StrFunc(key, -5)); + entry_int32_foreign_message->GetReflection()->SetInt32( + entry_int32_foreign_message.get(), + fd_map_int32_foreign_message->message_type()->field(0), key); + Message* value_message = + entry_int32_foreign_message->GetReflection()->MutableMessage( + entry_int32_foreign_message.get(), + fd_map_int32_foreign_message->message_type()->field(1)); + value_message->GetReflection()->SetInt32( + value_message, value_message->GetDescriptor()->FindFieldByName("c"), + Func(key, -6)); + + mmf_int32_int32.Set(i, *entry_int32_int32); + mmf_int32_double.Set(i, *entry_int32_double); + mmf_string_string.Set(i, *entry_string_string); + mmf_int32_foreign_message.Set(i, *entry_int32_foreign_message); + } + + for (int i = 0; i < 10; i++) { + EXPECT_EQ(Func(i, -1), message.map_int32_int32().at(i)); + EXPECT_EQ(Func(i, -2), message.map_int32_double().at(i)); + EXPECT_EQ(StrFunc(i, -5), message.map_string_string().at(StrFunc(i, 1))); + EXPECT_EQ(Func(i, -6), message.map_int32_foreign_message().at(i).c()); + } + + // Test iterators. + { + int index = 0; + std::unordered_map<int32, int32> result; + for (RepeatedFieldRef<Message>::iterator it = mf_int32_int32.begin(); + it != mf_int32_int32.end(); ++it) { + const Message& message = *it; + int32 key = + message.GetReflection()->GetInt32(message, fd_map_int32_in32_key); + int32 value = + message.GetReflection()->GetInt32(message, fd_map_int32_in32_value); + result[key] = value; + ++index; + } + EXPECT_EQ(10, index); + for (std::unordered_map<int32, int32>::const_iterator it = result.begin(); + it != result.end(); ++it) { + EXPECT_EQ(message.map_int32_int32().at(it->first), it->second); + } + } + + { + int index = 0; + std::unordered_map<int32, double> result; + for (RepeatedFieldRef<Message>::iterator it = mf_int32_double.begin(); + it != mf_int32_double.end(); ++it) { + const Message& message = *it; + int32 key = + message.GetReflection()->GetInt32(message, fd_map_int32_double_key); + double value = message.GetReflection()->GetDouble( + message, fd_map_int32_double_value); + result[key] = value; + ++index; + } + EXPECT_EQ(10, index); + for (std::unordered_map<int32, double>::const_iterator it = result.begin(); + it != result.end(); ++it) { + EXPECT_EQ(message.map_int32_double().at(it->first), it->second); + } + } + + { + int index = 0; + std::unordered_map<std::string, std::string> result; + for (RepeatedFieldRef<Message>::iterator it = mf_string_string.begin(); + it != mf_string_string.end(); ++it) { + const Message& message = *it; + std::string key = + message.GetReflection()->GetString(message, fd_map_string_string_key); + std::string value = message.GetReflection()->GetString( + message, fd_map_string_string_value); + result[key] = value; + ++index; + } + EXPECT_EQ(10, index); + for (std::unordered_map<std::string, std::string>::const_iterator it = + result.begin(); + it != result.end(); ++it) { + EXPECT_EQ(message.map_string_string().at(it->first), it->second); + } + } + + { + int index = 0; + std::map<int32, ForeignMessage> result; + for (RepeatedFieldRef<Message>::iterator it = + mf_int32_foreign_message.begin(); + it != mf_int32_foreign_message.end(); ++it) { + const Message& message = *it; + int32 key = message.GetReflection()->GetInt32( + message, fd_map_int32_foreign_message_key); + const ForeignMessage& sub_message = + down_cast<const ForeignMessage&>(message.GetReflection()->GetMessage( + message, fd_map_int32_foreign_message_value)); + result[key].MergeFrom(sub_message); + ++index; + } + EXPECT_EQ(10, index); + for (std::map<int32, ForeignMessage>::const_iterator it = result.begin(); + it != result.end(); ++it) { + EXPECT_EQ(message.map_int32_foreign_message().at(it->first).c(), + it->second.c()); + } + } + + // Test MutableRepeatedFieldRef::Add() + entry_int32_int32->GetReflection()->SetInt32( + entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(0), + 4321); + entry_int32_int32->GetReflection()->SetInt32( + entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(1), + 1234); + mmf_int32_int32.Add(*entry_int32_int32); + EXPECT_EQ(1234, message.map_int32_int32().at(4321)); + + entry_int32_double->GetReflection()->SetInt32( + entry_int32_double.get(), fd_map_int32_double->message_type()->field(0), + 4321); + entry_int32_double->GetReflection()->SetDouble( + entry_int32_double.get(), fd_map_int32_double->message_type()->field(1), + 1234.0); + mmf_int32_double.Add(*entry_int32_double); + EXPECT_EQ(1234.0, message.map_int32_double().at(4321)); + + entry_string_string->GetReflection()->SetString( + entry_string_string.get(), fd_map_string_string->message_type()->field(0), + "4321"); + entry_string_string->GetReflection()->SetString( + entry_string_string.get(), fd_map_string_string->message_type()->field(1), + "1234"); + mmf_string_string.Add(*entry_string_string); + EXPECT_EQ("1234", message.map_string_string().at("4321")); + + entry_int32_foreign_message->GetReflection()->SetInt32( + entry_int32_foreign_message.get(), + fd_map_int32_foreign_message->message_type()->field(0), 4321); + Message* value_message = + entry_int32_foreign_message->GetReflection()->MutableMessage( + entry_int32_foreign_message.get(), + fd_map_int32_foreign_message->message_type()->field(1)); + ForeignMessage foreign_message; + foreign_message.set_c(1234); + value_message->CopyFrom(foreign_message); + + mmf_int32_foreign_message.Add(*entry_int32_foreign_message); + EXPECT_EQ(1234, message.map_int32_foreign_message().at(4321).c()); + + // Test Reflection::AddAllocatedMessage + Message* free_entry_string_string = + MessageFactory::generated_factory() + ->GetPrototype(fd_map_string_string->message_type()) + ->New(); + entry_string_string->GetReflection()->SetString( + free_entry_string_string, fd_map_string_string->message_type()->field(0), + "4321"); + entry_string_string->GetReflection()->SetString( + free_entry_string_string, fd_map_string_string->message_type()->field(1), + "1234"); + refl->AddAllocatedMessage(&message, fd_map_string_string, + free_entry_string_string); + + // Test MutableRepeatedFieldRef::RemoveLast() + mmf_int32_int32.RemoveLast(); + mmf_int32_double.RemoveLast(); + mmf_string_string.RemoveLast(); + mmf_int32_foreign_message.RemoveLast(); + EXPECT_EQ(10, message.map_int32_int32().size()); + EXPECT_EQ(10, message.map_int32_double().size()); + EXPECT_EQ(11, message.map_string_string().size()); + EXPECT_EQ(10, message.map_int32_foreign_message().size()); + + // Test MutableRepeatedFieldRef::SwapElements() + { + const Message& message0a = mmf_int32_int32.Get(0, entry_int32_int32.get()); + int32 int32_value0a = + message0a.GetReflection()->GetInt32(message0a, fd_map_int32_in32_value); + const Message& message9a = mmf_int32_int32.Get(9, entry_int32_int32.get()); + int32 int32_value9a = + message9a.GetReflection()->GetInt32(message9a, fd_map_int32_in32_value); + + mmf_int32_int32.SwapElements(0, 9); + + const Message& message0b = mmf_int32_int32.Get(0, entry_int32_int32.get()); + int32 int32_value0b = + message0b.GetReflection()->GetInt32(message0b, fd_map_int32_in32_value); + const Message& message9b = mmf_int32_int32.Get(9, entry_int32_int32.get()); + int32 int32_value9b = + message9b.GetReflection()->GetInt32(message9b, fd_map_int32_in32_value); + + EXPECT_EQ(int32_value9a, int32_value0b); + EXPECT_EQ(int32_value0a, int32_value9b); + } + + { + const Message& message0a = + mmf_int32_double.Get(0, entry_int32_double.get()); + double double_value0a = message0a.GetReflection()->GetDouble( + message0a, fd_map_int32_double_value); + const Message& message9a = + mmf_int32_double.Get(9, entry_int32_double.get()); + double double_value9a = message9a.GetReflection()->GetDouble( + message9a, fd_map_int32_double_value); + + mmf_int32_double.SwapElements(0, 9); + + const Message& message0b = + mmf_int32_double.Get(0, entry_int32_double.get()); + double double_value0b = message0b.GetReflection()->GetDouble( + message0b, fd_map_int32_double_value); + const Message& message9b = + mmf_int32_double.Get(9, entry_int32_double.get()); + double double_value9b = message9b.GetReflection()->GetDouble( + message9b, fd_map_int32_double_value); + + EXPECT_EQ(double_value9a, double_value0b); + EXPECT_EQ(double_value0a, double_value9b); + } + + { + const Message& message0a = + mmf_string_string.Get(0, entry_string_string.get()); + std::string string_value0a = message0a.GetReflection()->GetString( + message0a, fd_map_string_string_value); + const Message& message9a = + mmf_string_string.Get(9, entry_string_string.get()); + std::string string_value9a = message9a.GetReflection()->GetString( + message9a, fd_map_string_string_value); + + mmf_string_string.SwapElements(0, 9); + + const Message& message0b = + mmf_string_string.Get(0, entry_string_string.get()); + std::string string_value0b = message0b.GetReflection()->GetString( + message0b, fd_map_string_string_value); + const Message& message9b = + mmf_string_string.Get(9, entry_string_string.get()); + std::string string_value9b = message9b.GetReflection()->GetString( + message9b, fd_map_string_string_value); + + EXPECT_EQ(string_value9a, string_value0b); + EXPECT_EQ(string_value0a, string_value9b); + } + + { + const Message& message0a = + mmf_int32_foreign_message.Get(0, entry_int32_foreign_message.get()); + const ForeignMessage& sub_message0a = + down_cast<const ForeignMessage&>(message0a.GetReflection()->GetMessage( + message0a, fd_map_int32_foreign_message_value)); + int32 int32_value0a = sub_message0a.c(); + const Message& message9a = + mmf_int32_foreign_message.Get(9, entry_int32_foreign_message.get()); + const ForeignMessage& sub_message9a = + down_cast<const ForeignMessage&>(message9a.GetReflection()->GetMessage( + message9a, fd_map_int32_foreign_message_value)); + int32 int32_value9a = sub_message9a.c(); + + mmf_int32_foreign_message.SwapElements(0, 9); + + const Message& message0b = + mmf_int32_foreign_message.Get(0, entry_int32_foreign_message.get()); + const ForeignMessage& sub_message0b = + down_cast<const ForeignMessage&>(message0b.GetReflection()->GetMessage( + message0b, fd_map_int32_foreign_message_value)); + int32 int32_value0b = sub_message0b.c(); + const Message& message9b = + mmf_int32_foreign_message.Get(9, entry_int32_foreign_message.get()); + const ForeignMessage& sub_message9b = + down_cast<const ForeignMessage&>(message9b.GetReflection()->GetMessage( + message9b, fd_map_int32_foreign_message_value)); + int32 int32_value9b = sub_message9b.c(); + + EXPECT_EQ(int32_value9a, int32_value0b); + EXPECT_EQ(int32_value0a, int32_value9b); + } + + // TODO(b/181148674): After supporting arena agnostic delete or let map entry + // handle heap allocation, this could be removed. + if (message.GetArena() != nullptr) { + entry_int32_int32.release(); + entry_int32_double.release(); + entry_string_string.release(); + entry_int32_foreign_message.release(); + } +} + +TEST_F(MapFieldReflectionTest, RepeatedFieldRefMergeFromAndSwap) { + // Set-up message content. + TestMap m0, m1, m2; + for (int i = 0; i < 10; ++i) { + (*m0.mutable_map_int32_int32())[i] = Func(i, 1); + (*m0.mutable_map_int32_double())[i] = Func(i, 2); + (*m0.mutable_map_string_string())[StrFunc(i, 1)] = StrFunc(i, 5); + (*m0.mutable_map_int32_foreign_message())[i].set_c(Func(i, 6)); + (*m1.mutable_map_int32_int32())[i + 10] = Func(i, 11); + (*m1.mutable_map_int32_double())[i + 10] = Func(i, 12); + (*m1.mutable_map_string_string())[StrFunc(i + 10, 1)] = StrFunc(i, 15); + (*m1.mutable_map_int32_foreign_message())[i + 10].set_c(Func(i, 16)); + (*m2.mutable_map_int32_int32())[i + 20] = Func(i, 21); + (*m2.mutable_map_int32_double())[i + 20] = Func(i, 22); + (*m2.mutable_map_string_string())[StrFunc(i + 20, 1)] = StrFunc(i, 25); + (*m2.mutable_map_int32_foreign_message())[i + 20].set_c(Func(i, 26)); + } + + const Reflection* refl = m0.GetReflection(); + const Descriptor* desc = m0.GetDescriptor(); + + // Get FieldDescriptors for all the fields of interest. + const FieldDescriptor* fd_map_int32_int32 = + desc->FindFieldByName("map_int32_int32"); + const FieldDescriptor* fd_map_int32_double = + desc->FindFieldByName("map_int32_double"); + const FieldDescriptor* fd_map_string_string = + desc->FindFieldByName("map_string_string"); + const FieldDescriptor* fd_map_int32_foreign_message = + desc->FindFieldByName("map_int32_foreign_message"); + + // Get MutableRepeatedFieldRef objects for all fields of interest. + const MutableRepeatedFieldRef<Message> mmf_int32_int32 = + refl->GetMutableRepeatedFieldRef<Message>(&m0, fd_map_int32_int32); + const MutableRepeatedFieldRef<Message> mmf_int32_double = + refl->GetMutableRepeatedFieldRef<Message>(&m0, fd_map_int32_double); + const MutableRepeatedFieldRef<Message> mmf_string_string = + refl->GetMutableRepeatedFieldRef<Message>(&m0, fd_map_string_string); + const MutableRepeatedFieldRef<Message> mmf_int32_foreign_message = + refl->GetMutableRepeatedFieldRef<Message>(&m0, + fd_map_int32_foreign_message); + + // Test MutableRepeatedRef::CopyFrom + mmf_int32_int32.CopyFrom( + refl->GetRepeatedFieldRef<Message>(m1, fd_map_int32_int32)); + mmf_int32_double.CopyFrom( + refl->GetRepeatedFieldRef<Message>(m1, fd_map_int32_double)); + mmf_string_string.CopyFrom( + refl->GetRepeatedFieldRef<Message>(m1, fd_map_string_string)); + mmf_int32_foreign_message.CopyFrom( + refl->GetRepeatedFieldRef<Message>(m1, fd_map_int32_foreign_message)); + + for (int i = 0; i < 10; ++i) { + EXPECT_EQ(Func(i, 11), m0.map_int32_int32().at(i + 10)); + EXPECT_EQ(Func(i, 12), m0.map_int32_double().at(i + 10)); + EXPECT_EQ(StrFunc(i, 15), m0.map_string_string().at(StrFunc(i + 10, 1))); + EXPECT_EQ(Func(i, 16), m0.map_int32_foreign_message().at(i + 10).c()); + } + + // Test MutableRepeatedRef::MergeFrom + mmf_int32_int32.MergeFrom( + refl->GetRepeatedFieldRef<Message>(m2, fd_map_int32_int32)); + mmf_int32_double.MergeFrom( + refl->GetRepeatedFieldRef<Message>(m2, fd_map_int32_double)); + mmf_string_string.MergeFrom( + refl->GetRepeatedFieldRef<Message>(m2, fd_map_string_string)); + mmf_int32_foreign_message.MergeFrom( + refl->GetRepeatedFieldRef<Message>(m2, fd_map_int32_foreign_message)); + for (int i = 0; i < 10; ++i) { + EXPECT_EQ(Func(i, 21), m0.map_int32_int32().at(i + 20)); + EXPECT_EQ(Func(i, 22), m0.map_int32_double().at(i + 20)); + EXPECT_EQ(StrFunc(i, 25), m0.map_string_string().at(StrFunc(i + 20, 1))); + EXPECT_EQ(Func(i, 26), m0.map_int32_foreign_message().at(i + 20).c()); + } + + // Test MutableRepeatedRef::Swap + // Swap between m0 and m2. + mmf_int32_int32.Swap( + refl->GetMutableRepeatedFieldRef<Message>(&m2, fd_map_int32_int32)); + mmf_int32_double.Swap( + refl->GetMutableRepeatedFieldRef<Message>(&m2, fd_map_int32_double)); + mmf_string_string.Swap( + refl->GetMutableRepeatedFieldRef<Message>(&m2, fd_map_string_string)); + mmf_int32_foreign_message.Swap(refl->GetMutableRepeatedFieldRef<Message>( + &m2, fd_map_int32_foreign_message)); + for (int i = 0; i < 10; ++i) { + // Check the content of m0. + EXPECT_EQ(Func(i, 21), m0.map_int32_int32().at(i + 20)); + EXPECT_EQ(Func(i, 22), m0.map_int32_double().at(i + 20)); + EXPECT_EQ(StrFunc(i, 25), m0.map_string_string().at(StrFunc(i + 20, 1))); + EXPECT_EQ(Func(i, 26), m0.map_int32_foreign_message().at(i + 20).c()); + + // Check the content of m2. + EXPECT_EQ(Func(i, 11), m2.map_int32_int32().at(i + 10)); + EXPECT_EQ(Func(i, 12), m2.map_int32_double().at(i + 10)); + EXPECT_EQ(StrFunc(i, 15), m2.map_string_string().at(StrFunc(i + 10, 1))); + EXPECT_EQ(Func(i, 16), m2.map_int32_foreign_message().at(i + 10).c()); + EXPECT_EQ(Func(i, 21), m2.map_int32_int32().at(i + 20)); + EXPECT_EQ(Func(i, 22), m2.map_int32_double().at(i + 20)); + EXPECT_EQ(StrFunc(i, 25), m2.map_string_string().at(StrFunc(i + 20, 1))); + EXPECT_EQ(Func(i, 26), m2.map_int32_foreign_message().at(i + 20).c()); + } + + // TODO(teboring): add test for duplicated key +} + +TEST_F(MapFieldReflectionTest, MapSizeWithDuplicatedKey) { + // Dynamic Message + { + DynamicMessageFactory factory; + std::unique_ptr<Message> message( + factory.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + const Reflection* reflection = message->GetReflection(); + const FieldDescriptor* field = + UNITTEST::TestMap::descriptor()->FindFieldByName("map_int32_int32"); + + Message* entry1 = reflection->AddMessage(message.get(), field); + Message* entry2 = reflection->AddMessage(message.get(), field); + + const Reflection* entry_reflection = entry1->GetReflection(); + const FieldDescriptor* key_field = + entry1->GetDescriptor()->FindFieldByName("key"); + entry_reflection->SetInt32(entry1, key_field, 1); + entry_reflection->SetInt32(entry2, key_field, 1); + + EXPECT_EQ(2, reflection->FieldSize(*message, field)); + EXPECT_EQ(1, MapSize(reflection, field, *message)); + EXPECT_EQ(2, reflection->FieldSize(*message, field)); + } + + // Generated Message + { + UNITTEST::TestMap message; + const Reflection* reflection = message.GetReflection(); + const FieldDescriptor* field = + message.GetDescriptor()->FindFieldByName("map_int32_int32"); + + Message* entry1 = reflection->AddMessage(&message, field); + Message* entry2 = reflection->AddMessage(&message, field); + + const Reflection* entry_reflection = entry1->GetReflection(); + const FieldDescriptor* key_field = + entry1->GetDescriptor()->FindFieldByName("key"); + entry_reflection->SetInt32(entry1, key_field, 1); + entry_reflection->SetInt32(entry2, key_field, 1); + + EXPECT_EQ(2, reflection->FieldSize(message, field)); + EXPECT_EQ(1, MapSize(reflection, field, message)); + } +} + +TEST_F(MapFieldReflectionTest, UninitializedEntry) { + UNITTEST::TestRequiredMessageMap message; + const Reflection* reflection = message.GetReflection(); + const FieldDescriptor* field = + message.GetDescriptor()->FindFieldByName("map_field"); + auto entry = reflection->AddMessage(&message, field); + EXPECT_FALSE(entry->IsInitialized()); + EXPECT_FALSE(message.IsInitialized()); +} + +class MyMapEntry + : public internal::MapEntry<MyMapEntry, ::google::protobuf::int32, ::google::protobuf::int32, + internal::WireFormatLite::TYPE_INT32, + internal::WireFormatLite::TYPE_INT32> { + public: + constexpr MyMapEntry() {} + MyMapEntry(Arena*) { std::abort(); } + Metadata GetMetadata() const override { std::abort(); } + static bool ValidateKey(void*) { return true; } + static bool ValidateValue(void*) { return true; } +}; + +class MyMapEntryLite + : public internal::MapEntryLite<MyMapEntryLite, ::google::protobuf::int32, ::google::protobuf::int32, + internal::WireFormatLite::TYPE_INT32, + internal::WireFormatLite::TYPE_INT32> { + public: + constexpr MyMapEntryLite() {} + explicit MyMapEntryLite(Arena*) { std::abort(); } + static bool ValidateKey(void*) { return true; } + static bool ValidateValue(void*) { return true; } +}; + +TEST(MapEntryTest, ConstInit) { + // This verifies that `MapEntry`, `MapEntryLite` and `MapEntryImpl` can be + // constant initialized. + PROTOBUF_CONSTINIT static MyMapEntry entry{}; + EXPECT_NE(entry.SpaceUsed(), 0); + + PROTOBUF_CONSTINIT static MyMapEntryLite entry_lite{}; // NOLINT + EXPECT_TRUE(entry_lite.IsInitialized()); +} + +// Generated Message Test =========================================== + +TEST(GeneratedMapFieldTest, Accessors) { + UNITTEST::TestMap message; + + MapTestUtil::SetMapFields(&message); + MapTestUtil::ExpectMapFieldsSet(message); + + MapTestUtil::ModifyMapFields(&message); + MapTestUtil::ExpectMapFieldsModified(message); +} + +TEST(GeneratedMapFieldTest, SetMapFieldsInitialized) { + UNITTEST::TestMap message; + + MapTestUtil::SetMapFieldsInitialized(&message); + MapTestUtil::ExpectMapFieldsSetInitialized(message); +} + +TEST(GeneratedMapFieldTest, Proto2SetMapFieldsInitialized) { + UNITTEST::TestEnumMap message; + EXPECT_EQ(UNITTEST::PROTO2_MAP_ENUM_FOO, + (*message.mutable_known_map_field())[0]); +} + +TEST(GeneratedMapFieldTest, Clear) { + UNITTEST::TestMap message; + + MapTestUtil::SetMapFields(&message); + message.Clear(); + MapTestUtil::ExpectClear(message); +} + +TEST(GeneratedMapFieldTest, ClearMessageMap) { + UNITTEST::TestMessageMap message; + + // Creates a TestAllTypes with default value + TestUtil::ExpectClear((*message.mutable_map_int32_message())[0]); +} + +TEST(GeneratedMapFieldTest, CopyFrom) { + UNITTEST::TestMap message1, message2; + + MapTestUtil::SetMapFields(&message1); + message2.CopyFrom(message1); + MapTestUtil::ExpectMapFieldsSet(message2); + + // Copying from self should be a no-op. + message2.CopyFrom(message2); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +TEST(GeneratedMapFieldTest, CopyFromMessageMap) { + UNITTEST::TestMessageMap message1, message2; + + (*message1.mutable_map_int32_message())[0].add_repeated_int32(100); + (*message2.mutable_map_int32_message())[0].add_repeated_int32(101); + + message1.CopyFrom(message2); + + // Checks repeated field is overwritten. + EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size()); + EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0)); +} + +TEST(GeneratedMapFieldTest, SwapWithEmpty) { + UNITTEST::TestMap message1, message2; + + MapTestUtil::SetMapFields(&message1); + MapTestUtil::ExpectMapFieldsSet(message1); + MapTestUtil::ExpectClear(message2); + + message1.Swap(&message2); + MapTestUtil::ExpectMapFieldsSet(message2); + MapTestUtil::ExpectClear(message1); +} + +TEST(GeneratedMapFieldTest, SwapWithSelf) { + UNITTEST::TestMap message; + + MapTestUtil::SetMapFields(&message); + MapTestUtil::ExpectMapFieldsSet(message); + + message.Swap(&message); + MapTestUtil::ExpectMapFieldsSet(message); +} + +TEST(GeneratedMapFieldTest, SwapWithOther) { + UNITTEST::TestMap message1, message2; + + MapTestUtil::SetMapFields(&message1); + MapTestUtil::SetMapFields(&message2); + MapTestUtil::ModifyMapFields(&message2); + + message1.Swap(&message2); + MapTestUtil::ExpectMapFieldsModified(message1); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +TEST(GeneratedMapFieldTest, CopyConstructor) { + UNITTEST::TestMap message1; + MapTestUtil::SetMapFields(&message1); + + UNITTEST::TestMap message2(message1); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +TEST(GeneratedMapFieldTest, CopyAssignmentOperator) { + UNITTEST::TestMap message1; + MapTestUtil::SetMapFields(&message1); + + UNITTEST::TestMap message2; + message2 = message1; + MapTestUtil::ExpectMapFieldsSet(message2); + + // Make sure that self-assignment does something sane. + message2.operator=(message2); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || PROTOBUF_RTTI +TEST(GeneratedMapFieldTest, UpcastCopyFrom) { + // Test the CopyFrom method that takes in the generic const Message& + // parameter. + UNITTEST::TestMap message1, message2; + + MapTestUtil::SetMapFields(&message1); + + const Message* source = implicit_cast<const Message*>(&message1); + message2.CopyFrom(*source); + + MapTestUtil::ExpectMapFieldsSet(message2); +} +#endif + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + +TEST(GeneratedMapFieldTest, CopyFromDynamicMessage) { + // Test copying from a DynamicMessage, which must fall back to using + // reflection. + UNITTEST::TestMap message2; + + // Construct a new version of the dynamic message via the factory. + DynamicMessageFactory factory; + std::unique_ptr<Message> message1; + message1.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaReflection(message1.get()); + reflection_tester.ExpectMapFieldsSetViaReflection(*message1); + reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get()); + message2.CopyFrom(*message1); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +TEST(GeneratedMapFieldTest, CopyFromDynamicMessageMapReflection) { + UNITTEST::TestMap message2; + + // Construct a new version of the dynamic message via the factory. + DynamicMessageFactory factory; + std::unique_ptr<Message> message1; + message1.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaMapReflection(message1.get()); + reflection_tester.ExpectMapFieldsSetViaReflection(*message1); + reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get()); + message2.CopyFrom(*message1); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +TEST(GeneratedMapFieldTest, DynamicMessageMergeFromDynamicMessage) { + // Construct two dynamic message and sets via map reflection. + DynamicMessageFactory factory; + std::unique_ptr<Message> message1; + message1.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaMapReflection(message1.get()); + + // message2 is created by same factory. + std::unique_ptr<Message> message2; + message2.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + reflection_tester.SetMapFieldsViaMapReflection(message2.get()); + + // message3 is created by different factory. + DynamicMessageFactory factory3; + std::unique_ptr<Message> message3; + message3.reset(factory3.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + reflection_tester.SetMapFieldsViaMapReflection(message3.get()); + + message2->MergeFrom(*message1); + message3->MergeFrom(*message1); + + // Test MergeFrom does not sync to repeated fields and + // there is no duplicate keys in text format. + std::string output1, output2, output3; + TextFormat::PrintToString(*message1, &output1); + TextFormat::PrintToString(*message2, &output2); + TextFormat::PrintToString(*message3, &output3); + EXPECT_EQ(output1, output2); + EXPECT_EQ(output1, output3); +} + +TEST(GeneratedMapFieldTest, DynamicMessageCopyFrom) { + // Test copying to a DynamicMessage, which must fall back to using reflection. + UNITTEST::TestMap message2; + MapTestUtil::SetMapFields(&message2); + + // Construct a new version of the dynamic message via the factory. + DynamicMessageFactory factory; + std::unique_ptr<Message> message1; + message1.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + message1->MergeFrom(message2); + reflection_tester.ExpectMapFieldsSetViaReflection(*message1); + reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get()); +} + +TEST(GeneratedMapFieldTest, DynamicMessageCopyFromMapReflection) { + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + UNITTEST::TestMap message2; + reflection_tester.SetMapFieldsViaMapReflection(&message2); + + // Construct a dynamic message via the factory. + DynamicMessageFactory factory; + std::unique_ptr<Message> message1; + message1.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + + message1->MergeFrom(message2); + reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get()); + reflection_tester.ExpectMapFieldsSetViaReflection(*message1); +} + +TEST(GeneratedMapFieldTest, SyncDynamicMapWithRepeatedField) { + // Construct a dynamic message via the factory. + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + DynamicMessageFactory factory; + std::unique_ptr<Message> message; + message.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + reflection_tester.SetMapFieldsViaReflection(message.get()); + reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message.get()); + reflection_tester.ExpectMapFieldsSetViaReflection(*message); +} + +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS + +TEST(GeneratedMapFieldTest, NonEmptyMergeFrom) { + UNITTEST::TestMap message1, message2; + + MapTestUtil::SetMapFields(&message1); + + // This field will test merging into an empty spot. + (*message2.mutable_map_int32_int32())[1] = 1; + message1.mutable_map_int32_int32()->erase(1); + + // This tests overwriting. + (*message2.mutable_map_int32_double())[1] = 1; + (*message1.mutable_map_int32_double())[1] = 2; + + message1.MergeFrom(message2); + MapTestUtil::ExpectMapFieldsSet(message1); + + // Test reflection MergeFrom does not sync to repeated field + // and there is no duplicated keys. + MapTestUtil::SetMapFields(&message1); + MapTestUtil::SetMapFields(&message2); + + message2.MergeFrom(message1); + + std::string output1, output2; + TextFormat::PrintToString(message1, &output1); + TextFormat::PrintToString(message2, &output2); + EXPECT_EQ(output1, output2); +} + +TEST(GeneratedMapFieldTest, MergeFromMessageMap) { + UNITTEST::TestMessageMap message1, message2; + + (*message1.mutable_map_int32_message())[0].add_repeated_int32(100); + (*message2.mutable_map_int32_message())[0].add_repeated_int32(101); + + message1.MergeFrom(message2); + + // Checks repeated field is overwritten. + EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size()); + EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0)); +} + +// Test the generated SerializeWithCachedSizesToArray() +TEST(GeneratedMapFieldTest, SerializationToArray) { + UNITTEST::TestMap message1, message2; + std::string data; + MapTestUtil::SetMapFields(&message1); + size_t size = message1.ByteSizeLong(); + data.resize(size); + uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data)); + uint8* end = message1.SerializeWithCachedSizesToArray(start); + EXPECT_EQ(size, end - start); + EXPECT_TRUE(message2.ParseFromString(data)); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +// Test the generated SerializeWithCachedSizes() +TEST(GeneratedMapFieldTest, SerializationToStream) { + UNITTEST::TestMap message1, message2; + MapTestUtil::SetMapFields(&message1); + size_t size = message1.ByteSizeLong(); + std::string data; + data.resize(size); + { + // Allow the output stream to buffer only one byte at a time. + io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message1.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + EXPECT_TRUE(message2.ParseFromString(data)); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +TEST(GeneratedMapFieldTest, ParseFailsIfMalformed) { + UNITTEST::TestMapSubmessage o, p; + auto m = o.mutable_test_map()->mutable_map_int32_foreign_message(); + (*m)[0].set_c(-1); + std::string serialized; + EXPECT_TRUE(o.SerializeToString(&serialized)); + + // Should parse correctly. + EXPECT_TRUE(p.ParseFromString(serialized)); + + // Overwriting the last byte to 0xFF results in malformed wire. + serialized[serialized.size() - 1] = 0xFF; + EXPECT_FALSE(p.ParseFromString(serialized)); +} + + +TEST(GeneratedMapFieldTest, SameTypeMaps) { + const Descriptor* map1 = UNITTEST::TestSameTypeMap::descriptor() + ->FindFieldByName("map1") + ->message_type(); + const Descriptor* map2 = UNITTEST::TestSameTypeMap::descriptor() + ->FindFieldByName("map2") + ->message_type(); + + const Message* map1_entry = + MessageFactory::generated_factory()->GetPrototype(map1); + const Message* map2_entry = + MessageFactory::generated_factory()->GetPrototype(map2); + + EXPECT_EQ(map1, map1_entry->GetDescriptor()); + EXPECT_EQ(map2, map2_entry->GetDescriptor()); +} + +TEST(GeneratedMapFieldTest, Proto2UnknownEnum) { + UNITTEST::TestEnumMapPlusExtra from; + (*from.mutable_known_map_field())[0] = UNITTEST::E_PROTO2_MAP_ENUM_FOO; + (*from.mutable_unknown_map_field())[0] = UNITTEST::E_PROTO2_MAP_ENUM_EXTRA; + std::string data; + from.SerializeToString(&data); + + UNITTEST::TestEnumMap to; + EXPECT_TRUE(to.ParseFromString(data)); + EXPECT_EQ(0, to.unknown_map_field().size()); + const UnknownFieldSet& unknown_field_set = + to.GetReflection()->GetUnknownFields(to); + EXPECT_EQ(1, unknown_field_set.field_count()); + EXPECT_EQ(1, to.known_map_field().size()); + EXPECT_EQ(UNITTEST::PROTO2_MAP_ENUM_FOO, to.known_map_field().at(0)); + + data.clear(); + from.Clear(); + to.SerializeToString(&data); + EXPECT_TRUE(from.ParseFromString(data)); + EXPECT_EQ(0, from.GetReflection()->GetUnknownFields(from).field_count()); + EXPECT_EQ(1, from.known_map_field().size()); + EXPECT_EQ(UNITTEST::E_PROTO2_MAP_ENUM_FOO, from.known_map_field().at(0)); + EXPECT_EQ(1, from.unknown_map_field().size()); + EXPECT_EQ(UNITTEST::E_PROTO2_MAP_ENUM_EXTRA, from.unknown_map_field().at(0)); +} + +TEST(GeneratedMapFieldTest, StandardWireFormat) { + UNITTEST::TestMap message; + std::string data = "\x0A\x04\x08\x01\x10\x01"; + + EXPECT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(1, message.map_int32_int32().size()); + EXPECT_EQ(1, message.map_int32_int32().at(1)); +} + +TEST(GeneratedMapFieldTest, UnorderedWireFormat) { + UNITTEST::TestMap message; + + // put value before key in wire format + std::string data = "\x0A\x04\x10\x01\x08\x02"; + + EXPECT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(1, message.map_int32_int32().size()); + ASSERT_NE(message.map_int32_int32().find(2), message.map_int32_int32().end()); + EXPECT_EQ(1, message.map_int32_int32().at(2)); +} + +TEST(GeneratedMapFieldTest, DuplicatedKeyWireFormat) { + UNITTEST::TestMap message; + + // Two key fields in wire format + std::string data = "\x0A\x06\x08\x01\x08\x02\x10\x01"; + + EXPECT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(1, message.map_int32_int32().size()); + EXPECT_EQ(1, message.map_int32_int32().at(2)); + + // A similar test, but with a map from int to a message type. + // Again, we want to be sure that the "second one wins" when + // there are two separate entries with the same key. + const int key = 99; + UNITTEST::TestRequiredMessageMap map_message; + UNITTEST::TestRequired with_dummy4; + with_dummy4.set_a(0); + with_dummy4.set_b(0); + with_dummy4.set_c(0); + with_dummy4.set_dummy4(11); + (*map_message.mutable_map_field())[key] = with_dummy4; + std::string s = map_message.SerializeAsString(); + UNITTEST::TestRequired with_dummy5; + with_dummy5.set_a(0); + with_dummy5.set_b(0); + with_dummy5.set_c(0); + with_dummy5.set_dummy5(12); + (*map_message.mutable_map_field())[key] = with_dummy5; + std::string both = s + map_message.SerializeAsString(); + // We don't expect a merge now. The "second one wins." + ASSERT_TRUE(map_message.ParseFromString(both)); + ASSERT_EQ(1, map_message.map_field().size()); + ASSERT_EQ(1, map_message.map_field().count(key)); + EXPECT_EQ(0, map_message.map_field().find(key)->second.a()); + EXPECT_EQ(0, map_message.map_field().find(key)->second.b()); + EXPECT_EQ(0, map_message.map_field().find(key)->second.c()); + EXPECT_FALSE(map_message.map_field().find(key)->second.has_dummy4()); + ASSERT_TRUE(map_message.map_field().find(key)->second.has_dummy5()); + EXPECT_EQ(12, map_message.map_field().find(key)->second.dummy5()); +} + +// Exhaustive combinations of keys, values, and junk in any order. +// This re-tests some of the things tested above, but if it fails +// it's more work to determine what went wrong, so it isn't necessarily +// bad that we have the simpler tests too. +TEST(GeneratedMapFieldTest, KeysValuesUnknownsWireFormat) { + UNITTEST::TestMap message; + const int kMaxNumKeysAndValuesAndJunk = 4; + const char kKeyTag = 0x08; + const char kValueTag = 0x10; + const char kJunkTag = 0x20; + for (int items = 0; items <= kMaxNumKeysAndValuesAndJunk; items++) { + std::string data = "\x0A"; + // Encode length of what will follow. + data.push_back(items * 2); + static const int kBitsOfIPerItem = 4; + static const int mask = (1 << kBitsOfIPerItem) - 1; + // Each iteration of the following is a test. It uses i as bit vector + // encoding the keys and values to put in the wire format. + for (int i = 0; i < (1 << (items * kBitsOfIPerItem)); i++) { + std::string wire_format = data; + int expected_key = 0; + int expected_value = 0; + for (int k = i, j = 0; j < items; j++, k >>= kBitsOfIPerItem) { + bool is_key = k & 0x1; + bool is_value = !is_key && (k & 0x2); + wire_format.push_back(is_key ? kKeyTag + : is_value ? kValueTag : kJunkTag); + char c = static_cast<char>(k & mask) >> 2; // One char after the tag. + wire_format.push_back(c); + if (is_key) expected_key = static_cast<int>(c); + if (is_value) expected_value = static_cast<int>(c); + bool res = message.ParseFromString(wire_format); + bool expect_success = true; + // Unfortunately the old map parser accepts malformed input, the new + // parser accepts only correct input. + if (j != items - 1) expect_success = false; + if (expect_success) { + ASSERT_TRUE(res); + ASSERT_EQ(1, message.map_int32_int32().size()); + ASSERT_EQ(expected_key, message.map_int32_int32().begin()->first); + ASSERT_EQ(expected_value, message.map_int32_int32().begin()->second); + } else { + ASSERT_FALSE(res); + } + } + } + } +} + +TEST(GeneratedMapFieldTest, DuplicatedValueWireFormat) { + UNITTEST::TestMap message; + + // Two value fields in wire format + std::string data = "\x0A\x06\x08\x01\x10\x01\x10\x02"; + + EXPECT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(1, message.map_int32_int32().size()); + EXPECT_EQ(2, message.map_int32_int32().at(1)); +} + +TEST(GeneratedMapFieldTest, MissedKeyWireFormat) { + UNITTEST::TestMap message; + + // No key field in wire format + std::string data = "\x0A\x02\x10\x01"; + + EXPECT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(1, message.map_int32_int32().size()); + ASSERT_NE(message.map_int32_int32().find(0), message.map_int32_int32().end()); + EXPECT_EQ(1, message.map_int32_int32().at(0)); +} + +TEST(GeneratedMapFieldTest, MissedValueWireFormat) { + UNITTEST::TestMap message; + + // No value field in wire format + std::string data = "\x0A\x02\x08\x01"; + + EXPECT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(1, message.map_int32_int32().size()); + ASSERT_NE(message.map_int32_int32().find(1), message.map_int32_int32().end()); + EXPECT_EQ(0, message.map_int32_int32().at(1)); +} + +TEST(GeneratedMapFieldTest, MissedValueTextFormat) { + UNITTEST::TestMap message; + + // No value field in text format + std::string text = + "map_int32_foreign_message {\n" + " key: 1234567890\n" + "}"; + + EXPECT_TRUE(TextFormat::ParseFromString(text, &message)); + EXPECT_EQ(1, message.map_int32_foreign_message().size()); + EXPECT_EQ(11, message.ByteSizeLong()); +} + +TEST(GeneratedMapFieldTest, UnknownFieldWireFormat) { + UNITTEST::TestMap message; + + // Unknown field in wire format + std::string data = "\x0A\x06\x08\x02\x10\x03\x18\x01"; + + EXPECT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(1, message.map_int32_int32().size()); + EXPECT_EQ(3, message.map_int32_int32().at(2)); +} + +TEST(GeneratedMapFieldTest, CorruptedWireFormat) { + UNITTEST::TestMap message; + + // corrupted data in wire format + std::string data = "\x0A\x06\x08\x02\x11\x03"; + + EXPECT_FALSE(message.ParseFromString(data)); +} + +TEST(GeneratedMapFieldTest, IsInitialized) { + UNITTEST::TestRequiredMessageMap map_message; + + // Add an uninitialized message. + (*map_message.mutable_map_field())[0]; + EXPECT_FALSE(map_message.IsInitialized()); + + // Initialize uninitialized message + (*map_message.mutable_map_field())[0].set_a(0); + (*map_message.mutable_map_field())[0].set_b(0); + (*map_message.mutable_map_field())[0].set_c(0); + EXPECT_TRUE(map_message.IsInitialized()); +} + +TEST(GeneratedMapFieldTest, SpaceUsed) { + UNITTEST::TestRequiredMessageMap map_message; + const size_t initial = map_message.SpaceUsed(); + const size_t space_used_message = UNITTEST::TestRequired().SpaceUsed(); + + auto& m = *map_message.mutable_map_field(); + constexpr int kNumValues = 100; + for (int i = 0; i < kNumValues; ++i) { + m[i]; + } + + // The exact value will depend on internal state, like collisions, + // so we can't predict it. But we can predict a lower bound. + size_t lower_bound = + initial + kNumValues * (space_used_message + sizeof(int32) + + /* Node::next */ sizeof(void*) + + /* table entry */ sizeof(void*)); + + EXPECT_LE(lower_bound, map_message.SpaceUsed()); +} + +TEST(GeneratedMapFieldTest, MessagesMustMerge) { + UNITTEST::TestRequiredMessageMap map_message; + + UNITTEST::TestRequired with_dummy4; + with_dummy4.set_a(97); + with_dummy4.set_b(91); + with_dummy4.set_dummy4(98); + EXPECT_FALSE(with_dummy4.IsInitialized()); + (*map_message.mutable_map_field())[0] = with_dummy4; + EXPECT_FALSE(map_message.IsInitialized()); + + UNITTEST::TestRequired with_dummy5; + with_dummy5.set_b(0); + with_dummy5.set_c(33); + with_dummy5.set_dummy5(99); + EXPECT_FALSE(with_dummy5.IsInitialized()); + (*map_message.mutable_map_field())[0] = with_dummy5; + EXPECT_FALSE(map_message.IsInitialized()); + + // The wire format of MapEntry is straightforward (*) and can be manually + // constructed to force merging of two uninitialized messages that would + // result in an initialized message. + // + // (*) http://google3/net/proto2/internal/map_test.cc?l=2433&rcl=310012028 + std::string dummy4_s = with_dummy4.SerializePartialAsString(); + std::string dummy5_s = with_dummy5.SerializePartialAsString(); + int payload_size = dummy4_s.size() + dummy5_s.size(); + // Makes sure the payload size fits into one byte. + ASSERT_LT(payload_size, 128); + + std::string s(6, 0); + char* p = &s[0]; + *p++ = WireFormatLite::MakeTag(1, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + // Length: 2B for key tag & val and 2B for val tag and length of the following + // payload. + *p++ = 4 + payload_size; + *p++ = WireFormatLite::MakeTag(1, WireFormatLite::WIRETYPE_VARINT); + *p++ = 0; + *p++ = WireFormatLite::MakeTag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + *p++ = payload_size; + StrAppend(&s, dummy4_s, dummy5_s); + + // Test key then value then value. + int key = 0; + ASSERT_TRUE(map_message.ParseFromString(s)); + ASSERT_EQ(1, map_message.map_field().size()); + ASSERT_EQ(1, map_message.map_field().count(key)); + EXPECT_EQ(97, map_message.map_field().find(key)->second.a()); + EXPECT_EQ(0, map_message.map_field().find(key)->second.b()); + EXPECT_EQ(33, map_message.map_field().find(key)->second.c()); + EXPECT_EQ(98, map_message.map_field().find(key)->second.dummy4()); + EXPECT_EQ(99, map_message.map_field().find(key)->second.dummy5()); + + // Test key then value then value then key. + s.push_back(s[2]); // Copy the key's tag. + key = 19; + s.push_back(key); // Second key is 19 instead of 0. + s[1] += 2; // Adjust encoded size. + ASSERT_TRUE(map_message.ParseFromString(s)); + ASSERT_EQ(1, map_message.map_field().size()); + ASSERT_EQ(1, map_message.map_field().count(key)); + EXPECT_EQ(97, map_message.map_field().find(key)->second.a()); + EXPECT_EQ(0, map_message.map_field().find(key)->second.b()); + EXPECT_EQ(33, map_message.map_field().find(key)->second.c()); + EXPECT_EQ(98, map_message.map_field().find(key)->second.dummy4()); + EXPECT_EQ(99, map_message.map_field().find(key)->second.dummy5()); +} + +// Generated Message Reflection Test ================================ + +TEST(GeneratedMapFieldReflectionTest, SpaceUsed) { + UNITTEST::TestMap message; + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaReflection(&message); + + EXPECT_LT(0, message.GetReflection()->SpaceUsedLong(message)); +} + +TEST(GeneratedMapFieldReflectionTest, Accessors) { + // Set every field to a unique value then go back and check all those + // values. + UNITTEST::TestMap message; + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaReflection(&message); + MapTestUtil::ExpectMapFieldsSet(message); + reflection_tester.ExpectMapFieldsSetViaReflection(message); + reflection_tester.ExpectMapFieldsSetViaReflectionIterator(&message); + + reflection_tester.ModifyMapFieldsViaReflection(&message); + MapTestUtil::ExpectMapFieldsModified(message); +} + +TEST(GeneratedMapFieldReflectionTest, Swap) { + UNITTEST::TestMap message1; + UNITTEST::TestMap message2; + + MapTestUtil::SetMapFields(&message1); + + const Reflection* reflection = message1.GetReflection(); + reflection->Swap(&message1, &message2); + + MapTestUtil::ExpectClear(message1); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +TEST(GeneratedMapFieldReflectionTest, SwapWithBothSet) { + UNITTEST::TestMap message1; + UNITTEST::TestMap message2; + + MapTestUtil::SetMapFields(&message1); + MapTestUtil::SetMapFields(&message2); + MapTestUtil::ModifyMapFields(&message2); + + const Reflection* reflection = message1.GetReflection(); + reflection->Swap(&message1, &message2); + + MapTestUtil::ExpectMapFieldsModified(message1); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +TEST(GeneratedMapFieldReflectionTest, SwapFields) { + UNITTEST::TestMap message1; + UNITTEST::TestMap message2; + + MapTestUtil::SetMapFields(&message2); + + std::vector<const FieldDescriptor*> fields; + const Reflection* reflection = message1.GetReflection(); + reflection->ListFields(message2, &fields); + reflection->SwapFields(&message1, &message2, fields); + + MapTestUtil::ExpectMapFieldsSet(message1); + MapTestUtil::ExpectClear(message2); +} + +TEST(GeneratedMapFieldReflectionTest, ClearField) { + UNITTEST::TestMap message; + MapTestUtil::SetMapFields(&message); + MapTestUtil::ExpectMapFieldsSet(message); + + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.ClearMapFieldsViaReflection(&message); + reflection_tester.ExpectClearViaReflection(message); + reflection_tester.ExpectClearViaReflectionIterator(&message); +} + +TEST(GeneratedMapFieldReflectionTest, RemoveLast) { + UNITTEST::TestMap message; + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + + MapTestUtil::SetMapFields(&message); + MapTestUtil::ExpectMapsSize(message, 2); + std::vector<const Message*> expected_entries = + MapTestUtil::GetMapEntries(message, 0); + + reflection_tester.RemoveLastMapsViaReflection(&message); + + MapTestUtil::ExpectMapsSize(message, 1); + std::vector<const Message*> remained_entries = + MapTestUtil::GetMapEntries(message, 0); + EXPECT_TRUE(expected_entries == remained_entries); +} + +TEST(GeneratedMapFieldReflectionTest, ReleaseLast) { + UNITTEST::TestMap message; + const Descriptor* descriptor = message.GetDescriptor(); + MapReflectionTester reflection_tester(descriptor); + + MapTestUtil::SetMapFields(&message); + + MapTestUtil::ExpectMapsSize(message, 2); + + reflection_tester.ReleaseLastMapsViaReflection(&message); + + MapTestUtil::ExpectMapsSize(message, 1); + + // Now test that we actually release the right message. + message.Clear(); + MapTestUtil::SetMapFields(&message); + + MapTestUtil::ExpectMapsSize(message, 2); + std::vector<const Message*> expect_last = + MapTestUtil::GetMapEntries(message, 1); + std::vector<const Message*> release_last = + MapTestUtil::GetMapEntriesFromRelease(&message); + MapTestUtil::ExpectMapsSize(message, 1); + EXPECT_TRUE(expect_last == release_last); + for (std::vector<const Message*>::iterator it = release_last.begin(); + it != release_last.end(); ++it) { + delete *it; + } +} + +TEST(GeneratedMapFieldReflectionTest, SwapElements) { + UNITTEST::TestMap message; + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + + MapTestUtil::SetMapFields(&message); + + // Get pointers of map entries at their original position + std::vector<const Message*> entries0 = MapTestUtil::GetMapEntries(message, 0); + std::vector<const Message*> entries1 = MapTestUtil::GetMapEntries(message, 1); + + // Swap the first time. + reflection_tester.SwapMapsViaReflection(&message); + + // Get pointer of map entry after swap once. + std::vector<const Message*> entries0_once = + MapTestUtil::GetMapEntries(message, 0); + std::vector<const Message*> entries1_once = + MapTestUtil::GetMapEntries(message, 1); + + // Test map entries are swapped. + MapTestUtil::ExpectMapsSize(message, 2); + EXPECT_TRUE(entries0 == entries1_once); + EXPECT_TRUE(entries1 == entries0_once); + + // Swap the second time. + reflection_tester.SwapMapsViaReflection(&message); + + // Get pointer of map entry after swap once. + std::vector<const Message*> entries0_twice = + MapTestUtil::GetMapEntries(message, 0); + std::vector<const Message*> entries1_twice = + MapTestUtil::GetMapEntries(message, 1); + + // Test map entries are swapped back. + MapTestUtil::ExpectMapsSize(message, 2); + EXPECT_TRUE(entries0 == entries0_twice); + EXPECT_TRUE(entries1 == entries1_twice); +} + +TEST(GeneratedMapFieldReflectionTest, MutableUnknownFields) { + UNITTEST::TestMap message; + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.MutableUnknownFieldsOfMapFieldsViaReflection(&message); +} + +TEST(GeneratedMapFieldReflectionTest, EmbedProto2Message) { + UNITTEST::TestMessageMap message; + + const FieldDescriptor* map_field = + UNITTEST::TestMessageMap::descriptor()->FindFieldByName( + "map_int32_message"); + const FieldDescriptor* value = + map_field->message_type()->FindFieldByName("value"); + + Message* entry_message = + message.GetReflection()->AddMessage(&message, map_field); + EXPECT_EQ( + &entry_message->GetReflection()->GetMessage(*entry_message, value), + reinterpret_cast<const Message*>(&TestAllTypes::default_instance())); + + Message* proto2_message = + entry_message->GetReflection()->MutableMessage(entry_message, value); + EXPECT_EQ(UNITTEST::TestAllTypes::descriptor(), + proto2_message->GetDescriptor()); + ASSERT_EQ(1, message.map_int32_message().size()); +} + +TEST(GeneratedMapFieldReflectionTest, MergeFromClearMapEntry) { + UNITTEST::TestMap message; + const FieldDescriptor* map_field = + UNITTEST::TestMap::descriptor()->FindFieldByName("map_int32_int32"); + const FieldDescriptor* key = + map_field->message_type()->FindFieldByName("key"); + const FieldDescriptor* value = + map_field->message_type()->FindFieldByName("value"); + + Message* entry_message1 = + message.GetReflection()->AddMessage(&message, map_field); + EXPECT_FALSE(entry_message1->GetReflection()->HasField(*entry_message1, key)); + EXPECT_FALSE( + entry_message1->GetReflection()->HasField(*entry_message1, value)); + + Message* entry_message2 = + message.GetReflection()->AddMessage(&message, map_field); + EXPECT_FALSE(entry_message2->GetReflection()->HasField(*entry_message2, key)); + EXPECT_FALSE( + entry_message2->GetReflection()->HasField(*entry_message2, value)); + + entry_message1->MergeFrom(*entry_message2); + EXPECT_FALSE(entry_message1->GetReflection()->HasField(*entry_message1, key)); + EXPECT_FALSE( + entry_message1->GetReflection()->HasField(*entry_message1, value)); +} + +TEST(GeneratedMapFieldReflectionTest, MapEntryClear) { + UNITTEST::TestMap message; + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.MutableUnknownFieldsOfMapFieldsViaReflection(&message); +} + +TEST(GeneratedMapFieldReflectionTest, Proto2MapEntryClear) { + UNITTEST::TestEnumMap message; + const Descriptor* descriptor = message.GetDescriptor(); + const FieldDescriptor* field_descriptor = + descriptor->FindFieldByName("known_map_field"); + const FieldDescriptor* value_descriptor = + field_descriptor->message_type()->FindFieldByName("value"); + Message* sub_message = + message.GetReflection()->AddMessage(&message, field_descriptor); + EXPECT_EQ(0, sub_message->GetReflection()->GetEnumValue(*sub_message, + value_descriptor)); +} + +// Map Reflection API Test ========================================= + +TEST(GeneratedMapFieldReflectionTest, SetViaMapReflection) { + UNITTEST::TestMap message; + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaMapReflection(&message); + reflection_tester.ExpectMapFieldsSetViaReflection(message); + reflection_tester.ExpectMapFieldsSetViaReflectionIterator(&message); +} + +// Dynamic Message Test ============================================= + +class MapFieldInDynamicMessageTest : public testing::Test { + protected: + const DescriptorPool* pool_; + DynamicMessageFactory factory_; + const Descriptor* map_descriptor_; + const Descriptor* recursive_map_descriptor_; + const Message* map_prototype_; + + MapFieldInDynamicMessageTest() + : pool_(DescriptorPool::generated_pool()), factory_(pool_) {} + + virtual void SetUp() { + map_descriptor_ = pool_->FindMessageTypeByName( + std::string(UNITTEST_PACKAGE_NAME) + ".TestMap"); + recursive_map_descriptor_ = pool_->FindMessageTypeByName( + std::string(UNITTEST_PACKAGE_NAME) + ".TestRecursiveMapMessage"); + ASSERT_TRUE(map_descriptor_ != NULL); + ASSERT_TRUE(recursive_map_descriptor_ != NULL); + map_prototype_ = factory_.GetPrototype(map_descriptor_); + } +}; + +TEST_F(MapFieldInDynamicMessageTest, MapIndependentOffsets) { + // Check that all fields have independent offsets by setting each + // one to a unique value then checking that they all still have those + // unique values (i.e. they don't stomp each other). + std::unique_ptr<Message> message(map_prototype_->New()); + MapReflectionTester reflection_tester(map_descriptor_); + + reflection_tester.SetMapFieldsViaReflection(message.get()); + reflection_tester.ExpectMapFieldsSetViaReflection(*message); +} + +TEST_F(MapFieldInDynamicMessageTest, DynamicMapReflection) { + // Check that map fields work properly. + std::unique_ptr<Message> message(map_prototype_->New()); + + // Check set functions. + MapReflectionTester reflection_tester(map_descriptor_); + reflection_tester.SetMapFieldsViaMapReflection(message.get()); + reflection_tester.ExpectMapFieldsSetViaReflection(*message); +} + +TEST_F(MapFieldInDynamicMessageTest, MapSpaceUsed) { + // Test that SpaceUsedLong() works properly + + // Since we share the implementation with generated messages, we don't need + // to test very much here. Just make sure it appears to be working. + + std::unique_ptr<Message> message(map_prototype_->New()); + MapReflectionTester reflection_tester(map_descriptor_); + + int initial_space_used = message->SpaceUsedLong(); + + reflection_tester.SetMapFieldsViaReflection(message.get()); + EXPECT_LT(initial_space_used, message->SpaceUsedLong()); +} + +TEST_F(MapFieldInDynamicMessageTest, RecursiveMap) { + TestRecursiveMapMessage from; + (*from.mutable_a())[""]; + std::string data = from.SerializeAsString(); + std::unique_ptr<Message> to( + factory_.GetPrototype(recursive_map_descriptor_)->New()); + ASSERT_TRUE(to->ParseFromString(data)); +} + +TEST_F(MapFieldInDynamicMessageTest, MapValueReferernceValidAfterSerialize) { + std::unique_ptr<Message> message(map_prototype_->New()); + MapReflectionTester reflection_tester(map_descriptor_); + reflection_tester.SetMapFieldsViaMapReflection(message.get()); + + // Get value reference before serialization, so that we know the value is from + // map. + MapKey map_key; + MapValueRef map_val; + map_key.SetInt32Value(0); + reflection_tester.GetMapValueViaMapReflection( + message.get(), "map_int32_foreign_message", map_key, &map_val); + Message* submsg = map_val.MutableMessageValue(); + + // In previous implementation, calling SerializeToString will cause syncing + // from map to repeated field, which will invalidate the submsg we previously + // got. + std::string data; + message->SerializeToString(&data); + + const Reflection* submsg_reflection = submsg->GetReflection(); + const Descriptor* submsg_desc = submsg->GetDescriptor(); + const FieldDescriptor* submsg_field = submsg_desc->FindFieldByName("c"); + submsg_reflection->SetInt32(submsg, submsg_field, 128); + + message->SerializeToString(&data); + TestMap to; + to.ParseFromString(data); + EXPECT_EQ(128, to.map_int32_foreign_message().at(0).c()); +} + +TEST_F(MapFieldInDynamicMessageTest, MapEntryReferernceValidAfterSerialize) { + std::unique_ptr<Message> message(map_prototype_->New()); + MapReflectionTester reflection_tester(map_descriptor_); + reflection_tester.SetMapFieldsViaReflection(message.get()); + + // Get map entry before serialization, so that we know the it is from + // repeated field. + Message* map_entry = reflection_tester.GetMapEntryViaReflection( + message.get(), "map_int32_foreign_message", 0); + const Reflection* map_entry_reflection = map_entry->GetReflection(); + const Descriptor* map_entry_desc = map_entry->GetDescriptor(); + const FieldDescriptor* value_field = map_entry_desc->FindFieldByName("value"); + Message* submsg = + map_entry_reflection->MutableMessage(map_entry, value_field); + + // In previous implementation, calling SerializeToString will cause syncing + // from repeated field to map, which will invalidate the map_entry we + // previously got. + std::string data; + message->SerializeToString(&data); + + const Reflection* submsg_reflection = submsg->GetReflection(); + const Descriptor* submsg_desc = submsg->GetDescriptor(); + const FieldDescriptor* submsg_field = submsg_desc->FindFieldByName("c"); + submsg_reflection->SetInt32(submsg, submsg_field, 128); + + message->SerializeToString(&data); + TestMap to; + to.ParseFromString(data); + EXPECT_EQ(128, to.map_int32_foreign_message().at(0).c()); +} + +// ReflectionOps Test =============================================== + +TEST(ReflectionOpsForMapFieldTest, MapSanityCheck) { + UNITTEST::TestMap message; + + MapTestUtil::SetMapFields(&message); + MapTestUtil::ExpectMapFieldsSet(message); +} + +TEST(ReflectionOpsForMapFieldTest, MapCopy) { + UNITTEST::TestMap message, message2; + + MapTestUtil::SetMapFields(&message); + + ReflectionOps::Copy(message, &message2); + + MapTestUtil::ExpectMapFieldsSet(message2); + + // Copying from self should be a no-op. + ReflectionOps::Copy(message2, &message2); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +TEST(ReflectionOpsForMapFieldTest, MergeMap) { + // Note: Copy is implemented in terms of Merge() so technically the Copy + // test already tested most of this. + + UNITTEST::TestMap message, message2; + + MapTestUtil::SetMapFields(&message); + + ReflectionOps::Merge(message2, &message); + + MapTestUtil::ExpectMapFieldsSet(message); +} + +TEST(ReflectionOpsForMapFieldTest, ClearMap) { + UNITTEST::TestMap message; + + MapTestUtil::SetMapFields(&message); + + ReflectionOps::Clear(&message); + + MapTestUtil::ExpectClear(message); +} + +TEST(ReflectionOpsForMapFieldTest, MapDiscardUnknownFields) { + UNITTEST::TestMap message; + MapTestUtil::SetMapFields(&message); + + // Set some unknown fields in message. + message.GetReflection()->MutableUnknownFields(&message)->AddVarint(123456, + 654321); + + // Discard them. + ReflectionOps::DiscardUnknownFields(&message); + MapTestUtil::ExpectMapFieldsSet(message); + + EXPECT_EQ(0, + message.GetReflection()->GetUnknownFields(message).field_count()); +} + +TEST(ReflectionOpsForMapFieldTest, IsInitialized) { + UNITTEST::TestRequiredMessageMap map_message; + + // Add an uninitialized message. + (*map_message.mutable_map_field())[0]; + EXPECT_FALSE(ReflectionOps::IsInitialized(map_message)); + + // Initialize uninitialized message + (*map_message.mutable_map_field())[0].set_a(0); + (*map_message.mutable_map_field())[0].set_b(0); + (*map_message.mutable_map_field())[0].set_c(0); + EXPECT_TRUE(ReflectionOps::IsInitialized(map_message)); +} + +// Wire Format Test ================================================= + +TEST(WireFormatForMapFieldTest, ParseMap) { + UNITTEST::TestMap source, dest; + std::string data; + + // Serialize using the generated code. + MapTestUtil::SetMapFields(&source); + source.SerializeToString(&data); + + // Parse using WireFormat. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + MapTestUtil::ExpectMapFieldsSet(dest); +} + +TEST(WireFormatForMapFieldTest, MapByteSize) { + UNITTEST::TestMap message; + MapTestUtil::SetMapFields(&message); + + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); + message.Clear(); + EXPECT_EQ(0, message.ByteSizeLong()); + EXPECT_EQ(0, WireFormat::ByteSize(message)); +} + +TEST(WireFormatForMapFieldTest, SerializeMap) { + UNITTEST::TestMap message; + std::string generated_data; + std::string dynamic_data; + + MapTestUtil::SetMapFields(&message); + + // Serialize using the generated code. + { + message.ByteSizeLong(); + io::StringOutputStream raw_output(&generated_data); + io::CodedOutputStream output(&raw_output); + message.SerializeWithCachedSizes(&output); + ASSERT_FALSE(output.HadError()); + } + + // Serialize using WireFormat. + { + io::StringOutputStream raw_output(&dynamic_data); + io::CodedOutputStream output(&raw_output); + size_t size = WireFormat::ByteSize(message); + WireFormat::SerializeWithCachedSizes(message, size, &output); + ASSERT_FALSE(output.HadError()); + } + + // Should parse to the same message. + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); +} + +TEST(WireFormatForMapFieldTest, SerializeMapDynamicMessage) { + DynamicMessageFactory factory; + std::unique_ptr<Message> dynamic_message; + dynamic_message.reset( + factory.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaReflection(dynamic_message.get()); + reflection_tester.ExpectMapFieldsSetViaReflection(*dynamic_message); + + UNITTEST::TestMap generated_message; + MapTestUtil::SetMapFields(&generated_message); + MapTestUtil::ExpectMapFieldsSet(generated_message); + + std::string generated_data; + std::string dynamic_data; + + // Serialize. + generated_message.SerializeToString(&generated_data); + dynamic_message->SerializeToString(&dynamic_data); + + // Because map serialization doesn't guarantee order, we just compare + // serialized size here. This is enough to tell dynamic message doesn't miss + // anything in serialization. + EXPECT_TRUE(dynamic_data.size() == generated_data.size()); +} + +TEST(WireFormatForMapFieldTest, MapByteSizeDynamicMessage) { + DynamicMessageFactory factory; + std::unique_ptr<Message> dynamic_message; + dynamic_message.reset( + factory.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaReflection(dynamic_message.get()); + reflection_tester.ExpectMapFieldsSetViaReflection(*dynamic_message); + std::string expected_serialized_data; + dynamic_message->SerializeToString(&expected_serialized_data); + int expected_size = expected_serialized_data.size(); + EXPECT_EQ(dynamic_message->ByteSizeLong(), expected_size); + TestMap expected_message; + expected_message.ParseFromString(expected_serialized_data); + + std::unique_ptr<Message> message2; + message2.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New()); + reflection_tester.SetMapFieldsViaMapReflection(message2.get()); + + const FieldDescriptor* field = + UNITTEST::TestMap::descriptor()->FindFieldByName("map_int32_int32"); + const Reflection* reflection = dynamic_message->GetReflection(); + + // Force the map field to mark with STATE_MODIFIED_REPEATED + reflection->RemoveLast(dynamic_message.get(), field); + dynamic_message->MergeFrom(*message2); + dynamic_message->MergeFrom(*message2); + // The map field is marked as STATE_MODIFIED_REPEATED, ByteSizeLong() will use + // repeated field which have duplicate keys to calculate. + size_t duplicate_size = dynamic_message->ByteSizeLong(); + EXPECT_TRUE(duplicate_size > expected_size); + std::string duplicate_serialized_data; + dynamic_message->SerializeToString(&duplicate_serialized_data); + EXPECT_EQ(dynamic_message->ByteSizeLong(), duplicate_serialized_data.size()); + + // Force the map field to mark with map CLEAN + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_int32_int32"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_int32_int32"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_int64_int64"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_uint32_uint32"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_uint64_uint64"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_sint32_sint32"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_sint64_sint64"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_fixed32_fixed32"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_fixed64_fixed64"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_sfixed32_sfixed32"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_sfixed64_sfixed64"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_int32_float"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_int32_double"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_bool_bool"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_string_string"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_int32_bytes"), 2); + EXPECT_EQ(reflection_tester.MapSize( + *dynamic_message, "map_int32_enum"), 2); + EXPECT_EQ(reflection_tester.MapSize(*dynamic_message, "map_int32_foreign_message"), 2); + // The map field is marked as CLEAN, ByteSizeLong() will use map which do not + // have duplicate keys to calculate. + int size = dynamic_message->ByteSizeLong(); + EXPECT_EQ(expected_size, size); + + // Protobuf used to have a bug for serialize when map it marked CLEAN. It used + // repeated field to calculate ByteSizeLong but use map to serialize the real + // data, thus the ByteSizeLong may bigger than real serialized size. A crash + // might be happen at SerializeToString(). Or an "unexpected end group" + // warning was raised at parse back if user use SerializeWithCachedSizes() + // which avoids size check at serialize. + std::string serialized_data; + dynamic_message->SerializeToString(&serialized_data); + EXPECT_TRUE(dynamic_message->ParseFromString(serialized_data)); +} + +TEST(WireFormatForMapFieldTest, MapParseHelpers) { + std::string data; + + { + // Set up. + UNITTEST::TestMap message; + MapTestUtil::SetMapFields(&message); + message.SerializeToString(&data); + } + + { + // Test ParseFromString. + UNITTEST::TestMap message; + EXPECT_TRUE(message.ParseFromString(data)); + MapTestUtil::ExpectMapFieldsSet(message); + } + + { + // Test ParseFromIstream. + UNITTEST::TestMap message; + std::stringstream stream(data); + EXPECT_TRUE(message.ParseFromIstream(&stream)); + EXPECT_TRUE(stream.eof()); + MapTestUtil::ExpectMapFieldsSet(message); + } + + { + // Test ParseFromBoundedZeroCopyStream. + std::string data_with_junk(data); + data_with_junk.append("some junk on the end"); + io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size()); + UNITTEST::TestMap message; + EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size())); + MapTestUtil::ExpectMapFieldsSet(message); + } + + { + // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if + // EOF is reached before the expected number of bytes. + io::ArrayInputStream stream(data.data(), data.size()); + UNITTEST::TestAllTypes message; + EXPECT_FALSE( + message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1)); + } +} + +// Deterministic Serialization Test ========================================== + +template <typename T> +static std::string DeterministicSerializationWithSerializePartialToCodedStream( + const T& t) { + const size_t size = t.ByteSizeLong(); + std::string result(size, '\0'); + io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size); + io::CodedOutputStream output_stream(&array_stream); + output_stream.SetSerializationDeterministic(true); + t.SerializePartialToCodedStream(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + return result; +} + +template <typename T> +static std::string DeterministicSerializationWithSerializeToCodedStream( + const T& t) { + const size_t size = t.ByteSizeLong(); + std::string result(size, '\0'); + io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size); + io::CodedOutputStream output_stream(&array_stream); + output_stream.SetSerializationDeterministic(true); + t.SerializeToCodedStream(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + return result; +} + +template <typename T> +static std::string DeterministicSerialization(const T& t) { + const size_t size = t.ByteSizeLong(); + std::string result(size, '\0'); + io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size); + { + io::CodedOutputStream output_stream(&array_stream); + output_stream.SetSerializationDeterministic(true); + t.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + EXPECT_EQ(result, DeterministicSerializationWithSerializeToCodedStream(t)); + EXPECT_EQ(result, + DeterministicSerializationWithSerializePartialToCodedStream(t)); + return result; +} + +// Helper for MapSerializationTest. Return a 7-bit ASCII string. +static std::string ConstructKey(uint64 n) { + std::string s(n % static_cast<uint64>(9), '\0'); + if (s.empty()) { + return StrCat(n); + } else { + while (n != 0) { + s[n % s.size()] = (n >> 10) & 0x7f; + n /= 888; + } + return s; + } +} + +TEST(MapSerializationTest, Deterministic) { + const int kIters = 25; + UNITTEST::TestMaps t; + UNITTEST::TestIntIntMap inner; + (*inner.mutable_m())[0] = (*inner.mutable_m())[10] = + (*inner.mutable_m())[-200] = 0; + uint64 frog = 9; + const uint64 multiplier = 0xa29cd16f; + for (int i = 0; i < kIters; i++) { + const int32 i32 = static_cast<int32>(frog & 0xffffffff); + const uint32 u32 = static_cast<uint32>(i32) * 91919; + const int64 i64 = static_cast<int64>(frog); + const uint64 u64 = frog * static_cast<uint64>(187321); + const bool b = i32 > 0; + const std::string s = ConstructKey(frog); + (*inner.mutable_m())[i] = i32; + (*t.mutable_m_int32())[i32] = (*t.mutable_m_sint32())[i32] = + (*t.mutable_m_sfixed32())[i32] = inner; + (*t.mutable_m_uint32())[u32] = (*t.mutable_m_fixed32())[u32] = inner; + (*t.mutable_m_int64())[i64] = (*t.mutable_m_sint64())[i64] = + (*t.mutable_m_sfixed64())[i64] = inner; + (*t.mutable_m_uint64())[u64] = (*t.mutable_m_fixed64())[u64] = inner; + (*t.mutable_m_bool())[b] = inner; + (*t.mutable_m_string())[s] = inner; + (*t.mutable_m_string())[s + std::string(1 << (u32 % static_cast<uint32>(9)), + b)] = inner; + inner.mutable_m()->erase(i); + frog = frog * multiplier + i; + frog ^= (frog >> 41); + } + + // Verifies if two consecutive calls to deterministic serialization produce + // the same bytes. Deterministic serialization means the same serialization + // bytes in the same binary. + const std::string s1 = DeterministicSerialization(t); + const std::string s2 = DeterministicSerialization(t); + EXPECT_EQ(s1, s2); + + UNITTEST::TestMaps u; + EXPECT_TRUE(u.ParseFromString(s1)); + EXPECT_TRUE(util::MessageDifferencer::Equals(u, t)); +} + +TEST(MapSerializationTest, DeterministicSubmessage) { + UNITTEST::TestSubmessageMaps p; + UNITTEST::TestMaps t; + const std::string filename = "golden_message_maps"; + std::string golden; + GOOGLE_CHECK_OK(File::GetContents( + TestUtil::GetTestDataPath("net/proto2/internal/testdata/" + filename), + &golden, true)); + t.ParseFromString(golden); + *(p.mutable_m()) = t; + std::vector<std::string> v; + // Use multiple attempts to increase the chance of a failure if something is + // buggy. For example, each separate copy of a map might use a different + // randomly-chosen hash function. + const int kAttempts = 10; + for (int i = 0; i < kAttempts; i++) { + UNITTEST::TestSubmessageMaps q(p); + ASSERT_EQ(DeterministicSerialization(q), DeterministicSerialization(p)); + } +} + +// Text Format Test ================================================= + +TEST(TextFormatMapTest, SerializeAndParse) { + UNITTEST::TestMap source; + UNITTEST::TestMap dest; + MapTestUtil::SetMapFields(&source); + std::string output; + + // Test compact ASCII + TextFormat::Printer printer; + printer.PrintToString(source, &output); + TextFormat::Parser parser; + EXPECT_TRUE(parser.ParseFromString(output, &dest)); + MapTestUtil::ExpectMapFieldsSet(dest); +} + +TEST(TextFormatMapTest, DynamicMessage) { + TestMap prototype; + DynamicMessageFactory factory; + std::unique_ptr<Message> message( + factory.GetPrototype(prototype.GetDescriptor())->New()); + MapReflectionTester tester(message->GetDescriptor()); + tester.SetMapFieldsViaReflection(message.get()); + + std::string expected_text; + GOOGLE_CHECK_OK( + File::GetContents(TestUtil::GetTestDataPath("net/proto2/internal/" + "testdata/map_test_data.txt"), + &expected_text, true)); + + CleanStringLineEndings(&expected_text, false); + EXPECT_EQ(message->DebugString(), expected_text); +} + +TEST(TextFormatMapTest, Sorted) { + UNITTEST::TestMap message; + MapReflectionTester tester(message.GetDescriptor()); + tester.SetMapFieldsViaReflection(&message); + + std::string expected_text; + GOOGLE_CHECK_OK( + File::GetContents(TestUtil::GetTestDataPath("net/proto2/internal/" + "testdata/map_test_data.txt"), + &expected_text, true)); + + CleanStringLineEndings(&expected_text, false); + EXPECT_EQ(message.DebugString(), expected_text); + + // Test again on the reverse order. + UNITTEST::TestMap message2; + tester.SetMapFieldsViaReflection(&message2); + tester.SwapMapsViaReflection(&message2); + EXPECT_EQ(message2.DebugString(), expected_text); +} + +TEST(TextFormatMapTest, ParseCorruptedString) { + std::string serialized_message; + GOOGLE_CHECK_OK( + File::GetContents(TestUtil::GetTestDataPath( + "net/proto2/internal/testdata/golden_message_maps"), + &serialized_message, true)); + UNITTEST::TestMaps message; + GOOGLE_CHECK(message.ParseFromString(serialized_message)); + TestParseCorruptedString<UNITTEST::TestMaps, true>(message); + TestParseCorruptedString<UNITTEST::TestMaps, false>(message); +} + +// Previously, serializing to text format will disable iterator from generated +// API. Now, the iterator can be still used even after serializing to text +// format. +TEST(TextFormatMapTest, NoDisableIterator) { + UNITTEST::TestMap source; + (*source.mutable_map_int32_int32())[1] = 1; + + // Get iterator. + Map<int32, int32>::iterator iter = source.mutable_map_int32_int32()->find(1); + + // Serialize message to text format, which will invalidate the previous + // iterator previously. + std::string output; + TextFormat::Printer printer; + printer.PrintToString(source, &output); + + // Modify map via the iterator (invalidated in previous implementation.). + iter->second = 2; + + // In previous implementation, the new change won't be reflected in text + // format, because the previous iterator has been invalidated. + output.clear(); + printer.PrintToString(source, &output); + std::string expected = + "map_int32_int32 {\n" + " key: 1\n" + " value: 2\n" + "}\n"; + EXPECT_EQ(output, expected); +} + +// Previously, serializing to text format will disable iterator from reflection +// API. +TEST(TextFormatMapTest, NoDisableReflectionIterator) { + UNITTEST::TestMap source; + (*source.mutable_map_int32_int32())[1] = 1; + + // Get iterator. This will also sync internal repeated field with map inside + // of MapField. + const Reflection* reflection = source.GetReflection(); + const FieldDescriptor* field_desc = + source.GetDescriptor()->FindFieldByName("map_int32_int32"); + RepeatedPtrField<Message>* map_field = + reflection->MutableRepeatedPtrField<Message>(&source, field_desc); + RepeatedPtrField<Message>::iterator iter = map_field->begin(); + + // Serialize message to text format, which will invalidate the previous + // iterator previously. + std::string output; + TextFormat::Printer printer; + printer.PrintToString(source, &output); + + // Modify map via the iterator (invalidated in previous implementation.). + const Reflection* map_entry_reflection = iter->GetReflection(); + const FieldDescriptor* value_field_desc = + iter->GetDescriptor()->FindFieldByName("value"); + map_entry_reflection->SetInt32(&(*iter), value_field_desc, 2); + GOOGLE_LOG(INFO) << iter->DebugString(); + + // In previous implementation, the new change won't be reflected in text + // format, because the previous iterator has been invalidated. + output.clear(); + printer.PrintToString(source, &output); + std::string expected = + "map_int32_int32 {\n" + " key: 1\n" + " value: 2\n" + "}\n"; + EXPECT_EQ(output, expected); +} + +// arena support ================================================= +TEST(ArenaTest, ParsingAndSerializingNoHeapAllocation) { + // Allocate a large initial block to avoid mallocs during hooked test. + std::vector<char> arena_block(128 * 1024); + ArenaOptions options; + options.initial_block = &arena_block[0]; + options.initial_block_size = arena_block.size(); + Arena arena(options); + std::string data; + data.reserve(128 * 1024); + + { + // TODO(teboring): Enable no heap check when ArenaStringPtr is used in map. + // NoHeapChecker no_heap; + + UNITTEST::TestArenaMap* from = + Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena); + MapTestUtil::SetArenaMapFields(from); + from->SerializeToString(&data); + + UNITTEST::TestArenaMap* to = + Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena); + to->ParseFromString(data); + MapTestUtil::ExpectArenaMapFieldsSet(*to); + } +} + +TEST(ArenaTest, SubmessageOnSameArena) { + Arena arena; + for (Arena* arena_to_use : {&arena, static_cast<Arena*>(nullptr)}) { + ArenaHolder<UNITTEST::TestArenaMap> m(arena_to_use); + auto* subm = &(*m->mutable_map_int32_foreign_message())[0]; + EXPECT_EQ(subm->GetArena(), arena_to_use); + } +} + +// Use text format parsing and serializing to test reflection api. +TEST(ArenaTest, ReflectionInTextFormat) { + Arena arena; + std::string data; + + TextFormat::Printer printer; + TextFormat::Parser parser; + + UNITTEST::TestArenaMap* from = + Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena); + UNITTEST::TestArenaMap* to = + Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena); + + MapTestUtil::SetArenaMapFields(from); + printer.PrintToString(*from, &data); + + EXPECT_TRUE(parser.ParseFromString(data, to)); + MapTestUtil::ExpectArenaMapFieldsSet(*to); +} + +// Make sure the memory allocated for string in map is deallocated. +TEST(ArenaTest, StringMapNoLeak) { + Arena arena; + UNITTEST::TestArenaMap* message = + Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena); + std::string data; + // String with length less than 16 will not be allocated from heap. + int original_capacity = data.capacity(); + while (data.capacity() <= original_capacity) { + data.append("a"); + } + (*message->mutable_map_string_string())[data] = data; + // We rely on heap checkers to detect memory leak for us. + ASSERT_FALSE(message == NULL); +} + +TEST(ArenaTest, IsInitialized) { + // Allocate a large initial polluted block. + std::vector<char> arena_block(128 * 1024); + std::fill(arena_block.begin(), arena_block.end(), '\xff'); + + ArenaOptions options; + options.initial_block = &arena_block[0]; + options.initial_block_size = arena_block.size(); + Arena arena(options); + + UNITTEST::TestArenaMap* message = + Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena); + EXPECT_EQ(0, (*message->mutable_map_int32_int32())[0]); +} + +TEST(ArenaTest, DynamicMapFieldOnArena) { + Arena arena; + UNITTEST::TestMap message2; + + DynamicMessageFactory factory; + Message* message1 = + factory.GetPrototype(UNITTEST::TestMap::descriptor())->New(&arena); + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaReflection(message1); + reflection_tester.ExpectMapFieldsSetViaReflection(*message1); + reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1); + message2.CopyFrom(*message1); + MapTestUtil::ExpectMapFieldsSet(message2); +} + +TEST(ArenaTest, DynamicMapFieldOnArenaMemoryLeak) { + auto* desc = UNITTEST::TestMap::descriptor(); + auto* field = desc->FindFieldByName("map_int32_int32"); + + Arena arena; + DynamicMessageFactory factory; + auto* message = factory.GetPrototype(desc)->New(&arena); + auto* reflection = message->GetReflection(); + reflection->AddMessage(message, field); + + // Force internal syncing, which initializes the mutex. + MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor()); + int size = reflection_tester.MapSize(*message, "map_int32_int32"); + EXPECT_EQ(size, 1); +} + +TEST(MoveTest, MoveConstructorWorks) { + Map<int32, TestAllTypes> original_map; + original_map[42].mutable_optional_nested_message()->set_bb(42); + original_map[43].mutable_optional_nested_message()->set_bb(43); + const auto* nested_msg42_ptr = &original_map[42].optional_nested_message(); + const auto* nested_msg43_ptr = &original_map[43].optional_nested_message(); + + Map<int32, TestAllTypes> moved_to_map(std::move(original_map)); + EXPECT_TRUE(original_map.empty()); + EXPECT_EQ(2, moved_to_map.size()); + EXPECT_EQ(42, moved_to_map[42].optional_nested_message().bb()); + EXPECT_EQ(43, moved_to_map[43].optional_nested_message().bb()); + // This test takes advantage of the fact that pointers are swapped, so there + // should be pointer stability. + EXPECT_EQ(nested_msg42_ptr, &moved_to_map[42].optional_nested_message()); + EXPECT_EQ(nested_msg43_ptr, &moved_to_map[43].optional_nested_message()); +} + +TEST(MoveTest, MoveAssignmentWorks) { + Map<int32, TestAllTypes> original_map; + original_map[42].mutable_optional_nested_message()->set_bb(42); + original_map[43].mutable_optional_nested_message()->set_bb(43); + const auto* nested_msg42_ptr = &original_map[42].optional_nested_message(); + const auto* nested_msg43_ptr = &original_map[43].optional_nested_message(); + + Map<int32, TestAllTypes> moved_to_map = std::move(original_map); + EXPECT_TRUE(original_map.empty()); + EXPECT_EQ(2, moved_to_map.size()); + EXPECT_EQ(42, moved_to_map[42].optional_nested_message().bb()); + EXPECT_EQ(43, moved_to_map[43].optional_nested_message().bb()); + // This test takes advantage of the fact that pointers are swapped, so there + // should be pointer stability. + EXPECT_EQ(nested_msg42_ptr, &moved_to_map[42].optional_nested_message()); + EXPECT_EQ(nested_msg43_ptr, &moved_to_map[43].optional_nested_message()); +} + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc>
diff --git a/src/google/protobuf/map_test_util.h b/src/google/protobuf/map_test_util.h index c3b84d1..f3215db 100644 --- a/src/google/protobuf/map_test_util.h +++ b/src/google/protobuf/map_test_util.h
@@ -32,1607 +32,15 @@ #define GOOGLE_PROTOBUF_MAP_TEST_UTIL_H__ #include <google/protobuf/map_unittest.pb.h> +#include <google/protobuf/reflection_tester.h> #define UNITTEST ::protobuf_unittest -// Must define UNITTEST before including map_test_util.inc. +#define BRIDGE_UNITTEST ::google::protobuf::bridge_unittest + +// Must be included after defining UNITTEST, etc. #include <google/protobuf/map_test_util.inc> + #undef UNITTEST - -#include <google/protobuf/port_def.inc> - -namespace google { -namespace protobuf { - -namespace unittest = ::protobuf_unittest; - - -// Like above, but use the reflection interface. -class MapReflectionTester { - public: - // base_descriptor must be a descriptor for TestMap, which is used for - // MapReflectionTester to fetch the FieldDescriptors needed to use the - // reflection interface. - explicit MapReflectionTester(const Descriptor* base_descriptor); - - void SetMapFieldsViaReflection(Message* message); - void SetMapFieldsViaMapReflection(Message* message); - void ClearMapFieldsViaReflection(Message* message); - void ModifyMapFieldsViaReflection(Message* message); - void RemoveLastMapsViaReflection(Message* message); - void ReleaseLastMapsViaReflection(Message* message); - void SwapMapsViaReflection(Message* message); - void MutableUnknownFieldsOfMapFieldsViaReflection(Message* message); - void ExpectMapFieldsSetViaReflection(const Message& message); - void ExpectMapFieldsSetViaReflectionIterator(Message* message); - void ExpectClearViaReflection(const Message& message); - void ExpectClearViaReflectionIterator(Message* message); - void GetMapValueViaMapReflection(Message* message, - const std::string& field_name, - const MapKey& map_key, MapValueRef* map_val); - Message* GetMapEntryViaReflection(Message* message, - const std::string& field_name, int index); - MapIterator MapBegin(Message* message, const std::string& field_name); - MapIterator MapEnd(Message* message, const std::string& field_name); - int MapSize(const Message& message, const std::string& field_name); - - private: - const FieldDescriptor* F(const std::string& name); - - const Descriptor* base_descriptor_; - - const EnumValueDescriptor* map_enum_bar_; - const EnumValueDescriptor* map_enum_baz_; - const EnumValueDescriptor* map_enum_foo_; - - const FieldDescriptor* foreign_c_; - const FieldDescriptor* map_int32_int32_key_; - const FieldDescriptor* map_int32_int32_val_; - const FieldDescriptor* map_int64_int64_key_; - const FieldDescriptor* map_int64_int64_val_; - const FieldDescriptor* map_uint32_uint32_key_; - const FieldDescriptor* map_uint32_uint32_val_; - const FieldDescriptor* map_uint64_uint64_key_; - const FieldDescriptor* map_uint64_uint64_val_; - const FieldDescriptor* map_sint32_sint32_key_; - const FieldDescriptor* map_sint32_sint32_val_; - const FieldDescriptor* map_sint64_sint64_key_; - const FieldDescriptor* map_sint64_sint64_val_; - const FieldDescriptor* map_fixed32_fixed32_key_; - const FieldDescriptor* map_fixed32_fixed32_val_; - const FieldDescriptor* map_fixed64_fixed64_key_; - const FieldDescriptor* map_fixed64_fixed64_val_; - const FieldDescriptor* map_sfixed32_sfixed32_key_; - const FieldDescriptor* map_sfixed32_sfixed32_val_; - const FieldDescriptor* map_sfixed64_sfixed64_key_; - const FieldDescriptor* map_sfixed64_sfixed64_val_; - const FieldDescriptor* map_int32_float_key_; - const FieldDescriptor* map_int32_float_val_; - const FieldDescriptor* map_int32_double_key_; - const FieldDescriptor* map_int32_double_val_; - const FieldDescriptor* map_bool_bool_key_; - const FieldDescriptor* map_bool_bool_val_; - const FieldDescriptor* map_string_string_key_; - const FieldDescriptor* map_string_string_val_; - const FieldDescriptor* map_int32_bytes_key_; - const FieldDescriptor* map_int32_bytes_val_; - const FieldDescriptor* map_int32_enum_key_; - const FieldDescriptor* map_int32_enum_val_; - const FieldDescriptor* map_int32_foreign_message_key_; - const FieldDescriptor* map_int32_foreign_message_val_; -}; - -inline MapReflectionTester::MapReflectionTester( - const Descriptor* base_descriptor) - : base_descriptor_(base_descriptor) { - const DescriptorPool* pool = base_descriptor->file()->pool(); - std::string package = base_descriptor->file()->package(); - - map_enum_foo_ = pool->FindEnumValueByName(package + ".MAP_ENUM_FOO"); - map_enum_bar_ = pool->FindEnumValueByName(package + ".MAP_ENUM_BAR"); - map_enum_baz_ = pool->FindEnumValueByName(package + ".MAP_ENUM_BAZ"); - - foreign_c_ = pool->FindFieldByName(package + ".ForeignMessage.c"); - map_int32_int32_key_ = - pool->FindFieldByName(package + ".TestMap.MapInt32Int32Entry.key"); - map_int32_int32_val_ = - pool->FindFieldByName(package + ".TestMap.MapInt32Int32Entry.value"); - map_int64_int64_key_ = - pool->FindFieldByName(package + ".TestMap.MapInt64Int64Entry.key"); - map_int64_int64_val_ = - pool->FindFieldByName(package + ".TestMap.MapInt64Int64Entry.value"); - map_uint32_uint32_key_ = - pool->FindFieldByName(package + ".TestMap.MapUint32Uint32Entry.key"); - map_uint32_uint32_val_ = - pool->FindFieldByName(package + ".TestMap.MapUint32Uint32Entry.value"); - map_uint64_uint64_key_ = - pool->FindFieldByName(package + ".TestMap.MapUint64Uint64Entry.key"); - map_uint64_uint64_val_ = - pool->FindFieldByName(package + ".TestMap.MapUint64Uint64Entry.value"); - map_sint32_sint32_key_ = - pool->FindFieldByName(package + ".TestMap.MapSint32Sint32Entry.key"); - map_sint32_sint32_val_ = - pool->FindFieldByName(package + ".TestMap.MapSint32Sint32Entry.value"); - map_sint64_sint64_key_ = - pool->FindFieldByName(package + ".TestMap.MapSint64Sint64Entry.key"); - map_sint64_sint64_val_ = - pool->FindFieldByName(package + ".TestMap.MapSint64Sint64Entry.value"); - map_fixed32_fixed32_key_ = - pool->FindFieldByName(package + ".TestMap.MapFixed32Fixed32Entry.key"); - map_fixed32_fixed32_val_ = - pool->FindFieldByName(package + ".TestMap.MapFixed32Fixed32Entry.value"); - map_fixed64_fixed64_key_ = - pool->FindFieldByName(package + ".TestMap.MapFixed64Fixed64Entry.key"); - map_fixed64_fixed64_val_ = - pool->FindFieldByName(package + ".TestMap.MapFixed64Fixed64Entry.value"); - map_sfixed32_sfixed32_key_ = - pool->FindFieldByName(package + ".TestMap.MapSfixed32Sfixed32Entry.key"); - map_sfixed32_sfixed32_val_ = pool->FindFieldByName( - package + ".TestMap.MapSfixed32Sfixed32Entry.value"); - map_sfixed64_sfixed64_key_ = - pool->FindFieldByName(package + ".TestMap.MapSfixed64Sfixed64Entry.key"); - map_sfixed64_sfixed64_val_ = pool->FindFieldByName( - package + ".TestMap.MapSfixed64Sfixed64Entry.value"); - map_int32_float_key_ = - pool->FindFieldByName(package + ".TestMap.MapInt32FloatEntry.key"); - map_int32_float_val_ = - pool->FindFieldByName(package + ".TestMap.MapInt32FloatEntry.value"); - map_int32_double_key_ = - pool->FindFieldByName(package + ".TestMap.MapInt32DoubleEntry.key"); - map_int32_double_val_ = - pool->FindFieldByName(package + ".TestMap.MapInt32DoubleEntry.value"); - map_bool_bool_key_ = - pool->FindFieldByName(package + ".TestMap.MapBoolBoolEntry.key"); - map_bool_bool_val_ = - pool->FindFieldByName(package + ".TestMap.MapBoolBoolEntry.value"); - map_string_string_key_ = - pool->FindFieldByName(package + ".TestMap.MapStringStringEntry.key"); - map_string_string_val_ = - pool->FindFieldByName(package + ".TestMap.MapStringStringEntry.value"); - map_int32_bytes_key_ = - pool->FindFieldByName(package + ".TestMap.MapInt32BytesEntry.key"); - map_int32_bytes_val_ = - pool->FindFieldByName(package + ".TestMap.MapInt32BytesEntry.value"); - map_int32_enum_key_ = - pool->FindFieldByName(package + ".TestMap.MapInt32EnumEntry.key"); - map_int32_enum_val_ = - pool->FindFieldByName(package + ".TestMap.MapInt32EnumEntry.value"); - map_int32_foreign_message_key_ = pool->FindFieldByName( - package + ".TestMap.MapInt32ForeignMessageEntry.key"); - map_int32_foreign_message_val_ = pool->FindFieldByName( - package + ".TestMap.MapInt32ForeignMessageEntry.value"); - - EXPECT_FALSE(map_enum_foo_ == nullptr); - EXPECT_FALSE(map_enum_bar_ == nullptr); - EXPECT_FALSE(map_enum_baz_ == nullptr); - EXPECT_FALSE(map_int32_int32_key_ == nullptr); - EXPECT_FALSE(map_int32_int32_val_ == nullptr); - EXPECT_FALSE(map_int64_int64_key_ == nullptr); - EXPECT_FALSE(map_int64_int64_val_ == nullptr); - EXPECT_FALSE(map_uint32_uint32_key_ == nullptr); - EXPECT_FALSE(map_uint32_uint32_val_ == nullptr); - EXPECT_FALSE(map_uint64_uint64_key_ == nullptr); - EXPECT_FALSE(map_uint64_uint64_val_ == nullptr); - EXPECT_FALSE(map_sint32_sint32_key_ == nullptr); - EXPECT_FALSE(map_sint32_sint32_val_ == nullptr); - EXPECT_FALSE(map_sint64_sint64_key_ == nullptr); - EXPECT_FALSE(map_sint64_sint64_val_ == nullptr); - EXPECT_FALSE(map_fixed32_fixed32_key_ == nullptr); - EXPECT_FALSE(map_fixed32_fixed32_val_ == nullptr); - EXPECT_FALSE(map_fixed64_fixed64_key_ == nullptr); - EXPECT_FALSE(map_fixed64_fixed64_val_ == nullptr); - EXPECT_FALSE(map_sfixed32_sfixed32_key_ == nullptr); - EXPECT_FALSE(map_sfixed32_sfixed32_val_ == nullptr); - EXPECT_FALSE(map_sfixed64_sfixed64_key_ == nullptr); - EXPECT_FALSE(map_sfixed64_sfixed64_val_ == nullptr); - EXPECT_FALSE(map_int32_float_key_ == nullptr); - EXPECT_FALSE(map_int32_float_val_ == nullptr); - EXPECT_FALSE(map_int32_double_key_ == nullptr); - EXPECT_FALSE(map_int32_double_val_ == nullptr); - EXPECT_FALSE(map_bool_bool_key_ == nullptr); - EXPECT_FALSE(map_bool_bool_val_ == nullptr); - EXPECT_FALSE(map_string_string_key_ == nullptr); - EXPECT_FALSE(map_string_string_val_ == nullptr); - EXPECT_FALSE(map_int32_bytes_key_ == nullptr); - EXPECT_FALSE(map_int32_bytes_val_ == nullptr); - EXPECT_FALSE(map_int32_enum_key_ == nullptr); - EXPECT_FALSE(map_int32_enum_val_ == nullptr); - EXPECT_FALSE(map_int32_foreign_message_key_ == nullptr); - EXPECT_FALSE(map_int32_foreign_message_val_ == nullptr); - - std::vector<const FieldDescriptor*> all_map_descriptors = { - map_int32_int32_key_, - map_int32_int32_val_, - map_int64_int64_key_, - map_int64_int64_val_, - map_uint32_uint32_key_, - map_uint32_uint32_val_, - map_uint64_uint64_key_, - map_uint64_uint64_val_, - map_sint32_sint32_key_, - map_sint32_sint32_val_, - map_sint64_sint64_key_, - map_sint64_sint64_val_, - map_fixed32_fixed32_key_, - map_fixed32_fixed32_val_, - map_fixed64_fixed64_key_, - map_fixed64_fixed64_val_, - map_sfixed32_sfixed32_key_, - map_sfixed32_sfixed32_val_, - map_sfixed64_sfixed64_key_, - map_sfixed64_sfixed64_val_, - map_int32_float_key_, - map_int32_float_val_, - map_int32_double_key_, - map_int32_double_val_, - map_bool_bool_key_, - map_bool_bool_val_, - map_string_string_key_, - map_string_string_val_, - map_int32_bytes_key_, - map_int32_bytes_val_, - map_int32_enum_key_, - map_int32_enum_val_, - map_int32_foreign_message_key_, - map_int32_foreign_message_val_}; - for (const FieldDescriptor* fdesc : all_map_descriptors) { - GOOGLE_CHECK(fdesc->containing_type() != nullptr) << fdesc->name(); - if (fdesc->name() == "key") { - EXPECT_EQ(fdesc->containing_type()->map_key(), fdesc); - } else { - EXPECT_EQ(fdesc->name(), "value"); - EXPECT_EQ(fdesc->containing_type()->map_value(), fdesc); - } - } -} - -// Shorthand to get a FieldDescriptor for a field of unittest::TestMap. -inline const FieldDescriptor* MapReflectionTester::F(const std::string& name) { - const FieldDescriptor* result = nullptr; - result = base_descriptor_->FindFieldByName(name); - GOOGLE_CHECK(result != nullptr); - return result; -} - -inline void MapReflectionTester::SetMapFieldsViaReflection(Message* message) { - const Reflection* reflection = message->GetReflection(); - Message* sub_message = nullptr; - Message* sub_foreign_message = nullptr; - - // Add first element. - sub_message = reflection->AddMessage(message, F("map_int32_int32")); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_key_, 0); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_val_, 0); - - sub_message = reflection->AddMessage(message, F("map_int64_int64")); - sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_key_, 0); - sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_val_, 0); - - sub_message = reflection->AddMessage(message, F("map_uint32_uint32")); - sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_key_, - 0); - sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_val_, - 0); - - sub_message = reflection->AddMessage(message, F("map_uint64_uint64")); - sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_key_, - 0); - sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_val_, - 0); - - sub_message = reflection->AddMessage(message, F("map_sint32_sint32")); - sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_key_, - 0); - sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_val_, - 0); - - sub_message = reflection->AddMessage(message, F("map_sint64_sint64")); - sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_key_, - 0); - sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_val_, - 0); - - sub_message = reflection->AddMessage(message, F("map_fixed32_fixed32")); - sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_key_, - 0); - sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_val_, - 0); - - sub_message = reflection->AddMessage(message, F("map_fixed64_fixed64")); - sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_key_, - 0); - sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_val_, - 0); - - sub_message = reflection->AddMessage(message, F("map_sfixed32_sfixed32")); - sub_message->GetReflection()->SetInt32(sub_message, - map_sfixed32_sfixed32_key_, 0); - sub_message->GetReflection()->SetInt32(sub_message, - map_sfixed32_sfixed32_val_, 0); - - sub_message = reflection->AddMessage(message, F("map_sfixed64_sfixed64")); - sub_message->GetReflection()->SetInt64(sub_message, - map_sfixed64_sfixed64_key_, 0); - sub_message->GetReflection()->SetInt64(sub_message, - map_sfixed64_sfixed64_val_, 0); - - sub_message = reflection->AddMessage(message, F("map_int32_float")); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_float_key_, 0); - sub_message->GetReflection()->SetFloat(sub_message, map_int32_float_val_, - 0.0); - - sub_message = reflection->AddMessage(message, F("map_int32_double")); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_double_key_, 0); - sub_message->GetReflection()->SetDouble(sub_message, map_int32_double_val_, - 0.0); - - sub_message = reflection->AddMessage(message, F("map_bool_bool")); - sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_key_, false); - sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_val_, false); - - sub_message = reflection->AddMessage(message, F("map_string_string")); - sub_message->GetReflection()->SetString(sub_message, map_string_string_key_, - "0"); - sub_message->GetReflection()->SetString(sub_message, map_string_string_val_, - "0"); - - sub_message = reflection->AddMessage(message, F("map_int32_bytes")); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_bytes_key_, 0); - sub_message->GetReflection()->SetString(sub_message, map_int32_bytes_val_, - "0"); - - sub_message = reflection->AddMessage(message, F("map_int32_enum")); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_enum_key_, 0); - sub_message->GetReflection()->SetEnum(sub_message, map_int32_enum_val_, - map_enum_bar_); - - sub_message = reflection->AddMessage(message, F("map_int32_foreign_message")); - sub_message->GetReflection()->SetInt32(sub_message, - map_int32_foreign_message_key_, 0); - sub_foreign_message = sub_message->GetReflection()->MutableMessage( - sub_message, map_int32_foreign_message_val_, nullptr); - sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message, - foreign_c_, 0); - - // Add second element - sub_message = reflection->AddMessage(message, F("map_int32_int32")); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_key_, 1); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_val_, 1); - - sub_message = reflection->AddMessage(message, F("map_int64_int64")); - sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_key_, 1); - sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_val_, 1); - - sub_message = reflection->AddMessage(message, F("map_uint32_uint32")); - sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_key_, - 1); - sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_val_, - 1); - - sub_message = reflection->AddMessage(message, F("map_uint64_uint64")); - sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_key_, - 1); - sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_val_, - 1); - - sub_message = reflection->AddMessage(message, F("map_sint32_sint32")); - sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_key_, - 1); - sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_val_, - 1); - - sub_message = reflection->AddMessage(message, F("map_sint64_sint64")); - sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_key_, - 1); - sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_val_, - 1); - - sub_message = reflection->AddMessage(message, F("map_fixed32_fixed32")); - sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_key_, - 1); - sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_val_, - 1); - - sub_message = reflection->AddMessage(message, F("map_fixed64_fixed64")); - sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_key_, - 1); - sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_val_, - 1); - - sub_message = reflection->AddMessage(message, F("map_sfixed32_sfixed32")); - sub_message->GetReflection()->SetInt32(sub_message, - map_sfixed32_sfixed32_key_, 1); - sub_message->GetReflection()->SetInt32(sub_message, - map_sfixed32_sfixed32_val_, 1); - - sub_message = reflection->AddMessage(message, F("map_sfixed64_sfixed64")); - sub_message->GetReflection()->SetInt64(sub_message, - map_sfixed64_sfixed64_key_, 1); - sub_message->GetReflection()->SetInt64(sub_message, - map_sfixed64_sfixed64_val_, 1); - - sub_message = reflection->AddMessage(message, F("map_int32_float")); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_float_key_, 1); - sub_message->GetReflection()->SetFloat(sub_message, map_int32_float_val_, - 1.0); - - sub_message = reflection->AddMessage(message, F("map_int32_double")); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_double_key_, 1); - sub_message->GetReflection()->SetDouble(sub_message, map_int32_double_val_, - 1.0); - - sub_message = reflection->AddMessage(message, F("map_bool_bool")); - sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_key_, true); - sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_val_, true); - - sub_message = reflection->AddMessage(message, F("map_string_string")); - sub_message->GetReflection()->SetString(sub_message, map_string_string_key_, - "1"); - sub_message->GetReflection()->SetString(sub_message, map_string_string_val_, - "1"); - - sub_message = reflection->AddMessage(message, F("map_int32_bytes")); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_bytes_key_, 1); - sub_message->GetReflection()->SetString(sub_message, map_int32_bytes_val_, - "1"); - - sub_message = reflection->AddMessage(message, F("map_int32_enum")); - sub_message->GetReflection()->SetInt32(sub_message, map_int32_enum_key_, 1); - sub_message->GetReflection()->SetEnum(sub_message, map_int32_enum_val_, - map_enum_baz_); - - sub_message = reflection->AddMessage(message, F("map_int32_foreign_message")); - sub_message->GetReflection()->SetInt32(sub_message, - map_int32_foreign_message_key_, 1); - sub_foreign_message = sub_message->GetReflection()->MutableMessage( - sub_message, map_int32_foreign_message_val_, nullptr); - sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message, - foreign_c_, 1); -} - -inline void MapReflectionTester::SetMapFieldsViaMapReflection( - Message* message) { - const Reflection* reflection = message->GetReflection(); - - Message* sub_foreign_message = nullptr; - MapValueRef map_val; - MapValueConstRef map_val_const; - - // Add first element. - MapKey map_key; - map_key.SetInt32Value(0); - EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_int32"), - map_key, &map_val_const)); - EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"), - map_key, &map_val)); - map_val.SetInt32Value(0); - - map_key.SetInt64Value(0); - EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int64_int64"), - map_key, &map_val_const)); - EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"), - map_key, &map_val)); - map_val.SetInt64Value(0); - - map_key.SetUInt32Value(0); - EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_uint32_uint32"), - map_key, &map_val_const)); - EXPECT_TRUE(reflection->InsertOrLookupMapValue( - message, F("map_uint32_uint32"), map_key, &map_val)); - map_val.SetUInt32Value(0); - - map_key.SetUInt64Value(0); - EXPECT_TRUE(reflection->InsertOrLookupMapValue( - message, F("map_uint64_uint64"), map_key, &map_val)); - map_val.SetUInt64Value(0); - - map_key.SetInt32Value(0); - EXPECT_TRUE(reflection->InsertOrLookupMapValue( - message, F("map_sint32_sint32"), map_key, &map_val)); - map_val.SetInt32Value(0); - - map_key.SetInt64Value(0); - EXPECT_TRUE(reflection->InsertOrLookupMapValue( - message, F("map_sint64_sint64"), map_key, &map_val)); - map_val.SetInt64Value(0); - - map_key.SetUInt32Value(0); - EXPECT_TRUE(reflection->InsertOrLookupMapValue( - message, F("map_fixed32_fixed32"), map_key, &map_val)); - map_val.SetUInt32Value(0); - - map_key.SetUInt64Value(0); - EXPECT_TRUE(reflection->InsertOrLookupMapValue( - message, F("map_fixed64_fixed64"), map_key, &map_val)); - map_val.SetUInt64Value(0); - - map_key.SetInt32Value(0); - EXPECT_TRUE(reflection->InsertOrLookupMapValue( - message, F("map_sfixed32_sfixed32"), map_key, &map_val)); - map_val.SetInt32Value(0); - - map_key.SetInt64Value(0); - EXPECT_TRUE(reflection->InsertOrLookupMapValue( - message, F("map_sfixed64_sfixed64"), map_key, &map_val)); - map_val.SetInt64Value(0); - - map_key.SetInt32Value(0); - EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_float"), - map_key, &map_val)); - map_val.SetFloatValue(0.0); - - map_key.SetInt32Value(0); - EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_double"), - map_key, &map_val)); - map_val.SetDoubleValue(0.0); - - map_key.SetBoolValue(false); - EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_bool_bool"), map_key, - &map_val_const)); - EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_bool_bool"), - map_key, &map_val)); - map_val.SetBoolValue(false); - - map_key.SetStringValue("0"); - EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_string_string"), - map_key, &map_val_const)); - EXPECT_TRUE(reflection->InsertOrLookupMapValue( - message, F("map_string_string"), map_key, &map_val)); - map_val.SetStringValue("0"); - - map_key.SetInt32Value(0); - EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_bytes"), - map_key, &map_val_const)); - EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"), - map_key, &map_val)); - map_val.SetStringValue("0"); - - map_key.SetInt32Value(0); - EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_enum"), - map_key, &map_val_const)); - EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_enum"), - map_key, &map_val)); - map_val.SetEnumValue(map_enum_bar_->number()); - - map_key.SetInt32Value(0); - EXPECT_FALSE(reflection->LookupMapValue( - *message, F("map_int32_foreign_message"), map_key, &map_val_const)); - EXPECT_TRUE(reflection->InsertOrLookupMapValue( - message, F("map_int32_foreign_message"), map_key, &map_val)); - sub_foreign_message = map_val.MutableMessageValue(); - sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message, - foreign_c_, 0); - - // Add second element - map_key.SetInt32Value(1); - EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"), - map_key, &map_val)); - map_val.SetInt32Value(1); - EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"), - map_key, &map_val)); - - map_key.SetInt64Value(1); - EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"), - map_key, &map_val)); - map_val.SetInt64Value(1); - EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"), - map_key, &map_val)); - - map_key.SetUInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_uint32_uint32"), map_key, - &map_val); - map_val.SetUInt32Value(1); - - map_key.SetUInt64Value(1); - reflection->InsertOrLookupMapValue(message, F("map_uint64_uint64"), map_key, - &map_val); - map_val.SetUInt64Value(1); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_sint32_sint32"), map_key, - &map_val); - map_val.SetInt32Value(1); - - map_key.SetInt64Value(1); - reflection->InsertOrLookupMapValue(message, F("map_sint64_sint64"), map_key, - &map_val); - map_val.SetInt64Value(1); - - map_key.SetUInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_fixed32_fixed32"), map_key, - &map_val); - map_val.SetUInt32Value(1); - - map_key.SetUInt64Value(1); - reflection->InsertOrLookupMapValue(message, F("map_fixed64_fixed64"), map_key, - &map_val); - map_val.SetUInt64Value(1); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_sfixed32_sfixed32"), - map_key, &map_val); - map_val.SetInt32Value(1); - - map_key.SetInt64Value(1); - reflection->InsertOrLookupMapValue(message, F("map_sfixed64_sfixed64"), - map_key, &map_val); - map_val.SetInt64Value(1); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_int32_float"), map_key, - &map_val); - map_val.SetFloatValue(1.0); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_int32_double"), map_key, - &map_val); - map_val.SetDoubleValue(1.0); - - map_key.SetBoolValue(true); - reflection->InsertOrLookupMapValue(message, F("map_bool_bool"), map_key, - &map_val); - map_val.SetBoolValue(true); - - map_key.SetStringValue("1"); - reflection->InsertOrLookupMapValue(message, F("map_string_string"), map_key, - &map_val); - map_val.SetStringValue("1"); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"), map_key, - &map_val); - map_val.SetStringValue("1"); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_int32_enum"), map_key, - &map_val); - map_val.SetEnumValue(map_enum_baz_->number()); - - map_key.SetInt32Value(1); - EXPECT_TRUE(reflection->InsertOrLookupMapValue( - message, F("map_int32_foreign_message"), map_key, &map_val)); - sub_foreign_message = map_val.MutableMessageValue(); - sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message, - foreign_c_, 1); -} - -inline void MapReflectionTester::GetMapValueViaMapReflection( - Message* message, const std::string& field_name, const MapKey& map_key, - MapValueRef* map_val) { - const Reflection* reflection = message->GetReflection(); - EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F(field_name), - map_key, map_val)); -} - -inline Message* MapReflectionTester::GetMapEntryViaReflection( - Message* message, const std::string& field_name, int index) { - const Reflection* reflection = message->GetReflection(); - return reflection->MutableRepeatedMessage(message, F(field_name), index); -} - -inline MapIterator MapReflectionTester::MapBegin( - Message* message, const std::string& field_name) { - const Reflection* reflection = message->GetReflection(); - return reflection->MapBegin(message, F(field_name)); -} - -inline MapIterator MapReflectionTester::MapEnd(Message* message, - const std::string& field_name) { - const Reflection* reflection = message->GetReflection(); - return reflection->MapEnd(message, F(field_name)); -} - -inline int MapReflectionTester::MapSize(const Message& message, - const std::string& field_name) { - const Reflection* reflection = message.GetReflection(); - return reflection->MapSize(message, F(field_name)); -} - -inline void MapReflectionTester::ClearMapFieldsViaReflection(Message* message) { - const Reflection* reflection = message->GetReflection(); - - reflection->ClearField(message, F("map_int32_int32")); - reflection->ClearField(message, F("map_int64_int64")); - reflection->ClearField(message, F("map_uint32_uint32")); - reflection->ClearField(message, F("map_uint64_uint64")); - reflection->ClearField(message, F("map_sint32_sint32")); - reflection->ClearField(message, F("map_sint64_sint64")); - reflection->ClearField(message, F("map_fixed32_fixed32")); - reflection->ClearField(message, F("map_fixed64_fixed64")); - reflection->ClearField(message, F("map_sfixed32_sfixed32")); - reflection->ClearField(message, F("map_sfixed64_sfixed64")); - reflection->ClearField(message, F("map_int32_float")); - reflection->ClearField(message, F("map_int32_double")); - reflection->ClearField(message, F("map_bool_bool")); - reflection->ClearField(message, F("map_string_string")); - reflection->ClearField(message, F("map_int32_bytes")); - reflection->ClearField(message, F("map_int32_enum")); - reflection->ClearField(message, F("map_int32_foreign_message")); -} - -inline void MapReflectionTester::ModifyMapFieldsViaReflection( - Message* message) { - const Reflection* reflection = message->GetReflection(); - MapValueRef map_val; - Message* sub_foreign_message; - - // Modify the second element - MapKey map_key; - map_key.SetInt32Value(1); - EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"), - map_key, &map_val)); - map_val.SetInt32Value(2); - - map_key.SetInt64Value(1); - EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"), - map_key, &map_val)); - map_val.SetInt64Value(2); - - map_key.SetUInt32Value(1); - EXPECT_FALSE(reflection->InsertOrLookupMapValue( - message, F("map_uint32_uint32"), map_key, &map_val)); - map_val.SetUInt32Value(2); - - map_key.SetUInt64Value(1); - reflection->InsertOrLookupMapValue(message, F("map_uint64_uint64"), map_key, - &map_val); - map_val.SetUInt64Value(2); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_sint32_sint32"), map_key, - &map_val); - map_val.SetInt32Value(2); - - map_key.SetInt64Value(1); - reflection->InsertOrLookupMapValue(message, F("map_sint64_sint64"), map_key, - &map_val); - map_val.SetInt64Value(2); - - map_key.SetUInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_fixed32_fixed32"), map_key, - &map_val); - map_val.SetUInt32Value(2); - - map_key.SetUInt64Value(1); - reflection->InsertOrLookupMapValue(message, F("map_fixed64_fixed64"), map_key, - &map_val); - map_val.SetUInt64Value(2); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_sfixed32_sfixed32"), - map_key, &map_val); - map_val.SetInt32Value(2); - - map_key.SetInt64Value(1); - reflection->InsertOrLookupMapValue(message, F("map_sfixed64_sfixed64"), - map_key, &map_val); - map_val.SetInt64Value(2); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_int32_float"), map_key, - &map_val); - map_val.SetFloatValue(2.0); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_int32_double"), map_key, - &map_val); - map_val.SetDoubleValue(2.0); - - map_key.SetBoolValue(true); - reflection->InsertOrLookupMapValue(message, F("map_bool_bool"), map_key, - &map_val); - map_val.SetBoolValue(false); - - map_key.SetStringValue("1"); - reflection->InsertOrLookupMapValue(message, F("map_string_string"), map_key, - &map_val); - map_val.SetStringValue("2"); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"), map_key, - &map_val); - map_val.SetStringValue("2"); - - map_key.SetInt32Value(1); - reflection->InsertOrLookupMapValue(message, F("map_int32_enum"), map_key, - &map_val); - map_val.SetEnumValue(map_enum_foo_->number()); - - map_key.SetInt32Value(1); - EXPECT_FALSE(reflection->InsertOrLookupMapValue( - message, F("map_int32_foreign_message"), map_key, &map_val)); - sub_foreign_message = map_val.MutableMessageValue(); - sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message, - foreign_c_, 2); -} - -inline void MapReflectionTester::RemoveLastMapsViaReflection(Message* message) { - const Reflection* reflection = message->GetReflection(); - - std::vector<const FieldDescriptor*> output; - reflection->ListFields(*message, &output); - for (int i = 0; i < output.size(); ++i) { - const FieldDescriptor* field = output[i]; - if (!field->is_repeated()) continue; - reflection->RemoveLast(message, field); - } -} - -inline void MapReflectionTester::ReleaseLastMapsViaReflection( - Message* message) { - const Reflection* reflection = message->GetReflection(); - - std::vector<const FieldDescriptor*> output; - reflection->ListFields(*message, &output); - for (int i = 0; i < output.size(); ++i) { - const FieldDescriptor* field = output[i]; - if (!field->is_repeated()) continue; - if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue; - - Message* released = reflection->ReleaseLast(message, field); - ASSERT_TRUE(released != nullptr) - << "ReleaseLast returned nullptr for: " << field->name(); - delete released; - } -} - -inline void MapReflectionTester::SwapMapsViaReflection(Message* message) { - const Reflection* reflection = message->GetReflection(); - std::vector<const FieldDescriptor*> output; - reflection->ListFields(*message, &output); - for (int i = 0; i < output.size(); ++i) { - const FieldDescriptor* field = output[i]; - if (!field->is_repeated()) continue; - reflection->SwapElements(message, field, 0, 1); - } -} - -inline void MapReflectionTester::MutableUnknownFieldsOfMapFieldsViaReflection( - Message* message) { - const Reflection* reflection = message->GetReflection(); - Message* sub_message = nullptr; - - sub_message = reflection->AddMessage(message, F("map_int32_int32")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_int64_int64")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_uint32_uint32")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_uint64_uint64")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_sint32_sint32")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_sint64_sint64")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_fixed32_fixed32")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_fixed64_fixed64")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_sfixed32_sfixed32")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_sfixed64_sfixed64")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_int32_float")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_int32_double")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_bool_bool")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_string_string")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_int32_bytes")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_int32_enum")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); - sub_message = reflection->AddMessage(message, F("map_int32_foreign_message")); - EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != - nullptr); -} - -inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( - const Message& message) { - std::string scratch; - const Reflection* reflection = message.GetReflection(); - const Message* sub_message; - MapKey map_key; - MapValueConstRef map_value_const_ref; - - // ----------------------------------------------------------------- - - ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_int32"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_int64_int64"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_uint32_uint32"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_uint64_uint64"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_sint32_sint32"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_sint64_sint64"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_fixed32_fixed32"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_fixed64_fixed64"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_sfixed32_sfixed32"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_sfixed64_sfixed64"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_float"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_double"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_bool_bool"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_string_string"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_bytes"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_enum"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_foreign_message"))); - - { - std::map<int32, int32> map; - map[0] = 0; - map[1] = 1; - for (int i = 0; i < 2; i++) { - // Check with RepeatedField Reflection - sub_message = - &reflection->GetRepeatedMessage(message, F("map_int32_int32"), i); - int32 key = sub_message->GetReflection()->GetInt32(*sub_message, - map_int32_int32_key_); - int32 val = sub_message->GetReflection()->GetInt32(*sub_message, - map_int32_int32_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetInt32Value(key); - EXPECT_TRUE( - reflection->ContainsMapKey(message, F("map_int32_int32"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_int32"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetInt32Value(), val); - } - } - { - std::map<int64, int64> map; - map[0] = 0; - map[1] = 1; - for (int i = 0; i < 2; i++) { - // Check with RepeatedField Reflection - sub_message = - &reflection->GetRepeatedMessage(message, F("map_int64_int64"), i); - int64 key = sub_message->GetReflection()->GetInt64(*sub_message, - map_int64_int64_key_); - int64 val = sub_message->GetReflection()->GetInt64(*sub_message, - map_int64_int64_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetInt64Value(key); - EXPECT_TRUE( - reflection->ContainsMapKey(message, F("map_int64_int64"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int64_int64"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetInt64Value(), val); - } - } - { - std::map<uint32, uint32> map; - map[0] = 0; - map[1] = 1; - for (int i = 0; i < 2; i++) { - // Check with RepeatedField Reflection - sub_message = - &reflection->GetRepeatedMessage(message, F("map_uint32_uint32"), i); - uint32 key = sub_message->GetReflection()->GetUInt32( - *sub_message, map_uint32_uint32_key_); - uint32 val = sub_message->GetReflection()->GetUInt32( - *sub_message, map_uint32_uint32_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetUInt32Value(key); - EXPECT_TRUE( - reflection->ContainsMapKey(message, F("map_uint32_uint32"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_uint32_uint32"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetUInt32Value(), val); - } - } - { - std::map<uint64, uint64> map; - map[0] = 0; - map[1] = 1; - for (int i = 0; i < 2; i++) { - sub_message = - &reflection->GetRepeatedMessage(message, F("map_uint64_uint64"), i); - uint64 key = sub_message->GetReflection()->GetUInt64( - *sub_message, map_uint64_uint64_key_); - uint64 val = sub_message->GetReflection()->GetUInt64( - *sub_message, map_uint64_uint64_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetUInt64Value(key); - EXPECT_TRUE( - reflection->ContainsMapKey(message, F("map_uint64_uint64"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_uint64_uint64"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetUInt64Value(), val); - } - } - { - std::map<int32, int32> map; - map[0] = 0; - map[1] = 1; - for (int i = 0; i < 2; i++) { - sub_message = - &reflection->GetRepeatedMessage(message, F("map_sint32_sint32"), i); - int32 key = sub_message->GetReflection()->GetInt32( - *sub_message, map_sint32_sint32_key_); - int32 val = sub_message->GetReflection()->GetInt32( - *sub_message, map_sint32_sint32_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetInt32Value(key); - EXPECT_EQ(true, reflection->ContainsMapKey( - message, F("map_sint32_sint32"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_sint32_sint32"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetInt32Value(), val); - } - } - { - std::map<int64, int64> map; - map[0] = 0; - map[1] = 1; - for (int i = 0; i < 2; i++) { - sub_message = - &reflection->GetRepeatedMessage(message, F("map_sint64_sint64"), i); - int64 key = sub_message->GetReflection()->GetInt64( - *sub_message, map_sint64_sint64_key_); - int64 val = sub_message->GetReflection()->GetInt64( - *sub_message, map_sint64_sint64_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetInt64Value(key); - EXPECT_EQ(true, reflection->ContainsMapKey( - message, F("map_sint64_sint64"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_sint64_sint64"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetInt64Value(), val); - } - } - { - std::map<uint32, uint32> map; - map[0] = 0; - map[1] = 1; - for (int i = 0; i < 2; i++) { - sub_message = - &reflection->GetRepeatedMessage(message, F("map_fixed32_fixed32"), i); - uint32 key = sub_message->GetReflection()->GetUInt32( - *sub_message, map_fixed32_fixed32_key_); - uint32 val = sub_message->GetReflection()->GetUInt32( - *sub_message, map_fixed32_fixed32_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetUInt32Value(key); - EXPECT_EQ(true, reflection->ContainsMapKey( - message, F("map_fixed32_fixed32"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_fixed32_fixed32"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetUInt32Value(), val); - } - } - { - std::map<uint64, uint64> map; - map[0] = 0; - map[1] = 1; - for (int i = 0; i < 2; i++) { - sub_message = - &reflection->GetRepeatedMessage(message, F("map_fixed64_fixed64"), i); - uint64 key = sub_message->GetReflection()->GetUInt64( - *sub_message, map_fixed64_fixed64_key_); - uint64 val = sub_message->GetReflection()->GetUInt64( - *sub_message, map_fixed64_fixed64_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetUInt64Value(key); - EXPECT_EQ(true, reflection->ContainsMapKey( - message, F("map_fixed64_fixed64"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_fixed64_fixed64"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetUInt64Value(), val); - } - } - { - std::map<int32, int32> map; - map[0] = 0; - map[1] = 1; - for (int i = 0; i < 2; i++) { - sub_message = &reflection->GetRepeatedMessage( - message, F("map_sfixed32_sfixed32"), i); - int32 key = sub_message->GetReflection()->GetInt32( - *sub_message, map_sfixed32_sfixed32_key_); - int32 val = sub_message->GetReflection()->GetInt32( - *sub_message, map_sfixed32_sfixed32_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetInt32Value(key); - EXPECT_EQ(true, reflection->ContainsMapKey( - message, F("map_sfixed32_sfixed32"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue( - message, F("map_sfixed32_sfixed32"), map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetInt32Value(), val); - } - } - { - std::map<int64, int64> map; - map[0] = 0; - map[1] = 1; - for (int i = 0; i < 2; i++) { - sub_message = &reflection->GetRepeatedMessage( - message, F("map_sfixed64_sfixed64"), i); - int64 key = sub_message->GetReflection()->GetInt64( - *sub_message, map_sfixed64_sfixed64_key_); - int64 val = sub_message->GetReflection()->GetInt64( - *sub_message, map_sfixed64_sfixed64_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetInt64Value(key); - EXPECT_EQ(true, reflection->ContainsMapKey( - message, F("map_sfixed64_sfixed64"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue( - message, F("map_sfixed64_sfixed64"), map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetInt64Value(), val); - } - } - { - std::map<int32, float> map; - map[0] = 0.0; - map[1] = 1.0; - for (int i = 0; i < 2; i++) { - sub_message = - &reflection->GetRepeatedMessage(message, F("map_int32_float"), i); - int32 key = sub_message->GetReflection()->GetInt32(*sub_message, - map_int32_float_key_); - float val = sub_message->GetReflection()->GetFloat(*sub_message, - map_int32_float_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetInt32Value(key); - EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_float"), - map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_float"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetFloatValue(), val); - } - } - { - std::map<int32, double> map; - map[0] = 0.0; - map[1] = 1.0; - for (int i = 0; i < 2; i++) { - sub_message = - &reflection->GetRepeatedMessage(message, F("map_int32_double"), i); - int32 key = sub_message->GetReflection()->GetInt32(*sub_message, - map_int32_double_key_); - double val = sub_message->GetReflection()->GetDouble( - *sub_message, map_int32_double_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetInt32Value(key); - EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_double"), - map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_double"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetDoubleValue(), val); - } - } - { - std::map<bool, bool> map; - map[false] = false; - map[true] = true; - for (int i = 0; i < 2; i++) { - sub_message = - &reflection->GetRepeatedMessage(message, F("map_bool_bool"), i); - bool key = sub_message->GetReflection()->GetBool(*sub_message, - map_bool_bool_key_); - bool val = sub_message->GetReflection()->GetBool(*sub_message, - map_bool_bool_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetBoolValue(key); - EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_bool_bool"), - map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_bool_bool"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetBoolValue(), val); - } - } - { - std::map<std::string, std::string> map; - map["0"] = "0"; - map["1"] = "1"; - for (int i = 0; i < 2; i++) { - sub_message = - &reflection->GetRepeatedMessage(message, F("map_string_string"), i); - std::string key = sub_message->GetReflection()->GetString( - *sub_message, map_string_string_key_); - std::string val = sub_message->GetReflection()->GetString( - *sub_message, map_string_string_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetStringValue(key); - EXPECT_EQ(true, reflection->ContainsMapKey( - message, F("map_string_string"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_string_string"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetStringValue(), val); - } - } - { - std::map<int32, std::string> map; - map[0] = "0"; - map[1] = "1"; - for (int i = 0; i < 2; i++) { - sub_message = - &reflection->GetRepeatedMessage(message, F("map_int32_bytes"), i); - int32 key = sub_message->GetReflection()->GetInt32(*sub_message, - map_int32_bytes_key_); - std::string val = sub_message->GetReflection()->GetString( - *sub_message, map_int32_bytes_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetInt32Value(key); - EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_bytes"), - map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_bytes"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetStringValue(), val); - } - } - { - std::map<int32, const EnumValueDescriptor*> map; - map[0] = map_enum_bar_; - map[1] = map_enum_baz_; - for (int i = 0; i < 2; i++) { - sub_message = - &reflection->GetRepeatedMessage(message, F("map_int32_enum"), i); - int32 key = sub_message->GetReflection()->GetInt32(*sub_message, - map_int32_enum_key_); - const EnumValueDescriptor* val = sub_message->GetReflection()->GetEnum( - *sub_message, map_int32_enum_val_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetInt32Value(key); - EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_enum"), - map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_enum"), - map_key, &map_value_const_ref)); - EXPECT_EQ(map_value_const_ref.GetEnumValue(), val->number()); - } - } - { - std::map<int32, int32> map; - map[0] = 0; - map[1] = 1; - for (int i = 0; i < 2; i++) { - sub_message = &reflection->GetRepeatedMessage( - message, F("map_int32_foreign_message"), i); - int32 key = sub_message->GetReflection()->GetInt32( - *sub_message, map_int32_foreign_message_key_); - const Message& foreign_message = sub_message->GetReflection()->GetMessage( - *sub_message, map_int32_foreign_message_val_); - int32 val = foreign_message.GetReflection()->GetInt32(foreign_message, - foreign_c_); - EXPECT_EQ(map[key], val); - // Check with Map Reflection - map_key.SetInt32Value(key); - EXPECT_EQ(true, reflection->ContainsMapKey( - message, F("map_int32_foreign_message"), map_key)); - EXPECT_TRUE(reflection->LookupMapValue(message, - F("map_int32_foreign_message"), - map_key, &map_value_const_ref)); - EXPECT_EQ(foreign_message.GetReflection()->GetInt32( - map_value_const_ref.GetMessageValue(), foreign_c_), - val); - } - } -} - -inline void MapReflectionTester::ExpectMapFieldsSetViaReflectionIterator( - Message* message) { - std::string scratch; - std::string serialized; - const Reflection* reflection = message->GetReflection(); - - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_int32"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int64_int64"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_uint32_uint32"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_uint64_uint64"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sint32_sint32"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sint64_sint64"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_fixed32_fixed32"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_fixed64_fixed64"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sfixed32_sfixed32"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sfixed64_sfixed64"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_float"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_double"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_bool_bool"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_string_string"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_bytes"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_enum"))); - ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_foreign_message"))); - - { - std::map<int32, int32> map; - map[0] = 0; - map[1] = 1; - int size = 0; - for (MapIterator iter = reflection->MapBegin(message, F("map_int32_int32")); - iter != reflection->MapEnd(message, F("map_int32_int32")); - ++iter, ++size) { - // Check const methods do not invalidate map. - message->DebugString(); - message->ShortDebugString(); - message->SerializeToString(&serialized); - message->SpaceUsedLong(); - message->ByteSizeLong(); - EXPECT_EQ(map[iter.GetKey().GetInt32Value()], - iter.GetValueRef().GetInt32Value()); - } - EXPECT_EQ(size, 2); - } - { - std::map<int64, int64> map; - map[0] = 0; - map[1] = 1; - for (MapIterator iter = reflection->MapBegin(message, F("map_int64_int64")); - iter != reflection->MapEnd(message, F("map_int64_int64")); ++iter) { - EXPECT_EQ(map[iter.GetKey().GetInt64Value()], - iter.GetValueRef().GetInt64Value()); - } - } - { - std::map<uint32, uint32> map; - map[0] = 0; - map[1] = 1; - for (MapIterator iter = - reflection->MapBegin(message, F("map_uint32_uint32")); - iter != reflection->MapEnd(message, F("map_uint32_uint32")); ++iter) { - EXPECT_EQ(map[iter.GetKey().GetUInt32Value()], - iter.GetValueRef().GetUInt32Value()); - } - } - { - std::map<uint64, uint64> map; - map[0] = 0; - map[1] = 1; - for (MapIterator iter = - reflection->MapBegin(message, F("map_uint64_uint64")); - iter != reflection->MapEnd(message, F("map_uint64_uint64")); ++iter) { - EXPECT_EQ(map[iter.GetKey().GetUInt64Value()], - iter.GetValueRef().GetUInt64Value()); - } - } - { - std::map<int32, int32> map; - map[0] = 0; - map[1] = 1; - for (MapIterator iter = - reflection->MapBegin(message, F("map_sint32_sint32")); - iter != reflection->MapEnd(message, F("map_sint32_sint32")); ++iter) { - EXPECT_EQ(map[iter.GetKey().GetInt32Value()], - iter.GetValueRef().GetInt32Value()); - } - } - { - std::map<int64, int64> map; - map[0] = 0; - map[1] = 1; - for (MapIterator iter = - reflection->MapBegin(message, F("map_sint64_sint64")); - iter != reflection->MapEnd(message, F("map_sint64_sint64")); ++iter) { - EXPECT_EQ(map[iter.GetKey().GetInt64Value()], - iter.GetValueRef().GetInt64Value()); - } - } - { - std::map<uint32, uint32> map; - map[0] = 0; - map[1] = 1; - for (MapIterator iter = - reflection->MapBegin(message, F("map_fixed32_fixed32")); - iter != reflection->MapEnd(message, F("map_fixed32_fixed32")); - ++iter) { - EXPECT_EQ(map[iter.GetKey().GetUInt32Value()], - iter.GetValueRef().GetUInt32Value()); - } - } - { - std::map<uint64, uint64> map; - map[0] = 0; - map[1] = 1; - for (MapIterator iter = - reflection->MapBegin(message, F("map_fixed64_fixed64")); - iter != reflection->MapEnd(message, F("map_fixed64_fixed64")); - ++iter) { - EXPECT_EQ(map[iter.GetKey().GetUInt64Value()], - iter.GetValueRef().GetUInt64Value()); - } - } - { - std::map<int32, int32> map; - map[0] = 0; - map[1] = 1; - for (MapIterator iter = - reflection->MapBegin(message, F("map_sfixed32_sfixed32")); - iter != reflection->MapEnd(message, F("map_sfixed32_sfixed32")); - ++iter) { - EXPECT_EQ(map[iter.GetKey().GetInt32Value()], - iter.GetValueRef().GetInt32Value()); - } - } - { - std::map<int32, float> map; - map[0] = 0.0; - map[1] = 1.0; - for (MapIterator iter = reflection->MapBegin(message, F("map_int32_float")); - iter != reflection->MapEnd(message, F("map_int32_float")); ++iter) { - EXPECT_EQ(map[iter.GetKey().GetInt32Value()], - iter.GetValueRef().GetFloatValue()); - } - } - { - std::map<int32, double> map; - map[0] = 0.0; - map[1] = 1.0; - for (MapIterator iter = - reflection->MapBegin(message, F("map_int32_double")); - iter != reflection->MapEnd(message, F("map_int32_double")); ++iter) { - EXPECT_EQ(map[iter.GetKey().GetInt32Value()], - iter.GetValueRef().GetDoubleValue()); - } - } - { - std::map<bool, bool> map; - map[false] = false; - map[true] = true; - for (MapIterator iter = reflection->MapBegin(message, F("map_bool_bool")); - iter != reflection->MapEnd(message, F("map_bool_bool")); ++iter) { - EXPECT_EQ(map[iter.GetKey().GetBoolValue()], - iter.GetValueRef().GetBoolValue()); - } - } - { - std::map<std::string, std::string> map; - map["0"] = "0"; - map["1"] = "1"; - int size = 0; - for (MapIterator iter = - reflection->MapBegin(message, F("map_string_string")); - iter != reflection->MapEnd(message, F("map_string_string")); - ++iter, ++size) { - // Check const methods do not invalidate map. - message->DebugString(); - message->ShortDebugString(); - message->SerializeToString(&serialized); - message->SpaceUsedLong(); - message->ByteSizeLong(); - EXPECT_EQ(map[iter.GetKey().GetStringValue()], - iter.GetValueRef().GetStringValue()); - } - EXPECT_EQ(size, 2); - } - { - std::map<int32, std::string> map; - map[0] = "0"; - map[1] = "1"; - for (MapIterator iter = reflection->MapBegin(message, F("map_int32_bytes")); - iter != reflection->MapEnd(message, F("map_int32_bytes")); ++iter) { - EXPECT_EQ(map[iter.GetKey().GetInt32Value()], - iter.GetValueRef().GetStringValue()); - } - } - { - std::map<int32, const EnumValueDescriptor*> map; - map[0] = map_enum_bar_; - map[1] = map_enum_baz_; - for (MapIterator iter = reflection->MapBegin(message, F("map_int32_enum")); - iter != reflection->MapEnd(message, F("map_int32_enum")); ++iter) { - EXPECT_EQ(map[iter.GetKey().GetInt32Value()]->number(), - iter.GetValueRef().GetEnumValue()); - } - } - { - std::map<int32, int32> map; - map[0] = 0; - map[1] = 1; - int size = 0; - for (MapIterator iter = - reflection->MapBegin(message, F("map_int32_foreign_message")); - iter != reflection->MapEnd(message, F("map_int32_foreign_message")); - ++iter, ++size) { - // Check const methods do not invalidate map. - message->DebugString(); - message->ShortDebugString(); - message->SerializeToString(&serialized); - message->SpaceUsedLong(); - message->ByteSizeLong(); - const Message& sub_message = iter.GetValueRef().GetMessageValue(); - EXPECT_EQ(map[iter.GetKey().GetInt32Value()], - sub_message.GetReflection()->GetInt32(sub_message, foreign_c_)); - } - EXPECT_EQ(size, 2); - } -} - -inline void MapReflectionTester::ExpectClearViaReflection( - const Message& message) { - const Reflection* reflection = message.GetReflection(); - // Map fields are empty. - EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_int32"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_int64_int64"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_uint32_uint32"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_uint64_uint64"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_sint32_sint32"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_sint64_sint64"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_fixed32_fixed32"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_fixed64_fixed64"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_sfixed32_sfixed32"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_sfixed64_sfixed64"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_float"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_double"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_bool_bool"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_string_string"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_bytes"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_enum"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_foreign_message"))); - EXPECT_TRUE(reflection->GetMapData(message, F("map_int32_foreign_message")) - ->IsMapValid()); -} - -inline void MapReflectionTester::ExpectClearViaReflectionIterator( - Message* message) { - const Reflection* reflection = message->GetReflection(); - EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_int32")) == - reflection->MapEnd(message, F("map_int32_int32"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_int64_int64")) == - reflection->MapEnd(message, F("map_int64_int64"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_uint32_uint32")) == - reflection->MapEnd(message, F("map_uint32_uint32"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_uint64_uint64")) == - reflection->MapEnd(message, F("map_uint64_uint64"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_sint32_sint32")) == - reflection->MapEnd(message, F("map_sint32_sint32"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_sint64_sint64")) == - reflection->MapEnd(message, F("map_sint64_sint64"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_fixed32_fixed32")) == - reflection->MapEnd(message, F("map_fixed32_fixed32"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_fixed64_fixed64")) == - reflection->MapEnd(message, F("map_fixed64_fixed64"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_sfixed32_sfixed32")) == - reflection->MapEnd(message, F("map_sfixed32_sfixed32"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_sfixed64_sfixed64")) == - reflection->MapEnd(message, F("map_sfixed64_sfixed64"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_float")) == - reflection->MapEnd(message, F("map_int32_float"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_double")) == - reflection->MapEnd(message, F("map_int32_double"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_bool_bool")) == - reflection->MapEnd(message, F("map_bool_bool"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_string_string")) == - reflection->MapEnd(message, F("map_string_string"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_bytes")) == - reflection->MapEnd(message, F("map_int32_bytes"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_enum")) == - reflection->MapEnd(message, F("map_int32_enum"))); - EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_foreign_message")) == - reflection->MapEnd(message, F("map_int32_foreign_message"))); -} - -} // namespace protobuf -} // namespace google - -#include <google/protobuf/port_undef.inc> +#undef BRIDGE_UNITTEST #endif // GOOGLE_PROTOBUF_MAP_TEST_UTIL_H__
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h index e718790..7f2892b 100644 --- a/src/google/protobuf/map_type_handler.h +++ b/src/google/protobuf/map_type_handler.h
@@ -28,8 +28,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifndef GOOGLE_PROTOBUF_TYPE_HANDLER_H__ -#define GOOGLE_PROTOBUF_TYPE_HANDLER_H__ +#ifndef GOOGLE_PROTOBUF_MAP_TYPE_HANDLER_H__ +#define GOOGLE_PROTOBUF_MAP_TYPE_HANDLER_H__ #include <google/protobuf/parse_context.h> #include <google/protobuf/io/coded_stream.h> @@ -100,19 +100,19 @@ TYPE_TRAITS(MESSAGE, Type, LENGTH_DELIMITED, true, false) TYPE_TRAITS(STRING, ArenaStringPtr, LENGTH_DELIMITED, false, false) TYPE_TRAITS(BYTES, ArenaStringPtr, LENGTH_DELIMITED, false, false) -TYPE_TRAITS(INT64, int64, VARINT, false, false) -TYPE_TRAITS(UINT64, uint64, VARINT, false, false) -TYPE_TRAITS(INT32, int32, VARINT, false, false) -TYPE_TRAITS(UINT32, uint32, VARINT, false, false) -TYPE_TRAITS(SINT64, int64, VARINT, false, false) -TYPE_TRAITS(SINT32, int32, VARINT, false, false) +TYPE_TRAITS(INT64, int64_t, VARINT, false, false) +TYPE_TRAITS(UINT64, uint64_t, VARINT, false, false) +TYPE_TRAITS(INT32, int32_t, VARINT, false, false) +TYPE_TRAITS(UINT32, uint32_t, VARINT, false, false) +TYPE_TRAITS(SINT64, int64_t, VARINT, false, false) +TYPE_TRAITS(SINT32, int32_t, VARINT, false, false) TYPE_TRAITS(ENUM, int, VARINT, false, true) TYPE_TRAITS(DOUBLE, double, FIXED64, false, false) TYPE_TRAITS(FLOAT, float, FIXED32, false, false) -TYPE_TRAITS(FIXED64, uint64, FIXED64, false, false) -TYPE_TRAITS(FIXED32, uint32, FIXED32, false, false) -TYPE_TRAITS(SFIXED64, int64, FIXED64, false, false) -TYPE_TRAITS(SFIXED32, int32, FIXED32, false, false) +TYPE_TRAITS(FIXED64, uint64_t, FIXED64, false, false) +TYPE_TRAITS(FIXED32, uint32_t, FIXED32, false, false) +TYPE_TRAITS(SFIXED64, int64_t, FIXED64, false, false) +TYPE_TRAITS(SFIXED32, int32_t, FIXED32, false, false) TYPE_TRAITS(BOOL, bool, VARINT, false, false) #undef TYPE_TRAITS @@ -149,8 +149,8 @@ static inline const char* Read(const char* ptr, ParseContext* ctx, MapEntryAccessorType* value); - static inline uint8* Write(int field, const MapEntryAccessorType& value, - uint8* ptr, io::EpsCopyOutputStream* stream); + static inline uint8_t* Write(int field, const MapEntryAccessorType& value, + uint8_t* ptr, io::EpsCopyOutputStream* stream); // Functions to manipulate data on memory. ======================== static inline const Type& GetExternalReference(const Type* value); @@ -170,46 +170,47 @@ static inline bool IsInitialized(Type* value); }; -#define MAP_HANDLER(FieldType) \ - template <typename Type> \ - class MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type> { \ - public: \ - typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ - Type>::MapEntryAccessorType \ - MapEntryAccessorType; \ - typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ - Type>::TypeOnMemory TypeOnMemory; \ - static const WireFormatLite::WireType kWireType = \ - MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ - Type>::kWireType; \ - static const bool kIsMessage = \ - MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ - Type>::kIsMessage; \ - static const bool kIsEnum = \ - MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ - Type>::kIsEnum; \ - static inline int ByteSize(const MapEntryAccessorType& value); \ - static inline int GetCachedSize(const MapEntryAccessorType& value); \ - static inline bool Read(io::CodedInputStream* input, \ - MapEntryAccessorType* value); \ - static inline const char* Read(const char* begin, ParseContext* ctx, \ - MapEntryAccessorType* value); \ - static inline uint8* Write(int field, const MapEntryAccessorType& value, \ - uint8* ptr, io::EpsCopyOutputStream* stream); \ - static inline const MapEntryAccessorType& GetExternalReference( \ - const TypeOnMemory& value); \ - static inline void DeleteNoArena(const TypeOnMemory& x); \ - static inline void Merge(const MapEntryAccessorType& from, \ - TypeOnMemory* to, Arena* arena); \ - static inline void Clear(TypeOnMemory* value, Arena* arena); \ - static inline size_t SpaceUsedInMapEntryLong(const TypeOnMemory& value); \ - static inline const MapEntryAccessorType& DefaultIfNotInitialized( \ - const TypeOnMemory& value); \ - static inline bool IsInitialized(const TypeOnMemory& value); \ - static void DeleteNoArena(TypeOnMemory& value); \ - static constexpr TypeOnMemory Constinit(); \ - static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \ - Arena* arena); \ +#define MAP_HANDLER(FieldType) \ + template <typename Type> \ + class MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type> { \ + public: \ + typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ + Type>::MapEntryAccessorType \ + MapEntryAccessorType; \ + typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ + Type>::TypeOnMemory TypeOnMemory; \ + static const WireFormatLite::WireType kWireType = \ + MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ + Type>::kWireType; \ + static const bool kIsMessage = \ + MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ + Type>::kIsMessage; \ + static const bool kIsEnum = \ + MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ + Type>::kIsEnum; \ + static inline int ByteSize(const MapEntryAccessorType& value); \ + static inline int GetCachedSize(const MapEntryAccessorType& value); \ + static inline bool Read(io::CodedInputStream* input, \ + MapEntryAccessorType* value); \ + static inline const char* Read(const char* begin, ParseContext* ctx, \ + MapEntryAccessorType* value); \ + static inline uint8_t* Write(int field, const MapEntryAccessorType& value, \ + uint8_t* ptr, \ + io::EpsCopyOutputStream* stream); \ + static inline const MapEntryAccessorType& GetExternalReference( \ + const TypeOnMemory& value); \ + static inline void DeleteNoArena(const TypeOnMemory& x); \ + static inline void Merge(const MapEntryAccessorType& from, \ + TypeOnMemory* to, Arena* arena); \ + static inline void Clear(TypeOnMemory* value, Arena* arena); \ + static inline size_t SpaceUsedInMapEntryLong(const TypeOnMemory& value); \ + static inline const MapEntryAccessorType& DefaultIfNotInitialized( \ + const TypeOnMemory& value); \ + static inline bool IsInitialized(const TypeOnMemory& value); \ + static void DeleteNoArena(TypeOnMemory& value); \ + static constexpr TypeOnMemory Constinit(); \ + static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \ + Arena* arena); \ }; MAP_HANDLER(STRING) MAP_HANDLER(BYTES) @@ -317,33 +318,35 @@ #undef GET_FIXED_CACHED_SIZE template <typename Type> -inline uint8* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Write( - int field, const MapEntryAccessorType& value, uint8* ptr, +inline uint8_t* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Write( + int field, const MapEntryAccessorType& value, uint8_t* ptr, io::EpsCopyOutputStream* stream) { ptr = stream->EnsureSpace(ptr); return WireFormatLite::InternalWriteMessage(field, value, ptr, stream); } -#define WRITE_METHOD(FieldType, DeclaredType) \ - template <typename Type> \ - inline uint8* MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Write( \ - int field, const MapEntryAccessorType& value, uint8* ptr, \ - io::EpsCopyOutputStream* stream) { \ - ptr = stream->EnsureSpace(ptr); \ - return stream->Write##DeclaredType(field, value, ptr); \ +#define WRITE_METHOD(FieldType, DeclaredType) \ + template <typename Type> \ + inline uint8_t* \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Write( \ + int field, const MapEntryAccessorType& value, uint8_t* ptr, \ + io::EpsCopyOutputStream* stream) { \ + ptr = stream->EnsureSpace(ptr); \ + return stream->Write##DeclaredType(field, value, ptr); \ } WRITE_METHOD(STRING, String) WRITE_METHOD(BYTES, Bytes) #undef WRITE_METHOD -#define WRITE_METHOD(FieldType, DeclaredType) \ - template <typename Type> \ - inline uint8* MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Write( \ - int field, const MapEntryAccessorType& value, uint8* ptr, \ - io::EpsCopyOutputStream* stream) { \ - ptr = stream->EnsureSpace(ptr); \ - return WireFormatLite::Write##DeclaredType##ToArray(field, value, ptr); \ +#define WRITE_METHOD(FieldType, DeclaredType) \ + template <typename Type> \ + inline uint8_t* \ + MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Write( \ + int field, const MapEntryAccessorType& value, uint8_t* ptr, \ + io::EpsCopyOutputStream* stream) { \ + ptr = stream->EnsureSpace(ptr); \ + return WireFormatLite::Write##DeclaredType##ToArray(field, value, ptr); \ } WRITE_METHOD(INT64, Int64) @@ -403,23 +406,23 @@ return ctx->ReadString(ptr, size, value); } -inline const char* ReadINT64(const char* ptr, int64* value) { - return VarintParse(ptr, reinterpret_cast<uint64*>(value)); +inline const char* ReadINT64(const char* ptr, int64_t* value) { + return VarintParse(ptr, reinterpret_cast<uint64_t*>(value)); } -inline const char* ReadUINT64(const char* ptr, uint64* value) { +inline const char* ReadUINT64(const char* ptr, uint64_t* value) { return VarintParse(ptr, value); } -inline const char* ReadINT32(const char* ptr, int32* value) { - return VarintParse(ptr, reinterpret_cast<uint32*>(value)); +inline const char* ReadINT32(const char* ptr, int32_t* value) { + return VarintParse(ptr, reinterpret_cast<uint32_t*>(value)); } -inline const char* ReadUINT32(const char* ptr, uint32* value) { +inline const char* ReadUINT32(const char* ptr, uint32_t* value) { return VarintParse(ptr, value); } -inline const char* ReadSINT64(const char* ptr, int64* value) { +inline const char* ReadSINT64(const char* ptr, int64_t* value) { *value = ReadVarintZigZag64(&ptr); return ptr; } -inline const char* ReadSINT32(const char* ptr, int32* value) { +inline const char* ReadSINT32(const char* ptr, int32_t* value) { *value = ReadVarintZigZag32(&ptr); return ptr; } @@ -444,16 +447,16 @@ inline const char* ReadDOUBLE(const char* ptr, double* value) { return ReadUnaligned(ptr, value); } -inline const char* ReadFIXED64(const char* ptr, uint64* value) { +inline const char* ReadFIXED64(const char* ptr, uint64_t* value) { return ReadUnaligned(ptr, value); } -inline const char* ReadFIXED32(const char* ptr, uint32* value) { +inline const char* ReadFIXED32(const char* ptr, uint32_t* value) { return ReadUnaligned(ptr, value); } -inline const char* ReadSFIXED64(const char* ptr, int64* value) { +inline const char* ReadSFIXED64(const char* ptr, int64_t* value) { return ReadUnaligned(ptr, value); } -inline const char* ReadSFIXED32(const char* ptr, int32* value) { +inline const char* ReadSFIXED32(const char* ptr, int32_t* value) { return ReadUnaligned(ptr, value); } @@ -685,4 +688,4 @@ } // namespace protobuf } // namespace google -#endif // GOOGLE_PROTOBUF_TYPE_HANDLER_H__ +#endif // GOOGLE_PROTOBUF_MAP_TYPE_HANDLER_H__
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index 744bbc6..9c8c648 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc
@@ -166,8 +166,8 @@ return WireFormat::_InternalParse(this, ptr, ctx); } -uint8* Message::_InternalSerialize(uint8* target, - io::EpsCopyOutputStream* stream) const { +uint8_t* Message::_InternalSerialize(uint8_t* target, + io::EpsCopyOutputStream* stream) const { return WireFormat::_InternalSerialize(*this, target, stream); } @@ -183,15 +183,111 @@ "Must implement one or the other."; } +size_t Message::ComputeUnknownFieldsSize( + size_t total_size, internal::CachedSize* cached_size) const { + total_size += WireFormat::ComputeUnknownFieldsSize( + _internal_metadata_.unknown_fields<UnknownFieldSet>( + UnknownFieldSet::default_instance)); + cached_size->Set(internal::ToCachedSize(total_size)); + return total_size; +} + +size_t Message::MaybeComputeUnknownFieldsSize( + size_t total_size, internal::CachedSize* cached_size) const { + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + return ComputeUnknownFieldsSize(total_size, cached_size); + } + cached_size->Set(internal::ToCachedSize(total_size)); + return total_size; +} + size_t Message::SpaceUsedLong() const { return GetReflection()->SpaceUsedLong(*this); } -uint64 Message::GetInvariantPerBuild(uint64 salt) { +uint64_t Message::GetInvariantPerBuild(uint64_t salt) { return salt; } // ============================================================================= +// ZeroFieldsBase + +namespace internal { + +void ZeroFieldsBase::Clear() { + _internal_metadata_.Clear<UnknownFieldSet>(); // +} + +ZeroFieldsBase::~ZeroFieldsBase() { + if (GetArenaForAllocation() != nullptr) return; + _internal_metadata_.Delete<UnknownFieldSet>(); +} + +size_t ZeroFieldsBase::ByteSizeLong() const { + return MaybeComputeUnknownFieldsSize(0, &_cached_size_); +} + +const char* ZeroFieldsBase::_InternalParse(const char* ptr, + internal::ParseContext* ctx) { +#define CHK_(x) \ + if (PROTOBUF_PREDICT_FALSE(!(x))) { \ + goto failure; \ + } + + while (!ctx->Done(&ptr)) { + uint32_t tag; + ptr = internal::ReadTag(ptr, &tag); + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, _internal_metadata_.mutable_unknown_fields<UnknownFieldSet>(), ptr, + ctx); + CHK_(ptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +::uint8_t* ZeroFieldsBase::_InternalSerialize( + ::uint8_t* target, io::EpsCopyOutputStream* stream) const { + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<UnknownFieldSet>( + UnknownFieldSet::default_instance), + target, stream); + } + return target; +} + +void ZeroFieldsBase::MergeImpl(Message* to_param, const Message& from_param) { + auto* to = static_cast<ZeroFieldsBase*>(to_param); + const auto* from = static_cast<const ZeroFieldsBase*>(&from_param); + GOOGLE_DCHECK_NE(from, to); + to->_internal_metadata_.MergeFrom<UnknownFieldSet>(from->_internal_metadata_); +} + +void ZeroFieldsBase::CopyImpl(Message* to_param, const Message& from_param) { + auto* to = static_cast<ZeroFieldsBase*>(to_param); + const auto* from = static_cast<const ZeroFieldsBase*>(&from_param); + if (from == to) return; + to->_internal_metadata_.Clear<UnknownFieldSet>(); + to->_internal_metadata_.MergeFrom<UnknownFieldSet>(from->_internal_metadata_); +} + +void ZeroFieldsBase::InternalSwap(ZeroFieldsBase* other) { + _internal_metadata_.Swap<UnknownFieldSet>(&other->_internal_metadata_); +} + +} // namespace internal + +// ============================================================================= // MessageFactory MessageFactory::~MessageFactory() {} @@ -325,14 +421,14 @@ #define HANDLE_PRIMITIVE_TYPE(TYPE, type) \ case FieldDescriptor::CPPTYPE_##TYPE: \ return GetSingleton<internal::RepeatedFieldPrimitiveAccessor<type> >(); - HANDLE_PRIMITIVE_TYPE(INT32, int32) - HANDLE_PRIMITIVE_TYPE(UINT32, uint32) - HANDLE_PRIMITIVE_TYPE(INT64, int64) - HANDLE_PRIMITIVE_TYPE(UINT64, uint64) + HANDLE_PRIMITIVE_TYPE(INT32, int32_t) + HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t) + HANDLE_PRIMITIVE_TYPE(INT64, int64_t) + HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t) HANDLE_PRIMITIVE_TYPE(FLOAT, float) HANDLE_PRIMITIVE_TYPE(DOUBLE, double) HANDLE_PRIMITIVE_TYPE(BOOL, bool) - HANDLE_PRIMITIVE_TYPE(ENUM, int32) + HANDLE_PRIMITIVE_TYPE(ENUM, int32_t) #undef HANDLE_PRIMITIVE_TYPE case FieldDescriptor::CPPTYPE_STRING: switch (field->options().ctype()) {
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index df8e895..b4fa705 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h
@@ -120,6 +120,7 @@ #include <google/protobuf/arena.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/generated_message_util.h> #include <google/protobuf/message_lite.h> #include <google/protobuf/port.h> @@ -144,6 +145,7 @@ // Defined in other files. class AssignDescriptorsHelper; class DynamicMessageFactory; +class DynamicMessageReflectionHelper; class GeneratedMessageReflectionTestHelper; class MapKey; class MapValueConstRef; @@ -155,6 +157,7 @@ struct DescriptorTable; class MapFieldBase; class SwapFieldHelper; +class CachedSize; } class UnknownFieldSet; // unknown_field_set.h namespace io { @@ -201,18 +204,18 @@ namespace internal { template <class To> -inline To* GetPointerAtOffset(Message* message, uint32 offset) { +inline To* GetPointerAtOffset(Message* message, uint32_t offset) { return reinterpret_cast<To*>(reinterpret_cast<char*>(message) + offset); } template <class To> -const To* GetConstPointerAtOffset(const Message* message, uint32 offset) { +const To* GetConstPointerAtOffset(const Message* message, uint32_t offset) { return reinterpret_cast<const To*>(reinterpret_cast<const char*>(message) + offset); } template <class To> -const To& GetConstRefAtOffset(const Message& message, uint32 offset) { +const To& GetConstRefAtOffset(const Message& message, uint32_t offset) { return *GetConstPointerAtOffset<To>(&message, offset); } @@ -333,8 +336,8 @@ const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) override; size_t ByteSizeLong() const override; - uint8* _InternalSerialize(uint8* target, - io::EpsCopyOutputStream* stream) const override; + uint8_t* _InternalSerialize(uint8_t* target, + io::EpsCopyOutputStream* stream) const override; private: // This is called only by the default implementation of ByteSize(), to @@ -388,16 +391,50 @@ inline explicit Message(Arena* arena, bool is_message_owned = false) : MessageLite(arena, is_message_owned) {} + size_t ComputeUnknownFieldsSize(size_t total_size, + internal::CachedSize* cached_size) const; + size_t MaybeComputeUnknownFieldsSize(size_t total_size, + internal::CachedSize* cached_size) const; protected: - static uint64 GetInvariantPerBuild(uint64 salt); + static uint64_t GetInvariantPerBuild(uint64_t salt); private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); }; namespace internal { +// To save code size, protos without any fields are derived from ZeroFieldsBase +// rather than Message. +class PROTOBUF_EXPORT ZeroFieldsBase : public Message { + public: + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final { return true; } + size_t ByteSizeLong() const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + const char* _InternalParse(const char* ptr, + internal::ParseContext* ctx) final; + ::uint8_t* _InternalSerialize(::uint8_t* target, + io::EpsCopyOutputStream* stream) const final; + + protected: + constexpr ZeroFieldsBase() {} + explicit ZeroFieldsBase(Arena* arena, bool is_message_owned) + : Message(arena, is_message_owned) {} + ZeroFieldsBase(const ZeroFieldsBase&) = delete; + ZeroFieldsBase& operator=(const ZeroFieldsBase&) = delete; + ~ZeroFieldsBase() override; + + void SetCachedSize(int size) const final { _cached_size_.Set(size); } + + static void MergeImpl(Message* to, const Message& from); + static void CopyImpl(Message* to, const Message& from); + void InternalSwap(ZeroFieldsBase* other); + + mutable internal::CachedSize _cached_size_; +}; + // Forward-declare interfaces used to implement RepeatedFieldRef. // These are protobuf internals that users shouldn't care about. class RepeatedFieldAccessor; @@ -503,6 +540,12 @@ PROTOBUF_MUST_USE_RESULT Message* ReleaseLast( Message* message, const FieldDescriptor* field) const; + // Similar to ReleaseLast() without internal safety and ownershp checks. This + // method should only be used when the objects are on the same arena or paired + // with a call to `UnsafeArenaAddAllocatedMessage`. + Message* UnsafeArenaReleaseLast(Message* message, + const FieldDescriptor* field) const; + // Swap the complete contents of two messages. void Swap(Message* message1, Message* message2) const; @@ -514,6 +557,16 @@ void SwapElements(Message* message, const FieldDescriptor* field, int index1, int index2) const; + // Swap without internal safety and ownership checks. This method should only + // be used when the objects are on the same arena. + void UnsafeArenaSwap(Message* lhs, Message* rhs) const; + + // SwapFields without internal safety and ownership checks. This method should + // only be used when the objects are on the same arena. + void UnsafeArenaSwapFields( + Message* lhs, Message* rhs, + const std::vector<const FieldDescriptor*>& fields) const; + // List all fields of the message which are currently set, except for unknown // fields, but including extension known to the parser (i.e. compiled in). // Singular fields will only be listed if HasField(field) would return true @@ -529,10 +582,12 @@ // These get the value of a non-repeated field. They return the default // value for fields that aren't set. - int32 GetInt32(const Message& message, const FieldDescriptor* field) const; - int64 GetInt64(const Message& message, const FieldDescriptor* field) const; - uint32 GetUInt32(const Message& message, const FieldDescriptor* field) const; - uint64 GetUInt64(const Message& message, const FieldDescriptor* field) const; + int32_t GetInt32(const Message& message, const FieldDescriptor* field) const; + int64_t GetInt64(const Message& message, const FieldDescriptor* field) const; + uint32_t GetUInt32(const Message& message, + const FieldDescriptor* field) const; + uint64_t GetUInt64(const Message& message, + const FieldDescriptor* field) const; float GetFloat(const Message& message, const FieldDescriptor* field) const; double GetDouble(const Message& message, const FieldDescriptor* field) const; bool GetBool(const Message& message, const FieldDescriptor* field) const; @@ -577,13 +632,13 @@ // These mutate the value of a non-repeated field. void SetInt32(Message* message, const FieldDescriptor* field, - int32 value) const; + int32_t value) const; void SetInt64(Message* message, const FieldDescriptor* field, - int64 value) const; + int64_t value) const; void SetUInt32(Message* message, const FieldDescriptor* field, - uint32 value) const; + uint32_t value) const; void SetUInt64(Message* message, const FieldDescriptor* field, - uint64 value) const; + uint64_t value) const; void SetFloat(Message* message, const FieldDescriptor* field, float value) const; void SetDouble(Message* message, const FieldDescriptor* field, @@ -652,14 +707,14 @@ // Repeated field getters ------------------------------------------ // These get the value of one element of a repeated field. - int32 GetRepeatedInt32(const Message& message, const FieldDescriptor* field, - int index) const; - int64 GetRepeatedInt64(const Message& message, const FieldDescriptor* field, - int index) const; - uint32 GetRepeatedUInt32(const Message& message, const FieldDescriptor* field, + int32_t GetRepeatedInt32(const Message& message, const FieldDescriptor* field, int index) const; - uint64 GetRepeatedUInt64(const Message& message, const FieldDescriptor* field, + int64_t GetRepeatedInt64(const Message& message, const FieldDescriptor* field, int index) const; + uint32_t GetRepeatedUInt32(const Message& message, + const FieldDescriptor* field, int index) const; + uint64_t GetRepeatedUInt64(const Message& message, + const FieldDescriptor* field, int index) const; float GetRepeatedFloat(const Message& message, const FieldDescriptor* field, int index) const; double GetRepeatedDouble(const Message& message, const FieldDescriptor* field, @@ -693,13 +748,13 @@ // These mutate the value of one element of a repeated field. void SetRepeatedInt32(Message* message, const FieldDescriptor* field, - int index, int32 value) const; + int index, int32_t value) const; void SetRepeatedInt64(Message* message, const FieldDescriptor* field, - int index, int64 value) const; + int index, int64_t value) const; void SetRepeatedUInt32(Message* message, const FieldDescriptor* field, - int index, uint32 value) const; + int index, uint32_t value) const; void SetRepeatedUInt64(Message* message, const FieldDescriptor* field, - int index, uint64 value) const; + int index, uint64_t value) const; void SetRepeatedFloat(Message* message, const FieldDescriptor* field, int index, float value) const; void SetRepeatedDouble(Message* message, const FieldDescriptor* field, @@ -730,13 +785,13 @@ // These add an element to a repeated field. void AddInt32(Message* message, const FieldDescriptor* field, - int32 value) const; + int32_t value) const; void AddInt64(Message* message, const FieldDescriptor* field, - int64 value) const; + int64_t value) const; void AddUInt32(Message* message, const FieldDescriptor* field, - uint32 value) const; + uint32_t value) const; void AddUInt64(Message* message, const FieldDescriptor* field, - uint64 value) const; + uint64_t value) const; void AddFloat(Message* message, const FieldDescriptor* field, float value) const; void AddDouble(Message* message, const FieldDescriptor* field, @@ -765,6 +820,13 @@ void AddAllocatedMessage(Message* message, const FieldDescriptor* field, Message* new_entry) const; + // Similar to AddAllocatedMessage() without internal safety and ownership + // checks. This method should only be used when the objects are on the same + // arena or paired with a call to `UnsafeArenaReleaseLast`. + void UnsafeArenaAddAllocatedMessage(Message* message, + const FieldDescriptor* field, + Message* new_entry) const; + // Get a RepeatedFieldRef object that can be used to read the underlying // repeated field. The type parameter T must be set according to the @@ -772,14 +834,14 @@ // to acceptable T. // // field->cpp_type() T - // CPPTYPE_INT32 int32 - // CPPTYPE_UINT32 uint32 - // CPPTYPE_INT64 int64 - // CPPTYPE_UINT64 uint64 + // CPPTYPE_INT32 int32_t + // CPPTYPE_UINT32 uint32_t + // CPPTYPE_INT64 int64_t + // CPPTYPE_UINT64 uint64_t // CPPTYPE_DOUBLE double // CPPTYPE_FLOAT float // CPPTYPE_BOOL bool - // CPPTYPE_ENUM generated enum type or int32 + // CPPTYPE_ENUM generated enum type or int32_t // CPPTYPE_STRING std::string // CPPTYPE_MESSAGE generated message type or google::protobuf::Message // @@ -1010,6 +1072,7 @@ friend class ::PROTOBUF_NAMESPACE_ID::MessageLayoutInspector; friend class ::PROTOBUF_NAMESPACE_ID::AssignDescriptorsHelper; friend class DynamicMessageFactory; + friend class DynamicMessageReflectionHelper; friend class GeneratedMessageReflectionTestHelper; friend class python::MapReflectionFriend; friend class python::MessageReflectionFriend; @@ -1101,11 +1164,11 @@ const Message* GetDefaultMessageInstance(const FieldDescriptor* field) const; - inline const uint32* GetHasBits(const Message& message) const; - inline uint32* MutableHasBits(Message* message) const; - inline uint32 GetOneofCase(const Message& message, - const OneofDescriptor* oneof_descriptor) const; - inline uint32* MutableOneofCase( + inline const uint32_t* GetHasBits(const Message& message) const; + inline uint32_t* MutableHasBits(Message* message) const; + inline uint32_t GetOneofCase(const Message& message, + const OneofDescriptor* oneof_descriptor) const; + inline uint32_t* MutableOneofCase( Message* message, const OneofDescriptor* oneof_descriptor) const; inline bool HasExtensionSet(const Message& /* message */) const { return schema_.HasExtensionSet(); @@ -1118,6 +1181,8 @@ internal::InternalMetadata* MutableInternalMetadata(Message* message) const; + inline bool IsInlined(const FieldDescriptor* field) const; + inline bool HasBit(const Message& message, const FieldDescriptor* field) const; inline void SetBit(Message* message, const FieldDescriptor* field) const; @@ -1125,6 +1190,12 @@ inline void SwapBit(Message* message1, Message* message2, const FieldDescriptor* field) const; + inline const uint32_t* GetInlinedStringDonatedArray( + const Message& message) const; + inline uint32_t* MutableInlinedStringDonatedArray(Message* message) const; + inline bool IsInlinedStringDonated(const Message& message, + const FieldDescriptor* field) const; + // Shallow-swap fields listed in fields vector of two messages. It is the // caller's responsibility to make sure shallow swap is safe. void UnsafeShallowSwapFields( @@ -1144,14 +1215,10 @@ void SwapFieldsImpl(Message* message1, Message* message2, const std::vector<const FieldDescriptor*>& fields) const; - void SwapOneofField(Message* message1, Message* message2, + template <bool unsafe_shallow_swap> + void SwapOneofField(Message* lhs, Message* rhs, const OneofDescriptor* oneof_descriptor) const; - // Unsafe but shallow version of SwapOneofField. - void UnsafeShallowSwapOneofField( - Message* message1, Message* message2, - const OneofDescriptor* oneof_descriptor) const; - inline bool HasOneofField(const Message& message, const FieldDescriptor* field) const; inline void SetOneofCase(Message* message, @@ -1294,10 +1361,10 @@ Reflection::MutableRepeatedFieldInternal<TYPE>( \ Message * message, const FieldDescriptor* field) const; -DECLARE_GET_REPEATED_FIELD(int32) -DECLARE_GET_REPEATED_FIELD(int64) -DECLARE_GET_REPEATED_FIELD(uint32) -DECLARE_GET_REPEATED_FIELD(uint64) +DECLARE_GET_REPEATED_FIELD(int32_t) +DECLARE_GET_REPEATED_FIELD(int64_t) +DECLARE_GET_REPEATED_FIELD(uint32_t) +DECLARE_GET_REPEATED_FIELD(uint64_t) DECLARE_GET_REPEATED_FIELD(float) DECLARE_GET_REPEATED_FIELD(double) DECLARE_GET_REPEATED_FIELD(bool) @@ -1422,6 +1489,28 @@ const Type& Reflection::DefaultRaw(const FieldDescriptor* field) const { return *reinterpret_cast<const Type*>(schema_.GetFieldDefault(field)); } + +uint32_t Reflection::GetOneofCase( + const Message& message, const OneofDescriptor* oneof_descriptor) const { + GOOGLE_DCHECK(!oneof_descriptor->is_synthetic()); + return internal::GetConstRefAtOffset<uint32_t>( + message, schema_.GetOneofCaseOffset(oneof_descriptor)); +} + +bool Reflection::HasOneofField(const Message& message, + const FieldDescriptor* field) const { + return (GetOneofCase(message, field->containing_oneof()) == + static_cast<uint32_t>(field->number())); +} + +template <typename Type> +const Type& Reflection::GetRaw(const Message& message, + const FieldDescriptor* field) const { + GOOGLE_DCHECK(!schema_.InRealOneof(field) || HasOneofField(message, field)) + << "Field = " << field->full_name(); + return internal::GetConstRefAtOffset<Type>(message, + schema_.GetFieldOffset(field)); +} } // namespace protobuf } // namespace google
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index f137675..3dea09e 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc
@@ -336,15 +336,15 @@ // =================================================================== -inline uint8* SerializeToArrayImpl(const MessageLite& msg, uint8* target, - int size) { +inline uint8_t* SerializeToArrayImpl(const MessageLite& msg, uint8_t* target, + int size) { constexpr bool debug = false; if (debug) { // Force serialization to a stream with a block size of 1, which forces // all writes to the stream to cross buffers triggering all fallback paths // in the unittests when serializing to string / array. io::ArrayOutputStream stream(target, size, 1); - uint8* ptr; + uint8_t* ptr; io::EpsCopyOutputStream out( &stream, io::CodedOutputStream::IsDefaultSerializationDeterministic(), &ptr); @@ -362,7 +362,7 @@ } } -uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const { +uint8_t* MessageLite::SerializeWithCachedSizesToArray(uint8_t* target) const { // We only optimize this when using optimize_for = SPEED. In other cases // we just use the CodedOutputStream path. return SerializeToArrayImpl(*this, target, GetCachedSize()); @@ -389,7 +389,7 @@ } int final_byte_count = output->ByteCount(); - if (final_byte_count - original_byte_count != static_cast<int64>(size)) { + if (final_byte_count - original_byte_count != static_cast<int64_t>(size)) { ByteSizeConsistencyError(size, ByteSizeLong(), final_byte_count - original_byte_count, *this); } @@ -412,7 +412,7 @@ return false; } - uint8* target; + uint8_t* target; io::EpsCopyOutputStream stream( output, io::CodedOutputStream::IsDefaultSerializationDeterministic(), &target); @@ -459,9 +459,9 @@ return false; } - STLStringResizeUninitialized(output, old_size + byte_size); - uint8* start = - reinterpret_cast<uint8*>(io::mutable_string_data(output) + old_size); + STLStringResizeUninitializedAmortized(output, old_size + byte_size); + uint8_t* start = + reinterpret_cast<uint8_t*>(io::mutable_string_data(output) + old_size); SerializeToArrayImpl(*this, start, byte_size); return true; } @@ -488,8 +488,8 @@ << " exceeded maximum protobuf size of 2GB: " << byte_size; return false; } - if (size < static_cast<int64>(byte_size)) return false; - uint8* start = reinterpret_cast<uint8*>(data); + if (size < static_cast<int64_t>(byte_size)) return false; + uint8_t* start = reinterpret_cast<uint8_t*>(data); SerializeToArrayImpl(*this, start, byte_size); return true; }
diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index f82bd0c..d813850 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h
@@ -158,7 +158,7 @@ // Prefer c++14 aligned_storage, but for compatibility this will do. union AlignedUnion { alignas(T) char space[sizeof(T)]; - int64 align_to_int64; + int64_t align_to_int64; void* align_to_ptr; } union_; }; @@ -449,7 +449,7 @@ // must point at a byte array of at least ByteSize() bytes. Whether to use // deterministic serialization, e.g., maps in sorted order, is determined by // CodedOutputStream::IsDefaultSerializationDeterministic(). - uint8* SerializeWithCachedSizesToArray(uint8* target) const; + uint8_t* SerializeWithCachedSizesToArray(uint8_t* target) const; // Returns the result of the last call to ByteSize(). An embedded message's // size is needed both to serialize it (because embedded messages are @@ -507,9 +507,9 @@ bool ParseFrom(const T& input); // Fast path when conditions match (ie. non-deterministic) - // uint8* _InternalSerialize(uint8* ptr) const; - virtual uint8* _InternalSerialize(uint8* ptr, - io::EpsCopyOutputStream* stream) const = 0; + // uint8_t* _InternalSerialize(uint8_t* ptr) const; + virtual uint8_t* _InternalSerialize( + uint8_t* ptr, io::EpsCopyOutputStream* stream) const = 0; // Identical to IsInitialized() except that it logs an error message. bool IsInitializedWithErrors() const {
diff --git a/src/google/protobuf/parse_context.cc b/src/google/protobuf/parse_context.cc index 1bf5ef8..354d748 100644 --- a/src/google/protobuf/parse_context.cc +++ b/src/google/protobuf/parse_context.cc
@@ -55,7 +55,7 @@ auto ptr = begin + overrun; auto end = begin + kSlopBytes; while (ptr < end) { - uint32 tag; + uint32_t tag; ptr = ReadTag(ptr, &tag); if (ptr == nullptr || ptr > end) return false; // ending on 0 tag is allowed and is the major reason for the necessity of @@ -63,7 +63,7 @@ if (tag == 0) return true; switch (tag & 7) { case 0: { // Varint - uint64 val; + uint64_t val; ptr = VarintParse(ptr, &val); if (ptr == nullptr) return false; break; @@ -73,7 +73,7 @@ break; } case 2: { // len delim - int32 size = ReadSize(&ptr); + int32_t size = ReadSize(&ptr); if (ptr == nullptr || size > end - ptr) return false; ptr += size; break; @@ -240,11 +240,11 @@ void byteswap<1>(void* p) {} template <> void byteswap<4>(void* p) { - *static_cast<uint32*>(p) = bswap_32(*static_cast<uint32*>(p)); + *static_cast<uint32_t*>(p) = bswap_32(*static_cast<uint32_t*>(p)); } template <> void byteswap<8>(void* p) { - *static_cast<uint64*>(p) = bswap_64(*static_cast<uint64*>(p)); + *static_cast<uint64_t*>(p) = bswap_64(*static_cast<uint64_t*>(p)); } const char* EpsCopyInputStream::InitFrom(io::ZeroCopyInputStream* zcis) { @@ -296,29 +296,30 @@ return ParseMessage(reinterpret_cast<MessageLite*>(msg), ptr); } -inline void WriteVarint(uint64 val, std::string* s) { +inline void WriteVarint(uint64_t val, std::string* s) { while (val >= 128) { - uint8 c = val | 0x80; + uint8_t c = val | 0x80; s->push_back(c); val >>= 7; } s->push_back(val); } -void WriteVarint(uint32 num, uint64 val, std::string* s) { +void WriteVarint(uint32_t num, uint64_t val, std::string* s) { WriteVarint(num << 3, s); WriteVarint(val, s); } -void WriteLengthDelimited(uint32 num, StringPiece val, std::string* s) { +void WriteLengthDelimited(uint32_t num, StringPiece val, std::string* s) { WriteVarint((num << 3) + 2, s); WriteVarint(val.size(), s); s->append(val.data(), val.size()); } -std::pair<const char*, uint32> VarintParseSlow32(const char* p, uint32 res) { +std::pair<const char*, uint32_t> VarintParseSlow32(const char* p, + uint32_t res) { for (std::uint32_t i = 2; i < 5; i++) { - uint32 byte = static_cast<uint8>(p[i]); + uint32_t byte = static_cast<uint8_t>(p[i]); res += (byte - 1) << (7 * i); if (PROTOBUF_PREDICT_TRUE(byte < 128)) { return {p + i + 1, res}; @@ -326,7 +327,7 @@ } // Accept >5 bytes for (std::uint32_t i = 5; i < 10; i++) { - uint32 byte = static_cast<uint8>(p[i]); + uint32_t byte = static_cast<uint8_t>(p[i]); if (PROTOBUF_PREDICT_TRUE(byte < 128)) { return {p + i + 1, res}; } @@ -334,10 +335,11 @@ return {nullptr, 0}; } -std::pair<const char*, uint64> VarintParseSlow64(const char* p, uint32 res32) { - uint64 res = res32; +std::pair<const char*, uint64_t> VarintParseSlow64(const char* p, + uint32_t res32) { + uint64_t res = res32; for (std::uint32_t i = 2; i < 10; i++) { - uint64 byte = static_cast<uint8>(p[i]); + uint64_t byte = static_cast<uint8_t>(p[i]); res += (byte - 1) << (7 * i); if (PROTOBUF_PREDICT_TRUE(byte < 128)) { return {p + i + 1, res}; @@ -346,9 +348,9 @@ return {nullptr, 0}; } -std::pair<const char*, uint32> ReadTagFallback(const char* p, uint32 res) { +std::pair<const char*, uint32_t> ReadTagFallback(const char* p, uint32_t res) { for (std::uint32_t i = 2; i < 5; i++) { - uint32 byte = static_cast<uint8>(p[i]); + uint32_t byte = static_cast<uint8_t>(p[i]); res += (byte - 1) << (7 * i); if (PROTOBUF_PREDICT_TRUE(byte < 128)) { return {p + i + 1, res}; @@ -357,15 +359,15 @@ return {nullptr, 0}; } -std::pair<const char*, int32> ReadSizeFallback(const char* p, uint32 res) { +std::pair<const char*, int32_t> ReadSizeFallback(const char* p, uint32_t res) { for (std::uint32_t i = 1; i < 4; i++) { - uint32 byte = static_cast<uint8>(p[i]); + uint32_t byte = static_cast<uint8_t>(p[i]); res += (byte - 1) << (7 * i); if (PROTOBUF_PREDICT_TRUE(byte < 128)) { return {p + i + 1, res}; } } - std::uint32_t byte = static_cast<uint8>(p[4]); + std::uint32_t byte = static_cast<uint8_t>(p[4]); if (PROTOBUF_PREDICT_FALSE(byte >= 8)) return {nullptr, 0}; // size >= 2gb res += (byte - 1) << 28; // Protect against sign integer overflow in PushLimit. Limits are relative @@ -406,7 +408,7 @@ template <typename T, bool sign> const char* VarintParser(void* object, const char* ptr, ParseContext* ctx) { - return ctx->ReadPackedVarint(ptr, [object](uint64 varint) { + return ctx->ReadPackedVarint(ptr, [object](uint64_t varint) { T val; if (sign) { if (sizeof(T) == 8) { @@ -423,27 +425,27 @@ const char* PackedInt32Parser(void* object, const char* ptr, ParseContext* ctx) { - return VarintParser<int32, false>(object, ptr, ctx); + return VarintParser<int32_t, false>(object, ptr, ctx); } const char* PackedUInt32Parser(void* object, const char* ptr, ParseContext* ctx) { - return VarintParser<uint32, false>(object, ptr, ctx); + return VarintParser<uint32_t, false>(object, ptr, ctx); } const char* PackedInt64Parser(void* object, const char* ptr, ParseContext* ctx) { - return VarintParser<int64, false>(object, ptr, ctx); + return VarintParser<int64_t, false>(object, ptr, ctx); } const char* PackedUInt64Parser(void* object, const char* ptr, ParseContext* ctx) { - return VarintParser<uint64, false>(object, ptr, ctx); + return VarintParser<uint64_t, false>(object, ptr, ctx); } const char* PackedSInt32Parser(void* object, const char* ptr, ParseContext* ctx) { - return VarintParser<int32, true>(object, ptr, ctx); + return VarintParser<int32_t, true>(object, ptr, ctx); } const char* PackedSInt64Parser(void* object, const char* ptr, ParseContext* ctx) { - return VarintParser<int64, true>(object, ptr, ctx); + return VarintParser<int64_t, true>(object, ptr, ctx); } const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx) { @@ -464,19 +466,19 @@ const char* PackedFixed32Parser(void* object, const char* ptr, ParseContext* ctx) { - return FixedParser<uint32>(object, ptr, ctx); + return FixedParser<uint32_t>(object, ptr, ctx); } const char* PackedSFixed32Parser(void* object, const char* ptr, ParseContext* ctx) { - return FixedParser<int32>(object, ptr, ctx); + return FixedParser<int32_t>(object, ptr, ctx); } const char* PackedFixed64Parser(void* object, const char* ptr, ParseContext* ctx) { - return FixedParser<uint64>(object, ptr, ctx); + return FixedParser<uint64_t>(object, ptr, ctx); } const char* PackedSFixed64Parser(void* object, const char* ptr, ParseContext* ctx) { - return FixedParser<int64>(object, ptr, ctx); + return FixedParser<int64_t>(object, ptr, ctx); } const char* PackedFloatParser(void* object, const char* ptr, ParseContext* ctx) { @@ -492,20 +494,20 @@ explicit UnknownFieldLiteParserHelper(std::string* unknown) : unknown_(unknown) {} - void AddVarint(uint32 num, uint64 value) { + void AddVarint(uint32_t num, uint64_t value) { if (unknown_ == nullptr) return; WriteVarint(num * 8, unknown_); WriteVarint(value, unknown_); } - void AddFixed64(uint32 num, uint64 value) { + void AddFixed64(uint32_t num, uint64_t value) { if (unknown_ == nullptr) return; WriteVarint(num * 8 + 1, unknown_); char buffer[8]; io::CodedOutputStream::WriteLittleEndian64ToArray( - value, reinterpret_cast<uint8*>(buffer)); + value, reinterpret_cast<uint8_t*>(buffer)); unknown_->append(buffer, 8); } - const char* ParseLengthDelimited(uint32 num, const char* ptr, + const char* ParseLengthDelimited(uint32_t num, const char* ptr, ParseContext* ctx) { int size = ReadSize(&ptr); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); @@ -514,19 +516,19 @@ WriteVarint(size, unknown_); return ctx->AppendString(ptr, size, unknown_); } - const char* ParseGroup(uint32 num, const char* ptr, ParseContext* ctx) { + const char* ParseGroup(uint32_t num, const char* ptr, ParseContext* ctx) { if (unknown_) WriteVarint(num * 8 + 3, unknown_); ptr = ctx->ParseGroup(this, ptr, num * 8 + 3); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); if (unknown_) WriteVarint(num * 8 + 4, unknown_); return ptr; } - void AddFixed32(uint32 num, uint32 value) { + void AddFixed32(uint32_t num, uint32_t value) { if (unknown_ == nullptr) return; WriteVarint(num * 8 + 5, unknown_); char buffer[4]; io::CodedOutputStream::WriteLittleEndian32ToArray( - value, reinterpret_cast<uint8*>(buffer)); + value, reinterpret_cast<uint8_t*>(buffer)); unknown_->append(buffer, 4); } @@ -544,8 +546,8 @@ return WireFormatParser(field_parser, ptr, ctx); } -const char* UnknownFieldParse(uint32 tag, std::string* unknown, const char* ptr, - ParseContext* ctx) { +const char* UnknownFieldParse(uint32_t tag, std::string* unknown, + const char* ptr, ParseContext* ctx) { UnknownFieldLiteParserHelper field_parser(unknown); return FieldParser(tag, field_parser, ptr, ctx); }
diff --git a/src/google/protobuf/parse_context.h b/src/google/protobuf/parse_context.h index d858191..c5d1ab9 100644 --- a/src/google/protobuf/parse_context.h +++ b/src/google/protobuf/parse_context.h
@@ -40,6 +40,7 @@ #include <google/protobuf/arena.h> #include <google/protobuf/arenastring.h> #include <google/protobuf/implicit_weak_message.h> +#include <google/protobuf/inlined_string_field.h> #include <google/protobuf/metadata_lite.h> #include <google/protobuf/port.h> #include <google/protobuf/repeated_field.h> @@ -59,12 +60,12 @@ namespace internal { // Template code below needs to know about the existence of these functions. -PROTOBUF_EXPORT void WriteVarint(uint32 num, uint64 val, std::string* s); -PROTOBUF_EXPORT void WriteLengthDelimited(uint32 num, StringPiece val, +PROTOBUF_EXPORT void WriteVarint(uint32_t num, uint64_t val, std::string* s); +PROTOBUF_EXPORT void WriteLengthDelimited(uint32_t num, StringPiece val, std::string* s); // Inline because it is just forwarding to s->WriteVarint -inline void WriteVarint(uint32 num, uint64 val, UnknownFieldSet* s); -inline void WriteLengthDelimited(uint32 num, StringPiece val, +inline void WriteVarint(uint32_t num, uint64_t val, UnknownFieldSet* s); +inline void WriteLengthDelimited(uint32_t num, StringPiece val, UnknownFieldSet* s); @@ -184,15 +185,15 @@ PROTOBUF_MUST_USE_RESULT const char* ReadPackedVarint(const char* ptr, Add add); - uint32 LastTag() const { return last_tag_minus_1_ + 1; } - bool ConsumeEndGroup(uint32 start_tag) { + uint32_t LastTag() const { return last_tag_minus_1_ + 1; } + bool ConsumeEndGroup(uint32_t start_tag) { bool res = last_tag_minus_1_ == start_tag; last_tag_minus_1_ = 0; return res; } bool EndedAtLimit() const { return last_tag_minus_1_ == 0; } bool EndedAtEndOfStream() const { return last_tag_minus_1_ == 1; } - void SetLastTag(uint32 tag) { last_tag_minus_1_ = tag - 1; } + void SetLastTag(uint32_t tag) { last_tag_minus_1_ = tag - 1; } void SetEndOfStream() { last_tag_minus_1_ = 1; } bool IsExceedingLimit(const char* ptr) { return ptr > limit_end_ && @@ -281,7 +282,7 @@ // This var doesn't really belong in EpsCopyInputStream and should be part of // the ParseContext, but case 2 is most easily and optimally implemented in // DoneFallback. - uint32 last_tag_minus_1_ = 0; + uint32_t last_tag_minus_1_ = 0; int overall_limit_ = INT_MAX; // Overall limit independent of pushed limits. // Pretty random large number that seems like a safe allocation on most // systems. TODO(gerbens) do we need to set this as build flag? @@ -406,7 +407,7 @@ template <typename T> PROTOBUF_MUST_USE_RESULT PROTOBUF_NDEBUG_INLINE const char* ParseGroup( - T* msg, const char* ptr, uint32 tag) { + T* msg, const char* ptr, uint32_t tag) { if (--depth_ < 0) return nullptr; group_depth_++; ptr = msg->_InternalParse(ptr, this); @@ -440,7 +441,7 @@ Data data_; }; -template <uint32 tag> +template <uint32_t tag> bool ExpectTag(const char* ptr) { if (tag < 128) { return *ptr == static_cast<char>(tag); @@ -456,13 +457,13 @@ template <> struct EndianHelper<1> { - static uint8 Load(const void* p) { return *static_cast<const uint8*>(p); } + static uint8_t Load(const void* p) { return *static_cast<const uint8_t*>(p); } }; template <> struct EndianHelper<2> { - static uint16 Load(const void* p) { - uint16 tmp; + static uint16_t Load(const void* p) { + uint16_t tmp; std::memcpy(&tmp, p, 2); #ifndef PROTOBUF_LITTLE_ENDIAN tmp = bswap_16(tmp); @@ -473,8 +474,8 @@ template <> struct EndianHelper<4> { - static uint32 Load(const void* p) { - uint32 tmp; + static uint32_t Load(const void* p) { + uint32_t tmp; std::memcpy(&tmp, p, 4); #ifndef PROTOBUF_LITTLE_ENDIAN tmp = bswap_32(tmp); @@ -485,8 +486,8 @@ template <> struct EndianHelper<8> { - static uint64 Load(const void* p) { - uint64 tmp; + static uint64_t Load(const void* p) { + uint64_t tmp; std::memcpy(&tmp, p, 8); #ifndef PROTOBUF_LITTLE_ENDIAN tmp = bswap_64(tmp); @@ -504,17 +505,17 @@ } PROTOBUF_EXPORT -std::pair<const char*, uint32> VarintParseSlow32(const char* p, uint32 res); +std::pair<const char*, uint32_t> VarintParseSlow32(const char* p, uint32_t res); PROTOBUF_EXPORT -std::pair<const char*, uint64> VarintParseSlow64(const char* p, uint32 res); +std::pair<const char*, uint64_t> VarintParseSlow64(const char* p, uint32_t res); -inline const char* VarintParseSlow(const char* p, uint32 res, uint32* out) { +inline const char* VarintParseSlow(const char* p, uint32_t res, uint32_t* out) { auto tmp = VarintParseSlow32(p, res); *out = tmp.second; return tmp.first; } -inline const char* VarintParseSlow(const char* p, uint32 res, uint64* out) { +inline const char* VarintParseSlow(const char* p, uint32_t res, uint64_t* out) { auto tmp = VarintParseSlow64(p, res); *out = tmp.second; return tmp.first; @@ -522,13 +523,13 @@ template <typename T> PROTOBUF_MUST_USE_RESULT const char* VarintParse(const char* p, T* out) { - auto ptr = reinterpret_cast<const uint8*>(p); - uint32 res = ptr[0]; + auto ptr = reinterpret_cast<const uint8_t*>(p); + uint32_t res = ptr[0]; if (!(res & 0x80)) { *out = res; return p + 1; } - uint32 byte = ptr[1]; + uint32_t byte = ptr[1]; res += (byte - 1) << 7; if (!(byte & 0x80)) { *out = res; @@ -541,16 +542,17 @@ // Caller must ensure its safe to call. PROTOBUF_EXPORT -std::pair<const char*, uint32> ReadTagFallback(const char* p, uint32 res); +std::pair<const char*, uint32_t> ReadTagFallback(const char* p, uint32_t res); // Same as ParseVarint but only accept 5 bytes at most. -inline const char* ReadTag(const char* p, uint32* out, uint32 /*max_tag*/ = 0) { - uint32 res = static_cast<uint8>(p[0]); +inline const char* ReadTag(const char* p, uint32_t* out, + uint32_t /*max_tag*/ = 0) { + uint32_t res = static_cast<uint8_t>(p[0]); if (res < 128) { *out = res; return p + 1; } - uint32 second = static_cast<uint8>(p[1]); + uint32_t second = static_cast<uint8_t>(p[1]); res += (second - 1) << 7; if (second < 128) { *out = res; @@ -571,8 +573,8 @@ // adc [rsi], 1 // add eax, eax // and eax, edi -inline uint32 DecodeTwoBytes(const char** ptr) { - uint32 value = UnalignedLoad<uint16>(*ptr); +inline uint32_t DecodeTwoBytes(const char** ptr) { + uint32_t value = UnalignedLoad<uint16_t>(*ptr); // Sign extend the low byte continuation bit uint32_t x = static_cast<int8_t>(value); // This add is an amazing operation, it cancels the low byte continuation bit @@ -586,11 +588,11 @@ } // More efficient varint parsing for big varints -inline const char* ParseBigVarint(const char* p, uint64* out) { +inline const char* ParseBigVarint(const char* p, uint64_t* out) { auto pnew = p; auto tmp = DecodeTwoBytes(&pnew); - uint64 res = tmp >> 1; - if (PROTOBUF_PREDICT_TRUE(std::int16_t(tmp) >= 0)) { + uint64_t res = tmp >> 1; + if (PROTOBUF_PREDICT_TRUE(static_cast<std::int16_t>(tmp) >= 0)) { *out = res; return pnew; } @@ -598,7 +600,7 @@ pnew = p + 2 * i; tmp = DecodeTwoBytes(&pnew); res += (static_cast<std::uint64_t>(tmp) - 2) << (14 * i - 1); - if (PROTOBUF_PREDICT_TRUE(std::int16_t(tmp) >= 0)) { + if (PROTOBUF_PREDICT_TRUE(static_cast<std::int16_t>(tmp) >= 0)) { *out = res; return pnew; } @@ -607,13 +609,13 @@ } PROTOBUF_EXPORT -std::pair<const char*, int32> ReadSizeFallback(const char* p, uint32 first); +std::pair<const char*, int32_t> ReadSizeFallback(const char* p, uint32_t first); // Used for tags, could read up to 5 bytes which must be available. Additionally -// it makes sure the unsigned value fits a int32, otherwise returns nullptr. +// it makes sure the unsigned value fits a int32_t, otherwise returns nullptr. // Caller must ensure its safe to call. -inline uint32 ReadSize(const char** pp) { +inline uint32_t ReadSize(const char** pp) { auto p = *pp; - uint32 res = static_cast<uint8>(p[0]); + uint32_t res = static_cast<uint8_t>(p[0]); if (res < 128) { *pp = p + 1; return res; @@ -628,28 +630,28 @@ // function composition. We rely on the compiler to inline this. // Also in debug compiles having local scoped variables tend to generated // stack frames that scale as O(num fields). -inline uint64 ReadVarint64(const char** p) { - uint64 tmp; +inline uint64_t ReadVarint64(const char** p) { + uint64_t tmp; *p = VarintParse(*p, &tmp); return tmp; } -inline uint32 ReadVarint32(const char** p) { - uint32 tmp; +inline uint32_t ReadVarint32(const char** p) { + uint32_t tmp; *p = VarintParse(*p, &tmp); return tmp; } -inline int64 ReadVarintZigZag64(const char** p) { - uint64 tmp; +inline int64_t ReadVarintZigZag64(const char** p) { + uint64_t tmp; *p = VarintParse(*p, &tmp); return WireFormatLite::ZigZagDecode64(tmp); } -inline int32 ReadVarintZigZag32(const char** p) { - uint64 tmp; +inline int32_t ReadVarintZigZag32(const char** p) { + uint64_t tmp; *p = VarintParse(*p, &tmp); - return WireFormatLite::ZigZagDecode32(static_cast<uint32>(tmp)); + return WireFormatLite::ZigZagDecode32(static_cast<uint32_t>(tmp)); } template <typename T> @@ -716,7 +718,7 @@ template <typename Add> const char* ReadPackedVarintArray(const char* ptr, const char* end, Add add) { while (ptr < end) { - uint64 varint; + uint64_t varint; ptr = VarintParse(ptr, &varint); if (ptr == nullptr) return nullptr; add(varint); @@ -786,22 +788,22 @@ GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, nullptr) template <typename T> -PROTOBUF_MUST_USE_RESULT const char* FieldParser(uint64 tag, T& field_parser, +PROTOBUF_MUST_USE_RESULT const char* FieldParser(uint64_t tag, T& field_parser, const char* ptr, ParseContext* ctx) { - uint32 number = tag >> 3; + uint32_t number = tag >> 3; GOOGLE_PROTOBUF_PARSER_ASSERT(number != 0); using WireType = internal::WireFormatLite::WireType; switch (tag & 7) { case WireType::WIRETYPE_VARINT: { - uint64 value; + uint64_t value; ptr = VarintParse(ptr, &value); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); field_parser.AddVarint(number, value); break; } case WireType::WIRETYPE_FIXED64: { - uint64 value = UnalignedLoad<uint64>(ptr); + uint64_t value = UnalignedLoad<uint64_t>(ptr); ptr += 8; field_parser.AddFixed64(number, value); break; @@ -821,7 +823,7 @@ break; } case WireType::WIRETYPE_FIXED32: { - uint32 value = UnalignedLoad<uint32>(ptr); + uint32_t value = UnalignedLoad<uint32_t>(ptr); ptr += 4; field_parser.AddFixed32(number, value); break; @@ -837,7 +839,7 @@ const char* ptr, ParseContext* ctx) { while (!ctx->Done(&ptr)) { - uint32 tag; + uint32_t tag; ptr = ReadTag(ptr, &tag); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr); if (tag == 0 || (tag & 7) == 4) { @@ -874,7 +876,7 @@ void* object, const char* ptr, ParseContext* ctx, bool (*is_valid)(int), InternalMetadata* metadata, int field_num) { return ctx->ReadPackedVarint( - ptr, [object, is_valid, metadata, field_num](uint64 val) { + ptr, [object, is_valid, metadata, field_num](uint64_t val) { if (is_valid(val)) { static_cast<RepeatedField<int>*>(object)->Add(val); } else { @@ -889,7 +891,7 @@ bool (*is_valid)(const void*, int), const void* data, InternalMetadata* metadata, int field_num) { return ctx->ReadPackedVarint( - ptr, [object, is_valid, data, metadata, field_num](uint64 val) { + ptr, [object, is_valid, data, metadata, field_num](uint64_t val) { if (is_valid(data, val)) { static_cast<RepeatedField<int>*>(object)->Add(val); } else { @@ -920,7 +922,7 @@ // useful in the generated code. It uses overload on std::string* vs // UnknownFieldSet* to make the generated code isomorphic between full and lite. PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* UnknownFieldParse( - uint32 tag, std::string* unknown, const char* ptr, ParseContext* ctx); + uint32_t tag, std::string* unknown, const char* ptr, ParseContext* ctx); } // namespace internal } // namespace protobuf
diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 82e98d9..4834d9d 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc
@@ -52,6 +52,35 @@ // GCC, and MSVC. Function-like macros are usable without an #ifdef guard. // Syntax macros (for example, attributes) are always defined, although // they may be empty. +// +// Some definitions rely on the NDEBUG macro and/or (in MSVC) _DEBUG: +// - https://en.cppreference.com/w/c/error/assert +// - https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros#microsoft-specific-predefined-macros +// +// References for predefined macros: +// - Standard: https://en.cppreference.com/w/cpp/preprocessor/replace +// - Clang: https://clang.llvm.org/docs/LanguageExtensions.html +// (see also GCC predefined macros) +// - GCC: https://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html +// - MSVC: https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros +// - Interactive (Clang/GCC only): https://www.compiler-explorer.com/z/hc6jKd3sj +// +// References for attributes (and extension attributes): +// - Standard: https://en.cppreference.com/w/cpp/language/attributes +// - Clang: https://clang.llvm.org/docs/AttributeReference.html +// - GCC: https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html +// (see Clang attribute docs as well) +// +// References for standard C++ language conformance (and minimum versions): +// - Clang: https://clang.llvm.org/cxx_status.html +// - GCC: https://gcc.gnu.org/projects/cxx-status.html +// - MSVC: https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance +// +// Historical release notes (which can help to determine minimum versions): +// - Clang: https://releases.llvm.org/ +// - GCC: https://gcc.gnu.org/releases.html +// - MSVC: https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-history +// https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2017-relnotes-history // Portable fallbacks for C++20 feature test macros: // https://en.cppreference.com/w/cpp/feature_test @@ -99,6 +128,23 @@ # define PROTOBUF_GNUC_MIN(x, y) 0 #endif +// Portable check for MSVC minimum version: +// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros +#if defined(_MSC_VER) +#define PROTOBUF_MSC_VER_MIN(x) (_MSC_VER >= x) +#else +#define PROTOBUF_MSC_VER_MIN(x) 0 +#endif + +// Portable check for minimum C++ language version: +// https://en.cppreference.com/w/cpp/preprocessor/replace +// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros +#if !defined(_MSVC_LANG) +#define PROTOBUF_CPLUSPLUS_MIN(x) (__cplusplus >= x) +#else +#define PROTOBUF_CPLUSPLUS_MIN(x) (_MSVC_LANG >= x) +#endif + // Future versions of protobuf will include breaking changes to some APIs. // This macro can be set to enable these API changes ahead of time, so that // user code can be updated before upgrading versions of protobuf. @@ -397,8 +443,8 @@ #error PROTOBUF_PREDICT_(TRUE|FALSE) was previously defined #endif #if PROTOBUF_GNUC_MIN(3, 0) -# define PROTOBUF_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) -# define PROTOBUF_PREDICT_FALSE(x) (__builtin_expect((x), 0)) +# define PROTOBUF_PREDICT_TRUE(x) (__builtin_expect(false || (x), true)) +# define PROTOBUF_PREDICT_FALSE(x) (__builtin_expect(false || (x), false)) #else # define PROTOBUF_PREDICT_TRUE(x) (x) # define PROTOBUF_PREDICT_FALSE(x) (x) @@ -409,10 +455,6 @@ #endif # define PROTOBUF_MUST_USE_RESULT -#ifdef PROTOBUF_MUST_USE_EXTRACT_RESULT -#error PROTOBUF_MUST_USE_EXTRACT_RESULT was previously defined -#endif - #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE #error PROTOBUF_FORCE_COPY_IN_RELEASE was previously defined #endif @@ -424,7 +466,9 @@ #ifdef PROTOBUF_FALLTHROUGH_INTENDED #error PROTOBUF_FALLTHROUGH_INTENDED was previously defined #endif -#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +#if __has_cpp_attribute(fallthrough) +#define PROTOBUF_FALLTHROUGH_INTENDED [[fallthrough]] +#elif __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") #define PROTOBUF_FALLTHROUGH_INTENDED [[clang::fallthrough]] #elif PROTOBUF_GNUC_MIN(7, 0) #define PROTOBUF_FALLTHROUGH_INTENDED [[gnu::fallthrough]] @@ -590,11 +634,42 @@ # define PROTOBUF_TSAN __SANITIZE_THREAD__ #endif +// Tail call table-driven parsing can be enabled by defining +// PROTOBUF_EXPERIMENTAL_USE_TAIL_CALL_TABLE_PARSER at compilation time. Note +// that this macro is for small-scale testing only, and is not supported. +#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED +#error PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED was previously declared +#endif +#if defined(PROTOBUF_EXPERIMENTAL_USE_TAIL_CALL_TABLE_PARSER) +#define PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED 1 +// Selectively use static member functions instead of templates: +#ifndef PROTOBUF_TC_STATIC_PARSE_SINGULAR1 +# define PROTOBUF_TC_STATIC_PARSE_SINGULAR1 1 +#endif +#ifndef PROTOBUF_TC_STATIC_PARSE_SINGULAR2 +# define PROTOBUF_TC_STATIC_PARSE_SINGULAR2 0 +#endif +#ifndef PROTOBUF_TC_STATIC_PARSE_REPEATED1 +# define PROTOBUF_TC_STATIC_PARSE_REPEATED1 0 +#endif +#ifndef PROTOBUF_TC_STATIC_PARSE_REPEATED2 +# define PROTOBUF_TC_STATIC_PARSE_REPEATED2 0 +#endif +#endif + +#define PROTOBUF_TC_PARAM_DECL \ + ::google::protobuf::MessageLite *msg, const char *ptr, \ + ::google::protobuf::internal::ParseContext *ctx, \ + const ::google::protobuf::internal::TailCallParseTableBase *table, \ + uint64_t hasbits, ::google::protobuf::internal::TcFieldData data + #ifdef PROTOBUF_UNUSED #error PROTOBUF_UNUSED was previously defined #endif -#if __has_cpp_attribute(unused) || \ - (PROTOBUF_GNUC_MIN(3, 0) && !defined(__clang__)) +#if __has_cpp_attribute(maybe_unused) || \ + (PROTOBUF_MSC_VER_MIN(1911) && PROTOBUF_CPLUSPLUS_MIN(201703L)) +#define PROTOBUF_UNUSED [[maybe_unused]] +#elif __has_attribute(unused) || PROTOBUF_GNUC_MIN(3, 0) #define PROTOBUF_UNUSED __attribute__((__unused__)) #else #define PROTOBUF_UNUSED @@ -706,4 +781,3 @@ # undef __has_builtin # undef PROTOBUF_has_builtin_DEFINED_ #endif -#undef PROTOBUF_GNUC_MIN
diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index 4e956d4..f038341 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc
@@ -34,6 +34,9 @@ #ifndef PROTOBUF_NAMESPACE #error "port_undef.inc must be included after port_def.inc" #endif +#undef PROTOBUF_GNUC_MIN +#undef PROTOBUF_MSC_VER_MIN +#undef PROTOBUF_CPLUSPLUS_MIN #undef PROTOBUF_NAMESPACE #undef PROTOBUF_NAMESPACE_ID #undef PROTOBUF_ALWAYS_INLINE @@ -61,7 +64,6 @@ #undef PROTOBUF_EXPORT #undef PROTOC_EXPORT #undef PROTOBUF_MUST_USE_RESULT -#undef PROTOBUF_MUST_USE_EXTRACT_RESULT #undef PROTOBUF_FORCE_COPY_IN_RELEASE #undef PROTOBUF_FORCE_COPY_IN_SWAP #undef PROTOBUF_NAMESPACE_OPEN @@ -82,6 +84,12 @@ #undef PROTOBUF_ASAN #undef PROTOBUF_MSAN #undef PROTOBUF_TSAN +#undef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED +#undef PROTOBUF_TC_STATIC_PARSE_SINGULAR1 +#undef PROTOBUF_TC_STATIC_PARSE_SINGULAR2 +#undef PROTOBUF_TC_STATIC_PARSE_REPEATED1 +#undef PROTOBUF_TC_STATIC_PARSE_REPEATED2 +#undef PROTOBUF_TC_PARAM_DECL #undef PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED #undef PROTOBUF_LOCKS_EXCLUDED #undef PROTOBUF_NO_THREAD_SAFETY_ANALYSIS
diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h index bb41fba..00be9c0 100644 --- a/src/google/protobuf/reflection.h +++ b/src/google/protobuf/reflection.h
@@ -282,19 +282,19 @@ // cpp_type to the type that should be used in this interface: // // field->cpp_type() T Actual type of void* -// CPPTYPE_INT32 int32 int32 -// CPPTYPE_UINT32 uint32 uint32 -// CPPTYPE_INT64 int64 int64 -// CPPTYPE_UINT64 uint64 uint64 +// CPPTYPE_INT32 int32_t int32_t +// CPPTYPE_UINT32 uint32_t uint32_t +// CPPTYPE_INT64 int64_t int64_t +// CPPTYPE_UINT64 uint64_t uint64_t // CPPTYPE_DOUBLE double double // CPPTYPE_FLOAT float float // CPPTYPE_BOOL bool bool -// CPPTYPE_ENUM generated enum type int32 +// CPPTYPE_ENUM generated enum type int32_t // CPPTYPE_STRING string std::string // CPPTYPE_MESSAGE generated message type google::protobuf::Message // or google::protobuf::Message // -// Note that for enums we use int32 in the interface. +// Note that for enums we use int32_t in the interface. // // You can map from T to the actual type using RefTypeTraits: // typedef RefTypeTraits<T>::AccessorValueType ActualType; @@ -362,7 +362,7 @@ // be ActualType. Here we have a ValueType object and want a ActualType // pointer. We can't cast a ValueType pointer to an ActualType pointer // directly because their type might be different (for enums ValueType - // may be a generated enum type while ActualType is int32). To be safe + // may be a generated enum type while ActualType is int32_t). To be safe // we make a copy to get a temporary ActualType object and use it. ActualType tmp = static_cast<ActualType>(value); Set(data, index, static_cast<const Value*>(&tmp)); @@ -376,7 +376,7 @@ // be ActualType. Here we have a ValueType object and want a ActualType // pointer. We can't cast a ValueType pointer to an ActualType pointer // directly because their type might be different (for enums ValueType - // may be a generated enum type while ActualType is int32). To be safe + // may be a generated enum type while ActualType is int32_t). To be safe // we make a copy to get a temporary ActualType object and use it. ActualType tmp = static_cast<ActualType>(value); Add(data, static_cast<const Value*>(&tmp)); @@ -485,10 +485,10 @@ static const FieldDescriptor::CppType cpp_type = \ FieldDescriptor::CPPTYPE_##TYPE; \ }; -DEFINE_PRIMITIVE(INT32, int32) -DEFINE_PRIMITIVE(UINT32, uint32) -DEFINE_PRIMITIVE(INT64, int64) -DEFINE_PRIMITIVE(UINT64, uint64) +DEFINE_PRIMITIVE(INT32, int32_t) +DEFINE_PRIMITIVE(UINT32, uint32_t) +DEFINE_PRIMITIVE(INT64, int64_t) +DEFINE_PRIMITIVE(UINT64, uint64_t) DEFINE_PRIMITIVE(FLOAT, float) DEFINE_PRIMITIVE(DOUBLE, double) DEFINE_PRIMITIVE(BOOL, bool) @@ -512,10 +512,10 @@ T, typename std::enable_if<is_proto_enum<T>::value>::type> { typedef RepeatedFieldRefIterator<T> iterator; typedef RepeatedFieldAccessor AccessorType; - // We use int32 for repeated enums in RepeatedFieldAccessor. - typedef int32 AccessorValueType; + // We use int32_t for repeated enums in RepeatedFieldAccessor. + typedef int32_t AccessorValueType; typedef T IteratorValueType; - typedef int32* IteratorPointerType; + typedef int32_t* IteratorPointerType; static constexpr FieldDescriptor::CppType cpp_type = FieldDescriptor::CPPTYPE_ENUM; static const Descriptor* GetMessageFieldDescriptor() { return NULL; }
diff --git a/src/google/protobuf/reflection_tester.cc b/src/google/protobuf/reflection_tester.cc new file mode 100644 index 0000000..77601a7 --- /dev/null +++ b/src/google/protobuf/reflection_tester.cc
@@ -0,0 +1,1673 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/reflection_tester.h> + +#include <google/protobuf/map_field.h> +#include <google/protobuf/message.h> +#include <gtest/gtest.h> + +// Must include last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +MapReflectionTester::MapReflectionTester(const Descriptor* base_descriptor) + : base_descriptor_(base_descriptor) { + const DescriptorPool* pool = base_descriptor->file()->pool(); + std::string package = base_descriptor->file()->package(); + + map_enum_foo_ = pool->FindEnumValueByName(package + ".MAP_ENUM_FOO"); + map_enum_bar_ = pool->FindEnumValueByName(package + ".MAP_ENUM_BAR"); + map_enum_baz_ = pool->FindEnumValueByName(package + ".MAP_ENUM_BAZ"); + + foreign_c_ = pool->FindFieldByName(package + ".ForeignMessage.c"); + map_int32_int32_key_ = + pool->FindFieldByName(package + ".TestMap.MapInt32Int32Entry.key"); + map_int32_int32_val_ = + pool->FindFieldByName(package + ".TestMap.MapInt32Int32Entry.value"); + map_int64_int64_key_ = + pool->FindFieldByName(package + ".TestMap.MapInt64Int64Entry.key"); + map_int64_int64_val_ = + pool->FindFieldByName(package + ".TestMap.MapInt64Int64Entry.value"); + map_uint32_uint32_key_ = + pool->FindFieldByName(package + ".TestMap.MapUint32Uint32Entry.key"); + map_uint32_uint32_val_ = + pool->FindFieldByName(package + ".TestMap.MapUint32Uint32Entry.value"); + map_uint64_uint64_key_ = + pool->FindFieldByName(package + ".TestMap.MapUint64Uint64Entry.key"); + map_uint64_uint64_val_ = + pool->FindFieldByName(package + ".TestMap.MapUint64Uint64Entry.value"); + map_sint32_sint32_key_ = + pool->FindFieldByName(package + ".TestMap.MapSint32Sint32Entry.key"); + map_sint32_sint32_val_ = + pool->FindFieldByName(package + ".TestMap.MapSint32Sint32Entry.value"); + map_sint64_sint64_key_ = + pool->FindFieldByName(package + ".TestMap.MapSint64Sint64Entry.key"); + map_sint64_sint64_val_ = + pool->FindFieldByName(package + ".TestMap.MapSint64Sint64Entry.value"); + map_fixed32_fixed32_key_ = + pool->FindFieldByName(package + ".TestMap.MapFixed32Fixed32Entry.key"); + map_fixed32_fixed32_val_ = + pool->FindFieldByName(package + ".TestMap.MapFixed32Fixed32Entry.value"); + map_fixed64_fixed64_key_ = + pool->FindFieldByName(package + ".TestMap.MapFixed64Fixed64Entry.key"); + map_fixed64_fixed64_val_ = + pool->FindFieldByName(package + ".TestMap.MapFixed64Fixed64Entry.value"); + map_sfixed32_sfixed32_key_ = + pool->FindFieldByName(package + ".TestMap.MapSfixed32Sfixed32Entry.key"); + map_sfixed32_sfixed32_val_ = pool->FindFieldByName( + package + ".TestMap.MapSfixed32Sfixed32Entry.value"); + map_sfixed64_sfixed64_key_ = + pool->FindFieldByName(package + ".TestMap.MapSfixed64Sfixed64Entry.key"); + map_sfixed64_sfixed64_val_ = pool->FindFieldByName( + package + ".TestMap.MapSfixed64Sfixed64Entry.value"); + map_int32_float_key_ = + pool->FindFieldByName(package + ".TestMap.MapInt32FloatEntry.key"); + map_int32_float_val_ = + pool->FindFieldByName(package + ".TestMap.MapInt32FloatEntry.value"); + map_int32_double_key_ = + pool->FindFieldByName(package + ".TestMap.MapInt32DoubleEntry.key"); + map_int32_double_val_ = + pool->FindFieldByName(package + ".TestMap.MapInt32DoubleEntry.value"); + map_bool_bool_key_ = + pool->FindFieldByName(package + ".TestMap.MapBoolBoolEntry.key"); + map_bool_bool_val_ = + pool->FindFieldByName(package + ".TestMap.MapBoolBoolEntry.value"); + map_string_string_key_ = + pool->FindFieldByName(package + ".TestMap.MapStringStringEntry.key"); + map_string_string_val_ = + pool->FindFieldByName(package + ".TestMap.MapStringStringEntry.value"); + map_int32_bytes_key_ = + pool->FindFieldByName(package + ".TestMap.MapInt32BytesEntry.key"); + map_int32_bytes_val_ = + pool->FindFieldByName(package + ".TestMap.MapInt32BytesEntry.value"); + map_int32_enum_key_ = + pool->FindFieldByName(package + ".TestMap.MapInt32EnumEntry.key"); + map_int32_enum_val_ = + pool->FindFieldByName(package + ".TestMap.MapInt32EnumEntry.value"); + map_int32_foreign_message_key_ = pool->FindFieldByName( + package + ".TestMap.MapInt32ForeignMessageEntry.key"); + map_int32_foreign_message_val_ = pool->FindFieldByName( + package + ".TestMap.MapInt32ForeignMessageEntry.value"); + + EXPECT_FALSE(map_enum_foo_ == nullptr); + EXPECT_FALSE(map_enum_bar_ == nullptr); + EXPECT_FALSE(map_enum_baz_ == nullptr); + EXPECT_FALSE(map_int32_int32_key_ == nullptr); + EXPECT_FALSE(map_int32_int32_val_ == nullptr); + EXPECT_FALSE(map_int64_int64_key_ == nullptr); + EXPECT_FALSE(map_int64_int64_val_ == nullptr); + EXPECT_FALSE(map_uint32_uint32_key_ == nullptr); + EXPECT_FALSE(map_uint32_uint32_val_ == nullptr); + EXPECT_FALSE(map_uint64_uint64_key_ == nullptr); + EXPECT_FALSE(map_uint64_uint64_val_ == nullptr); + EXPECT_FALSE(map_sint32_sint32_key_ == nullptr); + EXPECT_FALSE(map_sint32_sint32_val_ == nullptr); + EXPECT_FALSE(map_sint64_sint64_key_ == nullptr); + EXPECT_FALSE(map_sint64_sint64_val_ == nullptr); + EXPECT_FALSE(map_fixed32_fixed32_key_ == nullptr); + EXPECT_FALSE(map_fixed32_fixed32_val_ == nullptr); + EXPECT_FALSE(map_fixed64_fixed64_key_ == nullptr); + EXPECT_FALSE(map_fixed64_fixed64_val_ == nullptr); + EXPECT_FALSE(map_sfixed32_sfixed32_key_ == nullptr); + EXPECT_FALSE(map_sfixed32_sfixed32_val_ == nullptr); + EXPECT_FALSE(map_sfixed64_sfixed64_key_ == nullptr); + EXPECT_FALSE(map_sfixed64_sfixed64_val_ == nullptr); + EXPECT_FALSE(map_int32_float_key_ == nullptr); + EXPECT_FALSE(map_int32_float_val_ == nullptr); + EXPECT_FALSE(map_int32_double_key_ == nullptr); + EXPECT_FALSE(map_int32_double_val_ == nullptr); + EXPECT_FALSE(map_bool_bool_key_ == nullptr); + EXPECT_FALSE(map_bool_bool_val_ == nullptr); + EXPECT_FALSE(map_string_string_key_ == nullptr); + EXPECT_FALSE(map_string_string_val_ == nullptr); + EXPECT_FALSE(map_int32_bytes_key_ == nullptr); + EXPECT_FALSE(map_int32_bytes_val_ == nullptr); + EXPECT_FALSE(map_int32_enum_key_ == nullptr); + EXPECT_FALSE(map_int32_enum_val_ == nullptr); + EXPECT_FALSE(map_int32_foreign_message_key_ == nullptr); + EXPECT_FALSE(map_int32_foreign_message_val_ == nullptr); + + std::vector<const FieldDescriptor*> all_map_descriptors = { + map_int32_int32_key_, + map_int32_int32_val_, + map_int64_int64_key_, + map_int64_int64_val_, + map_uint32_uint32_key_, + map_uint32_uint32_val_, + map_uint64_uint64_key_, + map_uint64_uint64_val_, + map_sint32_sint32_key_, + map_sint32_sint32_val_, + map_sint64_sint64_key_, + map_sint64_sint64_val_, + map_fixed32_fixed32_key_, + map_fixed32_fixed32_val_, + map_fixed64_fixed64_key_, + map_fixed64_fixed64_val_, + map_sfixed32_sfixed32_key_, + map_sfixed32_sfixed32_val_, + map_sfixed64_sfixed64_key_, + map_sfixed64_sfixed64_val_, + map_int32_float_key_, + map_int32_float_val_, + map_int32_double_key_, + map_int32_double_val_, + map_bool_bool_key_, + map_bool_bool_val_, + map_string_string_key_, + map_string_string_val_, + map_int32_bytes_key_, + map_int32_bytes_val_, + map_int32_enum_key_, + map_int32_enum_val_, + map_int32_foreign_message_key_, + map_int32_foreign_message_val_}; + for (const FieldDescriptor* fdesc : all_map_descriptors) { + GOOGLE_CHECK(fdesc->containing_type() != nullptr) << fdesc->name(); + if (fdesc->name() == "key") { + EXPECT_EQ(fdesc->containing_type()->map_key(), fdesc); + } else { + EXPECT_EQ(fdesc->name(), "value"); + EXPECT_EQ(fdesc->containing_type()->map_value(), fdesc); + } + } +} + +// Shorthand to get a FieldDescriptor for a field of unittest::TestMap. +const FieldDescriptor* MapReflectionTester::F(const std::string& name) { + const FieldDescriptor* result = nullptr; + result = base_descriptor_->FindFieldByName(name); + GOOGLE_CHECK(result != nullptr); + return result; +} + +void MapReflectionTester::SetMapFieldsViaReflection(Message* message) { + const Reflection* reflection = message->GetReflection(); + Message* sub_message = nullptr; + Message* sub_foreign_message = nullptr; + + // Add first element. + sub_message = reflection->AddMessage(message, F("map_int32_int32")); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_key_, 0); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_val_, 0); + + sub_message = reflection->AddMessage(message, F("map_int64_int64")); + sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_key_, 0); + sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_val_, 0); + + sub_message = reflection->AddMessage(message, F("map_uint32_uint32")); + sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_key_, + 0); + sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_val_, + 0); + + sub_message = reflection->AddMessage(message, F("map_uint64_uint64")); + sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_key_, + 0); + sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_val_, + 0); + + sub_message = reflection->AddMessage(message, F("map_sint32_sint32")); + sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_key_, + 0); + sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_val_, + 0); + + sub_message = reflection->AddMessage(message, F("map_sint64_sint64")); + sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_key_, + 0); + sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_val_, + 0); + + sub_message = reflection->AddMessage(message, F("map_fixed32_fixed32")); + sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_key_, + 0); + sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_val_, + 0); + + sub_message = reflection->AddMessage(message, F("map_fixed64_fixed64")); + sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_key_, + 0); + sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_val_, + 0); + + sub_message = reflection->AddMessage(message, F("map_sfixed32_sfixed32")); + sub_message->GetReflection()->SetInt32(sub_message, + map_sfixed32_sfixed32_key_, 0); + sub_message->GetReflection()->SetInt32(sub_message, + map_sfixed32_sfixed32_val_, 0); + + sub_message = reflection->AddMessage(message, F("map_sfixed64_sfixed64")); + sub_message->GetReflection()->SetInt64(sub_message, + map_sfixed64_sfixed64_key_, 0); + sub_message->GetReflection()->SetInt64(sub_message, + map_sfixed64_sfixed64_val_, 0); + + sub_message = reflection->AddMessage(message, F("map_int32_float")); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_float_key_, 0); + sub_message->GetReflection()->SetFloat(sub_message, map_int32_float_val_, + 0.0); + + sub_message = reflection->AddMessage(message, F("map_int32_double")); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_double_key_, 0); + sub_message->GetReflection()->SetDouble(sub_message, map_int32_double_val_, + 0.0); + + sub_message = reflection->AddMessage(message, F("map_bool_bool")); + sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_key_, false); + sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_val_, false); + + sub_message = reflection->AddMessage(message, F("map_string_string")); + sub_message->GetReflection()->SetString(sub_message, map_string_string_key_, + "0"); + sub_message->GetReflection()->SetString(sub_message, map_string_string_val_, + "0"); + + sub_message = reflection->AddMessage(message, F("map_int32_bytes")); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_bytes_key_, 0); + sub_message->GetReflection()->SetString(sub_message, map_int32_bytes_val_, + "0"); + + sub_message = reflection->AddMessage(message, F("map_int32_enum")); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_enum_key_, 0); + sub_message->GetReflection()->SetEnum(sub_message, map_int32_enum_val_, + map_enum_bar_); + + sub_message = reflection->AddMessage(message, F("map_int32_foreign_message")); + sub_message->GetReflection()->SetInt32(sub_message, + map_int32_foreign_message_key_, 0); + sub_foreign_message = sub_message->GetReflection()->MutableMessage( + sub_message, map_int32_foreign_message_val_, nullptr); + sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message, + foreign_c_, 0); + + // Add second element + sub_message = reflection->AddMessage(message, F("map_int32_int32")); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_key_, 1); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_val_, 1); + + sub_message = reflection->AddMessage(message, F("map_int64_int64")); + sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_key_, 1); + sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_val_, 1); + + sub_message = reflection->AddMessage(message, F("map_uint32_uint32")); + sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_key_, + 1); + sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_val_, + 1); + + sub_message = reflection->AddMessage(message, F("map_uint64_uint64")); + sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_key_, + 1); + sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_val_, + 1); + + sub_message = reflection->AddMessage(message, F("map_sint32_sint32")); + sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_key_, + 1); + sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_val_, + 1); + + sub_message = reflection->AddMessage(message, F("map_sint64_sint64")); + sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_key_, + 1); + sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_val_, + 1); + + sub_message = reflection->AddMessage(message, F("map_fixed32_fixed32")); + sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_key_, + 1); + sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_val_, + 1); + + sub_message = reflection->AddMessage(message, F("map_fixed64_fixed64")); + sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_key_, + 1); + sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_val_, + 1); + + sub_message = reflection->AddMessage(message, F("map_sfixed32_sfixed32")); + sub_message->GetReflection()->SetInt32(sub_message, + map_sfixed32_sfixed32_key_, 1); + sub_message->GetReflection()->SetInt32(sub_message, + map_sfixed32_sfixed32_val_, 1); + + sub_message = reflection->AddMessage(message, F("map_sfixed64_sfixed64")); + sub_message->GetReflection()->SetInt64(sub_message, + map_sfixed64_sfixed64_key_, 1); + sub_message->GetReflection()->SetInt64(sub_message, + map_sfixed64_sfixed64_val_, 1); + + sub_message = reflection->AddMessage(message, F("map_int32_float")); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_float_key_, 1); + sub_message->GetReflection()->SetFloat(sub_message, map_int32_float_val_, + 1.0); + + sub_message = reflection->AddMessage(message, F("map_int32_double")); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_double_key_, 1); + sub_message->GetReflection()->SetDouble(sub_message, map_int32_double_val_, + 1.0); + + sub_message = reflection->AddMessage(message, F("map_bool_bool")); + sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_key_, true); + sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_val_, true); + + sub_message = reflection->AddMessage(message, F("map_string_string")); + sub_message->GetReflection()->SetString(sub_message, map_string_string_key_, + "1"); + sub_message->GetReflection()->SetString(sub_message, map_string_string_val_, + "1"); + + sub_message = reflection->AddMessage(message, F("map_int32_bytes")); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_bytes_key_, 1); + sub_message->GetReflection()->SetString(sub_message, map_int32_bytes_val_, + "1"); + + sub_message = reflection->AddMessage(message, F("map_int32_enum")); + sub_message->GetReflection()->SetInt32(sub_message, map_int32_enum_key_, 1); + sub_message->GetReflection()->SetEnum(sub_message, map_int32_enum_val_, + map_enum_baz_); + + sub_message = reflection->AddMessage(message, F("map_int32_foreign_message")); + sub_message->GetReflection()->SetInt32(sub_message, + map_int32_foreign_message_key_, 1); + sub_foreign_message = sub_message->GetReflection()->MutableMessage( + sub_message, map_int32_foreign_message_val_, nullptr); + sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message, + foreign_c_, 1); +} + +void MapReflectionTester::SetMapFieldsViaMapReflection(Message* message) { + const Reflection* reflection = message->GetReflection(); + + Message* sub_foreign_message = nullptr; + MapValueRef map_val; + MapValueConstRef map_val_const; + + // Add first element. + MapKey map_key; + map_key.SetInt32Value(0); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_int32"), + map_key, &map_val_const)); + EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"), + map_key, &map_val)); + map_val.SetInt32Value(0); + + map_key.SetInt64Value(0); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int64_int64"), + map_key, &map_val_const)); + EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"), + map_key, &map_val)); + map_val.SetInt64Value(0); + + map_key.SetUInt32Value(0); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_uint32_uint32"), + map_key, &map_val_const)); + EXPECT_TRUE(reflection->InsertOrLookupMapValue( + message, F("map_uint32_uint32"), map_key, &map_val)); + map_val.SetUInt32Value(0); + + map_key.SetUInt64Value(0); + EXPECT_TRUE(reflection->InsertOrLookupMapValue( + message, F("map_uint64_uint64"), map_key, &map_val)); + map_val.SetUInt64Value(0); + + map_key.SetInt32Value(0); + EXPECT_TRUE(reflection->InsertOrLookupMapValue( + message, F("map_sint32_sint32"), map_key, &map_val)); + map_val.SetInt32Value(0); + + map_key.SetInt64Value(0); + EXPECT_TRUE(reflection->InsertOrLookupMapValue( + message, F("map_sint64_sint64"), map_key, &map_val)); + map_val.SetInt64Value(0); + + map_key.SetUInt32Value(0); + EXPECT_TRUE(reflection->InsertOrLookupMapValue( + message, F("map_fixed32_fixed32"), map_key, &map_val)); + map_val.SetUInt32Value(0); + + map_key.SetUInt64Value(0); + EXPECT_TRUE(reflection->InsertOrLookupMapValue( + message, F("map_fixed64_fixed64"), map_key, &map_val)); + map_val.SetUInt64Value(0); + + map_key.SetInt32Value(0); + EXPECT_TRUE(reflection->InsertOrLookupMapValue( + message, F("map_sfixed32_sfixed32"), map_key, &map_val)); + map_val.SetInt32Value(0); + + map_key.SetInt64Value(0); + EXPECT_TRUE(reflection->InsertOrLookupMapValue( + message, F("map_sfixed64_sfixed64"), map_key, &map_val)); + map_val.SetInt64Value(0); + + map_key.SetInt32Value(0); + EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_float"), + map_key, &map_val)); + map_val.SetFloatValue(0.0); + + map_key.SetInt32Value(0); + EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_double"), + map_key, &map_val)); + map_val.SetDoubleValue(0.0); + + map_key.SetBoolValue(false); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_bool_bool"), map_key, + &map_val_const)); + EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_bool_bool"), + map_key, &map_val)); + map_val.SetBoolValue(false); + + map_key.SetStringValue("0"); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_string_string"), + map_key, &map_val_const)); + EXPECT_TRUE(reflection->InsertOrLookupMapValue( + message, F("map_string_string"), map_key, &map_val)); + map_val.SetStringValue("0"); + + map_key.SetInt32Value(0); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_bytes"), + map_key, &map_val_const)); + EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"), + map_key, &map_val)); + map_val.SetStringValue("0"); + + map_key.SetInt32Value(0); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_enum"), + map_key, &map_val_const)); + EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_enum"), + map_key, &map_val)); + map_val.SetEnumValue(map_enum_bar_->number()); + + map_key.SetInt32Value(0); + EXPECT_FALSE(reflection->LookupMapValue( + *message, F("map_int32_foreign_message"), map_key, &map_val_const)); + EXPECT_TRUE(reflection->InsertOrLookupMapValue( + message, F("map_int32_foreign_message"), map_key, &map_val)); + sub_foreign_message = map_val.MutableMessageValue(); + sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message, + foreign_c_, 0); + + // Add second element + map_key.SetInt32Value(1); + EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"), + map_key, &map_val)); + map_val.SetInt32Value(1); + EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"), + map_key, &map_val)); + + map_key.SetInt64Value(1); + EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"), + map_key, &map_val)); + map_val.SetInt64Value(1); + EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"), + map_key, &map_val)); + + map_key.SetUInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_uint32_uint32"), map_key, + &map_val); + map_val.SetUInt32Value(1); + + map_key.SetUInt64Value(1); + reflection->InsertOrLookupMapValue(message, F("map_uint64_uint64"), map_key, + &map_val); + map_val.SetUInt64Value(1); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_sint32_sint32"), map_key, + &map_val); + map_val.SetInt32Value(1); + + map_key.SetInt64Value(1); + reflection->InsertOrLookupMapValue(message, F("map_sint64_sint64"), map_key, + &map_val); + map_val.SetInt64Value(1); + + map_key.SetUInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_fixed32_fixed32"), map_key, + &map_val); + map_val.SetUInt32Value(1); + + map_key.SetUInt64Value(1); + reflection->InsertOrLookupMapValue(message, F("map_fixed64_fixed64"), map_key, + &map_val); + map_val.SetUInt64Value(1); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_sfixed32_sfixed32"), + map_key, &map_val); + map_val.SetInt32Value(1); + + map_key.SetInt64Value(1); + reflection->InsertOrLookupMapValue(message, F("map_sfixed64_sfixed64"), + map_key, &map_val); + map_val.SetInt64Value(1); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_int32_float"), map_key, + &map_val); + map_val.SetFloatValue(1.0); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_int32_double"), map_key, + &map_val); + map_val.SetDoubleValue(1.0); + + map_key.SetBoolValue(true); + reflection->InsertOrLookupMapValue(message, F("map_bool_bool"), map_key, + &map_val); + map_val.SetBoolValue(true); + + map_key.SetStringValue("1"); + reflection->InsertOrLookupMapValue(message, F("map_string_string"), map_key, + &map_val); + map_val.SetStringValue("1"); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"), map_key, + &map_val); + map_val.SetStringValue("1"); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_int32_enum"), map_key, + &map_val); + map_val.SetEnumValue(map_enum_baz_->number()); + + map_key.SetInt32Value(1); + EXPECT_TRUE(reflection->InsertOrLookupMapValue( + message, F("map_int32_foreign_message"), map_key, &map_val)); + sub_foreign_message = map_val.MutableMessageValue(); + sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message, + foreign_c_, 1); +} + +void MapReflectionTester::GetMapValueViaMapReflection( + Message* message, const std::string& field_name, const MapKey& map_key, + MapValueRef* map_val) { + const Reflection* reflection = message->GetReflection(); + EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F(field_name), + map_key, map_val)); +} + +Message* MapReflectionTester::GetMapEntryViaReflection( + Message* message, const std::string& field_name, int index) { + const Reflection* reflection = message->GetReflection(); + return reflection->MutableRepeatedMessage(message, F(field_name), index); +} + +MapIterator MapReflectionTester::MapBegin(Message* message, + const std::string& field_name) { + const Reflection* reflection = message->GetReflection(); + return reflection->MapBegin(message, F(field_name)); +} + +MapIterator MapReflectionTester::MapEnd(Message* message, + const std::string& field_name) { + const Reflection* reflection = message->GetReflection(); + return reflection->MapEnd(message, F(field_name)); +} + +int MapReflectionTester::MapSize(const Message& message, + const std::string& field_name) { + const Reflection* reflection = message.GetReflection(); + return reflection->MapSize(message, F(field_name)); +} + +void MapReflectionTester::ClearMapFieldsViaReflection(Message* message) { + const Reflection* reflection = message->GetReflection(); + + reflection->ClearField(message, F("map_int32_int32")); + reflection->ClearField(message, F("map_int64_int64")); + reflection->ClearField(message, F("map_uint32_uint32")); + reflection->ClearField(message, F("map_uint64_uint64")); + reflection->ClearField(message, F("map_sint32_sint32")); + reflection->ClearField(message, F("map_sint64_sint64")); + reflection->ClearField(message, F("map_fixed32_fixed32")); + reflection->ClearField(message, F("map_fixed64_fixed64")); + reflection->ClearField(message, F("map_sfixed32_sfixed32")); + reflection->ClearField(message, F("map_sfixed64_sfixed64")); + reflection->ClearField(message, F("map_int32_float")); + reflection->ClearField(message, F("map_int32_double")); + reflection->ClearField(message, F("map_bool_bool")); + reflection->ClearField(message, F("map_string_string")); + reflection->ClearField(message, F("map_int32_bytes")); + reflection->ClearField(message, F("map_int32_enum")); + reflection->ClearField(message, F("map_int32_foreign_message")); +} + +void MapReflectionTester::ModifyMapFieldsViaReflection(Message* message) { + const Reflection* reflection = message->GetReflection(); + MapValueRef map_val; + Message* sub_foreign_message; + + // Modify the second element + MapKey map_key; + map_key.SetInt32Value(1); + EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"), + map_key, &map_val)); + map_val.SetInt32Value(2); + + map_key.SetInt64Value(1); + EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"), + map_key, &map_val)); + map_val.SetInt64Value(2); + + map_key.SetUInt32Value(1); + EXPECT_FALSE(reflection->InsertOrLookupMapValue( + message, F("map_uint32_uint32"), map_key, &map_val)); + map_val.SetUInt32Value(2); + + map_key.SetUInt64Value(1); + reflection->InsertOrLookupMapValue(message, F("map_uint64_uint64"), map_key, + &map_val); + map_val.SetUInt64Value(2); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_sint32_sint32"), map_key, + &map_val); + map_val.SetInt32Value(2); + + map_key.SetInt64Value(1); + reflection->InsertOrLookupMapValue(message, F("map_sint64_sint64"), map_key, + &map_val); + map_val.SetInt64Value(2); + + map_key.SetUInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_fixed32_fixed32"), map_key, + &map_val); + map_val.SetUInt32Value(2); + + map_key.SetUInt64Value(1); + reflection->InsertOrLookupMapValue(message, F("map_fixed64_fixed64"), map_key, + &map_val); + map_val.SetUInt64Value(2); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_sfixed32_sfixed32"), + map_key, &map_val); + map_val.SetInt32Value(2); + + map_key.SetInt64Value(1); + reflection->InsertOrLookupMapValue(message, F("map_sfixed64_sfixed64"), + map_key, &map_val); + map_val.SetInt64Value(2); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_int32_float"), map_key, + &map_val); + map_val.SetFloatValue(2.0); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_int32_double"), map_key, + &map_val); + map_val.SetDoubleValue(2.0); + + map_key.SetBoolValue(true); + reflection->InsertOrLookupMapValue(message, F("map_bool_bool"), map_key, + &map_val); + map_val.SetBoolValue(false); + + map_key.SetStringValue("1"); + reflection->InsertOrLookupMapValue(message, F("map_string_string"), map_key, + &map_val); + map_val.SetStringValue("2"); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"), map_key, + &map_val); + map_val.SetStringValue("2"); + + map_key.SetInt32Value(1); + reflection->InsertOrLookupMapValue(message, F("map_int32_enum"), map_key, + &map_val); + map_val.SetEnumValue(map_enum_foo_->number()); + + map_key.SetInt32Value(1); + EXPECT_FALSE(reflection->InsertOrLookupMapValue( + message, F("map_int32_foreign_message"), map_key, &map_val)); + sub_foreign_message = map_val.MutableMessageValue(); + sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message, + foreign_c_, 2); +} + +void MapReflectionTester::RemoveLastMapsViaReflection(Message* message) { + const Reflection* reflection = message->GetReflection(); + + std::vector<const FieldDescriptor*> output; + reflection->ListFields(*message, &output); + for (int i = 0; i < output.size(); ++i) { + const FieldDescriptor* field = output[i]; + if (!field->is_repeated()) continue; + reflection->RemoveLast(message, field); + } +} + +void MapReflectionTester::ReleaseLastMapsViaReflection(Message* message) { + const Reflection* reflection = message->GetReflection(); + + std::vector<const FieldDescriptor*> output; + reflection->ListFields(*message, &output); + for (int i = 0; i < output.size(); ++i) { + const FieldDescriptor* field = output[i]; + if (!field->is_repeated()) continue; + if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue; + + Message* released = reflection->ReleaseLast(message, field); + ASSERT_TRUE(released != nullptr) + << "ReleaseLast returned nullptr for: " << field->name(); + delete released; + } +} + +void MapReflectionTester::SwapMapsViaReflection(Message* message) { + const Reflection* reflection = message->GetReflection(); + std::vector<const FieldDescriptor*> output; + reflection->ListFields(*message, &output); + for (int i = 0; i < output.size(); ++i) { + const FieldDescriptor* field = output[i]; + if (!field->is_repeated()) continue; + reflection->SwapElements(message, field, 0, 1); + } +} + +void MapReflectionTester::MutableUnknownFieldsOfMapFieldsViaReflection( + Message* message) { + const Reflection* reflection = message->GetReflection(); + Message* sub_message = nullptr; + + sub_message = reflection->AddMessage(message, F("map_int32_int32")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_int64_int64")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_uint32_uint32")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_uint64_uint64")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_sint32_sint32")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_sint64_sint64")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_fixed32_fixed32")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_fixed64_fixed64")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_sfixed32_sfixed32")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_sfixed64_sfixed64")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_int32_float")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_int32_double")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_bool_bool")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_string_string")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_int32_bytes")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_int32_enum")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); + sub_message = reflection->AddMessage(message, F("map_int32_foreign_message")); + EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) != + nullptr); +} + +void MapReflectionTester::ExpectMapFieldsSetViaReflection( + const Message& message) { + std::string scratch; + const Reflection* reflection = message.GetReflection(); + const Message* sub_message; + MapKey map_key; + MapValueConstRef map_value_const_ref; + + // ----------------------------------------------------------------- + + ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_int32"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_int64_int64"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_uint32_uint32"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_uint64_uint64"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_sint32_sint32"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_sint64_sint64"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_fixed32_fixed32"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_fixed64_fixed64"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_sfixed32_sfixed32"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_sfixed64_sfixed64"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_float"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_double"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_bool_bool"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_string_string"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_bytes"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_enum"))); + ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_foreign_message"))); + + { + std::map<int32_t, int32_t> map; + map[0] = 0; + map[1] = 1; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_int32_int32")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_int32_int32"), i); + int32_t key = sub_message->GetReflection()->GetInt32( + *sub_message, map_int32_int32_key_); + int32_t val = sub_message->GetReflection()->GetInt32( + *sub_message, map_int32_int32_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetInt32Value(i); + EXPECT_TRUE( + reflection->ContainsMapKey(message, F("map_int32_int32"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_int32"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt32Value(), map[i]); + } + } + } + { + std::map<int64_t, int64_t> map; + map[0] = 0; + map[1] = 1; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_int64_int64")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_int64_int64"), i); + int64_t key = sub_message->GetReflection()->GetInt64( + *sub_message, map_int64_int64_key_); + int64_t val = sub_message->GetReflection()->GetInt64( + *sub_message, map_int64_int64_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetInt64Value(i); + EXPECT_TRUE( + reflection->ContainsMapKey(message, F("map_int64_int64"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int64_int64"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt64Value(), map[i]); + } + } + } + { + std::map<uint32_t, uint32_t> map; + map[0] = 0; + map[1] = 1; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_uint32_uint32")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_uint32_uint32"), i); + uint32_t key = sub_message->GetReflection()->GetUInt32( + *sub_message, map_uint32_uint32_key_); + uint32_t val = sub_message->GetReflection()->GetUInt32( + *sub_message, map_uint32_uint32_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetUInt32Value(i); + EXPECT_TRUE(reflection->ContainsMapKey(message, F("map_uint32_uint32"), + map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_uint32_uint32"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetUInt32Value(), map[i]); + } + } + } + { + std::map<uint64_t, uint64_t> map; + map[0] = 0; + map[1] = 1; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_uint64_uint64")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_uint64_uint64"), i); + uint64_t key = sub_message->GetReflection()->GetUInt64( + *sub_message, map_uint64_uint64_key_); + uint64_t val = sub_message->GetReflection()->GetUInt64( + *sub_message, map_uint64_uint64_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetUInt64Value(i); + EXPECT_TRUE(reflection->ContainsMapKey(message, F("map_uint64_uint64"), + map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_uint64_uint64"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetUInt64Value(), map[i]); + } + } + } + { + std::map<int32_t, int32_t> map; + map[0] = 0; + map[1] = 1; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_sint32_sint32")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_sint32_sint32"), i); + int32_t key = sub_message->GetReflection()->GetInt32( + *sub_message, map_sint32_sint32_key_); + int32_t val = sub_message->GetReflection()->GetInt32( + *sub_message, map_sint32_sint32_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetInt32Value(i); + EXPECT_EQ(true, reflection->ContainsMapKey( + message, F("map_sint32_sint32"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_sint32_sint32"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt32Value(), map[i]); + } + } + } + { + std::map<int64_t, int64_t> map; + map[0] = 0; + map[1] = 1; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_sint64_sint64")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_sint64_sint64"), i); + int64_t key = sub_message->GetReflection()->GetInt64( + *sub_message, map_sint64_sint64_key_); + int64_t val = sub_message->GetReflection()->GetInt64( + *sub_message, map_sint64_sint64_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetInt64Value(i); + EXPECT_EQ(true, reflection->ContainsMapKey( + message, F("map_sint64_sint64"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_sint64_sint64"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt64Value(), map[i]); + } + } + } + { + std::map<uint32_t, uint32_t> map; + map[0] = 0; + map[1] = 1; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_fixed32_fixed32")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = &reflection->GetRepeatedMessage( + message, F("map_fixed32_fixed32"), i); + uint32_t key = sub_message->GetReflection()->GetUInt32( + *sub_message, map_fixed32_fixed32_key_); + uint32_t val = sub_message->GetReflection()->GetUInt32( + *sub_message, map_fixed32_fixed32_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetUInt32Value(i); + EXPECT_EQ(true, reflection->ContainsMapKey( + message, F("map_fixed32_fixed32"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue( + message, F("map_fixed32_fixed32"), map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetUInt32Value(), map[i]); + } + } + } + { + std::map<uint64_t, uint64_t> map; + map[0] = 0; + map[1] = 1; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_fixed64_fixed64")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = &reflection->GetRepeatedMessage( + message, F("map_fixed64_fixed64"), i); + uint64_t key = sub_message->GetReflection()->GetUInt64( + *sub_message, map_fixed64_fixed64_key_); + uint64_t val = sub_message->GetReflection()->GetUInt64( + *sub_message, map_fixed64_fixed64_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetUInt64Value(i); + EXPECT_EQ(true, reflection->ContainsMapKey( + message, F("map_fixed64_fixed64"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue( + message, F("map_fixed64_fixed64"), map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetUInt64Value(), map[i]); + } + } + } + { + std::map<int32_t, int32_t> map; + map[0] = 0; + map[1] = 1; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>( + message, F("map_sfixed32_sfixed32")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = &reflection->GetRepeatedMessage( + message, F("map_sfixed32_sfixed32"), i); + int32_t key = sub_message->GetReflection()->GetInt32( + *sub_message, map_sfixed32_sfixed32_key_); + int32_t val = sub_message->GetReflection()->GetInt32( + *sub_message, map_sfixed32_sfixed32_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetInt32Value(i); + EXPECT_EQ(true, reflection->ContainsMapKey( + message, F("map_sfixed32_sfixed32"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, + F("map_sfixed32_sfixed32"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt32Value(), map[i]); + } + } + } + { + std::map<int64_t, int64_t> map; + map[0] = 0; + map[1] = 1; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>( + message, F("map_sfixed64_sfixed64")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = &reflection->GetRepeatedMessage( + message, F("map_sfixed64_sfixed64"), i); + int64_t key = sub_message->GetReflection()->GetInt64( + *sub_message, map_sfixed64_sfixed64_key_); + int64_t val = sub_message->GetReflection()->GetInt64( + *sub_message, map_sfixed64_sfixed64_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetInt64Value(i); + EXPECT_EQ(true, reflection->ContainsMapKey( + message, F("map_sfixed64_sfixed64"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, + F("map_sfixed64_sfixed64"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt64Value(), map[i]); + } + } + } + { + std::map<int32_t, float> map; + map[0] = 0.0; + map[1] = 1.0; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_int32_float")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_int32_float"), i); + int32_t key = sub_message->GetReflection()->GetInt32( + *sub_message, map_int32_float_key_); + float val = sub_message->GetReflection()->GetFloat( + *sub_message, map_int32_float_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetInt32Value(i); + EXPECT_EQ(true, reflection->ContainsMapKey( + message, F("map_int32_float"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_float"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetFloatValue(), map[i]); + } + } + } + { + std::map<int32_t, double> map; + map[0] = 0.0; + map[1] = 1.0; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_int32_double")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_int32_double"), i); + int32_t key = sub_message->GetReflection()->GetInt32( + *sub_message, map_int32_double_key_); + double val = sub_message->GetReflection()->GetDouble( + *sub_message, map_int32_double_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetInt32Value(i); + EXPECT_EQ(true, reflection->ContainsMapKey( + message, F("map_int32_double"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_double"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetDoubleValue(), map[i]); + } + } + } + { + std::map<bool, bool> map; + map[false] = false; + map[true] = true; + std::vector<bool> keys = {false, true}; + std::vector<bool> vals = {false, true}; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_bool_bool")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_bool_bool"), i); + bool key = sub_message->GetReflection()->GetBool(*sub_message, + map_bool_bool_key_); + bool val = sub_message->GetReflection()->GetBool(*sub_message, + map_bool_bool_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetBoolValue(keys[i]); + EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_bool_bool"), + map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_bool_bool"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetBoolValue(), vals[i]); + } + } + } + { + std::map<std::string, std::string> map; + map["0"] = "0"; + map["1"] = "1"; + std::vector<std::string> keys = {"0", "1"}; + std::vector<std::string> vals = {"0", "1"}; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_string_string")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_string_string"), i); + std::string key = sub_message->GetReflection()->GetString( + *sub_message, map_string_string_key_); + std::string val = sub_message->GetReflection()->GetString( + *sub_message, map_string_string_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetStringValue(keys[i]); + EXPECT_EQ(true, reflection->ContainsMapKey( + message, F("map_string_string"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_string_string"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetStringValue(), vals[i]); + } + } + } + { + std::map<int32_t, std::string> map; + map[0] = "0"; + map[1] = "1"; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_int32_bytes")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_int32_bytes"), i); + int32_t key = sub_message->GetReflection()->GetInt32( + *sub_message, map_int32_bytes_key_); + std::string val = sub_message->GetReflection()->GetString( + *sub_message, map_int32_bytes_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetInt32Value(i); + EXPECT_EQ(true, reflection->ContainsMapKey( + message, F("map_int32_bytes"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_bytes"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetStringValue(), map[i]); + } + } + } + { + std::map<int32_t, const EnumValueDescriptor*> map; + map[0] = map_enum_bar_; + map[1] = map_enum_baz_; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>(message, + F("map_int32_enum")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = + &reflection->GetRepeatedMessage(message, F("map_int32_enum"), i); + int32_t key = sub_message->GetReflection()->GetInt32( + *sub_message, map_int32_enum_key_); + const EnumValueDescriptor* val = sub_message->GetReflection()->GetEnum( + *sub_message, map_int32_enum_val_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetInt32Value(i); + EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_enum"), + map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_enum"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetEnumValue(), map[i]->number()); + } + } + } + { + std::map<int32_t, int32_t> map; + map[0] = 0; + map[1] = 1; + for (int i = 0; i < 2; i++) { + const internal::MapFieldBase& map_field = + reflection->GetRaw<internal::MapFieldBase>( + message, F("map_int32_foreign_message")); + if (map_field.IsRepeatedFieldValid()) { + // Check with RepeatedField Reflection + sub_message = &reflection->GetRepeatedMessage( + message, F("map_int32_foreign_message"), i); + int32_t key = sub_message->GetReflection()->GetInt32( + *sub_message, map_int32_foreign_message_key_); + const Message& foreign_message = + sub_message->GetReflection()->GetMessage( + *sub_message, map_int32_foreign_message_val_); + int32_t val = foreign_message.GetReflection()->GetInt32(foreign_message, + foreign_c_); + EXPECT_EQ(map[key], val); + } else { + // Check with Map Reflection + map_key.SetInt32Value(i); + EXPECT_EQ(true, reflection->ContainsMapKey( + message, F("map_int32_foreign_message"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, + F("map_int32_foreign_message"), + map_key, &map_value_const_ref)); + const Message& foreign_message = map_value_const_ref.GetMessageValue(); + EXPECT_EQ(foreign_message.GetReflection()->GetInt32(foreign_message, + foreign_c_), + map[i]); + } + } + } +} + +void MapReflectionTester::ExpectMapFieldsSetViaReflectionIterator( + Message* message) { + std::string scratch; + std::string serialized; + const Reflection* reflection = message->GetReflection(); + + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_int32"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int64_int64"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_uint32_uint32"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_uint64_uint64"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sint32_sint32"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sint64_sint64"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_fixed32_fixed32"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_fixed64_fixed64"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sfixed32_sfixed32"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sfixed64_sfixed64"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_float"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_double"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_bool_bool"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_string_string"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_bytes"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_enum"))); + ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_foreign_message"))); + + { + std::map<int32_t, int32_t> map; + map[0] = 0; + map[1] = 1; + int size = 0; + for (MapIterator iter = reflection->MapBegin(message, F("map_int32_int32")); + iter != reflection->MapEnd(message, F("map_int32_int32")); + ++iter, ++size) { + // Check const methods do not invalidate map. + message->DebugString(); + message->ShortDebugString(); + message->SerializeToString(&serialized); + message->SpaceUsedLong(); + message->ByteSizeLong(); + EXPECT_EQ(map[iter.GetKey().GetInt32Value()], + iter.GetValueRef().GetInt32Value()); + } + EXPECT_EQ(size, 2); + } + { + std::map<int64_t, int64_t> map; + map[0] = 0; + map[1] = 1; + for (MapIterator iter = reflection->MapBegin(message, F("map_int64_int64")); + iter != reflection->MapEnd(message, F("map_int64_int64")); ++iter) { + EXPECT_EQ(map[iter.GetKey().GetInt64Value()], + iter.GetValueRef().GetInt64Value()); + } + } + { + std::map<uint32_t, uint32_t> map; + map[0] = 0; + map[1] = 1; + for (MapIterator iter = + reflection->MapBegin(message, F("map_uint32_uint32")); + iter != reflection->MapEnd(message, F("map_uint32_uint32")); ++iter) { + EXPECT_EQ(map[iter.GetKey().GetUInt32Value()], + iter.GetValueRef().GetUInt32Value()); + } + } + { + std::map<uint64_t, uint64_t> map; + map[0] = 0; + map[1] = 1; + for (MapIterator iter = + reflection->MapBegin(message, F("map_uint64_uint64")); + iter != reflection->MapEnd(message, F("map_uint64_uint64")); ++iter) { + EXPECT_EQ(map[iter.GetKey().GetUInt64Value()], + iter.GetValueRef().GetUInt64Value()); + } + } + { + std::map<int32_t, int32_t> map; + map[0] = 0; + map[1] = 1; + for (MapIterator iter = + reflection->MapBegin(message, F("map_sint32_sint32")); + iter != reflection->MapEnd(message, F("map_sint32_sint32")); ++iter) { + EXPECT_EQ(map[iter.GetKey().GetInt32Value()], + iter.GetValueRef().GetInt32Value()); + } + } + { + std::map<int64_t, int64_t> map; + map[0] = 0; + map[1] = 1; + for (MapIterator iter = + reflection->MapBegin(message, F("map_sint64_sint64")); + iter != reflection->MapEnd(message, F("map_sint64_sint64")); ++iter) { + EXPECT_EQ(map[iter.GetKey().GetInt64Value()], + iter.GetValueRef().GetInt64Value()); + } + } + { + std::map<uint32_t, uint32_t> map; + map[0] = 0; + map[1] = 1; + for (MapIterator iter = + reflection->MapBegin(message, F("map_fixed32_fixed32")); + iter != reflection->MapEnd(message, F("map_fixed32_fixed32")); + ++iter) { + EXPECT_EQ(map[iter.GetKey().GetUInt32Value()], + iter.GetValueRef().GetUInt32Value()); + } + } + { + std::map<uint64_t, uint64_t> map; + map[0] = 0; + map[1] = 1; + for (MapIterator iter = + reflection->MapBegin(message, F("map_fixed64_fixed64")); + iter != reflection->MapEnd(message, F("map_fixed64_fixed64")); + ++iter) { + EXPECT_EQ(map[iter.GetKey().GetUInt64Value()], + iter.GetValueRef().GetUInt64Value()); + } + } + { + std::map<int32_t, int32_t> map; + map[0] = 0; + map[1] = 1; + for (MapIterator iter = + reflection->MapBegin(message, F("map_sfixed32_sfixed32")); + iter != reflection->MapEnd(message, F("map_sfixed32_sfixed32")); + ++iter) { + EXPECT_EQ(map[iter.GetKey().GetInt32Value()], + iter.GetValueRef().GetInt32Value()); + } + } + { + std::map<int32_t, float> map; + map[0] = 0.0; + map[1] = 1.0; + for (MapIterator iter = reflection->MapBegin(message, F("map_int32_float")); + iter != reflection->MapEnd(message, F("map_int32_float")); ++iter) { + EXPECT_EQ(map[iter.GetKey().GetInt32Value()], + iter.GetValueRef().GetFloatValue()); + } + } + { + std::map<int32_t, double> map; + map[0] = 0.0; + map[1] = 1.0; + for (MapIterator iter = + reflection->MapBegin(message, F("map_int32_double")); + iter != reflection->MapEnd(message, F("map_int32_double")); ++iter) { + EXPECT_EQ(map[iter.GetKey().GetInt32Value()], + iter.GetValueRef().GetDoubleValue()); + } + } + { + std::map<bool, bool> map; + map[false] = false; + map[true] = true; + for (MapIterator iter = reflection->MapBegin(message, F("map_bool_bool")); + iter != reflection->MapEnd(message, F("map_bool_bool")); ++iter) { + EXPECT_EQ(map[iter.GetKey().GetBoolValue()], + iter.GetValueRef().GetBoolValue()); + } + } + { + std::map<std::string, std::string> map; + map["0"] = "0"; + map["1"] = "1"; + int size = 0; + for (MapIterator iter = + reflection->MapBegin(message, F("map_string_string")); + iter != reflection->MapEnd(message, F("map_string_string")); + ++iter, ++size) { + // Check const methods do not invalidate map. + message->DebugString(); + message->ShortDebugString(); + message->SerializeToString(&serialized); + message->SpaceUsedLong(); + message->ByteSizeLong(); + EXPECT_EQ(map[iter.GetKey().GetStringValue()], + iter.GetValueRef().GetStringValue()); + } + EXPECT_EQ(size, 2); + } + { + std::map<int32_t, std::string> map; + map[0] = "0"; + map[1] = "1"; + for (MapIterator iter = reflection->MapBegin(message, F("map_int32_bytes")); + iter != reflection->MapEnd(message, F("map_int32_bytes")); ++iter) { + EXPECT_EQ(map[iter.GetKey().GetInt32Value()], + iter.GetValueRef().GetStringValue()); + } + } + { + std::map<int32_t, const EnumValueDescriptor*> map; + map[0] = map_enum_bar_; + map[1] = map_enum_baz_; + for (MapIterator iter = reflection->MapBegin(message, F("map_int32_enum")); + iter != reflection->MapEnd(message, F("map_int32_enum")); ++iter) { + EXPECT_EQ(map[iter.GetKey().GetInt32Value()]->number(), + iter.GetValueRef().GetEnumValue()); + } + } + { + std::map<int32_t, int32_t> map; + map[0] = 0; + map[1] = 1; + int size = 0; + for (MapIterator iter = + reflection->MapBegin(message, F("map_int32_foreign_message")); + iter != reflection->MapEnd(message, F("map_int32_foreign_message")); + ++iter, ++size) { + // Check const methods do not invalidate map. + message->DebugString(); + message->ShortDebugString(); + message->SerializeToString(&serialized); + message->SpaceUsedLong(); + message->ByteSizeLong(); + const Message& sub_message = iter.GetValueRef().GetMessageValue(); + EXPECT_EQ(map[iter.GetKey().GetInt32Value()], + sub_message.GetReflection()->GetInt32(sub_message, foreign_c_)); + } + EXPECT_EQ(size, 2); + } +} + +void MapReflectionTester::ExpectClearViaReflection(const Message& message) { + const Reflection* reflection = message.GetReflection(); + // Map fields are empty. + EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_int32"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_int64_int64"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_uint32_uint32"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_uint64_uint64"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_sint32_sint32"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_sint64_sint64"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_fixed32_fixed32"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_fixed64_fixed64"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_sfixed32_sfixed32"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_sfixed64_sfixed64"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_float"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_double"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_bool_bool"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_string_string"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_bytes"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_enum"))); + EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_foreign_message"))); + EXPECT_TRUE(reflection->GetMapData(message, F("map_int32_foreign_message")) + ->IsMapValid()); +} + +void MapReflectionTester::ExpectClearViaReflectionIterator(Message* message) { + const Reflection* reflection = message->GetReflection(); + EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_int32")) == + reflection->MapEnd(message, F("map_int32_int32"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_int64_int64")) == + reflection->MapEnd(message, F("map_int64_int64"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_uint32_uint32")) == + reflection->MapEnd(message, F("map_uint32_uint32"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_uint64_uint64")) == + reflection->MapEnd(message, F("map_uint64_uint64"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_sint32_sint32")) == + reflection->MapEnd(message, F("map_sint32_sint32"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_sint64_sint64")) == + reflection->MapEnd(message, F("map_sint64_sint64"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_fixed32_fixed32")) == + reflection->MapEnd(message, F("map_fixed32_fixed32"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_fixed64_fixed64")) == + reflection->MapEnd(message, F("map_fixed64_fixed64"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_sfixed32_sfixed32")) == + reflection->MapEnd(message, F("map_sfixed32_sfixed32"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_sfixed64_sfixed64")) == + reflection->MapEnd(message, F("map_sfixed64_sfixed64"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_float")) == + reflection->MapEnd(message, F("map_int32_float"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_double")) == + reflection->MapEnd(message, F("map_int32_double"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_bool_bool")) == + reflection->MapEnd(message, F("map_bool_bool"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_string_string")) == + reflection->MapEnd(message, F("map_string_string"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_bytes")) == + reflection->MapEnd(message, F("map_int32_bytes"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_enum")) == + reflection->MapEnd(message, F("map_int32_enum"))); + EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_foreign_message")) == + reflection->MapEnd(message, F("map_int32_foreign_message"))); +} + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc>
diff --git a/src/google/protobuf/reflection_tester.h b/src/google/protobuf/reflection_tester.h new file mode 100644 index 0000000..3a2dc81 --- /dev/null +++ b/src/google/protobuf/reflection_tester.h
@@ -0,0 +1,122 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_REFLECTION_TESTER_H__ +#define GOOGLE_PROTOBUF_REFLECTION_TESTER_H__ + +#include <google/protobuf/message.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { + +// Provides APIs to test protocol buffers reflectively. +class MapReflectionTester { + public: + // base_descriptor must be a descriptor for TestMap, which is used for + // MapReflectionTester to fetch the FieldDescriptors needed to use the + // reflection interface. + explicit MapReflectionTester(const Descriptor* base_descriptor); + + void SetMapFieldsViaReflection(Message* message); + void SetMapFieldsViaMapReflection(Message* message); + void ClearMapFieldsViaReflection(Message* message); + void ModifyMapFieldsViaReflection(Message* message); + void RemoveLastMapsViaReflection(Message* message); + void ReleaseLastMapsViaReflection(Message* message); + void SwapMapsViaReflection(Message* message); + void MutableUnknownFieldsOfMapFieldsViaReflection(Message* message); + void ExpectMapFieldsSetViaReflection(const Message& message); + void ExpectMapFieldsSetViaReflectionIterator(Message* message); + void ExpectClearViaReflection(const Message& message); + void ExpectClearViaReflectionIterator(Message* message); + void GetMapValueViaMapReflection(Message* message, + const std::string& field_name, + const MapKey& map_key, MapValueRef* map_val); + Message* GetMapEntryViaReflection(Message* message, + const std::string& field_name, int index); + MapIterator MapBegin(Message* message, const std::string& field_name); + MapIterator MapEnd(Message* message, const std::string& field_name); + int MapSize(const Message& message, const std::string& field_name); + + private: + const FieldDescriptor* F(const std::string& name); + + const Descriptor* base_descriptor_; + + const EnumValueDescriptor* map_enum_bar_; + const EnumValueDescriptor* map_enum_baz_; + const EnumValueDescriptor* map_enum_foo_; + + const FieldDescriptor* foreign_c_; + const FieldDescriptor* map_int32_int32_key_; + const FieldDescriptor* map_int32_int32_val_; + const FieldDescriptor* map_int64_int64_key_; + const FieldDescriptor* map_int64_int64_val_; + const FieldDescriptor* map_uint32_uint32_key_; + const FieldDescriptor* map_uint32_uint32_val_; + const FieldDescriptor* map_uint64_uint64_key_; + const FieldDescriptor* map_uint64_uint64_val_; + const FieldDescriptor* map_sint32_sint32_key_; + const FieldDescriptor* map_sint32_sint32_val_; + const FieldDescriptor* map_sint64_sint64_key_; + const FieldDescriptor* map_sint64_sint64_val_; + const FieldDescriptor* map_fixed32_fixed32_key_; + const FieldDescriptor* map_fixed32_fixed32_val_; + const FieldDescriptor* map_fixed64_fixed64_key_; + const FieldDescriptor* map_fixed64_fixed64_val_; + const FieldDescriptor* map_sfixed32_sfixed32_key_; + const FieldDescriptor* map_sfixed32_sfixed32_val_; + const FieldDescriptor* map_sfixed64_sfixed64_key_; + const FieldDescriptor* map_sfixed64_sfixed64_val_; + const FieldDescriptor* map_int32_float_key_; + const FieldDescriptor* map_int32_float_val_; + const FieldDescriptor* map_int32_double_key_; + const FieldDescriptor* map_int32_double_val_; + const FieldDescriptor* map_bool_bool_key_; + const FieldDescriptor* map_bool_bool_val_; + const FieldDescriptor* map_string_string_key_; + const FieldDescriptor* map_string_string_val_; + const FieldDescriptor* map_int32_bytes_key_; + const FieldDescriptor* map_int32_bytes_val_; + const FieldDescriptor* map_int32_enum_key_; + const FieldDescriptor* map_int32_enum_val_; + const FieldDescriptor* map_int32_foreign_message_key_; + const FieldDescriptor* map_int32_foreign_message_val_; +}; + +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_REFLECTION_TESTER_H__
diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc index addd26ce..501575b 100644 --- a/src/google/protobuf/repeated_field.cc +++ b/src/google/protobuf/repeated_field.cc
@@ -58,10 +58,10 @@ Arena* arena = GetArena(); new_size = std::max(internal::kRepeatedFieldLowerClampLimit, std::max(total_size_ * 2, new_size)); - GOOGLE_CHECK_LE( - static_cast<int64>(new_size), - static_cast<int64>((std::numeric_limits<size_t>::max() - kRepHeaderSize) / - sizeof(old_rep->elements[0]))) + GOOGLE_CHECK_LE(static_cast<int64_t>(new_size), + static_cast<int64_t>( + (std::numeric_limits<size_t>::max() - kRepHeaderSize) / + sizeof(old_rep->elements[0]))) << "Requested size is too large to fit into size_t."; size_t bytes = kRepHeaderSize + sizeof(old_rep->elements[0]) * new_size; if (arena == NULL) { @@ -135,10 +135,10 @@ template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<bool>; -template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<int32>; -template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<uint32>; -template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<int64>; -template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<uint64>; +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<int32_t>; +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<uint32_t>; +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<int64_t>; +template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<uint64_t>; template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<float>; template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<double>; template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedPtrField<std::string>;
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index c8fe933..0541008 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h
@@ -144,15 +144,15 @@ q + sizeof(reg_type)); \ } -PROTO_MEMSWAP_DEF_SIZE(uint8, 2) -PROTO_MEMSWAP_DEF_SIZE(uint16, 4) -PROTO_MEMSWAP_DEF_SIZE(uint32, 8) +PROTO_MEMSWAP_DEF_SIZE(uint8_t, 2) +PROTO_MEMSWAP_DEF_SIZE(uint16_t, 4) +PROTO_MEMSWAP_DEF_SIZE(uint32_t, 8) #ifdef __SIZEOF_INT128__ -PROTO_MEMSWAP_DEF_SIZE(uint64, 16) +PROTO_MEMSWAP_DEF_SIZE(uint64_t, 16) PROTO_MEMSWAP_DEF_SIZE(__uint128_t, (1u << 31)) #else -PROTO_MEMSWAP_DEF_SIZE(uint64, (1u << 31)) +PROTO_MEMSWAP_DEF_SIZE(uint64_t, (1u << 31)) #endif #undef PROTO_MEMSWAP_DEF_SIZE @@ -1089,18 +1089,18 @@ // It is also useful in legacy code that uses temporary ownership to avoid // copies. Example: // RepeatedPtrField<T> temp_field; - // temp_field.AddAllocated(new T); + // temp_field.UnsafeArenaAddAllocated(new T); // ... // Do something with temp_field - // temp_field.ExtractSubrange(0, temp_field.size(), nullptr); + // temp_field.UnsafeArenaExtractSubrange(0, temp_field.size(), nullptr); // If you put temp_field on the arena this fails, because the ownership // transfers to the arena at the "AddAllocated" call and is not released // anymore causing a double delete. UnsafeArenaAddAllocated prevents this. void UnsafeArenaAddAllocated(Element* value); - // Remove the last element and return it. Works only when operating on an - // arena. The returned pointer is to the original object in the arena, hence - // has the arena's lifetime. - // Requires: current_size_ > 0 + // Remove the last element and return it. Unlike ReleaseLast, the returned + // pointer is always to the original object. This may be in an arena, and + // therefore have the arena's lifetime. + // Requires: current_size_ > 0 Element* UnsafeArenaReleaseLast(); // Extract elements with indices in the range "[start .. start+num-1]". @@ -1120,10 +1120,10 @@ // UnsafeArenaExtractSubrange(). void ExtractSubrange(int start, int num, Element** elements); - // Identical to ExtractSubrange() described above, except that when this - // repeated field is on an arena, no object copies are performed. Instead, the - // raw object pointers are returned. Thus, if on an arena, the returned - // objects must not be freed, because they will not be heap-allocated objects. + // Identical to ExtractSubrange() described above, except that no object + // copies are ever performed. Instead, the raw object pointers are returned. + // Thus, if on an arena, the returned objects must not be freed, because they + // will not be heap-allocated objects. void UnsafeArenaExtractSubrange(int start, int num, Element** elements); // When elements are removed by calls to RemoveLast() or Clear(), they @@ -1362,7 +1362,7 @@ template <typename Element> inline void RepeatedField<Element>::Add(const Element& value) { - uint32 size = current_size_; + uint32_t size = current_size_; if (static_cast<int>(size) == total_size_) { // value could reference an element of the array. Reserving new space will // invalidate the reference. So we must make a copy first. @@ -1377,7 +1377,7 @@ template <typename Element> inline Element* RepeatedField<Element>::Add() { - uint32 size = current_size_; + uint32_t size = current_size_; if (static_cast<int>(size) == total_size_) Reserve(total_size_ + 1); auto ptr = &elements()[size]; current_size_ = size + 1; @@ -1624,7 +1624,7 @@ // this, since Element is supposed to be POD, but a previous version of this // code allocated storage with "new Element[size]" and some code uses // RepeatedField with non-POD types, relying on constructor invocation. If - // Element has a trivial constructor (e.g., int32), gcc (tested with -O2) + // Element has a trivial constructor (e.g., int32_t), gcc (tested with -O2) // completely removes this loop because the loop body is empty, so this has no // effect unless its side-effects are required for correctness. // Note that we do this before MoveArray() below because Element's copy @@ -1978,9 +1978,7 @@ // Pass value_arena and my_arena to avoid duplicate virtual call (value) or // load (mine). typename TypeHandler::Type* value, Arena* value_arena, Arena* my_arena) { -#ifdef PROTOBUF_INTERNAL_USE_MUST_USE_RESULT GOOGLE_DCHECK(value_arena == nullptr || value_arena == my_arena); -#endif // PROTOBUF_INTERNAL_USE_MUST_USE_RESULT // Ensure that either the value is in the same arena, or if not, we do the // appropriate thing: Own() it (if it's on heap and we're in an arena) or copy // it to our arena/heap (otherwise). @@ -2285,11 +2283,9 @@ if (num == 0) return; -#ifdef PROTOBUF_MUST_USE_EXTRACT_RESULT GOOGLE_DCHECK_NE(elements, nullptr) << "Releasing elements without transferring ownership is an unsafe " "operation. Use UnsafeArenaExtractSubrange."; -#endif if (elements == nullptr) { CloseGap(start, num); return; @@ -2906,9 +2902,9 @@ // This is slightly faster if that matters. It is also useful in legacy code // that uses temporary ownership to avoid copies. Example: // RepeatedPtrField<T> temp_field; -// temp_field.AddAllocated(new T); +// temp_field.UnsafeArenaAddAllocated(new T); // ... // Do something with temp_field -// temp_field.ExtractSubrange(0, temp_field.size(), nullptr); +// temp_field.UnsafeArenaExtractSubrange(0, temp_field.size(), nullptr); // If you put temp_field on the arena this fails, because the ownership // transfers to the arena at the "AddAllocated" call and is not released anymore // causing a double delete. Using UnsafeArenaAddAllocated prevents this. @@ -2922,10 +2918,10 @@ // Extern declarations of common instantiations to reduce library bloat. extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<bool>; -extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<int32>; -extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<uint32>; -extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<int64>; -extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<uint64>; +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<int32_t>; +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<uint32_t>; +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<int64_t>; +extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<uint64_t>; extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<float>; extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<double>; extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 46b9e6d..429a63a 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -1128,14 +1128,13 @@ EXPECT_EQ(field.Add(), original); // Should return same string for reuse. - - EXPECT_EQ(field.ReleaseLast(), original); // We take ownership. + EXPECT_EQ(field.UnsafeArenaReleaseLast(), original); // We take ownership. EXPECT_EQ(field.ClearedCount(), 0); EXPECT_NE(field.Add(), original); // Should NOT return the same string. EXPECT_EQ(field.ClearedCount(), 0); - field.AddAllocated(original); // Give ownership back. + field.UnsafeArenaAddAllocated(original); // Give ownership back. EXPECT_EQ(field.ClearedCount(), 0); EXPECT_EQ(field.Mutable(1), original); @@ -1514,7 +1513,9 @@ std::vector<std::string*> subject; // Create an array with "sz" elements and "extra" cleared elements. - RepeatedPtrField<std::string> field; + // Use an arena to avoid copies from debug-build stability checks. + Arena arena; + RepeatedPtrField<std::string> field(&arena); for (int i = 0; i < sz + extra; ++i) { subject.push_back(new std::string()); field.AddAllocated(subject[i]); @@ -1534,7 +1535,7 @@ // Were the removed elements extracted into the catcher array? for (int i = 0; i < num; ++i) - EXPECT_EQ(catcher[i], subject[start + i]); + EXPECT_EQ(*catcher[i], *subject[start + i]); EXPECT_EQ(NULL, catcher[num]); // Does the resulting array contain the right values?
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index 1181ba8..14620c3 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc
@@ -40,10 +40,11 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::SourceContext, file_name_), }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(PROTOBUF_NAMESPACE_ID::SourceContext)}, + { 0, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::SourceContext)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -148,28 +149,29 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.SourceContext.file_name")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -212,13 +214,7 @@ this->_internal_file_name()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceContext::_class_data_ = { @@ -227,8 +223,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceContext::GetClassData() const { return &_class_data_; } -void SourceContext::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void SourceContext::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<SourceContext *>(to)->MergeFrom( static_cast<const SourceContext &>(from)); } @@ -259,11 +255,13 @@ void SourceContext::InternalSwap(SourceContext* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &file_name_, GetArenaForAllocation(), - &other->file_name_, other->GetArenaForAllocation() + &file_name_, lhs_arena, + &other->file_name_, rhs_arena ); }
diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index 8e49a7b..26e665b 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h
@@ -142,7 +142,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const SourceContext& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final;
diff --git a/src/google/protobuf/string_member_robber.h b/src/google/protobuf/string_member_robber.h new file mode 100644 index 0000000..a4c1051 --- /dev/null +++ b/src/google/protobuf/string_member_robber.h
@@ -0,0 +1,38 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_STRING_MEMBER_ROBBER_H__ +#define GOOGLE_PROTOBUF_STRING_MEMBER_ROBBER_H__ + +#include <string> +#include <type_traits> + + +#endif // GOOGLE_PROTOBUF_STRING_MEMBER_ROBBER_H__
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index a561d2b..766d99e 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc
@@ -75,6 +75,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse, key_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse, value_), 0, @@ -84,12 +85,14 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Struct, fields_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Value, _internal_metadata_), ~0u, // no _extensions_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Value, _oneof_case_[0]), ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, @@ -102,13 +105,14 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ListValue, values_), }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, 7, sizeof(PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse)}, - { 9, -1, sizeof(PROTOBUF_NAMESPACE_ID::Struct)}, - { 15, -1, sizeof(PROTOBUF_NAMESPACE_ID::Value)}, - { 27, -1, sizeof(PROTOBUF_NAMESPACE_ID::ListValue)}, + { 0, 8, -1, sizeof(PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse)}, + { 10, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Struct)}, + { 17, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Value)}, + { 30, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::ListValue)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -255,28 +259,29 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -353,13 +358,7 @@ total_size += Struct_FieldsEntry_DoNotUse::Funcs::ByteSizeLong(it->first, it->second); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Struct::_class_data_ = { @@ -368,8 +367,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Struct::GetClassData() const { return &_class_data_; } -void Struct::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Struct::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Struct *>(to)->MergeFrom( static_cast<const Struct &>(from)); } @@ -588,14 +587,16 @@ ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); _internal_set_null_value(static_cast<PROTOBUF_NAMESPACE_ID::NullValue>(val)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // double number_value = 2; case 2: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 17)) { _internal_set_number_value(::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<double>(ptr)); ptr += sizeof(double); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // string string_value = 3; case 3: @@ -604,49 +605,53 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Value.string_value")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // bool bool_value = 4; case 4: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 32)) { _internal_set_bool_value(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr)); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // .google.protobuf.Struct struct_value = 5; case 5: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { ptr = ctx->ParseMessage(_internal_mutable_struct_value(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // .google.protobuf.ListValue list_value = 6; case 6: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 50)) { ptr = ctx->ParseMessage(_internal_mutable_list_value(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -759,13 +764,7 @@ break; } } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Value::_class_data_ = { @@ -774,8 +773,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Value::GetClassData() const { return &_class_data_; } -void Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Value *>(to)->MergeFrom( static_cast<const Value &>(from)); } @@ -916,28 +915,29 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -978,13 +978,7 @@ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ListValue::_class_data_ = { @@ -993,8 +987,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ListValue::GetClassData() const { return &_class_data_; } -void ListValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void ListValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<ListValue *>(to)->MergeFrom( static_cast<const ListValue &>(from)); }
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index a9c3eba..2d364f9 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h
@@ -207,7 +207,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Struct& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -369,7 +369,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Value& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -619,7 +619,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const ListValue& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final;
diff --git a/src/google/protobuf/stubs/stl_util.h b/src/google/protobuf/stubs/stl_util.h index d01f9ec..3bc1dbf 100644 --- a/src/google/protobuf/stubs/stl_util.h +++ b/src/google/protobuf/stubs/stl_util.h
@@ -35,6 +35,8 @@ #include <google/protobuf/stubs/common.h> +#include <algorithm> + namespace google { namespace protobuf { @@ -48,6 +50,18 @@ s->resize(new_size); } +// As above, but we make sure to follow amortized growth in which we always +// increase the capacity by at least a constant factor >1. +inline void STLStringResizeUninitializedAmortized(std::string* s, + size_t new_size) { + const size_t cap = s->capacity(); + if (new_size > cap) { + // Make sure to always grow by at least a factor of 2x. + s->reserve(std::max(new_size, 2 * cap)); + } + STLStringResizeUninitialized(s, new_size); +} + // Return a mutable char* pointing to a string's internal buffer, // which may not be null-terminated. Writing through this pointer will // modify the string.
diff --git a/src/google/protobuf/test_messages_proto2.proto b/src/google/protobuf/test_messages_proto2.proto index 1d0c33f..d064fbb 100644 --- a/src/google/protobuf/test_messages_proto2.proto +++ b/src/google/protobuf/test_messages_proto2.proto
@@ -264,3 +264,13 @@ optional bool optional_bool = 1006; repeated int32 repeated_int32 = 1011; } + +message NullHypothesisProto2 { +} + +message EnumOnlyProto2 { + enum Bool { + kFalse = 0; + kTrue = 1; + } +}
diff --git a/src/google/protobuf/test_messages_proto3.proto b/src/google/protobuf/test_messages_proto3.proto index 4e409dc..278ee4f 100644 --- a/src/google/protobuf/test_messages_proto3.proto +++ b/src/google/protobuf/test_messages_proto3.proto
@@ -277,3 +277,13 @@ FOREIGN_BAR = 1; FOREIGN_BAZ = 2; } + +message NullHypothesisProto3 { +} + +message EnumOnlyProto3 { + enum Bool { + kFalse = 0; + kTrue = 1; + } +}
diff --git a/src/google/protobuf/test_util.h b/src/google/protobuf/test_util.h index 819f6d8..3ec3aa7 100644 --- a/src/google/protobuf/test_util.h +++ b/src/google/protobuf/test_util.h
@@ -1204,7 +1204,6 @@ "optional_import_message", }; for (int i = 0; i < GOOGLE_ARRAYSIZE(fields); i++) { - const Message& sub_message = reflection->GetMessage(*message, F(fields[i])); Message* released = reflection->ReleaseMessage(message, F(fields[i])); switch (expected_release_state) { case IS_NULL: @@ -1212,12 +1211,6 @@ break; case NOT_NULL: EXPECT_TRUE(released != nullptr); - if (Arena::InternalHelper<Message>::GetArenaForAllocation(message) == - nullptr) { - // released message must be same as sub_message if source message is - // not on arena. - EXPECT_EQ(&sub_message, released); - } break; case CAN_BE_NULL: break;
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index 449a5a6..13bf91c 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc
@@ -129,8 +129,8 @@ // =========================================================================== // Implementation of the parse information tree class. void TextFormat::ParseInfoTree::RecordLocation( - const FieldDescriptor* field, TextFormat::ParseLocation location) { - locations_[field].push_back(location); + const FieldDescriptor* field, TextFormat::ParseLocationRange range) { + locations_[field].push_back(range); } TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested( @@ -155,17 +155,18 @@ } } -TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation( +TextFormat::ParseLocationRange TextFormat::ParseInfoTree::GetLocationRange( const FieldDescriptor* field, int index) const { CheckFieldIndex(field, index); if (index == -1) { index = 0; } - const std::vector<TextFormat::ParseLocation>* locations = + const std::vector<TextFormat::ParseLocationRange>* locations = FindOrNull(locations_, field); - if (locations == nullptr || index >= static_cast<int64>(locations->size())) { - return TextFormat::ParseLocation(); + if (locations == nullptr || + index >= static_cast<int64_t>(locations->size())) { + return TextFormat::ParseLocationRange(); } return (*locations)[index]; @@ -179,7 +180,7 @@ } auto it = nested_.find(field); - if (it == nested_.end() || index >= static_cast<int64>(it->second.size())) { + if (it == nested_.end() || index >= static_cast<int64_t>(it->second.size())) { return nullptr; } @@ -458,7 +459,7 @@ } else { DO(ConsumeIdentifier(&field_name)); - int32 field_number; + int32_t field_number; if (allow_field_number_ && safe_strto32(field_name, &field_number)) { if (descriptor->IsExtensionNumber(field_number)) { field = finder_ @@ -610,8 +611,12 @@ // If a parse info tree exists, add the location for the parsed // field. if (parse_info_tree_ != nullptr) { + int end_line = tokenizer_.previous().line; + int end_column = tokenizer_.previous().end_column; + RecordLocation(parse_info_tree_, field, - ParseLocation(start_line, start_column)); + ParseLocationRange(ParseLocation(start_line, start_column), + ParseLocation(end_line, end_column))); } return true; @@ -716,28 +721,28 @@ switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { - int64 value; + int64_t value; DO(ConsumeSignedInteger(&value, kint32max)); - SET_FIELD(Int32, static_cast<int32>(value)); + SET_FIELD(Int32, static_cast<int32_t>(value)); break; } case FieldDescriptor::CPPTYPE_UINT32: { - uint64 value; + uint64_t value; DO(ConsumeUnsignedInteger(&value, kuint32max)); - SET_FIELD(UInt32, static_cast<uint32>(value)); + SET_FIELD(UInt32, static_cast<uint32_t>(value)); break; } case FieldDescriptor::CPPTYPE_INT64: { - int64 value; + int64_t value; DO(ConsumeSignedInteger(&value, kint64max)); SET_FIELD(Int64, value); break; } case FieldDescriptor::CPPTYPE_UINT64: { - uint64 value; + uint64_t value; DO(ConsumeUnsignedInteger(&value, kuint64max)); SET_FIELD(UInt64, value); break; @@ -766,7 +771,7 @@ case FieldDescriptor::CPPTYPE_BOOL: { if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { - uint64 value; + uint64_t value; DO(ConsumeUnsignedInteger(&value, 1)); SET_FIELD(Bool, value); } else { @@ -787,7 +792,7 @@ case FieldDescriptor::CPPTYPE_ENUM: { std::string value; - int64 int_value = kint64max; + int64_t int_value = kint64max; const EnumDescriptor* enum_type = field->enum_type(); const EnumValueDescriptor* enum_value = nullptr; @@ -996,9 +1001,9 @@ return true; } - // Consumes a uint64 and saves its value in the value parameter. + // Consumes a uint64_t and saves its value in the value parameter. // Returns false if the token is not of type INTEGER. - bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) { + bool ConsumeUnsignedInteger(uint64_t* value, uint64_t max_value) { if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { ReportError("Expected integer, got: " + tokenizer_.current().text); return false; @@ -1014,12 +1019,12 @@ return true; } - // Consumes an int64 and saves its value in the value parameter. + // Consumes an int64_t and saves its value in the value parameter. // Note that since the tokenizer does not support negative numbers, // we actually may consume an additional token (for the minus sign) in this // method. Returns false if the token is not an integer // (signed or otherwise). - bool ConsumeSignedInteger(int64* value, uint64 max_value) { + bool ConsumeSignedInteger(int64_t* value, uint64_t max_value) { bool negative = false; if (TryConsume("-")) { @@ -1029,18 +1034,18 @@ ++max_value; } - uint64 unsigned_value; + uint64_t unsigned_value; DO(ConsumeUnsignedInteger(&unsigned_value, max_value)); if (negative) { - if ((static_cast<uint64>(kint64max) + 1) == unsigned_value) { + if ((static_cast<uint64_t>(kint64max) + 1) == unsigned_value) { *value = kint64min; } else { - *value = -static_cast<int64>(unsigned_value); + *value = -static_cast<int64_t>(unsigned_value); } } else { - *value = static_cast<int64>(unsigned_value); + *value = static_cast<int64_t>(unsigned_value); } return true; @@ -1048,7 +1053,7 @@ // Consumes a double and saves its value in the value parameter. // Accepts decimal numbers only, rejects hex or oct numbers. - bool ConsumeUnsignedDecimalAsDouble(double* value, uint64 max_value) { + bool ConsumeUnsignedDecimalAsDouble(double* value, uint64_t max_value) { if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { ReportError("Expected integer, got: " + tokenizer_.current().text); return false; @@ -1060,7 +1065,7 @@ return false; } - uint64 uint64_value; + uint64_t uint64_value; if (io::Tokenizer::ParseInteger(text, max_value, &uint64_value)) { *value = static_cast<double>(uint64_value); } else { @@ -1352,7 +1357,7 @@ if (failed_) return; } - while (static_cast<int64>(size) > buffer_size_) { + while (static_cast<int64_t>(size) > buffer_size_) { // Data exceeds space in the buffer. Copy what we can and request a // new buffer. if (buffer_size_ > 0) { @@ -1509,8 +1514,9 @@ if (input.size() > INT_MAX) { error_collector->AddError( -1, 0, - StrCat("Input size too large: ", static_cast<int64>(input.size()), - " bytes", " > ", INT_MAX, " bytes.")); + StrCat( + "Input size too large: ", static_cast<int64_t>(input.size()), + " bytes", " > ", INT_MAX, " bytes.")); return false; } return true; @@ -1661,16 +1667,16 @@ std::string TextFormat::FieldValuePrinter::PrintBool(bool val) const { FORWARD_IMPL(PrintBool, val); } -std::string TextFormat::FieldValuePrinter::PrintInt32(int32 val) const { +std::string TextFormat::FieldValuePrinter::PrintInt32(int32_t val) const { FORWARD_IMPL(PrintInt32, val); } -std::string TextFormat::FieldValuePrinter::PrintUInt32(uint32 val) const { +std::string TextFormat::FieldValuePrinter::PrintUInt32(uint32_t val) const { FORWARD_IMPL(PrintUInt32, val); } -std::string TextFormat::FieldValuePrinter::PrintInt64(int64 val) const { +std::string TextFormat::FieldValuePrinter::PrintInt64(int64_t val) const { FORWARD_IMPL(PrintInt64, val); } -std::string TextFormat::FieldValuePrinter::PrintUInt64(uint64 val) const { +std::string TextFormat::FieldValuePrinter::PrintUInt64(uint64_t val) const { FORWARD_IMPL(PrintUInt64, val); } std::string TextFormat::FieldValuePrinter::PrintFloat(float val) const { @@ -1688,7 +1694,7 @@ return PrintString(val); } std::string TextFormat::FieldValuePrinter::PrintEnum( - int32 val, const std::string& name) const { + int32_t val, const std::string& name) const { FORWARD_IMPL(PrintEnum, val, name); } std::string TextFormat::FieldValuePrinter::PrintFieldName( @@ -1721,19 +1727,19 @@ } } void TextFormat::FastFieldValuePrinter::PrintInt32( - int32 val, BaseTextGenerator* generator) const { + int32_t val, BaseTextGenerator* generator) const { generator->PrintString(StrCat(val)); } void TextFormat::FastFieldValuePrinter::PrintUInt32( - uint32 val, BaseTextGenerator* generator) const { + uint32_t val, BaseTextGenerator* generator) const { generator->PrintString(StrCat(val)); } void TextFormat::FastFieldValuePrinter::PrintInt64( - int64 val, BaseTextGenerator* generator) const { + int64_t val, BaseTextGenerator* generator) const { generator->PrintString(StrCat(val)); } void TextFormat::FastFieldValuePrinter::PrintUInt64( - uint64 val, BaseTextGenerator* generator) const { + uint64_t val, BaseTextGenerator* generator) const { generator->PrintString(StrCat(val)); } void TextFormat::FastFieldValuePrinter::PrintFloat( @@ -1745,7 +1751,7 @@ generator->PrintString(!std::isnan(val) ? SimpleDtoa(val) : "nan"); } void TextFormat::FastFieldValuePrinter::PrintEnum( - int32 val, const std::string& name, BaseTextGenerator* generator) const { + int32_t val, const std::string& name, BaseTextGenerator* generator) const { generator->PrintString(name); } @@ -1820,19 +1826,19 @@ TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintBool(val)); } - void PrintInt32(int32 val, + void PrintInt32(int32_t val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintInt32(val)); } - void PrintUInt32(uint32 val, + void PrintUInt32(uint32_t val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintUInt32(val)); } - void PrintInt64(int64 val, + void PrintInt64(int64_t val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintInt64(val)); } - void PrintUInt64(uint64 val, + void PrintUInt64(uint64_t val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintUInt64(val)); } @@ -1852,7 +1858,7 @@ TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintBytes(val)); } - void PrintEnum(int32 val, const std::string& name, + void PrintEnum(int32_t val, const std::string& name, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintEnum(val, name)); } @@ -2155,23 +2161,23 @@ return first < second; } case FieldDescriptor::CPPTYPE_INT32: { - int32 first = reflection->GetInt32(*a, field_); - int32 second = reflection->GetInt32(*b, field_); + int32_t first = reflection->GetInt32(*a, field_); + int32_t second = reflection->GetInt32(*b, field_); return first < second; } case FieldDescriptor::CPPTYPE_INT64: { - int64 first = reflection->GetInt64(*a, field_); - int64 second = reflection->GetInt64(*b, field_); + int64_t first = reflection->GetInt64(*a, field_); + int64_t second = reflection->GetInt64(*b, field_); return first < second; } case FieldDescriptor::CPPTYPE_UINT32: { - uint32 first = reflection->GetUInt32(*a, field_); - uint32 second = reflection->GetUInt32(*b, field_); + uint32_t first = reflection->GetUInt32(*a, field_); + uint32_t second = reflection->GetUInt32(*b, field_); return first < second; } case FieldDescriptor::CPPTYPE_UINT64: { - uint64 first = reflection->GetUInt64(*a, field_); - uint64 second = reflection->GetUInt64(*b, field_); + uint64_t first = reflection->GetUInt64(*a, field_); + uint64_t second = reflection->GetUInt64(*b, field_); return first < second; } case FieldDescriptor::CPPTYPE_STRING: { @@ -2585,7 +2591,7 @@ // budget when we attempt to parse the data. UnknownFieldSet parsing is // recursive because of groups. io::CodedInputStream input_stream( - reinterpret_cast<const uint8*>(value.data()), value.size()); + reinterpret_cast<const uint8_t*>(value.data()), value.size()); input_stream.SetRecursionLimit(recursion_budget); UnknownFieldSet embedded_unknown_fields; if (!value.empty() && recursion_budget > 0 &&
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index ce4d1f4..4831de6 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h
@@ -126,17 +126,17 @@ FastFieldValuePrinter(); virtual ~FastFieldValuePrinter(); virtual void PrintBool(bool val, BaseTextGenerator* generator) const; - virtual void PrintInt32(int32 val, BaseTextGenerator* generator) const; - virtual void PrintUInt32(uint32 val, BaseTextGenerator* generator) const; - virtual void PrintInt64(int64 val, BaseTextGenerator* generator) const; - virtual void PrintUInt64(uint64 val, BaseTextGenerator* generator) const; + virtual void PrintInt32(int32_t val, BaseTextGenerator* generator) const; + virtual void PrintUInt32(uint32_t val, BaseTextGenerator* generator) const; + virtual void PrintInt64(int64_t val, BaseTextGenerator* generator) const; + virtual void PrintUInt64(uint64_t val, BaseTextGenerator* generator) const; virtual void PrintFloat(float val, BaseTextGenerator* generator) const; virtual void PrintDouble(double val, BaseTextGenerator* generator) const; virtual void PrintString(const std::string& val, BaseTextGenerator* generator) const; virtual void PrintBytes(const std::string& val, BaseTextGenerator* generator) const; - virtual void PrintEnum(int32 val, const std::string& name, + virtual void PrintEnum(int32_t val, const std::string& name, BaseTextGenerator* generator) const; virtual void PrintFieldName(const Message& message, int field_index, int field_count, const Reflection* reflection, @@ -171,15 +171,15 @@ FieldValuePrinter(); virtual ~FieldValuePrinter(); virtual std::string PrintBool(bool val) const; - virtual std::string PrintInt32(int32 val) const; - virtual std::string PrintUInt32(uint32 val) const; - virtual std::string PrintInt64(int64 val) const; - virtual std::string PrintUInt64(uint64 val) const; + virtual std::string PrintInt32(int32_t val) const; + virtual std::string PrintUInt32(uint32_t val) const; + virtual std::string PrintInt64(int64_t val) const; + virtual std::string PrintUInt64(uint64_t val) const; virtual std::string PrintFloat(float val) const; virtual std::string PrintDouble(double val) const; virtual std::string PrintString(const std::string& val) const; virtual std::string PrintBytes(const std::string& val) const; - virtual std::string PrintEnum(int32 val, const std::string& name) const; + virtual std::string PrintEnum(int32_t val, const std::string& name) const; virtual std::string PrintFieldName(const Message& message, const Reflection* reflection, const FieldDescriptor* field) const; @@ -341,7 +341,7 @@ // property of TextFormat::Printer. That is, from the printed message, we // cannot fully recover the original string field any more. void SetTruncateStringFieldLongerThan( - const int64 truncate_string_field_longer_than) { + const int64_t truncate_string_field_longer_than) { truncate_string_field_longer_than_ = truncate_string_field_longer_than; } @@ -431,7 +431,7 @@ bool hide_unknown_fields_; bool print_message_fields_in_index_order_; bool expand_any_; - int64 truncate_string_field_longer_than_; + int64_t truncate_string_field_longer_than_; std::unique_ptr<const FastFieldValuePrinter> default_field_value_printer_; typedef std::map<const FieldDescriptor*, @@ -488,6 +488,16 @@ : line(line_param), column(column_param) {} }; + // A range of locations in the parsed text, including `start` and excluding + // `end`. + struct ParseLocationRange { + ParseLocation start; + ParseLocation end; + ParseLocationRange() : start(), end() {} + ParseLocationRange(ParseLocation start_param, ParseLocation end_param) + : start(start_param), end(end_param) {} + }; + // Data structure which is populated with the locations of each field // value parsed from the text. class PROTOBUF_EXPORT ParseInfoTree { @@ -496,10 +506,18 @@ ParseInfoTree(const ParseInfoTree&) = delete; ParseInfoTree& operator=(const ParseInfoTree&) = delete; - // Returns the parse location for index-th value of the field in the parsed - // text. If none exists, returns a location with line = -1. Index should be - // -1 for not-repeated fields. - ParseLocation GetLocation(const FieldDescriptor* field, int index) const; + // Returns the parse location range for index-th value of the field in + // the parsed text. If none exists, returns a location with start and end + // line -1. Index should be -1 for not-repeated fields. + ParseLocationRange GetLocationRange(const FieldDescriptor* field, + int index) const; + + // Returns the starting parse location for index-th value of the field in + // the parsed text. If none exists, returns a location with line = -1. Index + // should be -1 for not-repeated fields. + ParseLocation GetLocation(const FieldDescriptor* field, int index) const { + return GetLocationRange(field, index).start; + } // Returns the parse info tree for the given field, which must be a message // type. The nested information tree is owned by the root tree and will be @@ -511,14 +529,14 @@ // Allow the text format parser to record information into the tree. friend class TextFormat; - // Records the starting location of a single value for a field. - void RecordLocation(const FieldDescriptor* field, ParseLocation location); + // Records the starting and ending locations of a single value for a field. + void RecordLocation(const FieldDescriptor* field, ParseLocationRange range); // Create and records a nested tree for a nested message field. ParseInfoTree* CreateNested(const FieldDescriptor* field); // Defines the map from the index-th field descriptor to its parse location. - typedef std::map<const FieldDescriptor*, std::vector<ParseLocation> > + typedef std::map<const FieldDescriptor*, std::vector<ParseLocationRange>> LocationMap; // Defines the map from the index-th field descriptor to the nested parse @@ -635,7 +653,7 @@ // helpers for ParserImpl to call methods of ParseInfoTree. static inline void RecordLocation(ParseInfoTree* info_tree, const FieldDescriptor* field, - ParseLocation location); + ParseLocationRange location); static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree, const FieldDescriptor* field); @@ -644,7 +662,7 @@ inline void TextFormat::RecordLocation(ParseInfoTree* info_tree, const FieldDescriptor* field, - ParseLocation location) { + ParseLocationRange location) { info_tree->RecordLocation(field, location); }
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index cedc928..f8848c4 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc
@@ -1407,12 +1407,18 @@ } void ExpectLocation(TextFormat::ParseInfoTree* tree, const Descriptor* d, - const std::string& field_name, int index, int line, - int column) { - TextFormat::ParseLocation location = + const std::string& field_name, int index, int start_line, + int start_column, int end_line, int end_column) { + TextFormat::ParseLocationRange range = + tree->GetLocationRange(d->FindFieldByName(field_name), index); + EXPECT_EQ(start_line, range.start.line); + EXPECT_EQ(start_column, range.start.column); + EXPECT_EQ(end_line, range.end.line); + EXPECT_EQ(end_column, range.end.column); + TextFormat::ParseLocation start_location = tree->GetLocation(d->FindFieldByName(field_name), index); - EXPECT_EQ(line, location.line); - EXPECT_EQ(column, location.column); + EXPECT_EQ(start_line, start_location.line); + EXPECT_EQ(start_column, start_location.column); } // An error collector which simply concatenates all its errors into a big @@ -1462,22 +1468,22 @@ ExpectSuccessAndTree(stringData, message.get(), &tree); // Verify that the tree has the correct positions. - ExpectLocation(&tree, d, "optional_int32", -1, 0, 0); - ExpectLocation(&tree, d, "optional_int64", -1, 1, 0); - ExpectLocation(&tree, d, "optional_double", -1, 2, 2); + ExpectLocation(&tree, d, "optional_int32", -1, 0, 0, 0, 17); + ExpectLocation(&tree, d, "optional_int64", -1, 1, 0, 1, 17); + ExpectLocation(&tree, d, "optional_double", -1, 2, 2, 2, 22); - ExpectLocation(&tree, d, "repeated_int32", 0, 3, 0); - ExpectLocation(&tree, d, "repeated_int32", 1, 4, 0); + ExpectLocation(&tree, d, "repeated_int32", 0, 3, 0, 3, 17); + ExpectLocation(&tree, d, "repeated_int32", 1, 4, 0, 4, 18); - ExpectLocation(&tree, d, "optional_nested_message", -1, 5, 0); - ExpectLocation(&tree, d, "repeated_nested_message", 0, 8, 0); - ExpectLocation(&tree, d, "repeated_nested_message", 1, 11, 0); + ExpectLocation(&tree, d, "optional_nested_message", -1, 5, 0, 7, 1); + ExpectLocation(&tree, d, "repeated_nested_message", 0, 8, 0, 10, 1); + ExpectLocation(&tree, d, "repeated_nested_message", 1, 11, 0, 13, 1); - // Check for fields not set. For an invalid field, the location returned - // should be -1, -1. - ExpectLocation(&tree, d, "repeated_int64", 0, -1, -1); - ExpectLocation(&tree, d, "repeated_int32", 6, -1, -1); - ExpectLocation(&tree, d, "some_unknown_field", -1, -1, -1); + // Check for fields not set. For an invalid field, the start and end locations + // returned should be -1, -1. + ExpectLocation(&tree, d, "repeated_int64", 0, -1, -1, -1, -1); + ExpectLocation(&tree, d, "repeated_int32", 6, -1, -1, -1, -1); + ExpectLocation(&tree, d, "some_unknown_field", -1, -1, -1, -1, -1); // Verify inside the nested message. const FieldDescriptor* nested_field = @@ -1485,15 +1491,18 @@ TextFormat::ParseInfoTree* nested_tree = tree.GetTreeForNested(nested_field, -1); - ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 6, 2); + ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 6, 2, 6, + 8); // Verify inside another nested message. nested_field = d->FindFieldByName("repeated_nested_message"); nested_tree = tree.GetTreeForNested(nested_field, 0); - ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 9, 2); + ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 9, 2, 9, + 8); nested_tree = tree.GetTreeForNested(nested_field, 1); - ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 12, 2); + ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 12, 2, 12, + 8); // Verify a NULL tree for an unknown nested field. TextFormat::ParseInfoTree* unknown_nested_tree =
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index c74a973..43954d9 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc
@@ -41,11 +41,12 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Timestamp, seconds_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Timestamp, nanos_), }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(PROTOBUF_NAMESPACE_ID::Timestamp)}, + { 0, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Timestamp)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -150,35 +151,37 @@ if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { seconds_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // int32 nanos = 2; case 2: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { nanos_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -218,25 +221,15 @@ // int64 seconds = 1; if (this->_internal_seconds() != 0) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->_internal_seconds()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_seconds()); } // int32 nanos = 2; if (this->_internal_nanos() != 0) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_nanos()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_nanos()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Timestamp::_class_data_ = { @@ -245,8 +238,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Timestamp::GetClassData() const { return &_class_data_; } -void Timestamp::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Timestamp::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Timestamp *>(to)->MergeFrom( static_cast<const Timestamp &>(from)); }
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index 8ea03e2..3efba58 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h
@@ -142,7 +142,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Timestamp& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final;
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index 1de2532..c892956 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc
@@ -113,6 +113,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Type, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Type, fields_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Type, oneofs_), @@ -124,6 +125,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Field, kind_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Field, cardinality_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Field, number_), @@ -139,6 +141,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Enum, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Enum, enumvalue_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Enum, options_), @@ -149,6 +152,7 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumValue, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumValue, number_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumValue, options_), @@ -157,15 +161,16 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Option, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Option, value_), }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(PROTOBUF_NAMESPACE_ID::Type)}, - { 11, -1, sizeof(PROTOBUF_NAMESPACE_ID::Field)}, - { 26, -1, sizeof(PROTOBUF_NAMESPACE_ID::Enum)}, - { 36, -1, sizeof(PROTOBUF_NAMESPACE_ID::EnumValue)}, - { 44, -1, sizeof(PROTOBUF_NAMESPACE_ID::Option)}, + { 0, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Type)}, + { 12, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Field)}, + { 28, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Enum)}, + { 39, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::EnumValue)}, + { 48, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Option)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -442,7 +447,8 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Type.name")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.Field fields = 2; case 2: @@ -454,7 +460,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated string oneofs = 3; case 3: @@ -468,7 +475,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.Option options = 4; case 4: @@ -480,14 +488,16 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // .google.protobuf.SourceContext source_context = 5; case 5: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 42)) { ptr = ctx->ParseMessage(_internal_mutable_source_context(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // .google.protobuf.Syntax syntax = 6; case 6: @@ -495,28 +505,29 @@ ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); _internal_set_syntax(static_cast<PROTOBUF_NAMESPACE_ID::Syntax>(val)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -635,13 +646,7 @@ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Type::_class_data_ = { @@ -650,8 +655,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Type::GetClassData() const { return &_class_data_; } -void Type::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Type::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Type *>(to)->MergeFrom( static_cast<const Type &>(from)); } @@ -691,14 +696,16 @@ void Type::InternalSwap(Type* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); fields_.InternalSwap(&other->fields_); oneofs_.InternalSwap(&other->oneofs_); options_.InternalSwap(&other->options_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(Type, syntax_) @@ -825,7 +832,8 @@ ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); _internal_set_kind(static_cast<PROTOBUF_NAMESPACE_ID::Field_Kind>(val)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // .google.protobuf.Field.Cardinality cardinality = 2; case 2: @@ -833,14 +841,16 @@ ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); _internal_set_cardinality(static_cast<PROTOBUF_NAMESPACE_ID::Field_Cardinality>(val)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // int32 number = 3; case 3: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) { number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // string name = 4; case 4: @@ -849,7 +859,8 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.name")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // string type_url = 6; case 6: @@ -858,21 +869,24 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.type_url")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // int32 oneof_index = 7; case 7: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 56)) { oneof_index_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // bool packed = 8; case 8: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 64)) { packed_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.Option options = 9; case 9: @@ -884,7 +898,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<74>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // string json_name = 10; case 10: @@ -893,7 +908,8 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.json_name")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // string default_value = 11; case 11: @@ -902,28 +918,29 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.default_value")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1078,16 +1095,12 @@ // int32 number = 3; if (this->_internal_number() != 0) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_number()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number()); } // int32 oneof_index = 7; if (this->_internal_oneof_index() != 0) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_oneof_index()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_oneof_index()); } // bool packed = 8; @@ -1095,13 +1108,7 @@ total_size += 1 + 1; } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Field::_class_data_ = { @@ -1110,8 +1117,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Field::GetClassData() const { return &_class_data_; } -void Field::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Field::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Field *>(to)->MergeFrom( static_cast<const Field &>(from)); } @@ -1167,27 +1174,29 @@ void Field::InternalSwap(Field* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); options_.InternalSwap(&other->options_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &type_url_, GetArenaForAllocation(), - &other->type_url_, other->GetArenaForAllocation() + &type_url_, lhs_arena, + &other->type_url_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &json_name_, GetArenaForAllocation(), - &other->json_name_, other->GetArenaForAllocation() + &json_name_, lhs_arena, + &other->json_name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &default_value_, GetArenaForAllocation(), - &other->default_value_, other->GetArenaForAllocation() + &default_value_, lhs_arena, + &other->default_value_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(Field, packed_) @@ -1311,7 +1320,8 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Enum.name")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.EnumValue enumvalue = 2; case 2: @@ -1323,7 +1333,8 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.Option options = 3; case 3: @@ -1335,14 +1346,16 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // .google.protobuf.SourceContext source_context = 4; case 4: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 34)) { ptr = ctx->ParseMessage(_internal_mutable_source_context(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // .google.protobuf.Syntax syntax = 5; case 5: @@ -1350,28 +1363,29 @@ ::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); _internal_set_syntax(static_cast<PROTOBUF_NAMESPACE_ID::Syntax>(val)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1472,13 +1486,7 @@ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Enum::_class_data_ = { @@ -1487,8 +1495,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Enum::GetClassData() const { return &_class_data_; } -void Enum::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Enum::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Enum *>(to)->MergeFrom( static_cast<const Enum &>(from)); } @@ -1527,13 +1535,15 @@ void Enum::InternalSwap(Enum* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); enumvalue_.InternalSwap(&other->enumvalue_); options_.InternalSwap(&other->options_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< PROTOBUF_FIELD_OFFSET(Enum, syntax_) @@ -1630,14 +1640,16 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.EnumValue.name")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // int32 number = 2; case 2: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // repeated .google.protobuf.Option options = 3; case 3: @@ -1649,28 +1661,29 @@ CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1736,18 +1749,10 @@ // int32 number = 2; if (this->_internal_number() != 0) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_number()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValue::_class_data_ = { @@ -1756,8 +1761,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValue::GetClassData() const { return &_class_data_; } -void EnumValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void EnumValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<EnumValue *>(to)->MergeFrom( static_cast<const EnumValue &>(from)); } @@ -1792,12 +1797,14 @@ void EnumValue::InternalSwap(EnumValue* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); options_.InternalSwap(&other->options_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); swap(number_, other->number_); } @@ -1905,35 +1912,37 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Option.name")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; // .google.protobuf.Any value = 2; case 2: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) { ptr = ctx->ParseMessage(_internal_mutable_value(), ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1991,13 +2000,7 @@ *value_); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Option::_class_data_ = { @@ -2006,8 +2009,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Option::GetClassData() const { return &_class_data_; } -void Option::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Option::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Option *>(to)->MergeFrom( static_cast<const Option &>(from)); } @@ -2041,11 +2044,13 @@ void Option::InternalSwap(Option* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, GetArenaForAllocation(), - &other->name_, other->GetArenaForAllocation() + &name_, lhs_arena, + &other->name_, rhs_arena ); swap(value_, other->value_); }
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index 1ec987c..ca45f0f 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h
@@ -255,7 +255,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Type& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -496,7 +496,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Field& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -861,7 +861,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Enum& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1076,7 +1076,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const EnumValue& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1251,7 +1251,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Option& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final;
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto index 0925165..7dda924 100644 --- a/src/google/protobuf/unittest.proto +++ b/src/google/protobuf/unittest.proto
@@ -972,6 +972,7 @@ optional int32 _field_name4 = 4; optional int32 FIELD_NAME5 = 5; optional int32 field_name6 = 6 [json_name = "@type"]; + optional int32 fieldname7 = 7; } message TestHugeFieldNumbers {
diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc index 1e81116..0d9bf62 100644 --- a/src/google/protobuf/unknown_field_set.cc +++ b/src/google/protobuf/unknown_field_set.cc
@@ -132,7 +132,7 @@ return sizeof(*this) + SpaceUsedExcludingSelf(); } -void UnknownFieldSet::AddVarint(int number, uint64 value) { +void UnknownFieldSet::AddVarint(int number, uint64_t value) { UnknownField field; field.number_ = number; field.SetType(UnknownField::TYPE_VARINT); @@ -140,7 +140,7 @@ fields_.push_back(field); } -void UnknownFieldSet::AddFixed32(int number, uint32 value) { +void UnknownFieldSet::AddFixed32(int number, uint32_t value) { UnknownField field; field.number_ = number; field.SetType(UnknownField::TYPE_FIXED32); @@ -148,7 +148,7 @@ fields_.push_back(field); } -void UnknownFieldSet::AddFixed64(int number, uint64 value) { +void UnknownFieldSet::AddFixed64(int number, uint64_t value) { UnknownField field; field.number_ = number; field.SetType(UnknownField::TYPE_FIXED64); @@ -269,8 +269,8 @@ } -uint8* UnknownField::InternalSerializeLengthDelimitedNoTag( - uint8* target, io::EpsCopyOutputStream* stream) const { +uint8_t* UnknownField::InternalSerializeLengthDelimitedNoTag( + uint8_t* target, io::EpsCopyOutputStream* stream) const { GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); const std::string& data = *data_.length_delimited_.string_value; target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target); @@ -285,22 +285,24 @@ explicit UnknownFieldParserHelper(UnknownFieldSet* unknown) : unknown_(unknown) {} - void AddVarint(uint32 num, uint64 value) { unknown_->AddVarint(num, value); } - void AddFixed64(uint32 num, uint64 value) { + void AddVarint(uint32_t num, uint64_t value) { + unknown_->AddVarint(num, value); + } + void AddFixed64(uint32_t num, uint64_t value) { unknown_->AddFixed64(num, value); } - const char* ParseLengthDelimited(uint32 num, const char* ptr, + const char* ParseLengthDelimited(uint32_t num, const char* ptr, ParseContext* ctx) { std::string* s = unknown_->AddLengthDelimited(num); int size = ReadSize(&ptr); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); return ctx->ReadString(ptr, size, s); } - const char* ParseGroup(uint32 num, const char* ptr, ParseContext* ctx) { + const char* ParseGroup(uint32_t num, const char* ptr, ParseContext* ctx) { UnknownFieldParserHelper child(unknown_->AddGroup(num)); return ctx->ParseGroup(&child, ptr, num * 8 + 3); } - void AddFixed32(uint32 num, uint32 value) { + void AddFixed32(uint32_t num, uint32_t value) { unknown_->AddFixed32(num, value); } @@ -318,7 +320,7 @@ return WireFormatParser(field_parser, ptr, ctx); } -const char* UnknownFieldParse(uint64 tag, UnknownFieldSet* unknown, +const char* UnknownFieldParse(uint64_t tag, UnknownFieldSet* unknown, const char* ptr, ParseContext* ctx) { UnknownFieldParserHelper field_parser(unknown); return FieldParser(tag, field_parser, ptr, ctx);
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h index ab3633d..c5ca06b 100644 --- a/src/google/protobuf/unknown_field_set.h +++ b/src/google/protobuf/unknown_field_set.h
@@ -136,9 +136,9 @@ // Adding fields --------------------------------------------------- - void AddVarint(int number, uint64 value); - void AddFixed32(int number, uint32 value); - void AddFixed64(int number, uint64 value); + void AddVarint(int number, uint64_t value); + void AddFixed32(int number, uint32_t value); + void AddFixed64(int number, uint64_t value); void AddLengthDelimited(int number, const std::string& value); std::string* AddLengthDelimited(int number); UnknownFieldSet* AddGroup(int number); @@ -209,10 +209,10 @@ namespace internal { -inline void WriteVarint(uint32 num, uint64 val, UnknownFieldSet* unknown) { +inline void WriteVarint(uint32_t num, uint64_t val, UnknownFieldSet* unknown) { unknown->AddVarint(num, val); } -inline void WriteLengthDelimited(uint32 num, StringPiece val, +inline void WriteLengthDelimited(uint32_t num, StringPiece val, UnknownFieldSet* unknown) { unknown->AddLengthDelimited(num)->assign(val.data(), val.size()); } @@ -221,7 +221,7 @@ const char* UnknownGroupParse(UnknownFieldSet* unknown, const char* ptr, ParseContext* ctx); PROTOBUF_EXPORT -const char* UnknownFieldParse(uint64 tag, UnknownFieldSet* unknown, +const char* UnknownFieldParse(uint64_t tag, UnknownFieldSet* unknown, const char* ptr, ParseContext* ctx); } // namespace internal @@ -246,15 +246,15 @@ // Accessors ------------------------------------------------------- // Each method works only for UnknownFields of the corresponding type. - inline uint64 varint() const; - inline uint32 fixed32() const; - inline uint64 fixed64() const; + inline uint64_t varint() const; + inline uint32_t fixed32() const; + inline uint64_t fixed64() const; inline const std::string& length_delimited() const; inline const UnknownFieldSet& group() const; - inline void set_varint(uint64 value); - inline void set_fixed32(uint32 value); - inline void set_fixed64(uint64 value); + inline void set_varint(uint64_t value); + inline void set_fixed32(uint32_t value); + inline void set_fixed64(uint64_t value); inline void set_length_delimited(const std::string& value); inline std::string* mutable_length_delimited(); inline UnknownFieldSet* mutable_group(); @@ -269,8 +269,8 @@ } inline size_t GetLengthDelimitedSize() const; - uint8* InternalSerializeLengthDelimitedNoTag( - uint8* target, io::EpsCopyOutputStream* stream) const; + uint8_t* InternalSerializeLengthDelimitedNoTag( + uint8_t* target, io::EpsCopyOutputStream* stream) const; // If this UnknownField contains a pointer, delete it. @@ -287,12 +287,12 @@ std::string* string_value; }; - uint32 number_; - uint32 type_; + uint32_t number_; + uint32_t type_; union { - uint64 varint_; - uint32 fixed32_; - uint64 fixed64_; + uint64_t varint_; + uint32_t fixed32_; + uint64_t fixed64_; mutable union LengthDelimited length_delimited_; UnknownFieldSet* group_; } data_; @@ -342,15 +342,15 @@ return static_cast<Type>(type_); } -inline uint64 UnknownField::varint() const { +inline uint64_t UnknownField::varint() const { assert(type() == TYPE_VARINT); return data_.varint_; } -inline uint32 UnknownField::fixed32() const { +inline uint32_t UnknownField::fixed32() const { assert(type() == TYPE_FIXED32); return data_.fixed32_; } -inline uint64 UnknownField::fixed64() const { +inline uint64_t UnknownField::fixed64() const { assert(type() == TYPE_FIXED64); return data_.fixed64_; } @@ -363,15 +363,15 @@ return *data_.group_; } -inline void UnknownField::set_varint(uint64 value) { +inline void UnknownField::set_varint(uint64_t value) { assert(type() == TYPE_VARINT); data_.varint_ = value; } -inline void UnknownField::set_fixed32(uint32 value) { +inline void UnknownField::set_fixed32(uint32_t value) { assert(type() == TYPE_FIXED32); data_.fixed32_ = value; } -inline void UnknownField::set_fixed64(uint64 value) { +inline void UnknownField::set_fixed64(uint64_t value) { assert(type() == TYPE_FIXED64); data_.fixed64_ = value; }
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index 88e01df..6d7f2f9 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc
@@ -204,6 +204,28 @@ } } +void AddSpecificIndex( + google::protobuf::util::MessageDifferencer::SpecificField* specific_field, + const Message& message, const FieldDescriptor* field, int index) { + if (field->is_map()) { + const Reflection* reflection = message.GetReflection(); + specific_field->map_entry1 = + &reflection->GetRepeatedMessage(message, field, index); + } + specific_field->index = index; +} + +void AddSpecificNewIndex( + google::protobuf::util::MessageDifferencer::SpecificField* specific_field, + const Message& message, const FieldDescriptor* field, int index) { + if (field->is_map()) { + const Reflection* reflection = message.GetReflection(); + specific_field->map_entry2 = + &reflection->GetRepeatedMessage(message, field, index); + } + specific_field->new_index = index; +} + MessageDifferencer::MapEntryKeyComparator::MapEntryKeyComparator( MessageDifferencer* message_differencer) : message_differencer_(message_differencer) {} @@ -759,7 +781,11 @@ for (int i = 0; i < count; ++i) { SpecificField specific_field; specific_field.field = field1; - specific_field.index = field1->is_repeated() ? i : -1; + if (field1->is_repeated()) { + AddSpecificIndex(&specific_field, message1, field1, i); + } else { + specific_field.index = -1; + } parent_fields->push_back(specific_field); reporter_->ReportDeleted(message1, message2, *parent_fields); @@ -799,8 +825,13 @@ for (int i = 0; i < count; ++i) { SpecificField specific_field; specific_field.field = field2; - specific_field.index = field2->is_repeated() ? i : -1; - specific_field.new_index = specific_field.index; + if (field2->is_repeated()) { + specific_field.index = i; + AddSpecificNewIndex(&specific_field, message2, field2, i); + } else { + specific_field.index = -1; + specific_field.new_index = -1; + } parent_fields->push_back(specific_field); reporter_->ReportAdded(message1, message2, *parent_fields); @@ -904,6 +935,10 @@ reflection2->GetRepeatedMessage(*message2, repeated_field, index2); SpecificField specific_field; specific_field.field = repeated_field; + if (repeated_field->is_map()) { + specific_field.map_entry1 = &m1; + specific_field.map_entry2 = &m2; + } specific_field.index = index1; specific_field.new_index = index2; current_parent_fields.push_back(specific_field); @@ -1116,7 +1151,7 @@ if (!simple_list && match_list1[i] == -1) { if (smart_list) { if (reporter_ == nullptr) return false; - specific_field.index = i; + AddSpecificIndex(&specific_field, message1, repeated_field, i); parent_fields->push_back(specific_field); reporter_->ReportDeleted(message1, message2, *parent_fields); parent_fields->pop_back(); @@ -1131,7 +1166,7 @@ GOOGLE_CHECK_LE(0, j); if (reporter_ == nullptr) return false; specific_field.index = j; - specific_field.new_index = j; + AddSpecificNewIndex(&specific_field, message2, repeated_field, j); parent_fields->push_back(specific_field); reporter_->ReportAdded(message1, message2, *parent_fields); parent_fields->pop_back(); @@ -1140,11 +1175,12 @@ match_list2[j] = -2; } } - specific_field.index = i; + AddSpecificIndex(&specific_field, message1, repeated_field, i); if (simple_list) { - specific_field.new_index = i; + AddSpecificNewIndex(&specific_field, message2, repeated_field, i); } else { - specific_field.new_index = match_list1[i]; + AddSpecificNewIndex(&specific_field, message2, repeated_field, + match_list1[i]); next_unmatched_index = match_list1[i] + 1; } @@ -1184,7 +1220,7 @@ if (reporter_ == NULL) continue; specific_field.index = i; - specific_field.new_index = i; + AddSpecificNewIndex(&specific_field, message2, repeated_field, i); parent_fields->push_back(specific_field); reporter_->ReportAdded(message1, message2, *parent_fields); parent_fields->pop_back(); @@ -1194,7 +1230,7 @@ if (!simple_list && match_list1[i] != -1) continue; if (simple_list && i < count2) continue; assert(reporter_ != NULL); - specific_field.index = i; + AddSpecificIndex(&specific_field, message1, repeated_field, i); parent_fields->push_back(specific_field); reporter_->ReportDeleted(message1, message2, *parent_fields); parent_fields->pop_back(); @@ -1239,8 +1275,8 @@ // Append currently compared field to the end of parent_fields. SpecificField specific_field; specific_field.field = field; - specific_field.index = index1; - specific_field.new_index = index2; + AddSpecificIndex(&specific_field, message1, field, index1); + AddSpecificNewIndex(&specific_field, message2, field, index2); parent_fields->push_back(specific_field); const bool compare_result = Compare(m1, m2, parent_fields); parent_fields->pop_back(); @@ -1377,7 +1413,7 @@ any.GetDescriptor()->file()->pool()->FindMessageTypeByName( full_type_name); if (desc == NULL) { - GOOGLE_DLOG(ERROR) << "Proto type '" << full_type_name << "' not found"; + GOOGLE_LOG(INFO) << "Proto type '" << full_type_name << "' not found"; return false; } @@ -1932,7 +1968,7 @@ } if (specific_field.field->is_map()) { - PrintMapKey(field_path, left_side, specific_field, i); + PrintMapKey(left_side, specific_field); continue; } } else { @@ -2038,66 +2074,21 @@ } void MessageDifferencer::StreamReporter::PrintMapKey( - const std::vector<SpecificField>& field_path, bool left_side, - const SpecificField& specific_field, size_t target_field_index) { + bool left_side, const SpecificField& specific_field) { if (message1_ == nullptr || message2_ == nullptr) { GOOGLE_LOG(WARNING) << "PrintPath cannot log map keys; " "use SetMessages to provide the messages " "being compared prior to any processing."; return; } - auto get_target_message = [=](const SpecificField& specific_field, - const Reflection* reflection, - const Message* message) { - return &( - specific_field.field->is_repeated() - ? reflection->GetRepeatedMessage( - *message, specific_field.field, - left_side ? specific_field.index : specific_field.new_index) - : reflection->GetMessage(*message, specific_field.field)); - }; - std::unique_ptr<Message> deserialized_msg; // used for protobuf.Any case - std::unique_ptr<DynamicMessageFactory> dynamic_message_factory; - const Message* found_message = left_side ? message1_ : message2_; - for (size_t j = 0; j <= target_field_index; - j++) { // iterate until we find target field - if (specific_field.field->is_repeated()) { - int index = left_side ? specific_field.index : specific_field.new_index; - if (index < 0) { - // Filtered messages fall in this case - GOOGLE_LOG(WARNING) << "Invalid index " << index << " for map.\n"; - found_message = nullptr; - break; - } - } - if (found_message->GetTypeName() == "google.protobuf.Any") { - if (!unpack_any_field_.UnpackAny(*found_message, &deserialized_msg)) { - GOOGLE_LOG(ERROR) << "Cannot print Any message map key due to " - "unpacking error\n"; - found_message = nullptr; - break; - } - - found_message = - get_target_message(field_path[j], deserialized_msg->GetReflection(), - deserialized_msg.get()); - - } else { - found_message = get_target_message( - field_path[j], found_message->GetReflection(), found_message); - } - } - + const Message* found_message = + left_side ? specific_field.map_entry1 : specific_field.map_entry2; std::string key_string = ""; if (found_message != nullptr) { // NB: the map key is always the first field const FieldDescriptor* fd = found_message->GetDescriptor()->field(0); - if (fd->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - key_string = found_message->GetReflection() - ->GetMessage(*found_message, fd) - .ShortDebugString(); - } else if (fd->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + if (fd->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { // Not using PrintFieldValueToString for strings to avoid extra // characters key_string = found_message->GetReflection()->GetString(
diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h index 4cdb817..1ee6a38 100644 --- a/src/google/protobuf/util/message_differencer.h +++ b/src/google/protobuf/util/message_differencer.h
@@ -194,6 +194,10 @@ // has not moved, "new_index" will have the same value as "index". int new_index = -1; + // If "field" is a map field, point to the map entry. + const Message* map_entry1 = nullptr; + const Message* map_entry2 = nullptr; + // For unknown fields, these are the pointers to the UnknownFieldSet // containing the unknown fields. In certain cases (e.g. proto1's // MessageSet, or nested groups of unknown fields), these may differ from @@ -695,12 +699,10 @@ // Just print a string void Print(const std::string& str); - // helper function for PrintPath that contains logic for printing maps - void PrintMapKey(const std::vector<SpecificField>& field_path, - bool left_side, const SpecificField& specific_field, - size_t target_field_index); - private: + // helper function for PrintPath that contains logic for printing maps + void PrintMapKey(bool left_side, const SpecificField& specific_field); + io::Printer* printer_; bool delete_printer_; bool report_modified_aggregates_;
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index c30b7ab..4b94f68 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc
@@ -70,7 +70,7 @@ // =================================================================== bool UnknownFieldSetFieldSkipper::SkipField(io::CodedInputStream* input, - uint32 tag) { + uint32_t tag) { return WireFormat::SkipField(input, tag, unknown_fields_); } @@ -82,7 +82,7 @@ unknown_fields_->AddVarint(field_number, value); } -bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, +bool WireFormat::SkipField(io::CodedInputStream* input, uint32_t tag, UnknownFieldSet* unknown_fields) { int number = WireFormatLite::GetTagFieldNumber(tag); // Field number 0 is illegal. @@ -90,19 +90,19 @@ switch (WireFormatLite::GetTagWireType(tag)) { case WireFormatLite::WIRETYPE_VARINT: { - uint64 value; + uint64_t value; if (!input->ReadVarint64(&value)) return false; if (unknown_fields != NULL) unknown_fields->AddVarint(number, value); return true; } case WireFormatLite::WIRETYPE_FIXED64: { - uint64 value; + uint64_t value; if (!input->ReadLittleEndian64(&value)) return false; if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value); return true; } case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { - uint32 length; + uint32_t length; if (!input->ReadVarint32(&length)) return false; if (unknown_fields == NULL) { if (!input->Skip(length)) return false; @@ -134,7 +134,7 @@ return false; } case WireFormatLite::WIRETYPE_FIXED32: { - uint32 value; + uint32_t value; if (!input->ReadLittleEndian32(&value)) return false; if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value); return true; @@ -148,7 +148,7 @@ bool WireFormat::SkipMessage(io::CodedInputStream* input, UnknownFieldSet* unknown_fields) { while (true) { - uint32 tag = input->ReadTag(); + uint32_t tag = input->ReadTag(); if (tag == 0) { // End of input. This is a valid place to end, so return true. return true; @@ -166,11 +166,11 @@ } bool WireFormat::ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input, - uint32 field_number, + uint32_t field_number, bool (*is_valid)(int), UnknownFieldSet* unknown_fields, RepeatedField<int>* values) { - uint32 length; + uint32_t length; if (!input->ReadVarint32(&length)) return false; io::CodedInputStream::Limit limit = input->PushLimit(length); while (input->BytesUntilLimit() > 0) { @@ -189,8 +189,8 @@ return true; } -uint8* WireFormat::InternalSerializeUnknownFieldsToArray( - const UnknownFieldSet& unknown_fields, uint8* target, +uint8_t* WireFormat::InternalSerializeUnknownFieldsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target, io::EpsCopyOutputStream* stream) { for (int i = 0; i < unknown_fields.field_count(); i++) { const UnknownField& field = unknown_fields.field(i); @@ -227,8 +227,8 @@ return target; } -uint8* WireFormat::InternalSerializeUnknownMessageSetItemsToArray( - const UnknownFieldSet& unknown_fields, uint8* target, +uint8_t* WireFormat::InternalSerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target, io::EpsCopyOutputStream* stream) { for (int i = 0; i < unknown_fields.field_count(); i++) { const UnknownField& field = unknown_fields.field(i); @@ -278,12 +278,12 @@ case UnknownField::TYPE_FIXED32: size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( field.number(), WireFormatLite::WIRETYPE_FIXED32)); - size += sizeof(int32); + size += sizeof(int32_t); break; case UnknownField::TYPE_FIXED64: size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( field.number(), WireFormatLite::WIRETYPE_FIXED64)); - size += sizeof(int64); + size += sizeof(int64_t); break; case UnknownField::TYPE_LENGTH_DELIMITED: size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( @@ -334,7 +334,7 @@ const Reflection* message_reflection = message->GetReflection(); while (true) { - uint32 tag = input->ReadTag(); + uint32_t tag = input->ReadTag(); if (tag == 0) { // End of input. This is a valid place to end, so return true. return true; @@ -380,15 +380,15 @@ } bool WireFormat::SkipMessageSetField(io::CodedInputStream* input, - uint32 field_number, + uint32_t field_number, UnknownFieldSet* unknown_fields) { - uint32 length; + uint32_t length; if (!input->ReadVarint32(&length)) return false; return input->ReadString(unknown_fields->AddLengthDelimited(field_number), length); } -bool WireFormat::ParseAndMergeMessageSetField(uint32 field_number, +bool WireFormat::ParseAndMergeMessageSetField(uint32_t field_number, const FieldDescriptor* field, Message* message, io::CodedInputStream* input) { @@ -415,7 +415,7 @@ } bool WireFormat::ParseAndMergeField( - uint32 tag, + uint32_t tag, const FieldDescriptor* field, // May be NULL for unknown Message* message, io::CodedInputStream* input) { const Reflection* message_reflection = message->GetReflection(); @@ -441,7 +441,7 @@ return SkipField(input, tag, message_reflection->MutableUnknownFields(message)); } else if (value_format == PACKED_FORMAT) { - uint32 length; + uint32_t length; if (!input->ReadVarint32(&length)) return false; io::CodedInputStream::Limit limit = input->PushLimit(length); @@ -459,17 +459,17 @@ break; \ } - HANDLE_PACKED_TYPE(INT32, int32, Int32) - HANDLE_PACKED_TYPE(INT64, int64, Int64) - HANDLE_PACKED_TYPE(SINT32, int32, Int32) - HANDLE_PACKED_TYPE(SINT64, int64, Int64) - HANDLE_PACKED_TYPE(UINT32, uint32, UInt32) - HANDLE_PACKED_TYPE(UINT64, uint64, UInt64) + HANDLE_PACKED_TYPE(INT32, int32_t, Int32) + HANDLE_PACKED_TYPE(INT64, int64_t, Int64) + HANDLE_PACKED_TYPE(SINT32, int32_t, Int32) + HANDLE_PACKED_TYPE(SINT64, int64_t, Int64) + HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32) + HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64) - HANDLE_PACKED_TYPE(FIXED32, uint32, UInt32) - HANDLE_PACKED_TYPE(FIXED64, uint64, UInt64) - HANDLE_PACKED_TYPE(SFIXED32, int32, Int32) - HANDLE_PACKED_TYPE(SFIXED64, int64, Int64) + HANDLE_PACKED_TYPE(FIXED32, uint32_t, UInt32) + HANDLE_PACKED_TYPE(FIXED64, uint64_t, UInt64) + HANDLE_PACKED_TYPE(SFIXED32, int32_t, Int32) + HANDLE_PACKED_TYPE(SFIXED64, int64_t, Int64) HANDLE_PACKED_TYPE(FLOAT, float, Float) HANDLE_PACKED_TYPE(DOUBLE, double, Double) @@ -494,7 +494,7 @@ } else { // The enum value is not one of the known values. Add it to the // UnknownFieldSet. - int64 sign_extended_value = static_cast<int64>(value); + int64_t sign_extended_value = static_cast<int64_t>(value); message_reflection->MutableUnknownFields(message)->AddVarint( WireFormatLite::GetTagFieldNumber(tag), sign_extended_value); } @@ -532,17 +532,17 @@ break; \ } - HANDLE_TYPE(INT32, int32, Int32) - HANDLE_TYPE(INT64, int64, Int64) - HANDLE_TYPE(SINT32, int32, Int32) - HANDLE_TYPE(SINT64, int64, Int64) - HANDLE_TYPE(UINT32, uint32, UInt32) - HANDLE_TYPE(UINT64, uint64, UInt64) + HANDLE_TYPE(INT32, int32_t, Int32) + HANDLE_TYPE(INT64, int64_t, Int64) + HANDLE_TYPE(SINT32, int32_t, Int32) + HANDLE_TYPE(SINT64, int64_t, Int64) + HANDLE_TYPE(UINT32, uint32_t, UInt32) + HANDLE_TYPE(UINT64, uint64_t, UInt64) - HANDLE_TYPE(FIXED32, uint32, UInt32) - HANDLE_TYPE(FIXED64, uint64, UInt64) - HANDLE_TYPE(SFIXED32, int32, Int32) - HANDLE_TYPE(SFIXED64, int64, Int64) + HANDLE_TYPE(FIXED32, uint32_t, UInt32) + HANDLE_TYPE(FIXED64, uint64_t, UInt64) + HANDLE_TYPE(SFIXED32, int32_t, Int32) + HANDLE_TYPE(SFIXED64, int64_t, Int64) HANDLE_TYPE(FLOAT, float, Float) HANDLE_TYPE(DOUBLE, double, Double) @@ -641,7 +641,7 @@ return ParseAndMergeMessageSetField(type_id, field, message, input); } - bool SkipField(uint32 tag, io::CodedInputStream* input) { + bool SkipField(uint32_t tag, io::CodedInputStream* input) { return WireFormat::SkipField(input, tag, NULL); } @@ -658,14 +658,14 @@ // Parse a MessageSetItem auto metadata = reflection->MutableInternalMetadata(msg); std::string payload; - uint32 type_id = 0; + uint32_t type_id = 0; bool payload_read = false; while (!ctx->Done(&ptr)) { // We use 64 bit tags in order to allow typeid's that span the whole // range of 32 bit numbers. - uint32 tag = static_cast<uint8>(*ptr++); + uint32_t tag = static_cast<uint8_t>(*ptr++); if (tag == WireFormatLite::kMessageSetTypeIdTag) { - uint64 tmp; + uint64_t tmp; ptr = ParseBigVarint(ptr, &tmp); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); type_id = tmp; @@ -701,7 +701,7 @@ continue; } else if (tag == WireFormatLite::kMessageSetMessageTag) { if (type_id == 0) { - int32 size = ReadSize(&ptr); + int32_t size = ReadSize(&ptr); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); ptr = ctx->ReadString(ptr, size, &payload); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); @@ -718,7 +718,7 @@ } } ptr = WireFormat::_InternalParseAndMergeField( - msg, ptr, ctx, static_cast<uint64>(type_id) * 8 + 2, reflection, + msg, ptr, ctx, static_cast<uint64_t>(type_id) * 8 + 2, reflection, field); type_id = 0; } @@ -740,7 +740,7 @@ const char* ParseMessageSet(const char* ptr, internal::ParseContext* ctx) { while (!ctx->Done(&ptr)) { - uint32 tag; + uint32_t tag; ptr = ReadTag(ptr, &tag); if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { @@ -786,7 +786,7 @@ return message_set.ParseMessageSet(ptr, ctx); } while (!ctx->Done(&ptr)) { - uint32 tag; + uint32_t tag; ptr = ReadTag(ptr, &tag); if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { @@ -815,7 +815,7 @@ } const char* WireFormat::_InternalParseAndMergeField( - Message* msg, const char* ptr, internal::ParseContext* ctx, uint64 tag, + Message* msg, const char* ptr, internal::ParseContext* ctx, uint64_t tag, const Reflection* reflection, const FieldDescriptor* field) { if (field == nullptr) { // unknown field set parser takes 64bit tags, because message set type ids @@ -836,17 +836,17 @@ return ptr; \ } - HANDLE_PACKED_TYPE(INT32, int32, Int32) - HANDLE_PACKED_TYPE(INT64, int64, Int64) - HANDLE_PACKED_TYPE(SINT32, int32, SInt32) - HANDLE_PACKED_TYPE(SINT64, int64, SInt64) - HANDLE_PACKED_TYPE(UINT32, uint32, UInt32) - HANDLE_PACKED_TYPE(UINT64, uint64, UInt64) + HANDLE_PACKED_TYPE(INT32, int32_t, Int32) + HANDLE_PACKED_TYPE(INT64, int64_t, Int64) + HANDLE_PACKED_TYPE(SINT32, int32_t, SInt32) + HANDLE_PACKED_TYPE(SINT64, int64_t, SInt64) + HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32) + HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64) - HANDLE_PACKED_TYPE(FIXED32, uint32, Fixed32) - HANDLE_PACKED_TYPE(FIXED64, uint64, Fixed64) - HANDLE_PACKED_TYPE(SFIXED32, int32, SFixed32) - HANDLE_PACKED_TYPE(SFIXED64, int64, SFixed64) + HANDLE_PACKED_TYPE(FIXED32, uint32_t, Fixed32) + HANDLE_PACKED_TYPE(FIXED64, uint64_t, Fixed64) + HANDLE_PACKED_TYPE(SFIXED32, int32_t, SFixed32) + HANDLE_PACKED_TYPE(SFIXED64, int64_t, SFixed64) HANDLE_PACKED_TYPE(FLOAT, float, Float) HANDLE_PACKED_TYPE(DOUBLE, double, Double) @@ -863,7 +863,7 @@ ptr = internal::PackedEnumParser(rep_enum, ptr, ctx); } else { return ctx->ReadPackedVarint( - ptr, [rep_enum, field, reflection, msg](uint64 val) { + ptr, [rep_enum, field, reflection, msg](uint64_t val) { if (field->enum_type()->FindValueByNumber(val) != nullptr) { rep_enum->Add(val); } else { @@ -906,14 +906,14 @@ return ptr; \ } - HANDLE_TYPE(BOOL, uint64, Bool) - HANDLE_TYPE(INT32, uint32, Int32) - HANDLE_TYPE(INT64, uint64, Int64) - HANDLE_TYPE(UINT32, uint32, UInt32) - HANDLE_TYPE(UINT64, uint64, UInt64) + HANDLE_TYPE(BOOL, uint64_t, Bool) + HANDLE_TYPE(INT32, uint32_t, Int32) + HANDLE_TYPE(INT64, uint64_t, Int64) + HANDLE_TYPE(UINT32, uint32_t, UInt32) + HANDLE_TYPE(UINT64, uint64_t, UInt64) case FieldDescriptor::TYPE_SINT32: { - int32 value = ReadVarintZigZag32(&ptr); + int32_t value = ReadVarintZigZag32(&ptr); if (ptr == nullptr) return nullptr; if (field->is_repeated()) { reflection->AddInt32(msg, field, value); @@ -923,7 +923,7 @@ return ptr; } case FieldDescriptor::TYPE_SINT64: { - int64 value = ReadVarintZigZag64(&ptr); + int64_t value = ReadVarintZigZag64(&ptr); if (ptr == nullptr) return nullptr; if (field->is_repeated()) { reflection->AddInt64(msg, field, value); @@ -946,10 +946,10 @@ return ptr; \ } - HANDLE_TYPE(FIXED32, uint32, UInt32) - HANDLE_TYPE(FIXED64, uint64, UInt64) - HANDLE_TYPE(SFIXED32, int32, Int32) - HANDLE_TYPE(SFIXED64, int64, Int64) + HANDLE_TYPE(FIXED32, uint32_t, UInt32) + HANDLE_TYPE(FIXED64, uint64_t, UInt64) + HANDLE_TYPE(SFIXED32, int32_t, Int32) + HANDLE_TYPE(SFIXED64, int64_t, Int64) HANDLE_TYPE(FLOAT, float, Float) HANDLE_TYPE(DOUBLE, double, Double) @@ -957,7 +957,7 @@ #undef HANDLE_TYPE case FieldDescriptor::TYPE_ENUM: { - uint32 value; + uint32_t value; ptr = VarintParse(ptr, &value); if (ptr == nullptr) return nullptr; if (field->is_repeated()) { @@ -1030,8 +1030,8 @@ // =================================================================== -uint8* WireFormat::_InternalSerialize(const Message& message, uint8* target, - io::EpsCopyOutputStream* stream) { +uint8_t* WireFormat::_InternalSerialize(const Message& message, uint8_t* target, + io::EpsCopyOutputStream* stream) { const Descriptor* descriptor = message.GetDescriptor(); const Reflection* message_reflection = message.GetReflection(); @@ -1059,9 +1059,9 @@ } } -uint8* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field, - const MapKey& value, uint8* target, - io::EpsCopyOutputStream* stream) { +uint8_t* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field, + const MapKey& value, uint8_t* target, + io::EpsCopyOutputStream* stream) { target = stream->EnsureSpace(target); switch (field->type()) { case FieldDescriptor::TYPE_DOUBLE: @@ -1096,9 +1096,9 @@ return target; } -static uint8* SerializeMapValueRefWithCachedSizes( - const FieldDescriptor* field, const MapValueConstRef& value, uint8* target, - io::EpsCopyOutputStream* stream) { +static uint8_t* SerializeMapValueRefWithCachedSizes( + const FieldDescriptor* field, const MapValueConstRef& value, + uint8_t* target, io::EpsCopyOutputStream* stream) { target = stream->EnsureSpace(target); switch (field->type()) { #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ @@ -1180,11 +1180,11 @@ }; }; -static uint8* InternalSerializeMapEntry(const FieldDescriptor* field, - const MapKey& key, - const MapValueConstRef& value, - uint8* target, - io::EpsCopyOutputStream* stream) { +static uint8_t* InternalSerializeMapEntry(const FieldDescriptor* field, + const MapKey& key, + const MapValueConstRef& value, + uint8_t* target, + io::EpsCopyOutputStream* stream) { const FieldDescriptor* key_field = field->message_type()->field(0); const FieldDescriptor* value_field = field->message_type()->field(1); @@ -1201,9 +1201,10 @@ return target; } -uint8* WireFormat::InternalSerializeField(const FieldDescriptor* field, - const Message& message, uint8* target, - io::EpsCopyOutputStream* stream) { +uint8_t* WireFormat::InternalSerializeField(const FieldDescriptor* field, + const Message& message, + uint8_t* target, + io::EpsCopyOutputStream* stream) { const Reflection* message_reflection = message.GetReflection(); if (field->is_extension() && @@ -1286,12 +1287,12 @@ break; \ } - HANDLE_PRIMITIVE_TYPE(INT32, int32, Int32, Int32) - HANDLE_PRIMITIVE_TYPE(INT64, int64, Int64, Int64) - HANDLE_PRIMITIVE_TYPE(SINT32, int32, SInt32, Int32) - HANDLE_PRIMITIVE_TYPE(SINT64, int64, SInt64, Int64) - HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32) - HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64) + HANDLE_PRIMITIVE_TYPE(INT32, int32_t, Int32, Int32) + HANDLE_PRIMITIVE_TYPE(INT64, int64_t, Int64, Int64) + HANDLE_PRIMITIVE_TYPE(SINT32, int32_t, SInt32, Int32) + HANDLE_PRIMITIVE_TYPE(SINT64, int64_t, SInt64, Int64) + HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t, UInt32, UInt32) + HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t, UInt64, UInt64) HANDLE_PRIMITIVE_TYPE(ENUM, int, Enum, Enum) #undef HANDLE_PRIMITIVE_TYPE @@ -1303,10 +1304,10 @@ break; \ } - HANDLE_PRIMITIVE_TYPE(FIXED32, uint32, Fixed32, UInt32) - HANDLE_PRIMITIVE_TYPE(FIXED64, uint64, Fixed64, UInt64) - HANDLE_PRIMITIVE_TYPE(SFIXED32, int32, SFixed32, Int32) - HANDLE_PRIMITIVE_TYPE(SFIXED64, int64, SFixed64, Int64) + HANDLE_PRIMITIVE_TYPE(FIXED32, uint32_t, Fixed32, UInt32) + HANDLE_PRIMITIVE_TYPE(FIXED64, uint64_t, Fixed64, UInt64) + HANDLE_PRIMITIVE_TYPE(SFIXED32, int32_t, SFixed32, Int32) + HANDLE_PRIMITIVE_TYPE(SFIXED64, int64_t, SFixed64, Int64) HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float) HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double) @@ -1334,17 +1335,17 @@ break; \ } - HANDLE_PRIMITIVE_TYPE(INT32, int32, Int32, Int32) - HANDLE_PRIMITIVE_TYPE(INT64, int64, Int64, Int64) - HANDLE_PRIMITIVE_TYPE(SINT32, int32, SInt32, Int32) - HANDLE_PRIMITIVE_TYPE(SINT64, int64, SInt64, Int64) - HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32) - HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64) + HANDLE_PRIMITIVE_TYPE(INT32, int32_t, Int32, Int32) + HANDLE_PRIMITIVE_TYPE(INT64, int64_t, Int64, Int64) + HANDLE_PRIMITIVE_TYPE(SINT32, int32_t, SInt32, Int32) + HANDLE_PRIMITIVE_TYPE(SINT64, int64_t, SInt64, Int64) + HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t, UInt32, UInt32) + HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t, UInt64, UInt64) - HANDLE_PRIMITIVE_TYPE(FIXED32, uint32, Fixed32, UInt32) - HANDLE_PRIMITIVE_TYPE(FIXED64, uint64, Fixed64, UInt64) - HANDLE_PRIMITIVE_TYPE(SFIXED32, int32, SFixed32, Int32) - HANDLE_PRIMITIVE_TYPE(SFIXED64, int64, SFixed64, Int64) + HANDLE_PRIMITIVE_TYPE(FIXED32, uint32_t, Fixed32, UInt32) + HANDLE_PRIMITIVE_TYPE(FIXED64, uint64_t, Fixed64, UInt64) + HANDLE_PRIMITIVE_TYPE(SFIXED32, int32_t, SFixed32, Int32) + HANDLE_PRIMITIVE_TYPE(SFIXED64, int64_t, SFixed64, Int64) HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float) HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double) @@ -1418,8 +1419,8 @@ return target; } -uint8* WireFormat::InternalSerializeMessageSetItem( - const FieldDescriptor* field, const Message& message, uint8* target, +uint8_t* WireFormat::InternalSerializeMessageSetItem( + const FieldDescriptor* field, const Message& message, uint8_t* target, io::EpsCopyOutputStream* stream) { const Reflection* message_reflection = message.GetReflection();
diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h index d4ffbdf..7ca217a 100644 --- a/src/google/protobuf/wire_format.h +++ b/src/google/protobuf/wire_format.h
@@ -132,8 +132,8 @@ "originally expected. Perhaps it was modified by another thread " "during serialization?"; } - static uint8* _InternalSerialize(const Message& message, uint8* target, - io::EpsCopyOutputStream* stream); + static uint8_t* _InternalSerialize(const Message& message, uint8_t* target, + io::EpsCopyOutputStream* stream); // Implements Message::ByteSize() via reflection. WARNING: The result // of this method is *not* cached anywhere. However, all embedded messages @@ -148,7 +148,7 @@ // Skips a field value of the given WireType. The input should start // positioned immediately after the tag. If unknown_fields is non-NULL, // the contents of the field will be added to it. - static bool SkipField(io::CodedInputStream* input, uint32 tag, + static bool SkipField(io::CodedInputStream* input, uint32_t tag, UnknownFieldSet* unknown_fields); // Reads and ignores a message from the input. If unknown_fields is @@ -160,7 +160,7 @@ // for which is_valid(value) returns false are appended to // unknown_fields_stream. static bool ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input, - uint32 field_number, + uint32_t field_number, bool (*is_valid)(int), UnknownFieldSet* unknown_fields, RepeatedField<int>* values); @@ -176,16 +176,16 @@ // ComputeUnknownFieldsSize(unknown_fields). // // Returns a pointer past the last written byte. - static uint8* SerializeUnknownFieldsToArray( - const UnknownFieldSet& unknown_fields, uint8* target) { + static uint8_t* SerializeUnknownFieldsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target) { io::EpsCopyOutputStream stream( target, static_cast<int>(ComputeUnknownFieldsSize(unknown_fields)), io::CodedOutputStream::IsDefaultSerializationDeterministic()); return InternalSerializeUnknownFieldsToArray(unknown_fields, target, &stream); } - static uint8* InternalSerializeUnknownFieldsToArray( - const UnknownFieldSet& unknown_fields, uint8* target, + static uint8_t* InternalSerializeUnknownFieldsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target, io::EpsCopyOutputStream* stream); // Same thing except for messages that have the message_set_wire_format @@ -200,10 +200,10 @@ // ComputeUnknownMessageSetItemsSize(unknown_fields). // // Returns a pointer past the last written byte. - static uint8* SerializeUnknownMessageSetItemsToArray( - const UnknownFieldSet& unknown_fields, uint8* target); - static uint8* InternalSerializeUnknownMessageSetItemsToArray( - const UnknownFieldSet& unknown_fields, uint8* target, + static uint8_t* SerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target); + static uint8_t* InternalSerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target, io::EpsCopyOutputStream* stream); // Compute the size of the UnknownFieldSet on the wire. @@ -219,12 +219,12 @@ // // This is different from MakeTag(field->number(), field->type()) in the // case of packed repeated fields. - static uint32 MakeTag(const FieldDescriptor* field); + static uint32_t MakeTag(const FieldDescriptor* field); // Parse a single field. The input should start out positioned immediately // after the tag. static bool ParseAndMergeField( - uint32 tag, + uint32_t tag, const FieldDescriptor* field, // May be NULL for unknown Message* message, io::CodedInputStream* input); @@ -235,9 +235,9 @@ output->SetCur(InternalSerializeField(field, message, output->Cur(), output->EpsCopy())); } - static uint8* InternalSerializeField( + static uint8_t* InternalSerializeField( const FieldDescriptor* field, // Cannot be NULL - const Message& message, uint8* target, io::EpsCopyOutputStream* stream); + const Message& message, uint8_t* target, io::EpsCopyOutputStream* stream); // Compute size of a single field. If the field is a message type, this // will call ByteSize() for the embedded message, insuring that it caches @@ -255,8 +255,8 @@ output->SetCur(InternalSerializeMessageSetItem( field, message, output->Cur(), output->EpsCopy())); } - static uint8* InternalSerializeMessageSetItem( - const FieldDescriptor* field, const Message& message, uint8* target, + static uint8_t* InternalSerializeMessageSetItem( + const FieldDescriptor* field, const Message& message, uint8_t* target, io::EpsCopyOutputStream* stream); static size_t MessageSetItemByteSize(const FieldDescriptor* field, const Message& message); @@ -287,18 +287,18 @@ struct MessageSetParser; // Skip a MessageSet field. static bool SkipMessageSetField(io::CodedInputStream* input, - uint32 field_number, + uint32_t field_number, UnknownFieldSet* unknown_fields); // Parse a MessageSet field. - static bool ParseAndMergeMessageSetField(uint32 field_number, + static bool ParseAndMergeMessageSetField(uint32_t field_number, const FieldDescriptor* field, Message* message, io::CodedInputStream* input); // Parses the value from the wire that belongs to tag. static const char* _InternalParseAndMergeField(Message* msg, const char* ptr, internal::ParseContext* ctx, - uint64 tag, + uint64_t tag, const Reflection* reflection, const FieldDescriptor* field); @@ -313,7 +313,7 @@ ~UnknownFieldSetFieldSkipper() override {} // implements FieldSkipper ----------------------------------------- - bool SkipField(io::CodedInputStream* input, uint32 tag) override; + bool SkipField(io::CodedInputStream* input, uint32_t tag) override; bool SkipMessage(io::CodedInputStream* input) override; void SkipUnknownEnum(int field_number, int value) override; @@ -340,7 +340,7 @@ static_cast<WireFormatLite::FieldType>(implicit_cast<int>(type))); } -inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) { +inline uint32_t WireFormat::MakeTag(const FieldDescriptor* field) { return WireFormatLite::MakeTag(field->number(), WireTypeForField(field)); } @@ -382,8 +382,8 @@ } -inline uint8* InternalSerializeUnknownMessageSetItemsToArray( - const UnknownFieldSet& unknown_fields, uint8* target, +inline uint8_t* InternalSerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, uint8_t* target, io::EpsCopyOutputStream* stream) { return WireFormat::InternalSerializeUnknownMessageSetItemsToArray( unknown_fields, target, stream); @@ -402,9 +402,9 @@ size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field, const MapKey& value); -uint8* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field, - const MapKey& value, uint8* target, - io::EpsCopyOutputStream* stream); +uint8_t* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field, + const MapKey& value, uint8_t* target, + io::EpsCopyOutputStream* stream); } // namespace internal } // namespace protobuf } // namespace google
diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc index 7af7bf4..f61f4e5 100644 --- a/src/google/protobuf/wire_format_lite.cc +++ b/src/google/protobuf/wire_format_lite.cc
@@ -120,22 +120,22 @@ WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64 }; -bool WireFormatLite::SkipField(io::CodedInputStream* input, uint32 tag) { +bool WireFormatLite::SkipField(io::CodedInputStream* input, uint32_t tag) { // Field number 0 is illegal. if (WireFormatLite::GetTagFieldNumber(tag) == 0) return false; switch (WireFormatLite::GetTagWireType(tag)) { case WireFormatLite::WIRETYPE_VARINT: { - uint64 value; + uint64_t value; if (!input->ReadVarint64(&value)) return false; return true; } case WireFormatLite::WIRETYPE_FIXED64: { - uint64 value; + uint64_t value; if (!input->ReadLittleEndian64(&value)) return false; return true; } case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { - uint32 length; + uint32_t length; if (!input->ReadVarint32(&length)) return false; if (!input->Skip(length)) return false; return true; @@ -156,7 +156,7 @@ return false; } case WireFormatLite::WIRETYPE_FIXED32: { - uint32 value; + uint32_t value; if (!input->ReadLittleEndian32(&value)) return false; return true; } @@ -166,27 +166,27 @@ } } -bool WireFormatLite::SkipField(io::CodedInputStream* input, uint32 tag, +bool WireFormatLite::SkipField(io::CodedInputStream* input, uint32_t tag, io::CodedOutputStream* output) { // Field number 0 is illegal. if (WireFormatLite::GetTagFieldNumber(tag) == 0) return false; switch (WireFormatLite::GetTagWireType(tag)) { case WireFormatLite::WIRETYPE_VARINT: { - uint64 value; + uint64_t value; if (!input->ReadVarint64(&value)) return false; output->WriteVarint32(tag); output->WriteVarint64(value); return true; } case WireFormatLite::WIRETYPE_FIXED64: { - uint64 value; + uint64_t value; if (!input->ReadLittleEndian64(&value)) return false; output->WriteVarint32(tag); output->WriteLittleEndian64(value); return true; } case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { - uint32 length; + uint32_t length; if (!input->ReadVarint32(&length)) return false; output->WriteVarint32(tag); output->WriteVarint32(length); @@ -213,7 +213,7 @@ return false; } case WireFormatLite::WIRETYPE_FIXED32: { - uint32 value; + uint32_t value; if (!input->ReadLittleEndian32(&value)) return false; output->WriteVarint32(tag); output->WriteLittleEndian32(value); @@ -227,7 +227,7 @@ bool WireFormatLite::SkipMessage(io::CodedInputStream* input) { while (true) { - uint32 tag = input->ReadTag(); + uint32_t tag = input->ReadTag(); if (tag == 0) { // End of input. This is a valid place to end, so return true. return true; @@ -247,7 +247,7 @@ bool WireFormatLite::SkipMessage(io::CodedInputStream* input, io::CodedOutputStream* output) { while (true) { - uint32 tag = input->ReadTag(); + uint32_t tag = input->ReadTag(); if (tag == 0) { // End of input. This is a valid place to end, so return true. return true; @@ -265,7 +265,7 @@ } } -bool FieldSkipper::SkipField(io::CodedInputStream* input, uint32 tag) { +bool FieldSkipper::SkipField(io::CodedInputStream* input, uint32_t tag) { return WireFormatLite::SkipField(input, tag); } @@ -278,7 +278,7 @@ } bool CodedOutputStreamFieldSkipper::SkipField(io::CodedInputStream* input, - uint32 tag) { + uint32_t tag) { return WireFormatLite::SkipField(input, tag, unknown_fields_); } @@ -295,7 +295,7 @@ bool WireFormatLite::ReadPackedEnumPreserveUnknowns( io::CodedInputStream* input, int field_number, bool (*is_valid)(int), io::CodedOutputStream* unknown_fields_stream, RepeatedField<int>* values) { - uint32 length; + uint32_t length; if (!input->ReadVarint32(&length)) return false; io::CodedInputStream::Limit limit = input->PushLimit(length); while (input->BytesUntilLimit() > 0) { @@ -306,8 +306,8 @@ if (is_valid == NULL || is_valid(value)) { values->Add(value); } else { - uint32 tag = WireFormatLite::MakeTag(field_number, - WireFormatLite::WIRETYPE_VARINT); + uint32_t tag = WireFormatLite::MakeTag(field_number, + WireFormatLite::WIRETYPE_VARINT); unknown_fields_stream->WriteVarint32(tag); unknown_fields_stream->WriteVarint32(value); } @@ -319,31 +319,31 @@ #if !defined(PROTOBUF_LITTLE_ENDIAN) namespace { -void EncodeFixedSizeValue(float v, uint8* dest) { +void EncodeFixedSizeValue(float v, uint8_t* dest) { WireFormatLite::WriteFloatNoTagToArray(v, dest); } -void EncodeFixedSizeValue(double v, uint8* dest) { +void EncodeFixedSizeValue(double v, uint8_t* dest) { WireFormatLite::WriteDoubleNoTagToArray(v, dest); } -void EncodeFixedSizeValue(uint32 v, uint8* dest) { +void EncodeFixedSizeValue(uint32_t v, uint8_t* dest) { WireFormatLite::WriteFixed32NoTagToArray(v, dest); } -void EncodeFixedSizeValue(uint64 v, uint8* dest) { +void EncodeFixedSizeValue(uint64_t v, uint8_t* dest) { WireFormatLite::WriteFixed64NoTagToArray(v, dest); } -void EncodeFixedSizeValue(int32 v, uint8* dest) { +void EncodeFixedSizeValue(int32_t v, uint8_t* dest) { WireFormatLite::WriteSFixed32NoTagToArray(v, dest); } -void EncodeFixedSizeValue(int64 v, uint8* dest) { +void EncodeFixedSizeValue(int64_t v, uint8_t* dest) { WireFormatLite::WriteSFixed64NoTagToArray(v, dest); } -void EncodeFixedSizeValue(bool v, uint8* dest) { +void EncodeFixedSizeValue(bool v, uint8_t* dest) { WireFormatLite::WriteBoolNoTagToArray(v, dest); } } // anonymous namespace @@ -356,10 +356,10 @@ output->WriteRaw(reinterpret_cast<const char*>(a), n * sizeof(a[0])); #else const int kAtATime = 128; - uint8 buf[sizeof(CType) * kAtATime]; + uint8_t buf[sizeof(CType) * kAtATime]; for (int i = 0; i < n; i += kAtATime) { int to_do = std::min(kAtATime, n - i); - uint8* ptr = buf; + uint8_t* ptr = buf; for (int j = 0; j < to_do; j++) { EncodeFixedSizeValue(a[i + j], ptr); ptr += sizeof(a[0]); @@ -379,24 +379,24 @@ WriteArray<double>(a, n, output); } -void WireFormatLite::WriteFixed32Array(const uint32* a, int n, +void WireFormatLite::WriteFixed32Array(const uint32_t* a, int n, io::CodedOutputStream* output) { - WriteArray<uint32>(a, n, output); + WriteArray<uint32_t>(a, n, output); } -void WireFormatLite::WriteFixed64Array(const uint64* a, int n, +void WireFormatLite::WriteFixed64Array(const uint64_t* a, int n, io::CodedOutputStream* output) { - WriteArray<uint64>(a, n, output); + WriteArray<uint64_t>(a, n, output); } -void WireFormatLite::WriteSFixed32Array(const int32* a, int n, +void WireFormatLite::WriteSFixed32Array(const int32_t* a, int n, io::CodedOutputStream* output) { - WriteArray<int32>(a, n, output); + WriteArray<int32_t>(a, n, output); } -void WireFormatLite::WriteSFixed64Array(const int64* a, int n, +void WireFormatLite::WriteSFixed64Array(const int64_t* a, int n, io::CodedOutputStream* output) { - WriteArray<int64>(a, n, output); + WriteArray<int64_t>(a, n, output); } void WireFormatLite::WriteBoolArray(const bool* a, int n, @@ -404,52 +404,52 @@ WriteArray<bool>(a, n, output); } -void WireFormatLite::WriteInt32(int field_number, int32 value, +void WireFormatLite::WriteInt32(int field_number, int32_t value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_VARINT, output); WriteInt32NoTag(value, output); } -void WireFormatLite::WriteInt64(int field_number, int64 value, +void WireFormatLite::WriteInt64(int field_number, int64_t value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_VARINT, output); WriteInt64NoTag(value, output); } -void WireFormatLite::WriteUInt32(int field_number, uint32 value, +void WireFormatLite::WriteUInt32(int field_number, uint32_t value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_VARINT, output); WriteUInt32NoTag(value, output); } -void WireFormatLite::WriteUInt64(int field_number, uint64 value, +void WireFormatLite::WriteUInt64(int field_number, uint64_t value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_VARINT, output); WriteUInt64NoTag(value, output); } -void WireFormatLite::WriteSInt32(int field_number, int32 value, +void WireFormatLite::WriteSInt32(int field_number, int32_t value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_VARINT, output); WriteSInt32NoTag(value, output); } -void WireFormatLite::WriteSInt64(int field_number, int64 value, +void WireFormatLite::WriteSInt64(int field_number, int64_t value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_VARINT, output); WriteSInt64NoTag(value, output); } -void WireFormatLite::WriteFixed32(int field_number, uint32 value, +void WireFormatLite::WriteFixed32(int field_number, uint32_t value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_FIXED32, output); WriteFixed32NoTag(value, output); } -void WireFormatLite::WriteFixed64(int field_number, uint64 value, +void WireFormatLite::WriteFixed64(int field_number, uint64_t value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_FIXED64, output); WriteFixed64NoTag(value, output); } -void WireFormatLite::WriteSFixed32(int field_number, int32 value, +void WireFormatLite::WriteSFixed32(int field_number, int32_t value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_FIXED32, output); WriteSFixed32NoTag(value, output); } -void WireFormatLite::WriteSFixed64(int field_number, int64 value, +void WireFormatLite::WriteSFixed64(int field_number, int64_t value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_FIXED64, output); WriteSFixed64NoTag(value, output); @@ -551,7 +551,7 @@ io::CodedInputStream* input, std::string* value); inline static bool ReadBytesToString(io::CodedInputStream* input, std::string* value) { - uint32 length; + uint32_t length; return input->ReadVarint32(&length) && input->ReadString(value, length); } @@ -614,10 +614,10 @@ "Cannot SignExtended unsigned types"); static_assert(!(SignExtended && ZigZag), "Cannot SignExtended and ZigZag on the same type"); - uint32 sum = n; - uint32 msb_sum = 0; + uint32_t sum = n; + uint32_t msb_sum = 0; for (int i = 0; i < n; i++) { - uint32 x = data[i]; + uint32_t x = data[i]; if (ZigZag) { x = WireFormatLite::ZigZagEncode32(x); } else if (SignExtended) { @@ -642,16 +642,16 @@ // is_unsigned<T> => !ZigZag static_assert(!ZigZag || !std::is_unsigned<T>::value, "Cannot ZigZag encode unsigned types"); - uint64 sum = n; + uint64_t sum = n; for (int i = 0; i < n; i++) { - uint64 x = data[i]; + uint64_t x = data[i]; if (ZigZag) { x = WireFormatLite::ZigZagEncode64(x); } // First step is a binary search, we can't branch in sse so we use the // result of the compare to adjust sum and appropriately. This code is // written to make clang recognize the vectorization. - uint64 tmp = x >= (static_cast<uint64>(1) << 35) ? -1 : 0; + uint64_t tmp = x >= (static_cast<uint64_t>(1) << 35) ? -1 : 0; sum += 5 & tmp; x >>= 35 & tmp; if (x > 0x7F) sum++; @@ -667,15 +667,15 @@ // varint size routine for each element is faster. // Hence we enable it only for clang #if defined(__SSE__) && defined(__clang__) -size_t WireFormatLite::Int32Size(const RepeatedField<int32>& value) { +size_t WireFormatLite::Int32Size(const RepeatedField<int32_t>& value) { return VarintSize<false, true>(value.data(), value.size()); } -size_t WireFormatLite::UInt32Size(const RepeatedField<uint32>& value) { +size_t WireFormatLite::UInt32Size(const RepeatedField<uint32_t>& value) { return VarintSize<false, false>(value.data(), value.size()); } -size_t WireFormatLite::SInt32Size(const RepeatedField<int32>& value) { +size_t WireFormatLite::SInt32Size(const RepeatedField<int32_t>& value) { return VarintSize<true, false>(value.data(), value.size()); } @@ -686,7 +686,7 @@ #else // !(defined(__SSE4_1__) && defined(__clang__)) -size_t WireFormatLite::Int32Size(const RepeatedField<int32>& value) { +size_t WireFormatLite::Int32Size(const RepeatedField<int32_t>& value) { size_t out = 0; const int n = value.size(); for (int i = 0; i < n; i++) { @@ -695,7 +695,7 @@ return out; } -size_t WireFormatLite::UInt32Size(const RepeatedField<uint32>& value) { +size_t WireFormatLite::UInt32Size(const RepeatedField<uint32_t>& value) { size_t out = 0; const int n = value.size(); for (int i = 0; i < n; i++) { @@ -704,7 +704,7 @@ return out; } -size_t WireFormatLite::SInt32Size(const RepeatedField<int32>& value) { +size_t WireFormatLite::SInt32Size(const RepeatedField<int32_t>& value) { size_t out = 0; const int n = value.size(); for (int i = 0; i < n; i++) { @@ -730,21 +730,21 @@ // enable this. #define USE_SSE_FOR_64_BIT_INTEGER_ARRAYS 0 #if USE_SSE_FOR_64_BIT_INTEGER_ARRAYS -size_t WireFormatLite::Int64Size(const RepeatedField<int64>& value) { +size_t WireFormatLite::Int64Size(const RepeatedField<int64_t>& value) { return VarintSize64<false>(value.data(), value.size()); } -size_t WireFormatLite::UInt64Size(const RepeatedField<uint64>& value) { +size_t WireFormatLite::UInt64Size(const RepeatedField<uint64_t>& value) { return VarintSize64<false>(value.data(), value.size()); } -size_t WireFormatLite::SInt64Size(const RepeatedField<int64>& value) { +size_t WireFormatLite::SInt64Size(const RepeatedField<int64_t>& value) { return VarintSize64<true>(value.data(), value.size()); } #else -size_t WireFormatLite::Int64Size(const RepeatedField<int64>& value) { +size_t WireFormatLite::Int64Size(const RepeatedField<int64_t>& value) { size_t out = 0; const int n = value.size(); for (int i = 0; i < n; i++) { @@ -753,7 +753,7 @@ return out; } -size_t WireFormatLite::UInt64Size(const RepeatedField<uint64>& value) { +size_t WireFormatLite::UInt64Size(const RepeatedField<uint64_t>& value) { size_t out = 0; const int n = value.size(); for (int i = 0; i < n; i++) { @@ -762,7 +762,7 @@ return out; } -size_t WireFormatLite::SInt64Size(const RepeatedField<int64>& value) { +size_t WireFormatLite::SInt64Size(const RepeatedField<int64_t>& value) { size_t out = 0; const int n = value.size(); for (int i = 0; i < n; i++) {
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h index c1abaf1..83668e9 100644 --- a/src/google/protobuf/wire_format_lite.h +++ b/src/google/protobuf/wire_format_lite.h
@@ -157,16 +157,16 @@ // Number of bits in a tag which identify the wire type. static constexpr int kTagTypeBits = 3; // Mask for those bits. - static constexpr uint32 kTagTypeMask = (1 << kTagTypeBits) - 1; + static constexpr uint32_t kTagTypeMask = (1 << kTagTypeBits) - 1; // Helper functions for encoding and decoding tags. (Inlined below and in // _inl.h) // // This is different from MakeTag(field->number(), field->type()) in the // case of packed repeated fields. - constexpr static uint32 MakeTag(int field_number, WireType type); - static WireType GetTagWireType(uint32 tag); - static int GetTagFieldNumber(uint32 tag); + constexpr static uint32_t MakeTag(int field_number, WireType type); + static WireType GetTagWireType(uint32_t tag); + static int GetTagFieldNumber(uint32_t tag); // Compute the byte size of a tag. For groups, this includes both the start // and end tags. @@ -177,12 +177,12 @@ // positioned immediately after the tag. Skipped values are simply // discarded, not recorded anywhere. See WireFormat::SkipField() for a // version that records to an UnknownFieldSet. - static bool SkipField(io::CodedInputStream* input, uint32 tag); + static bool SkipField(io::CodedInputStream* input, uint32_t tag); // Skips a field value with the given tag. The input should start // positioned immediately after the tag. Skipped values are recorded to a // CodedOutputStream. - static bool SkipField(io::CodedInputStream* input, uint32 tag, + static bool SkipField(io::CodedInputStream* input, uint32_t tag, io::CodedOutputStream* output); // Reads and ignores a message from the input. Skipped values are simply @@ -200,7 +200,7 @@ // as a switch case or a template input. WireFormatLite::MakeTag() is more // type-safe, though, so prefer it if possible. #define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \ - static_cast<uint32>((static_cast<uint32>(FIELD_NUMBER) << 3) | (TYPE)) + static_cast<uint32_t>((static_cast<uint32_t>(FIELD_NUMBER) << 3) | (TYPE)) // These are the tags for the old MessageSet format, which was defined as: // message MessageSet { @@ -227,10 +227,10 @@ // Helper functions for converting between floats/doubles and IEEE-754 // uint32s/uint64s so that they can be written. (Assumes your platform // uses IEEE-754 floats.) - static uint32 EncodeFloat(float value); - static float DecodeFloat(uint32 value); - static uint64 EncodeDouble(double value); - static double DecodeDouble(uint64 value); + static uint32_t EncodeFloat(float value); + static float DecodeFloat(uint32_t value); + static uint64_t EncodeDouble(double value); + static double DecodeDouble(uint64_t value); // Helper functions for mapping signed integers to unsigned integers in // such a way that numbers with small magnitudes will encode to smaller @@ -238,10 +238,10 @@ // number and varint-encode it, it will always take 10 bytes, defeating // the purpose of varint. So, for the "sint32" and "sint64" field types, // we ZigZag-encode the values. - static uint32 ZigZagEncode32(int32 n); - static int32 ZigZagDecode32(uint32 n); - static uint64 ZigZagEncode64(int64 n); - static int64 ZigZagDecode64(uint64 n); + static uint32_t ZigZagEncode32(int32_t n); + static int32_t ZigZagDecode32(uint32_t n); + static uint64_t ZigZagEncode64(int64_t n); + static int64_t ZigZagDecode64(uint64_t n); // ================================================================= // Methods for reading/writing individual field. @@ -261,13 +261,13 @@ // protocol compiler. template <typename CType, enum FieldType DeclaredType> PROTOBUF_NDEBUG_INLINE static bool ReadRepeatedPrimitive( - int tag_size, uint32 tag, io::CodedInputStream* input, + int tag_size, uint32_t tag, io::CodedInputStream* input, RepeatedField<CType>* value); // Identical to ReadRepeatedPrimitive, except will not inline the // implementation. template <typename CType, enum FieldType DeclaredType> - static bool ReadRepeatedPrimitiveNoInline(int tag_size, uint32 tag, + static bool ReadRepeatedPrimitiveNoInline(int tag_size, uint32_t tag, io::CodedInputStream* input, RepeatedField<CType>* value); @@ -277,8 +277,8 @@ // This is only implemented for the types with fixed wire size, e.g. // float, double, and the (s)fixed* types. template <typename CType, enum FieldType DeclaredType> - PROTOBUF_NDEBUG_INLINE static const uint8* ReadPrimitiveFromArray( - const uint8* buffer, CType* value); + PROTOBUF_NDEBUG_INLINE static const uint8_t* ReadPrimitiveFromArray( + const uint8_t* buffer, CType* value); // Reads a primitive packed field. // @@ -350,25 +350,25 @@ // Write fields, without tags. PROTOBUF_NDEBUG_INLINE static void WriteInt32NoTag( - int32 value, io::CodedOutputStream* output); + int32_t value, io::CodedOutputStream* output); PROTOBUF_NDEBUG_INLINE static void WriteInt64NoTag( - int64 value, io::CodedOutputStream* output); + int64_t value, io::CodedOutputStream* output); PROTOBUF_NDEBUG_INLINE static void WriteUInt32NoTag( - uint32 value, io::CodedOutputStream* output); + uint32_t value, io::CodedOutputStream* output); PROTOBUF_NDEBUG_INLINE static void WriteUInt64NoTag( - uint64 value, io::CodedOutputStream* output); + uint64_t value, io::CodedOutputStream* output); PROTOBUF_NDEBUG_INLINE static void WriteSInt32NoTag( - int32 value, io::CodedOutputStream* output); + int32_t value, io::CodedOutputStream* output); PROTOBUF_NDEBUG_INLINE static void WriteSInt64NoTag( - int64 value, io::CodedOutputStream* output); + int64_t value, io::CodedOutputStream* output); PROTOBUF_NDEBUG_INLINE static void WriteFixed32NoTag( - uint32 value, io::CodedOutputStream* output); + uint32_t value, io::CodedOutputStream* output); PROTOBUF_NDEBUG_INLINE static void WriteFixed64NoTag( - uint64 value, io::CodedOutputStream* output); + uint64_t value, io::CodedOutputStream* output); PROTOBUF_NDEBUG_INLINE static void WriteSFixed32NoTag( - int32 value, io::CodedOutputStream* output); + int32_t value, io::CodedOutputStream* output); PROTOBUF_NDEBUG_INLINE static void WriteSFixed64NoTag( - int64 value, io::CodedOutputStream* output); + int64_t value, io::CodedOutputStream* output); PROTOBUF_NDEBUG_INLINE static void WriteFloatNoTag( float value, io::CodedOutputStream* output); PROTOBUF_NDEBUG_INLINE static void WriteDoubleNoTag( @@ -383,37 +383,37 @@ io::CodedOutputStream* output); static void WriteDoubleArray(const double* a, int n, io::CodedOutputStream* output); - static void WriteFixed32Array(const uint32* a, int n, + static void WriteFixed32Array(const uint32_t* a, int n, io::CodedOutputStream* output); - static void WriteFixed64Array(const uint64* a, int n, + static void WriteFixed64Array(const uint64_t* a, int n, io::CodedOutputStream* output); - static void WriteSFixed32Array(const int32* a, int n, + static void WriteSFixed32Array(const int32_t* a, int n, io::CodedOutputStream* output); - static void WriteSFixed64Array(const int64* a, int n, + static void WriteSFixed64Array(const int64_t* a, int n, io::CodedOutputStream* output); static void WriteBoolArray(const bool* a, int n, io::CodedOutputStream* output); // Write fields, including tags. - static void WriteInt32(int field_number, int32 value, + static void WriteInt32(int field_number, int32_t value, io::CodedOutputStream* output); - static void WriteInt64(int field_number, int64 value, + static void WriteInt64(int field_number, int64_t value, io::CodedOutputStream* output); - static void WriteUInt32(int field_number, uint32 value, + static void WriteUInt32(int field_number, uint32_t value, io::CodedOutputStream* output); - static void WriteUInt64(int field_number, uint64 value, + static void WriteUInt64(int field_number, uint64_t value, io::CodedOutputStream* output); - static void WriteSInt32(int field_number, int32 value, + static void WriteSInt32(int field_number, int32_t value, io::CodedOutputStream* output); - static void WriteSInt64(int field_number, int64 value, + static void WriteSInt64(int field_number, int64_t value, io::CodedOutputStream* output); - static void WriteFixed32(int field_number, uint32 value, + static void WriteFixed32(int field_number, uint32_t value, io::CodedOutputStream* output); - static void WriteFixed64(int field_number, uint64 value, + static void WriteFixed64(int field_number, uint64_t value, io::CodedOutputStream* output); - static void WriteSFixed32(int field_number, int32 value, + static void WriteSFixed32(int field_number, int32_t value, io::CodedOutputStream* output); - static void WriteSFixed64(int field_number, int64 value, + static void WriteSFixed64(int field_number, int64_t value, io::CodedOutputStream* output); static void WriteFloat(int field_number, float value, io::CodedOutputStream* output); @@ -459,161 +459,161 @@ io::CodedOutputStream* output); // Like above, but use only *ToArray methods of CodedOutputStream. - PROTOBUF_NDEBUG_INLINE static uint8* WriteTagToArray(int field_number, - WireType type, - uint8* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteTagToArray(int field_number, + WireType type, + uint8_t* target); // Write fields, without tags. - PROTOBUF_NDEBUG_INLINE static uint8* WriteInt32NoTagToArray(int32 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteInt64NoTagToArray(int64 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteUInt32NoTagToArray(uint32 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteUInt64NoTagToArray(uint64 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSInt32NoTagToArray(int32 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSInt64NoTagToArray(int64 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFixed32NoTagToArray(uint32 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFixed64NoTagToArray(uint64 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSFixed32NoTagToArray(int32 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSFixed64NoTagToArray(int64 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFloatNoTagToArray(float value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteDoubleNoTagToArray(double value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteBoolNoTagToArray(bool value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteEnumNoTagToArray(int value, - uint8* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32NoTagToArray( + int32_t value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64NoTagToArray( + int64_t value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32NoTagToArray( + uint32_t value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64NoTagToArray( + uint64_t value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32NoTagToArray( + int32_t value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64NoTagToArray( + int64_t value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32NoTagToArray( + uint32_t value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64NoTagToArray( + uint64_t value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32NoTagToArray( + int32_t value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64NoTagToArray( + int64_t value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatNoTagToArray( + float value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleNoTagToArray( + double value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolNoTagToArray(bool value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumNoTagToArray(int value, + uint8_t* target); // Write fields, without tags. These require that value.size() > 0. template <typename T> - PROTOBUF_NDEBUG_INLINE static uint8* WritePrimitiveNoTagToArray( - const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*), - uint8* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WritePrimitiveNoTagToArray( + const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*), + uint8_t* target); template <typename T> - PROTOBUF_NDEBUG_INLINE static uint8* WriteFixedNoTagToArray( - const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*), - uint8* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixedNoTagToArray( + const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*), + uint8_t* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteInt32NoTagToArray( - const RepeatedField<int32>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteInt64NoTagToArray( - const RepeatedField<int64>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteUInt32NoTagToArray( - const RepeatedField<uint32>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteUInt64NoTagToArray( - const RepeatedField<uint64>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSInt32NoTagToArray( - const RepeatedField<int32>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSInt64NoTagToArray( - const RepeatedField<int64>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFixed32NoTagToArray( - const RepeatedField<uint32>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFixed64NoTagToArray( - const RepeatedField<uint64>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSFixed32NoTagToArray( - const RepeatedField<int32>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSFixed64NoTagToArray( - const RepeatedField<int64>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFloatNoTagToArray( - const RepeatedField<float>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteDoubleNoTagToArray( - const RepeatedField<double>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteBoolNoTagToArray( - const RepeatedField<bool>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteEnumNoTagToArray( - const RepeatedField<int>& value, uint8* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32NoTagToArray( + const RepeatedField<int32_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64NoTagToArray( + const RepeatedField<int64_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32NoTagToArray( + const RepeatedField<uint32_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64NoTagToArray( + const RepeatedField<uint64_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32NoTagToArray( + const RepeatedField<int32_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64NoTagToArray( + const RepeatedField<int64_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32NoTagToArray( + const RepeatedField<uint32_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64NoTagToArray( + const RepeatedField<uint64_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32NoTagToArray( + const RepeatedField<int32_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64NoTagToArray( + const RepeatedField<int64_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatNoTagToArray( + const RepeatedField<float>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleNoTagToArray( + const RepeatedField<double>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolNoTagToArray( + const RepeatedField<bool>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumNoTagToArray( + const RepeatedField<int>& value, uint8_t* output); // Write fields, including tags. - PROTOBUF_NDEBUG_INLINE static uint8* WriteInt32ToArray(int field_number, - int32 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteInt64ToArray(int field_number, - int64 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteUInt32ToArray(int field_number, - uint32 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteUInt64ToArray(int field_number, - uint64 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSInt32ToArray(int field_number, - int32 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSInt64ToArray(int field_number, - int64 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFixed32ToArray(int field_number, - uint32 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFixed64ToArray(int field_number, - uint64 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSFixed32ToArray(int field_number, - int32 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSFixed64ToArray(int field_number, - int64 value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFloatToArray(int field_number, - float value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteDoubleToArray(int field_number, - double value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteBoolToArray(int field_number, - bool value, - uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteEnumToArray(int field_number, - int value, - uint8* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32ToArray(int field_number, + int32_t value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64ToArray(int field_number, + int64_t value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32ToArray(int field_number, + uint32_t value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64ToArray(int field_number, + uint64_t value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32ToArray(int field_number, + int32_t value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64ToArray(int field_number, + int64_t value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32ToArray(int field_number, + uint32_t value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64ToArray(int field_number, + uint64_t value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32ToArray(int field_number, + int32_t value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64ToArray(int field_number, + int64_t value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatToArray(int field_number, + float value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleToArray(int field_number, + double value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolToArray(int field_number, + bool value, + uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumToArray(int field_number, + int value, + uint8_t* target); template <typename T> - PROTOBUF_NDEBUG_INLINE static uint8* WritePrimitiveToArray( + PROTOBUF_NDEBUG_INLINE static uint8_t* WritePrimitiveToArray( int field_number, const RepeatedField<T>& value, - uint8* (*Writer)(int, T, uint8*), uint8* target); + uint8_t* (*Writer)(int, T, uint8_t*), uint8_t* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteInt32ToArray( - int field_number, const RepeatedField<int32>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteInt64ToArray( - int field_number, const RepeatedField<int64>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteUInt32ToArray( - int field_number, const RepeatedField<uint32>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteUInt64ToArray( - int field_number, const RepeatedField<uint64>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSInt32ToArray( - int field_number, const RepeatedField<int32>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSInt64ToArray( - int field_number, const RepeatedField<int64>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFixed32ToArray( - int field_number, const RepeatedField<uint32>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFixed64ToArray( - int field_number, const RepeatedField<uint64>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSFixed32ToArray( - int field_number, const RepeatedField<int32>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteSFixed64ToArray( - int field_number, const RepeatedField<int64>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteFloatToArray( - int field_number, const RepeatedField<float>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteDoubleToArray( - int field_number, const RepeatedField<double>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteBoolToArray( - int field_number, const RepeatedField<bool>& value, uint8* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteEnumToArray( - int field_number, const RepeatedField<int>& value, uint8* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32ToArray( + int field_number, const RepeatedField<int32_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64ToArray( + int field_number, const RepeatedField<int64_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32ToArray( + int field_number, const RepeatedField<uint32_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64ToArray( + int field_number, const RepeatedField<uint64_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32ToArray( + int field_number, const RepeatedField<int32_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64ToArray( + int field_number, const RepeatedField<int64_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32ToArray( + int field_number, const RepeatedField<uint32_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64ToArray( + int field_number, const RepeatedField<uint64_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32ToArray( + int field_number, const RepeatedField<int32_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64ToArray( + int field_number, const RepeatedField<int64_t>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatToArray( + int field_number, const RepeatedField<float>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleToArray( + int field_number, const RepeatedField<double>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolToArray( + int field_number, const RepeatedField<bool>& value, uint8_t* output); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumToArray( + int field_number, const RepeatedField<int>& value, uint8_t* output); - PROTOBUF_NDEBUG_INLINE static uint8* WriteStringToArray( - int field_number, const std::string& value, uint8* target); - PROTOBUF_NDEBUG_INLINE static uint8* WriteBytesToArray( - int field_number, const std::string& value, uint8* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteStringToArray( + int field_number, const std::string& value, uint8_t* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBytesToArray( + int field_number, const std::string& value, uint8_t* target); // Whether to serialize deterministically (e.g., map keys are // sorted) is a property of a CodedOutputStream, and in the process @@ -621,43 +621,43 @@ // have a CodedOutputStream available, so they get an additional parameter // telling them whether to serialize deterministically. template <typename MessageType> - PROTOBUF_NDEBUG_INLINE static uint8* InternalWriteGroup( - int field_number, const MessageType& value, uint8* target, + PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteGroup( + int field_number, const MessageType& value, uint8_t* target, io::EpsCopyOutputStream* stream); template <typename MessageType> - PROTOBUF_NDEBUG_INLINE static uint8* InternalWriteMessage( - int field_number, const MessageType& value, uint8* target, + PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteMessage( + int field_number, const MessageType& value, uint8_t* target, io::EpsCopyOutputStream* stream); // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The // pointer must point at an instance of MessageType, *not* a subclass (or // the subclass must not override SerializeWithCachedSizes()). template <typename MessageType> - PROTOBUF_NDEBUG_INLINE static uint8* InternalWriteGroupNoVirtualToArray( - int field_number, const MessageType& value, uint8* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteGroupNoVirtualToArray( + int field_number, const MessageType& value, uint8_t* target); template <typename MessageType> - PROTOBUF_NDEBUG_INLINE static uint8* InternalWriteMessageNoVirtualToArray( - int field_number, const MessageType& value, uint8* target); + PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteMessageNoVirtualToArray( + int field_number, const MessageType& value, uint8_t* target); // For backward-compatibility, the last four methods also have versions // that are non-deterministic always. - PROTOBUF_NDEBUG_INLINE static uint8* WriteGroupToArray( - int field_number, const MessageLite& value, uint8* target) { + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteGroupToArray( + int field_number, const MessageLite& value, uint8_t* target) { io::EpsCopyOutputStream stream( target, value.GetCachedSize() + static_cast<int>(2 * io::CodedOutputStream::VarintSize32( - static_cast<uint32>(field_number) << 3)), + static_cast<uint32_t>(field_number) << 3)), io::CodedOutputStream::IsDefaultSerializationDeterministic()); return InternalWriteGroup(field_number, value, target, &stream); } - PROTOBUF_NDEBUG_INLINE static uint8* WriteMessageToArray( - int field_number, const MessageLite& value, uint8* target) { + PROTOBUF_NDEBUG_INLINE static uint8_t* WriteMessageToArray( + int field_number, const MessageLite& value, uint8_t* target) { int size = value.GetCachedSize(); io::EpsCopyOutputStream stream( target, size + static_cast<int>(io::CodedOutputStream::VarintSize32( - static_cast<uint32>(field_number) << 3) + + static_cast<uint32_t>(field_number) << 3) + io::CodedOutputStream::VarintSize32(size)), io::CodedOutputStream::IsDefaultSerializationDeterministic()); return InternalWriteMessage(field_number, value, target, &stream); @@ -667,20 +667,27 @@ // the tag, so you must also call TagSize(). (This is because, for repeated // fields, you should only call TagSize() once and multiply it by the element // count, but you may have to call XxSize() for each individual element.) - static inline size_t Int32Size(int32 value); - static inline size_t Int64Size(int64 value); - static inline size_t UInt32Size(uint32 value); - static inline size_t UInt64Size(uint64 value); - static inline size_t SInt32Size(int32 value); - static inline size_t SInt64Size(int64 value); + static inline size_t Int32Size(int32_t value); + static inline size_t Int64Size(int64_t value); + static inline size_t UInt32Size(uint32_t value); + static inline size_t UInt64Size(uint64_t value); + static inline size_t SInt32Size(int32_t value); + static inline size_t SInt64Size(int64_t value); static inline size_t EnumSize(int value); + static inline size_t Int32SizePlusOne(int32_t value); + static inline size_t Int64SizePlusOne(int64_t value); + static inline size_t UInt32SizePlusOne(uint32_t value); + static inline size_t UInt64SizePlusOne(uint64_t value); + static inline size_t SInt32SizePlusOne(int32_t value); + static inline size_t SInt64SizePlusOne(int64_t value); + static inline size_t EnumSizePlusOne(int value); - static size_t Int32Size(const RepeatedField<int32>& value); - static size_t Int64Size(const RepeatedField<int64>& value); - static size_t UInt32Size(const RepeatedField<uint32>& value); - static size_t UInt64Size(const RepeatedField<uint64>& value); - static size_t SInt32Size(const RepeatedField<int32>& value); - static size_t SInt64Size(const RepeatedField<int64>& value); + static size_t Int32Size(const RepeatedField<int32_t>& value); + static size_t Int64Size(const RepeatedField<int64_t>& value); + static size_t UInt32Size(const RepeatedField<uint32_t>& value); + static size_t UInt64Size(const RepeatedField<uint64_t>& value); + static size_t SInt32Size(const RepeatedField<int32_t>& value); + static size_t SInt64Size(const RepeatedField<int64_t>& value); static size_t EnumSize(const RepeatedField<int>& value); // These types always have the same size. @@ -718,7 +725,7 @@ // can be read using potentially faster paths. template <typename CType, enum FieldType DeclaredType> PROTOBUF_NDEBUG_INLINE static bool ReadRepeatedFixedSizePrimitive( - int tag_size, uint32 tag, io::CodedInputStream* input, + int tag_size, uint32_t tag, io::CodedInputStream* input, RepeatedField<CType>* value); // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields. @@ -744,7 +751,7 @@ virtual ~FieldSkipper() {} // Skip a field whose tag has already been consumed. - virtual bool SkipField(io::CodedInputStream* input, uint32 tag); + virtual bool SkipField(io::CodedInputStream* input, uint32_t tag); // Skip an entire message or group, up to an end-group tag (which is consumed) // or end-of-stream. @@ -765,7 +772,7 @@ ~CodedOutputStreamFieldSkipper() override {} // implements FieldSkipper ----------------------------------------- - bool SkipField(io::CodedInputStream* input, uint32 tag) override; + bool SkipField(io::CodedInputStream* input, uint32_t tag) override; bool SkipMessage(io::CodedInputStream* input) override; void SkipUnknownEnum(int field_number, int value) override; @@ -780,23 +787,23 @@ return kFieldTypeToCppTypeMap[type]; } -constexpr inline uint32 WireFormatLite::MakeTag(int field_number, - WireType type) { +constexpr inline uint32_t WireFormatLite::MakeTag(int field_number, + WireType type) { return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type); } -inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) { +inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32_t tag) { return static_cast<WireType>(tag & kTagTypeMask); } -inline int WireFormatLite::GetTagFieldNumber(uint32 tag) { +inline int WireFormatLite::GetTagFieldNumber(uint32_t tag) { return static_cast<int>(tag >> kTagTypeBits); } inline size_t WireFormatLite::TagSize(int field_number, WireFormatLite::FieldType type) { size_t result = io::CodedOutputStream::VarintSize32( - static_cast<uint32>(field_number << kTagTypeBits)); + static_cast<uint32_t>(field_number << kTagTypeBits)); if (type == TYPE_GROUP) { // Groups have both a start and an end tag. return result * 2; @@ -805,19 +812,19 @@ } } -inline uint32 WireFormatLite::EncodeFloat(float value) { - return bit_cast<uint32>(value); +inline uint32_t WireFormatLite::EncodeFloat(float value) { + return bit_cast<uint32_t>(value); } -inline float WireFormatLite::DecodeFloat(uint32 value) { +inline float WireFormatLite::DecodeFloat(uint32_t value) { return bit_cast<float>(value); } -inline uint64 WireFormatLite::EncodeDouble(double value) { - return bit_cast<uint64>(value); +inline uint64_t WireFormatLite::EncodeDouble(double value) { + return bit_cast<uint64_t>(value); } -inline double WireFormatLite::DecodeDouble(uint64 value) { +inline double WireFormatLite::DecodeDouble(uint64_t value) { return bit_cast<double>(value); } @@ -832,7 +839,7 @@ // in such a way that those with a small absolute value will have smaller // encoded values, making them appropriate for encoding using varint. // -// int32 -> uint32 +// int32_t -> uint32_t // ------------------------- // 0 -> 0 // -1 -> 1 @@ -845,26 +852,26 @@ // >> encode >> // << decode << -inline uint32 WireFormatLite::ZigZagEncode32(int32 n) { +inline uint32_t WireFormatLite::ZigZagEncode32(int32_t n) { // Note: the right-shift must be arithmetic // Note: left shift must be unsigned because of overflow - return (static_cast<uint32>(n) << 1) ^ static_cast<uint32>(n >> 31); + return (static_cast<uint32_t>(n) << 1) ^ static_cast<uint32_t>(n >> 31); } -inline int32 WireFormatLite::ZigZagDecode32(uint32 n) { +inline int32_t WireFormatLite::ZigZagDecode32(uint32_t n) { // Note: Using unsigned types prevent undefined behavior - return static_cast<int32>((n >> 1) ^ (~(n & 1) + 1)); + return static_cast<int32_t>((n >> 1) ^ (~(n & 1) + 1)); } -inline uint64 WireFormatLite::ZigZagEncode64(int64 n) { +inline uint64_t WireFormatLite::ZigZagEncode64(int64_t n) { // Note: the right-shift must be arithmetic // Note: left shift must be unsigned because of overflow - return (static_cast<uint64>(n) << 1) ^ static_cast<uint64>(n >> 63); + return (static_cast<uint64_t>(n) << 1) ^ static_cast<uint64_t>(n >> 63); } -inline int64 WireFormatLite::ZigZagDecode64(uint64 n) { +inline int64_t WireFormatLite::ZigZagDecode64(uint64_t n) { // Note: Using unsigned types prevent undefined behavior - return static_cast<int64>((n >> 1) ^ (~(n & 1) + 1)); + return static_cast<int64_t>((n >> 1) ^ (~(n & 1) + 1)); } // String is for UTF-8 text only, but, even so, ReadString() can simply @@ -880,8 +887,8 @@ return ReadBytes(input, p); } -inline uint8* InternalSerializeUnknownMessageSetItemsToArray( - const std::string& unknown_fields, uint8* target, +inline uint8_t* InternalSerializeUnknownMessageSetItemsToArray( + const std::string& unknown_fields, uint8_t* target, io::EpsCopyOutputStream* stream) { return stream->WriteRaw(unknown_fields.data(), static_cast<int>(unknown_fields.size()), target); @@ -895,77 +902,83 @@ // Implementation details of ReadPrimitive. template <> -inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>( - io::CodedInputStream* input, int32* value) { - uint32 temp; +inline bool WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_INT32>( + io::CodedInputStream* input, int32_t* value) { + uint32_t temp; if (!input->ReadVarint32(&temp)) return false; - *value = static_cast<int32>(temp); + *value = static_cast<int32_t>(temp); return true; } template <> -inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>( - io::CodedInputStream* input, int64* value) { - uint64 temp; +inline bool WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_INT64>( + io::CodedInputStream* input, int64_t* value) { + uint64_t temp; if (!input->ReadVarint64(&temp)) return false; - *value = static_cast<int64>(temp); + *value = static_cast<int64_t>(temp); return true; } template <> -inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>( - io::CodedInputStream* input, uint32* value) { +inline bool +WireFormatLite::ReadPrimitive<uint32_t, WireFormatLite::TYPE_UINT32>( + io::CodedInputStream* input, uint32_t* value) { return input->ReadVarint32(value); } template <> -inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>( - io::CodedInputStream* input, uint64* value) { +inline bool +WireFormatLite::ReadPrimitive<uint64_t, WireFormatLite::TYPE_UINT64>( + io::CodedInputStream* input, uint64_t* value) { return input->ReadVarint64(value); } template <> -inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>( - io::CodedInputStream* input, int32* value) { - uint32 temp; +inline bool WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_SINT32>( + io::CodedInputStream* input, int32_t* value) { + uint32_t temp; if (!input->ReadVarint32(&temp)) return false; *value = ZigZagDecode32(temp); return true; } template <> -inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>( - io::CodedInputStream* input, int64* value) { - uint64 temp; +inline bool WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_SINT64>( + io::CodedInputStream* input, int64_t* value) { + uint64_t temp; if (!input->ReadVarint64(&temp)) return false; *value = ZigZagDecode64(temp); return true; } template <> -inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>( - io::CodedInputStream* input, uint32* value) { +inline bool +WireFormatLite::ReadPrimitive<uint32_t, WireFormatLite::TYPE_FIXED32>( + io::CodedInputStream* input, uint32_t* value) { return input->ReadLittleEndian32(value); } template <> -inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>( - io::CodedInputStream* input, uint64* value) { +inline bool +WireFormatLite::ReadPrimitive<uint64_t, WireFormatLite::TYPE_FIXED64>( + io::CodedInputStream* input, uint64_t* value) { return input->ReadLittleEndian64(value); } template <> -inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>( - io::CodedInputStream* input, int32* value) { - uint32 temp; +inline bool +WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_SFIXED32>( + io::CodedInputStream* input, int32_t* value) { + uint32_t temp; if (!input->ReadLittleEndian32(&temp)) return false; - *value = static_cast<int32>(temp); + *value = static_cast<int32_t>(temp); return true; } template <> -inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>( - io::CodedInputStream* input, int64* value) { - uint64 temp; +inline bool +WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_SFIXED64>( + io::CodedInputStream* input, int64_t* value) { + uint64_t temp; if (!input->ReadLittleEndian64(&temp)) return false; - *value = static_cast<int64>(temp); + *value = static_cast<int64_t>(temp); return true; } template <> inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>( io::CodedInputStream* input, float* value) { - uint32 temp; + uint32_t temp; if (!input->ReadLittleEndian32(&temp)) return false; *value = DecodeFloat(temp); return true; @@ -973,7 +986,7 @@ template <> inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>( io::CodedInputStream* input, double* value) { - uint64 temp; + uint64_t temp; if (!input->ReadLittleEndian64(&temp)) return false; *value = DecodeDouble(temp); return true; @@ -981,7 +994,7 @@ template <> inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>( io::CodedInputStream* input, bool* value) { - uint64 temp; + uint64_t temp; if (!input->ReadVarint64(&temp)) return false; *value = temp != 0; return true; @@ -989,56 +1002,56 @@ template <> inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( io::CodedInputStream* input, int* value) { - uint32 temp; + uint32_t temp; if (!input->ReadVarint32(&temp)) return false; *value = static_cast<int>(temp); return true; } template <> -inline const uint8* -WireFormatLite::ReadPrimitiveFromArray<uint32, WireFormatLite::TYPE_FIXED32>( - const uint8* buffer, uint32* value) { +inline const uint8_t* +WireFormatLite::ReadPrimitiveFromArray<uint32_t, WireFormatLite::TYPE_FIXED32>( + const uint8_t* buffer, uint32_t* value) { return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value); } template <> -inline const uint8* -WireFormatLite::ReadPrimitiveFromArray<uint64, WireFormatLite::TYPE_FIXED64>( - const uint8* buffer, uint64* value) { +inline const uint8_t* +WireFormatLite::ReadPrimitiveFromArray<uint64_t, WireFormatLite::TYPE_FIXED64>( + const uint8_t* buffer, uint64_t* value) { return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value); } template <> -inline const uint8* -WireFormatLite::ReadPrimitiveFromArray<int32, WireFormatLite::TYPE_SFIXED32>( - const uint8* buffer, int32* value) { - uint32 temp; +inline const uint8_t* +WireFormatLite::ReadPrimitiveFromArray<int32_t, WireFormatLite::TYPE_SFIXED32>( + const uint8_t* buffer, int32_t* value) { + uint32_t temp; buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); - *value = static_cast<int32>(temp); + *value = static_cast<int32_t>(temp); return buffer; } template <> -inline const uint8* -WireFormatLite::ReadPrimitiveFromArray<int64, WireFormatLite::TYPE_SFIXED64>( - const uint8* buffer, int64* value) { - uint64 temp; +inline const uint8_t* +WireFormatLite::ReadPrimitiveFromArray<int64_t, WireFormatLite::TYPE_SFIXED64>( + const uint8_t* buffer, int64_t* value) { + uint64_t temp; buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); - *value = static_cast<int64>(temp); + *value = static_cast<int64_t>(temp); return buffer; } template <> -inline const uint8* +inline const uint8_t* WireFormatLite::ReadPrimitiveFromArray<float, WireFormatLite::TYPE_FLOAT>( - const uint8* buffer, float* value) { - uint32 temp; + const uint8_t* buffer, float* value) { + uint32_t temp; buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); *value = DecodeFloat(temp); return buffer; } template <> -inline const uint8* +inline const uint8_t* WireFormatLite::ReadPrimitiveFromArray<double, WireFormatLite::TYPE_DOUBLE>( - const uint8* buffer, double* value) { - uint64 temp; + const uint8_t* buffer, double* value) { + uint64_t temp; buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); *value = DecodeDouble(temp); return buffer; @@ -1047,7 +1060,7 @@ template <typename CType, enum WireFormatLite::FieldType DeclaredType> inline bool WireFormatLite::ReadRepeatedPrimitive( int, // tag_size, unused. - uint32 tag, io::CodedInputStream* input, RepeatedField<CType>* values) { + uint32_t tag, io::CodedInputStream* input, RepeatedField<CType>* values) { CType value; if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; values->Add(value); @@ -1062,7 +1075,7 @@ template <typename CType, enum WireFormatLite::FieldType DeclaredType> inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive( - int tag_size, uint32 tag, io::CodedInputStream* input, + int tag_size, uint32_t tag, io::CodedInputStream* input, RepeatedField<CType>* values) { GOOGLE_DCHECK_EQ(UInt32Size(tag), static_cast<size_t>(tag_size)); CType value; @@ -1082,7 +1095,7 @@ int size; input->GetDirectBufferPointerInline(&void_pointer, &size); if (size > 0) { - const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer); + const uint8_t* buffer = reinterpret_cast<const uint8_t*>(void_pointer); // The number of bytes each type occupies on the wire. const int per_value_size = tag_size + static_cast<int>(sizeof(value)); @@ -1111,17 +1124,17 @@ template <> \ inline bool WireFormatLite::ReadRepeatedPrimitive< \ CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ - int tag_size, uint32 tag, io::CodedInputStream* input, \ + int tag_size, uint32_t tag, io::CodedInputStream* input, \ RepeatedField<CPPTYPE>* values) { \ return ReadRepeatedFixedSizePrimitive<CPPTYPE, \ WireFormatLite::DECLARED_TYPE>( \ tag_size, tag, input, values); \ } -READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32) -READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64) -READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32) -READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32_t, TYPE_FIXED32) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64_t, TYPE_FIXED64) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32_t, TYPE_SFIXED32) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64_t, TYPE_SFIXED64) READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) @@ -1129,7 +1142,7 @@ template <typename CType, enum WireFormatLite::FieldType DeclaredType> bool WireFormatLite::ReadRepeatedPrimitiveNoInline( - int tag_size, uint32 tag, io::CodedInputStream* input, + int tag_size, uint32_t tag, io::CodedInputStream* input, RepeatedField<CType>* value) { return ReadRepeatedPrimitive<CType, DeclaredType>(tag_size, tag, input, value); @@ -1171,13 +1184,13 @@ // -1 >= 0 Use fast path if length <= Limit. // >= 0 -1 Use slow path. // >= 0 >= 0 Use fast path if length <= min(both limits). - int64 bytes_limit = input->BytesUntilTotalBytesLimit(); + int64_t bytes_limit = input->BytesUntilTotalBytesLimit(); if (bytes_limit == -1) { bytes_limit = input->BytesUntilLimit(); } else { // parentheses around (std::min) prevents macro expansion of min(...) bytes_limit = - (std::min)(bytes_limit, static_cast<int64>(input->BytesUntilLimit())); + (std::min)(bytes_limit, static_cast<int64_t>(input->BytesUntilLimit())); } if (bytes_limit >= new_bytes) { // Fast-path that pre-allocates *values to the final size. @@ -1222,10 +1235,10 @@ input, values); \ } -READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32) -READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64) -READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32) -READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32_t, TYPE_FIXED32) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64_t, TYPE_FIXED64) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32_t, TYPE_SFIXED32) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64_t, TYPE_SFIXED64) READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) @@ -1271,45 +1284,45 @@ output->WriteTag(MakeTag(field_number, type)); } -inline void WireFormatLite::WriteInt32NoTag(int32 value, +inline void WireFormatLite::WriteInt32NoTag(int32_t value, io::CodedOutputStream* output) { output->WriteVarint32SignExtended(value); } -inline void WireFormatLite::WriteInt64NoTag(int64 value, +inline void WireFormatLite::WriteInt64NoTag(int64_t value, io::CodedOutputStream* output) { - output->WriteVarint64(static_cast<uint64>(value)); + output->WriteVarint64(static_cast<uint64_t>(value)); } -inline void WireFormatLite::WriteUInt32NoTag(uint32 value, +inline void WireFormatLite::WriteUInt32NoTag(uint32_t value, io::CodedOutputStream* output) { output->WriteVarint32(value); } -inline void WireFormatLite::WriteUInt64NoTag(uint64 value, +inline void WireFormatLite::WriteUInt64NoTag(uint64_t value, io::CodedOutputStream* output) { output->WriteVarint64(value); } -inline void WireFormatLite::WriteSInt32NoTag(int32 value, +inline void WireFormatLite::WriteSInt32NoTag(int32_t value, io::CodedOutputStream* output) { output->WriteVarint32(ZigZagEncode32(value)); } -inline void WireFormatLite::WriteSInt64NoTag(int64 value, +inline void WireFormatLite::WriteSInt64NoTag(int64_t value, io::CodedOutputStream* output) { output->WriteVarint64(ZigZagEncode64(value)); } -inline void WireFormatLite::WriteFixed32NoTag(uint32 value, +inline void WireFormatLite::WriteFixed32NoTag(uint32_t value, io::CodedOutputStream* output) { output->WriteLittleEndian32(value); } -inline void WireFormatLite::WriteFixed64NoTag(uint64 value, +inline void WireFormatLite::WriteFixed64NoTag(uint64_t value, io::CodedOutputStream* output) { output->WriteLittleEndian64(value); } -inline void WireFormatLite::WriteSFixed32NoTag(int32 value, +inline void WireFormatLite::WriteSFixed32NoTag(int32_t value, io::CodedOutputStream* output) { - output->WriteLittleEndian32(static_cast<uint32>(value)); + output->WriteLittleEndian32(static_cast<uint32_t>(value)); } -inline void WireFormatLite::WriteSFixed64NoTag(int64 value, +inline void WireFormatLite::WriteSFixed64NoTag(int64_t value, io::CodedOutputStream* output) { - output->WriteLittleEndian64(static_cast<uint64>(value)); + output->WriteLittleEndian64(static_cast<uint64_t>(value)); } inline void WireFormatLite::WriteFloatNoTag(float value, io::CodedOutputStream* output) { @@ -1350,77 +1363,80 @@ // =================================================================== -inline uint8* WireFormatLite::WriteTagToArray(int field_number, WireType type, - uint8* target) { +inline uint8_t* WireFormatLite::WriteTagToArray(int field_number, WireType type, + uint8_t* target) { return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type), target); } -inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteInt32NoTagToArray(int32_t value, + uint8_t* target) { return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); } -inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value, - uint8* target) { - return io::CodedOutputStream::WriteVarint64ToArray(static_cast<uint64>(value), - target); +inline uint8_t* WireFormatLite::WriteInt64NoTagToArray(int64_t value, + uint8_t* target) { + return io::CodedOutputStream::WriteVarint64ToArray( + static_cast<uint64_t>(value), target); } -inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteUInt32NoTagToArray(uint32_t value, + uint8_t* target) { return io::CodedOutputStream::WriteVarint32ToArray(value, target); } -inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteUInt64NoTagToArray(uint64_t value, + uint8_t* target) { return io::CodedOutputStream::WriteVarint64ToArray(value, target); } -inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteSInt32NoTagToArray(int32_t value, + uint8_t* target) { return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value), target); } -inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteSInt64NoTagToArray(int64_t value, + uint8_t* target) { return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value), target); } -inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteFixed32NoTagToArray(uint32_t value, + uint8_t* target) { return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target); } -inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteFixed64NoTagToArray(uint64_t value, + uint8_t* target) { return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target); } -inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteSFixed32NoTagToArray(int32_t value, + uint8_t* target) { return io::CodedOutputStream::WriteLittleEndian32ToArray( - static_cast<uint32>(value), target); + static_cast<uint32_t>(value), target); } -inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteSFixed64NoTagToArray(int64_t value, + uint8_t* target) { return io::CodedOutputStream::WriteLittleEndian64ToArray( - static_cast<uint64>(value), target); + static_cast<uint64_t>(value), target); } -inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteFloatNoTagToArray(float value, + uint8_t* target) { return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value), target); } -inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteDoubleNoTagToArray(double value, + uint8_t* target) { return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value), target); } -inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value, uint8* target) { +inline uint8_t* WireFormatLite::WriteBoolNoTagToArray(bool value, + uint8_t* target) { return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target); } -inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value, uint8* target) { +inline uint8_t* WireFormatLite::WriteEnumNoTagToArray(int value, + uint8_t* target) { return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); } template <typename T> -inline uint8* WireFormatLite::WritePrimitiveNoTagToArray( - const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*), uint8* target) { +inline uint8_t* WireFormatLite::WritePrimitiveNoTagToArray( + const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*), + uint8_t* target) { const int n = value.size(); GOOGLE_DCHECK_GT(n, 0); @@ -1434,8 +1450,9 @@ } template <typename T> -inline uint8* WireFormatLite::WriteFixedNoTagToArray( - const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*), uint8* target) { +inline uint8_t* WireFormatLite::WriteFixedNoTagToArray( + const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*), + uint8_t* target) { #if defined(PROTOBUF_LITTLE_ENDIAN) (void)Writer; @@ -1451,138 +1468,149 @@ #endif } -inline uint8* WireFormatLite::WriteInt32NoTagToArray( - const RepeatedField<int32>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteInt32NoTagToArray( + const RepeatedField<int32_t>& value, uint8_t* target) { return WritePrimitiveNoTagToArray(value, WriteInt32NoTagToArray, target); } -inline uint8* WireFormatLite::WriteInt64NoTagToArray( - const RepeatedField<int64>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteInt64NoTagToArray( + const RepeatedField<int64_t>& value, uint8_t* target) { return WritePrimitiveNoTagToArray(value, WriteInt64NoTagToArray, target); } -inline uint8* WireFormatLite::WriteUInt32NoTagToArray( - const RepeatedField<uint32>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteUInt32NoTagToArray( + const RepeatedField<uint32_t>& value, uint8_t* target) { return WritePrimitiveNoTagToArray(value, WriteUInt32NoTagToArray, target); } -inline uint8* WireFormatLite::WriteUInt64NoTagToArray( - const RepeatedField<uint64>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteUInt64NoTagToArray( + const RepeatedField<uint64_t>& value, uint8_t* target) { return WritePrimitiveNoTagToArray(value, WriteUInt64NoTagToArray, target); } -inline uint8* WireFormatLite::WriteSInt32NoTagToArray( - const RepeatedField<int32>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteSInt32NoTagToArray( + const RepeatedField<int32_t>& value, uint8_t* target) { return WritePrimitiveNoTagToArray(value, WriteSInt32NoTagToArray, target); } -inline uint8* WireFormatLite::WriteSInt64NoTagToArray( - const RepeatedField<int64>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteSInt64NoTagToArray( + const RepeatedField<int64_t>& value, uint8_t* target) { return WritePrimitiveNoTagToArray(value, WriteSInt64NoTagToArray, target); } -inline uint8* WireFormatLite::WriteFixed32NoTagToArray( - const RepeatedField<uint32>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteFixed32NoTagToArray( + const RepeatedField<uint32_t>& value, uint8_t* target) { return WriteFixedNoTagToArray(value, WriteFixed32NoTagToArray, target); } -inline uint8* WireFormatLite::WriteFixed64NoTagToArray( - const RepeatedField<uint64>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteFixed64NoTagToArray( + const RepeatedField<uint64_t>& value, uint8_t* target) { return WriteFixedNoTagToArray(value, WriteFixed64NoTagToArray, target); } -inline uint8* WireFormatLite::WriteSFixed32NoTagToArray( - const RepeatedField<int32>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteSFixed32NoTagToArray( + const RepeatedField<int32_t>& value, uint8_t* target) { return WriteFixedNoTagToArray(value, WriteSFixed32NoTagToArray, target); } -inline uint8* WireFormatLite::WriteSFixed64NoTagToArray( - const RepeatedField<int64>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteSFixed64NoTagToArray( + const RepeatedField<int64_t>& value, uint8_t* target) { return WriteFixedNoTagToArray(value, WriteSFixed64NoTagToArray, target); } -inline uint8* WireFormatLite::WriteFloatNoTagToArray( - const RepeatedField<float>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteFloatNoTagToArray( + const RepeatedField<float>& value, uint8_t* target) { return WriteFixedNoTagToArray(value, WriteFloatNoTagToArray, target); } -inline uint8* WireFormatLite::WriteDoubleNoTagToArray( - const RepeatedField<double>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteDoubleNoTagToArray( + const RepeatedField<double>& value, uint8_t* target) { return WriteFixedNoTagToArray(value, WriteDoubleNoTagToArray, target); } -inline uint8* WireFormatLite::WriteBoolNoTagToArray( - const RepeatedField<bool>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteBoolNoTagToArray( + const RepeatedField<bool>& value, uint8_t* target) { return WritePrimitiveNoTagToArray(value, WriteBoolNoTagToArray, target); } -inline uint8* WireFormatLite::WriteEnumNoTagToArray( - const RepeatedField<int>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteEnumNoTagToArray( + const RepeatedField<int>& value, uint8_t* target) { return WritePrimitiveNoTagToArray(value, WriteEnumNoTagToArray, target); } -inline uint8* WireFormatLite::WriteInt32ToArray(int field_number, int32 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteInt32ToArray(int field_number, + int32_t value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); return WriteInt32NoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteInt64ToArray(int field_number, int64 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteInt64ToArray(int field_number, + int64_t value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); return WriteInt64NoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number, uint32 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteUInt32ToArray(int field_number, + uint32_t value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); return WriteUInt32NoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number, uint64 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteUInt64ToArray(int field_number, + uint64_t value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); return WriteUInt64NoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number, int32 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteSInt32ToArray(int field_number, + int32_t value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); return WriteSInt32NoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number, int64 value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteSInt64ToArray(int field_number, + int64_t value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); return WriteSInt64NoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number, - uint32 value, uint8* target) { +inline uint8_t* WireFormatLite::WriteFixed32ToArray(int field_number, + uint32_t value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); return WriteFixed32NoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number, - uint64 value, uint8* target) { +inline uint8_t* WireFormatLite::WriteFixed64ToArray(int field_number, + uint64_t value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); return WriteFixed64NoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number, - int32 value, uint8* target) { +inline uint8_t* WireFormatLite::WriteSFixed32ToArray(int field_number, + int32_t value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); return WriteSFixed32NoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number, - int64 value, uint8* target) { +inline uint8_t* WireFormatLite::WriteSFixed64ToArray(int field_number, + int64_t value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); return WriteSFixed64NoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteFloatToArray(int field_number, float value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteFloatToArray(int field_number, float value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); return WriteFloatNoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteDoubleToArray(int field_number, double value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteDoubleToArray(int field_number, + double value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); return WriteDoubleNoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteBoolToArray(int field_number, bool value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteBoolToArray(int field_number, bool value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); return WriteBoolNoTagToArray(value, target); } -inline uint8* WireFormatLite::WriteEnumToArray(int field_number, int value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteEnumToArray(int field_number, int value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); return WriteEnumNoTagToArray(value, target); } template <typename T> -inline uint8* WireFormatLite::WritePrimitiveToArray( +inline uint8_t* WireFormatLite::WritePrimitiveToArray( int field_number, const RepeatedField<T>& value, - uint8* (*Writer)(int, T, uint8*), uint8* target) { + uint8_t* (*Writer)(int, T, uint8_t*), uint8_t* target) { const int n = value.size(); if (n == 0) { return target; @@ -1597,71 +1625,69 @@ return target; } -inline uint8* WireFormatLite::WriteInt32ToArray( - int field_number, const RepeatedField<int32>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteInt32ToArray( + int field_number, const RepeatedField<int32_t>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteInt32ToArray, target); } -inline uint8* WireFormatLite::WriteInt64ToArray( - int field_number, const RepeatedField<int64>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteInt64ToArray( + int field_number, const RepeatedField<int64_t>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteInt64ToArray, target); } -inline uint8* WireFormatLite::WriteUInt32ToArray( - int field_number, const RepeatedField<uint32>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteUInt32ToArray( + int field_number, const RepeatedField<uint32_t>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteUInt32ToArray, target); } -inline uint8* WireFormatLite::WriteUInt64ToArray( - int field_number, const RepeatedField<uint64>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteUInt64ToArray( + int field_number, const RepeatedField<uint64_t>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteUInt64ToArray, target); } -inline uint8* WireFormatLite::WriteSInt32ToArray( - int field_number, const RepeatedField<int32>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteSInt32ToArray( + int field_number, const RepeatedField<int32_t>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteSInt32ToArray, target); } -inline uint8* WireFormatLite::WriteSInt64ToArray( - int field_number, const RepeatedField<int64>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteSInt64ToArray( + int field_number, const RepeatedField<int64_t>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteSInt64ToArray, target); } -inline uint8* WireFormatLite::WriteFixed32ToArray( - int field_number, const RepeatedField<uint32>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteFixed32ToArray( + int field_number, const RepeatedField<uint32_t>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteFixed32ToArray, target); } -inline uint8* WireFormatLite::WriteFixed64ToArray( - int field_number, const RepeatedField<uint64>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteFixed64ToArray( + int field_number, const RepeatedField<uint64_t>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteFixed64ToArray, target); } -inline uint8* WireFormatLite::WriteSFixed32ToArray( - int field_number, const RepeatedField<int32>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteSFixed32ToArray( + int field_number, const RepeatedField<int32_t>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteSFixed32ToArray, target); } -inline uint8* WireFormatLite::WriteSFixed64ToArray( - int field_number, const RepeatedField<int64>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteSFixed64ToArray( + int field_number, const RepeatedField<int64_t>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteSFixed64ToArray, target); } -inline uint8* WireFormatLite::WriteFloatToArray( - int field_number, const RepeatedField<float>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteFloatToArray( + int field_number, const RepeatedField<float>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteFloatToArray, target); } -inline uint8* WireFormatLite::WriteDoubleToArray( - int field_number, const RepeatedField<double>& value, uint8* target) { +inline uint8_t* WireFormatLite::WriteDoubleToArray( + int field_number, const RepeatedField<double>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteDoubleToArray, target); } -inline uint8* WireFormatLite::WriteBoolToArray(int field_number, - const RepeatedField<bool>& value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteBoolToArray( + int field_number, const RepeatedField<bool>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteBoolToArray, target); } -inline uint8* WireFormatLite::WriteEnumToArray(int field_number, - const RepeatedField<int>& value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteEnumToArray( + int field_number, const RepeatedField<int>& value, uint8_t* target) { return WritePrimitiveToArray(field_number, value, WriteEnumToArray, target); } -inline uint8* WireFormatLite::WriteStringToArray(int field_number, - const std::string& value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteStringToArray(int field_number, + const std::string& value, + uint8_t* target) { // String is for UTF-8 text only // WARNING: In wire_format.cc, both strings and bytes are handled by // WriteString() to avoid code duplication. If the implementations become @@ -1669,17 +1695,17 @@ target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); } -inline uint8* WireFormatLite::WriteBytesToArray(int field_number, - const std::string& value, - uint8* target) { +inline uint8_t* WireFormatLite::WriteBytesToArray(int field_number, + const std::string& value, + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); } template <typename MessageType> -inline uint8* WireFormatLite::InternalWriteGroup( - int field_number, const MessageType& value, uint8* target, +inline uint8_t* WireFormatLite::InternalWriteGroup( + int field_number, const MessageType& value, uint8_t* target, io::EpsCopyOutputStream* stream) { target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); target = value._InternalSerialize(target, stream); @@ -1687,33 +1713,33 @@ return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); } template <typename MessageType> -inline uint8* WireFormatLite::InternalWriteMessage( - int field_number, const MessageType& value, uint8* target, +inline uint8_t* WireFormatLite::InternalWriteMessage( + int field_number, const MessageType& value, uint8_t* target, io::EpsCopyOutputStream* stream) { target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); target = io::CodedOutputStream::WriteVarint32ToArrayOutOfLine( - static_cast<uint32>(value.GetCachedSize()), target); + static_cast<uint32_t>(value.GetCachedSize()), target); return value._InternalSerialize(target, stream); } // See comment on ReadGroupNoVirtual to understand the need for this template // parameter name. template <typename MessageType_WorkAroundCppLookupDefect> -inline uint8* WireFormatLite::InternalWriteGroupNoVirtualToArray( +inline uint8_t* WireFormatLite::InternalWriteGroupNoVirtualToArray( int field_number, const MessageType_WorkAroundCppLookupDefect& value, - uint8* target) { + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); target = value.MessageType_WorkAroundCppLookupDefect:: SerializeWithCachedSizesToArray(target); return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); } template <typename MessageType_WorkAroundCppLookupDefect> -inline uint8* WireFormatLite::InternalWriteMessageNoVirtualToArray( +inline uint8_t* WireFormatLite::InternalWriteMessageNoVirtualToArray( int field_number, const MessageType_WorkAroundCppLookupDefect& value, - uint8* target) { + uint8_t* target) { target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); target = io::CodedOutputStream::WriteVarint32ToArray( - static_cast<uint32>( + static_cast<uint32_t>( value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()), target); return value @@ -1723,27 +1749,49 @@ // =================================================================== -inline size_t WireFormatLite::Int32Size(int32 value) { +inline size_t WireFormatLite::Int32Size(int32_t value) { return io::CodedOutputStream::VarintSize32SignExtended(value); } -inline size_t WireFormatLite::Int64Size(int64 value) { - return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value)); +inline size_t WireFormatLite::Int64Size(int64_t value) { + return io::CodedOutputStream::VarintSize64(static_cast<uint64_t>(value)); } -inline size_t WireFormatLite::UInt32Size(uint32 value) { +inline size_t WireFormatLite::UInt32Size(uint32_t value) { return io::CodedOutputStream::VarintSize32(value); } -inline size_t WireFormatLite::UInt64Size(uint64 value) { +inline size_t WireFormatLite::UInt64Size(uint64_t value) { return io::CodedOutputStream::VarintSize64(value); } -inline size_t WireFormatLite::SInt32Size(int32 value) { +inline size_t WireFormatLite::SInt32Size(int32_t value) { return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); } -inline size_t WireFormatLite::SInt64Size(int64 value) { +inline size_t WireFormatLite::SInt64Size(int64_t value) { return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); } inline size_t WireFormatLite::EnumSize(int value) { return io::CodedOutputStream::VarintSize32SignExtended(value); } +inline size_t WireFormatLite::Int32SizePlusOne(int32_t value) { + return io::CodedOutputStream::VarintSize32SignExtendedPlusOne(value); +} +inline size_t WireFormatLite::Int64SizePlusOne(int64_t value) { + return io::CodedOutputStream::VarintSize64PlusOne( + static_cast<uint64_t>(value)); +} +inline size_t WireFormatLite::UInt32SizePlusOne(uint32_t value) { + return io::CodedOutputStream::VarintSize32PlusOne(value); +} +inline size_t WireFormatLite::UInt64SizePlusOne(uint64_t value) { + return io::CodedOutputStream::VarintSize64PlusOne(value); +} +inline size_t WireFormatLite::SInt32SizePlusOne(int32_t value) { + return io::CodedOutputStream::VarintSize32PlusOne(ZigZagEncode32(value)); +} +inline size_t WireFormatLite::SInt64SizePlusOne(int64_t value) { + return io::CodedOutputStream::VarintSize64PlusOne(ZigZagEncode64(value)); +} +inline size_t WireFormatLite::EnumSizePlusOne(int value) { + return io::CodedOutputStream::VarintSize32SignExtendedPlusOne(value); +} inline size_t WireFormatLite::StringSize(const std::string& value) { return LengthDelimitedSize(value.size()); @@ -1778,11 +1826,11 @@ inline size_t WireFormatLite::LengthDelimitedSize(size_t length) { // The static_cast here prevents an error in certain compiler configurations - // but is not technically correct--if length is too large to fit in a uint32 + // but is not technically correct--if length is too large to fit in a uint32_t // then it will be silently truncated. We will need to fix this if we ever // decide to start supporting serialized messages greater than 2 GiB in size. return length + - io::CodedOutputStream::VarintSize32(static_cast<uint32>(length)); + io::CodedOutputStream::VarintSize32(static_cast<uint32_t>(length)); } template <typename MS> @@ -1791,19 +1839,19 @@ // required int32 type_id = 2; // required data message = 3; - uint32 last_type_id = 0; + uint32_t last_type_id = 0; // If we see message data before the type_id, we'll append it to this so // we can parse it later. std::string message_data; while (true) { - const uint32 tag = input->ReadTagNoLastTag(); + const uint32_t tag = input->ReadTagNoLastTag(); if (tag == 0) return false; switch (tag) { case WireFormatLite::kMessageSetTypeIdTag: { - uint32 type_id; + uint32_t type_id; if (!input->ReadVarint32(&type_id)) return false; last_type_id = type_id; @@ -1811,7 +1859,7 @@ // We saw some message data before the type_id. Have to parse it // now. io::CodedInputStream sub_input( - reinterpret_cast<const uint8*>(message_data.data()), + reinterpret_cast<const uint8_t*>(message_data.data()), static_cast<int>(message_data.size())); sub_input.SetRecursionLimit(input->RecursionBudget()); if (!ms.ParseField(last_type_id, &sub_input)) { @@ -1826,13 +1874,13 @@ case WireFormatLite::kMessageSetMessageTag: { if (last_type_id == 0) { // We haven't seen a type_id yet. Append this data to message_data. - uint32 length; + uint32_t length; if (!input->ReadVarint32(&length)) return false; - if (static_cast<int32>(length) < 0) return false; - uint32 size = static_cast<uint32>( + if (static_cast<int32_t>(length) < 0) return false; + uint32_t size = static_cast<uint32_t>( length + io::CodedOutputStream::VarintSize32(length)); message_data.resize(size); - auto ptr = reinterpret_cast<uint8*>(&message_data[0]); + auto ptr = reinterpret_cast<uint8_t*>(&message_data[0]); ptr = io::CodedOutputStream::WriteVarint32ToArray(length, ptr); if (!input->ReadRaw(ptr, length)) return false; } else {
diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc index 4393066..f1ed951 100644 --- a/src/google/protobuf/wire_format_unittest.cc +++ b/src/google/protobuf/wire_format_unittest.cc
@@ -34,1553 +34,33 @@ #include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/logging.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/test_util.h> -#include <google/protobuf/test_util2.h> #include <google/protobuf/unittest.pb.h> #include <google/protobuf/unittest_mset.pb.h> #include <google/protobuf/unittest_mset_wire_format.pb.h> #include <google/protobuf/unittest_proto3_arena.pb.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/io/zero_copy_stream_impl_lite.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/wire_format_lite.h> -#include <google/protobuf/testing/googletest.h> -#include <google/protobuf/stubs/logging.h> #include <gmock/gmock.h> #include <gtest/gtest.h> -#include <google/protobuf/stubs/casts.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/stl_util.h> +#define UNITTEST ::protobuf_unittest +#define UNITTEST_IMPORT ::protobuf_unittest_import +#define UNITTEST_PACKAGE_NAME "protobuf_unittest" +#define PROTO2_WIREFORMAT_UNITTEST ::proto2_wireformat_unittest +#define PROTO3_ARENA_UNITTEST ::proto3_arena_unittest + +// Must include after defining UNITTEST, etc. // clang-format off -#include <google/protobuf/port_def.inc> +#include <google/protobuf/test_util.inc> +#include <google/protobuf/wire_format_unittest.inc> // clang-format on +// Must be included last. +#include <google/protobuf/port_def.inc> + namespace google { namespace protobuf { namespace internal { namespace { -TEST(WireFormatTest, EnumsInSync) { - // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match - // FieldDescriptor::Type and FieldDescriptor::CppType. - - EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_TYPE), - implicit_cast<int>(WireFormatLite::MAX_FIELD_TYPE)); - EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_CPPTYPE), - implicit_cast<int>(WireFormatLite::MAX_CPPTYPE)); - - for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) { - EXPECT_EQ(implicit_cast<int>(FieldDescriptor::TypeToCppType( - static_cast<FieldDescriptor::Type>(i))), - implicit_cast<int>(WireFormatLite::FieldTypeToCppType( - static_cast<WireFormatLite::FieldType>(i)))); - } -} - -TEST(WireFormatTest, MaxFieldNumber) { - // Make sure the max field number constant is accurate. - EXPECT_EQ((1 << (32 - WireFormatLite::kTagTypeBits)) - 1, - FieldDescriptor::kMaxNumber); -} - -TEST(WireFormatTest, Parse) { - unittest::TestAllTypes source, dest; - std::string data; - - // Serialize using the generated code. - TestUtil::SetAllFields(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectAllFieldsSet(dest); -} - -TEST(WireFormatTest, ParseExtensions) { - unittest::TestAllExtensions source, dest; - std::string data; - - // Serialize using the generated code. - TestUtil::SetAllExtensions(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectAllExtensionsSet(dest); -} - -TEST(WireFormatTest, ParsePacked) { - unittest::TestPackedTypes source, dest; - std::string data; - - // Serialize using the generated code. - TestUtil::SetPackedFields(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectPackedFieldsSet(dest); -} - -TEST(WireFormatTest, ParsePackedFromUnpacked) { - // Serialize using the generated code. - unittest::TestUnpackedTypes source; - TestUtil::SetUnpackedFields(&source); - std::string data = source.SerializeAsString(); - - // Parse using WireFormat. - unittest::TestPackedTypes dest; - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectPackedFieldsSet(dest); -} - -TEST(WireFormatTest, ParseUnpackedFromPacked) { - // Serialize using the generated code. - unittest::TestPackedTypes source; - TestUtil::SetPackedFields(&source); - std::string data = source.SerializeAsString(); - - // Parse using WireFormat. - unittest::TestUnpackedTypes dest; - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectUnpackedFieldsSet(dest); -} - -TEST(WireFormatTest, ParsePackedExtensions) { - unittest::TestPackedExtensions source, dest; - std::string data; - - // Serialize using the generated code. - TestUtil::SetPackedExtensions(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectPackedExtensionsSet(dest); -} - -TEST(WireFormatTest, ParseOneof) { - unittest::TestOneof2 source, dest; - std::string data; - - // Serialize using the generated code. - TestUtil::SetOneof1(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectOneofSet1(dest); -} - -TEST(WireFormatTest, OneofOnlySetLast) { - unittest::TestOneofBackwardsCompatible source; - unittest::TestOneof oneof_dest; - std::string data; - - // Set two fields - source.set_foo_int(100); - source.set_foo_string("101"); - - // Serialize and parse to oneof message. Generated serializer may not order - // fields in tag order. Use WireFormat::SerializeWithCachedSizes instead as - // it sorts fields beforehand. - { - io::StringOutputStream raw_output(&data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(source, source.ByteSizeLong(), - &output); - ASSERT_FALSE(output.HadError()); - } - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &oneof_dest); - - // Only the last field is set. - EXPECT_FALSE(oneof_dest.has_foo_int()); - EXPECT_TRUE(oneof_dest.has_foo_string()); -} - -TEST(WireFormatTest, ByteSize) { - unittest::TestAllTypes message; - TestUtil::SetAllFields(&message); - - EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); - message.Clear(); - EXPECT_EQ(0, message.ByteSizeLong()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatTest, ByteSizeExtensions) { - unittest::TestAllExtensions message; - TestUtil::SetAllExtensions(&message); - - EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); - message.Clear(); - EXPECT_EQ(0, message.ByteSizeLong()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatTest, ByteSizePacked) { - unittest::TestPackedTypes message; - TestUtil::SetPackedFields(&message); - - EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); - message.Clear(); - EXPECT_EQ(0, message.ByteSizeLong()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatTest, ByteSizePackedExtensions) { - unittest::TestPackedExtensions message; - TestUtil::SetPackedExtensions(&message); - - EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); - message.Clear(); - EXPECT_EQ(0, message.ByteSizeLong()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatTest, ByteSizeOneof) { - unittest::TestOneof2 message; - TestUtil::SetOneof1(&message); - - EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); - message.Clear(); - - EXPECT_EQ(0, message.ByteSizeLong()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatTest, Serialize) { - unittest::TestAllTypes message; - std::string generated_data; - std::string dynamic_data; - - TestUtil::SetAllFields(&message); - size_t size = message.ByteSizeLong(); - - // Serialize using the generated code. - { - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message.SerializeWithCachedSizes(&output); - ASSERT_FALSE(output.HadError()); - } - - // Serialize using WireFormat. - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(message, size, &output); - ASSERT_FALSE(output.HadError()); - } - - // Should parse to the same message. - EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); - EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); -} - -TEST(WireFormatTest, SerializeExtensions) { - unittest::TestAllExtensions message; - std::string generated_data; - std::string dynamic_data; - - TestUtil::SetAllExtensions(&message); - size_t size = message.ByteSizeLong(); - - // Serialize using the generated code. - { - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message.SerializeWithCachedSizes(&output); - ASSERT_FALSE(output.HadError()); - } - - // Serialize using WireFormat. - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(message, size, &output); - ASSERT_FALSE(output.HadError()); - } - - // Should parse to the same message. - EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); - EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); -} - -TEST(WireFormatTest, SerializeFieldsAndExtensions) { - unittest::TestFieldOrderings message; - std::string generated_data; - std::string dynamic_data; - - TestUtil::SetAllFieldsAndExtensions(&message); - size_t size = message.ByteSizeLong(); - - // Serialize using the generated code. - { - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message.SerializeWithCachedSizes(&output); - ASSERT_FALSE(output.HadError()); - } - - // Serialize using WireFormat. - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(message, size, &output); - ASSERT_FALSE(output.HadError()); - } - - // Should parse to the same message. - EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); - EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); -} - -TEST(WireFormatTest, SerializeOneof) { - unittest::TestOneof2 message; - std::string generated_data; - std::string dynamic_data; - - TestUtil::SetOneof1(&message); - size_t size = message.ByteSizeLong(); - - // Serialize using the generated code. - { - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message.SerializeWithCachedSizes(&output); - ASSERT_FALSE(output.HadError()); - } - - // Serialize using WireFormat. - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(message, size, &output); - ASSERT_FALSE(output.HadError()); - } - - // Should parse to the same message. - EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); - EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); -} - -TEST(WireFormatTest, ParseMultipleExtensionRanges) { - // Make sure we can parse a message that contains multiple extensions ranges. - unittest::TestFieldOrderings source; - std::string data; - - TestUtil::SetAllFieldsAndExtensions(&source); - source.SerializeToString(&data); - - { - unittest::TestFieldOrderings dest; - EXPECT_TRUE(dest.ParseFromString(data)); - EXPECT_EQ(source.DebugString(), dest.DebugString()); - } - - // Also test using reflection-based parsing. - { - unittest::TestFieldOrderings dest; - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream coded_input(&raw_input); - EXPECT_TRUE(WireFormat::ParseAndMergePartial(&coded_input, &dest)); - EXPECT_EQ(source.DebugString(), dest.DebugString()); - } -} - -const int kUnknownTypeId = 1550055; - -TEST(WireFormatTest, SerializeMessageSet) { - // Set up a TestMessageSet with two known messages and an unknown one. - proto2_wireformat_unittest::TestMessageSet message_set; - message_set - .MutableExtension( - unittest::TestMessageSetExtension1::message_set_extension) - ->set_i(123); - message_set - .MutableExtension( - unittest::TestMessageSetExtension2::message_set_extension) - ->set_str("foo"); - message_set.mutable_unknown_fields()->AddLengthDelimited(kUnknownTypeId, - "bar"); - - std::string data; - ASSERT_TRUE(message_set.SerializeToString(&data)); - - // Parse back using RawMessageSet and check the contents. - unittest::RawMessageSet raw; - ASSERT_TRUE(raw.ParseFromString(data)); - - EXPECT_EQ(0, raw.unknown_fields().field_count()); - - ASSERT_EQ(3, raw.item_size()); - EXPECT_EQ( - unittest::TestMessageSetExtension1::descriptor()->extension(0)->number(), - raw.item(0).type_id()); - EXPECT_EQ( - unittest::TestMessageSetExtension2::descriptor()->extension(0)->number(), - raw.item(1).type_id()); - EXPECT_EQ(kUnknownTypeId, raw.item(2).type_id()); - - unittest::TestMessageSetExtension1 message1; - EXPECT_TRUE(message1.ParseFromString(raw.item(0).message())); - EXPECT_EQ(123, message1.i()); - - unittest::TestMessageSetExtension2 message2; - EXPECT_TRUE(message2.ParseFromString(raw.item(1).message())); - EXPECT_EQ("foo", message2.str()); - - EXPECT_EQ("bar", raw.item(2).message()); -} - -TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) { - // Serialize a MessageSet to a stream and to a flat array using generated - // code, and also using WireFormat, and check that the results are equal. - // Set up a TestMessageSet with two known messages and an unknown one, as - // above. - - proto2_wireformat_unittest::TestMessageSet message_set; - message_set - .MutableExtension( - unittest::TestMessageSetExtension1::message_set_extension) - ->set_i(123); - message_set - .MutableExtension( - unittest::TestMessageSetExtension2::message_set_extension) - ->set_str("foo"); - message_set.mutable_unknown_fields()->AddLengthDelimited(kUnknownTypeId, - "bar"); - - size_t size = message_set.ByteSizeLong(); - EXPECT_EQ(size, message_set.GetCachedSize()); - ASSERT_EQ(size, WireFormat::ByteSize(message_set)); - - std::string flat_data; - std::string stream_data; - std::string dynamic_data; - flat_data.resize(size); - stream_data.resize(size); - - // Serialize to flat array - { - uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&flat_data)); - uint8* end = message_set.SerializeWithCachedSizesToArray(target); - EXPECT_EQ(size, end - target); - } - - // Serialize to buffer - { - io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&stream_data), size, - 1); - io::CodedOutputStream output_stream(&array_stream); - message_set.SerializeWithCachedSizes(&output_stream); - ASSERT_FALSE(output_stream.HadError()); - } - - // Serialize to buffer with WireFormat. - { - io::StringOutputStream string_stream(&dynamic_data); - io::CodedOutputStream output_stream(&string_stream); - WireFormat::SerializeWithCachedSizes(message_set, size, &output_stream); - ASSERT_FALSE(output_stream.HadError()); - } - - EXPECT_TRUE(flat_data == stream_data); - EXPECT_TRUE(flat_data == dynamic_data); -} - -TEST(WireFormatTest, ParseMessageSet) { - // Set up a RawMessageSet with two known messages and an unknown one. - unittest::RawMessageSet raw; - - { - unittest::RawMessageSet::Item* item = raw.add_item(); - item->set_type_id(unittest::TestMessageSetExtension1::descriptor() - ->extension(0) - ->number()); - unittest::TestMessageSetExtension1 message; - message.set_i(123); - message.SerializeToString(item->mutable_message()); - } - - { - unittest::RawMessageSet::Item* item = raw.add_item(); - item->set_type_id(unittest::TestMessageSetExtension2::descriptor() - ->extension(0) - ->number()); - unittest::TestMessageSetExtension2 message; - message.set_str("foo"); - message.SerializeToString(item->mutable_message()); - } - - { - unittest::RawMessageSet::Item* item = raw.add_item(); - item->set_type_id(kUnknownTypeId); - item->set_message("bar"); - } - - std::string data; - ASSERT_TRUE(raw.SerializeToString(&data)); - - // Parse as a TestMessageSet and check the contents. - proto2_wireformat_unittest::TestMessageSet message_set; - ASSERT_TRUE(message_set.ParseFromString(data)); - - EXPECT_EQ(123, - message_set - .GetExtension( - unittest::TestMessageSetExtension1::message_set_extension) - .i()); - EXPECT_EQ("foo", - message_set - .GetExtension( - unittest::TestMessageSetExtension2::message_set_extension) - .str()); - - ASSERT_EQ(1, message_set.unknown_fields().field_count()); - ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED, - message_set.unknown_fields().field(0).type()); - EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited()); - - // Also parse using WireFormat. - proto2_wireformat_unittest::TestMessageSet dynamic_message_set; - io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()), - data.size()); - ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set)); - EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString()); -} - -TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) { - std::string data; - { - unittest::TestMessageSetExtension1 message; - message.set_i(123); - // Build a MessageSet manually with its message content put before its - // type_id. - io::StringOutputStream output_stream(&data); - io::CodedOutputStream coded_output(&output_stream); - coded_output.WriteTag(WireFormatLite::kMessageSetItemStartTag); - // Write the message content first. - WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber, - WireFormatLite::WIRETYPE_LENGTH_DELIMITED, - &coded_output); - coded_output.WriteVarint32(message.ByteSizeLong()); - message.SerializeWithCachedSizes(&coded_output); - // Write the type id. - uint32 type_id = message.GetDescriptor()->extension(0)->number(); - WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber, - type_id, &coded_output); - coded_output.WriteTag(WireFormatLite::kMessageSetItemEndTag); - } - { - proto2_wireformat_unittest::TestMessageSet message_set; - ASSERT_TRUE(message_set.ParseFromString(data)); - - EXPECT_EQ(123, - message_set - .GetExtension( - unittest::TestMessageSetExtension1::message_set_extension) - .i()); - } - { - // Test parse the message via Reflection. - proto2_wireformat_unittest::TestMessageSet message_set; - io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()), - data.size()); - EXPECT_TRUE(WireFormat::ParseAndMergePartial(&input, &message_set)); - EXPECT_TRUE(input.ConsumedEntireMessage()); - - EXPECT_EQ(123, - message_set - .GetExtension( - unittest::TestMessageSetExtension1::message_set_extension) - .i()); - } -} - -void SerializeReverseOrder( - const proto2_wireformat_unittest::TestMessageSet& mset, - io::CodedOutputStream* coded_output); - -void SerializeReverseOrder(const unittest::TestMessageSetExtension1& message, - io::CodedOutputStream* coded_output) { - WireFormatLite::WriteTag(15, // i - WireFormatLite::WIRETYPE_VARINT, coded_output); - coded_output->WriteVarint64(message.i()); - WireFormatLite::WriteTag(16, // recursive - WireFormatLite::WIRETYPE_LENGTH_DELIMITED, - coded_output); - coded_output->WriteVarint32(message.recursive().GetCachedSize()); - SerializeReverseOrder(message.recursive(), coded_output); -} - -void SerializeReverseOrder( - const proto2_wireformat_unittest::TestMessageSet& mset, - io::CodedOutputStream* coded_output) { - if (!mset.HasExtension( - unittest::TestMessageSetExtension1::message_set_extension)) - return; - coded_output->WriteTag(WireFormatLite::kMessageSetItemStartTag); - // Write the message content first. - WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber, - WireFormatLite::WIRETYPE_LENGTH_DELIMITED, - coded_output); - auto& message = mset.GetExtension( - unittest::TestMessageSetExtension1::message_set_extension); - coded_output->WriteVarint32(message.GetCachedSize()); - SerializeReverseOrder(message, coded_output); - // Write the type id. - uint32 type_id = message.GetDescriptor()->extension(0)->number(); - WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber, type_id, - coded_output); - coded_output->WriteTag(WireFormatLite::kMessageSetItemEndTag); -} - -TEST(WireFormatTest, ParseMessageSetWithDeepRecReverseOrder) { - std::string data; - { - proto2_wireformat_unittest::TestMessageSet message_set; - proto2_wireformat_unittest::TestMessageSet* mset = &message_set; - for (int i = 0; i < 200; i++) { - auto m = mset->MutableExtension( - unittest::TestMessageSetExtension1::message_set_extension); - m->set_i(i); - mset = m->mutable_recursive(); - } - message_set.ByteSizeLong(); - // Serialize with reverse payload tag order - io::StringOutputStream output_stream(&data); - io::CodedOutputStream coded_output(&output_stream); - SerializeReverseOrder(message_set, &coded_output); - } - proto2_wireformat_unittest::TestMessageSet message_set; - EXPECT_FALSE(message_set.ParseFromString(data)); -} - -TEST(WireFormatTest, ParseFailMalformedMessageSet) { - constexpr int kDepth = 5; - std::string data; - { - proto2_wireformat_unittest::TestMessageSet message_set; - proto2_wireformat_unittest::TestMessageSet* mset = &message_set; - for (int i = 0; i < kDepth; i++) { - auto m = mset->MutableExtension( - unittest::TestMessageSetExtension1::message_set_extension); - m->set_i(i); - mset = m->mutable_recursive(); - } - auto m = mset->MutableExtension( - unittest::TestMessageSetExtension1::message_set_extension); - // -1 becomes \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1 - m->set_i(-1); - - EXPECT_TRUE(message_set.SerializeToString(&data)); - // Make the proto mal-formed. - data[data.size() - 2 - kDepth] = 0xFF; - } - - proto2_wireformat_unittest::TestMessageSet message_set; - EXPECT_FALSE(message_set.ParseFromString(data)); -} - -TEST(WireFormatTest, ParseFailMalformedMessageSetReverseOrder) { - constexpr int kDepth = 5; - std::string data; - { - proto2_wireformat_unittest::TestMessageSet message_set; - proto2_wireformat_unittest::TestMessageSet* mset = &message_set; - for (int i = 0; i < kDepth; i++) { - auto m = mset->MutableExtension( - unittest::TestMessageSetExtension1::message_set_extension); - m->set_i(i); - mset = m->mutable_recursive(); - } - auto m = mset->MutableExtension( - unittest::TestMessageSetExtension1::message_set_extension); - // -1 becomes \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1 - m->set_i(-1); - // SerializeReverseOrder() assumes "recursive" is always present. - m->mutable_recursive(); - - message_set.ByteSizeLong(); - - // Serialize with reverse payload tag order - io::StringOutputStream output_stream(&data); - io::CodedOutputStream coded_output(&output_stream); - SerializeReverseOrder(message_set, &coded_output); - } - - // Make varint for -1 malformed. - data[data.size() - 5 * (kDepth + 1) - 4] = 0xFF; - - proto2_wireformat_unittest::TestMessageSet message_set; - EXPECT_FALSE(message_set.ParseFromString(data)); -} - -TEST(WireFormatTest, ParseBrokenMessageSet) { - proto2_wireformat_unittest::TestMessageSet message_set; - std::string input("goodbye"); // Invalid wire format data. - EXPECT_FALSE(message_set.ParseFromString(input)); -} - -TEST(WireFormatTest, RecursionLimit) { - unittest::TestRecursiveMessage message; - message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1); - std::string data; - message.SerializeToString(&data); - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(4); - unittest::TestRecursiveMessage message2; - EXPECT_TRUE(message2.ParseFromCodedStream(&input)); - } - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(3); - unittest::TestRecursiveMessage message2; - EXPECT_FALSE(message2.ParseFromCodedStream(&input)); - } -} - -TEST(WireFormatTest, UnknownFieldRecursionLimit) { - unittest::TestEmptyMessage message; - message.mutable_unknown_fields() - ->AddGroup(1234) - ->AddGroup(1234) - ->AddGroup(1234) - ->AddGroup(1234) - ->AddVarint(1234, 123); - std::string data; - message.SerializeToString(&data); - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(4); - unittest::TestEmptyMessage message2; - EXPECT_TRUE(message2.ParseFromCodedStream(&input)); - } - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(3); - unittest::TestEmptyMessage message2; - EXPECT_FALSE(message2.ParseFromCodedStream(&input)); - } -} - -TEST(WireFormatTest, ZigZag) { -// avoid line-wrapping -#define LL(x) static_cast<int64_t>(ULL(x)) -#define ULL(x) uint64_t{x##u} -#define ZigZagEncode32(x) WireFormatLite::ZigZagEncode32(x) -#define ZigZagDecode32(x) WireFormatLite::ZigZagDecode32(x) -#define ZigZagEncode64(x) WireFormatLite::ZigZagEncode64(x) -#define ZigZagDecode64(x) WireFormatLite::ZigZagDecode64(x) - - EXPECT_EQ(0u, ZigZagEncode32(0)); - EXPECT_EQ(1u, ZigZagEncode32(-1)); - EXPECT_EQ(2u, ZigZagEncode32(1)); - EXPECT_EQ(3u, ZigZagEncode32(-2)); - EXPECT_EQ(0x7FFFFFFEu, ZigZagEncode32(0x3FFFFFFF)); - EXPECT_EQ(0x7FFFFFFFu, ZigZagEncode32(0xC0000000)); - EXPECT_EQ(0xFFFFFFFEu, ZigZagEncode32(0x7FFFFFFF)); - EXPECT_EQ(0xFFFFFFFFu, ZigZagEncode32(0x80000000)); - - EXPECT_EQ(0, ZigZagDecode32(0u)); - EXPECT_EQ(-1, ZigZagDecode32(1u)); - EXPECT_EQ(1, ZigZagDecode32(2u)); - EXPECT_EQ(-2, ZigZagDecode32(3u)); - EXPECT_EQ(0x3FFFFFFF, ZigZagDecode32(0x7FFFFFFEu)); - EXPECT_EQ(0xC0000000, ZigZagDecode32(0x7FFFFFFFu)); - EXPECT_EQ(0x7FFFFFFF, ZigZagDecode32(0xFFFFFFFEu)); - EXPECT_EQ(0x80000000, ZigZagDecode32(0xFFFFFFFFu)); - - EXPECT_EQ(0u, ZigZagEncode64(0)); - EXPECT_EQ(1u, ZigZagEncode64(-1)); - EXPECT_EQ(2u, ZigZagEncode64(1)); - EXPECT_EQ(3u, ZigZagEncode64(-2)); - EXPECT_EQ(ULL(0x000000007FFFFFFE), ZigZagEncode64(LL(0x000000003FFFFFFF))); - EXPECT_EQ(ULL(0x000000007FFFFFFF), ZigZagEncode64(LL(0xFFFFFFFFC0000000))); - EXPECT_EQ(ULL(0x00000000FFFFFFFE), ZigZagEncode64(LL(0x000000007FFFFFFF))); - EXPECT_EQ(ULL(0x00000000FFFFFFFF), ZigZagEncode64(LL(0xFFFFFFFF80000000))); - EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFE), ZigZagEncode64(LL(0x7FFFFFFFFFFFFFFF))); - EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFF), ZigZagEncode64(LL(0x8000000000000000))); - - EXPECT_EQ(0, ZigZagDecode64(0u)); - EXPECT_EQ(-1, ZigZagDecode64(1u)); - EXPECT_EQ(1, ZigZagDecode64(2u)); - EXPECT_EQ(-2, ZigZagDecode64(3u)); - EXPECT_EQ(LL(0x000000003FFFFFFF), ZigZagDecode64(ULL(0x000000007FFFFFFE))); - EXPECT_EQ(LL(0xFFFFFFFFC0000000), ZigZagDecode64(ULL(0x000000007FFFFFFF))); - EXPECT_EQ(LL(0x000000007FFFFFFF), ZigZagDecode64(ULL(0x00000000FFFFFFFE))); - EXPECT_EQ(LL(0xFFFFFFFF80000000), ZigZagDecode64(ULL(0x00000000FFFFFFFF))); - EXPECT_EQ(LL(0x7FFFFFFFFFFFFFFF), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFE))); - EXPECT_EQ(LL(0x8000000000000000), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFF))); - - // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1) - // were chosen semi-randomly via keyboard bashing. - EXPECT_EQ(0, ZigZagDecode32(ZigZagEncode32(0))); - EXPECT_EQ(1, ZigZagDecode32(ZigZagEncode32(1))); - EXPECT_EQ(-1, ZigZagDecode32(ZigZagEncode32(-1))); - EXPECT_EQ(14927, ZigZagDecode32(ZigZagEncode32(14927))); - EXPECT_EQ(-3612, ZigZagDecode32(ZigZagEncode32(-3612))); - - EXPECT_EQ(0, ZigZagDecode64(ZigZagEncode64(0))); - EXPECT_EQ(1, ZigZagDecode64(ZigZagEncode64(1))); - EXPECT_EQ(-1, ZigZagDecode64(ZigZagEncode64(-1))); - EXPECT_EQ(14927, ZigZagDecode64(ZigZagEncode64(14927))); - EXPECT_EQ(-3612, ZigZagDecode64(ZigZagEncode64(-3612))); - - EXPECT_EQ(LL(856912304801416), - ZigZagDecode64(ZigZagEncode64(LL(856912304801416)))); - EXPECT_EQ(LL(-75123905439571256), - ZigZagDecode64(ZigZagEncode64(LL(-75123905439571256)))); -} - -TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) { - // At one point checks would trigger when parsing repeated fixed scalar - // fields. - protobuf_unittest::TestRepeatedScalarDifferentTagSizes msg1, msg2; - for (int i = 0; i < 100; ++i) { - msg1.add_repeated_fixed32(i); - msg1.add_repeated_int32(i); - msg1.add_repeated_fixed64(i); - msg1.add_repeated_int64(i); - msg1.add_repeated_float(i); - msg1.add_repeated_uint64(i); - } - - // Make sure that we have a variety of tag sizes. - const Descriptor* desc = msg1.GetDescriptor(); - const FieldDescriptor* field; - field = desc->FindFieldByName("repeated_fixed32"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type())); - field = desc->FindFieldByName("repeated_int32"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type())); - field = desc->FindFieldByName("repeated_fixed64"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type())); - field = desc->FindFieldByName("repeated_int64"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type())); - field = desc->FindFieldByName("repeated_float"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type())); - field = desc->FindFieldByName("repeated_uint64"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type())); - - EXPECT_TRUE(msg2.ParseFromString(msg1.SerializeAsString())); - EXPECT_EQ(msg1.DebugString(), msg2.DebugString()); -} - -TEST(WireFormatTest, CompatibleTypes) { - const int64 data = 0x100000000LL; - unittest::Int64Message msg1; - msg1.set_data(data); - std::string serialized; - msg1.SerializeToString(&serialized); - - // Test int64 is compatible with bool - unittest::BoolMessage msg2; - ASSERT_TRUE(msg2.ParseFromString(serialized)); - ASSERT_EQ(static_cast<bool>(data), msg2.data()); - - // Test int64 is compatible with uint64 - unittest::Uint64Message msg3; - ASSERT_TRUE(msg3.ParseFromString(serialized)); - ASSERT_EQ(static_cast<uint64>(data), msg3.data()); - - // Test int64 is compatible with int32 - unittest::Int32Message msg4; - ASSERT_TRUE(msg4.ParseFromString(serialized)); - ASSERT_EQ(static_cast<int32>(data), msg4.data()); - - // Test int64 is compatible with uint32 - unittest::Uint32Message msg5; - ASSERT_TRUE(msg5.ParseFromString(serialized)); - ASSERT_EQ(static_cast<uint32>(data), msg5.data()); -} - -class Proto3PrimitiveRepeatedWireFormatTest : public ::testing::Test { - protected: - Proto3PrimitiveRepeatedWireFormatTest() - : packedTestAllTypes_( - "\xFA\x01\x01\x01" - "\x82\x02\x01\x01" - "\x8A\x02\x01\x01" - "\x92\x02\x01\x01" - "\x9A\x02\x01\x02" - "\xA2\x02\x01\x02" - "\xAA\x02\x04\x01\x00\x00\x00" - "\xB2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00" - "\xBA\x02\x04\x01\x00\x00\x00" - "\xC2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00" - "\xCA\x02\x04\x00\x00\x80\x3f" - "\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xf0\x3f" - "\xDA\x02\x01\x01" - "\x9A\x03\x01\x01", - 86), - packedTestUnpackedTypes_( - "\x0A\x01\x01" - "\x12\x01\x01" - "\x1A\x01\x01" - "\x22\x01\x01" - "\x2A\x01\x02" - "\x32\x01\x02" - "\x3A\x04\x01\x00\x00\x00" - "\x42\x08\x01\x00\x00\x00\x00\x00\x00\x00" - "\x4A\x04\x01\x00\x00\x00" - "\x52\x08\x01\x00\x00\x00\x00\x00\x00\x00" - "\x5A\x04\x00\x00\x80\x3f" - "\x62\x08\x00\x00\x00\x00\x00\x00\xf0\x3f" - "\x6A\x01\x01" - "\x72\x01\x01", - 72), - unpackedTestAllTypes_( - "\xF8\x01\x01" - "\x80\x02\x01" - "\x88\x02\x01" - "\x90\x02\x01" - "\x98\x02\x02" - "\xA0\x02\x02" - "\xAD\x02\x01\x00\x00\x00" - "\xB1\x02\x01\x00\x00\x00\x00\x00\x00\x00" - "\xBD\x02\x01\x00\x00\x00" - "\xC1\x02\x01\x00\x00\x00\x00\x00\x00\x00" - "\xCD\x02\x00\x00\x80\x3f" - "\xD1\x02\x00\x00\x00\x00\x00\x00\xf0\x3f" - "\xD8\x02\x01" - "\x98\x03\x01", - 72), - unpackedTestUnpackedTypes_( - "\x08\x01" - "\x10\x01" - "\x18\x01" - "\x20\x01" - "\x28\x02" - "\x30\x02" - "\x3D\x01\x00\x00\x00" - "\x41\x01\x00\x00\x00\x00\x00\x00\x00" - "\x4D\x01\x00\x00\x00" - "\x51\x01\x00\x00\x00\x00\x00\x00\x00" - "\x5D\x00\x00\x80\x3f" - "\x61\x00\x00\x00\x00\x00\x00\xf0\x3f" - "\x68\x01" - "\x70\x01", - 58) {} - template <class Proto> - void SetProto3PrimitiveRepeatedFields(Proto* message) { - message->add_repeated_int32(1); - message->add_repeated_int64(1); - message->add_repeated_uint32(1); - message->add_repeated_uint64(1); - message->add_repeated_sint32(1); - message->add_repeated_sint64(1); - message->add_repeated_fixed32(1); - message->add_repeated_fixed64(1); - message->add_repeated_sfixed32(1); - message->add_repeated_sfixed64(1); - message->add_repeated_float(1.0); - message->add_repeated_double(1.0); - message->add_repeated_bool(true); - message->add_repeated_nested_enum(proto3_arena_unittest::TestAllTypes::FOO); - } - - template <class Proto> - void ExpectProto3PrimitiveRepeatedFieldsSet(const Proto& message) { - EXPECT_EQ(1, message.repeated_int32(0)); - EXPECT_EQ(1, message.repeated_int64(0)); - EXPECT_EQ(1, message.repeated_uint32(0)); - EXPECT_EQ(1, message.repeated_uint64(0)); - EXPECT_EQ(1, message.repeated_sint32(0)); - EXPECT_EQ(1, message.repeated_sint64(0)); - EXPECT_EQ(1, message.repeated_fixed32(0)); - EXPECT_EQ(1, message.repeated_fixed64(0)); - EXPECT_EQ(1, message.repeated_sfixed32(0)); - EXPECT_EQ(1, message.repeated_sfixed64(0)); - EXPECT_EQ(1.0, message.repeated_float(0)); - EXPECT_EQ(1.0, message.repeated_double(0)); - EXPECT_EQ(true, message.repeated_bool(0)); - EXPECT_EQ(proto3_arena_unittest::TestAllTypes::FOO, - message.repeated_nested_enum(0)); - } - - template <class Proto> - void TestSerialization(Proto* message, const std::string& expected) { - SetProto3PrimitiveRepeatedFields(message); - - size_t size = message->ByteSizeLong(); - - // Serialize using the generated code. - std::string generated_data; - { - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message->SerializeWithCachedSizes(&output); - ASSERT_FALSE(output.HadError()); - } - EXPECT_TRUE(TestUtil::EqualsToSerialized(*message, generated_data)); - - // Serialize using the dynamic code. - std::string dynamic_data; - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(*message, size, &output); - ASSERT_FALSE(output.HadError()); - } - EXPECT_TRUE(expected == dynamic_data); - } - - template <class Proto> - void TestParsing(Proto* message, const std::string& compatible_data) { - message->Clear(); - message->ParseFromString(compatible_data); - ExpectProto3PrimitiveRepeatedFieldsSet(*message); - - message->Clear(); - io::CodedInputStream input( - reinterpret_cast<const uint8*>(compatible_data.data()), - compatible_data.size()); - WireFormat::ParseAndMergePartial(&input, message); - ExpectProto3PrimitiveRepeatedFieldsSet(*message); - } - - const std::string packedTestAllTypes_; - const std::string packedTestUnpackedTypes_; - const std::string unpackedTestAllTypes_; - const std::string unpackedTestUnpackedTypes_; -}; - -TEST_F(Proto3PrimitiveRepeatedWireFormatTest, Proto3PrimitiveRepeated) { - proto3_arena_unittest::TestAllTypes packed_message; - proto3_arena_unittest::TestUnpackedTypes unpacked_message; - TestSerialization(&packed_message, packedTestAllTypes_); - TestParsing(&packed_message, packedTestAllTypes_); - TestParsing(&packed_message, unpackedTestAllTypes_); - TestSerialization(&unpacked_message, unpackedTestUnpackedTypes_); - TestParsing(&unpacked_message, packedTestUnpackedTypes_); - TestParsing(&unpacked_message, unpackedTestUnpackedTypes_); -} - -class WireFormatInvalidInputTest : public testing::Test { - protected: - // Make a serialized TestAllTypes in which the field optional_nested_message - // contains exactly the given bytes, which may be invalid. - std::string MakeInvalidEmbeddedMessage(const char* bytes, int size) { - const FieldDescriptor* field = - unittest::TestAllTypes::descriptor()->FindFieldByName( - "optional_nested_message"); - GOOGLE_CHECK(field != NULL); - - std::string result; - - { - io::StringOutputStream raw_output(&result); - io::CodedOutputStream output(&raw_output); - - WireFormatLite::WriteBytes(field->number(), std::string(bytes, size), - &output); - } - - return result; - } - - // Make a serialized TestAllTypes in which the field optionalgroup - // contains exactly the given bytes -- which may be invalid -- and - // possibly no end tag. - std::string MakeInvalidGroup(const char* bytes, int size, - bool include_end_tag) { - const FieldDescriptor* field = - unittest::TestAllTypes::descriptor()->FindFieldByName("optionalgroup"); - GOOGLE_CHECK(field != NULL); - - std::string result; - - { - io::StringOutputStream raw_output(&result); - io::CodedOutputStream output(&raw_output); - - output.WriteVarint32(WireFormat::MakeTag(field)); - output.WriteString(std::string(bytes, size)); - if (include_end_tag) { - output.WriteVarint32(WireFormatLite::MakeTag( - field->number(), WireFormatLite::WIRETYPE_END_GROUP)); - } - } - - return result; - } -}; - -TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) { - unittest::TestAllTypes message; - - // Control case. - EXPECT_TRUE(message.ParseFromString(MakeInvalidEmbeddedMessage("", 0))); - - // The byte is a valid varint, but not a valid tag (zero). - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\0", 1))); - - // The byte is a malformed varint. - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\200", 1))); - - // The byte is an endgroup tag, but we aren't parsing a group. - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\014", 1))); - - // The byte is a valid varint but not a valid tag (bad wire type). - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1))); -} - -TEST_F(WireFormatInvalidInputTest, InvalidMessageWithExtraZero) { - std::string data; - { - // Serialize a valid proto - unittest::TestAllTypes message; - message.set_optional_int32(1); - message.SerializeToString(&data); - data.push_back(0); // Append invalid zero tag - } - - // Control case. - { - io::ArrayInputStream ais(data.data(), data.size()); - io::CodedInputStream is(&ais); - unittest::TestAllTypes message; - // It should fail but currently passes. - EXPECT_TRUE(message.MergePartialFromCodedStream(&is)); - // Parsing from the string should fail. - EXPECT_FALSE(message.ParseFromString(data)); - } -} - -TEST_F(WireFormatInvalidInputTest, InvalidGroup) { - unittest::TestAllTypes message; - - // Control case. - EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true))); - - // Missing end tag. Groups cannot end at EOF. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false))); - - // The byte is a valid varint, but not a valid tag (zero). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false))); - - // The byte is a malformed varint. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false))); - - // The byte is an endgroup tag, but not the right one for this group. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false))); - - // The byte is a valid varint but not a valid tag (bad wire type). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true))); -} - -TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) { - // Use TestEmptyMessage so that the group made by MakeInvalidGroup will not - // be a known tag number. - unittest::TestEmptyMessage message; - - // Control case. - EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true))); - - // Missing end tag. Groups cannot end at EOF. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false))); - - // The byte is a valid varint, but not a valid tag (zero). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false))); - - // The byte is a malformed varint. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false))); - - // The byte is an endgroup tag, but not the right one for this group. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false))); - - // The byte is a valid varint but not a valid tag (bad wire type). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true))); -} - -TEST_F(WireFormatInvalidInputTest, InvalidStringInUnknownGroup) { - // Test a bug fix: SkipMessage should fail if the message contains a - // string whose length would extend beyond the message end. - - unittest::TestAllTypes message; - message.set_optional_string("foo foo foo foo"); - std::string data; - message.SerializeToString(&data); - - // Chop some bytes off the end. - data.resize(data.size() - 4); - - // Try to skip it. Note that the bug was only present when parsing to an - // UnknownFieldSet. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream coded_input(&raw_input); - UnknownFieldSet unknown_fields; - EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields)); -} - -// Test differences between string and bytes. -// Value of a string type must be valid UTF-8 string. When UTF-8 -// validation is enabled (GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED): -// WriteInvalidUTF8String: see error message. -// ReadInvalidUTF8String: see error message. -// WriteValidUTF8String: fine. -// ReadValidUTF8String: fine. -// WriteAnyBytes: fine. -// ReadAnyBytes: fine. -const char* kInvalidUTF8String = "Invalid UTF-8: \xA0\xB0\xC0\xD0"; -// This used to be "Valid UTF-8: \x01\x02\u8C37\u6B4C", but MSVC seems to -// interpret \u differently from GCC. -const char* kValidUTF8String = "Valid UTF-8: \x01\x02\350\260\267\346\255\214"; - -template <typename T> -bool WriteMessage(const char* value, T* message, std::string* wire_buffer) { - message->set_data(value); - wire_buffer->clear(); - message->AppendToString(wire_buffer); - return (wire_buffer->size() > 0); -} - -template <typename T> -bool ReadMessage(const std::string& wire_buffer, T* message) { - return message->ParseFromArray(wire_buffer.data(), wire_buffer.size()); -} - -class Utf8ValidationTest : public ::testing::Test { - protected: - Utf8ValidationTest() {} - virtual ~Utf8ValidationTest() {} - virtual void SetUp() { - } - -}; - -TEST_F(Utf8ValidationTest, WriteInvalidUTF8String) { - std::string wire_buffer; - protobuf_unittest::OneString input; - std::vector<std::string> errors; - { - ScopedMemoryLog log; - WriteMessage(kInvalidUTF8String, &input, &wire_buffer); - errors = log.GetMessages(ERROR); - } -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - ASSERT_EQ(1, errors.size()); - EXPECT_TRUE( - HasPrefixString(errors[0], - "String field 'protobuf_unittest.OneString.data' " - "contains invalid UTF-8 data when " - "serializing a protocol buffer. Use the " - "'bytes' type if you intend to send raw bytes.")); -#else - ASSERT_EQ(0, errors.size()); -#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED -} - - -TEST_F(Utf8ValidationTest, ReadInvalidUTF8String) { - std::string wire_buffer; - protobuf_unittest::OneString input; - WriteMessage(kInvalidUTF8String, &input, &wire_buffer); - protobuf_unittest::OneString output; - std::vector<std::string> errors; - { - ScopedMemoryLog log; - ReadMessage(wire_buffer, &output); - errors = log.GetMessages(ERROR); - } -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - ASSERT_EQ(1, errors.size()); - EXPECT_TRUE( - HasPrefixString(errors[0], - "String field 'protobuf_unittest.OneString.data' " - "contains invalid UTF-8 data when " - "parsing a protocol buffer. Use the " - "'bytes' type if you intend to send raw bytes.")); - -#else - ASSERT_EQ(0, errors.size()); -#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED -} - - -TEST_F(Utf8ValidationTest, WriteValidUTF8String) { - std::string wire_buffer; - protobuf_unittest::OneString input; - std::vector<std::string> errors; - { - ScopedMemoryLog log; - WriteMessage(kValidUTF8String, &input, &wire_buffer); - errors = log.GetMessages(ERROR); - } - ASSERT_EQ(0, errors.size()); -} - -TEST_F(Utf8ValidationTest, ReadValidUTF8String) { - std::string wire_buffer; - protobuf_unittest::OneString input; - WriteMessage(kValidUTF8String, &input, &wire_buffer); - protobuf_unittest::OneString output; - std::vector<std::string> errors; - { - ScopedMemoryLog log; - ReadMessage(wire_buffer, &output); - errors = log.GetMessages(ERROR); - } - ASSERT_EQ(0, errors.size()); - EXPECT_EQ(input.data(), output.data()); -} - -// Bytes: anything can pass as bytes, use invalid UTF-8 string to test -TEST_F(Utf8ValidationTest, WriteArbitraryBytes) { - std::string wire_buffer; - protobuf_unittest::OneBytes input; - std::vector<std::string> errors; - { - ScopedMemoryLog log; - WriteMessage(kInvalidUTF8String, &input, &wire_buffer); - errors = log.GetMessages(ERROR); - } - ASSERT_EQ(0, errors.size()); -} - -TEST_F(Utf8ValidationTest, ReadArbitraryBytes) { - std::string wire_buffer; - protobuf_unittest::OneBytes input; - WriteMessage(kInvalidUTF8String, &input, &wire_buffer); - protobuf_unittest::OneBytes output; - std::vector<std::string> errors; - { - ScopedMemoryLog log; - ReadMessage(wire_buffer, &output); - errors = log.GetMessages(ERROR); - } - ASSERT_EQ(0, errors.size()); - EXPECT_EQ(input.data(), output.data()); -} - -TEST_F(Utf8ValidationTest, ParseRepeatedString) { - protobuf_unittest::MoreBytes input; - input.add_data(kValidUTF8String); - input.add_data(kInvalidUTF8String); - input.add_data(kInvalidUTF8String); - std::string wire_buffer = input.SerializeAsString(); - - protobuf_unittest::MoreString output; - std::vector<std::string> errors; - { - ScopedMemoryLog log; - ReadMessage(wire_buffer, &output); - errors = log.GetMessages(ERROR); - } -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - ASSERT_EQ(2, errors.size()); -#else - ASSERT_EQ(0, errors.size()); -#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - EXPECT_EQ(wire_buffer, output.SerializeAsString()); -} - -// Test the old VerifyUTF8String() function, which may still be called by old -// generated code. -TEST_F(Utf8ValidationTest, OldVerifyUTF8String) { - std::string data(kInvalidUTF8String); - - std::vector<std::string> errors; - { - ScopedMemoryLog log; - WireFormat::VerifyUTF8String(data.data(), data.size(), - WireFormat::SERIALIZE); - errors = log.GetMessages(ERROR); - } -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - ASSERT_EQ(1, errors.size()); - EXPECT_TRUE( - HasPrefixString(errors[0], - "String field contains invalid UTF-8 data when " - "serializing a protocol buffer. Use the " - "'bytes' type if you intend to send raw bytes.")); -#else - ASSERT_EQ(0, errors.size()); -#endif -} - - -TEST(RepeatedVarint, Int32) { - RepeatedField<int32> v; - - // Insert -2^n, 2^n and 2^n-1. - for (int n = 0; n < 10; n++) { - v.Add(-(1 << n)); - v.Add(1 << n); - v.Add((1 << n) - 1); - } - - // Check consistency with the scalar Int32Size. - size_t expected = 0; - for (int i = 0; i < v.size(); i++) { - expected += WireFormatLite::Int32Size(v[i]); - } - - EXPECT_EQ(expected, WireFormatLite::Int32Size(v)); -} - -TEST(RepeatedVarint, Int64) { - RepeatedField<int64> v; - - // Insert -2^n, 2^n and 2^n-1. - for (int n = 0; n < 10; n++) { - v.Add(-(1 << n)); - v.Add(1 << n); - v.Add((1 << n) - 1); - } - - // Check consistency with the scalar Int64Size. - size_t expected = 0; - for (int i = 0; i < v.size(); i++) { - expected += WireFormatLite::Int64Size(v[i]); - } - - EXPECT_EQ(expected, WireFormatLite::Int64Size(v)); -} - -TEST(RepeatedVarint, SInt32) { - RepeatedField<int32> v; - - // Insert -2^n, 2^n and 2^n-1. - for (int n = 0; n < 10; n++) { - v.Add(-(1 << n)); - v.Add(1 << n); - v.Add((1 << n) - 1); - } - - // Check consistency with the scalar SInt32Size. - size_t expected = 0; - for (int i = 0; i < v.size(); i++) { - expected += WireFormatLite::SInt32Size(v[i]); - } - - EXPECT_EQ(expected, WireFormatLite::SInt32Size(v)); -} - -TEST(RepeatedVarint, SInt64) { - RepeatedField<int64> v; - - // Insert -2^n, 2^n and 2^n-1. - for (int n = 0; n < 10; n++) { - v.Add(-(1 << n)); - v.Add(1 << n); - v.Add((1 << n) - 1); - } - - // Check consistency with the scalar SInt64Size. - size_t expected = 0; - for (int i = 0; i < v.size(); i++) { - expected += WireFormatLite::SInt64Size(v[i]); - } - - EXPECT_EQ(expected, WireFormatLite::SInt64Size(v)); -} - -TEST(RepeatedVarint, UInt32) { - RepeatedField<uint32> v; - - // Insert 2^n and 2^n-1. - for (int n = 0; n < 10; n++) { - v.Add(1 << n); - v.Add((1 << n) - 1); - } - - // Check consistency with the scalar UInt32Size. - size_t expected = 0; - for (int i = 0; i < v.size(); i++) { - expected += WireFormatLite::UInt32Size(v[i]); - } - - EXPECT_EQ(expected, WireFormatLite::UInt32Size(v)); -} - -TEST(RepeatedVarint, UInt64) { - RepeatedField<uint64> v; - - // Insert 2^n and 2^n-1. - for (int n = 0; n < 10; n++) { - v.Add(1 << n); - v.Add((1 << n) - 1); - } - - // Check consistency with the scalar UInt64Size. - size_t expected = 0; - for (int i = 0; i < v.size(); i++) { - expected += WireFormatLite::UInt64Size(v[i]); - } - - EXPECT_EQ(expected, WireFormatLite::UInt64Size(v)); -} - -TEST(RepeatedVarint, Enum) { - RepeatedField<int> v; - - // Insert 2^n and 2^n-1. - for (int n = 0; n < 10; n++) { - v.Add(1 << n); - v.Add((1 << n) - 1); - } - - // Check consistency with the scalar EnumSize. - size_t expected = 0; - for (int i = 0; i < v.size(); i++) { - expected += WireFormatLite::EnumSize(v[i]); - } - - EXPECT_EQ(expected, WireFormatLite::EnumSize(v)); -} - } // namespace } // namespace internal
diff --git a/src/google/protobuf/wire_format_unittest.inc b/src/google/protobuf/wire_format_unittest.inc new file mode 100644 index 0000000..3f3ddff --- /dev/null +++ b/src/google/protobuf/wire_format_unittest.inc
@@ -0,0 +1,1585 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/wire_format.h> + +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/test_util2.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/testing/googletest.h> +#include <google/protobuf/stubs/logging.h> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/stl_util.h> + +// clang-format off +#include <google/protobuf/port_def.inc> +// clang-format on + +namespace google { +namespace protobuf { +namespace internal { +namespace { + +TEST(WireFormatTest, EnumsInSync) { + // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match + // FieldDescriptor::Type and FieldDescriptor::CppType. + + EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_TYPE), + implicit_cast<int>(WireFormatLite::MAX_FIELD_TYPE)); + EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_CPPTYPE), + implicit_cast<int>(WireFormatLite::MAX_CPPTYPE)); + + for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) { + EXPECT_EQ(implicit_cast<int>(FieldDescriptor::TypeToCppType( + static_cast<FieldDescriptor::Type>(i))), + implicit_cast<int>(WireFormatLite::FieldTypeToCppType( + static_cast<WireFormatLite::FieldType>(i)))); + } +} + +TEST(WireFormatTest, MaxFieldNumber) { + // Make sure the max field number constant is accurate. + EXPECT_EQ((1 << (32 - WireFormatLite::kTagTypeBits)) - 1, + FieldDescriptor::kMaxNumber); +} + +TEST(WireFormatTest, Parse) { + UNITTEST::TestAllTypes source, dest; + std::string data; + + // Serialize using the generated code. + TestUtil::SetAllFields(&source); + source.SerializeToString(&data); + + // Parse using WireFormat. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectAllFieldsSet(dest); +} + +TEST(WireFormatTest, ParseExtensions) { + UNITTEST::TestAllExtensions source, dest; + std::string data; + + // Serialize using the generated code. + TestUtil::SetAllExtensions(&source); + source.SerializeToString(&data); + + // Parse using WireFormat. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectAllExtensionsSet(dest); +} + +TEST(WireFormatTest, ParsePacked) { + UNITTEST::TestPackedTypes source, dest; + std::string data; + + // Serialize using the generated code. + TestUtil::SetPackedFields(&source); + source.SerializeToString(&data); + + // Parse using WireFormat. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectPackedFieldsSet(dest); +} + +TEST(WireFormatTest, ParsePackedFromUnpacked) { + // Serialize using the generated code. + UNITTEST::TestUnpackedTypes source; + TestUtil::SetUnpackedFields(&source); + std::string data = source.SerializeAsString(); + + // Parse using WireFormat. + UNITTEST::TestPackedTypes dest; + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectPackedFieldsSet(dest); +} + +TEST(WireFormatTest, ParseUnpackedFromPacked) { + // Serialize using the generated code. + UNITTEST::TestPackedTypes source; + TestUtil::SetPackedFields(&source); + std::string data = source.SerializeAsString(); + + // Parse using WireFormat. + UNITTEST::TestUnpackedTypes dest; + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectUnpackedFieldsSet(dest); +} + +TEST(WireFormatTest, ParsePackedExtensions) { + UNITTEST::TestPackedExtensions source, dest; + std::string data; + + // Serialize using the generated code. + TestUtil::SetPackedExtensions(&source); + source.SerializeToString(&data); + + // Parse using WireFormat. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectPackedExtensionsSet(dest); +} + +TEST(WireFormatTest, ParseOneof) { + UNITTEST::TestOneof2 source, dest; + std::string data; + + // Serialize using the generated code. + TestUtil::SetOneof1(&source); + source.SerializeToString(&data); + + // Parse using WireFormat. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectOneofSet1(dest); +} + +TEST(WireFormatTest, OneofOnlySetLast) { + UNITTEST::TestOneofBackwardsCompatible source; + UNITTEST::TestOneof oneof_dest; + std::string data; + + // Set two fields + source.set_foo_int(100); + source.set_foo_string("101"); + + // Serialize and parse to oneof message. Generated serializer may not order + // fields in tag order. Use WireFormat::SerializeWithCachedSizes instead as + // it sorts fields beforehand. + { + io::StringOutputStream raw_output(&data); + io::CodedOutputStream output(&raw_output); + WireFormat::SerializeWithCachedSizes(source, source.ByteSizeLong(), + &output); + ASSERT_FALSE(output.HadError()); + } + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &oneof_dest); + + // Only the last field is set. + EXPECT_FALSE(oneof_dest.has_foo_int()); + EXPECT_TRUE(oneof_dest.has_foo_string()); +} + +TEST(WireFormatTest, ByteSize) { + UNITTEST::TestAllTypes message; + TestUtil::SetAllFields(&message); + + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); + message.Clear(); + EXPECT_EQ(0, message.ByteSizeLong()); + EXPECT_EQ(0, WireFormat::ByteSize(message)); +} + +TEST(WireFormatTest, ByteSizeExtensions) { + UNITTEST::TestAllExtensions message; + TestUtil::SetAllExtensions(&message); + + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); + message.Clear(); + EXPECT_EQ(0, message.ByteSizeLong()); + EXPECT_EQ(0, WireFormat::ByteSize(message)); +} + +TEST(WireFormatTest, ByteSizePacked) { + UNITTEST::TestPackedTypes message; + TestUtil::SetPackedFields(&message); + + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); + message.Clear(); + EXPECT_EQ(0, message.ByteSizeLong()); + EXPECT_EQ(0, WireFormat::ByteSize(message)); +} + +TEST(WireFormatTest, ByteSizePackedExtensions) { + UNITTEST::TestPackedExtensions message; + TestUtil::SetPackedExtensions(&message); + + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); + message.Clear(); + EXPECT_EQ(0, message.ByteSizeLong()); + EXPECT_EQ(0, WireFormat::ByteSize(message)); +} + +TEST(WireFormatTest, ByteSizeOneof) { + UNITTEST::TestOneof2 message; + TestUtil::SetOneof1(&message); + + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); + message.Clear(); + + EXPECT_EQ(0, message.ByteSizeLong()); + EXPECT_EQ(0, WireFormat::ByteSize(message)); +} + +TEST(WireFormatTest, Serialize) { + UNITTEST::TestAllTypes message; + std::string generated_data; + std::string dynamic_data; + + TestUtil::SetAllFields(&message); + size_t size = message.ByteSizeLong(); + + // Serialize using the generated code. + { + io::StringOutputStream raw_output(&generated_data); + io::CodedOutputStream output(&raw_output); + message.SerializeWithCachedSizes(&output); + ASSERT_FALSE(output.HadError()); + } + + // Serialize using WireFormat. + { + io::StringOutputStream raw_output(&dynamic_data); + io::CodedOutputStream output(&raw_output); + WireFormat::SerializeWithCachedSizes(message, size, &output); + ASSERT_FALSE(output.HadError()); + } + + // Should parse to the same message. + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); +} + +TEST(WireFormatTest, SerializeExtensions) { + UNITTEST::TestAllExtensions message; + std::string generated_data; + std::string dynamic_data; + + TestUtil::SetAllExtensions(&message); + size_t size = message.ByteSizeLong(); + + // Serialize using the generated code. + { + io::StringOutputStream raw_output(&generated_data); + io::CodedOutputStream output(&raw_output); + message.SerializeWithCachedSizes(&output); + ASSERT_FALSE(output.HadError()); + } + + // Serialize using WireFormat. + { + io::StringOutputStream raw_output(&dynamic_data); + io::CodedOutputStream output(&raw_output); + WireFormat::SerializeWithCachedSizes(message, size, &output); + ASSERT_FALSE(output.HadError()); + } + + // Should parse to the same message. + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); +} + +TEST(WireFormatTest, SerializeFieldsAndExtensions) { + UNITTEST::TestFieldOrderings message; + std::string generated_data; + std::string dynamic_data; + + TestUtil::SetAllFieldsAndExtensions(&message); + size_t size = message.ByteSizeLong(); + + // Serialize using the generated code. + { + io::StringOutputStream raw_output(&generated_data); + io::CodedOutputStream output(&raw_output); + message.SerializeWithCachedSizes(&output); + ASSERT_FALSE(output.HadError()); + } + + // Serialize using WireFormat. + { + io::StringOutputStream raw_output(&dynamic_data); + io::CodedOutputStream output(&raw_output); + WireFormat::SerializeWithCachedSizes(message, size, &output); + ASSERT_FALSE(output.HadError()); + } + + // Should parse to the same message. + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); +} + +TEST(WireFormatTest, SerializeOneof) { + UNITTEST::TestOneof2 message; + std::string generated_data; + std::string dynamic_data; + + TestUtil::SetOneof1(&message); + size_t size = message.ByteSizeLong(); + + // Serialize using the generated code. + { + io::StringOutputStream raw_output(&generated_data); + io::CodedOutputStream output(&raw_output); + message.SerializeWithCachedSizes(&output); + ASSERT_FALSE(output.HadError()); + } + + // Serialize using WireFormat. + { + io::StringOutputStream raw_output(&dynamic_data); + io::CodedOutputStream output(&raw_output); + WireFormat::SerializeWithCachedSizes(message, size, &output); + ASSERT_FALSE(output.HadError()); + } + + // Should parse to the same message. + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); +} + +TEST(WireFormatTest, ParseMultipleExtensionRanges) { + // Make sure we can parse a message that contains multiple extensions ranges. + UNITTEST::TestFieldOrderings source; + std::string data; + + TestUtil::SetAllFieldsAndExtensions(&source); + source.SerializeToString(&data); + + { + UNITTEST::TestFieldOrderings dest; + EXPECT_TRUE(dest.ParseFromString(data)); + EXPECT_EQ(source.DebugString(), dest.DebugString()); + } + + // Also test using reflection-based parsing. + { + UNITTEST::TestFieldOrderings dest; + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream coded_input(&raw_input); + EXPECT_TRUE(WireFormat::ParseAndMergePartial(&coded_input, &dest)); + EXPECT_EQ(source.DebugString(), dest.DebugString()); + } +} + +const int kUnknownTypeId = 1550055; + +TEST(WireFormatTest, SerializeMessageSet) { + // Set up a TestMessageSet with two known messages and an unknown one. + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + message_set + .MutableExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension) + ->set_i(123); + message_set + .MutableExtension( + UNITTEST::TestMessageSetExtension2::message_set_extension) + ->set_str("foo"); + message_set.mutable_unknown_fields()->AddLengthDelimited(kUnknownTypeId, + "bar"); + + std::string data; + ASSERT_TRUE(message_set.SerializeToString(&data)); + + // Parse back using RawMessageSet and check the contents. + UNITTEST::RawMessageSet raw; + ASSERT_TRUE(raw.ParseFromString(data)); + + EXPECT_EQ(0, raw.unknown_fields().field_count()); + + ASSERT_EQ(3, raw.item_size()); + EXPECT_EQ( + UNITTEST::TestMessageSetExtension1::descriptor()->extension(0)->number(), + raw.item(0).type_id()); + EXPECT_EQ( + UNITTEST::TestMessageSetExtension2::descriptor()->extension(0)->number(), + raw.item(1).type_id()); + EXPECT_EQ(kUnknownTypeId, raw.item(2).type_id()); + + UNITTEST::TestMessageSetExtension1 message1; + EXPECT_TRUE(message1.ParseFromString(raw.item(0).message())); + EXPECT_EQ(123, message1.i()); + + UNITTEST::TestMessageSetExtension2 message2; + EXPECT_TRUE(message2.ParseFromString(raw.item(1).message())); + EXPECT_EQ("foo", message2.str()); + + EXPECT_EQ("bar", raw.item(2).message()); +} + +TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) { + // Serialize a MessageSet to a stream and to a flat array using generated + // code, and also using WireFormat, and check that the results are equal. + // Set up a TestMessageSet with two known messages and an unknown one, as + // above. + + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + message_set + .MutableExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension) + ->set_i(123); + message_set + .MutableExtension( + UNITTEST::TestMessageSetExtension2::message_set_extension) + ->set_str("foo"); + message_set.mutable_unknown_fields()->AddLengthDelimited(kUnknownTypeId, + "bar"); + + size_t size = message_set.ByteSizeLong(); + EXPECT_EQ(size, message_set.GetCachedSize()); + ASSERT_EQ(size, WireFormat::ByteSize(message_set)); + + std::string flat_data; + std::string stream_data; + std::string dynamic_data; + flat_data.resize(size); + stream_data.resize(size); + + // Serialize to flat array + { + uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&flat_data)); + uint8* end = message_set.SerializeWithCachedSizesToArray(target); + EXPECT_EQ(size, end - target); + } + + // Serialize to buffer + { + io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&stream_data), size, + 1); + io::CodedOutputStream output_stream(&array_stream); + message_set.SerializeWithCachedSizes(&output_stream); + ASSERT_FALSE(output_stream.HadError()); + } + + // Serialize to buffer with WireFormat. + { + io::StringOutputStream string_stream(&dynamic_data); + io::CodedOutputStream output_stream(&string_stream); + WireFormat::SerializeWithCachedSizes(message_set, size, &output_stream); + ASSERT_FALSE(output_stream.HadError()); + } + + EXPECT_TRUE(flat_data == stream_data); + EXPECT_TRUE(flat_data == dynamic_data); +} + +TEST(WireFormatTest, ParseMessageSet) { + // Set up a RawMessageSet with two known messages and an unknown one. + UNITTEST::RawMessageSet raw; + + { + UNITTEST::RawMessageSet::Item* item = raw.add_item(); + item->set_type_id(UNITTEST::TestMessageSetExtension1::descriptor() + ->extension(0) + ->number()); + UNITTEST::TestMessageSetExtension1 message; + message.set_i(123); + message.SerializeToString(item->mutable_message()); + } + + { + UNITTEST::RawMessageSet::Item* item = raw.add_item(); + item->set_type_id(UNITTEST::TestMessageSetExtension2::descriptor() + ->extension(0) + ->number()); + UNITTEST::TestMessageSetExtension2 message; + message.set_str("foo"); + message.SerializeToString(item->mutable_message()); + } + + { + UNITTEST::RawMessageSet::Item* item = raw.add_item(); + item->set_type_id(kUnknownTypeId); + item->set_message("bar"); + } + + std::string data; + ASSERT_TRUE(raw.SerializeToString(&data)); + + // Parse as a TestMessageSet and check the contents. + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + ASSERT_TRUE(message_set.ParseFromString(data)); + + EXPECT_EQ(123, + message_set + .GetExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension) + .i()); + EXPECT_EQ("foo", + message_set + .GetExtension( + UNITTEST::TestMessageSetExtension2::message_set_extension) + .str()); + + ASSERT_EQ(1, message_set.unknown_fields().field_count()); + ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED, + message_set.unknown_fields().field(0).type()); + EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited()); + + // Also parse using WireFormat. + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet dynamic_message_set; + io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()), + data.size()); + ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set)); + EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString()); +} + +TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) { + std::string data; + { + UNITTEST::TestMessageSetExtension1 message; + message.set_i(123); + // Build a MessageSet manually with its message content put before its + // type_id. + io::StringOutputStream output_stream(&data); + io::CodedOutputStream coded_output(&output_stream); + coded_output.WriteTag(WireFormatLite::kMessageSetItemStartTag); + // Write the message content first. + WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + &coded_output); + coded_output.WriteVarint32(message.ByteSizeLong()); + message.SerializeWithCachedSizes(&coded_output); + // Write the type id. + uint32 type_id = message.GetDescriptor()->extension(0)->number(); + WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber, + type_id, &coded_output); + coded_output.WriteTag(WireFormatLite::kMessageSetItemEndTag); + } + { + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + ASSERT_TRUE(message_set.ParseFromString(data)); + + EXPECT_EQ(123, + message_set + .GetExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension) + .i()); + } + { + // Test parse the message via Reflection. + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()), + data.size()); + EXPECT_TRUE(WireFormat::ParseAndMergePartial(&input, &message_set)); + EXPECT_TRUE(input.ConsumedEntireMessage()); + + EXPECT_EQ(123, + message_set + .GetExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension) + .i()); + } +} + +void SerializeReverseOrder( + const PROTO2_WIREFORMAT_UNITTEST::TestMessageSet& mset, + io::CodedOutputStream* coded_output); + +void SerializeReverseOrder(const UNITTEST::TestMessageSetExtension1& message, + io::CodedOutputStream* coded_output) { + WireFormatLite::WriteTag(15, // i + WireFormatLite::WIRETYPE_VARINT, coded_output); + coded_output->WriteVarint64(message.i()); + WireFormatLite::WriteTag(16, // recursive + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + coded_output); + coded_output->WriteVarint32(message.recursive().GetCachedSize()); + SerializeReverseOrder(message.recursive(), coded_output); +} + +void SerializeReverseOrder( + const PROTO2_WIREFORMAT_UNITTEST::TestMessageSet& mset, + io::CodedOutputStream* coded_output) { + if (!mset.HasExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension)) + return; + coded_output->WriteTag(WireFormatLite::kMessageSetItemStartTag); + // Write the message content first. + WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + coded_output); + auto& message = mset.GetExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension); + coded_output->WriteVarint32(message.GetCachedSize()); + SerializeReverseOrder(message, coded_output); + // Write the type id. + uint32 type_id = message.GetDescriptor()->extension(0)->number(); + WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber, type_id, + coded_output); + coded_output->WriteTag(WireFormatLite::kMessageSetItemEndTag); +} + +TEST(WireFormatTest, ParseMessageSetWithDeepRecReverseOrder) { + std::string data; + { + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet* mset = &message_set; + for (int i = 0; i < 200; i++) { + auto m = mset->MutableExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension); + m->set_i(i); + mset = m->mutable_recursive(); + } + message_set.ByteSizeLong(); + // Serialize with reverse payload tag order + io::StringOutputStream output_stream(&data); + io::CodedOutputStream coded_output(&output_stream); + SerializeReverseOrder(message_set, &coded_output); + } + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + EXPECT_FALSE(message_set.ParseFromString(data)); +} + +TEST(WireFormatTest, ParseFailMalformedMessageSet) { + constexpr int kDepth = 5; + std::string data; + { + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet* mset = &message_set; + for (int i = 0; i < kDepth; i++) { + auto m = mset->MutableExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension); + m->set_i(i); + mset = m->mutable_recursive(); + } + auto m = mset->MutableExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension); + // -1 becomes \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1 + m->set_i(-1); + + EXPECT_TRUE(message_set.SerializeToString(&data)); + // Make the proto mal-formed. + data[data.size() - 2 - kDepth] = 0xFF; + } + + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + EXPECT_FALSE(message_set.ParseFromString(data)); +} + +TEST(WireFormatTest, ParseFailMalformedMessageSetReverseOrder) { + constexpr int kDepth = 5; + std::string data; + { + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet* mset = &message_set; + for (int i = 0; i < kDepth; i++) { + auto m = mset->MutableExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension); + m->set_i(i); + mset = m->mutable_recursive(); + } + auto m = mset->MutableExtension( + UNITTEST::TestMessageSetExtension1::message_set_extension); + // -1 becomes \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1 + m->set_i(-1); + // SerializeReverseOrder() assumes "recursive" is always present. + m->mutable_recursive(); + + message_set.ByteSizeLong(); + + // Serialize with reverse payload tag order + io::StringOutputStream output_stream(&data); + io::CodedOutputStream coded_output(&output_stream); + SerializeReverseOrder(message_set, &coded_output); + } + + // Make varint for -1 malformed. + data[data.size() - 5 * (kDepth + 1) - 4] = 0xFF; + + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + EXPECT_FALSE(message_set.ParseFromString(data)); +} + +TEST(WireFormatTest, ParseBrokenMessageSet) { + PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set; + std::string input("goodbye"); // Invalid wire format data. + EXPECT_FALSE(message_set.ParseFromString(input)); +} + +TEST(WireFormatTest, RecursionLimit) { + UNITTEST::TestRecursiveMessage message; + message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1); + std::string data; + message.SerializeToString(&data); + + { + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetRecursionLimit(4); + UNITTEST::TestRecursiveMessage message2; + EXPECT_TRUE(message2.ParseFromCodedStream(&input)); + } + + { + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetRecursionLimit(3); + UNITTEST::TestRecursiveMessage message2; + EXPECT_FALSE(message2.ParseFromCodedStream(&input)); + } +} + +TEST(WireFormatTest, UnknownFieldRecursionLimit) { + UNITTEST::TestEmptyMessage message; + message.mutable_unknown_fields() + ->AddGroup(1234) + ->AddGroup(1234) + ->AddGroup(1234) + ->AddGroup(1234) + ->AddVarint(1234, 123); + std::string data; + message.SerializeToString(&data); + + { + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetRecursionLimit(4); + UNITTEST::TestEmptyMessage message2; + EXPECT_TRUE(message2.ParseFromCodedStream(&input)); + } + + { + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetRecursionLimit(3); + UNITTEST::TestEmptyMessage message2; + EXPECT_FALSE(message2.ParseFromCodedStream(&input)); + } +} + +TEST(WireFormatTest, ZigZag) { +// avoid line-wrapping +#define LL(x) static_cast<int64_t>(ULL(x)) +#define ULL(x) uint64_t{x##u} +#define ZigZagEncode32(x) WireFormatLite::ZigZagEncode32(x) +#define ZigZagDecode32(x) WireFormatLite::ZigZagDecode32(x) +#define ZigZagEncode64(x) WireFormatLite::ZigZagEncode64(x) +#define ZigZagDecode64(x) WireFormatLite::ZigZagDecode64(x) + + EXPECT_EQ(0u, ZigZagEncode32(0)); + EXPECT_EQ(1u, ZigZagEncode32(-1)); + EXPECT_EQ(2u, ZigZagEncode32(1)); + EXPECT_EQ(3u, ZigZagEncode32(-2)); + EXPECT_EQ(0x7FFFFFFEu, ZigZagEncode32(0x3FFFFFFF)); + EXPECT_EQ(0x7FFFFFFFu, ZigZagEncode32(0xC0000000)); + EXPECT_EQ(0xFFFFFFFEu, ZigZagEncode32(0x7FFFFFFF)); + EXPECT_EQ(0xFFFFFFFFu, ZigZagEncode32(0x80000000)); + + EXPECT_EQ(0, ZigZagDecode32(0u)); + EXPECT_EQ(-1, ZigZagDecode32(1u)); + EXPECT_EQ(1, ZigZagDecode32(2u)); + EXPECT_EQ(-2, ZigZagDecode32(3u)); + EXPECT_EQ(0x3FFFFFFF, ZigZagDecode32(0x7FFFFFFEu)); + EXPECT_EQ(0xC0000000, ZigZagDecode32(0x7FFFFFFFu)); + EXPECT_EQ(0x7FFFFFFF, ZigZagDecode32(0xFFFFFFFEu)); + EXPECT_EQ(0x80000000, ZigZagDecode32(0xFFFFFFFFu)); + + EXPECT_EQ(0u, ZigZagEncode64(0)); + EXPECT_EQ(1u, ZigZagEncode64(-1)); + EXPECT_EQ(2u, ZigZagEncode64(1)); + EXPECT_EQ(3u, ZigZagEncode64(-2)); + EXPECT_EQ(ULL(0x000000007FFFFFFE), ZigZagEncode64(LL(0x000000003FFFFFFF))); + EXPECT_EQ(ULL(0x000000007FFFFFFF), ZigZagEncode64(LL(0xFFFFFFFFC0000000))); + EXPECT_EQ(ULL(0x00000000FFFFFFFE), ZigZagEncode64(LL(0x000000007FFFFFFF))); + EXPECT_EQ(ULL(0x00000000FFFFFFFF), ZigZagEncode64(LL(0xFFFFFFFF80000000))); + EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFE), ZigZagEncode64(LL(0x7FFFFFFFFFFFFFFF))); + EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFF), ZigZagEncode64(LL(0x8000000000000000))); + + EXPECT_EQ(0, ZigZagDecode64(0u)); + EXPECT_EQ(-1, ZigZagDecode64(1u)); + EXPECT_EQ(1, ZigZagDecode64(2u)); + EXPECT_EQ(-2, ZigZagDecode64(3u)); + EXPECT_EQ(LL(0x000000003FFFFFFF), ZigZagDecode64(ULL(0x000000007FFFFFFE))); + EXPECT_EQ(LL(0xFFFFFFFFC0000000), ZigZagDecode64(ULL(0x000000007FFFFFFF))); + EXPECT_EQ(LL(0x000000007FFFFFFF), ZigZagDecode64(ULL(0x00000000FFFFFFFE))); + EXPECT_EQ(LL(0xFFFFFFFF80000000), ZigZagDecode64(ULL(0x00000000FFFFFFFF))); + EXPECT_EQ(LL(0x7FFFFFFFFFFFFFFF), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFE))); + EXPECT_EQ(LL(0x8000000000000000), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFF))); + + // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1) + // were chosen semi-randomly via keyboard bashing. + EXPECT_EQ(0, ZigZagDecode32(ZigZagEncode32(0))); + EXPECT_EQ(1, ZigZagDecode32(ZigZagEncode32(1))); + EXPECT_EQ(-1, ZigZagDecode32(ZigZagEncode32(-1))); + EXPECT_EQ(14927, ZigZagDecode32(ZigZagEncode32(14927))); + EXPECT_EQ(-3612, ZigZagDecode32(ZigZagEncode32(-3612))); + + EXPECT_EQ(0, ZigZagDecode64(ZigZagEncode64(0))); + EXPECT_EQ(1, ZigZagDecode64(ZigZagEncode64(1))); + EXPECT_EQ(-1, ZigZagDecode64(ZigZagEncode64(-1))); + EXPECT_EQ(14927, ZigZagDecode64(ZigZagEncode64(14927))); + EXPECT_EQ(-3612, ZigZagDecode64(ZigZagEncode64(-3612))); + + EXPECT_EQ(LL(856912304801416), + ZigZagDecode64(ZigZagEncode64(LL(856912304801416)))); + EXPECT_EQ(LL(-75123905439571256), + ZigZagDecode64(ZigZagEncode64(LL(-75123905439571256)))); +} + +TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) { + // At one point checks would trigger when parsing repeated fixed scalar + // fields. + UNITTEST::TestRepeatedScalarDifferentTagSizes msg1, msg2; + for (int i = 0; i < 100; ++i) { + msg1.add_repeated_fixed32(i); + msg1.add_repeated_int32(i); + msg1.add_repeated_fixed64(i); + msg1.add_repeated_int64(i); + msg1.add_repeated_float(i); + msg1.add_repeated_uint64(i); + } + + // Make sure that we have a variety of tag sizes. + const Descriptor* desc = msg1.GetDescriptor(); + const FieldDescriptor* field; + field = desc->FindFieldByName("repeated_fixed32"); + ASSERT_TRUE(field != nullptr); + ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_int32"); + ASSERT_TRUE(field != nullptr); + ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_fixed64"); + ASSERT_TRUE(field != nullptr); + ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_int64"); + ASSERT_TRUE(field != nullptr); + ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_float"); + ASSERT_TRUE(field != nullptr); + ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_uint64"); + ASSERT_TRUE(field != nullptr); + ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type())); + + EXPECT_TRUE(msg2.ParseFromString(msg1.SerializeAsString())); + EXPECT_EQ(msg1.DebugString(), msg2.DebugString()); +} + +TEST(WireFormatTest, CompatibleTypes) { + const int64 data = 0x100000000LL; + UNITTEST::Int64Message msg1; + msg1.set_data(data); + std::string serialized; + msg1.SerializeToString(&serialized); + + // Test int64 is compatible with bool + UNITTEST::BoolMessage msg2; + ASSERT_TRUE(msg2.ParseFromString(serialized)); + ASSERT_EQ(static_cast<bool>(data), msg2.data()); + + // Test int64 is compatible with uint64 + UNITTEST::Uint64Message msg3; + ASSERT_TRUE(msg3.ParseFromString(serialized)); + ASSERT_EQ(static_cast<uint64>(data), msg3.data()); + + // Test int64 is compatible with int32 + UNITTEST::Int32Message msg4; + ASSERT_TRUE(msg4.ParseFromString(serialized)); + ASSERT_EQ(static_cast<int32>(data), msg4.data()); + + // Test int64 is compatible with uint32 + UNITTEST::Uint32Message msg5; + ASSERT_TRUE(msg5.ParseFromString(serialized)); + ASSERT_EQ(static_cast<uint32>(data), msg5.data()); +} + +class Proto3PrimitiveRepeatedWireFormatTest : public ::testing::Test { + protected: + Proto3PrimitiveRepeatedWireFormatTest() + : packedTestAllTypes_( + "\xFA\x01\x01\x01" + "\x82\x02\x01\x01" + "\x8A\x02\x01\x01" + "\x92\x02\x01\x01" + "\x9A\x02\x01\x02" + "\xA2\x02\x01\x02" + "\xAA\x02\x04\x01\x00\x00\x00" + "\xB2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00" + "\xBA\x02\x04\x01\x00\x00\x00" + "\xC2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00" + "\xCA\x02\x04\x00\x00\x80\x3f" + "\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xf0\x3f" + "\xDA\x02\x01\x01" + "\x9A\x03\x01\x01", + 86), + packedTestUnpackedTypes_( + "\x0A\x01\x01" + "\x12\x01\x01" + "\x1A\x01\x01" + "\x22\x01\x01" + "\x2A\x01\x02" + "\x32\x01\x02" + "\x3A\x04\x01\x00\x00\x00" + "\x42\x08\x01\x00\x00\x00\x00\x00\x00\x00" + "\x4A\x04\x01\x00\x00\x00" + "\x52\x08\x01\x00\x00\x00\x00\x00\x00\x00" + "\x5A\x04\x00\x00\x80\x3f" + "\x62\x08\x00\x00\x00\x00\x00\x00\xf0\x3f" + "\x6A\x01\x01" + "\x72\x01\x01", + 72), + unpackedTestAllTypes_( + "\xF8\x01\x01" + "\x80\x02\x01" + "\x88\x02\x01" + "\x90\x02\x01" + "\x98\x02\x02" + "\xA0\x02\x02" + "\xAD\x02\x01\x00\x00\x00" + "\xB1\x02\x01\x00\x00\x00\x00\x00\x00\x00" + "\xBD\x02\x01\x00\x00\x00" + "\xC1\x02\x01\x00\x00\x00\x00\x00\x00\x00" + "\xCD\x02\x00\x00\x80\x3f" + "\xD1\x02\x00\x00\x00\x00\x00\x00\xf0\x3f" + "\xD8\x02\x01" + "\x98\x03\x01", + 72), + unpackedTestUnpackedTypes_( + "\x08\x01" + "\x10\x01" + "\x18\x01" + "\x20\x01" + "\x28\x02" + "\x30\x02" + "\x3D\x01\x00\x00\x00" + "\x41\x01\x00\x00\x00\x00\x00\x00\x00" + "\x4D\x01\x00\x00\x00" + "\x51\x01\x00\x00\x00\x00\x00\x00\x00" + "\x5D\x00\x00\x80\x3f" + "\x61\x00\x00\x00\x00\x00\x00\xf0\x3f" + "\x68\x01" + "\x70\x01", + 58) {} + template <class Proto> + void SetProto3PrimitiveRepeatedFields(Proto* message) { + message->add_repeated_int32(1); + message->add_repeated_int64(1); + message->add_repeated_uint32(1); + message->add_repeated_uint64(1); + message->add_repeated_sint32(1); + message->add_repeated_sint64(1); + message->add_repeated_fixed32(1); + message->add_repeated_fixed64(1); + message->add_repeated_sfixed32(1); + message->add_repeated_sfixed64(1); + message->add_repeated_float(1.0); + message->add_repeated_double(1.0); + message->add_repeated_bool(true); + message->add_repeated_nested_enum(PROTO3_ARENA_UNITTEST::TestAllTypes::FOO); + } + + template <class Proto> + void ExpectProto3PrimitiveRepeatedFieldsSet(const Proto& message) { + EXPECT_EQ(1, message.repeated_int32(0)); + EXPECT_EQ(1, message.repeated_int64(0)); + EXPECT_EQ(1, message.repeated_uint32(0)); + EXPECT_EQ(1, message.repeated_uint64(0)); + EXPECT_EQ(1, message.repeated_sint32(0)); + EXPECT_EQ(1, message.repeated_sint64(0)); + EXPECT_EQ(1, message.repeated_fixed32(0)); + EXPECT_EQ(1, message.repeated_fixed64(0)); + EXPECT_EQ(1, message.repeated_sfixed32(0)); + EXPECT_EQ(1, message.repeated_sfixed64(0)); + EXPECT_EQ(1.0, message.repeated_float(0)); + EXPECT_EQ(1.0, message.repeated_double(0)); + EXPECT_EQ(true, message.repeated_bool(0)); + EXPECT_EQ(PROTO3_ARENA_UNITTEST::TestAllTypes::FOO, + message.repeated_nested_enum(0)); + } + + template <class Proto> + void TestSerialization(Proto* message, const std::string& expected) { + SetProto3PrimitiveRepeatedFields(message); + + size_t size = message->ByteSizeLong(); + + // Serialize using the generated code. + std::string generated_data; + { + io::StringOutputStream raw_output(&generated_data); + io::CodedOutputStream output(&raw_output); + message->SerializeWithCachedSizes(&output); + ASSERT_FALSE(output.HadError()); + } + EXPECT_TRUE(TestUtil::EqualsToSerialized(*message, generated_data)); + + // Serialize using the dynamic code. + std::string dynamic_data; + { + io::StringOutputStream raw_output(&dynamic_data); + io::CodedOutputStream output(&raw_output); + WireFormat::SerializeWithCachedSizes(*message, size, &output); + ASSERT_FALSE(output.HadError()); + } + EXPECT_TRUE(expected == dynamic_data); + } + + template <class Proto> + void TestParsing(Proto* message, const std::string& compatible_data) { + message->Clear(); + message->ParseFromString(compatible_data); + ExpectProto3PrimitiveRepeatedFieldsSet(*message); + + message->Clear(); + io::CodedInputStream input( + reinterpret_cast<const uint8*>(compatible_data.data()), + compatible_data.size()); + WireFormat::ParseAndMergePartial(&input, message); + ExpectProto3PrimitiveRepeatedFieldsSet(*message); + } + + const std::string packedTestAllTypes_; + const std::string packedTestUnpackedTypes_; + const std::string unpackedTestAllTypes_; + const std::string unpackedTestUnpackedTypes_; +}; + +TEST_F(Proto3PrimitiveRepeatedWireFormatTest, Proto3PrimitiveRepeated) { + PROTO3_ARENA_UNITTEST::TestAllTypes packed_message; + PROTO3_ARENA_UNITTEST::TestUnpackedTypes unpacked_message; + TestSerialization(&packed_message, packedTestAllTypes_); + TestParsing(&packed_message, packedTestAllTypes_); + TestParsing(&packed_message, unpackedTestAllTypes_); + TestSerialization(&unpacked_message, unpackedTestUnpackedTypes_); + TestParsing(&unpacked_message, packedTestUnpackedTypes_); + TestParsing(&unpacked_message, unpackedTestUnpackedTypes_); +} + +class WireFormatInvalidInputTest : public testing::Test { + protected: + // Make a serialized TestAllTypes in which the field optional_nested_message + // contains exactly the given bytes, which may be invalid. + std::string MakeInvalidEmbeddedMessage(const char* bytes, int size) { + const FieldDescriptor* field = + UNITTEST::TestAllTypes::descriptor()->FindFieldByName( + "optional_nested_message"); + GOOGLE_CHECK(field != nullptr); + + std::string result; + + { + io::StringOutputStream raw_output(&result); + io::CodedOutputStream output(&raw_output); + + WireFormatLite::WriteBytes(field->number(), std::string(bytes, size), + &output); + } + + return result; + } + + // Make a serialized TestAllTypes in which the field optionalgroup + // contains exactly the given bytes -- which may be invalid -- and + // possibly no end tag. + std::string MakeInvalidGroup(const char* bytes, int size, + bool include_end_tag) { + const FieldDescriptor* field = + UNITTEST::TestAllTypes::descriptor()->FindFieldByName("optionalgroup"); + GOOGLE_CHECK(field != nullptr); + + std::string result; + + { + io::StringOutputStream raw_output(&result); + io::CodedOutputStream output(&raw_output); + + output.WriteVarint32(WireFormat::MakeTag(field)); + output.WriteString(std::string(bytes, size)); + if (include_end_tag) { + output.WriteVarint32(WireFormatLite::MakeTag( + field->number(), WireFormatLite::WIRETYPE_END_GROUP)); + } + } + + return result; + } +}; + +TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) { + UNITTEST::TestAllTypes message; + + // Control case. + EXPECT_TRUE(message.ParseFromString(MakeInvalidEmbeddedMessage("", 0))); + + // The byte is a valid varint, but not a valid tag (zero). + EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\0", 1))); + + // The byte is a malformed varint. + EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\200", 1))); + + // The byte is an endgroup tag, but we aren't parsing a group. + EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\014", 1))); + + // The byte is a valid varint but not a valid tag (bad wire type). + EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1))); +} + +TEST_F(WireFormatInvalidInputTest, InvalidMessageWithExtraZero) { + std::string data; + { + // Serialize a valid proto + UNITTEST::TestAllTypes message; + message.set_optional_int32(1); + message.SerializeToString(&data); + data.push_back(0); // Append invalid zero tag + } + + // Control case. + { + io::ArrayInputStream ais(data.data(), data.size()); + io::CodedInputStream is(&ais); + UNITTEST::TestAllTypes message; + // It should fail but currently passes. + EXPECT_TRUE(message.MergePartialFromCodedStream(&is)); + // Parsing from the string should fail. + EXPECT_FALSE(message.ParseFromString(data)); + } +} + +TEST_F(WireFormatInvalidInputTest, InvalidGroup) { + UNITTEST::TestAllTypes message; + + // Control case. + EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true))); + + // Missing end tag. Groups cannot end at EOF. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false))); + + // The byte is a valid varint, but not a valid tag (zero). + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false))); + + // The byte is a malformed varint. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false))); + + // The byte is an endgroup tag, but not the right one for this group. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false))); + + // The byte is a valid varint but not a valid tag (bad wire type). + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true))); +} + +TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) { + // Use TestEmptyMessage so that the group made by MakeInvalidGroup will not + // be a known tag number. + UNITTEST::TestEmptyMessage message; + + // Control case. + EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true))); + + // Missing end tag. Groups cannot end at EOF. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false))); + + // The byte is a valid varint, but not a valid tag (zero). + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false))); + + // The byte is a malformed varint. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false))); + + // The byte is an endgroup tag, but not the right one for this group. + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false))); + + // The byte is a valid varint but not a valid tag (bad wire type). + EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true))); +} + +TEST_F(WireFormatInvalidInputTest, InvalidStringInUnknownGroup) { + // Test a bug fix: SkipMessage should fail if the message contains a + // string whose length would extend beyond the message end. + + UNITTEST::TestAllTypes message; + message.set_optional_string("foo foo foo foo"); + std::string data; + message.SerializeToString(&data); + + // Chop some bytes off the end. + data.resize(data.size() - 4); + + // Try to skip it. Note that the bug was only present when parsing to an + // UnknownFieldSet. + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream coded_input(&raw_input); + UnknownFieldSet unknown_fields; + EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields)); +} + +// Test differences between string and bytes. +// Value of a string type must be valid UTF-8 string. When UTF-8 +// validation is enabled (GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED): +// WriteInvalidUTF8String: see error message. +// ReadInvalidUTF8String: see error message. +// WriteValidUTF8String: fine. +// ReadValidUTF8String: fine. +// WriteAnyBytes: fine. +// ReadAnyBytes: fine. +const char* kInvalidUTF8String = "Invalid UTF-8: \xA0\xB0\xC0\xD0"; +// This used to be "Valid UTF-8: \x01\x02\u8C37\u6B4C", but MSVC seems to +// interpret \u differently from GCC. +const char* kValidUTF8String = "Valid UTF-8: \x01\x02\350\260\267\346\255\214"; + +template <typename T> +bool WriteMessage(const char* value, T* message, std::string* wire_buffer) { + message->set_data(value); + wire_buffer->clear(); + message->AppendToString(wire_buffer); + return (wire_buffer->size() > 0); +} + +template <typename T> +bool ReadMessage(const std::string& wire_buffer, T* message) { + return message->ParseFromArray(wire_buffer.data(), wire_buffer.size()); +} + +class Utf8ValidationTest : public ::testing::Test { + protected: + Utf8ValidationTest() {} + virtual ~Utf8ValidationTest() {} + virtual void SetUp() { + } + +}; + +TEST_F(Utf8ValidationTest, WriteInvalidUTF8String) { + std::string wire_buffer; + UNITTEST::OneString input; + std::vector<std::string> errors; + { + ScopedMemoryLog log; + WriteMessage(kInvalidUTF8String, &input, &wire_buffer); + errors = log.GetMessages(ERROR); + } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + EXPECT_THAT(errors, + testing::ElementsAre( + "String field '" + std::string(UNITTEST_PACKAGE_NAME) + + ".OneString.data' " + "contains invalid UTF-8 data when " + "serializing a protocol buffer. Use the " + "'bytes' type if you intend to send raw bytes. ")); +#else + ASSERT_EQ(0, errors.size()); +#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED +} + + +TEST_F(Utf8ValidationTest, ReadInvalidUTF8String) { + std::string wire_buffer; + UNITTEST::OneString input; + WriteMessage(kInvalidUTF8String, &input, &wire_buffer); + UNITTEST::OneString output; + std::vector<std::string> errors; + { + ScopedMemoryLog log; + ReadMessage(wire_buffer, &output); + errors = log.GetMessages(ERROR); + } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + EXPECT_THAT(errors, + testing::ElementsAre( + "String field '" + std::string(UNITTEST_PACKAGE_NAME) + + ".OneString.data' " + "contains invalid UTF-8 data when " + "parsing a protocol buffer. Use the " + "'bytes' type if you intend to send raw bytes. ")); + +#else + ASSERT_EQ(0, errors.size()); +#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED +} + + +TEST_F(Utf8ValidationTest, WriteValidUTF8String) { + std::string wire_buffer; + UNITTEST::OneString input; + std::vector<std::string> errors; + { + ScopedMemoryLog log; + WriteMessage(kValidUTF8String, &input, &wire_buffer); + errors = log.GetMessages(ERROR); + } + ASSERT_EQ(0, errors.size()); +} + +TEST_F(Utf8ValidationTest, ReadValidUTF8String) { + std::string wire_buffer; + UNITTEST::OneString input; + WriteMessage(kValidUTF8String, &input, &wire_buffer); + UNITTEST::OneString output; + std::vector<std::string> errors; + { + ScopedMemoryLog log; + ReadMessage(wire_buffer, &output); + errors = log.GetMessages(ERROR); + } + ASSERT_EQ(0, errors.size()); + EXPECT_EQ(input.data(), output.data()); +} + +// Bytes: anything can pass as bytes, use invalid UTF-8 string to test +TEST_F(Utf8ValidationTest, WriteArbitraryBytes) { + std::string wire_buffer; + UNITTEST::OneBytes input; + std::vector<std::string> errors; + { + ScopedMemoryLog log; + WriteMessage(kInvalidUTF8String, &input, &wire_buffer); + errors = log.GetMessages(ERROR); + } + ASSERT_EQ(0, errors.size()); +} + +TEST_F(Utf8ValidationTest, ReadArbitraryBytes) { + std::string wire_buffer; + UNITTEST::OneBytes input; + WriteMessage(kInvalidUTF8String, &input, &wire_buffer); + UNITTEST::OneBytes output; + std::vector<std::string> errors; + { + ScopedMemoryLog log; + ReadMessage(wire_buffer, &output); + errors = log.GetMessages(ERROR); + } + ASSERT_EQ(0, errors.size()); + EXPECT_EQ(input.data(), output.data()); +} + +TEST_F(Utf8ValidationTest, ParseRepeatedString) { + UNITTEST::MoreBytes input; + input.add_data(kValidUTF8String); + input.add_data(kInvalidUTF8String); + input.add_data(kInvalidUTF8String); + std::string wire_buffer = input.SerializeAsString(); + + UNITTEST::MoreString output; + std::vector<std::string> errors; + { + ScopedMemoryLog log; + ReadMessage(wire_buffer, &output); + errors = log.GetMessages(ERROR); + } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + ASSERT_EQ(2, errors.size()); +#else + ASSERT_EQ(0, errors.size()); +#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + EXPECT_EQ(wire_buffer, output.SerializeAsString()); +} + +// Test the old VerifyUTF8String() function, which may still be called by old +// generated code. +TEST_F(Utf8ValidationTest, OldVerifyUTF8String) { + std::string data(kInvalidUTF8String); + + std::vector<std::string> errors; + { + ScopedMemoryLog log; + WireFormat::VerifyUTF8String(data.data(), data.size(), + WireFormat::SERIALIZE); + errors = log.GetMessages(ERROR); + } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + ASSERT_EQ(1, errors.size()); + EXPECT_TRUE( + HasPrefixString(errors[0], + "String field contains invalid UTF-8 data when " + "serializing a protocol buffer. Use the " + "'bytes' type if you intend to send raw bytes.")); +#else + ASSERT_EQ(0, errors.size()); +#endif +} + + +TEST(RepeatedVarint, Int32) { + RepeatedField<int32> v; + + // Insert -2^n, 2^n and 2^n-1. + for (int n = 0; n < 10; n++) { + v.Add(-(1 << n)); + v.Add(1 << n); + v.Add((1 << n) - 1); + } + + // Check consistency with the scalar Int32Size. + size_t expected = 0; + for (int i = 0; i < v.size(); i++) { + expected += WireFormatLite::Int32Size(v[i]); + } + + EXPECT_EQ(expected, WireFormatLite::Int32Size(v)); +} + +TEST(RepeatedVarint, Int64) { + RepeatedField<int64> v; + + // Insert -2^n, 2^n and 2^n-1. + for (int n = 0; n < 10; n++) { + v.Add(-(1 << n)); + v.Add(1 << n); + v.Add((1 << n) - 1); + } + + // Check consistency with the scalar Int64Size. + size_t expected = 0; + for (int i = 0; i < v.size(); i++) { + expected += WireFormatLite::Int64Size(v[i]); + } + + EXPECT_EQ(expected, WireFormatLite::Int64Size(v)); +} + +TEST(RepeatedVarint, SInt32) { + RepeatedField<int32> v; + + // Insert -2^n, 2^n and 2^n-1. + for (int n = 0; n < 10; n++) { + v.Add(-(1 << n)); + v.Add(1 << n); + v.Add((1 << n) - 1); + } + + // Check consistency with the scalar SInt32Size. + size_t expected = 0; + for (int i = 0; i < v.size(); i++) { + expected += WireFormatLite::SInt32Size(v[i]); + } + + EXPECT_EQ(expected, WireFormatLite::SInt32Size(v)); +} + +TEST(RepeatedVarint, SInt64) { + RepeatedField<int64> v; + + // Insert -2^n, 2^n and 2^n-1. + for (int n = 0; n < 10; n++) { + v.Add(-(1 << n)); + v.Add(1 << n); + v.Add((1 << n) - 1); + } + + // Check consistency with the scalar SInt64Size. + size_t expected = 0; + for (int i = 0; i < v.size(); i++) { + expected += WireFormatLite::SInt64Size(v[i]); + } + + EXPECT_EQ(expected, WireFormatLite::SInt64Size(v)); +} + +TEST(RepeatedVarint, UInt32) { + RepeatedField<uint32> v; + + // Insert 2^n and 2^n-1. + for (int n = 0; n < 10; n++) { + v.Add(1 << n); + v.Add((1 << n) - 1); + } + + // Check consistency with the scalar UInt32Size. + size_t expected = 0; + for (int i = 0; i < v.size(); i++) { + expected += WireFormatLite::UInt32Size(v[i]); + } + + EXPECT_EQ(expected, WireFormatLite::UInt32Size(v)); +} + +TEST(RepeatedVarint, UInt64) { + RepeatedField<uint64> v; + + // Insert 2^n and 2^n-1. + for (int n = 0; n < 10; n++) { + v.Add(1 << n); + v.Add((1 << n) - 1); + } + + // Check consistency with the scalar UInt64Size. + size_t expected = 0; + for (int i = 0; i < v.size(); i++) { + expected += WireFormatLite::UInt64Size(v[i]); + } + + EXPECT_EQ(expected, WireFormatLite::UInt64Size(v)); +} + +TEST(RepeatedVarint, Enum) { + RepeatedField<int> v; + + // Insert 2^n and 2^n-1. + for (int n = 0; n < 10; n++) { + v.Add(1 << n); + v.Add((1 << n) - 1); + } + + // Check consistency with the scalar EnumSize. + size_t expected = 0; + for (int i = 0; i < v.size(); i++) { + expected += WireFormatLite::EnumSize(v[i]); + } + + EXPECT_EQ(expected, WireFormatLite::EnumSize(v)); +} + + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc>
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index 128ddfc..8bc8a00 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc
@@ -136,66 +136,75 @@ ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::DoubleValue, value_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FloatValue, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FloatValue, value_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Int64Value, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Int64Value, value_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::UInt64Value, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::UInt64Value, value_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Int32Value, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Int32Value, value_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::UInt32Value, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::UInt32Value, value_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::BoolValue, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::BoolValue, value_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::StringValue, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::StringValue, value_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::BytesValue, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::BytesValue, value_), }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, -1, sizeof(PROTOBUF_NAMESPACE_ID::DoubleValue)}, - { 6, -1, sizeof(PROTOBUF_NAMESPACE_ID::FloatValue)}, - { 12, -1, sizeof(PROTOBUF_NAMESPACE_ID::Int64Value)}, - { 18, -1, sizeof(PROTOBUF_NAMESPACE_ID::UInt64Value)}, - { 24, -1, sizeof(PROTOBUF_NAMESPACE_ID::Int32Value)}, - { 30, -1, sizeof(PROTOBUF_NAMESPACE_ID::UInt32Value)}, - { 36, -1, sizeof(PROTOBUF_NAMESPACE_ID::BoolValue)}, - { 42, -1, sizeof(PROTOBUF_NAMESPACE_ID::StringValue)}, - { 48, -1, sizeof(PROTOBUF_NAMESPACE_ID::BytesValue)}, + { 0, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::DoubleValue)}, + { 7, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::FloatValue)}, + { 14, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Int64Value)}, + { 21, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::UInt64Value)}, + { 28, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::Int32Value)}, + { 35, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::UInt32Value)}, + { 42, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::BoolValue)}, + { 49, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::StringValue)}, + { 56, -1, -1, sizeof(PROTOBUF_NAMESPACE_ID::BytesValue)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -307,28 +316,29 @@ if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 9)) { value_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<double>(ptr); ptr += sizeof(double); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -365,13 +375,7 @@ total_size += 1 + 8; } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DoubleValue::_class_data_ = { @@ -380,8 +384,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DoubleValue::GetClassData() const { return &_class_data_; } -void DoubleValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void DoubleValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<DoubleValue *>(to)->MergeFrom( static_cast<const DoubleValue &>(from)); } @@ -490,28 +494,29 @@ if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 13)) { value_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr); ptr += sizeof(float); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -548,13 +553,7 @@ total_size += 1 + 4; } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FloatValue::_class_data_ = { @@ -563,8 +562,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FloatValue::GetClassData() const { return &_class_data_; } -void FloatValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void FloatValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<FloatValue *>(to)->MergeFrom( static_cast<const FloatValue &>(from)); } @@ -673,28 +672,29 @@ if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -728,18 +728,10 @@ // int64 value = 1; if (this->_internal_value() != 0) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( - this->_internal_value()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_value()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Int64Value::_class_data_ = { @@ -748,8 +740,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Int64Value::GetClassData() const { return &_class_data_; } -void Int64Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Int64Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Int64Value *>(to)->MergeFrom( static_cast<const Int64Value &>(from)); } @@ -858,28 +850,29 @@ if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -913,18 +906,10 @@ // uint64 value = 1; if (this->_internal_value() != 0) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64Size( - this->_internal_value()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64SizePlusOne(this->_internal_value()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UInt64Value::_class_data_ = { @@ -933,8 +918,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UInt64Value::GetClassData() const { return &_class_data_; } -void UInt64Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void UInt64Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<UInt64Value *>(to)->MergeFrom( static_cast<const UInt64Value &>(from)); } @@ -1043,28 +1028,29 @@ if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1098,18 +1084,10 @@ // int32 value = 1; if (this->_internal_value() != 0) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( - this->_internal_value()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_value()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Int32Value::_class_data_ = { @@ -1118,8 +1096,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Int32Value::GetClassData() const { return &_class_data_; } -void Int32Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void Int32Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<Int32Value *>(to)->MergeFrom( static_cast<const Int32Value &>(from)); } @@ -1228,28 +1206,29 @@ if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1283,18 +1262,10 @@ // uint32 value = 1; if (this->_internal_value() != 0) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( - this->_internal_value()); + total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32SizePlusOne(this->_internal_value()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UInt32Value::_class_data_ = { @@ -1303,8 +1274,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UInt32Value::GetClassData() const { return &_class_data_; } -void UInt32Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void UInt32Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<UInt32Value *>(to)->MergeFrom( static_cast<const UInt32Value &>(from)); } @@ -1413,28 +1384,29 @@ if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) { value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1471,13 +1443,7 @@ total_size += 1 + 1; } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData BoolValue::_class_data_ = { @@ -1486,8 +1452,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*BoolValue::GetClassData() const { return &_class_data_; } -void BoolValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void BoolValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<BoolValue *>(to)->MergeFrom( static_cast<const BoolValue &>(from)); } @@ -1603,28 +1569,29 @@ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.StringValue.value")); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1667,13 +1634,7 @@ this->_internal_value()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData StringValue::_class_data_ = { @@ -1682,8 +1643,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*StringValue::GetClassData() const { return &_class_data_; } -void StringValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void StringValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<StringValue *>(to)->MergeFrom( static_cast<const StringValue &>(from)); } @@ -1714,11 +1675,13 @@ void StringValue::InternalSwap(StringValue* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &value_, GetArenaForAllocation(), - &other->value_, other->GetArenaForAllocation() + &value_, lhs_arena, + &other->value_, rhs_arena ); } @@ -1802,28 +1765,29 @@ auto str = _internal_mutable_value(); ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); - } else goto handle_unusual; + } else + goto handle_unusual; continue; - default: { - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto success; - } - ptr = UnknownFieldParse(tag, - _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), - ptr, ctx); - CHK_(ptr != nullptr); - continue; - } + default: + goto handle_unusual; } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); } // while -success: +message_done: return ptr; failure: ptr = nullptr; - goto success; + goto message_done; #undef CHK_ } @@ -1862,13 +1826,7 @@ this->_internal_value()); } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( - _internal_metadata_, total_size, &_cached_size_); - } - int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData BytesValue::_class_data_ = { @@ -1877,8 +1835,8 @@ }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*BytesValue::GetClassData() const { return &_class_data_; } -void BytesValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, - const ::PROTOBUF_NAMESPACE_ID::Message&from) { +void BytesValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { static_cast<BytesValue *>(to)->MergeFrom( static_cast<const BytesValue &>(from)); } @@ -1909,11 +1867,13 @@ void BytesValue::InternalSwap(BytesValue* other) { using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &value_, GetArenaForAllocation(), - &other->value_, other->GetArenaForAllocation() + &value_, lhs_arena, + &other->value_, rhs_arena ); }
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index 1be7ae0..defdf68 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h
@@ -174,7 +174,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const DoubleValue& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -313,7 +313,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const FloatValue& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -452,7 +452,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Int64Value& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -591,7 +591,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const UInt64Value& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -730,7 +730,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const Int32Value& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -869,7 +869,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const UInt32Value& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1008,7 +1008,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const BoolValue& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1147,7 +1147,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const StringValue& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1291,7 +1291,7 @@ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; void MergeFrom(const BytesValue& from); private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message*to, const ::PROTOBUF_NAMESPACE_ID::Message&from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final;