diff options
author | csharptest <roger@csharptest.net> | 2011-09-28 11:31:27 -0500 |
---|---|---|
committer | rogerk <devnull@localhost> | 2011-09-28 11:31:27 -0500 |
commit | 8c2b8d11de91ae7869d19a94e48e993e97455470 (patch) | |
tree | c6056349009e6b0f0c523835ada884522cb67ed8 /src/ProtoGen | |
parent | 7f20cc9084d929d2506ed9f2dccff09c51165d1f (diff) | |
parent | 3b625064e8e40f37ec510cc4f25035a9c1554c73 (diff) | |
download | protobuf-8c2b8d11de91ae7869d19a94e48e993e97455470.tar.gz protobuf-8c2b8d11de91ae7869d19a94e48e993e97455470.tar.bz2 protobuf-8c2b8d11de91ae7869d19a94e48e993e97455470.zip |
merged issue-22
Diffstat (limited to 'src/ProtoGen')
-rw-r--r-- | src/ProtoGen/EnumFieldGenerator.cs | 2 | ||||
-rw-r--r-- | src/ProtoGen/MessageFieldGenerator.cs | 4 | ||||
-rw-r--r-- | src/ProtoGen/MessageGenerator.cs | 55 | ||||
-rw-r--r-- | src/ProtoGen/PrimitiveFieldGenerator.cs | 2 | ||||
-rw-r--r-- | src/ProtoGen/RepeatedEnumFieldGenerator.cs | 6 | ||||
-rw-r--r-- | src/ProtoGen/RepeatedMessageFieldGenerator.cs | 8 | ||||
-rw-r--r-- | src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs | 6 |
7 files changed, 68 insertions, 15 deletions
diff --git a/src/ProtoGen/EnumFieldGenerator.cs b/src/ProtoGen/EnumFieldGenerator.cs index 78384fdd..8d70bc67 100644 --- a/src/ProtoGen/EnumFieldGenerator.cs +++ b/src/ProtoGen/EnumFieldGenerator.cs @@ -72,12 +72,14 @@ namespace Google.ProtocolBuffers.ProtoGen writer.WriteLine("}");
AddPublicMemberAttributes(writer);
writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.has{0} = true;", PropertyName);
writer.WriteLine(" result.{0}_ = value;", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.has{0} = false;", PropertyName);
writer.WriteLine(" result.{0}_ = {1};", Name, DefaultValue);
writer.WriteLine(" return this;");
diff --git a/src/ProtoGen/MessageFieldGenerator.cs b/src/ProtoGen/MessageFieldGenerator.cs index 8e4bef5b..8e2691ee 100644 --- a/src/ProtoGen/MessageFieldGenerator.cs +++ b/src/ProtoGen/MessageFieldGenerator.cs @@ -73,6 +73,7 @@ namespace Google.ProtocolBuffers.ProtoGen AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.has{0} = true;", PropertyName);
writer.WriteLine(" result.{0}_ = value;", Name);
writer.WriteLine(" return this;");
@@ -80,6 +81,7 @@ namespace Google.ProtocolBuffers.ProtoGen AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Set{0}({1}.Builder builderForValue) {{", PropertyName, TypeName);
AddNullCheck(writer, "builderForValue");
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.has{0} = true;", PropertyName);
writer.WriteLine(" result.{0}_ = builderForValue.Build();", Name);
writer.WriteLine(" return this;");
@@ -87,6 +89,7 @@ namespace Google.ProtocolBuffers.ProtoGen AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Merge{0}({1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" if (result.has{0} &&", PropertyName);
writer.WriteLine(" result.{0}_ != {1}) {{", Name, DefaultValue);
writer.WriteLine(" result.{0}_ = {1}.CreateBuilder(result.{0}_).MergeFrom(value).BuildPartial();", Name,
@@ -99,6 +102,7 @@ namespace Google.ProtocolBuffers.ProtoGen writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.has{0} = false;", PropertyName);
writer.WriteLine(" result.{0}_ = {1};", Name, DefaultValue);
writer.WriteLine(" return this;");
diff --git a/src/ProtoGen/MessageGenerator.cs b/src/ProtoGen/MessageGenerator.cs index c8b2087f..89c4aaec 100644 --- a/src/ProtoGen/MessageGenerator.cs +++ b/src/ProtoGen/MessageGenerator.cs @@ -556,7 +556,7 @@ namespace Google.ProtocolBuffers.ProtoGen writer.WriteLine("public override Builder ToBuilder() { return CreateBuilder(this); }");
writer.WriteLine("public override Builder CreateBuilderForType() { return new Builder(); }");
writer.WriteLine("public static Builder CreateBuilder({0} prototype) {{", ClassName);
- writer.WriteLine(" return (Builder) new Builder().MergeFrom(prototype);");
+ writer.WriteLine(" return new Builder(prototype);");
writer.WriteLine("}");
writer.WriteLine();
if (Descriptor.File.CSharpOptions.AddSerializable)
@@ -591,21 +591,52 @@ namespace Google.ProtocolBuffers.ProtoGen private void GenerateCommonBuilderMethods(TextGenerator writer)
{
- writer.WriteLine("public Builder() {{}}", ClassAccessLevel);
+ //default constructor
+ writer.WriteLine("public Builder() {");
+ //Durring static initialization of message, DefaultInstance is expected to return null.
+ writer.WriteLine(" result = DefaultInstance ?? new {0}();", ClassName);
+ writer.WriteLine(" builderIsReadOnly = result == DefaultInstance;");
+ writer.WriteLine("}");
+ //clone constructor
+ writer.WriteLine("internal Builder({0} cloneFrom) {{", ClassName);
+ writer.WriteLine(" result = cloneFrom;");
+ writer.WriteLine(" builderIsReadOnly = true;");
+ writer.WriteLine("}");
+ writer.WriteLine();
+ writer.WriteLine("bool builderIsReadOnly;");
+ writer.WriteLine("{0} result;", ClassName);
+ writer.WriteLine();
+ writer.WriteLine("private {0} PrepareBuilder() {{", ClassName);
+ writer.WriteLine(" if (builderIsReadOnly) {");
+ writer.WriteLine(" {0} original = result;", ClassName);
+ writer.WriteLine(" result = new {0}();", ClassName);
+ writer.WriteLine(" builderIsReadOnly = false;");
+ writer.WriteLine(" MergeFrom(original);");
+ writer.WriteLine(" }");
+ writer.WriteLine(" return result;");
+ writer.WriteLine("}");
writer.WriteLine();
- writer.WriteLine("{0} result = new {0}();", ClassName);
+ writer.WriteLine("public override bool IsInitialized {");
+ writer.WriteLine(" get { return result.IsInitialized; }");
+ writer.WriteLine("}");
writer.WriteLine();
writer.WriteLine("protected override {0} MessageBeingBuilt {{", ClassName);
- writer.WriteLine(" get { return result; }");
+ writer.WriteLine(" get { return PrepareBuilder(); }");
writer.WriteLine("}");
writer.WriteLine();
+ //Not actually expecting that DefaultInstance would ever be null here; however, we will ensure it does not break
writer.WriteLine("public override Builder Clear() {");
- writer.WriteLine(" result = new {0}();", ClassName);
+ writer.WriteLine(" result = DefaultInstance ?? new {0}();", ClassName);
+ writer.WriteLine(" builderIsReadOnly = true;");
writer.WriteLine(" return this;");
writer.WriteLine("}");
writer.WriteLine();
writer.WriteLine("public override Builder Clone() {");
- writer.WriteLine(" return new Builder().MergeFrom(result);");
+ writer.WriteLine(" if (builderIsReadOnly) {");
+ writer.WriteLine(" return new Builder(result);");
+ writer.WriteLine(" } else {");
+ writer.WriteLine(" return new Builder().MergeFrom(result);");
+ writer.WriteLine(" }");
writer.WriteLine("}");
writer.WriteLine();
if (!UseLiteRuntime)
@@ -622,17 +653,15 @@ namespace Google.ProtocolBuffers.ProtoGen writer.WriteLine("public override {0} BuildPartial() {{", ClassName);
writer.Indent();
- writer.WriteLine("if (result == null) {");
- writer.WriteLine(
- " throw new global::System.InvalidOperationException(\"build() has already been called on this Builder\");");
+ writer.WriteLine("if (builderIsReadOnly) {");
+ writer.WriteLine(" return result;");
writer.WriteLine("}");
foreach (FieldDescriptor field in Descriptor.Fields)
{
CreateFieldGenerator(field).GenerateBuildingCode(writer);
}
- writer.WriteLine("{0} returnMe = result;", ClassName);
- writer.WriteLine("result = null;");
- writer.WriteLine("return returnMe;");
+ writer.WriteLine("builderIsReadOnly = true;");
+ writer.WriteLine("return result;");
writer.Outdent();
writer.WriteLine("}");
writer.WriteLine();
@@ -653,6 +682,7 @@ namespace Google.ProtocolBuffers.ProtoGen // fields are set so we can skip the merge.
writer.Indent();
writer.WriteLine("if (other == {0}.DefaultInstance) return this;", FullClassName);
+ writer.WriteLine("PrepareBuilder();");
foreach (FieldDescriptor field in Descriptor.Fields)
{
CreateFieldGenerator(field).GenerateMergingCode(writer);
@@ -685,6 +715,7 @@ namespace Google.ProtocolBuffers.ProtoGen writer.WriteLine(
"public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {");
writer.Indent();
+ writer.WriteLine("PrepareBuilder();");
if (!UseLiteRuntime)
{
writer.WriteLine("pb::UnknownFieldSet.Builder unknownFields = null;");
diff --git a/src/ProtoGen/PrimitiveFieldGenerator.cs b/src/ProtoGen/PrimitiveFieldGenerator.cs index 0904ce22..69e0d4d9 100644 --- a/src/ProtoGen/PrimitiveFieldGenerator.cs +++ b/src/ProtoGen/PrimitiveFieldGenerator.cs @@ -74,12 +74,14 @@ namespace Google.ProtocolBuffers.ProtoGen AddPublicMemberAttributes(writer);
writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.has{0} = true;", PropertyName);
writer.WriteLine(" result.{0}_ = value;", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.has{0} = false;", PropertyName);
writer.WriteLine(" result.{0}_ = {1};", Name, DefaultValue);
writer.WriteLine(" return this;");
diff --git a/src/ProtoGen/RepeatedEnumFieldGenerator.cs b/src/ProtoGen/RepeatedEnumFieldGenerator.cs index fcda6564..aacee937 100644 --- a/src/ProtoGen/RepeatedEnumFieldGenerator.cs +++ b/src/ProtoGen/RepeatedEnumFieldGenerator.cs @@ -75,7 +75,7 @@ namespace Google.ProtocolBuffers.ProtoGen // We return it via IPopsicleList so that collection initializers work more pleasantly.
AddDeprecatedFlag(writer);
writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
- writer.WriteLine(" get {{ return result.{0}_; }}", Name);
+ writer.WriteLine(" get {{ return PrepareBuilder().{0}_; }}", Name);
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public int {0}Count {{", PropertyName);
@@ -87,21 +87,25 @@ namespace Google.ProtocolBuffers.ProtoGen writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_[index] = value;", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_.Add(value);", Name, TypeName);
writer.WriteLine(" return this;");
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_.Add(values);", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_.Clear();", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
diff --git a/src/ProtoGen/RepeatedMessageFieldGenerator.cs b/src/ProtoGen/RepeatedMessageFieldGenerator.cs index d8f0a8eb..6cc1e631 100644 --- a/src/ProtoGen/RepeatedMessageFieldGenerator.cs +++ b/src/ProtoGen/RepeatedMessageFieldGenerator.cs @@ -71,7 +71,7 @@ namespace Google.ProtocolBuffers.ProtoGen // We return it via IPopsicleList so that collection initializers work more pleasantly.
AddDeprecatedFlag(writer);
writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
- writer.WriteLine(" get {{ return result.{0}_; }}", Name);
+ writer.WriteLine(" get {{ return PrepareBuilder().{0}_; }}", Name);
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public int {0}Count {{", PropertyName);
@@ -84,6 +84,7 @@ namespace Google.ProtocolBuffers.ProtoGen AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_[index] = value;", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
@@ -91,12 +92,14 @@ namespace Google.ProtocolBuffers.ProtoGen AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Set{0}(int index, {1}.Builder builderForValue) {{", PropertyName, TypeName);
AddNullCheck(writer, "builderForValue");
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_[index] = builderForValue.Build();", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_.Add(value);", Name, TypeName);
writer.WriteLine(" return this;");
writer.WriteLine("}");
@@ -104,16 +107,19 @@ namespace Google.ProtocolBuffers.ProtoGen AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Add{0}({1}.Builder builderForValue) {{", PropertyName, TypeName);
AddNullCheck(writer, "builderForValue");
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_.Add(builderForValue.Build());", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_.Add(values);", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_.Clear();", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
diff --git a/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs b/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs index 33f0fa2b..645dce5c 100644 --- a/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs +++ b/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs @@ -75,7 +75,7 @@ namespace Google.ProtocolBuffers.ProtoGen // We return it via IPopsicleList so that collection initializers work more pleasantly.
AddPublicMemberAttributes(writer);
writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
- writer.WriteLine(" get {{ return result.{0}_; }}", Name);
+ writer.WriteLine(" get {{ return PrepareBuilder().{0}_; }}", Name);
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public int {0}Count {{", PropertyName);
@@ -88,22 +88,26 @@ namespace Google.ProtocolBuffers.ProtoGen AddPublicMemberAttributes(writer);
writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_[index] = value;", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
AddPublicMemberAttributes(writer);
writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_.Add(value);", Name, TypeName);
writer.WriteLine(" return this;");
writer.WriteLine("}");
AddPublicMemberAttributes(writer);
writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_.Add(values);", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
AddDeprecatedFlag(writer);
writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+ writer.WriteLine(" PrepareBuilder();");
writer.WriteLine(" result.{0}_.Clear();", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
|