First pass at implementation and testing of reusable builders.
diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs
index ae309fa..3c5e930 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs
@@ -188,7 +188,7 @@
public override Builder ToBuilder() { return CreateBuilder(this); }
public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(SearchRequest prototype) {
- return (Builder) new Builder().MergeFrom(prototype);
+ return new Builder(prototype);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -198,21 +198,48 @@
protected override Builder ThisBuilder {
get { return this; }
}
- public Builder() {}
+ public Builder() {
+ result = DefaultInstance ?? new SearchRequest();
+ builderIsReadOnly = result == DefaultInstance;
+ }
+ internal Builder(SearchRequest cloneFrom) {
+ result = cloneFrom;
+ builderIsReadOnly = true;
+ }
- SearchRequest result = new SearchRequest();
+ bool builderIsReadOnly;
+ SearchRequest result;
+
+ private SearchRequest PrepareBuilder() {
+ if (builderIsReadOnly) {
+ SearchRequest original = result;
+ result = new SearchRequest();
+ builderIsReadOnly = false;
+ MergeFrom(original);
+ }
+ return result;
+ }
+
+ public override bool IsInitialized {
+ get { return result.IsInitialized; }
+ }
protected override SearchRequest MessageBeingBuilt {
- get { return result; }
+ get { return PrepareBuilder(); }
}
public override Builder Clear() {
- result = new SearchRequest();
+ result = DefaultInstance ?? new SearchRequest();
+ 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 {
@@ -224,13 +251,12 @@
}
public override SearchRequest BuildPartial() {
- if (result == null) {
- throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+ if (builderIsReadOnly) {
+ return result;
}
result.criteria_.MakeReadOnly();
- SearchRequest returnMe = result;
- result = null;
- return returnMe;
+ builderIsReadOnly = true;
+ return result;
}
public override Builder MergeFrom(pb::IMessage other) {
@@ -244,6 +270,7 @@
public override Builder MergeFrom(SearchRequest other) {
if (other == global::Google.ProtocolBuffers.TestProtos.SearchRequest.DefaultInstance) return this;
+ PrepareBuilder();
if (other.criteria_.Count != 0) {
base.AddRange(other.criteria_, result.criteria_);
}
@@ -256,6 +283,7 @@
}
public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+ PrepareBuilder();
pb::UnknownFieldSet.Builder unknownFields = null;
uint tag;
string field_name;
@@ -304,7 +332,7 @@
public pbc::IPopsicleList<string> CriteriaList {
- get { return result.criteria_; }
+ get { return PrepareBuilder().criteria_; }
}
public int CriteriaCount {
get { return result.CriteriaCount; }
@@ -314,19 +342,23 @@
}
public Builder SetCriteria(int index, string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
+ PrepareBuilder();
result.criteria_[index] = value;
return this;
}
public Builder AddCriteria(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
+ PrepareBuilder();
result.criteria_.Add(value);
return this;
}
public Builder AddRangeCriteria(scg::IEnumerable<string> values) {
+ PrepareBuilder();
base.AddRange(values, result.criteria_);
return this;
}
public Builder ClearCriteria() {
+ PrepareBuilder();
result.criteria_.Clear();
return this;
}
@@ -487,7 +519,7 @@
public override Builder ToBuilder() { return CreateBuilder(this); }
public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(ResultItem prototype) {
- return (Builder) new Builder().MergeFrom(prototype);
+ return new Builder(prototype);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -497,21 +529,48 @@
protected override Builder ThisBuilder {
get { return this; }
}
- public Builder() {}
+ public Builder() {
+ result = DefaultInstance ?? new ResultItem();
+ builderIsReadOnly = result == DefaultInstance;
+ }
+ internal Builder(ResultItem cloneFrom) {
+ result = cloneFrom;
+ builderIsReadOnly = true;
+ }
- ResultItem result = new ResultItem();
+ bool builderIsReadOnly;
+ ResultItem result;
+
+ private ResultItem PrepareBuilder() {
+ if (builderIsReadOnly) {
+ ResultItem original = result;
+ result = new ResultItem();
+ builderIsReadOnly = false;
+ MergeFrom(original);
+ }
+ return result;
+ }
+
+ public override bool IsInitialized {
+ get { return result.IsInitialized; }
+ }
protected override ResultItem MessageBeingBuilt {
- get { return result; }
+ get { return PrepareBuilder(); }
}
public override Builder Clear() {
- result = new ResultItem();
+ result = DefaultInstance ?? new ResultItem();
+ 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 {
@@ -523,12 +582,11 @@
}
public override ResultItem BuildPartial() {
- if (result == null) {
- throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+ if (builderIsReadOnly) {
+ return result;
}
- ResultItem returnMe = result;
- result = null;
- return returnMe;
+ builderIsReadOnly = true;
+ return result;
}
public override Builder MergeFrom(pb::IMessage other) {
@@ -542,6 +600,7 @@
public override Builder MergeFrom(ResultItem other) {
if (other == global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem.DefaultInstance) return this;
+ PrepareBuilder();
if (other.HasUrl) {
Url = other.Url;
}
@@ -557,6 +616,7 @@
}
public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+ PrepareBuilder();
pb::UnknownFieldSet.Builder unknownFields = null;
uint tag;
string field_name;
@@ -617,11 +677,13 @@
}
public Builder SetUrl(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
+ PrepareBuilder();
result.hasUrl = true;
result.url_ = value;
return this;
}
public Builder ClearUrl() {
+ PrepareBuilder();
result.hasUrl = false;
result.url_ = "";
return this;
@@ -636,11 +698,13 @@
}
public Builder SetName(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
+ PrepareBuilder();
result.hasName = true;
result.name_ = value;
return this;
}
public Builder ClearName() {
+ PrepareBuilder();
result.hasName = false;
result.name_ = "";
return this;
@@ -734,7 +798,7 @@
public override Builder ToBuilder() { return CreateBuilder(this); }
public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(SearchResponse prototype) {
- return (Builder) new Builder().MergeFrom(prototype);
+ return new Builder(prototype);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -744,21 +808,48 @@
protected override Builder ThisBuilder {
get { return this; }
}
- public Builder() {}
+ public Builder() {
+ result = DefaultInstance ?? new SearchResponse();
+ builderIsReadOnly = result == DefaultInstance;
+ }
+ internal Builder(SearchResponse cloneFrom) {
+ result = cloneFrom;
+ builderIsReadOnly = true;
+ }
- SearchResponse result = new SearchResponse();
+ bool builderIsReadOnly;
+ SearchResponse result;
+
+ private SearchResponse PrepareBuilder() {
+ if (builderIsReadOnly) {
+ SearchResponse original = result;
+ result = new SearchResponse();
+ builderIsReadOnly = false;
+ MergeFrom(original);
+ }
+ return result;
+ }
+
+ public override bool IsInitialized {
+ get { return result.IsInitialized; }
+ }
protected override SearchResponse MessageBeingBuilt {
- get { return result; }
+ get { return PrepareBuilder(); }
}
public override Builder Clear() {
- result = new SearchResponse();
+ result = DefaultInstance ?? new SearchResponse();
+ 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 {
@@ -770,13 +861,12 @@
}
public override SearchResponse BuildPartial() {
- if (result == null) {
- throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+ if (builderIsReadOnly) {
+ return result;
}
result.results_.MakeReadOnly();
- SearchResponse returnMe = result;
- result = null;
- return returnMe;
+ builderIsReadOnly = true;
+ return result;
}
public override Builder MergeFrom(pb::IMessage other) {
@@ -790,6 +880,7 @@
public override Builder MergeFrom(SearchResponse other) {
if (other == global::Google.ProtocolBuffers.TestProtos.SearchResponse.DefaultInstance) return this;
+ PrepareBuilder();
if (other.results_.Count != 0) {
base.AddRange(other.results_, result.results_);
}
@@ -802,6 +893,7 @@
}
public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+ PrepareBuilder();
pb::UnknownFieldSet.Builder unknownFields = null;
uint tag;
string field_name;
@@ -850,7 +942,7 @@
public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem> ResultsList {
- get { return result.results_; }
+ get { return PrepareBuilder().results_; }
}
public int ResultsCount {
get { return result.ResultsCount; }
@@ -860,29 +952,35 @@
}
public Builder SetResults(int index, global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
+ PrepareBuilder();
result.results_[index] = value;
return this;
}
public Builder SetResults(int index, global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+ PrepareBuilder();
result.results_[index] = builderForValue.Build();
return this;
}
public Builder AddResults(global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
+ PrepareBuilder();
result.results_.Add(value);
return this;
}
public Builder AddResults(global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+ PrepareBuilder();
result.results_.Add(builderForValue.Build());
return this;
}
public Builder AddRangeResults(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem> values) {
+ PrepareBuilder();
base.AddRange(values, result.results_);
return this;
}
public Builder ClearResults() {
+ PrepareBuilder();
result.results_.Clear();
return this;
}
@@ -1019,7 +1117,7 @@
public override Builder ToBuilder() { return CreateBuilder(this); }
public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(RefineSearchRequest prototype) {
- return (Builder) new Builder().MergeFrom(prototype);
+ return new Builder(prototype);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -1029,21 +1127,48 @@
protected override Builder ThisBuilder {
get { return this; }
}
- public Builder() {}
+ public Builder() {
+ result = DefaultInstance ?? new RefineSearchRequest();
+ builderIsReadOnly = result == DefaultInstance;
+ }
+ internal Builder(RefineSearchRequest cloneFrom) {
+ result = cloneFrom;
+ builderIsReadOnly = true;
+ }
- RefineSearchRequest result = new RefineSearchRequest();
+ bool builderIsReadOnly;
+ RefineSearchRequest result;
+
+ private RefineSearchRequest PrepareBuilder() {
+ if (builderIsReadOnly) {
+ RefineSearchRequest original = result;
+ result = new RefineSearchRequest();
+ builderIsReadOnly = false;
+ MergeFrom(original);
+ }
+ return result;
+ }
+
+ public override bool IsInitialized {
+ get { return result.IsInitialized; }
+ }
protected override RefineSearchRequest MessageBeingBuilt {
- get { return result; }
+ get { return PrepareBuilder(); }
}
public override Builder Clear() {
- result = new RefineSearchRequest();
+ result = DefaultInstance ?? new RefineSearchRequest();
+ 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 {
@@ -1055,13 +1180,12 @@
}
public override RefineSearchRequest BuildPartial() {
- if (result == null) {
- throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+ if (builderIsReadOnly) {
+ return result;
}
result.criteria_.MakeReadOnly();
- RefineSearchRequest returnMe = result;
- result = null;
- return returnMe;
+ builderIsReadOnly = true;
+ return result;
}
public override Builder MergeFrom(pb::IMessage other) {
@@ -1075,6 +1199,7 @@
public override Builder MergeFrom(RefineSearchRequest other) {
if (other == global::Google.ProtocolBuffers.TestProtos.RefineSearchRequest.DefaultInstance) return this;
+ PrepareBuilder();
if (other.criteria_.Count != 0) {
base.AddRange(other.criteria_, result.criteria_);
}
@@ -1090,6 +1215,7 @@
}
public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+ PrepareBuilder();
pb::UnknownFieldSet.Builder unknownFields = null;
uint tag;
string field_name;
@@ -1147,7 +1273,7 @@
public pbc::IPopsicleList<string> CriteriaList {
- get { return result.criteria_; }
+ get { return PrepareBuilder().criteria_; }
}
public int CriteriaCount {
get { return result.CriteriaCount; }
@@ -1157,19 +1283,23 @@
}
public Builder SetCriteria(int index, string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
+ PrepareBuilder();
result.criteria_[index] = value;
return this;
}
public Builder AddCriteria(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
+ PrepareBuilder();
result.criteria_.Add(value);
return this;
}
public Builder AddRangeCriteria(scg::IEnumerable<string> values) {
+ PrepareBuilder();
base.AddRange(values, result.criteria_);
return this;
}
public Builder ClearCriteria() {
+ PrepareBuilder();
result.criteria_.Clear();
return this;
}
@@ -1183,18 +1313,21 @@
}
public Builder SetPreviousResults(global::Google.ProtocolBuffers.TestProtos.SearchResponse value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
+ PrepareBuilder();
result.hasPreviousResults = true;
result.previousResults_ = value;
return this;
}
public Builder SetPreviousResults(global::Google.ProtocolBuffers.TestProtos.SearchResponse.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+ PrepareBuilder();
result.hasPreviousResults = true;
result.previousResults_ = builderForValue.Build();
return this;
}
public Builder MergePreviousResults(global::Google.ProtocolBuffers.TestProtos.SearchResponse value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
+ PrepareBuilder();
if (result.hasPreviousResults &&
result.previousResults_ != global::Google.ProtocolBuffers.TestProtos.SearchResponse.DefaultInstance) {
result.previousResults_ = global::Google.ProtocolBuffers.TestProtos.SearchResponse.CreateBuilder(result.previousResults_).MergeFrom(value).BuildPartial();
@@ -1205,6 +1338,7 @@
return this;
}
public Builder ClearPreviousResults() {
+ PrepareBuilder();
result.hasPreviousResults = false;
result.previousResults_ = global::Google.ProtocolBuffers.TestProtos.SearchResponse.DefaultInstance;
return this;