diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs index cd1f6231..2fb6be83 100644 --- a/csharp/src/AddressBook/Addressbook.cs +++ b/csharp/src/AddressBook/Addressbook.cs @@ -76,6 +76,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { get { return global::Google.ProtocolBuffers.Examples.AddressBook.Addressbook.internal__static_tutorial_Person__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public Person() { } public Person(Person other) { @@ -89,30 +92,44 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { return new Person(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + phone_.Freeze(); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { get { return name_; } - set { name_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + name_ = value ?? ""; + } } - public const int IdFieldNumber = 2; private int id_; public int Id { get { return id_; } - set { id_ = value; } + set { + pb::Freezable.CheckMutable(this); + id_ = value; + } } - public const int EmailFieldNumber = 3; private string email_ = ""; public string Email { get { return email_; } - set { email_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + email_ = value ?? ""; + } } - public const int PhoneFieldNumber = 4; private readonly pbc::RepeatedField phone_ = new pbc::RepeatedField(); public pbc::RepeatedField Phone { @@ -254,6 +271,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { get { return global::Google.ProtocolBuffers.Examples.AddressBook.Addressbook.internal__static_tutorial_Person_PhoneNumber__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public PhoneNumber() { } public PhoneNumber(PhoneNumber other) { @@ -265,22 +285,33 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { return new PhoneNumber(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int NumberFieldNumber = 1; private string number_ = ""; public string Number { get { return number_; } - set { number_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + number_ = value ?? ""; + } } - public const int TypeFieldNumber = 2; private global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType type_ = global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType.HOME; public global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType Type { get { return type_; } - set { type_ = value; } + set { + pb::Freezable.CheckMutable(this); + type_ = value; + } } - public override bool Equals(object other) { return Equals(other as PhoneNumber); } @@ -382,6 +413,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { get { return global::Google.ProtocolBuffers.Examples.AddressBook.Addressbook.internal__static_tutorial_AddressBook__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public AddressBook() { } public AddressBook(AddressBook other) { @@ -392,6 +426,14 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { return new AddressBook(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + person_.Freeze(); + } + 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 e21d904d..26165428 100644 --- a/csharp/src/ProtocolBuffers.Test/GeneratedMessageTest.cs +++ b/csharp/src/ProtocolBuffers.Test/GeneratedMessageTest.cs @@ -1,4 +1,5 @@ -using Google.Protobuf.TestProtos; +using System; +using Google.Protobuf.TestProtos; using NUnit.Framework; namespace Google.Protobuf @@ -257,5 +258,22 @@ namespace Google.Protobuf original.OneofNestedMessage.Bb = 30; Assert.AreNotEqual(original, clone); } + + [Test] + public void Freeze() + { + var frozen = new TestAllTypes(); + frozen.Freeze(); + Assert.IsTrue(frozen.IsFrozen); + + Assert.Throws(() => frozen.ClearOneofField()); + Assert.Throws(() => frozen.SingleInt32 = 0); + Assert.Throws(() => frozen.SingleNestedMessage = null); + Assert.Throws(() => frozen.SingleNestedEnum = 0); + Assert.Throws(() => frozen.OneofString = null); + Assert.Throws(() => frozen.OneofUint32 = 0U); + Assert.Throws(() => frozen.RepeatedDouble.Add(0.0)); + Assert.Throws(() => frozen.RepeatedNestedMessage.Add(new TestAllTypes.Types.NestedMessage())); + } } } diff --git a/csharp/src/ProtocolBuffers.Test/RepeatedFieldTest.cs b/csharp/src/ProtocolBuffers.Test/RepeatedFieldTest.cs index cbe79294..c01cd8ff 100644 --- a/csharp/src/ProtocolBuffers.Test/RepeatedFieldTest.cs +++ b/csharp/src/ProtocolBuffers.Test/RepeatedFieldTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Google.Protobuf.Collections; +using Google.Protobuf.TestProtos; using NUnit.Framework; namespace Google.Protobuf @@ -11,8 +12,8 @@ namespace Google.Protobuf public void NullValuesRejected() { var list = new RepeatedField(); - Assert.Throws(() => list.Add((string) null)); - Assert.Throws(() => list.Add((IEnumerable) null)); + Assert.Throws(() => list.Add((string)null)); + Assert.Throws(() => list.Add((IEnumerable)null)); Assert.Throws(() => list.Add((RepeatedField)null)); Assert.Throws(() => list.Contains(null)); Assert.Throws(() => list.IndexOf(null)); @@ -47,5 +48,47 @@ namespace Google.Protobuf Assert.AreEqual("foo", list[1]); Assert.AreEqual("bar", list[2]); } + + [Test] + public void Freeze_FreezesElements() + { + var list = new RepeatedField { new TestAllTypes() }; + Assert.IsFalse(list[0].IsFrozen); + list.Freeze(); + Assert.IsTrue(list[0].IsFrozen); + } + + [Test] + public void Freeze_PreventsMutations() + { + var list = new RepeatedField { 0 }; + list.Freeze(); + Assert.Throws(() => list.Add(1)); + Assert.Throws(() => list[0] = 1); + Assert.Throws(() => list.Clear()); + Assert.Throws(() => list.RemoveAt(0)); + Assert.Throws(() => list.Remove(0)); + Assert.Throws(() => list.Insert(0, 0)); + } + + [Test] + public void Freeze_ReportsFrozen() + { + var list = new RepeatedField { 0 }; + Assert.IsFalse(list.IsFrozen); + Assert.IsFalse(list.IsReadOnly); + list.Freeze(); + Assert.IsTrue(list.IsFrozen); + Assert.IsTrue(list.IsReadOnly); + } + + [Test] + public void Clone_ReturnsMutable() + { + var list = new RepeatedField { 0 }; + list.Freeze(); + var clone = list.Clone(); + clone[0] = 1; + } } } diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs index 30256972..a32d19c2 100644 --- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs +++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs @@ -74,6 +74,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestImportProto3.internal__static_protobuf_unittest_import_ImportMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public ImportMessage() { } public ImportMessage(ImportMessage other) { @@ -84,14 +87,23 @@ namespace Google.Protobuf.TestProtos { return new ImportMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int DFieldNumber = 1; private int d_; public int D { get { return d_; } - set { d_ = value; } + set { + pb::Freezable.CheckMutable(this); + d_ = value; + } } - public override bool Equals(object other) { return Equals(other as ImportMessage); } diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs index cb7292f3..2c8b0a31 100644 --- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs +++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs @@ -59,6 +59,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestImportPublicProto3.internal__static_protobuf_unittest_import_PublicImportMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public PublicImportMessage() { } public PublicImportMessage(PublicImportMessage other) { @@ -69,14 +72,23 @@ namespace Google.Protobuf.TestProtos { return new PublicImportMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int EFieldNumber = 1; private int e_; public int E { get { return e_; } - set { e_ = value; } + set { + pb::Freezable.CheckMutable(this); + e_ = value; + } } - public override bool Equals(object other) { return Equals(other as PublicImportMessage); } diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs index d32718d5..28508a3b 100644 --- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs +++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs @@ -104,6 +104,9 @@ namespace UnitTest.Issues.TestProtos { get { return global::UnitTest.Issues.TestProtos.UnittestIssues.internal__static_unittest_issues_NegativeEnumMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public NegativeEnumMessage() { } public NegativeEnumMessage(NegativeEnumMessage other) { @@ -116,14 +119,25 @@ namespace UnitTest.Issues.TestProtos { return new NegativeEnumMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + values_.Freeze(); + packedValues_.Freeze(); + } + 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 { get { return value_; } - set { value_ = value; } + set { + pb::Freezable.CheckMutable(this); + value_ = value; + } } - public const int ValuesFieldNumber = 2; private readonly pbc::RepeatedField values_ = new pbc::RepeatedField(); public pbc::RepeatedField Values { @@ -255,6 +269,9 @@ namespace UnitTest.Issues.TestProtos { get { return global::UnitTest.Issues.TestProtos.UnittestIssues.internal__static_unittest_issues_DeprecatedChild__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public DeprecatedChild() { } public DeprecatedChild(DeprecatedChild other) { @@ -264,6 +281,13 @@ namespace UnitTest.Issues.TestProtos { return new DeprecatedChild(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public override bool Equals(object other) { return Equals(other as DeprecatedChild); } @@ -328,6 +352,9 @@ namespace UnitTest.Issues.TestProtos { get { return global::UnitTest.Issues.TestProtos.UnittestIssues.internal__static_unittest_issues_DeprecatedFieldsMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public DeprecatedFieldsMessage() { } public DeprecatedFieldsMessage(DeprecatedFieldsMessage other) { @@ -343,15 +370,28 @@ namespace UnitTest.Issues.TestProtos { return new DeprecatedFieldsMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + primitiveArray_.Freeze(); + if (messageValue_ != null) MessageValue.Freeze(); + messageArray_.Freeze(); + enumArray_.Freeze(); + } + public const int PrimitiveValueFieldNumber = 1; private int primitiveValue_; [global::System.ObsoleteAttribute()] public int PrimitiveValue { get { return primitiveValue_; } - set { primitiveValue_ = value; } + set { + pb::Freezable.CheckMutable(this); + primitiveValue_ = value; + } } - public const int PrimitiveArrayFieldNumber = 2; private readonly pbc::RepeatedField primitiveArray_ = new pbc::RepeatedField(); [global::System.ObsoleteAttribute()] @@ -364,7 +404,10 @@ namespace UnitTest.Issues.TestProtos { [global::System.ObsoleteAttribute()] public global::UnitTest.Issues.TestProtos.DeprecatedChild MessageValue { get { return messageValue_; } - set { messageValue_ = value; } + set { + pb::Freezable.CheckMutable(this); + messageValue_ = value; + } } public const int MessageArrayFieldNumber = 4; @@ -379,10 +422,12 @@ namespace UnitTest.Issues.TestProtos { [global::System.ObsoleteAttribute()] public global::UnitTest.Issues.TestProtos.DeprecatedEnum EnumValue { get { return enumValue_; } - set { enumValue_ = value; } + set { + pb::Freezable.CheckMutable(this); + enumValue_ = value; + } } - public const int EnumArrayFieldNumber = 6; private readonly pbc::RepeatedField enumArray_ = new pbc::RepeatedField(); [global::System.ObsoleteAttribute()] @@ -403,7 +448,8 @@ namespace UnitTest.Issues.TestProtos { } if (PrimitiveValue != other.PrimitiveValue) return false; if(!primitiveArray_.Equals(other.primitiveArray_)) return false; - if (!object.Equals(MessageValue, other.MessageValue)) return false;if(!messageArray_.Equals(other.messageArray_)) return false; + if (!object.Equals(MessageValue, other.MessageValue)) return false; + if(!messageArray_.Equals(other.messageArray_)) return false; if (EnumValue != other.EnumValue) return false; if(!enumArray_.Equals(other.enumArray_)) return false; return true; @@ -563,6 +609,9 @@ namespace UnitTest.Issues.TestProtos { get { return global::UnitTest.Issues.TestProtos.UnittestIssues.internal__static_unittest_issues_ItemField__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public ItemField() { } public ItemField(ItemField other) { @@ -573,14 +622,23 @@ namespace UnitTest.Issues.TestProtos { return new ItemField(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int ItemFieldNumber = 1; private int item_; public int Item { get { return item_; } - set { item_ = value; } + set { + pb::Freezable.CheckMutable(this); + item_ = value; + } } - public override bool Equals(object other) { return Equals(other as ItemField); } diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs index d9d33b10..d758ef5c 100644 --- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs +++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs @@ -416,6 +416,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestAllTypes__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestAllTypes() { } public TestAllTypes(TestAllTypes other) { @@ -484,176 +487,258 @@ namespace Google.Protobuf.TestProtos { return new TestAllTypes(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (singleNestedMessage_ != null) SingleNestedMessage.Freeze(); + if (singleForeignMessage_ != null) SingleForeignMessage.Freeze(); + if (singleImportMessage_ != null) SingleImportMessage.Freeze(); + if (singlePublicImportMessage_ != null) SinglePublicImportMessage.Freeze(); + repeatedInt32_.Freeze(); + repeatedInt64_.Freeze(); + repeatedUint32_.Freeze(); + repeatedUint64_.Freeze(); + repeatedSint32_.Freeze(); + repeatedSint64_.Freeze(); + repeatedFixed32_.Freeze(); + repeatedFixed64_.Freeze(); + repeatedSfixed32_.Freeze(); + repeatedSfixed64_.Freeze(); + repeatedFloat_.Freeze(); + repeatedDouble_.Freeze(); + repeatedBool_.Freeze(); + repeatedString_.Freeze(); + repeatedBytes_.Freeze(); + repeatedNestedMessage_.Freeze(); + repeatedForeignMessage_.Freeze(); + repeatedImportMessage_.Freeze(); + repeatedNestedEnum_.Freeze(); + repeatedForeignEnum_.Freeze(); + repeatedImportEnum_.Freeze(); + repeatedPublicImportMessage_.Freeze(); + if (oneofField_ is IFreezable) ((IFreezable) oneofField_).Freeze(); + } + public const int SingleInt32FieldNumber = 1; private int singleInt32_; public int SingleInt32 { get { return singleInt32_; } - set { singleInt32_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleInt32_ = value; + } } - public const int SingleInt64FieldNumber = 2; private long singleInt64_; public long SingleInt64 { get { return singleInt64_; } - set { singleInt64_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleInt64_ = value; + } } - public const int SingleUint32FieldNumber = 3; private uint singleUint32_; public uint SingleUint32 { get { return singleUint32_; } - set { singleUint32_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleUint32_ = value; + } } - public const int SingleUint64FieldNumber = 4; private ulong singleUint64_; public ulong SingleUint64 { get { return singleUint64_; } - set { singleUint64_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleUint64_ = value; + } } - public const int SingleSint32FieldNumber = 5; private int singleSint32_; public int SingleSint32 { get { return singleSint32_; } - set { singleSint32_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleSint32_ = value; + } } - public const int SingleSint64FieldNumber = 6; private long singleSint64_; public long SingleSint64 { get { return singleSint64_; } - set { singleSint64_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleSint64_ = value; + } } - public const int SingleFixed32FieldNumber = 7; private uint singleFixed32_; public uint SingleFixed32 { get { return singleFixed32_; } - set { singleFixed32_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleFixed32_ = value; + } } - public const int SingleFixed64FieldNumber = 8; private ulong singleFixed64_; public ulong SingleFixed64 { get { return singleFixed64_; } - set { singleFixed64_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleFixed64_ = value; + } } - public const int SingleSfixed32FieldNumber = 9; private int singleSfixed32_; public int SingleSfixed32 { get { return singleSfixed32_; } - set { singleSfixed32_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleSfixed32_ = value; + } } - public const int SingleSfixed64FieldNumber = 10; private long singleSfixed64_; public long SingleSfixed64 { get { return singleSfixed64_; } - set { singleSfixed64_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleSfixed64_ = value; + } } - public const int SingleFloatFieldNumber = 11; private float singleFloat_; public float SingleFloat { get { return singleFloat_; } - set { singleFloat_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleFloat_ = value; + } } - public const int SingleDoubleFieldNumber = 12; private double singleDouble_; public double SingleDouble { get { return singleDouble_; } - set { singleDouble_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleDouble_ = value; + } } - public const int SingleBoolFieldNumber = 13; private bool singleBool_; public bool SingleBool { get { return singleBool_; } - set { singleBool_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleBool_ = value; + } } - public const int SingleStringFieldNumber = 14; private string singleString_ = ""; public string SingleString { get { return singleString_; } - set { singleString_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + singleString_ = value ?? ""; + } } - public const int SingleBytesFieldNumber = 15; private pb::ByteString singleBytes_ = pb::ByteString.Empty; public pb::ByteString SingleBytes { get { return singleBytes_; } - set { singleBytes_ = value ?? pb::ByteString.Empty; } + set { + pb::Freezable.CheckMutable(this); + singleBytes_ = value ?? pb::ByteString.Empty; + } } - public const int SingleNestedMessageFieldNumber = 18; private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage singleNestedMessage_; public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage SingleNestedMessage { get { return singleNestedMessage_; } - set { singleNestedMessage_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleNestedMessage_ = value; + } } public const int SingleForeignMessageFieldNumber = 19; private global::Google.Protobuf.TestProtos.ForeignMessage singleForeignMessage_; public global::Google.Protobuf.TestProtos.ForeignMessage SingleForeignMessage { get { return singleForeignMessage_; } - set { singleForeignMessage_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleForeignMessage_ = value; + } } public const int SingleImportMessageFieldNumber = 20; private global::Google.Protobuf.TestProtos.ImportMessage singleImportMessage_; public global::Google.Protobuf.TestProtos.ImportMessage SingleImportMessage { get { return singleImportMessage_; } - set { singleImportMessage_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleImportMessage_ = value; + } } public const int SingleNestedEnumFieldNumber = 21; private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum singleNestedEnum_ = global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED; public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum SingleNestedEnum { get { return singleNestedEnum_; } - set { singleNestedEnum_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleNestedEnum_ = value; + } } - public const int SingleForeignEnumFieldNumber = 22; private global::Google.Protobuf.TestProtos.ForeignEnum singleForeignEnum_ = global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED; public global::Google.Protobuf.TestProtos.ForeignEnum SingleForeignEnum { get { return singleForeignEnum_; } - set { singleForeignEnum_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleForeignEnum_ = value; + } } - public const int SingleImportEnumFieldNumber = 23; private global::Google.Protobuf.TestProtos.ImportEnum singleImportEnum_ = global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED; public global::Google.Protobuf.TestProtos.ImportEnum SingleImportEnum { get { return singleImportEnum_; } - set { singleImportEnum_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleImportEnum_ = value; + } } - public const int SinglePublicImportMessageFieldNumber = 26; private global::Google.Protobuf.TestProtos.PublicImportMessage singlePublicImportMessage_; public global::Google.Protobuf.TestProtos.PublicImportMessage SinglePublicImportMessage { get { return singlePublicImportMessage_; } - set { singlePublicImportMessage_ = value; } + set { + pb::Freezable.CheckMutable(this); + singlePublicImportMessage_ = value; + } } public const int RepeatedInt32FieldNumber = 31; @@ -792,6 +877,7 @@ namespace Google.Protobuf.TestProtos { public uint OneofUint32 { get { return oneofFieldCase_ == OneofFieldOneofCase.OneofUint32 ? (uint) oneofField_ : 0; } set { + pb::Freezable.CheckMutable(this); oneofField_ = value; oneofFieldCase_ = OneofFieldOneofCase.OneofUint32; } @@ -801,6 +887,7 @@ namespace Google.Protobuf.TestProtos { public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage OneofNestedMessage { get { return oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage ? (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage) oneofField_ : null; } set { + pb::Freezable.CheckMutable(this); oneofField_ = value; oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.OneofNestedMessage; } @@ -810,6 +897,7 @@ namespace Google.Protobuf.TestProtos { public string OneofString { get { return oneofFieldCase_ == OneofFieldOneofCase.OneofString ? (string) oneofField_ : ""; } set { + pb::Freezable.CheckMutable(this); oneofField_ = value ?? ""; oneofFieldCase_ = OneofFieldOneofCase.OneofString; } @@ -819,6 +907,7 @@ namespace Google.Protobuf.TestProtos { public pb::ByteString OneofBytes { get { return oneofFieldCase_ == OneofFieldOneofCase.OneofBytes ? (pb::ByteString) oneofField_ : pb::ByteString.Empty; } set { + pb::Freezable.CheckMutable(this); oneofField_ = value ?? pb::ByteString.Empty; oneofFieldCase_ = OneofFieldOneofCase.OneofBytes; } @@ -838,6 +927,7 @@ namespace Google.Protobuf.TestProtos { } public void ClearOneofField() { + pb::Freezable.CheckMutable(this); oneofFieldCase_ = OneofFieldOneofCase.None; oneofField_ = null; } @@ -868,10 +958,14 @@ namespace Google.Protobuf.TestProtos { if (SingleBool != other.SingleBool) return false; if (SingleString != other.SingleString) return false; if (SingleBytes != other.SingleBytes) return false; - if (!object.Equals(SingleNestedMessage, other.SingleNestedMessage)) return false;if (!object.Equals(SingleForeignMessage, other.SingleForeignMessage)) return false;if (!object.Equals(SingleImportMessage, other.SingleImportMessage)) return false;if (SingleNestedEnum != other.SingleNestedEnum) return false; + if (!object.Equals(SingleNestedMessage, other.SingleNestedMessage)) return false; + if (!object.Equals(SingleForeignMessage, other.SingleForeignMessage)) return false; + if (!object.Equals(SingleImportMessage, other.SingleImportMessage)) return false; + if (SingleNestedEnum != other.SingleNestedEnum) return false; if (SingleForeignEnum != other.SingleForeignEnum) return false; if (SingleImportEnum != other.SingleImportEnum) return false; - if (!object.Equals(SinglePublicImportMessage, other.SinglePublicImportMessage)) return false;if(!repeatedInt32_.Equals(other.repeatedInt32_)) return false; + if (!object.Equals(SinglePublicImportMessage, other.SinglePublicImportMessage)) return false; + if(!repeatedInt32_.Equals(other.repeatedInt32_)) return false; if(!repeatedInt64_.Equals(other.repeatedInt64_)) return false; if(!repeatedUint32_.Equals(other.repeatedUint32_)) return false; if(!repeatedUint64_.Equals(other.repeatedUint64_)) return false; @@ -894,7 +988,8 @@ namespace Google.Protobuf.TestProtos { if(!repeatedImportEnum_.Equals(other.repeatedImportEnum_)) return false; if(!repeatedPublicImportMessage_.Equals(other.repeatedPublicImportMessage_)) return false; if (OneofUint32 != other.OneofUint32) return false; - if (!object.Equals(OneofNestedMessage, other.OneofNestedMessage)) return false;if (OneofString != other.OneofString) return false; + if (!object.Equals(OneofNestedMessage, other.OneofNestedMessage)) return false; + if (OneofString != other.OneofString) return false; if (OneofBytes != other.OneofBytes) return false; return true; } @@ -1764,6 +1859,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestAllTypes_NestedMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public NestedMessage() { } public NestedMessage(NestedMessage other) { @@ -1774,14 +1872,23 @@ namespace Google.Protobuf.TestProtos { return new NestedMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int BbFieldNumber = 1; private int bb_; public int Bb { get { return bb_; } - set { bb_ = value; } + set { + pb::Freezable.CheckMutable(this); + bb_ = value; + } } - public override bool Equals(object other) { return Equals(other as NestedMessage); } @@ -1867,6 +1974,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_NestedTestAllTypes__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public NestedTestAllTypes() { } public NestedTestAllTypes(NestedTestAllTypes other) { @@ -1879,18 +1989,34 @@ namespace Google.Protobuf.TestProtos { return new NestedTestAllTypes(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (child_ != null) Child.Freeze(); + if (payload_ != null) Payload.Freeze(); + repeatedChild_.Freeze(); + } + public const int ChildFieldNumber = 1; private global::Google.Protobuf.TestProtos.NestedTestAllTypes child_; public global::Google.Protobuf.TestProtos.NestedTestAllTypes Child { get { return child_; } - set { child_ = value; } + set { + pb::Freezable.CheckMutable(this); + child_ = value; + } } public const int PayloadFieldNumber = 2; private global::Google.Protobuf.TestProtos.TestAllTypes payload_; public global::Google.Protobuf.TestProtos.TestAllTypes Payload { get { return payload_; } - set { payload_ = value; } + set { + pb::Freezable.CheckMutable(this); + payload_ = value; + } } public const int RepeatedChildFieldNumber = 3; @@ -1910,7 +2036,9 @@ namespace Google.Protobuf.TestProtos { if (ReferenceEquals(other, this)) { return true; } - if (!object.Equals(Child, other.Child)) return false;if (!object.Equals(Payload, other.Payload)) return false;if(!repeatedChild_.Equals(other.repeatedChild_)) return false; + if (!object.Equals(Child, other.Child)) return false; + if (!object.Equals(Payload, other.Payload)) return false; + if(!repeatedChild_.Equals(other.repeatedChild_)) return false; return true; } @@ -2021,6 +2149,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestDeprecatedFields__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestDeprecatedFields() { } public TestDeprecatedFields(TestDeprecatedFields other) { @@ -2031,15 +2162,24 @@ namespace Google.Protobuf.TestProtos { return new TestDeprecatedFields(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int DeprecatedInt32FieldNumber = 1; private int deprecatedInt32_; [global::System.ObsoleteAttribute()] public int DeprecatedInt32 { get { return deprecatedInt32_; } - set { deprecatedInt32_ = value; } + set { + pb::Freezable.CheckMutable(this); + deprecatedInt32_ = value; + } } - public override bool Equals(object other) { return Equals(other as TestDeprecatedFields); } @@ -2120,6 +2260,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_ForeignMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public ForeignMessage() { } public ForeignMessage(ForeignMessage other) { @@ -2130,14 +2273,23 @@ namespace Google.Protobuf.TestProtos { return new ForeignMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int CFieldNumber = 1; private int c_; public int C { get { return c_; } - set { c_ = value; } + set { + pb::Freezable.CheckMutable(this); + c_ = value; + } } - public override bool Equals(object other) { return Equals(other as ForeignMessage); } @@ -2218,6 +2370,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestReservedFields__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestReservedFields() { } public TestReservedFields(TestReservedFields other) { @@ -2227,6 +2382,13 @@ namespace Google.Protobuf.TestProtos { return new TestReservedFields(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public override bool Equals(object other) { return Equals(other as TestReservedFields); } @@ -2291,6 +2453,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestForeignNested__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestForeignNested() { } public TestForeignNested(TestForeignNested other) { @@ -2301,11 +2466,22 @@ namespace Google.Protobuf.TestProtos { return new TestForeignNested(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (foreignNested_ != null) ForeignNested.Freeze(); + } + public const int ForeignNestedFieldNumber = 1; private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage foreignNested_; public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage ForeignNested { get { return foreignNested_; } - set { foreignNested_ = value; } + set { + pb::Freezable.CheckMutable(this); + foreignNested_ = value; + } } public override bool Equals(object other) { @@ -2319,7 +2495,8 @@ namespace Google.Protobuf.TestProtos { if (ReferenceEquals(other, this)) { return true; } - if (!object.Equals(ForeignNested, other.ForeignNested)) return false; return true; + if (!object.Equals(ForeignNested, other.ForeignNested)) return false; + return true; } public override int GetHashCode() { @@ -2393,6 +2570,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestReallyLargeTagNumber__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestReallyLargeTagNumber() { } public TestReallyLargeTagNumber(TestReallyLargeTagNumber other) { @@ -2404,22 +2584,33 @@ namespace Google.Protobuf.TestProtos { return new TestReallyLargeTagNumber(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int AFieldNumber = 1; private int a_; public int A { get { return a_; } - set { a_ = value; } + set { + pb::Freezable.CheckMutable(this); + a_ = value; + } } - public const int BbFieldNumber = 268435455; private int bb_; public int Bb { get { return bb_; } - set { bb_ = value; } + set { + pb::Freezable.CheckMutable(this); + bb_ = value; + } } - public override bool Equals(object other) { return Equals(other as TestReallyLargeTagNumber); } @@ -2516,6 +2707,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestRecursiveMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestRecursiveMessage() { } public TestRecursiveMessage(TestRecursiveMessage other) { @@ -2527,21 +2721,34 @@ namespace Google.Protobuf.TestProtos { return new TestRecursiveMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (a_ != null) A.Freeze(); + } + public const int AFieldNumber = 1; private global::Google.Protobuf.TestProtos.TestRecursiveMessage a_; public global::Google.Protobuf.TestProtos.TestRecursiveMessage A { get { return a_; } - set { a_ = value; } + set { + pb::Freezable.CheckMutable(this); + a_ = value; + } } public const int IFieldNumber = 2; private int i_; public int I { get { return i_; } - set { i_ = value; } + set { + pb::Freezable.CheckMutable(this); + i_ = value; + } } - public override bool Equals(object other) { return Equals(other as TestRecursiveMessage); } @@ -2553,7 +2760,8 @@ namespace Google.Protobuf.TestProtos { if (ReferenceEquals(other, this)) { return true; } - if (!object.Equals(A, other.A)) return false;if (I != other.I) return false; + if (!object.Equals(A, other.A)) return false; + if (I != other.I) return false; return true; } @@ -2643,6 +2851,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestMutualRecursionA__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestMutualRecursionA() { } public TestMutualRecursionA(TestMutualRecursionA other) { @@ -2653,11 +2864,22 @@ namespace Google.Protobuf.TestProtos { return new TestMutualRecursionA(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (bb_ != null) Bb.Freeze(); + } + public const int BbFieldNumber = 1; private global::Google.Protobuf.TestProtos.TestMutualRecursionB bb_; public global::Google.Protobuf.TestProtos.TestMutualRecursionB Bb { get { return bb_; } - set { bb_ = value; } + set { + pb::Freezable.CheckMutable(this); + bb_ = value; + } } public override bool Equals(object other) { @@ -2671,7 +2893,8 @@ namespace Google.Protobuf.TestProtos { if (ReferenceEquals(other, this)) { return true; } - if (!object.Equals(Bb, other.Bb)) return false; return true; + if (!object.Equals(Bb, other.Bb)) return false; + return true; } public override int GetHashCode() { @@ -2745,6 +2968,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestMutualRecursionB__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestMutualRecursionB() { } public TestMutualRecursionB(TestMutualRecursionB other) { @@ -2756,21 +2982,34 @@ namespace Google.Protobuf.TestProtos { return new TestMutualRecursionB(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (a_ != null) A.Freeze(); + } + public const int AFieldNumber = 1; private global::Google.Protobuf.TestProtos.TestMutualRecursionA a_; public global::Google.Protobuf.TestProtos.TestMutualRecursionA A { get { return a_; } - set { a_ = value; } + set { + pb::Freezable.CheckMutable(this); + a_ = value; + } } public const int OptionalInt32FieldNumber = 2; private int optionalInt32_; public int OptionalInt32 { get { return optionalInt32_; } - set { optionalInt32_ = value; } + set { + pb::Freezable.CheckMutable(this); + optionalInt32_ = value; + } } - public override bool Equals(object other) { return Equals(other as TestMutualRecursionB); } @@ -2782,7 +3021,8 @@ namespace Google.Protobuf.TestProtos { if (ReferenceEquals(other, this)) { return true; } - if (!object.Equals(A, other.A)) return false;if (OptionalInt32 != other.OptionalInt32) return false; + if (!object.Equals(A, other.A)) return false; + if (OptionalInt32 != other.OptionalInt32) return false; return true; } @@ -2872,6 +3112,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestCamelCaseFieldNames__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestCamelCaseFieldNames() { } public TestCamelCaseFieldNames(TestCamelCaseFieldNames other) { @@ -2889,35 +3132,56 @@ namespace Google.Protobuf.TestProtos { return new TestCamelCaseFieldNames(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (messageField_ != null) MessageField.Freeze(); + repeatedPrimitiveField_.Freeze(); + repeatedStringField_.Freeze(); + repeatedEnumField_.Freeze(); + repeatedMessageField_.Freeze(); + } + public const int PrimitiveFieldFieldNumber = 1; private int primitiveField_; public int PrimitiveField { get { return primitiveField_; } - set { primitiveField_ = value; } + set { + pb::Freezable.CheckMutable(this); + primitiveField_ = value; + } } - public const int StringFieldFieldNumber = 2; private string stringField_ = ""; public string StringField { get { return stringField_; } - set { stringField_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + stringField_ = value ?? ""; + } } - public const int EnumFieldFieldNumber = 3; private global::Google.Protobuf.TestProtos.ForeignEnum enumField_ = global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED; public global::Google.Protobuf.TestProtos.ForeignEnum EnumField { get { return enumField_; } - set { enumField_ = value; } + set { + pb::Freezable.CheckMutable(this); + enumField_ = value; + } } - public const int MessageFieldFieldNumber = 4; private global::Google.Protobuf.TestProtos.ForeignMessage messageField_; public global::Google.Protobuf.TestProtos.ForeignMessage MessageField { get { return messageField_; } - set { messageField_ = value; } + set { + pb::Freezable.CheckMutable(this); + messageField_ = value; + } } public const int RepeatedPrimitiveFieldFieldNumber = 7; @@ -2958,7 +3222,8 @@ namespace Google.Protobuf.TestProtos { if (PrimitiveField != other.PrimitiveField) return false; if (StringField != other.StringField) return false; if (EnumField != other.EnumField) return false; - if (!object.Equals(MessageField, other.MessageField)) return false;if(!repeatedPrimitiveField_.Equals(other.repeatedPrimitiveField_)) return false; + if (!object.Equals(MessageField, other.MessageField)) return false; + if(!repeatedPrimitiveField_.Equals(other.repeatedPrimitiveField_)) return false; if(!repeatedStringField_.Equals(other.repeatedStringField_)) return false; if(!repeatedEnumField_.Equals(other.repeatedEnumField_)) return false; if(!repeatedMessageField_.Equals(other.repeatedMessageField_)) return false; @@ -3151,6 +3416,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestFieldOrderings__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestFieldOrderings() { } public TestFieldOrderings(TestFieldOrderings other) { @@ -3164,35 +3432,52 @@ namespace Google.Protobuf.TestProtos { return new TestFieldOrderings(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (singleNestedMessage_ != null) SingleNestedMessage.Freeze(); + } + public const int MyStringFieldNumber = 11; private string myString_ = ""; public string MyString { get { return myString_; } - set { myString_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + myString_ = value ?? ""; + } } - public const int MyIntFieldNumber = 1; private long myInt_; public long MyInt { get { return myInt_; } - set { myInt_ = value; } + set { + pb::Freezable.CheckMutable(this); + myInt_ = value; + } } - public const int MyFloatFieldNumber = 101; private float myFloat_; public float MyFloat { get { return myFloat_; } - set { myFloat_ = value; } + set { + pb::Freezable.CheckMutable(this); + myFloat_ = value; + } } - public const int SingleNestedMessageFieldNumber = 200; private global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage singleNestedMessage_; public global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage SingleNestedMessage { get { return singleNestedMessage_; } - set { singleNestedMessage_ = value; } + set { + pb::Freezable.CheckMutable(this); + singleNestedMessage_ = value; + } } public override bool Equals(object other) { @@ -3209,7 +3494,8 @@ namespace Google.Protobuf.TestProtos { if (MyString != other.MyString) return false; if (MyInt != other.MyInt) return false; if (MyFloat != other.MyFloat) return false; - if (!object.Equals(SingleNestedMessage, other.SingleNestedMessage)) return false; return true; + if (!object.Equals(SingleNestedMessage, other.SingleNestedMessage)) return false; + return true; } public override int GetHashCode() { @@ -3329,6 +3615,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestFieldOrderings_NestedMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public NestedMessage() { } public NestedMessage(NestedMessage other) { @@ -3340,22 +3629,33 @@ namespace Google.Protobuf.TestProtos { return new NestedMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int OoFieldNumber = 2; private long oo_; public long Oo { get { return oo_; } - set { oo_ = value; } + set { + pb::Freezable.CheckMutable(this); + oo_ = value; + } } - public const int BbFieldNumber = 1; private int bb_; public int Bb { get { return bb_; } - set { bb_ = value; } + set { + pb::Freezable.CheckMutable(this); + bb_ = value; + } } - public override bool Equals(object other) { return Equals(other as NestedMessage); } @@ -3457,6 +3757,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_SparseEnumMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public SparseEnumMessage() { } public SparseEnumMessage(SparseEnumMessage other) { @@ -3467,14 +3770,23 @@ namespace Google.Protobuf.TestProtos { return new SparseEnumMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + 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 { get { return sparseEnum_; } - set { sparseEnum_ = value; } + set { + pb::Freezable.CheckMutable(this); + sparseEnum_ = value; + } } - public override bool Equals(object other) { return Equals(other as SparseEnumMessage); } @@ -3555,6 +3867,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_OneString__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public OneString() { } public OneString(OneString other) { @@ -3565,14 +3880,23 @@ namespace Google.Protobuf.TestProtos { return new OneString(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int DataFieldNumber = 1; private string data_ = ""; public string Data { get { return data_; } - set { data_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + data_ = value ?? ""; + } } - public override bool Equals(object other) { return Equals(other as OneString); } @@ -3653,6 +3977,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_MoreString__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public MoreString() { } public MoreString(MoreString other) { @@ -3663,6 +3990,14 @@ namespace Google.Protobuf.TestProtos { return new MoreString(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + data_.Freeze(); + } + public const int DataFieldNumber = 1; private readonly pbc::RepeatedField data_ = new pbc::RepeatedField(); public pbc::RepeatedField Data { @@ -3751,6 +4086,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_OneBytes__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public OneBytes() { } public OneBytes(OneBytes other) { @@ -3761,14 +4099,23 @@ namespace Google.Protobuf.TestProtos { return new OneBytes(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int DataFieldNumber = 1; private pb::ByteString data_ = pb::ByteString.Empty; public pb::ByteString Data { get { return data_; } - set { data_ = value ?? pb::ByteString.Empty; } + set { + pb::Freezable.CheckMutable(this); + data_ = value ?? pb::ByteString.Empty; + } } - public override bool Equals(object other) { return Equals(other as OneBytes); } @@ -3849,6 +4196,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_MoreBytes__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public MoreBytes() { } public MoreBytes(MoreBytes other) { @@ -3859,14 +4209,23 @@ namespace Google.Protobuf.TestProtos { return new MoreBytes(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int DataFieldNumber = 1; private pb::ByteString data_ = pb::ByteString.Empty; public pb::ByteString Data { get { return data_; } - set { data_ = value ?? pb::ByteString.Empty; } + set { + pb::Freezable.CheckMutable(this); + data_ = value ?? pb::ByteString.Empty; + } } - public override bool Equals(object other) { return Equals(other as MoreBytes); } @@ -3947,6 +4306,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_Int32Message__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public Int32Message() { } public Int32Message(Int32Message other) { @@ -3957,14 +4319,23 @@ namespace Google.Protobuf.TestProtos { return new Int32Message(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int DataFieldNumber = 1; private int data_; public int Data { get { return data_; } - set { data_ = value; } + set { + pb::Freezable.CheckMutable(this); + data_ = value; + } } - public override bool Equals(object other) { return Equals(other as Int32Message); } @@ -4045,6 +4416,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_Uint32Message__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public Uint32Message() { } public Uint32Message(Uint32Message other) { @@ -4055,14 +4429,23 @@ namespace Google.Protobuf.TestProtos { return new Uint32Message(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int DataFieldNumber = 1; private uint data_; public uint Data { get { return data_; } - set { data_ = value; } + set { + pb::Freezable.CheckMutable(this); + data_ = value; + } } - public override bool Equals(object other) { return Equals(other as Uint32Message); } @@ -4143,6 +4526,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_Int64Message__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public Int64Message() { } public Int64Message(Int64Message other) { @@ -4153,14 +4539,23 @@ namespace Google.Protobuf.TestProtos { return new Int64Message(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int DataFieldNumber = 1; private long data_; public long Data { get { return data_; } - set { data_ = value; } + set { + pb::Freezable.CheckMutable(this); + data_ = value; + } } - public override bool Equals(object other) { return Equals(other as Int64Message); } @@ -4241,6 +4636,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_Uint64Message__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public Uint64Message() { } public Uint64Message(Uint64Message other) { @@ -4251,14 +4649,23 @@ namespace Google.Protobuf.TestProtos { return new Uint64Message(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int DataFieldNumber = 1; private ulong data_; public ulong Data { get { return data_; } - set { data_ = value; } + set { + pb::Freezable.CheckMutable(this); + data_ = value; + } } - public override bool Equals(object other) { return Equals(other as Uint64Message); } @@ -4339,6 +4746,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_BoolMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public BoolMessage() { } public BoolMessage(BoolMessage other) { @@ -4349,14 +4759,23 @@ namespace Google.Protobuf.TestProtos { return new BoolMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int DataFieldNumber = 1; private bool data_; public bool Data { get { return data_; } - set { data_ = value; } + set { + pb::Freezable.CheckMutable(this); + data_ = value; + } } - public override bool Equals(object other) { return Equals(other as BoolMessage); } @@ -4437,6 +4856,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestOneof__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestOneof() { } public TestOneof(TestOneof other) { @@ -4458,10 +4880,19 @@ namespace Google.Protobuf.TestProtos { return new TestOneof(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (foo_ is IFreezable) ((IFreezable) foo_).Freeze(); + } + public const int FooIntFieldNumber = 1; public int FooInt { get { return fooCase_ == FooOneofCase.FooInt ? (int) foo_ : 0; } set { + pb::Freezable.CheckMutable(this); foo_ = value; fooCase_ = FooOneofCase.FooInt; } @@ -4471,6 +4902,7 @@ namespace Google.Protobuf.TestProtos { public string FooString { get { return fooCase_ == FooOneofCase.FooString ? (string) foo_ : ""; } set { + pb::Freezable.CheckMutable(this); foo_ = value ?? ""; fooCase_ = FooOneofCase.FooString; } @@ -4480,6 +4912,7 @@ namespace Google.Protobuf.TestProtos { public global::Google.Protobuf.TestProtos.TestAllTypes FooMessage { get { return fooCase_ == FooOneofCase.FooMessage ? (global::Google.Protobuf.TestProtos.TestAllTypes) foo_ : null; } set { + pb::Freezable.CheckMutable(this); foo_ = value; fooCase_ = value == null ? FooOneofCase.None : FooOneofCase.FooMessage; } @@ -4498,6 +4931,7 @@ namespace Google.Protobuf.TestProtos { } public void ClearFoo() { + pb::Freezable.CheckMutable(this); fooCase_ = FooOneofCase.None; foo_ = null; } @@ -4515,7 +4949,8 @@ namespace Google.Protobuf.TestProtos { } if (FooInt != other.FooInt) return false; if (FooString != other.FooString) return false; - if (!object.Equals(FooMessage, other.FooMessage)) return false; return true; + if (!object.Equals(FooMessage, other.FooMessage)) return false; + return true; } public override int GetHashCode() { @@ -4621,6 +5056,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestPackedTypes__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestPackedTypes() { } public TestPackedTypes(TestPackedTypes other) { @@ -4644,6 +5082,27 @@ namespace Google.Protobuf.TestProtos { return new TestPackedTypes(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + packedInt32_.Freeze(); + packedInt64_.Freeze(); + packedUint32_.Freeze(); + packedUint64_.Freeze(); + packedSint32_.Freeze(); + packedSint64_.Freeze(); + packedFixed32_.Freeze(); + packedFixed64_.Freeze(); + packedSfixed32_.Freeze(); + packedSfixed64_.Freeze(); + packedFloat_.Freeze(); + packedDouble_.Freeze(); + packedBool_.Freeze(); + packedEnum_.Freeze(); + } + public const int PackedInt32FieldNumber = 90; private readonly pbc::RepeatedField packedInt32_ = new pbc::RepeatedField(); public pbc::RepeatedField PackedInt32 { @@ -5058,6 +5517,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestUnpackedTypes__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestUnpackedTypes() { } public TestUnpackedTypes(TestUnpackedTypes other) { @@ -5081,6 +5543,27 @@ namespace Google.Protobuf.TestProtos { return new TestUnpackedTypes(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + unpackedInt32_.Freeze(); + unpackedInt64_.Freeze(); + unpackedUint32_.Freeze(); + unpackedUint64_.Freeze(); + unpackedSint32_.Freeze(); + unpackedSint64_.Freeze(); + unpackedFixed32_.Freeze(); + unpackedFixed64_.Freeze(); + unpackedSfixed32_.Freeze(); + unpackedSfixed64_.Freeze(); + unpackedFloat_.Freeze(); + unpackedDouble_.Freeze(); + unpackedBool_.Freeze(); + unpackedEnum_.Freeze(); + } + public const int UnpackedInt32FieldNumber = 90; private readonly pbc::RepeatedField unpackedInt32_ = new pbc::RepeatedField(); public pbc::RepeatedField UnpackedInt32 { @@ -5481,6 +5964,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestRepeatedScalarDifferentTagSizes__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestRepeatedScalarDifferentTagSizes() { } public TestRepeatedScalarDifferentTagSizes(TestRepeatedScalarDifferentTagSizes other) { @@ -5496,6 +5982,19 @@ namespace Google.Protobuf.TestProtos { return new TestRepeatedScalarDifferentTagSizes(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + repeatedFixed32_.Freeze(); + repeatedInt32_.Freeze(); + repeatedFixed64_.Freeze(); + repeatedInt64_.Freeze(); + repeatedFloat_.Freeze(); + repeatedUint64_.Freeze(); + } + public const int RepeatedFixed32FieldNumber = 12; private readonly pbc::RepeatedField repeatedFixed32_ = new pbc::RepeatedField(); public pbc::RepeatedField RepeatedFixed32 { @@ -5710,6 +6209,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_TestCommentInjectionMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public TestCommentInjectionMessage() { } public TestCommentInjectionMessage(TestCommentInjectionMessage other) { @@ -5720,14 +6222,23 @@ namespace Google.Protobuf.TestProtos { return new TestCommentInjectionMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int AFieldNumber = 1; private string a_ = ""; public string A { get { return a_; } - set { a_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + a_ = value ?? ""; + } } - public override bool Equals(object other) { return Equals(other as TestCommentInjectionMessage); } @@ -5808,6 +6319,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_FooRequest__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public FooRequest() { } public FooRequest(FooRequest other) { @@ -5817,6 +6331,13 @@ namespace Google.Protobuf.TestProtos { return new FooRequest(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public override bool Equals(object other) { return Equals(other as FooRequest); } @@ -5881,6 +6402,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_FooResponse__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public FooResponse() { } public FooResponse(FooResponse other) { @@ -5890,6 +6414,13 @@ namespace Google.Protobuf.TestProtos { return new FooResponse(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public override bool Equals(object other) { return Equals(other as FooResponse); } @@ -5954,6 +6485,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_FooClientMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public FooClientMessage() { } public FooClientMessage(FooClientMessage other) { @@ -5963,6 +6497,13 @@ namespace Google.Protobuf.TestProtos { return new FooClientMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public override bool Equals(object other) { return Equals(other as FooClientMessage); } @@ -6027,6 +6568,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_FooServerMessage__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public FooServerMessage() { } public FooServerMessage(FooServerMessage other) { @@ -6036,6 +6580,13 @@ namespace Google.Protobuf.TestProtos { return new FooServerMessage(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public override bool Equals(object other) { return Equals(other as FooServerMessage); } @@ -6100,6 +6651,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_BarRequest__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public BarRequest() { } public BarRequest(BarRequest other) { @@ -6109,6 +6663,13 @@ namespace Google.Protobuf.TestProtos { return new BarRequest(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public override bool Equals(object other) { return Equals(other as BarRequest); } @@ -6173,6 +6734,9 @@ namespace Google.Protobuf.TestProtos { get { return global::Google.Protobuf.TestProtos.UnittestProto3.internal__static_protobuf_unittest_BarResponse__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public BarResponse() { } public BarResponse(BarResponse other) { @@ -6182,6 +6746,13 @@ namespace Google.Protobuf.TestProtos { return new BarResponse(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public override bool Equals(object other) { return Equals(other as BarResponse); } diff --git a/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs b/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs index 5100e4db..ebfc522f 100644 --- a/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs +++ b/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs @@ -4,10 +4,16 @@ using System.Collections.Generic; namespace Google.Protobuf.Collections { - public sealed class RepeatedField : IList, IEquatable> + /// + /// The contents of a repeated field: essentially, a collection with some extra + /// restrictions (no null values) and capabilities (deep cloning and freezing). + /// + /// The element type of the repeated field. + public sealed class RepeatedField : IList, IDeepCloneable>, IEquatable>, IFreezable { private static readonly T[] EmptyArray = new T[0]; + private bool frozen; private const int MinArraySize = 8; private T[] array = EmptyArray; private int count = 0; @@ -26,6 +32,7 @@ namespace Google.Protobuf.Collections public RepeatedField Clone() { RepeatedField clone = new RepeatedField(); + // Clone is implicitly *not* frozen, even if this object is. if (array != EmptyArray) { clone.array = (T[])array.Clone(); @@ -42,6 +49,21 @@ namespace Google.Protobuf.Collections return clone; } + public bool IsFrozen { get { return frozen; } } + + public void Freeze() + { + frozen = true; + IFreezable[] freezableArray = array as IFreezable[]; + if (freezableArray != null) + { + for (int i = 0; i < count; i++) + { + freezableArray[i].Freeze(); + } + } + } + private void EnsureSize(int size) { size = Math.Max(size, MinArraySize); @@ -60,6 +82,7 @@ namespace Google.Protobuf.Collections { throw new ArgumentNullException("item"); } + this.CheckMutable(); EnsureSize(count + 1); array[count++] = item; } @@ -70,6 +93,7 @@ namespace Google.Protobuf.Collections /// internal void AddInt32(int item) { + this.CheckMutable(); EnsureSize(count + 1); int[] castArray = (int[]) (object) array; castArray[count++] = item; @@ -77,6 +101,7 @@ namespace Google.Protobuf.Collections public void Clear() { + this.CheckMutable(); array = EmptyArray; count = 0; } @@ -93,6 +118,7 @@ namespace Google.Protobuf.Collections public bool Remove(T item) { + this.CheckMutable(); int index = IndexOf(item); if (index == -1) { @@ -107,7 +133,7 @@ namespace Google.Protobuf.Collections public int Count { get { return count; } } // TODO(jonskeet): If we implement freezing, make this reflect it. - public bool IsReadOnly { get { return false; } } + public bool IsReadOnly { get { return IsFrozen; } } public void Add(RepeatedField values) { @@ -115,6 +141,7 @@ namespace Google.Protobuf.Collections { throw new ArgumentNullException("values"); } + this.CheckMutable(); EnsureSize(count + values.count); // We know that all the values will be valid, because it's a RepeatedField. Array.Copy(values.array, 0, array, count, values.count); @@ -127,6 +154,7 @@ namespace Google.Protobuf.Collections { throw new ArgumentNullException("values"); } + this.CheckMutable(); // TODO: Check for ICollection and get the Count? foreach (T item in values) { @@ -227,6 +255,7 @@ namespace Google.Protobuf.Collections { throw new ArgumentOutOfRangeException("index"); } + this.CheckMutable(); EnsureSize(count + 1); Array.Copy(array, index, array, index + 1, count - index); count++; @@ -238,6 +267,7 @@ namespace Google.Protobuf.Collections { throw new ArgumentOutOfRangeException("index"); } + this.CheckMutable(); Array.Copy(array, index + 1, array, index, count - index - 1); count--; array[count] = default(T); @@ -259,6 +289,7 @@ namespace Google.Protobuf.Collections { throw new ArgumentOutOfRangeException("index"); } + this.CheckMutable(); if (value == null) { throw new ArgumentNullException("value"); diff --git a/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs b/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs index 23d5e964..eedb21fe 100644 --- a/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs +++ b/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs @@ -292,6 +292,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FileDescriptorSet__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public FileDescriptorSet() { } public FileDescriptorSet(FileDescriptorSet other) { @@ -302,6 +305,14 @@ namespace Google.Protobuf.DescriptorProtos { return new FileDescriptorSet(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + file_.Freeze(); + } + public const int FileFieldNumber = 1; private readonly pbc::RepeatedField file_ = new pbc::RepeatedField(); public pbc::RepeatedField File { @@ -388,6 +399,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FileDescriptorProto__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public FileDescriptorProto() { } public FileDescriptorProto(FileDescriptorProto other) { @@ -409,22 +423,42 @@ namespace Google.Protobuf.DescriptorProtos { return new FileDescriptorProto(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + dependency_.Freeze(); + publicDependency_.Freeze(); + weakDependency_.Freeze(); + messageType_.Freeze(); + enumType_.Freeze(); + service_.Freeze(); + extension_.Freeze(); + if (options_ != null) Options.Freeze(); + if (sourceCodeInfo_ != null) SourceCodeInfo.Freeze(); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { get { return name_; } - set { name_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + name_ = value ?? ""; + } } - public const int PackageFieldNumber = 2; private string package_ = ""; public string Package { get { return package_; } - set { package_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + package_ = value ?? ""; + } } - public const int DependencyFieldNumber = 3; private readonly pbc::RepeatedField dependency_ = new pbc::RepeatedField(); public pbc::RepeatedField Dependency { @@ -471,24 +505,32 @@ namespace Google.Protobuf.DescriptorProtos { private global::Google.Protobuf.DescriptorProtos.FileOptions options_; public global::Google.Protobuf.DescriptorProtos.FileOptions Options { get { return options_; } - set { options_ = value; } + set { + pb::Freezable.CheckMutable(this); + options_ = value; + } } public const int SourceCodeInfoFieldNumber = 9; private global::Google.Protobuf.DescriptorProtos.SourceCodeInfo sourceCodeInfo_; public global::Google.Protobuf.DescriptorProtos.SourceCodeInfo SourceCodeInfo { get { return sourceCodeInfo_; } - set { sourceCodeInfo_ = value; } + set { + pb::Freezable.CheckMutable(this); + sourceCodeInfo_ = value; + } } public const int SyntaxFieldNumber = 12; private string syntax_ = ""; public string Syntax { get { return syntax_; } - set { syntax_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + syntax_ = value ?? ""; + } } - public override bool Equals(object other) { return Equals(other as FileDescriptorProto); } @@ -509,7 +551,9 @@ namespace Google.Protobuf.DescriptorProtos { if(!enumType_.Equals(other.enumType_)) return false; if(!service_.Equals(other.service_)) return false; if(!extension_.Equals(other.extension_)) return false; - if (!object.Equals(Options, other.Options)) return false;if (!object.Equals(SourceCodeInfo, other.SourceCodeInfo)) return false;if (Syntax != other.Syntax) return false; + if (!object.Equals(Options, other.Options)) return false; + if (!object.Equals(SourceCodeInfo, other.SourceCodeInfo)) return false; + if (Syntax != other.Syntax) return false; return true; } @@ -763,6 +807,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_DescriptorProto__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public DescriptorProto() { } public DescriptorProto(DescriptorProto other) { @@ -782,14 +829,32 @@ namespace Google.Protobuf.DescriptorProtos { return new DescriptorProto(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + field_.Freeze(); + extension_.Freeze(); + nestedType_.Freeze(); + enumType_.Freeze(); + extensionRange_.Freeze(); + oneofDecl_.Freeze(); + if (options_ != null) Options.Freeze(); + reservedRange_.Freeze(); + reservedName_.Freeze(); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { get { return name_; } - set { name_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + name_ = value ?? ""; + } } - public const int FieldFieldNumber = 2; private readonly pbc::RepeatedField field_ = new pbc::RepeatedField(); public pbc::RepeatedField Field { @@ -830,7 +895,10 @@ namespace Google.Protobuf.DescriptorProtos { private global::Google.Protobuf.DescriptorProtos.MessageOptions options_; public global::Google.Protobuf.DescriptorProtos.MessageOptions Options { get { return options_; } - set { options_ = value; } + set { + pb::Freezable.CheckMutable(this); + options_ = value; + } } public const int ReservedRangeFieldNumber = 9; @@ -863,7 +931,8 @@ namespace Google.Protobuf.DescriptorProtos { if(!enumType_.Equals(other.enumType_)) return false; if(!extensionRange_.Equals(other.extensionRange_)) return false; if(!oneofDecl_.Equals(other.oneofDecl_)) return false; - if (!object.Equals(Options, other.Options)) return false;if(!reservedRange_.Equals(other.reservedRange_)) return false; + if (!object.Equals(Options, other.Options)) return false; + if(!reservedRange_.Equals(other.reservedRange_)) return false; if(!reservedName_.Equals(other.reservedName_)) return false; return true; } @@ -1077,6 +1146,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_DescriptorProto_ExtensionRange__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public ExtensionRange() { } public ExtensionRange(ExtensionRange other) { @@ -1088,22 +1160,33 @@ namespace Google.Protobuf.DescriptorProtos { return new ExtensionRange(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int StartFieldNumber = 1; private int start_; public int Start { get { return start_; } - set { start_ = value; } + set { + pb::Freezable.CheckMutable(this); + start_ = value; + } } - public const int EndFieldNumber = 2; private int end_; public int End { get { return end_; } - set { end_ = value; } + set { + pb::Freezable.CheckMutable(this); + end_ = value; + } } - public override bool Equals(object other) { return Equals(other as ExtensionRange); } @@ -1200,6 +1283,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_DescriptorProto_ReservedRange__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public ReservedRange() { } public ReservedRange(ReservedRange other) { @@ -1211,22 +1297,33 @@ namespace Google.Protobuf.DescriptorProtos { return new ReservedRange(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int StartFieldNumber = 1; private int start_; public int Start { get { return start_; } - set { start_ = value; } + set { + pb::Freezable.CheckMutable(this); + start_ = value; + } } - public const int EndFieldNumber = 2; private int end_; public int End { get { return end_; } - set { end_ = value; } + set { + pb::Freezable.CheckMutable(this); + end_ = value; + } } - public override bool Equals(object other) { return Equals(other as ReservedRange); } @@ -1328,6 +1425,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FieldDescriptorProto__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public FieldDescriptorProto() { } public FieldDescriptorProto(FieldDescriptorProto other) { @@ -1346,75 +1446,102 @@ namespace Google.Protobuf.DescriptorProtos { return new FieldDescriptorProto(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (options_ != null) Options.Freeze(); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { get { return name_; } - set { name_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + name_ = value ?? ""; + } } - public const int NumberFieldNumber = 3; private int number_; public int Number { get { return number_; } - set { number_ = value; } + set { + pb::Freezable.CheckMutable(this); + number_ = value; + } } - public const int LabelFieldNumber = 4; private global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Label label_ = global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL; public global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Label Label { get { return label_; } - set { label_ = value; } + set { + pb::Freezable.CheckMutable(this); + label_ = value; + } } - public const int TypeFieldNumber = 5; private global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Type type_ = global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Type.TYPE_DOUBLE; public global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Type Type { get { return type_; } - set { type_ = value; } + set { + pb::Freezable.CheckMutable(this); + type_ = value; + } } - public const int TypeNameFieldNumber = 6; private string typeName_ = ""; public string TypeName { get { return typeName_; } - set { typeName_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + typeName_ = value ?? ""; + } } - public const int ExtendeeFieldNumber = 2; private string extendee_ = ""; public string Extendee { get { return extendee_; } - set { extendee_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + extendee_ = value ?? ""; + } } - public const int DefaultValueFieldNumber = 7; private string defaultValue_ = ""; public string DefaultValue { get { return defaultValue_; } - set { defaultValue_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + defaultValue_ = value ?? ""; + } } - public const int OneofIndexFieldNumber = 9; private int oneofIndex_; public int OneofIndex { get { return oneofIndex_; } - set { oneofIndex_ = value; } + set { + pb::Freezable.CheckMutable(this); + oneofIndex_ = value; + } } - public const int OptionsFieldNumber = 8; private global::Google.Protobuf.DescriptorProtos.FieldOptions options_; public global::Google.Protobuf.DescriptorProtos.FieldOptions Options { get { return options_; } - set { options_ = value; } + set { + pb::Freezable.CheckMutable(this); + options_ = value; + } } public override bool Equals(object other) { @@ -1436,7 +1563,8 @@ namespace Google.Protobuf.DescriptorProtos { if (Extendee != other.Extendee) return false; if (DefaultValue != other.DefaultValue) return false; if (OneofIndex != other.OneofIndex) return false; - if (!object.Equals(Options, other.Options)) return false; return true; + if (!object.Equals(Options, other.Options)) return false; + return true; } public override int GetHashCode() { @@ -1663,6 +1791,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_OneofDescriptorProto__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public OneofDescriptorProto() { } public OneofDescriptorProto(OneofDescriptorProto other) { @@ -1673,14 +1804,23 @@ namespace Google.Protobuf.DescriptorProtos { return new OneofDescriptorProto(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { get { return name_; } - set { name_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + name_ = value ?? ""; + } } - public override bool Equals(object other) { return Equals(other as OneofDescriptorProto); } @@ -1761,6 +1901,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumDescriptorProto__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public EnumDescriptorProto() { } public EnumDescriptorProto(EnumDescriptorProto other) { @@ -1773,14 +1916,25 @@ namespace Google.Protobuf.DescriptorProtos { return new EnumDescriptorProto(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + value_.Freeze(); + if (options_ != null) Options.Freeze(); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { get { return name_; } - set { name_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + name_ = value ?? ""; + } } - public const int ValueFieldNumber = 2; private readonly pbc::RepeatedField value_ = new pbc::RepeatedField(); public pbc::RepeatedField Value { @@ -1791,7 +1945,10 @@ namespace Google.Protobuf.DescriptorProtos { private global::Google.Protobuf.DescriptorProtos.EnumOptions options_; public global::Google.Protobuf.DescriptorProtos.EnumOptions Options { get { return options_; } - set { options_ = value; } + set { + pb::Freezable.CheckMutable(this); + options_ = value; + } } public override bool Equals(object other) { @@ -1807,7 +1964,8 @@ namespace Google.Protobuf.DescriptorProtos { } if (Name != other.Name) return false; if(!value_.Equals(other.value_)) return false; - if (!object.Equals(Options, other.Options)) return false; return true; + if (!object.Equals(Options, other.Options)) return false; + return true; } public override int GetHashCode() { @@ -1911,6 +2069,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumValueDescriptorProto__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public EnumValueDescriptorProto() { } public EnumValueDescriptorProto(EnumValueDescriptorProto other) { @@ -1923,27 +2084,42 @@ namespace Google.Protobuf.DescriptorProtos { return new EnumValueDescriptorProto(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (options_ != null) Options.Freeze(); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { get { return name_; } - set { name_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + name_ = value ?? ""; + } } - public const int NumberFieldNumber = 2; private int number_; public int Number { get { return number_; } - set { number_ = value; } + set { + pb::Freezable.CheckMutable(this); + number_ = value; + } } - public const int OptionsFieldNumber = 3; private global::Google.Protobuf.DescriptorProtos.EnumValueOptions options_; public global::Google.Protobuf.DescriptorProtos.EnumValueOptions Options { get { return options_; } - set { options_ = value; } + set { + pb::Freezable.CheckMutable(this); + options_ = value; + } } public override bool Equals(object other) { @@ -1959,7 +2135,8 @@ namespace Google.Protobuf.DescriptorProtos { } if (Name != other.Name) return false; if (Number != other.Number) return false; - if (!object.Equals(Options, other.Options)) return false; return true; + if (!object.Equals(Options, other.Options)) return false; + return true; } public override int GetHashCode() { @@ -2063,6 +2240,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_ServiceDescriptorProto__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public ServiceDescriptorProto() { } public ServiceDescriptorProto(ServiceDescriptorProto other) { @@ -2075,14 +2255,25 @@ namespace Google.Protobuf.DescriptorProtos { return new ServiceDescriptorProto(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + method_.Freeze(); + if (options_ != null) Options.Freeze(); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { get { return name_; } - set { name_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + name_ = value ?? ""; + } } - public const int MethodFieldNumber = 2; private readonly pbc::RepeatedField method_ = new pbc::RepeatedField(); public pbc::RepeatedField Method { @@ -2093,7 +2284,10 @@ namespace Google.Protobuf.DescriptorProtos { private global::Google.Protobuf.DescriptorProtos.ServiceOptions options_; public global::Google.Protobuf.DescriptorProtos.ServiceOptions Options { get { return options_; } - set { options_ = value; } + set { + pb::Freezable.CheckMutable(this); + options_ = value; + } } public override bool Equals(object other) { @@ -2109,7 +2303,8 @@ namespace Google.Protobuf.DescriptorProtos { } if (Name != other.Name) return false; if(!method_.Equals(other.method_)) return false; - if (!object.Equals(Options, other.Options)) return false; return true; + if (!object.Equals(Options, other.Options)) return false; + return true; } public override int GetHashCode() { @@ -2213,6 +2408,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_MethodDescriptorProto__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public MethodDescriptorProto() { } public MethodDescriptorProto(MethodDescriptorProto other) { @@ -2228,53 +2426,74 @@ namespace Google.Protobuf.DescriptorProtos { return new MethodDescriptorProto(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + if (options_ != null) Options.Freeze(); + } + public const int NameFieldNumber = 1; private string name_ = ""; public string Name { get { return name_; } - set { name_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + name_ = value ?? ""; + } } - public const int InputTypeFieldNumber = 2; private string inputType_ = ""; public string InputType { get { return inputType_; } - set { inputType_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + inputType_ = value ?? ""; + } } - public const int OutputTypeFieldNumber = 3; private string outputType_ = ""; public string OutputType { get { return outputType_; } - set { outputType_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + outputType_ = value ?? ""; + } } - public const int OptionsFieldNumber = 4; private global::Google.Protobuf.DescriptorProtos.MethodOptions options_; public global::Google.Protobuf.DescriptorProtos.MethodOptions Options { get { return options_; } - set { options_ = value; } + set { + pb::Freezable.CheckMutable(this); + options_ = value; + } } public const int ClientStreamingFieldNumber = 5; private bool clientStreaming_; public bool ClientStreaming { get { return clientStreaming_; } - set { clientStreaming_ = value; } + set { + pb::Freezable.CheckMutable(this); + clientStreaming_ = value; + } } - public const int ServerStreamingFieldNumber = 6; private bool serverStreaming_; public bool ServerStreaming { get { return serverStreaming_; } - set { serverStreaming_ = value; } + set { + pb::Freezable.CheckMutable(this); + serverStreaming_ = value; + } } - public override bool Equals(object other) { return Equals(other as MethodDescriptorProto); } @@ -2289,7 +2508,8 @@ namespace Google.Protobuf.DescriptorProtos { if (Name != other.Name) return false; if (InputType != other.InputType) return false; if (OutputType != other.OutputType) return false; - if (!object.Equals(Options, other.Options)) return false;if (ClientStreaming != other.ClientStreaming) return false; + if (!object.Equals(Options, other.Options)) return false; + if (ClientStreaming != other.ClientStreaming) return false; if (ServerStreaming != other.ServerStreaming) return false; return true; } @@ -2440,6 +2660,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FileOptions__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public FileOptions() { } public FileOptions(FileOptions other) { @@ -2464,118 +2687,154 @@ namespace Google.Protobuf.DescriptorProtos { return new FileOptions(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + uninterpretedOption_.Freeze(); + } + public const int JavaPackageFieldNumber = 1; private string javaPackage_ = ""; public string JavaPackage { get { return javaPackage_; } - set { javaPackage_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + javaPackage_ = value ?? ""; + } } - public const int JavaOuterClassnameFieldNumber = 8; private string javaOuterClassname_ = ""; public string JavaOuterClassname { get { return javaOuterClassname_; } - set { javaOuterClassname_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + javaOuterClassname_ = value ?? ""; + } } - public const int JavaMultipleFilesFieldNumber = 10; private bool javaMultipleFiles_; public bool JavaMultipleFiles { get { return javaMultipleFiles_; } - set { javaMultipleFiles_ = value; } + set { + pb::Freezable.CheckMutable(this); + javaMultipleFiles_ = value; + } } - public const int JavaGenerateEqualsAndHashFieldNumber = 20; private bool javaGenerateEqualsAndHash_; public bool JavaGenerateEqualsAndHash { get { return javaGenerateEqualsAndHash_; } - set { javaGenerateEqualsAndHash_ = value; } + set { + pb::Freezable.CheckMutable(this); + javaGenerateEqualsAndHash_ = value; + } } - public const int JavaStringCheckUtf8FieldNumber = 27; private bool javaStringCheckUtf8_; public bool JavaStringCheckUtf8 { get { return javaStringCheckUtf8_; } - set { javaStringCheckUtf8_ = value; } + set { + pb::Freezable.CheckMutable(this); + javaStringCheckUtf8_ = value; + } } - public const int OptimizeForFieldNumber = 9; private global::Google.Protobuf.DescriptorProtos.FileOptions.Types.OptimizeMode optimizeFor_ = global::Google.Protobuf.DescriptorProtos.FileOptions.Types.OptimizeMode.SPEED; public global::Google.Protobuf.DescriptorProtos.FileOptions.Types.OptimizeMode OptimizeFor { get { return optimizeFor_; } - set { optimizeFor_ = value; } + set { + pb::Freezable.CheckMutable(this); + optimizeFor_ = value; + } } - public const int GoPackageFieldNumber = 11; private string goPackage_ = ""; public string GoPackage { get { return goPackage_; } - set { goPackage_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + goPackage_ = value ?? ""; + } } - public const int CcGenericServicesFieldNumber = 16; private bool ccGenericServices_; public bool CcGenericServices { get { return ccGenericServices_; } - set { ccGenericServices_ = value; } + set { + pb::Freezable.CheckMutable(this); + ccGenericServices_ = value; + } } - public const int JavaGenericServicesFieldNumber = 17; private bool javaGenericServices_; public bool JavaGenericServices { get { return javaGenericServices_; } - set { javaGenericServices_ = value; } + set { + pb::Freezable.CheckMutable(this); + javaGenericServices_ = value; + } } - public const int PyGenericServicesFieldNumber = 18; private bool pyGenericServices_; public bool PyGenericServices { get { return pyGenericServices_; } - set { pyGenericServices_ = value; } + set { + pb::Freezable.CheckMutable(this); + pyGenericServices_ = value; + } } - public const int DeprecatedFieldNumber = 23; private bool deprecated_; public bool Deprecated { get { return deprecated_; } - set { deprecated_ = value; } + set { + pb::Freezable.CheckMutable(this); + deprecated_ = value; + } } - public const int CcEnableArenasFieldNumber = 31; private bool ccEnableArenas_; public bool CcEnableArenas { get { return ccEnableArenas_; } - set { ccEnableArenas_ = value; } + set { + pb::Freezable.CheckMutable(this); + ccEnableArenas_ = value; + } } - public const int ObjcClassPrefixFieldNumber = 36; private string objcClassPrefix_ = ""; public string ObjcClassPrefix { get { return objcClassPrefix_; } - set { objcClassPrefix_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + objcClassPrefix_ = value ?? ""; + } } - public const int CsharpNamespaceFieldNumber = 37; private string csharpNamespace_ = ""; public string CsharpNamespace { get { return csharpNamespace_; } - set { csharpNamespace_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + csharpNamespace_ = value ?? ""; + } } - public const int UninterpretedOptionFieldNumber = 999; private readonly pbc::RepeatedField uninterpretedOption_ = new pbc::RepeatedField(); public pbc::RepeatedField UninterpretedOption { @@ -2898,6 +3157,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_MessageOptions__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public MessageOptions() { } public MessageOptions(MessageOptions other) { @@ -2912,38 +3174,54 @@ namespace Google.Protobuf.DescriptorProtos { return new MessageOptions(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + uninterpretedOption_.Freeze(); + } + public const int MessageSetWireFormatFieldNumber = 1; private bool messageSetWireFormat_; public bool MessageSetWireFormat { get { return messageSetWireFormat_; } - set { messageSetWireFormat_ = value; } + set { + pb::Freezable.CheckMutable(this); + messageSetWireFormat_ = value; + } } - public const int NoStandardDescriptorAccessorFieldNumber = 2; private bool noStandardDescriptorAccessor_; public bool NoStandardDescriptorAccessor { get { return noStandardDescriptorAccessor_; } - set { noStandardDescriptorAccessor_ = value; } + set { + pb::Freezable.CheckMutable(this); + noStandardDescriptorAccessor_ = value; + } } - public const int DeprecatedFieldNumber = 3; private bool deprecated_; public bool Deprecated { get { return deprecated_; } - set { deprecated_ = value; } + set { + pb::Freezable.CheckMutable(this); + deprecated_ = value; + } } - public const int MapEntryFieldNumber = 7; private bool mapEntry_; public bool MapEntry { get { return mapEntry_; } - set { mapEntry_ = value; } + set { + pb::Freezable.CheckMutable(this); + mapEntry_ = value; + } } - public const int UninterpretedOptionFieldNumber = 999; private readonly pbc::RepeatedField uninterpretedOption_ = new pbc::RepeatedField(); public pbc::RepeatedField UninterpretedOption { @@ -3094,6 +3372,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_FieldOptions__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public FieldOptions() { } public FieldOptions(FieldOptions other) { @@ -3110,54 +3391,74 @@ namespace Google.Protobuf.DescriptorProtos { return new FieldOptions(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + uninterpretedOption_.Freeze(); + } + 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 { get { return ctype_; } - set { ctype_ = value; } + set { + pb::Freezable.CheckMutable(this); + ctype_ = value; + } } - public const int PackedFieldNumber = 2; private bool packed_; public bool Packed { get { return packed_; } - set { packed_ = value; } + set { + pb::Freezable.CheckMutable(this); + packed_ = value; + } } - public const int JstypeFieldNumber = 6; private global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.JSType jstype_ = global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.JSType.JS_NORMAL; public global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.JSType Jstype { get { return jstype_; } - set { jstype_ = value; } + set { + pb::Freezable.CheckMutable(this); + jstype_ = value; + } } - public const int LazyFieldNumber = 5; private bool lazy_; public bool Lazy { get { return lazy_; } - set { lazy_ = value; } + set { + pb::Freezable.CheckMutable(this); + lazy_ = value; + } } - public const int DeprecatedFieldNumber = 3; private bool deprecated_; public bool Deprecated { get { return deprecated_; } - set { deprecated_ = value; } + set { + pb::Freezable.CheckMutable(this); + deprecated_ = value; + } } - public const int WeakFieldNumber = 10; private bool weak_; public bool Weak { get { return weak_; } - set { weak_ = value; } + set { + pb::Freezable.CheckMutable(this); + weak_ = value; + } } - public const int UninterpretedOptionFieldNumber = 999; private readonly pbc::RepeatedField uninterpretedOption_ = new pbc::RepeatedField(); public pbc::RepeatedField UninterpretedOption { @@ -3358,6 +3659,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumOptions__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public EnumOptions() { } public EnumOptions(EnumOptions other) { @@ -3370,22 +3674,34 @@ namespace Google.Protobuf.DescriptorProtos { return new EnumOptions(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + uninterpretedOption_.Freeze(); + } + public const int AllowAliasFieldNumber = 2; private bool allowAlias_; public bool AllowAlias { get { return allowAlias_; } - set { allowAlias_ = value; } + set { + pb::Freezable.CheckMutable(this); + allowAlias_ = value; + } } - public const int DeprecatedFieldNumber = 3; private bool deprecated_; public bool Deprecated { get { return deprecated_; } - set { deprecated_ = value; } + set { + pb::Freezable.CheckMutable(this); + deprecated_ = value; + } } - public const int UninterpretedOptionFieldNumber = 999; private readonly pbc::RepeatedField uninterpretedOption_ = new pbc::RepeatedField(); public pbc::RepeatedField UninterpretedOption { @@ -3504,6 +3820,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_EnumValueOptions__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public EnumValueOptions() { } public EnumValueOptions(EnumValueOptions other) { @@ -3515,14 +3834,24 @@ namespace Google.Protobuf.DescriptorProtos { return new EnumValueOptions(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + uninterpretedOption_.Freeze(); + } + public const int DeprecatedFieldNumber = 1; private bool deprecated_; public bool Deprecated { get { return deprecated_; } - set { deprecated_ = value; } + set { + pb::Freezable.CheckMutable(this); + deprecated_ = value; + } } - public const int UninterpretedOptionFieldNumber = 999; private readonly pbc::RepeatedField uninterpretedOption_ = new pbc::RepeatedField(); public pbc::RepeatedField UninterpretedOption { @@ -3625,6 +3954,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_ServiceOptions__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public ServiceOptions() { } public ServiceOptions(ServiceOptions other) { @@ -3636,14 +3968,24 @@ namespace Google.Protobuf.DescriptorProtos { return new ServiceOptions(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + uninterpretedOption_.Freeze(); + } + public const int DeprecatedFieldNumber = 33; private bool deprecated_; public bool Deprecated { get { return deprecated_; } - set { deprecated_ = value; } + set { + pb::Freezable.CheckMutable(this); + deprecated_ = value; + } } - public const int UninterpretedOptionFieldNumber = 999; private readonly pbc::RepeatedField uninterpretedOption_ = new pbc::RepeatedField(); public pbc::RepeatedField UninterpretedOption { @@ -3746,6 +4088,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_MethodOptions__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public MethodOptions() { } public MethodOptions(MethodOptions other) { @@ -3757,14 +4102,24 @@ namespace Google.Protobuf.DescriptorProtos { return new MethodOptions(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + uninterpretedOption_.Freeze(); + } + public const int DeprecatedFieldNumber = 33; private bool deprecated_; public bool Deprecated { get { return deprecated_; } - set { deprecated_ = value; } + set { + pb::Freezable.CheckMutable(this); + deprecated_ = value; + } } - public const int UninterpretedOptionFieldNumber = 999; private readonly pbc::RepeatedField uninterpretedOption_ = new pbc::RepeatedField(); public pbc::RepeatedField UninterpretedOption { @@ -3867,6 +4222,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_UninterpretedOption__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public UninterpretedOption() { } public UninterpretedOption(UninterpretedOption other) { @@ -3883,6 +4241,14 @@ namespace Google.Protobuf.DescriptorProtos { return new UninterpretedOption(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + name_.Freeze(); + } + public const int NameFieldNumber = 2; private readonly pbc::RepeatedField name_ = new pbc::RepeatedField(); public pbc::RepeatedField Name { @@ -3893,50 +4259,62 @@ namespace Google.Protobuf.DescriptorProtos { private string identifierValue_ = ""; public string IdentifierValue { get { return identifierValue_; } - set { identifierValue_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + identifierValue_ = value ?? ""; + } } - public const int PositiveIntValueFieldNumber = 4; private ulong positiveIntValue_; public ulong PositiveIntValue { get { return positiveIntValue_; } - set { positiveIntValue_ = value; } + set { + pb::Freezable.CheckMutable(this); + positiveIntValue_ = value; + } } - public const int NegativeIntValueFieldNumber = 5; private long negativeIntValue_; public long NegativeIntValue { get { return negativeIntValue_; } - set { negativeIntValue_ = value; } + set { + pb::Freezable.CheckMutable(this); + negativeIntValue_ = value; + } } - public const int DoubleValueFieldNumber = 6; private double doubleValue_; public double DoubleValue { get { return doubleValue_; } - set { doubleValue_ = value; } + set { + pb::Freezable.CheckMutable(this); + doubleValue_ = value; + } } - public const int StringValueFieldNumber = 7; private pb::ByteString stringValue_ = pb::ByteString.Empty; public pb::ByteString StringValue { get { return stringValue_; } - set { stringValue_ = value ?? pb::ByteString.Empty; } + set { + pb::Freezable.CheckMutable(this); + stringValue_ = value ?? pb::ByteString.Empty; + } } - public const int AggregateValueFieldNumber = 8; private string aggregateValue_ = ""; public string AggregateValue { get { return aggregateValue_; } - set { aggregateValue_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + aggregateValue_ = value ?? ""; + } } - public override bool Equals(object other) { return Equals(other as UninterpretedOption); } @@ -4114,6 +4492,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_UninterpretedOption_NamePart__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public NamePart() { } public NamePart(NamePart other) { @@ -4125,22 +4506,33 @@ namespace Google.Protobuf.DescriptorProtos { return new NamePart(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + } + public const int NamePart_FieldNumber = 1; private string namePart_ = ""; public string NamePart_ { get { return namePart_; } - set { namePart_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + namePart_ = value ?? ""; + } } - public const int IsExtensionFieldNumber = 2; private bool isExtension_; public bool IsExtension { get { return isExtension_; } - set { isExtension_ = value; } + set { + pb::Freezable.CheckMutable(this); + isExtension_ = value; + } } - public override bool Equals(object other) { return Equals(other as NamePart); } @@ -4242,6 +4634,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_SourceCodeInfo__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public SourceCodeInfo() { } public SourceCodeInfo(SourceCodeInfo other) { @@ -4252,6 +4647,14 @@ namespace Google.Protobuf.DescriptorProtos { return new SourceCodeInfo(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + location_.Freeze(); + } + public const int LocationFieldNumber = 1; private readonly pbc::RepeatedField location_ = new pbc::RepeatedField(); public pbc::RepeatedField Location { @@ -4339,6 +4742,9 @@ namespace Google.Protobuf.DescriptorProtos { get { return global::Google.Protobuf.DescriptorProtos.DescriptorProtoFile.internal__static_google_protobuf_SourceCodeInfo_Location__FieldAccessorTable; } } + private bool _frozen = false; + public bool IsFrozen { get { return _frozen; } } + public Location() { } public Location(Location other) { @@ -4353,6 +4759,16 @@ namespace Google.Protobuf.DescriptorProtos { return new Location(this); } + public void Freeze() { + if (IsFrozen) { + return; + } + _frozen = true; + path_.Freeze(); + span_.Freeze(); + leadingDetachedComments_.Freeze(); + } + public const int PathFieldNumber = 1; private readonly pbc::RepeatedField path_ = new pbc::RepeatedField(); public pbc::RepeatedField Path { @@ -4369,18 +4785,22 @@ namespace Google.Protobuf.DescriptorProtos { private string leadingComments_ = ""; public string LeadingComments { get { return leadingComments_; } - set { leadingComments_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + leadingComments_ = value ?? ""; + } } - public const int TrailingCommentsFieldNumber = 4; private string trailingComments_ = ""; public string TrailingComments { get { return trailingComments_; } - set { trailingComments_ = value ?? ""; } + set { + pb::Freezable.CheckMutable(this); + trailingComments_ = value ?? ""; + } } - public const int LeadingDetachedCommentsFieldNumber = 6; private readonly pbc::RepeatedField leadingDetachedComments_ = new pbc::RepeatedField(); public pbc::RepeatedField LeadingDetachedComments { diff --git a/csharp/src/ProtocolBuffers/Freezable.cs b/csharp/src/ProtocolBuffers/Freezable.cs new file mode 100644 index 00000000..40b4398a --- /dev/null +++ b/csharp/src/ProtocolBuffers/Freezable.cs @@ -0,0 +1,60 @@ +#region Copyright notice and license + +// Protocol Buffers - Google's data interchange format +// Copyright 2015 Google Inc. All rights reserved. +// http://github.com/google/protobuf +// +// 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. + +#endregion + +using System; + +namespace Google.Protobuf +{ + /// + /// Extension methods for types. + /// + public static class Freezable + { + /// + /// Throws an if + /// is frozen. + /// + /// + /// This is a convenience methods that freezable types can call before all + /// mutations, to protect frozen objects. + /// + public static void CheckMutable(this IFreezable target) + { + if (target.IsFrozen) + { + throw new InvalidOperationException("Attempt to mutate frozen object"); + } + } + } +} diff --git a/csharp/src/ProtocolBuffers/IMessage.cs b/csharp/src/ProtocolBuffers/IMessage.cs index 5d662cfd..d606aee1 100644 --- a/csharp/src/ProtocolBuffers/IMessage.cs +++ b/csharp/src/ProtocolBuffers/IMessage.cs @@ -41,6 +41,7 @@ namespace Google.Protobuf { // TODO(jonskeet): Do we want a "weak" (non-generic) version of IReflectedMessage? + // TODO(jonskeet): Split these interfaces into separate files when we're happy with them. /// /// Reflection support for a specific message type. message @@ -85,7 +86,7 @@ namespace Google.Protobuf /// the implementation class. /// /// The message type. - public interface IMessage : IMessage, IEquatable, IDeepCloneable where T : IMessage + public interface IMessage : IMessage, IEquatable, IDeepCloneable, IFreezable where T : IMessage { /// /// Merges the given message into this one. @@ -102,6 +103,11 @@ namespace Google.Protobuf /// All generated messages implement this interface, but so do some non-message types. /// Additionally, due to the type constraint on T in , /// it is simpler to keep this as a separate interface. + /// + /// + /// Freezable types which implement this interface should always return a mutable clone, + /// even if the original object is frozen. + /// /// /// The type itself, returned by the method. public interface IDeepCloneable @@ -112,4 +118,32 @@ namespace Google.Protobuf /// A deep clone of this object. T Clone(); } + + /// + /// Provides a mechanism for freezing a message (or repeated field collection) + /// to make it immutable. + /// + /// + /// Implementations are under no obligation to make this thread-safe: if a freezable + /// type instance is shared between threads before being frozen, and one thread then + /// freezes it, it is possible for other threads to make changes during the freezing + /// operation and also to observe stale values for mutated fields. Objects should be + /// frozen before being made available to other threads. + /// + public interface IFreezable + { + /// + /// Freezes this object. + /// + /// + /// If the object is already frozen, this method has no effect. + /// + void Freeze(); + + /// + /// Returns whether or not this object is frozen (and therefore immutable). + /// + /// true if this object is frozen; false otherwise. + bool IsFrozen { get; } + } } diff --git a/csharp/src/ProtocolBuffers/ProtocolBuffers.csproj b/csharp/src/ProtocolBuffers/ProtocolBuffers.csproj index 33a32ff2..d1551148 100644 --- a/csharp/src/ProtocolBuffers/ProtocolBuffers.csproj +++ b/csharp/src/ProtocolBuffers/ProtocolBuffers.csproj @@ -85,6 +85,7 @@ + diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc index 54f281ee..0bfbc70e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -107,6 +107,11 @@ FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor, FieldGeneratorBase::~FieldGeneratorBase() { } +void FieldGeneratorBase::GenerateFreezingCode(io::Printer* printer) { + // No-op: only message fields and repeated fields need + // special handling for freezing, so default to not generating any code. +} + void FieldGeneratorBase::AddDeprecatedFlag(io::Printer* printer) { if (descriptor_->options().deprecated()) { diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h index 91ae3ba1..abf9254b 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.h +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h @@ -48,6 +48,7 @@ class FieldGeneratorBase : public SourceGeneratorBase { ~FieldGeneratorBase(); virtual void GenerateCloningCode(io::Printer* printer) = 0; + virtual void GenerateFreezingCode(io::Printer* printer); 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 39938fa3..9580c167 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -211,7 +211,9 @@ void MessageGenerator::Generate(io::Printer* printer) { "public pb::FieldAccess.FieldAccessorTable<$class_name$> Fields {\n" " get { return $umbrella_class_name$.internal__$identifier$__FieldAccessorTable; }\n" "}\n" - "\n"); + "\n" + "private bool _frozen = false;\n" + "public bool IsFrozen { get { return _frozen; } }\n\n"); // Parameterless constructor printer->Print( @@ -219,6 +221,7 @@ void MessageGenerator::Generate(io::Printer* printer) { "public $class_name$() { }\n\n"); GenerateCloningCode(printer); + GenerateFreezingCode(printer); // Fields/properties for (int i = 0; i < descriptor_->field_count(); i++) { @@ -260,6 +263,7 @@ void MessageGenerator::Generate(io::Printer* printer) { " get { return $name$Case_; }\n" "}\n\n" "public void Clear$property_name$() {\n" + " pb::Freezable.CheckMutable(this);\n" " $name$Case_ = $property_name$OneofCase.None;\n" " $name$_ = null;\n" "}\n\n"); @@ -346,6 +350,36 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) { "}\n\n"); } +void MessageGenerator::GenerateFreezingCode(io::Printer* printer) { + map vars; + vars["class_name"] = class_name(); + printer->Print( + "public void Freeze() {\n" + " if (IsFrozen) {\n" + " return;\n" + " }\n" + " _frozen = true;\n"); + printer->Indent(); + // Freeze non-oneof fields first (only messages and repeated fields will actually generate any code) + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!descriptor_->field(i)->containing_oneof()) { + scoped_ptr generator( + CreateFieldGeneratorInternal(descriptor_->field(i))); + generator->GenerateFreezingCode(printer); + } + } + + // For each oneof, if the value is freezable, freeze it. We don't actually need to know which type it was. + for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { + vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false); + printer->Print(vars, + "if ($name$_ is IFreezable) ((IFreezable) $name$_).Freeze();\n"); + } + + printer->Outdent(); + printer->Print("}\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 c3a37a0e..6c7153aa 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.h +++ b/src/google/protobuf/compiler/csharp/csharp_message.h @@ -51,6 +51,7 @@ class MessageGenerator : public SourceGeneratorBase { ~MessageGenerator(); void GenerateCloningCode(io::Printer* printer); + void GenerateFreezingCode(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 82deef54..cbf182d2 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -66,7 +66,10 @@ void MessageFieldGenerator::GenerateMembers(io::Printer* printer) { variables_, "public $type_name$ $property_name$ {\n" " get { return $name$_; }\n" - " set { $name$_ = value; }\n" + " set {\n" + " pb::Freezable.CheckMutable(this);\n" + " $name$_ = value;\n" + " }\n" "}\n"); } @@ -116,7 +119,7 @@ void MessageFieldGenerator::WriteHash(io::Printer* printer) { void MessageFieldGenerator::WriteEquals(io::Printer* printer) { printer->Print( variables_, - "if (!object.Equals($property_name$, other.$property_name$)) return false;"); + "if (!object.Equals($property_name$, other.$property_name$)) return false;\n"); } void MessageFieldGenerator::WriteToString(io::Printer* printer) { variables_["field_name"] = GetFieldName(descriptor_); @@ -130,6 +133,11 @@ void MessageFieldGenerator::GenerateCloningCode(io::Printer* printer) { "$property_name$ = other.$has_property_check$ ? other.$property_name$.Clone() : null;\n"); } +void MessageFieldGenerator::GenerateFreezingCode(io::Printer* printer) { + printer->Print(variables_, + "if ($has_property_check$) $property_name$.Freeze();\n"); +} + MessageOneofFieldGenerator::MessageOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal) : MessageFieldGenerator(descriptor, fieldOrdinal) { @@ -147,6 +155,7 @@ void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) { "public $type_name$ $property_name$ {\n" " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : null; }\n" " set {\n" + " pb::Freezable.CheckMutable(this);\n" " $oneof_name$_ = value;\n" " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n" " }\n" diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.h b/src/google/protobuf/compiler/csharp/csharp_message_field.h index f15e8e7e..3e17f92a 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.h @@ -47,6 +47,7 @@ class MessageFieldGenerator : public FieldGeneratorBase { ~MessageFieldGenerator(); virtual void GenerateCloningCode(io::Printer* printer); + virtual void GenerateFreezingCode(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_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc index c426c37a..d5542f57 100644 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc @@ -72,17 +72,21 @@ void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( variables_, "public $type_name$ $property_name$ {\n" - " get { return $name$_; }\n"); + " get { return $name$_; }\n" + " set {\n" + " pb::Freezable.CheckMutable(this);\n"); if (is_value_type) { printer->Print( variables_, - " set { $name$_ = value; }\n"); + " $name$_ = value;\n"); } else { printer->Print( variables_, - " set { $name$_ = value ?? $default_value$; }\n"); + " $name$_ = value ?? $default_value$;\n"); } - printer->Print("}\n\n"); + printer->Print( + " }\n" + "}\n"); } void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) { @@ -166,7 +170,8 @@ void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) { variables_, "public $type_name$ $property_name$ {\n" " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : $default_value$; }\n" - " set {\n"); + " set {\n" + " pb::Freezable.CheckMutable(this);\n"); if (is_value_type) { printer->Print( variables_, 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 ce526b37..d223273c 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc @@ -147,6 +147,11 @@ void RepeatedEnumFieldGenerator::GenerateCloningCode(io::Printer* printer) { "$name$_ = other.$name$_.Clone();\n"); } +void RepeatedEnumFieldGenerator::GenerateFreezingCode(io::Printer* printer) { + printer->Print(variables_, + "$name$_.Freeze();\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 c7846a61..ee50eef0 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h @@ -49,6 +49,7 @@ class RepeatedEnumFieldGenerator : public FieldGeneratorBase { ~RepeatedEnumFieldGenerator(); virtual void GenerateCloningCode(io::Printer* printer); + virtual void GenerateFreezingCode(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 edfb98b4..400f0e4f 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc @@ -123,6 +123,11 @@ void RepeatedMessageFieldGenerator::GenerateCloningCode(io::Printer* printer) { "$name$_ = other.$name$_.Clone();\n"); } +void RepeatedMessageFieldGenerator::GenerateFreezingCode(io::Printer* printer) { + printer->Print(variables_, + "$name$_.Freeze();\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 38006731..cf601c7e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h @@ -47,6 +47,7 @@ class RepeatedMessageFieldGenerator : public FieldGeneratorBase { ~RepeatedMessageFieldGenerator(); virtual void GenerateCloningCode(io::Printer* printer); + virtual void GenerateFreezingCode(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 49a29c55..a78a74c0 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc @@ -153,6 +153,11 @@ void RepeatedPrimitiveFieldGenerator::GenerateCloningCode(io::Printer* printer) "$name$_ = other.$name$_.Clone();\n"); } +void RepeatedPrimitiveFieldGenerator::GenerateFreezingCode(io::Printer* printer) { + printer->Print(variables_, + "$name$_.Freeze();\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 7f8f17a8..f1ceeb50 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h @@ -47,6 +47,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase { ~RepeatedPrimitiveFieldGenerator(); virtual void GenerateCloningCode(io::Printer* printer); + virtual void GenerateFreezingCode(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer);