First pass at implementation and testing of reusable builders.
diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs
index 74d6af6..ca40192 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs
@@ -183,7 +183,7 @@
public override Builder ToBuilder() { return CreateBuilder(this); }
public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(TestMessage prototype) {
- return (Builder) new Builder().MergeFrom(prototype);
+ return new Builder(prototype);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -193,21 +193,48 @@
protected override Builder ThisBuilder {
get { return this; }
}
- public Builder() {}
+ public Builder() {
+ result = DefaultInstance ?? new TestMessage();
+ builderIsReadOnly = result == DefaultInstance;
+ }
+ internal Builder(TestMessage cloneFrom) {
+ result = cloneFrom;
+ builderIsReadOnly = true;
+ }
- TestMessage result = new TestMessage();
+ bool builderIsReadOnly;
+ TestMessage result;
+
+ private TestMessage PrepareBuilder() {
+ if (builderIsReadOnly) {
+ TestMessage original = result;
+ result = new TestMessage();
+ builderIsReadOnly = false;
+ MergeFrom(original);
+ }
+ return result;
+ }
+
+ public override bool IsInitialized {
+ get { return result.IsInitialized; }
+ }
protected override TestMessage MessageBeingBuilt {
- get { return result; }
+ get { return PrepareBuilder(); }
}
public override Builder Clear() {
- result = new TestMessage();
+ result = DefaultInstance ?? new TestMessage();
+ builderIsReadOnly = true;
return this;
}
public override Builder Clone() {
- return new Builder().MergeFrom(result);
+ if (builderIsReadOnly) {
+ return new Builder(result);
+ } else {
+ return new Builder().MergeFrom(result);
+ }
}
public override pbd::MessageDescriptor DescriptorForType {
@@ -219,12 +246,11 @@
}
public override TestMessage BuildPartial() {
- if (result == null) {
- throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+ if (builderIsReadOnly) {
+ return result;
}
- TestMessage returnMe = result;
- result = null;
- return returnMe;
+ builderIsReadOnly = true;
+ return result;
}
public override Builder MergeFrom(pb::IMessage other) {
@@ -238,6 +264,7 @@
public override Builder MergeFrom(TestMessage other) {
if (other == global::Google.ProtocolBuffers.TestProtos.NoGenericService.TestMessage.DefaultInstance) return this;
+ PrepareBuilder();
if (other.HasA) {
A = other.A;
}
@@ -251,6 +278,7 @@
}
public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+ PrepareBuilder();
pb::UnknownFieldSet.Builder unknownFields = null;
uint tag;
string field_name;
@@ -306,11 +334,13 @@
set { SetA(value); }
}
public Builder SetA(int value) {
+ PrepareBuilder();
result.hasA = true;
result.a_ = value;
return this;
}
public Builder ClearA() {
+ PrepareBuilder();
result.hasA = false;
result.a_ = 0;
return this;