From 6c1fe6ea3e4e3915fc4164c43230210f9a0ac24f Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Tue, 23 Jun 2015 11:54:19 +0100 Subject: [PATCH] Implement Clone. Fixes issue #527. --- csharp/src/AddressBook/Addressbook.cs | 34 +- .../GeneratedMessageTest.cs | 124 ++++- .../TestProtos/UnittestImportProto3.cs | 10 +- .../TestProtos/UnittestImportPublicProto3.cs | 10 +- .../TestProtos/UnittestIssues.cs | 46 +- .../TestProtos/UnittestProto3.cs | 459 +++++++++++++++--- csharp/src/ProtocolBuffers/ByteString.cs | 2 +- .../Collections/RepeatedField.cs | 30 ++ .../DescriptorProtos/DescriptorProtoFile.cs | 301 ++++++++++-- csharp/src/ProtocolBuffers/IMessage.cs | 18 + .../compiler/csharp/csharp_field_base.h | 1 + .../compiler/csharp/csharp_message.cc | 59 ++- .../protobuf/compiler/csharp/csharp_message.h | 1 + .../compiler/csharp/csharp_message_field.cc | 10 + .../compiler/csharp/csharp_message_field.h | 2 + .../compiler/csharp/csharp_primitive_field.cc | 10 + .../compiler/csharp/csharp_primitive_field.h | 2 + .../csharp/csharp_repeated_enum_field.cc | 5 + .../csharp/csharp_repeated_enum_field.h | 1 + .../csharp/csharp_repeated_message_field.cc | 5 + .../csharp/csharp_repeated_message_field.h | 1 + .../csharp/csharp_repeated_primitive_field.cc | 5 + .../csharp/csharp_repeated_primitive_field.h | 1 + 23 files changed, 988 insertions(+), 149 deletions(-) diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs index 322f85f7b3..cf09bc4c4a 100644 --- a/csharp/src/AddressBook/Addressbook.cs +++ b/csharp/src/AddressBook/Addressbook.cs @@ -62,7 +62,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { } #region Messages [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Person : pb::IMessage, global::System.IEquatable { + public sealed partial class Person : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Person()); public static pb::MessageParser Parser { get { return _parser; } } @@ -77,9 +77,18 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { } public Person() { } + public Person(Person other) { - MergeFrom(other); + name_ = other.name_; + id_ = other.id_; + email_ = other.email_; + phone_ = other.phone_.Clone(); + } + + public Person Clone() { + return new Person(this); } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { @@ -231,7 +240,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class PhoneNumber : pb::IMessage, global::System.IEquatable { + public sealed partial class PhoneNumber : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PhoneNumber()); public static pb::MessageParser Parser { get { return _parser; } } @@ -246,9 +255,16 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { } public PhoneNumber() { } + public PhoneNumber(PhoneNumber other) { - MergeFrom(other); + number_ = other.number_; + type_ = other.type_; + } + + public PhoneNumber Clone() { + return new PhoneNumber(this); } + public const int NumberFieldNumber = 1; private string number_ = ""; public string Number { @@ -352,7 +368,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class AddressBook : pb::IMessage, global::System.IEquatable { + public sealed partial class AddressBook : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new AddressBook()); public static pb::MessageParser Parser { get { return _parser; } } @@ -367,9 +383,15 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { } public AddressBook() { } + public AddressBook(AddressBook other) { - MergeFrom(other); + person_ = other.person_.Clone(); } + + public AddressBook Clone() { + return new AddressBook(this); + } + public const int PersonFieldNumber = 1; private readonly pbc::RepeatedField person_ = new pbc::RepeatedField(); public pbc::RepeatedField Person { diff --git a/csharp/src/ProtocolBuffers.Test/GeneratedMessageTest.cs b/csharp/src/ProtocolBuffers.Test/GeneratedMessageTest.cs index c5564060d1..e21d904da4 100644 --- a/csharp/src/ProtocolBuffers.Test/GeneratedMessageTest.cs +++ b/csharp/src/ProtocolBuffers.Test/GeneratedMessageTest.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Google.Protobuf.TestProtos; +using Google.Protobuf.TestProtos; using NUnit.Framework; namespace Google.Protobuf @@ -88,7 +83,7 @@ namespace Google.Protobuf var message = new TestAllTypes { SingleBool = true, - SingleBytes = ByteString.CopyFrom(new byte[] { 1, 2, 3, 4 }), + SingleBytes = ByteString.CopyFrom(1, 2, 3, 4), SingleDouble = 23.5, SingleFixed32 = 23, SingleFixed64 = 1234567890123, @@ -122,7 +117,7 @@ namespace Google.Protobuf var message = new TestAllTypes { RepeatedBool = { true, false }, - RepeatedBytes = { ByteString.CopyFrom(new byte[] { 1, 2, 3, 4 }), ByteString.CopyFrom(new byte[] { 5, 6 }) }, + RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) }, RepeatedDouble = { -12.25, 23.5 }, RepeatedFixed32 = { uint.MaxValue, 23 }, RepeatedFixed64 = { ulong.MaxValue, 1234567890123 }, @@ -149,5 +144,118 @@ namespace Google.Protobuf TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes); Assert.AreEqual(message, parsed); } + + [Test] + public void CloneSingleNonMessageValues() + { + var original = new TestAllTypes + { + SingleBool = true, + SingleBytes = ByteString.CopyFrom(1, 2, 3, 4), + SingleDouble = 23.5, + SingleFixed32 = 23, + SingleFixed64 = 1234567890123, + SingleFloat = 12.25f, + SingleInt32 = 100, + SingleInt64 = 3210987654321, + SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO, + SingleSfixed32 = -123, + SingleSfixed64 = -12345678901234, + SingleSint32 = -456, + SingleSint64 = -12345678901235, + SingleString = "test", + SingleUint32 = uint.MaxValue, + SingleUint64 = ulong.MaxValue + }; + var clone = original.Clone(); + Assert.AreNotSame(original, clone); + Assert.AreEqual(original, clone); + // Just as a single example + clone.SingleInt32 = 150; + Assert.AreNotEqual(original, clone); + } + + [Test] + public void CloneRepeatedNonMessageValues() + { + var original = new TestAllTypes + { + RepeatedBool = { true, false }, + RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) }, + RepeatedDouble = { -12.25, 23.5 }, + RepeatedFixed32 = { uint.MaxValue, 23 }, + RepeatedFixed64 = { ulong.MaxValue, 1234567890123 }, + RepeatedFloat = { 100f, 12.25f }, + RepeatedInt32 = { 100, 200 }, + RepeatedInt64 = { 3210987654321, long.MaxValue }, + RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG }, + RepeatedSfixed32 = { -123, 123 }, + RepeatedSfixed64 = { -12345678901234, 12345678901234 }, + RepeatedSint32 = { -456, 100 }, + RepeatedSint64 = { -12345678901235, 123 }, + RepeatedString = { "foo", "bar" }, + RepeatedUint32 = { uint.MaxValue, uint.MinValue }, + RepeatedUint64 = { ulong.MaxValue, uint.MinValue } + }; + + var clone = original.Clone(); + Assert.AreNotSame(original, clone); + Assert.AreEqual(original, clone); + // Just as a single example + clone.RepeatedDouble.Add(25.5); + Assert.AreNotEqual(original, clone); + } + + [Test] + public void CloneSingleMessageField() + { + var original = new TestAllTypes + { + SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 } + }; + + var clone = original.Clone(); + Assert.AreNotSame(original, clone); + Assert.AreNotSame(original.SingleNestedMessage, clone.SingleNestedMessage); + Assert.AreEqual(original, clone); + + clone.SingleNestedMessage.Bb = 30; + Assert.AreNotEqual(original, clone); + } + + [Test] + public void CloneRepeatedMessageField() + { + var original = new TestAllTypes + { + RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 20 } } + }; + + var clone = original.Clone(); + Assert.AreNotSame(original, clone); + Assert.AreNotSame(original.RepeatedNestedMessage, clone.RepeatedNestedMessage); + Assert.AreNotSame(original.RepeatedNestedMessage[0], clone.RepeatedNestedMessage[0]); + Assert.AreEqual(original, clone); + + clone.RepeatedNestedMessage[0].Bb = 30; + Assert.AreNotEqual(original, clone); + } + + [Test] + public void CloneOneofField() + { + var original = new TestAllTypes + { + OneofNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 } + }; + + var clone = original.Clone(); + Assert.AreNotSame(original, clone); + Assert.AreEqual(original, clone); + + // We should have cloned the message + original.OneofNestedMessage.Bb = 30; + Assert.AreNotEqual(original, clone); + } } } diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs index e048f65c4a..0b8a9dd367 100644 --- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs +++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs @@ -60,7 +60,7 @@ namespace Google.Protobuf.TestProtos { #region Messages [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class ImportMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class ImportMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ImportMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -75,9 +75,15 @@ namespace Google.Protobuf.TestProtos { } public ImportMessage() { } + public ImportMessage(ImportMessage other) { - MergeFrom(other); + d_ = other.d_; + } + + public ImportMessage Clone() { + return new ImportMessage(this); } + public const int DFieldNumber = 1; private int d_; public int D { diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs index 5d9f0b7a6e..b634ccff05 100644 --- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs +++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs @@ -45,7 +45,7 @@ namespace Google.Protobuf.TestProtos { } #region Messages [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class PublicImportMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class PublicImportMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PublicImportMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -60,9 +60,15 @@ namespace Google.Protobuf.TestProtos { } public PublicImportMessage() { } + public PublicImportMessage(PublicImportMessage other) { - MergeFrom(other); + e_ = other.e_; + } + + public PublicImportMessage Clone() { + return new PublicImportMessage(this); } + public const int EFieldNumber = 1; private int e_; public int E { diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs index 959b3866af..df14932389 100644 --- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs +++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs @@ -90,7 +90,7 @@ namespace UnitTest.Issues.TestProtos { #region Messages [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class NegativeEnumMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class NegativeEnumMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NegativeEnumMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -105,9 +105,17 @@ namespace UnitTest.Issues.TestProtos { } public NegativeEnumMessage() { } + public NegativeEnumMessage(NegativeEnumMessage other) { - MergeFrom(other); + value_ = other.value_; + values_ = other.values_.Clone(); + packedValues_ = other.packedValues_.Clone(); + } + + public NegativeEnumMessage Clone() { + return new NegativeEnumMessage(this); } + public const int ValueFieldNumber = 1; private global::UnitTest.Issues.TestProtos.NegativeEnum value_ = global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO; public global::UnitTest.Issues.TestProtos.NegativeEnum Value { @@ -233,7 +241,7 @@ namespace UnitTest.Issues.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class DeprecatedChild : pb::IMessage, global::System.IEquatable { + public sealed partial class DeprecatedChild : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DeprecatedChild()); public static pb::MessageParser Parser { get { return _parser; } } @@ -248,9 +256,14 @@ namespace UnitTest.Issues.TestProtos { } public DeprecatedChild() { } + public DeprecatedChild(DeprecatedChild other) { - MergeFrom(other); } + + public DeprecatedChild Clone() { + return new DeprecatedChild(this); + } + public override bool Equals(object other) { return Equals(other as DeprecatedChild); } @@ -301,7 +314,7 @@ namespace UnitTest.Issues.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class DeprecatedFieldsMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class DeprecatedFieldsMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DeprecatedFieldsMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -316,9 +329,20 @@ namespace UnitTest.Issues.TestProtos { } public DeprecatedFieldsMessage() { } + public DeprecatedFieldsMessage(DeprecatedFieldsMessage other) { - MergeFrom(other); + primitiveValue_ = other.primitiveValue_; + primitiveArray_ = other.primitiveArray_.Clone(); + MessageValue = other.messageValue_ != null ? other.MessageValue.Clone() : null; + messageArray_ = other.messageArray_.Clone(); + enumValue_ = other.enumValue_; + enumArray_ = other.enumArray_.Clone(); + } + + public DeprecatedFieldsMessage Clone() { + return new DeprecatedFieldsMessage(this); } + public const int PrimitiveValueFieldNumber = 1; private int primitiveValue_; [global::System.ObsoleteAttribute()] @@ -525,7 +549,7 @@ namespace UnitTest.Issues.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class ItemField : pb::IMessage, global::System.IEquatable { + public sealed partial class ItemField : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ItemField()); public static pb::MessageParser Parser { get { return _parser; } } @@ -540,9 +564,15 @@ namespace UnitTest.Issues.TestProtos { } public ItemField() { } + public ItemField(ItemField other) { - MergeFrom(other); + item_ = other.item_; + } + + public ItemField Clone() { + return new ItemField(this); } + public const int ItemFieldNumber = 1; private int item_; public int Item { diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs index bbfa8c3e94..1fab673705 100644 --- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs +++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs @@ -402,7 +402,7 @@ namespace Google.Protobuf.TestProtos { #region Messages [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestAllTypes : pb::IMessage, global::System.IEquatable { + public sealed partial class TestAllTypes : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestAllTypes()); public static pb::MessageParser Parser { get { return _parser; } } @@ -417,9 +417,73 @@ namespace Google.Protobuf.TestProtos { } public TestAllTypes() { } + public TestAllTypes(TestAllTypes other) { - MergeFrom(other); + singleInt32_ = other.singleInt32_; + singleInt64_ = other.singleInt64_; + singleUint32_ = other.singleUint32_; + singleUint64_ = other.singleUint64_; + singleSint32_ = other.singleSint32_; + singleSint64_ = other.singleSint64_; + singleFixed32_ = other.singleFixed32_; + singleFixed64_ = other.singleFixed64_; + singleSfixed32_ = other.singleSfixed32_; + singleSfixed64_ = other.singleSfixed64_; + singleFloat_ = other.singleFloat_; + singleDouble_ = other.singleDouble_; + singleBool_ = other.singleBool_; + singleString_ = other.singleString_; + singleBytes_ = other.singleBytes_; + SingleNestedMessage = other.singleNestedMessage_ != null ? other.SingleNestedMessage.Clone() : null; + SingleForeignMessage = other.singleForeignMessage_ != null ? other.SingleForeignMessage.Clone() : null; + SingleImportMessage = other.singleImportMessage_ != null ? other.SingleImportMessage.Clone() : null; + singleNestedEnum_ = other.singleNestedEnum_; + singleForeignEnum_ = other.singleForeignEnum_; + singleImportEnum_ = other.singleImportEnum_; + SinglePublicImportMessage = other.singlePublicImportMessage_ != null ? other.SinglePublicImportMessage.Clone() : null; + repeatedInt32_ = other.repeatedInt32_.Clone(); + repeatedInt64_ = other.repeatedInt64_.Clone(); + repeatedUint32_ = other.repeatedUint32_.Clone(); + repeatedUint64_ = other.repeatedUint64_.Clone(); + repeatedSint32_ = other.repeatedSint32_.Clone(); + repeatedSint64_ = other.repeatedSint64_.Clone(); + repeatedFixed32_ = other.repeatedFixed32_.Clone(); + repeatedFixed64_ = other.repeatedFixed64_.Clone(); + repeatedSfixed32_ = other.repeatedSfixed32_.Clone(); + repeatedSfixed64_ = other.repeatedSfixed64_.Clone(); + repeatedFloat_ = other.repeatedFloat_.Clone(); + repeatedDouble_ = other.repeatedDouble_.Clone(); + repeatedBool_ = other.repeatedBool_.Clone(); + repeatedString_ = other.repeatedString_.Clone(); + repeatedBytes_ = other.repeatedBytes_.Clone(); + repeatedNestedMessage_ = other.repeatedNestedMessage_.Clone(); + repeatedForeignMessage_ = other.repeatedForeignMessage_.Clone(); + repeatedImportMessage_ = other.repeatedImportMessage_.Clone(); + repeatedNestedEnum_ = other.repeatedNestedEnum_.Clone(); + repeatedForeignEnum_ = other.repeatedForeignEnum_.Clone(); + repeatedImportEnum_ = other.repeatedImportEnum_.Clone(); + repeatedPublicImportMessage_ = other.repeatedPublicImportMessage_.Clone(); + switch (other.OneofFieldCase) { + case OneofFieldOneofCase.OneofUint32: + OneofUint32 = other.OneofUint32; + break; + case OneofFieldOneofCase.OneofNestedMessage: + OneofNestedMessage = other.OneofNestedMessage.Clone(); + break; + case OneofFieldOneofCase.OneofString: + OneofString = other.OneofString; + break; + case OneofFieldOneofCase.OneofBytes: + OneofBytes = other.OneofBytes; + break; + } + + } + + public TestAllTypes Clone() { + return new TestAllTypes(this); } + public const int SingleInt32FieldNumber = 1; private int singleInt32_; public int SingleInt32 { @@ -1686,7 +1750,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class NestedMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class NestedMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -1701,9 +1765,15 @@ namespace Google.Protobuf.TestProtos { } public NestedMessage() { } + public NestedMessage(NestedMessage other) { - MergeFrom(other); + bb_ = other.bb_; + } + + public NestedMessage Clone() { + return new NestedMessage(this); } + public const int BbFieldNumber = 1; private int bb_; public int Bb { @@ -1783,7 +1853,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class NestedTestAllTypes : pb::IMessage, global::System.IEquatable { + public sealed partial class NestedTestAllTypes : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedTestAllTypes()); public static pb::MessageParser Parser { get { return _parser; } } @@ -1798,9 +1868,17 @@ namespace Google.Protobuf.TestProtos { } public NestedTestAllTypes() { } + public NestedTestAllTypes(NestedTestAllTypes other) { - MergeFrom(other); + Child = other.child_ != null ? other.Child.Clone() : null; + Payload = other.payload_ != null ? other.Payload.Clone() : null; + repeatedChild_ = other.repeatedChild_.Clone(); } + + public NestedTestAllTypes Clone() { + return new NestedTestAllTypes(this); + } + public const int ChildFieldNumber = 1; private global::Google.Protobuf.TestProtos.NestedTestAllTypes child_; public global::Google.Protobuf.TestProtos.NestedTestAllTypes Child { @@ -1929,7 +2007,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestDeprecatedFields : pb::IMessage, global::System.IEquatable { + public sealed partial class TestDeprecatedFields : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestDeprecatedFields()); public static pb::MessageParser Parser { get { return _parser; } } @@ -1944,9 +2022,15 @@ namespace Google.Protobuf.TestProtos { } public TestDeprecatedFields() { } + public TestDeprecatedFields(TestDeprecatedFields other) { - MergeFrom(other); + deprecatedInt32_ = other.deprecatedInt32_; + } + + public TestDeprecatedFields Clone() { + return new TestDeprecatedFields(this); } + public const int DeprecatedInt32FieldNumber = 1; private int deprecatedInt32_; [global::System.ObsoleteAttribute()] @@ -2022,7 +2106,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class ForeignMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class ForeignMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ForeignMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2037,9 +2121,15 @@ namespace Google.Protobuf.TestProtos { } public ForeignMessage() { } + public ForeignMessage(ForeignMessage other) { - MergeFrom(other); + c_ = other.c_; } + + public ForeignMessage Clone() { + return new ForeignMessage(this); + } + public const int CFieldNumber = 1; private int c_; public int C { @@ -2114,7 +2204,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestReservedFields : pb::IMessage, global::System.IEquatable { + public sealed partial class TestReservedFields : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestReservedFields()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2129,9 +2219,14 @@ namespace Google.Protobuf.TestProtos { } public TestReservedFields() { } + public TestReservedFields(TestReservedFields other) { - MergeFrom(other); } + + public TestReservedFields Clone() { + return new TestReservedFields(this); + } + public override bool Equals(object other) { return Equals(other as TestReservedFields); } @@ -2182,7 +2277,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestForeignNested : pb::IMessage, global::System.IEquatable { + public sealed partial class TestForeignNested : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestForeignNested()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2197,9 +2292,15 @@ namespace Google.Protobuf.TestProtos { } public TestForeignNested() { } + public TestForeignNested(TestForeignNested other) { - MergeFrom(other); + ForeignNested = other.foreignNested_ != null ? other.ForeignNested.Clone() : null; + } + + public TestForeignNested Clone() { + return new TestForeignNested(this); } + public const int ForeignNestedFieldNumber = 1; private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage foreignNested_; public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage ForeignNested { @@ -2278,7 +2379,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestReallyLargeTagNumber : pb::IMessage, global::System.IEquatable { + public sealed partial class TestReallyLargeTagNumber : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestReallyLargeTagNumber()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2293,9 +2394,16 @@ namespace Google.Protobuf.TestProtos { } public TestReallyLargeTagNumber() { } + public TestReallyLargeTagNumber(TestReallyLargeTagNumber other) { - MergeFrom(other); + a_ = other.a_; + bb_ = other.bb_; } + + public TestReallyLargeTagNumber Clone() { + return new TestReallyLargeTagNumber(this); + } + public const int AFieldNumber = 1; private int a_; public int A { @@ -2394,7 +2502,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestRecursiveMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class TestRecursiveMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestRecursiveMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2409,9 +2517,16 @@ namespace Google.Protobuf.TestProtos { } public TestRecursiveMessage() { } + public TestRecursiveMessage(TestRecursiveMessage other) { - MergeFrom(other); + A = other.a_ != null ? other.A.Clone() : null; + i_ = other.i_; + } + + public TestRecursiveMessage Clone() { + return new TestRecursiveMessage(this); } + public const int AFieldNumber = 1; private global::Google.Protobuf.TestProtos.TestRecursiveMessage a_; public global::Google.Protobuf.TestProtos.TestRecursiveMessage A { @@ -2514,7 +2629,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestMutualRecursionA : pb::IMessage, global::System.IEquatable { + public sealed partial class TestMutualRecursionA : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestMutualRecursionA()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2529,9 +2644,15 @@ namespace Google.Protobuf.TestProtos { } public TestMutualRecursionA() { } + public TestMutualRecursionA(TestMutualRecursionA other) { - MergeFrom(other); + Bb = other.bb_ != null ? other.Bb.Clone() : null; } + + public TestMutualRecursionA Clone() { + return new TestMutualRecursionA(this); + } + public const int BbFieldNumber = 1; private global::Google.Protobuf.TestProtos.TestMutualRecursionB bb_; public global::Google.Protobuf.TestProtos.TestMutualRecursionB Bb { @@ -2610,7 +2731,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestMutualRecursionB : pb::IMessage, global::System.IEquatable { + public sealed partial class TestMutualRecursionB : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestMutualRecursionB()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2625,9 +2746,16 @@ namespace Google.Protobuf.TestProtos { } public TestMutualRecursionB() { } + public TestMutualRecursionB(TestMutualRecursionB other) { - MergeFrom(other); + A = other.a_ != null ? other.A.Clone() : null; + optionalInt32_ = other.optionalInt32_; + } + + public TestMutualRecursionB Clone() { + return new TestMutualRecursionB(this); } + public const int AFieldNumber = 1; private global::Google.Protobuf.TestProtos.TestMutualRecursionA a_; public global::Google.Protobuf.TestProtos.TestMutualRecursionA A { @@ -2730,7 +2858,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestCamelCaseFieldNames : pb::IMessage, global::System.IEquatable { + public sealed partial class TestCamelCaseFieldNames : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestCamelCaseFieldNames()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2745,9 +2873,22 @@ namespace Google.Protobuf.TestProtos { } public TestCamelCaseFieldNames() { } + public TestCamelCaseFieldNames(TestCamelCaseFieldNames other) { - MergeFrom(other); + primitiveField_ = other.primitiveField_; + stringField_ = other.stringField_; + enumField_ = other.enumField_; + MessageField = other.messageField_ != null ? other.MessageField.Clone() : null; + repeatedPrimitiveField_ = other.repeatedPrimitiveField_.Clone(); + repeatedStringField_ = other.repeatedStringField_.Clone(); + repeatedEnumField_ = other.repeatedEnumField_.Clone(); + repeatedMessageField_ = other.repeatedMessageField_.Clone(); + } + + public TestCamelCaseFieldNames Clone() { + return new TestCamelCaseFieldNames(this); } + public const int PrimitiveFieldFieldNumber = 1; private int primitiveField_; public int PrimitiveField { @@ -2996,7 +3137,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestFieldOrderings : pb::IMessage, global::System.IEquatable { + public sealed partial class TestFieldOrderings : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestFieldOrderings()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3011,9 +3152,18 @@ namespace Google.Protobuf.TestProtos { } public TestFieldOrderings() { } + public TestFieldOrderings(TestFieldOrderings other) { - MergeFrom(other); + myString_ = other.myString_; + myInt_ = other.myInt_; + myFloat_ = other.myFloat_; + SingleNestedMessage = other.singleNestedMessage_ != null ? other.SingleNestedMessage.Clone() : null; } + + public TestFieldOrderings Clone() { + return new TestFieldOrderings(this); + } + public const int MyStringFieldNumber = 11; private string myString_ = ""; public string MyString { @@ -3165,7 +3315,7 @@ namespace Google.Protobuf.TestProtos { [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class Types { [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class NestedMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class NestedMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3180,9 +3330,16 @@ namespace Google.Protobuf.TestProtos { } public NestedMessage() { } + public NestedMessage(NestedMessage other) { - MergeFrom(other); + oo_ = other.oo_; + bb_ = other.bb_; + } + + public NestedMessage Clone() { + return new NestedMessage(this); } + public const int OoFieldNumber = 2; private long oo_; public long Oo { @@ -3286,7 +3443,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class SparseEnumMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class SparseEnumMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SparseEnumMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3301,9 +3458,15 @@ namespace Google.Protobuf.TestProtos { } public SparseEnumMessage() { } + public SparseEnumMessage(SparseEnumMessage other) { - MergeFrom(other); + sparseEnum_ = other.sparseEnum_; } + + public SparseEnumMessage Clone() { + return new SparseEnumMessage(this); + } + public const int SparseEnumFieldNumber = 1; private global::Google.Protobuf.TestProtos.TestSparseEnum sparseEnum_ = global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED; public global::Google.Protobuf.TestProtos.TestSparseEnum SparseEnum { @@ -3378,7 +3541,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class OneString : pb::IMessage, global::System.IEquatable { + public sealed partial class OneString : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneString()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3393,9 +3556,15 @@ namespace Google.Protobuf.TestProtos { } public OneString() { } + public OneString(OneString other) { - MergeFrom(other); + data_ = other.data_; + } + + public OneString Clone() { + return new OneString(this); } + public const int DataFieldNumber = 1; private string data_ = ""; public string Data { @@ -3470,7 +3639,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class MoreString : pb::IMessage, global::System.IEquatable { + public sealed partial class MoreString : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MoreString()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3485,9 +3654,15 @@ namespace Google.Protobuf.TestProtos { } public MoreString() { } + public MoreString(MoreString other) { - MergeFrom(other); + data_ = other.data_.Clone(); + } + + public MoreString Clone() { + return new MoreString(this); } + public const int DataFieldNumber = 1; private readonly pbc::RepeatedField data_ = new pbc::RepeatedField(); public pbc::RepeatedField Data { @@ -3562,7 +3737,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class OneBytes : pb::IMessage, global::System.IEquatable { + public sealed partial class OneBytes : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneBytes()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3577,9 +3752,15 @@ namespace Google.Protobuf.TestProtos { } public OneBytes() { } + public OneBytes(OneBytes other) { - MergeFrom(other); + data_ = other.data_; } + + public OneBytes Clone() { + return new OneBytes(this); + } + public const int DataFieldNumber = 1; private pb::ByteString data_ = pb::ByteString.Empty; public pb::ByteString Data { @@ -3654,7 +3835,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class MoreBytes : pb::IMessage, global::System.IEquatable { + public sealed partial class MoreBytes : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MoreBytes()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3669,9 +3850,15 @@ namespace Google.Protobuf.TestProtos { } public MoreBytes() { } + public MoreBytes(MoreBytes other) { - MergeFrom(other); + data_ = other.data_; + } + + public MoreBytes Clone() { + return new MoreBytes(this); } + public const int DataFieldNumber = 1; private pb::ByteString data_ = pb::ByteString.Empty; public pb::ByteString Data { @@ -3746,7 +3933,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Int32Message : pb::IMessage, global::System.IEquatable { + public sealed partial class Int32Message : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Int32Message()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3761,9 +3948,15 @@ namespace Google.Protobuf.TestProtos { } public Int32Message() { } + public Int32Message(Int32Message other) { - MergeFrom(other); + data_ = other.data_; } + + public Int32Message Clone() { + return new Int32Message(this); + } + public const int DataFieldNumber = 1; private int data_; public int Data { @@ -3838,7 +4031,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Uint32Message : pb::IMessage, global::System.IEquatable { + public sealed partial class Uint32Message : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Uint32Message()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3853,9 +4046,15 @@ namespace Google.Protobuf.TestProtos { } public Uint32Message() { } + public Uint32Message(Uint32Message other) { - MergeFrom(other); + data_ = other.data_; + } + + public Uint32Message Clone() { + return new Uint32Message(this); } + public const int DataFieldNumber = 1; private uint data_; public uint Data { @@ -3930,7 +4129,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Int64Message : pb::IMessage, global::System.IEquatable { + public sealed partial class Int64Message : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Int64Message()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3945,9 +4144,15 @@ namespace Google.Protobuf.TestProtos { } public Int64Message() { } + public Int64Message(Int64Message other) { - MergeFrom(other); + data_ = other.data_; + } + + public Int64Message Clone() { + return new Int64Message(this); } + public const int DataFieldNumber = 1; private long data_; public long Data { @@ -4022,7 +4227,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Uint64Message : pb::IMessage, global::System.IEquatable { + public sealed partial class Uint64Message : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Uint64Message()); public static pb::MessageParser Parser { get { return _parser; } } @@ -4037,9 +4242,15 @@ namespace Google.Protobuf.TestProtos { } public Uint64Message() { } + public Uint64Message(Uint64Message other) { - MergeFrom(other); + data_ = other.data_; } + + public Uint64Message Clone() { + return new Uint64Message(this); + } + public const int DataFieldNumber = 1; private ulong data_; public ulong Data { @@ -4114,7 +4325,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class BoolMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class BoolMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BoolMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -4129,9 +4340,15 @@ namespace Google.Protobuf.TestProtos { } public BoolMessage() { } + public BoolMessage(BoolMessage other) { - MergeFrom(other); + data_ = other.data_; + } + + public BoolMessage Clone() { + return new BoolMessage(this); } + public const int DataFieldNumber = 1; private bool data_; public bool Data { @@ -4206,7 +4423,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestOneof : pb::IMessage, global::System.IEquatable { + public sealed partial class TestOneof : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestOneof()); public static pb::MessageParser Parser { get { return _parser; } } @@ -4221,9 +4438,26 @@ namespace Google.Protobuf.TestProtos { } public TestOneof() { } + public TestOneof(TestOneof other) { - MergeFrom(other); + switch (other.FooCase) { + case FooOneofCase.FooInt: + FooInt = other.FooInt; + break; + case FooOneofCase.FooString: + FooString = other.FooString; + break; + case FooOneofCase.FooMessage: + FooMessage = other.FooMessage.Clone(); + break; + } + + } + + public TestOneof Clone() { + return new TestOneof(this); } + public const int FooIntFieldNumber = 1; public int FooInt { get { return fooCase_ == FooOneofCase.FooInt ? (int) foo_ : 0; } @@ -4373,7 +4607,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestPackedTypes : pb::IMessage, global::System.IEquatable { + public sealed partial class TestPackedTypes : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestPackedTypes()); public static pb::MessageParser Parser { get { return _parser; } } @@ -4388,9 +4622,28 @@ namespace Google.Protobuf.TestProtos { } public TestPackedTypes() { } + public TestPackedTypes(TestPackedTypes other) { - MergeFrom(other); + packedInt32_ = other.packedInt32_.Clone(); + packedInt64_ = other.packedInt64_.Clone(); + packedUint32_ = other.packedUint32_.Clone(); + packedUint64_ = other.packedUint64_.Clone(); + packedSint32_ = other.packedSint32_.Clone(); + packedSint64_ = other.packedSint64_.Clone(); + packedFixed32_ = other.packedFixed32_.Clone(); + packedFixed64_ = other.packedFixed64_.Clone(); + packedSfixed32_ = other.packedSfixed32_.Clone(); + packedSfixed64_ = other.packedSfixed64_.Clone(); + packedFloat_ = other.packedFloat_.Clone(); + packedDouble_ = other.packedDouble_.Clone(); + packedBool_ = other.packedBool_.Clone(); + packedEnum_ = other.packedEnum_.Clone(); + } + + public TestPackedTypes Clone() { + return new TestPackedTypes(this); } + public const int PackedInt32FieldNumber = 90; private readonly pbc::RepeatedField packedInt32_ = new pbc::RepeatedField(); public pbc::RepeatedField PackedInt32 { @@ -4791,7 +5044,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestUnpackedTypes : pb::IMessage, global::System.IEquatable { + public sealed partial class TestUnpackedTypes : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestUnpackedTypes()); public static pb::MessageParser Parser { get { return _parser; } } @@ -4806,9 +5059,28 @@ namespace Google.Protobuf.TestProtos { } public TestUnpackedTypes() { } + public TestUnpackedTypes(TestUnpackedTypes other) { - MergeFrom(other); + unpackedInt32_ = other.unpackedInt32_.Clone(); + unpackedInt64_ = other.unpackedInt64_.Clone(); + unpackedUint32_ = other.unpackedUint32_.Clone(); + unpackedUint64_ = other.unpackedUint64_.Clone(); + unpackedSint32_ = other.unpackedSint32_.Clone(); + unpackedSint64_ = other.unpackedSint64_.Clone(); + unpackedFixed32_ = other.unpackedFixed32_.Clone(); + unpackedFixed64_ = other.unpackedFixed64_.Clone(); + unpackedSfixed32_ = other.unpackedSfixed32_.Clone(); + unpackedSfixed64_ = other.unpackedSfixed64_.Clone(); + unpackedFloat_ = other.unpackedFloat_.Clone(); + unpackedDouble_ = other.unpackedDouble_.Clone(); + unpackedBool_ = other.unpackedBool_.Clone(); + unpackedEnum_ = other.unpackedEnum_.Clone(); + } + + public TestUnpackedTypes Clone() { + return new TestUnpackedTypes(this); } + public const int UnpackedInt32FieldNumber = 90; private readonly pbc::RepeatedField unpackedInt32_ = new pbc::RepeatedField(); public pbc::RepeatedField UnpackedInt32 { @@ -5195,7 +5467,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestRepeatedScalarDifferentTagSizes : pb::IMessage, global::System.IEquatable { + public sealed partial class TestRepeatedScalarDifferentTagSizes : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestRepeatedScalarDifferentTagSizes()); public static pb::MessageParser Parser { get { return _parser; } } @@ -5210,9 +5482,20 @@ namespace Google.Protobuf.TestProtos { } public TestRepeatedScalarDifferentTagSizes() { } + public TestRepeatedScalarDifferentTagSizes(TestRepeatedScalarDifferentTagSizes other) { - MergeFrom(other); + repeatedFixed32_ = other.repeatedFixed32_.Clone(); + repeatedInt32_ = other.repeatedInt32_.Clone(); + repeatedFixed64_ = other.repeatedFixed64_.Clone(); + repeatedInt64_ = other.repeatedInt64_.Clone(); + repeatedFloat_ = other.repeatedFloat_.Clone(); + repeatedUint64_ = other.repeatedUint64_.Clone(); + } + + public TestRepeatedScalarDifferentTagSizes Clone() { + return new TestRepeatedScalarDifferentTagSizes(this); } + public const int RepeatedFixed32FieldNumber = 12; private readonly pbc::RepeatedField repeatedFixed32_ = new pbc::RepeatedField(); public pbc::RepeatedField RepeatedFixed32 { @@ -5413,7 +5696,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class TestCommentInjectionMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class TestCommentInjectionMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestCommentInjectionMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -5428,9 +5711,15 @@ namespace Google.Protobuf.TestProtos { } public TestCommentInjectionMessage() { } + public TestCommentInjectionMessage(TestCommentInjectionMessage other) { - MergeFrom(other); + a_ = other.a_; + } + + public TestCommentInjectionMessage Clone() { + return new TestCommentInjectionMessage(this); } + public const int AFieldNumber = 1; private string a_ = ""; public string A { @@ -5505,7 +5794,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class FooRequest : pb::IMessage, global::System.IEquatable { + public sealed partial class FooRequest : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooRequest()); public static pb::MessageParser Parser { get { return _parser; } } @@ -5520,9 +5809,14 @@ namespace Google.Protobuf.TestProtos { } public FooRequest() { } + public FooRequest(FooRequest other) { - MergeFrom(other); } + + public FooRequest Clone() { + return new FooRequest(this); + } + public override bool Equals(object other) { return Equals(other as FooRequest); } @@ -5573,7 +5867,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class FooResponse : pb::IMessage, global::System.IEquatable { + public sealed partial class FooResponse : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooResponse()); public static pb::MessageParser Parser { get { return _parser; } } @@ -5588,9 +5882,14 @@ namespace Google.Protobuf.TestProtos { } public FooResponse() { } + public FooResponse(FooResponse other) { - MergeFrom(other); } + + public FooResponse Clone() { + return new FooResponse(this); + } + public override bool Equals(object other) { return Equals(other as FooResponse); } @@ -5641,7 +5940,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class FooClientMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class FooClientMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooClientMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -5656,9 +5955,14 @@ namespace Google.Protobuf.TestProtos { } public FooClientMessage() { } + public FooClientMessage(FooClientMessage other) { - MergeFrom(other); } + + public FooClientMessage Clone() { + return new FooClientMessage(this); + } + public override bool Equals(object other) { return Equals(other as FooClientMessage); } @@ -5709,7 +6013,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class FooServerMessage : pb::IMessage, global::System.IEquatable { + public sealed partial class FooServerMessage : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooServerMessage()); public static pb::MessageParser Parser { get { return _parser; } } @@ -5724,9 +6028,14 @@ namespace Google.Protobuf.TestProtos { } public FooServerMessage() { } + public FooServerMessage(FooServerMessage other) { - MergeFrom(other); } + + public FooServerMessage Clone() { + return new FooServerMessage(this); + } + public override bool Equals(object other) { return Equals(other as FooServerMessage); } @@ -5777,7 +6086,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class BarRequest : pb::IMessage, global::System.IEquatable { + public sealed partial class BarRequest : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BarRequest()); public static pb::MessageParser Parser { get { return _parser; } } @@ -5792,9 +6101,14 @@ namespace Google.Protobuf.TestProtos { } public BarRequest() { } + public BarRequest(BarRequest other) { - MergeFrom(other); } + + public BarRequest Clone() { + return new BarRequest(this); + } + public override bool Equals(object other) { return Equals(other as BarRequest); } @@ -5845,7 +6159,7 @@ namespace Google.Protobuf.TestProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class BarResponse : pb::IMessage, global::System.IEquatable { + public sealed partial class BarResponse : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BarResponse()); public static pb::MessageParser Parser { get { return _parser; } } @@ -5860,9 +6174,14 @@ namespace Google.Protobuf.TestProtos { } public BarResponse() { } + public BarResponse(BarResponse other) { - MergeFrom(other); } + + public BarResponse Clone() { + return new BarResponse(this); + } + public override bool Equals(object other) { return Equals(other as BarResponse); } diff --git a/csharp/src/ProtocolBuffers/ByteString.cs b/csharp/src/ProtocolBuffers/ByteString.cs index 000914f08b..e3a7ee50a4 100644 --- a/csharp/src/ProtocolBuffers/ByteString.cs +++ b/csharp/src/ProtocolBuffers/ByteString.cs @@ -139,7 +139,7 @@ namespace Google.Protobuf /// are copied, so further modifications to the array will not /// be reflected in the returned ByteString. /// - public static ByteString CopyFrom(byte[] bytes) + public static ByteString CopyFrom(params byte[] bytes) { return new ByteString((byte[]) bytes.Clone()); } diff --git a/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs b/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs index 256517842b..5100e4dbb7 100644 --- a/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs +++ b/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs @@ -12,6 +12,36 @@ namespace Google.Protobuf.Collections private T[] array = EmptyArray; private int count = 0; + /// + /// Creates a deep clone of this repeated field. + /// + /// + /// If the field type is + /// a message type, each element is also cloned; otherwise, it is + /// assumed that the field type is primitive (including string and + /// bytes, both of which are immutable) and so a simple copy is + /// equivalent to a deep clone. + /// + /// A deep clone of this repeated field. + public RepeatedField Clone() + { + RepeatedField clone = new RepeatedField(); + if (array != EmptyArray) + { + clone.array = (T[])array.Clone(); + IDeepCloneable[] cloneableArray = clone.array as IDeepCloneable[]; + if (cloneableArray != null) + { + for (int i = 0; i < count; i++) + { + clone.array[i] = cloneableArray[i].Clone(); + } + } + } + clone.count = count; + return clone; + } + private void EnsureSize(int size) { size = Math.Max(size, MinArraySize); diff --git a/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs b/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs index 7b7abd8e72..0b966aea9b 100644 --- a/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs +++ b/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs @@ -278,7 +278,7 @@ namespace Google.Protobuf.DescriptorProtos { } #region Messages [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class FileDescriptorSet : pb::IMessage, global::System.IEquatable { + public sealed partial class FileDescriptorSet : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FileDescriptorSet()); public static pb::MessageParser Parser { get { return _parser; } } @@ -293,9 +293,15 @@ namespace Google.Protobuf.DescriptorProtos { } public FileDescriptorSet() { } + public FileDescriptorSet(FileDescriptorSet other) { - MergeFrom(other); + file_ = other.file_.Clone(); + } + + public FileDescriptorSet Clone() { + return new FileDescriptorSet(this); } + public const int FileFieldNumber = 1; private readonly pbc::RepeatedField file_ = new pbc::RepeatedField(); public pbc::RepeatedField File { @@ -368,7 +374,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class FileDescriptorProto : pb::IMessage, global::System.IEquatable { + public sealed partial class FileDescriptorProto : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FileDescriptorProto()); public static pb::MessageParser Parser { get { return _parser; } } @@ -383,9 +389,26 @@ namespace Google.Protobuf.DescriptorProtos { } public FileDescriptorProto() { } + public FileDescriptorProto(FileDescriptorProto other) { - MergeFrom(other); + name_ = other.name_; + package_ = other.package_; + dependency_ = other.dependency_.Clone(); + publicDependency_ = other.publicDependency_.Clone(); + weakDependency_ = other.weakDependency_.Clone(); + messageType_ = other.messageType_.Clone(); + enumType_ = other.enumType_.Clone(); + service_ = other.service_.Clone(); + extension_ = other.extension_.Clone(); + Options = other.options_ != null ? other.Options.Clone() : null; + SourceCodeInfo = other.sourceCodeInfo_ != null ? other.SourceCodeInfo.Clone() : null; + syntax_ = other.syntax_; } + + public FileDescriptorProto Clone() { + return new FileDescriptorProto(this); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { @@ -726,7 +749,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class DescriptorProto : pb::IMessage, global::System.IEquatable { + public sealed partial class DescriptorProto : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DescriptorProto()); public static pb::MessageParser Parser { get { return _parser; } } @@ -741,9 +764,24 @@ namespace Google.Protobuf.DescriptorProtos { } public DescriptorProto() { } + public DescriptorProto(DescriptorProto other) { - MergeFrom(other); + name_ = other.name_; + field_ = other.field_.Clone(); + extension_ = other.extension_.Clone(); + nestedType_ = other.nestedType_.Clone(); + enumType_ = other.enumType_.Clone(); + extensionRange_ = other.extensionRange_.Clone(); + oneofDecl_ = other.oneofDecl_.Clone(); + Options = other.options_ != null ? other.Options.Clone() : null; + reservedRange_ = other.reservedRange_.Clone(); + reservedName_ = other.reservedName_.Clone(); + } + + public DescriptorProto Clone() { + return new DescriptorProto(this); } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { @@ -1025,7 +1063,7 @@ namespace Google.Protobuf.DescriptorProtos { [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class Types { [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class ExtensionRange : pb::IMessage, global::System.IEquatable { + public sealed partial class ExtensionRange : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ExtensionRange()); public static pb::MessageParser Parser { get { return _parser; } } @@ -1040,9 +1078,16 @@ namespace Google.Protobuf.DescriptorProtos { } public ExtensionRange() { } + public ExtensionRange(ExtensionRange other) { - MergeFrom(other); + start_ = other.start_; + end_ = other.end_; + } + + public ExtensionRange Clone() { + return new ExtensionRange(this); } + public const int StartFieldNumber = 1; private int start_; public int Start { @@ -1141,7 +1186,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class ReservedRange : pb::IMessage, global::System.IEquatable { + public sealed partial class ReservedRange : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ReservedRange()); public static pb::MessageParser Parser { get { return _parser; } } @@ -1156,9 +1201,16 @@ namespace Google.Protobuf.DescriptorProtos { } public ReservedRange() { } + public ReservedRange(ReservedRange other) { - MergeFrom(other); + start_ = other.start_; + end_ = other.end_; } + + public ReservedRange Clone() { + return new ReservedRange(this); + } + public const int StartFieldNumber = 1; private int start_; public int Start { @@ -1262,7 +1314,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class FieldDescriptorProto : pb::IMessage, global::System.IEquatable { + public sealed partial class FieldDescriptorProto : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FieldDescriptorProto()); public static pb::MessageParser Parser { get { return _parser; } } @@ -1277,9 +1329,23 @@ namespace Google.Protobuf.DescriptorProtos { } public FieldDescriptorProto() { } + public FieldDescriptorProto(FieldDescriptorProto other) { - MergeFrom(other); + name_ = other.name_; + number_ = other.number_; + label_ = other.label_; + type_ = other.type_; + typeName_ = other.typeName_; + extendee_ = other.extendee_; + defaultValue_ = other.defaultValue_; + oneofIndex_ = other.oneofIndex_; + Options = other.options_ != null ? other.Options.Clone() : null; } + + public FieldDescriptorProto Clone() { + return new FieldDescriptorProto(this); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { @@ -1583,7 +1649,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class OneofDescriptorProto : pb::IMessage, global::System.IEquatable { + public sealed partial class OneofDescriptorProto : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneofDescriptorProto()); public static pb::MessageParser Parser { get { return _parser; } } @@ -1598,9 +1664,15 @@ namespace Google.Protobuf.DescriptorProtos { } public OneofDescriptorProto() { } + public OneofDescriptorProto(OneofDescriptorProto other) { - MergeFrom(other); + name_ = other.name_; } + + public OneofDescriptorProto Clone() { + return new OneofDescriptorProto(this); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { @@ -1675,7 +1747,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class EnumDescriptorProto : pb::IMessage, global::System.IEquatable { + public sealed partial class EnumDescriptorProto : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumDescriptorProto()); public static pb::MessageParser Parser { get { return _parser; } } @@ -1690,9 +1762,17 @@ namespace Google.Protobuf.DescriptorProtos { } public EnumDescriptorProto() { } + public EnumDescriptorProto(EnumDescriptorProto other) { - MergeFrom(other); + name_ = other.name_; + value_ = other.value_.Clone(); + Options = other.options_ != null ? other.Options.Clone() : null; + } + + public EnumDescriptorProto Clone() { + return new EnumDescriptorProto(this); } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { @@ -1817,7 +1897,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class EnumValueDescriptorProto : pb::IMessage, global::System.IEquatable { + public sealed partial class EnumValueDescriptorProto : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumValueDescriptorProto()); public static pb::MessageParser Parser { get { return _parser; } } @@ -1832,9 +1912,17 @@ namespace Google.Protobuf.DescriptorProtos { } public EnumValueDescriptorProto() { } + public EnumValueDescriptorProto(EnumValueDescriptorProto other) { - MergeFrom(other); + name_ = other.name_; + number_ = other.number_; + Options = other.options_ != null ? other.Options.Clone() : null; } + + public EnumValueDescriptorProto Clone() { + return new EnumValueDescriptorProto(this); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { @@ -1961,7 +2049,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class ServiceDescriptorProto : pb::IMessage, global::System.IEquatable { + public sealed partial class ServiceDescriptorProto : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServiceDescriptorProto()); public static pb::MessageParser Parser { get { return _parser; } } @@ -1976,9 +2064,17 @@ namespace Google.Protobuf.DescriptorProtos { } public ServiceDescriptorProto() { } + public ServiceDescriptorProto(ServiceDescriptorProto other) { - MergeFrom(other); + name_ = other.name_; + method_ = other.method_.Clone(); + Options = other.options_ != null ? other.Options.Clone() : null; + } + + public ServiceDescriptorProto Clone() { + return new ServiceDescriptorProto(this); } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { @@ -2103,7 +2199,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class MethodDescriptorProto : pb::IMessage, global::System.IEquatable { + public sealed partial class MethodDescriptorProto : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MethodDescriptorProto()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2118,9 +2214,20 @@ namespace Google.Protobuf.DescriptorProtos { } public MethodDescriptorProto() { } + public MethodDescriptorProto(MethodDescriptorProto other) { - MergeFrom(other); + name_ = other.name_; + inputType_ = other.inputType_; + outputType_ = other.outputType_; + Options = other.options_ != null ? other.Options.Clone() : null; + clientStreaming_ = other.clientStreaming_; + serverStreaming_ = other.serverStreaming_; + } + + public MethodDescriptorProto Clone() { + return new MethodDescriptorProto(this); } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { @@ -2319,7 +2426,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class FileOptions : pb::IMessage, global::System.IEquatable { + public sealed partial class FileOptions : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FileOptions()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2334,9 +2441,29 @@ namespace Google.Protobuf.DescriptorProtos { } public FileOptions() { } + public FileOptions(FileOptions other) { - MergeFrom(other); + javaPackage_ = other.javaPackage_; + javaOuterClassname_ = other.javaOuterClassname_; + javaMultipleFiles_ = other.javaMultipleFiles_; + javaGenerateEqualsAndHash_ = other.javaGenerateEqualsAndHash_; + javaStringCheckUtf8_ = other.javaStringCheckUtf8_; + optimizeFor_ = other.optimizeFor_; + goPackage_ = other.goPackage_; + ccGenericServices_ = other.ccGenericServices_; + javaGenericServices_ = other.javaGenericServices_; + pyGenericServices_ = other.pyGenericServices_; + deprecated_ = other.deprecated_; + ccEnableArenas_ = other.ccEnableArenas_; + objcClassPrefix_ = other.objcClassPrefix_; + csharpNamespace_ = other.csharpNamespace_; + uninterpretedOption_ = other.uninterpretedOption_.Clone(); + } + + public FileOptions Clone() { + return new FileOptions(this); } + public const int JavaPackageFieldNumber = 1; private string javaPackage_ = ""; public string JavaPackage { @@ -2757,7 +2884,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class MessageOptions : pb::IMessage, global::System.IEquatable { + public sealed partial class MessageOptions : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MessageOptions()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2772,9 +2899,19 @@ namespace Google.Protobuf.DescriptorProtos { } public MessageOptions() { } + public MessageOptions(MessageOptions other) { - MergeFrom(other); + messageSetWireFormat_ = other.messageSetWireFormat_; + noStandardDescriptorAccessor_ = other.noStandardDescriptorAccessor_; + deprecated_ = other.deprecated_; + mapEntry_ = other.mapEntry_; + uninterpretedOption_ = other.uninterpretedOption_.Clone(); + } + + public MessageOptions Clone() { + return new MessageOptions(this); } + public const int MessageSetWireFormatFieldNumber = 1; private bool messageSetWireFormat_; public bool MessageSetWireFormat { @@ -2943,7 +3080,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class FieldOptions : pb::IMessage, global::System.IEquatable { + public sealed partial class FieldOptions : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FieldOptions()); public static pb::MessageParser Parser { get { return _parser; } } @@ -2958,9 +3095,21 @@ namespace Google.Protobuf.DescriptorProtos { } public FieldOptions() { } + public FieldOptions(FieldOptions other) { - MergeFrom(other); + ctype_ = other.ctype_; + packed_ = other.packed_; + jstype_ = other.jstype_; + lazy_ = other.lazy_; + deprecated_ = other.deprecated_; + weak_ = other.weak_; + uninterpretedOption_ = other.uninterpretedOption_.Clone(); } + + public FieldOptions Clone() { + return new FieldOptions(this); + } + public const int CtypeFieldNumber = 1; private global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.CType ctype_ = global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.CType.STRING; public global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.CType Ctype { @@ -3195,7 +3344,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class EnumOptions : pb::IMessage, global::System.IEquatable { + public sealed partial class EnumOptions : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumOptions()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3210,9 +3359,17 @@ namespace Google.Protobuf.DescriptorProtos { } public EnumOptions() { } + public EnumOptions(EnumOptions other) { - MergeFrom(other); + allowAlias_ = other.allowAlias_; + deprecated_ = other.deprecated_; + uninterpretedOption_ = other.uninterpretedOption_.Clone(); + } + + public EnumOptions Clone() { + return new EnumOptions(this); } + public const int AllowAliasFieldNumber = 2; private bool allowAlias_; public bool AllowAlias { @@ -3333,7 +3490,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class EnumValueOptions : pb::IMessage, global::System.IEquatable { + public sealed partial class EnumValueOptions : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumValueOptions()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3348,9 +3505,16 @@ namespace Google.Protobuf.DescriptorProtos { } public EnumValueOptions() { } + public EnumValueOptions(EnumValueOptions other) { - MergeFrom(other); + deprecated_ = other.deprecated_; + uninterpretedOption_ = other.uninterpretedOption_.Clone(); } + + public EnumValueOptions Clone() { + return new EnumValueOptions(this); + } + public const int DeprecatedFieldNumber = 1; private bool deprecated_; public bool Deprecated { @@ -3447,7 +3611,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class ServiceOptions : pb::IMessage, global::System.IEquatable { + public sealed partial class ServiceOptions : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServiceOptions()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3462,9 +3626,16 @@ namespace Google.Protobuf.DescriptorProtos { } public ServiceOptions() { } + public ServiceOptions(ServiceOptions other) { - MergeFrom(other); + deprecated_ = other.deprecated_; + uninterpretedOption_ = other.uninterpretedOption_.Clone(); + } + + public ServiceOptions Clone() { + return new ServiceOptions(this); } + public const int DeprecatedFieldNumber = 33; private bool deprecated_; public bool Deprecated { @@ -3561,7 +3732,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class MethodOptions : pb::IMessage, global::System.IEquatable { + public sealed partial class MethodOptions : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MethodOptions()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3576,9 +3747,16 @@ namespace Google.Protobuf.DescriptorProtos { } public MethodOptions() { } + public MethodOptions(MethodOptions other) { - MergeFrom(other); + deprecated_ = other.deprecated_; + uninterpretedOption_ = other.uninterpretedOption_.Clone(); + } + + public MethodOptions Clone() { + return new MethodOptions(this); } + public const int DeprecatedFieldNumber = 33; private bool deprecated_; public bool Deprecated { @@ -3675,7 +3853,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class UninterpretedOption : pb::IMessage, global::System.IEquatable { + public sealed partial class UninterpretedOption : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new UninterpretedOption()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3690,9 +3868,21 @@ namespace Google.Protobuf.DescriptorProtos { } public UninterpretedOption() { } + public UninterpretedOption(UninterpretedOption other) { - MergeFrom(other); + name_ = other.name_.Clone(); + identifierValue_ = other.identifierValue_; + positiveIntValue_ = other.positiveIntValue_; + negativeIntValue_ = other.negativeIntValue_; + doubleValue_ = other.doubleValue_; + stringValue_ = other.stringValue_; + aggregateValue_ = other.aggregateValue_; } + + public UninterpretedOption Clone() { + return new UninterpretedOption(this); + } + public const int NameFieldNumber = 2; private readonly pbc::RepeatedField name_ = new pbc::RepeatedField(); public pbc::RepeatedField Name { @@ -3910,7 +4100,7 @@ namespace Google.Protobuf.DescriptorProtos { [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class Types { [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class NamePart : pb::IMessage, global::System.IEquatable { + public sealed partial class NamePart : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NamePart()); public static pb::MessageParser Parser { get { return _parser; } } @@ -3925,9 +4115,16 @@ namespace Google.Protobuf.DescriptorProtos { } public NamePart() { } + public NamePart(NamePart other) { - MergeFrom(other); + namePart_ = other.namePart_; + isExtension_ = other.isExtension_; } + + public NamePart Clone() { + return new NamePart(this); + } + public const int NamePart_FieldNumber = 1; private string namePart_ = ""; public string NamePart_ { @@ -4031,7 +4228,7 @@ namespace Google.Protobuf.DescriptorProtos { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class SourceCodeInfo : pb::IMessage, global::System.IEquatable { + public sealed partial class SourceCodeInfo : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SourceCodeInfo()); public static pb::MessageParser Parser { get { return _parser; } } @@ -4046,9 +4243,15 @@ namespace Google.Protobuf.DescriptorProtos { } public SourceCodeInfo() { } + public SourceCodeInfo(SourceCodeInfo other) { - MergeFrom(other); + location_ = other.location_.Clone(); + } + + public SourceCodeInfo Clone() { + return new SourceCodeInfo(this); } + public const int LocationFieldNumber = 1; private readonly pbc::RepeatedField location_ = new pbc::RepeatedField(); public pbc::RepeatedField Location { @@ -4122,7 +4325,7 @@ namespace Google.Protobuf.DescriptorProtos { [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] public static partial class Types { [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public sealed partial class Location : pb::IMessage, global::System.IEquatable { + public sealed partial class Location : pb::IMessage, global::System.IEquatable, pb::IDeepCloneable { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Location()); public static pb::MessageParser Parser { get { return _parser; } } @@ -4137,9 +4340,19 @@ namespace Google.Protobuf.DescriptorProtos { } public Location() { } + public Location(Location other) { - MergeFrom(other); + path_ = other.path_.Clone(); + span_ = other.span_.Clone(); + leadingComments_ = other.leadingComments_; + trailingComments_ = other.trailingComments_; + leadingDetachedComments_ = other.leadingDetachedComments_.Clone(); } + + public Location Clone() { + return new Location(this); + } + public const int PathFieldNumber = 1; private readonly pbc::RepeatedField path_ = new pbc::RepeatedField(); public pbc::RepeatedField Path { diff --git a/csharp/src/ProtocolBuffers/IMessage.cs b/csharp/src/ProtocolBuffers/IMessage.cs index 9c2a2d852f..32dfcaff0f 100644 --- a/csharp/src/ProtocolBuffers/IMessage.cs +++ b/csharp/src/ProtocolBuffers/IMessage.cs @@ -93,4 +93,22 @@ namespace Google.Protobuf /// The message to merge with this one. Must not be null. void MergeFrom(T message); } + + /// + /// Generic interface for a deeply cloneable type. + /// + /// + /// In practice, all generated messages implement this interface. + /// However, due to the type constraint on T in , + /// it is simpler to keep this as a separate interface. + /// + /// The type itself, returned by the method. + public interface IDeepCloneable + { + /// + /// Creates a deep clone of this object. + /// + /// A deep clone of this object. + T Clone(); + } } \ No newline at end of file diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h index 1b044a4977..91ae3ba1af 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.h +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h @@ -47,6 +47,7 @@ class FieldGeneratorBase : public SourceGeneratorBase { FieldGeneratorBase(const FieldDescriptor* descriptor, int fieldOrdinal); ~FieldGeneratorBase(); + virtual void GenerateCloningCode(io::Printer* printer) = 0; virtual void GenerateMembers(io::Printer* printer) = 0; virtual void GenerateMergingCode(io::Printer* printer) = 0; virtual void GenerateParsingCode(io::Printer* printer) = 0; diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index aca68fb78a..32d0a82dab 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -179,7 +179,7 @@ void MessageGenerator::Generate(io::Printer* printer) { WriteGeneratedCodeAttributes(printer); printer->Print( vars, - "$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name$>, global::System.IEquatable<$class_name$> {\n"); + "$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name$>, global::System.IEquatable<$class_name$>, pb::IDeepCloneable<$class_name$> {\n"); printer->Indent(); // All static fields and properties @@ -213,16 +213,12 @@ void MessageGenerator::Generate(io::Printer* printer) { "}\n" "\n"); - // Constructors + // Parameterless constructor printer->Print( vars, - "public $class_name$() { }\n"); // Public parameterless ctor. + "public $class_name$() { }\n\n"); - printer->Print( - vars, - "public $class_name$($class_name$ other) {\n" - " MergeFrom(other);\n" - "}\n"); // Merge ctor. + GenerateCloningCode(printer); // Fields/properties for (int i = 0; i < descriptor_->field_count(); i++) { @@ -303,6 +299,53 @@ void MessageGenerator::Generate(io::Printer* printer) { } +void MessageGenerator::GenerateCloningCode(io::Printer* printer) { + map vars; + vars["class_name"] = class_name(); + printer->Print( + vars, + "public $class_name$($class_name$ other) {\n"); + printer->Indent(); + // Clone non-oneof fields first + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!descriptor_->field(i)->containing_oneof()) { + scoped_ptr generator( + CreateFieldGeneratorInternal(descriptor_->field(i))); + generator->GenerateCloningCode(printer); + } + } + // Clone just the right field for each oneof + for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { + vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false); + vars["property_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true); + printer->Print(vars, "switch (other.$property_name$Case) {\n"); + printer->Indent(); + for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + scoped_ptr generator(CreateFieldGeneratorInternal(field)); + vars["field_property_name"] = GetPropertyName(field); + printer->Print( + vars, + "case $property_name$OneofCase.$field_property_name$:\n"); + printer->Indent(); + generator->GenerateCloningCode(printer); + printer->Print("break;\n"); + printer->Outdent(); + } + printer->Outdent(); + printer->Print("}\n\n"); + } + + printer->Outdent(); + printer->Print("}\n\n"); + + printer->Print( + vars, + "public $class_name$ Clone() {\n" + " return new $class_name$(this);\n" + "}\n\n"); +} + void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { map vars; vars["class_name"] = class_name(); diff --git a/src/google/protobuf/compiler/csharp/csharp_message.h b/src/google/protobuf/compiler/csharp/csharp_message.h index eb90ce67ad..c3a37a0efb 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.h +++ b/src/google/protobuf/compiler/csharp/csharp_message.h @@ -50,6 +50,7 @@ class MessageGenerator : public SourceGeneratorBase { MessageGenerator(const Descriptor* descriptor); ~MessageGenerator(); + void GenerateCloningCode(io::Printer* printer); void GenerateFrameworkMethods(io::Printer* printer); void GenerateStaticVariables(io::Printer* printer); void GenerateStaticVariableInitializers(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc index bd67aa0ffd..82deef54bd 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -125,6 +125,11 @@ void MessageFieldGenerator::WriteToString(io::Printer* printer) { "PrintField(\"$field_name$\", has$property_name$, $name$_, writer);\n"); } +void MessageFieldGenerator::GenerateCloningCode(io::Printer* printer) { + printer->Print(variables_, + "$property_name$ = other.$has_property_check$ ? other.$property_name$.Clone() : null;\n"); +} + MessageOneofFieldGenerator::MessageOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal) : MessageFieldGenerator(descriptor, fieldOrdinal) { @@ -166,6 +171,11 @@ void MessageOneofFieldGenerator::WriteToString(io::Printer* printer) { "PrintField(\"$descriptor_name$\", $has_property_check$, $oneof_name$_, writer);\n"); } +void MessageOneofFieldGenerator::GenerateCloningCode(io::Printer* printer) { + printer->Print(variables_, + "$property_name$ = other.$property_name$.Clone();\n"); +} + } // namespace csharp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.h b/src/google/protobuf/compiler/csharp/csharp_message_field.h index 02053b4f6b..f15e8e7e8a 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.h @@ -46,6 +46,7 @@ class MessageFieldGenerator : public FieldGeneratorBase { MessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); ~MessageFieldGenerator(); + virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); @@ -65,6 +66,7 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator { MessageOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); ~MessageOneofFieldGenerator(); + virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer); virtual void WriteToString(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc index 5820eb372b..c426c37ae0 100644 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc @@ -146,6 +146,11 @@ void PrimitiveFieldGenerator::WriteToString(io::Printer* printer) { "PrintField(\"$descriptor_name$\", $has_property_check$, $property_name$, writer);\n"); } +void PrimitiveFieldGenerator::GenerateCloningCode(io::Printer* printer) { + printer->Print(variables_, + "$name$_ = other.$name$_;\n"); +} + PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator( const FieldDescriptor* descriptor, int fieldOrdinal) : PrimitiveFieldGenerator(descriptor, fieldOrdinal) { @@ -189,6 +194,11 @@ void PrimitiveOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) { "$property_name$ = input.Read$capitalized_type_name$();\n"); } +void PrimitiveOneofFieldGenerator::GenerateCloningCode(io::Printer* printer) { + printer->Print(variables_, + "$property_name$ = other.$property_name$;\n"); +} + } // namespace csharp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h index d6672b6c45..bac3321487 100644 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h @@ -46,6 +46,7 @@ class PrimitiveFieldGenerator : public FieldGeneratorBase { PrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); ~PrimitiveFieldGenerator(); + virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); @@ -68,6 +69,7 @@ class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator { PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); ~PrimitiveOneofFieldGenerator(); + virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer); virtual void WriteToString(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc index 29c931e3ab..ce526b3784 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc @@ -142,6 +142,11 @@ void RepeatedEnumFieldGenerator::WriteToString(io::Printer* printer) { "PrintField(\"$descriptor_name$\", $name$_, writer);\n"); } +void RepeatedEnumFieldGenerator::GenerateCloningCode(io::Printer* printer) { + printer->Print(variables_, + "$name$_ = other.$name$_.Clone();\n"); +} + } // namespace csharp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h index 92f265c507..c7846a6199 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h @@ -48,6 +48,7 @@ class RepeatedEnumFieldGenerator : public FieldGeneratorBase { RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); ~RepeatedEnumFieldGenerator(); + virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc index 3ab0b19082..edfb98b44e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc @@ -118,6 +118,11 @@ void RepeatedMessageFieldGenerator::WriteToString(io::Printer* printer) { "PrintField(\"$field_name$\", $name$_, writer);\n"); } +void RepeatedMessageFieldGenerator::GenerateCloningCode(io::Printer* printer) { + printer->Print(variables_, + "$name$_ = other.$name$_.Clone();\n"); +} + } // namespace csharp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h index b8582800d8..38006731fd 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h @@ -46,6 +46,7 @@ class RepeatedMessageFieldGenerator : public FieldGeneratorBase { RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); ~RepeatedMessageFieldGenerator(); + virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc index cc787d503d..49a29c5558 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc @@ -148,6 +148,11 @@ void RepeatedPrimitiveFieldGenerator::WriteToString(io::Printer* printer) { "PrintField(\"$descriptor_name$\", $name$_, writer);\n"); } +void RepeatedPrimitiveFieldGenerator::GenerateCloningCode(io::Printer* printer) { + printer->Print(variables_, + "$name$_ = other.$name$_.Clone();\n"); +} + } // namespace csharp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h index 29d437d7fa..7f8f17a84e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h @@ -46,6 +46,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase { RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); ~RepeatedPrimitiveFieldGenerator(); + virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer);