Commit 0bf2ad14 authored by Jon Skeet's avatar Jon Skeet

Implemented popsicle immutability for lists. Modified MessageStreamIterator to be singly generic.

parent ad6903fe
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
namespace Google.ProtocolBuffers.Collections {
[TestFixture]
public class PopsicleListTest {
[Test]
public void MutatingOperationsOnFrozenList() {
PopsicleList<string> list = new PopsicleList<string>();
list.MakeReadOnly();
AssertNotSupported(() => list.Add(""));
AssertNotSupported(() => list.Clear());
AssertNotSupported(() => list.Insert(0, ""));
AssertNotSupported(() => list.Remove(""));
AssertNotSupported(() => list.RemoveAt(0));
}
[Test]
public void NonMutatingOperationsOnFrozenList() {
PopsicleList<string> list = new PopsicleList<string>();
list.MakeReadOnly();
Assert.IsFalse(list.Contains(""));
Assert.AreEqual(0, list.Count);
list.CopyTo(new string[5], 0);
list.GetEnumerator();
Assert.AreEqual(-1, list.IndexOf(""));
Assert.IsTrue(list.IsReadOnly);
}
[Test]
public void MutatingOperationsOnFluidList() {
PopsicleList<string> list = new PopsicleList<string>();
list.Add("");
list.Clear();
list.Insert(0, "");
list.Remove("");
list.Add("x"); // Just to make the next call valid
list.RemoveAt(0);
}
[Test]
public void NonMutatingOperationsOnFluidList() {
PopsicleList<string> list = new PopsicleList<string>();
Assert.IsFalse(list.Contains(""));
Assert.AreEqual(0, list.Count);
list.CopyTo(new string[5], 0);
list.GetEnumerator();
Assert.AreEqual(-1, list.IndexOf(""));
Assert.IsFalse(list.IsReadOnly);
}
private static void AssertNotSupported(Action action) {
try {
action();
Assert.Fail("Expected NotSupportedException");
} catch (NotSupportedException) {
// Expected
}
}
}
}
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using System;
using System.Collections.Generic;
using Google.ProtocolBuffers.Descriptors; using Google.ProtocolBuffers.Descriptors;
using Google.ProtocolBuffers.TestProtos; using Google.ProtocolBuffers.TestProtos;
using NUnit.Framework; using NUnit.Framework;
...@@ -28,7 +30,50 @@ namespace Google.ProtocolBuffers { ...@@ -28,7 +30,50 @@ namespace Google.ProtocolBuffers {
reflectionTester = ReflectionTester.CreateTestAllTypesInstance(); reflectionTester = ReflectionTester.CreateTestAllTypesInstance();
extensionsReflectionTester = ReflectionTester.CreateTestAllExtensionsInstance(); extensionsReflectionTester = ReflectionTester.CreateTestAllExtensionsInstance();
} }
[Test]
public void RepeatedAddPrimitiveBeforeBuild() {
TestAllTypes message = new TestAllTypes.Builder { RepeatedInt32List = { 1, 2, 3 } }.Build();
TestUtil.AssertEqual(new int[]{1, 2, 3}, message.RepeatedInt32List);
}
[Test]
public void AddPrimitiveFailsAfterBuild() {
TestAllTypes.Builder builder = new TestAllTypes.Builder();
IList<int> list = builder.RepeatedInt32List;
list.Add(1); // Fine
builder.Build();
try {
list.Add(2);
Assert.Fail("List should be frozen");
} catch (NotSupportedException) {
// Expected
}
}
[Test]
public void RepeatedAddMessageBeforeBuild() {
TestAllTypes message = new TestAllTypes.Builder {
RepeatedNestedMessageList = { new TestAllTypes.Types.NestedMessage.Builder { Bb = 10 }.Build() } }.Build();
Assert.AreEqual(1, message.RepeatedNestedMessageCount);
Assert.AreEqual(10, message.RepeatedNestedMessageList[0].Bb);
}
[Test]
public void AddMessageFailsAfterBuild() {
TestAllTypes.Builder builder = new TestAllTypes.Builder();
IList<TestAllTypes.Types.NestedMessage> list = builder.RepeatedNestedMessageList;
builder.Build();
try {
list.Add(new TestAllTypes.Types.NestedMessage.Builder { Bb = 10 }.Build());
Assert.Fail("List should be frozen");
} catch (NotSupportedException) {
// Expected
}
}
[Test] [Test]
public void DefaultInstance() { public void DefaultInstance() {
Assert.AreSame(TestAllTypes.DefaultInstance, TestAllTypes.DefaultInstance.DefaultInstanceForType); Assert.AreSame(TestAllTypes.DefaultInstance, TestAllTypes.DefaultInstance.DefaultInstanceForType);
......
...@@ -11,7 +11,7 @@ namespace Google.ProtocolBuffers { ...@@ -11,7 +11,7 @@ namespace Google.ProtocolBuffers {
[Test] [Test]
public void ThreeMessagesInMemory() { public void ThreeMessagesInMemory() {
MemoryStream stream = new MemoryStream(MessageStreamWriterTest.ThreeMessageData); MemoryStream stream = new MemoryStream(MessageStreamWriterTest.ThreeMessageData);
IEnumerable<NestedMessage> iterator = MessageStreamIterator.FromStreamProvider<NestedMessage>(() => stream); IEnumerable<NestedMessage> iterator = MessageStreamIterator<NestedMessage>.FromStreamProvider(() => stream);
List<NestedMessage> messages = new List<NestedMessage>(iterator); List<NestedMessage> messages = new List<NestedMessage>(iterator);
Assert.AreEqual(3, messages.Count); Assert.AreEqual(3, messages.Count);
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
<Compile Include="ByteStringTest.cs" /> <Compile Include="ByteStringTest.cs" />
<Compile Include="CodedInputStreamTest.cs" /> <Compile Include="CodedInputStreamTest.cs" />
<Compile Include="CodedOutputStreamTest.cs" /> <Compile Include="CodedOutputStreamTest.cs" />
<Compile Include="Collections\PopsicleListTest.cs" />
<Compile Include="DescriptorsTest.cs" /> <Compile Include="DescriptorsTest.cs" />
<Compile Include="DynamicMessageTest.cs" /> <Compile Include="DynamicMessageTest.cs" />
<Compile Include="GeneratedMessageTest.cs" /> <Compile Include="GeneratedMessageTest.cs" />
......
...@@ -7,7 +7,7 @@ using scg = global::System.Collections.Generic; ...@@ -7,7 +7,7 @@ using scg = global::System.Collections.Generic;
namespace Google.ProtocolBuffers.TestProtos { namespace Google.ProtocolBuffers.TestProtos {
public sealed partial class MessageWithNoOuter : pb::GeneratedMessage<MessageWithNoOuter, MessageWithNoOuter.Builder> { public sealed partial class MessageWithNoOuter : pb::GeneratedMessage<MessageWithNoOuter, MessageWithNoOuter.Builder> {
private static readonly MessageWithNoOuter defaultInstance = new MessageWithNoOuter(); private static readonly MessageWithNoOuter defaultInstance = new Builder().BuildPartial();
public static MessageWithNoOuter DefaultInstance { public static MessageWithNoOuter DefaultInstance {
get { return defaultInstance; } get { return defaultInstance; }
} }
...@@ -35,7 +35,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -35,7 +35,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public sealed partial class NestedMessage : pb::GeneratedMessage<NestedMessage, NestedMessage.Builder> { public sealed partial class NestedMessage : pb::GeneratedMessage<NestedMessage, NestedMessage.Builder> {
private static readonly NestedMessage defaultInstance = new NestedMessage(); private static readonly NestedMessage defaultInstance = new Builder().BuildPartial();
public static NestedMessage DefaultInstance { public static NestedMessage DefaultInstance {
get { return defaultInstance; } get { return defaultInstance; }
} }
...@@ -179,7 +179,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -179,7 +179,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
// repeated .protobuf_unittest.TestAllTypes foreign = 2; // repeated .protobuf_unittest.TestAllTypes foreign = 2;
private scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> foreign_ = pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>.Empty; private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> foreign_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>();
public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> ForeignList { public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> ForeignList {
get { return foreign_; } get { return foreign_; }
} }
...@@ -278,9 +278,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -278,9 +278,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override global::Google.ProtocolBuffers.TestProtos.MessageWithNoOuter BuildPartial() { public override global::Google.ProtocolBuffers.TestProtos.MessageWithNoOuter BuildPartial() {
if (result.foreign_ != pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>.Empty) { result.foreign_.MakeReadOnly();
result.foreign_ = pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>.AsReadOnly(result.foreign_);
}
global::Google.ProtocolBuffers.TestProtos.MessageWithNoOuter returnMe = result; global::Google.ProtocolBuffers.TestProtos.MessageWithNoOuter returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -324,7 +322,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -324,7 +322,7 @@ namespace Google.ProtocolBuffers.TestProtos {
// repeated .protobuf_unittest.TestAllTypes foreign = 2; // repeated .protobuf_unittest.TestAllTypes foreign = 2;
public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> ForeignList { public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> ForeignList {
get { return pbc::Lists.AsReadOnly(result.foreign_); } get { return result.foreign_; }
} }
public int ForeignCount { public int ForeignCount {
get { return result.ForeignCount; } get { return result.ForeignCount; }
...@@ -341,28 +339,19 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -341,28 +339,19 @@ namespace Google.ProtocolBuffers.TestProtos {
return this; return this;
} }
public Builder AddForeign(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) { public Builder AddForeign(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
if (result.foreign_ == pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>.Empty) {
result.foreign_ = new scg::List<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>();
}
result.foreign_.Add(value); result.foreign_.Add(value);
return this; return this;
} }
public Builder AddForeign(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) { public Builder AddForeign(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
if (result.foreign_ == pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>.Empty) {
result.foreign_ = new scg::List<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>();
}
result.foreign_.Add(builderForValue.Build()); result.foreign_.Add(builderForValue.Build());
return this; return this;
} }
public Builder AddRangeForeign(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> values) { public Builder AddRangeForeign(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> values) {
if (result.foreign_ == pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>.Empty) {
result.foreign_ = new scg::List<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>();
}
base.AddRange(values, result.foreign_); base.AddRange(values, result.foreign_);
return this; return this;
} }
public Builder ClearForeign() { public Builder ClearForeign() {
result.foreign_ = pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>.Empty; result.foreign_.Clear();
return this; return this;
} }
......
...@@ -55,7 +55,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -55,7 +55,7 @@ namespace Google.ProtocolBuffers.TestProtos {
#region Messages #region Messages
public sealed partial class TestEmbedOptimizedForSize : pb::GeneratedMessage<TestEmbedOptimizedForSize, TestEmbedOptimizedForSize.Builder> { public sealed partial class TestEmbedOptimizedForSize : pb::GeneratedMessage<TestEmbedOptimizedForSize, TestEmbedOptimizedForSize.Builder> {
private static readonly TestEmbedOptimizedForSize defaultInstance = new TestEmbedOptimizedForSize(); private static readonly TestEmbedOptimizedForSize defaultInstance = new Builder().BuildPartial();
public static TestEmbedOptimizedForSize DefaultInstance { public static TestEmbedOptimizedForSize DefaultInstance {
get { return defaultInstance; } get { return defaultInstance; }
} }
...@@ -87,7 +87,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -87,7 +87,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
// repeated .protobuf_unittest.TestOptimizedForSize repeated_message = 2; // repeated .protobuf_unittest.TestOptimizedForSize repeated_message = 2;
private scg::IList<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize> repeatedMessage_ = pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>.Empty; private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize> repeatedMessage_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>();
public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize> RepeatedMessageList { public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize> RepeatedMessageList {
get { return repeatedMessage_; } get { return repeatedMessage_; }
} }
...@@ -211,9 +211,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -211,9 +211,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize BuildPartial() { public override global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize BuildPartial() {
if (result.repeatedMessage_ != pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>.Empty) { result.repeatedMessage_.MakeReadOnly();
result.repeatedMessage_ = pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>.AsReadOnly(result.repeatedMessage_);
}
global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize returnMe = result; global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -234,9 +232,6 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -234,9 +232,6 @@ namespace Google.ProtocolBuffers.TestProtos {
MergeOptionalMessage(other.OptionalMessage); MergeOptionalMessage(other.OptionalMessage);
} }
if (other.repeatedMessage_.Count != 0) { if (other.repeatedMessage_.Count != 0) {
if (result.repeatedMessage_.Count == 0) {
result.repeatedMessage_ = new scg::List<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>();
}
base.AddRange(other.repeatedMessage_, result.repeatedMessage_); base.AddRange(other.repeatedMessage_, result.repeatedMessage_);
} }
this.MergeUnknownFields(other.UnknownFields); this.MergeUnknownFields(other.UnknownFields);
...@@ -321,7 +316,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -321,7 +316,7 @@ namespace Google.ProtocolBuffers.TestProtos {
// repeated .protobuf_unittest.TestOptimizedForSize repeated_message = 2; // repeated .protobuf_unittest.TestOptimizedForSize repeated_message = 2;
public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize> RepeatedMessageList { public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize> RepeatedMessageList {
get { return pbc::Lists.AsReadOnly(result.repeatedMessage_); } get { return result.repeatedMessage_; }
} }
public int RepeatedMessageCount { public int RepeatedMessageCount {
get { return result.RepeatedMessageCount; } get { return result.RepeatedMessageCount; }
...@@ -338,28 +333,19 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -338,28 +333,19 @@ namespace Google.ProtocolBuffers.TestProtos {
return this; return this;
} }
public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize value) { public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize value) {
if (result.repeatedMessage_ == pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>.Empty) {
result.repeatedMessage_ = new scg::List<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>();
}
result.repeatedMessage_.Add(value); result.repeatedMessage_.Add(value);
return this; return this;
} }
public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Builder builderForValue) { public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Builder builderForValue) {
if (result.repeatedMessage_ == pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>.Empty) {
result.repeatedMessage_ = new scg::List<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>();
}
result.repeatedMessage_.Add(builderForValue.Build()); result.repeatedMessage_.Add(builderForValue.Build());
return this; return this;
} }
public Builder AddRangeRepeatedMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize> values) { public Builder AddRangeRepeatedMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize> values) {
if (result.repeatedMessage_ == pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>.Empty) {
result.repeatedMessage_ = new scg::List<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>();
}
base.AddRange(values, result.repeatedMessage_); base.AddRange(values, result.repeatedMessage_);
return this; return this;
} }
public Builder ClearRepeatedMessage() { public Builder ClearRepeatedMessage() {
result.repeatedMessage_ = pbc::Lists<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize>.Empty; result.repeatedMessage_.Clear();
return this; return this;
} }
} }
......
...@@ -55,7 +55,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -55,7 +55,7 @@ namespace Google.ProtocolBuffers.TestProtos {
#region Messages #region Messages
public sealed partial class ImportMessage : pb::GeneratedMessage<ImportMessage, ImportMessage.Builder> { public sealed partial class ImportMessage : pb::GeneratedMessage<ImportMessage, ImportMessage.Builder> {
private static readonly ImportMessage defaultInstance = new ImportMessage(); private static readonly ImportMessage defaultInstance = new Builder().BuildPartial();
public static ImportMessage DefaultInstance { public static ImportMessage DefaultInstance {
get { return defaultInstance; } get { return defaultInstance; }
} }
......
...@@ -95,7 +95,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -95,7 +95,7 @@ namespace Google.ProtocolBuffers.TestProtos {
#region Messages #region Messages
public sealed partial class TestMessageSet : pb::ExtendableMessage<TestMessageSet, TestMessageSet.Builder> { public sealed partial class TestMessageSet : pb::ExtendableMessage<TestMessageSet, TestMessageSet.Builder> {
private static readonly TestMessageSet defaultInstance = new TestMessageSet(); private static readonly TestMessageSet defaultInstance = new Builder().BuildPartial();
public static TestMessageSet DefaultInstance { public static TestMessageSet DefaultInstance {
get { return defaultInstance; } get { return defaultInstance; }
} }
...@@ -264,7 +264,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -264,7 +264,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public sealed partial class TestMessageSetContainer : pb::GeneratedMessage<TestMessageSetContainer, TestMessageSetContainer.Builder> { public sealed partial class TestMessageSetContainer : pb::GeneratedMessage<TestMessageSetContainer, TestMessageSetContainer.Builder> {
private static readonly TestMessageSetContainer defaultInstance = new TestMessageSetContainer(); private static readonly TestMessageSetContainer defaultInstance = new Builder().BuildPartial();
public static TestMessageSetContainer DefaultInstance { public static TestMessageSetContainer DefaultInstance {
get { return defaultInstance; } get { return defaultInstance; }
} }
...@@ -495,7 +495,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -495,7 +495,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public sealed partial class TestMessageSetExtension1 : pb::GeneratedMessage<TestMessageSetExtension1, TestMessageSetExtension1.Builder> { public sealed partial class TestMessageSetExtension1 : pb::GeneratedMessage<TestMessageSetExtension1, TestMessageSetExtension1.Builder> {
private static readonly TestMessageSetExtension1 defaultInstance = new TestMessageSetExtension1(); private static readonly TestMessageSetExtension1 defaultInstance = new Builder().BuildPartial();
public static TestMessageSetExtension1 DefaultInstance { public static TestMessageSetExtension1 DefaultInstance {
get { return defaultInstance; } get { return defaultInstance; }
} }
...@@ -709,7 +709,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -709,7 +709,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public sealed partial class TestMessageSetExtension2 : pb::GeneratedMessage<TestMessageSetExtension2, TestMessageSetExtension2.Builder> { public sealed partial class TestMessageSetExtension2 : pb::GeneratedMessage<TestMessageSetExtension2, TestMessageSetExtension2.Builder> {
private static readonly TestMessageSetExtension2 defaultInstance = new TestMessageSetExtension2(); private static readonly TestMessageSetExtension2 defaultInstance = new Builder().BuildPartial();
public static TestMessageSetExtension2 DefaultInstance { public static TestMessageSetExtension2 DefaultInstance {
get { return defaultInstance; } get { return defaultInstance; }
} }
...@@ -923,7 +923,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -923,7 +923,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public sealed partial class RawMessageSet : pb::GeneratedMessage<RawMessageSet, RawMessageSet.Builder> { public sealed partial class RawMessageSet : pb::GeneratedMessage<RawMessageSet, RawMessageSet.Builder> {
private static readonly RawMessageSet defaultInstance = new RawMessageSet(); private static readonly RawMessageSet defaultInstance = new Builder().BuildPartial();
public static RawMessageSet DefaultInstance { public static RawMessageSet DefaultInstance {
get { return defaultInstance; } get { return defaultInstance; }
} }
...@@ -947,7 +947,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -947,7 +947,7 @@ namespace Google.ProtocolBuffers.TestProtos {
#region Nested types #region Nested types
public static class Types { public static class Types {
public sealed partial class Item : pb::GeneratedMessage<Item, Item.Builder> { public sealed partial class Item : pb::GeneratedMessage<Item, Item.Builder> {
private static readonly Item defaultInstance = new Item(); private static readonly Item defaultInstance = new Builder().BuildPartial();
public static Item DefaultInstance { public static Item DefaultInstance {
get { return defaultInstance; } get { return defaultInstance; }
} }
...@@ -1201,7 +1201,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -1201,7 +1201,7 @@ namespace Google.ProtocolBuffers.TestProtos {
#endregion #endregion
// repeated group Item = 1 { // repeated group Item = 1 {
private scg::IList<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item> item_ = pbc::Lists<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>.Empty; private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item> item_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>();
public scg::IList<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item> ItemList { public scg::IList<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item> ItemList {
get { return item_; } get { return item_; }
} }
...@@ -1316,9 +1316,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -1316,9 +1316,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override global::Google.ProtocolBuffers.TestProtos.RawMessageSet BuildPartial() { public override global::Google.ProtocolBuffers.TestProtos.RawMessageSet BuildPartial() {
if (result.item_ != pbc::Lists<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>.Empty) { result.item_.MakeReadOnly();
result.item_ = pbc::Lists<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>.AsReadOnly(result.item_);
}
global::Google.ProtocolBuffers.TestProtos.RawMessageSet returnMe = result; global::Google.ProtocolBuffers.TestProtos.RawMessageSet returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -1336,9 +1334,6 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -1336,9 +1334,6 @@ namespace Google.ProtocolBuffers.TestProtos {
public override Builder MergeFrom(global::Google.ProtocolBuffers.TestProtos.RawMessageSet other) { public override Builder MergeFrom(global::Google.ProtocolBuffers.TestProtos.RawMessageSet other) {
if (other == global::Google.ProtocolBuffers.TestProtos.RawMessageSet.DefaultInstance) return this; if (other == global::Google.ProtocolBuffers.TestProtos.RawMessageSet.DefaultInstance) return this;
if (other.item_.Count != 0) { if (other.item_.Count != 0) {
if (result.item_.Count == 0) {
result.item_ = new scg::List<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>();
}
base.AddRange(other.item_, result.item_); base.AddRange(other.item_, result.item_);
} }
this.MergeUnknownFields(other.UnknownFields); this.MergeUnknownFields(other.UnknownFields);
...@@ -1379,7 +1374,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -1379,7 +1374,7 @@ namespace Google.ProtocolBuffers.TestProtos {
// repeated group Item = 1 { // repeated group Item = 1 {
public scg::IList<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item> ItemList { public scg::IList<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item> ItemList {
get { return pbc::Lists.AsReadOnly(result.item_); } get { return result.item_; }
} }
public int ItemCount { public int ItemCount {
get { return result.ItemCount; } get { return result.ItemCount; }
...@@ -1396,28 +1391,19 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -1396,28 +1391,19 @@ namespace Google.ProtocolBuffers.TestProtos {
return this; return this;
} }
public Builder AddItem(global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item value) { public Builder AddItem(global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item value) {
if (result.item_ == pbc::Lists<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>.Empty) {
result.item_ = new scg::List<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>();
}
result.item_.Add(value); result.item_.Add(value);
return this; return this;
} }
public Builder AddItem(global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item.Builder builderForValue) { public Builder AddItem(global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item.Builder builderForValue) {
if (result.item_ == pbc::Lists<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>.Empty) {
result.item_ = new scg::List<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>();
}
result.item_.Add(builderForValue.Build()); result.item_.Add(builderForValue.Build());
return this; return this;
} }
public Builder AddRangeItem(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item> values) { public Builder AddRangeItem(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item> values) {
if (result.item_ == pbc::Lists<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>.Empty) {
result.item_ = new scg::List<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>();
}
base.AddRange(values, result.item_); base.AddRange(values, result.item_);
return this; return this;
} }
public Builder ClearItem() { public Builder ClearItem() {
result.item_ = pbc::Lists<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item>.Empty; result.item_.Clear();
return this; return this;
} }
} }
......
...@@ -54,7 +54,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -54,7 +54,7 @@ namespace Google.ProtocolBuffers.TestProtos {
#region Messages #region Messages
public sealed partial class TestOptimizedForSize : pb::ExtendableMessage<TestOptimizedForSize, TestOptimizedForSize.Builder> { public sealed partial class TestOptimizedForSize : pb::ExtendableMessage<TestOptimizedForSize, TestOptimizedForSize.Builder> {
private static readonly TestOptimizedForSize defaultInstance = new TestOptimizedForSize(); private static readonly TestOptimizedForSize defaultInstance = new Builder().BuildPartial();
public static TestOptimizedForSize DefaultInstance { public static TestOptimizedForSize DefaultInstance {
get { return defaultInstance; } get { return defaultInstance; }
} }
......
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace Google.ProtocolBuffers.Collections {
/// <summary>
/// Proxies calls to a <see cref="List{T}" />, but allows the list
/// to be made read-only (with the <see cref="MakeReadOnly" /> method),
/// after which any modifying methods throw <see cref="NotSupportedException" />.
/// </summary>
public sealed class PopsicleList<T> : IList<T> {
private readonly List<T> items = new List<T>();
private bool readOnly = false;
/// <summary>
/// Makes this list read-only ("freezes the popsicle"). From this
/// point on, mutating methods (Clear, Add etc) will throw a
/// NotSupportedException. There is no way of "defrosting" the list afterwards.
/// </summary>
public void MakeReadOnly() {
readOnly = true;
}
public int IndexOf(T item) {
return items.IndexOf(item);
}
public void Insert(int index, T item) {
ValidateModification();
items.Insert(index, item);
}
public void RemoveAt(int index) {
ValidateModification();
items.RemoveAt(index);
}
public T this[int index] {
get {
return items[index];
}
set {
ValidateModification();
items[index] = value;
}
}
public void Add(T item) {
ValidateModification();
items.Add(item);
}
public void Clear() {
ValidateModification();
items.Clear();
}
public bool Contains(T item) {
return items.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex) {
items.CopyTo(array, arrayIndex);
}
public int Count {
get { return items.Count; }
}
public bool IsReadOnly {
get { return readOnly; }
}
public bool Remove(T item) {
ValidateModification();
return items.Remove(item);
}
public IEnumerator<T> GetEnumerator() {
return items.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
private void ValidateModification() {
if (readOnly) {
throw new NotSupportedException("List is read-only");
}
}
}
}
using System.IO; // Protocol Buffers - Google's data interchange format
namespace Google.ProtocolBuffers { // Copyright 2008 Google Inc.
// http://code.google.com/p/protobuf/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Delegate to return a stream when asked, used by MessageStreamIterator. /// Delegate to return a stream when asked, used by MessageStreamIterator.
/// </summary> /// </summary>
public delegate Stream StreamProvider(); public delegate Stream StreamProvider();
// These delegate declarations mirror the ones in .NET 3.5 for the sake of familiarity.
internal delegate TResult Func<TResult>();
internal delegate TResult Func<T, TResult>(T arg);
internal delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
internal delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
internal delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
internal delegate void Action();
internal delegate void Action<T1, T2>(T1 arg1, T2 arg2);
} }
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.
// http://code.google.com/p/protobuf/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Google.ProtocolBuffers.FieldAccess {
// These delegate declarations mirror the ones in .NET 3.5 for the sake of familiarity.
internal delegate TResult Func<TResult>();
internal delegate TResult Func<T, TResult>(T arg);
internal delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
internal delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
internal delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
internal delegate void Action<T1, T2>(T1 arg1, T2 arg2);
}
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
<Compile Include="AbstractBuilder.cs" /> <Compile Include="AbstractBuilder.cs" />
<Compile Include="AbstractMessage.cs" /> <Compile Include="AbstractMessage.cs" />
<Compile Include="ByteString.cs" /> <Compile Include="ByteString.cs" />
<Compile Include="Collections\PopsicleList.cs" />
<Compile Include="Delegates.cs" /> <Compile Include="Delegates.cs" />
<Compile Include="CodedInputStream.cs" /> <Compile Include="CodedInputStream.cs" />
<Compile Include="CodedOutputStream.cs" /> <Compile Include="CodedOutputStream.cs" />
...@@ -72,7 +73,6 @@ ...@@ -72,7 +73,6 @@
<Compile Include="ExtendableMessage.cs" /> <Compile Include="ExtendableMessage.cs" />
<Compile Include="ExtensionInfo.cs" /> <Compile Include="ExtensionInfo.cs" />
<Compile Include="ExtensionRegistry.cs" /> <Compile Include="ExtensionRegistry.cs" />
<Compile Include="FieldAccess\Delegates.cs" />
<Compile Include="FieldAccess\ReflectionUtil.cs" /> <Compile Include="FieldAccess\ReflectionUtil.cs" />
<Compile Include="FieldAccess\SingleEnumAccessor.cs" /> <Compile Include="FieldAccess\SingleEnumAccessor.cs" />
<Compile Include="FieldAccess\SingleMessageAccessor.cs" /> <Compile Include="FieldAccess\SingleMessageAccessor.cs" />
......
...@@ -212,7 +212,8 @@ void MessageGenerator::Generate(io::Printer* printer) { ...@@ -212,7 +212,8 @@ void MessageGenerator::Generate(io::Printer* printer) {
} }
printer->Indent(); printer->Indent();
printer->Print( printer->Print(
"private static readonly $classname$ defaultInstance = new $classname$();\r\n" // Must call Build() to make sure all lists are made read-only
"private static readonly $classname$ defaultInstance = new Builder().BuildPartial();\r\n"
"public static $classname$ DefaultInstance {\r\n" "public static $classname$ DefaultInstance {\r\n"
" get { return defaultInstance; }\r\n" " get { return defaultInstance; }\r\n"
"}\r\n" "}\r\n"
......
...@@ -175,9 +175,9 @@ RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} ...@@ -175,9 +175,9 @@ RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
void RepeatedMessageFieldGenerator:: void RepeatedMessageFieldGenerator::
GenerateMembers(io::Printer* printer) const { GenerateMembers(io::Printer* printer) const {
printer->Print(variables_, printer->Print(variables_,
"private scg::IList<$type$> $name$_ = pbc::Lists<$type$>.Empty;\r\n" "private pbc::PopsicleList<$type$> $name$_ = new pbc::PopsicleList<$type$>();\r\n"
"public scg::IList<$type$> $capitalized_name$List {\r\n" "public scg::IList<$type$> $capitalized_name$List {\r\n"
" get { return $name$_; } \r\n" // note: unmodifiable list " get { return $name$_; } \r\n" // Will be unmodifiable by the time it's exposed
"}\r\n" "}\r\n"
"public int $capitalized_name$Count\r\n" "public int $capitalized_name$Count\r\n"
" { get { return $name$_.Count; }\r\n" " { get { return $name$_.Count; }\r\n"
...@@ -190,12 +190,10 @@ GenerateMembers(io::Printer* printer) const { ...@@ -190,12 +190,10 @@ GenerateMembers(io::Printer* printer) const {
void RepeatedMessageFieldGenerator:: void RepeatedMessageFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const { GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_, printer->Print(variables_,
// Note: We return an unmodifiable list because otherwise the caller // Note: We can return the original list here, because we
// could hold on to the returned list and modify it after the message // make it read-only when we build.
// has been built, thus mutating the message which is supposed to be
// immutable.
"public scg::IList<$type$> $capitalized_name$List {\r\n" "public scg::IList<$type$> $capitalized_name$List {\r\n"
" get { return pbc::Lists.AsReadOnly(result.$name$_); }\r\n" " get { return result.$name$_; }\r\n"
"}\r\n" "}\r\n"
"public int $capitalized_name$Count {\r\n" "public int $capitalized_name$Count {\r\n"
" get { return result.$capitalized_name$Count; }\r\n" " get { return result.$capitalized_name$Count; }\r\n"
...@@ -212,28 +210,19 @@ GenerateBuilderMembers(io::Printer* printer) const { ...@@ -212,28 +210,19 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return this;\r\n" " return this;\r\n"
"}\r\n" "}\r\n"
"public Builder Add$capitalized_name$($type$ value) {\r\n" "public Builder Add$capitalized_name$($type$ value) {\r\n"
" if (result.$name$_ == pbc::Lists<$type$>.Empty) {\r\n"
" result.$name$_ = new scg::List<$type$>();\r\n"
" }\r\n"
" result.$name$_.Add(value);\r\n" " result.$name$_.Add(value);\r\n"
" return this;\r\n" " return this;\r\n"
"}\r\n" "}\r\n"
"public Builder Add$capitalized_name$($type$.Builder builderForValue) {\r\n" "public Builder Add$capitalized_name$($type$.Builder builderForValue) {\r\n"
" if (result.$name$_ == pbc::Lists<$type$>.Empty) {\r\n"
" result.$name$_ = new scg::List<$type$>();\r\n"
" }\r\n"
" result.$name$_.Add(builderForValue.Build());\r\n" " result.$name$_.Add(builderForValue.Build());\r\n"
" return this;\r\n" " return this;\r\n"
"}\r\n" "}\r\n"
"public Builder AddRange$capitalized_name$(scg::IEnumerable<$type$> values) {\r\n" "public Builder AddRange$capitalized_name$(scg::IEnumerable<$type$> values) {\r\n"
" if (result.$name$_ == pbc::Lists<$type$>.Empty) {\r\n"
" result.$name$_ = new scg::List<$type$>();\r\n"
" }\r\n"
" base.AddRange(values, result.$name$_);\r\n" " base.AddRange(values, result.$name$_);\r\n"
" return this;\r\n" " return this;\r\n"
"}\r\n" "}\r\n"
"public Builder Clear$capitalized_name$() {\r\n" "public Builder Clear$capitalized_name$() {\r\n"
" result.$name$_ = pbc::Lists<$type$>.Empty;\r\n" " result.$name$_.Clear();\r\n"
" return this;\r\n" " return this;\r\n"
"}\r\n"); "}\r\n");
} }
...@@ -242,9 +231,6 @@ void RepeatedMessageFieldGenerator:: ...@@ -242,9 +231,6 @@ void RepeatedMessageFieldGenerator::
GenerateMergingCode(io::Printer* printer) const { GenerateMergingCode(io::Printer* printer) const {
printer->Print(variables_, printer->Print(variables_,
"if (other.$name$_.Count != 0) {\r\n" "if (other.$name$_.Count != 0) {\r\n"
" if (result.$name$_.Count == 0) {\r\n"
" result.$name$_ = new scg::List<$type$>();\r\n"
" }\r\n"
" base.AddRange(other.$name$_, result.$name$_);\r\n" " base.AddRange(other.$name$_, result.$name$_);\r\n"
"}\r\n"); "}\r\n");
} }
...@@ -252,9 +238,7 @@ GenerateMergingCode(io::Printer* printer) const { ...@@ -252,9 +238,7 @@ GenerateMergingCode(io::Printer* printer) const {
void RepeatedMessageFieldGenerator:: void RepeatedMessageFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const { GenerateBuildingCode(io::Printer* printer) const {
printer->Print(variables_, printer->Print(variables_,
"if (result.$name$_ != pbc::Lists<$type$>.Empty) {\r\n" "result.$name$_.MakeReadOnly();\r\n");
" result.$name$_ = pbc::Lists<$type$>.AsReadOnly(result.$name$_);\r\n"
"}\r\n");
} }
void RepeatedMessageFieldGenerator:: void RepeatedMessageFieldGenerator::
......
...@@ -239,9 +239,9 @@ RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} ...@@ -239,9 +239,9 @@ RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
void RepeatedPrimitiveFieldGenerator:: void RepeatedPrimitiveFieldGenerator::
GenerateMembers(io::Printer* printer) const { GenerateMembers(io::Printer* printer) const {
printer->Print(variables_, printer->Print(variables_,
"private scg::IList<$type$> $name$_ = pbc::Lists<$type$>.Empty;\r\n" "private pbc::PopsicleList<$type$> $name$_ = new pbc::PopsicleList<$type$>();\r\n"
"public scg::IList<$type$> $capitalized_name$List {\r\n" "public scg::IList<$type$> $capitalized_name$List {\r\n"
" get { return $name$_; }\r\n" // note: unmodifiable list " get { return $name$_; } \r\n" // Will be unmodifiable by the time it's exposed
"}\r\n" "}\r\n"
"public int $capitalized_name$Count {\r\n" "public int $capitalized_name$Count {\r\n"
" get { return $name$_.Count; }\r\n" " get { return $name$_.Count; }\r\n"
...@@ -254,12 +254,10 @@ GenerateMembers(io::Printer* printer) const { ...@@ -254,12 +254,10 @@ GenerateMembers(io::Printer* printer) const {
void RepeatedPrimitiveFieldGenerator:: void RepeatedPrimitiveFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const { GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_, printer->Print(variables_,
// Note: We return an unmodifiable list because otherwise the caller // Note: We can return the original list here, because we
// could hold on to the returned list and modify it after the message // make it read-only when we build.
// has been built, thus mutating the message which is supposed to be
// immutable. This unfortunately limits the use for collection initializers...
"public scg::IList<$type$> $capitalized_name$List {\r\n" "public scg::IList<$type$> $capitalized_name$List {\r\n"
" get { return pbc::Lists<$type$>.AsReadOnly(result.$name$_); }\r\n" " get { return result.$name$_; }\r\n"
"}\r\n" "}\r\n"
"public int $capitalized_name$Count {\r\n" "public int $capitalized_name$Count {\r\n"
" get { return result.$capitalized_name$Count; }\r\n" " get { return result.$capitalized_name$Count; }\r\n"
...@@ -272,21 +270,15 @@ GenerateBuilderMembers(io::Printer* printer) const { ...@@ -272,21 +270,15 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return this;\r\n" " return this;\r\n"
"}\r\n" "}\r\n"
"public Builder Add$capitalized_name$($type$ value) {\r\n" "public Builder Add$capitalized_name$($type$ value) {\r\n"
" if (result.$name$_.Count == 0) {\r\n"
" result.$name$_ = new scg::List<$type$>();\r\n"
" }\r\n"
" result.$name$_.Add(value);\r\n" " result.$name$_.Add(value);\r\n"
" return this;\r\n" " return this;\r\n"
"}\r\n" "}\r\n"
"public Builder AddRange$capitalized_name$(scg::IEnumerable<$type$> values) {\r\n" "public Builder AddRange$capitalized_name$(scg::IEnumerable<$type$> values) {\r\n"
" if (result.$name$_.Count == 0) {\r\n"
" result.$name$_ = new scg::List<$type$>();\r\n"
" }\r\n"
" base.AddRange(values, result.$name$_);\r\n" " base.AddRange(values, result.$name$_);\r\n"
" return this;\r\n" " return this;\r\n"
"}\r\n" "}\r\n"
"public Builder Clear$capitalized_name$() {\r\n" "public Builder Clear$capitalized_name$() {\r\n"
" result.$name$_ = pbc::Lists<$type$>.Empty;\r\n" " result.$name$_.Clear();\r\n"
" return this;\r\n" " return this;\r\n"
"}\r\n"); "}\r\n");
} }
...@@ -295,9 +287,6 @@ void RepeatedPrimitiveFieldGenerator:: ...@@ -295,9 +287,6 @@ void RepeatedPrimitiveFieldGenerator::
GenerateMergingCode(io::Printer* printer) const { GenerateMergingCode(io::Printer* printer) const {
printer->Print(variables_, printer->Print(variables_,
"if (other.$name$_.Count != 0) {\r\n" "if (other.$name$_.Count != 0) {\r\n"
" if (result.$name$_.Count == 0) {\r\n"
" result.$name$_ = new scg::List<$type$>();\r\n"
" }\r\n"
" base.AddRange(other.$name$_, result.$name$_);\r\n" " base.AddRange(other.$name$_, result.$name$_);\r\n"
"}\r\n"); "}\r\n");
} }
...@@ -305,7 +294,7 @@ GenerateMergingCode(io::Printer* printer) const { ...@@ -305,7 +294,7 @@ GenerateMergingCode(io::Printer* printer) const {
void RepeatedPrimitiveFieldGenerator:: void RepeatedPrimitiveFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const { GenerateBuildingCode(io::Printer* printer) const {
printer->Print(variables_, printer->Print(variables_,
"result.$name$_ = pbc::Lists<$type$>.AsReadOnly(result.$name$_);\r\n"); "result.$name$_.MakeReadOnly();\r\n");
} }
void RepeatedPrimitiveFieldGenerator:: void RepeatedPrimitiveFieldGenerator::
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment