Commit 642a8140 authored by Jon Skeet's avatar Jon Skeet

Setters/adders now throw ArgumentNullException appropriately.

parent 25a27922
......@@ -286,6 +286,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
set { SetNumber(value); }
}
public Builder SetNumber(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasNumber = true;
result.number_ = value;
return this;
......@@ -553,6 +554,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
set { SetName(value); }
}
public Builder SetName(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasName = true;
result.name_ = value;
return this;
......@@ -589,6 +591,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
set { SetEmail(value); }
}
public Builder SetEmail(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasEmail = true;
result.email_ = value;
return this;
......@@ -609,18 +612,22 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
return result.GetPhone(index);
}
public Builder SetPhone(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.phone_[index] = value;
return this;
}
public Builder SetPhone(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.phone_[index] = builderForValue.Build();
return this;
}
public Builder AddPhone(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.phone_.Add(value);
return this;
}
public Builder AddPhone(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.phone_.Add(builderForValue.Build());
return this;
}
......@@ -825,18 +832,22 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
return result.GetPerson(index);
}
public Builder SetPerson(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.person_[index] = value;
return this;
}
public Builder SetPerson(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.person_[index] = builderForValue.Build();
return this;
}
public Builder AddPerson(global::Google.ProtocolBuffers.Examples.AddressBook.Person value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.person_.Add(value);
return this;
}
public Builder AddPerson(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.person_.Add(builderForValue.Build());
return this;
}
......
This diff is collapsed.
This diff is collapsed.
using System;
using Google.ProtocolBuffers.Descriptors;
using System.Globalization;
using Google.ProtocolBuffers.Descriptors;
namespace Google.ProtocolBuffers.ProtoGen {
internal abstract class FieldGeneratorBase : SourceGeneratorBase<FieldDescriptor> {
......@@ -87,6 +87,45 @@ namespace Google.ProtocolBuffers.ProtoGen {
get { return Descriptor.FieldNumber; }
}
protected void AddNullCheck(TextGenerator writer) {
AddNullCheck(writer, "value");
}
protected void AddNullCheck(TextGenerator writer, string name) {
if (IsNullableType) {
writer.WriteLine(" pb::ThrowHelper.ThrowIfNull({0}, \"{0}\");", name);
}
}
protected bool IsNullableType {
get {
switch (Descriptor.FieldType) {
case FieldType.Float:
case FieldType.Double:
case FieldType.Int32:
case FieldType.Int64:
case FieldType.SInt32:
case FieldType.SInt64:
case FieldType.SFixed32:
case FieldType.SFixed64:
case FieldType.UInt32:
case FieldType.UInt64:
case FieldType.Fixed32:
case FieldType.Fixed64:
case FieldType.Bool:
case FieldType.Enum:
return false;
case FieldType.Bytes:
case FieldType.String:
case FieldType.Message:
case FieldType.Group:
return true;
default:
throw new InvalidOperationException("Invalid field descriptor type");
}
}
}
protected string TypeName {
get {
switch (Descriptor.FieldType) {
......
......@@ -27,16 +27,19 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine(" set {{ Set{0}(value); }}", PropertyName);
writer.WriteLine("}");
writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
writer.WriteLine(" result.has{0} = true;", PropertyName);
writer.WriteLine(" result.{0}_ = value;", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
writer.WriteLine("public Builder Set{0}({1}.Builder builderForValue) {{", PropertyName, TypeName);
AddNullCheck(writer, "builderForValue");
writer.WriteLine(" result.has{0} = true;", PropertyName);
writer.WriteLine(" result.{0}_ = builderForValue.Build();", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
writer.WriteLine("public Builder Merge{0}({1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
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, TypeName);
......
......@@ -29,6 +29,7 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine(" set {{ Set{0}(value); }}", PropertyName);
writer.WriteLine("}");
writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
writer.WriteLine(" result.has{0} = true;", PropertyName);
writer.WriteLine(" result.{0}_ = value;", Name);
writer.WriteLine(" return this;");
......
......@@ -38,20 +38,24 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine(" return result.Get{0}(index);", PropertyName);
writer.WriteLine("}");
writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
writer.WriteLine(" result.{0}_[index] = value;", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
// Extra overload for builder (just on messages)
writer.WriteLine("public Builder Set{0}(int index, {1}.Builder builderForValue) {{", PropertyName, TypeName);
AddNullCheck(writer, "builderForValue");
writer.WriteLine(" result.{0}_[index] = builderForValue.Build();", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
writer.WriteLine(" result.{0}_.Add(value);", Name, TypeName);
writer.WriteLine(" return this;");
writer.WriteLine("}");
// Extra overload for builder (just on messages)
writer.WriteLine("public Builder Add{0}({1}.Builder builderForValue) {{", PropertyName, TypeName);
AddNullCheck(writer, "builderForValue");
writer.WriteLine(" result.{0}_.Add(builderForValue.Build());", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
......
......@@ -38,10 +38,12 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine(" return result.Get{0}(index);", PropertyName);
writer.WriteLine("}");
writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
writer.WriteLine(" result.{0}_[index] = value;", Name);
writer.WriteLine(" return this;");
writer.WriteLine("}");
writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
AddNullCheck(writer);
writer.WriteLine(" result.{0}_.Add(value);", Name, TypeName);
writer.WriteLine(" return this;");
writer.WriteLine("}");
......
......@@ -53,16 +53,28 @@ namespace Google.ProtocolBuffers {
reflectionTester.AssertAllFieldsSetViaReflection(message);
}
[Test]
public void DynamicMessageSettersRejectNull() {
IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
reflectionTester.AssertReflectionSettersRejectNull(builder);
}
[Test]
public void DynamicMessageExtensionAccessors() {
// We don't need to extensively test DynamicMessage's handling of
// extensions because, frankly, it doesn't do anything special with them.
// It treats them just like any other fields.
IBuilder builder = DynamicMessage.CreateBuilder(TestAllExtensions.Descriptor);
extensionsReflectionTester.SetAllFieldsViaReflection(builder);
IMessage message = builder.WeakBuild();
extensionsReflectionTester.AssertAllFieldsSetViaReflection(message);
}
// We don't need to extensively test DynamicMessage's handling of
// extensions because, frankly, it doesn't do anything special with them.
// It treats them just like any other fields.
IBuilder builder = DynamicMessage.CreateBuilder(TestAllExtensions.Descriptor);
extensionsReflectionTester.SetAllFieldsViaReflection(builder);
IMessage message = builder.WeakBuild();
extensionsReflectionTester.AssertAllFieldsSetViaReflection(message);
}
[Test]
public void DynamicMessageExtensionSettersRejectNull() {
IBuilder builder = DynamicMessage.CreateBuilder(TestAllExtensions.Descriptor);
extensionsReflectionTester.AssertReflectionSettersRejectNull(builder);
}
[Test]
public void DynamicMessageRepeatedSetters() {
......@@ -73,6 +85,12 @@ namespace Google.ProtocolBuffers {
reflectionTester.AssertRepeatedFieldsModifiedViaReflection(message);
}
[Test]
public void DynamicMessageRepeatedSettersRejectNull() {
IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
reflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
}
[Test]
public void DynamicMessageDefaults() {
reflectionTester.AssertClearViaReflection(DynamicMessage.GetDefaultInstance(TestAllTypes.Descriptor));
......
......@@ -103,7 +103,20 @@ namespace Google.ProtocolBuffers {
TestAllTypes message = builder.Build();
TestUtil.AssertAllFieldsSet(message);
}
[Test]
public void SettersRejectNull() {
TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
TestUtil.AssertArgumentNullException(() => builder.SetOptionalString(null));
TestUtil.AssertArgumentNullException(() => builder.SetOptionalBytes(null));
TestUtil.AssertArgumentNullException(() => builder.SetOptionalNestedMessage((TestAllTypes.Types.NestedMessage)null));
TestUtil.AssertArgumentNullException(() => builder.SetOptionalNestedMessage((TestAllTypes.Types.NestedMessage.Builder)null));
TestUtil.AssertArgumentNullException(() => builder.AddRepeatedString(null));
TestUtil.AssertArgumentNullException(() => builder.AddRepeatedBytes(null));
TestUtil.AssertArgumentNullException(() => builder.AddRepeatedNestedMessage((TestAllTypes.Types.NestedMessage)null));
TestUtil.AssertArgumentNullException(() => builder.AddRepeatedNestedMessage((TestAllTypes.Types.NestedMessage.Builder)null));
}
[Test]
public void RepeatedSetters() {
TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
......@@ -130,6 +143,18 @@ namespace Google.ProtocolBuffers {
Assert.AreEqual(12, message.GetRepeatedForeignMessage(0).C);
}
[Test]
public void RepeatedAppendRejectsNull() {
TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
ForeignMessage foreignMessage = ForeignMessage.CreateBuilder().SetC(12).Build();
TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedForeignMessage(new[] { foreignMessage, null }));
TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedForeignMessage(null));
TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedForeignEnum(null));
TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedString(new[] { "one", null }));
TestUtil.AssertArgumentNullException(() => builder.AddRangeRepeatedBytes(new[] { TestUtil.ToBytes("one"), null }));
}
[Test]
public void SettingForeignMessageUsingBuilder() {
TestAllTypes message = TestAllTypes.CreateBuilder()
......@@ -181,6 +206,11 @@ namespace Google.ProtocolBuffers {
TestUtil.AssertAllFieldsSet(message);
}
[Test]
public void ReflectionSettersRejectNull() {
TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
reflectionTester.AssertReflectionSettersRejectNull(builder);
}
[Test]
public void ReflectionRepeatedSetters() {
TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
......@@ -190,6 +220,12 @@ namespace Google.ProtocolBuffers {
TestUtil.AssertRepeatedFieldsModified(message);
}
[Test]
public void TestReflectionRepeatedSettersRejectNull() {
TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
reflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
}
[Test]
public void ReflectionDefaults() {
reflectionTester.AssertClearViaReflection(TestAllTypes.DefaultInstance);
......@@ -237,6 +273,12 @@ namespace Google.ProtocolBuffers {
TestUtil.AssertAllExtensionsSet(message);
}
[Test]
public void ExtensionReflectionSettersRejectNull() {
TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
extensionsReflectionTester.AssertReflectionSettersRejectNull(builder);
}
[Test]
public void ExtensionReflectionRepeatedSetters() {
TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
......@@ -246,6 +288,12 @@ namespace Google.ProtocolBuffers {
TestUtil.AssertRepeatedExtensionsModified(message);
}
[Test]
public void ExtensionReflectionRepeatedSettersRejectNull() {
TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
extensionsReflectionTester.AssertReflectionRepeatedSettersRejectNull(builder);
}
[Test]
public void ExtensionReflectionDefaults() {
extensionsReflectionTester.AssertClearViaReflection(TestAllExtensions.DefaultInstance);
......@@ -265,6 +313,18 @@ namespace Google.ProtocolBuffers {
.GetExtensionCount(UnitTestProtoFile.RepeatedInt32Extension));
}
/* Reinstate this test in the commit where it's fixed...
[Test]
public void ExtensionMergeFrom() {
TestAllExtensions original = TestAllExtensions.CreateBuilder()
.SetExtension(UnitTestProtoFile.OptionalInt32Extension, 1).Build();
TestAllExtensions merged =
TestAllExtensions.CreateBuilder().MergeFrom(original).Build();
Assert.IsTrue((merged.HasExtension(UnitTestProtoFile.OptionalInt32Extension)));
Assert.AreEqual(1, (int)merged.GetExtension(UnitTestProtoFile.OptionalInt32Extension));
}
*/
/* Removed multiple files option for the moment
[Test]
public void MultipleFilesOption() {
......
......@@ -810,5 +810,37 @@ namespace Google.ProtocolBuffers {
Assert.AreEqual("524", message[f("repeated_string_piece"), 1]);
Assert.AreEqual("525", message[f("repeated_cord"), 1]);
}
/// <summary>
/// Verifies that the reflection setters for the given Builder object throw an
/// ArgumentNullException if they are passed a null value.
/// </summary>
public void AssertReflectionSettersRejectNull(IBuilder builder) {
TestUtil.AssertArgumentNullException(() => builder[f("optional_string")] = null);
TestUtil.AssertArgumentNullException(() => builder[f("optional_bytes")] = null);
TestUtil.AssertArgumentNullException(() => builder[f("optional_nested_enum")] = null);
TestUtil.AssertArgumentNullException(() => builder[f("optional_nested_message")] = null);
TestUtil.AssertArgumentNullException(() => builder[f("optional_nested_message")] = null);
TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_string"), null));
TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_bytes"), null));
TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_nested_enum"), null));
TestUtil.AssertArgumentNullException(() => builder.WeakAddRepeatedField(f("repeated_nested_message"), null));
}
/// <summary>
/// Verifies that the reflection repeated setters for the given Builder object throw an
/// ArgumentNullException if they are passed a null value.
/// </summary>
public void AssertReflectionRepeatedSettersRejectNull(IBuilder builder) {
builder.WeakAddRepeatedField(f("repeated_string"), "one");
TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_string"), 0, null));
builder.WeakAddRepeatedField(f("repeated_bytes"), TestUtil.ToBytes("one"));
TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_bytes"), 0, null));
builder.WeakAddRepeatedField(f("repeated_nested_enum"), nestedBaz);
TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_nested_enum"), 0, null));
builder.WeakAddRepeatedField(f("repeated_nested_message"),
new TestAllTypes.Types.NestedMessage.Builder { Bb = 218 }.Build());
TestUtil.AssertArgumentNullException(() => builder.SetRepeatedField(f("repeated_nested_message"), 0, null));
}
}
}
......@@ -397,6 +397,7 @@ namespace Google.ProtocolBuffers.TestProtos {
set { SetField1(value); }
}
public Builder SetField1(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasField1 = true;
result.field1_ = value;
return this;
......@@ -1593,16 +1594,19 @@ namespace Google.ProtocolBuffers.TestProtos {
set { SetBar(value); }
}
public Builder SetBar(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1 value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasBar = true;
result.bar_ = value;
return this;
}
public Builder SetBar(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.hasBar = true;
result.bar_ = builderForValue.Build();
return this;
}
public Builder MergeBar(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1 value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
if (result.HasBar &&
result.bar_ != global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.DefaultInstance) {
result.bar_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.CreateBuilder(result.bar_).MergeFrom(value).BuildPartial();
......@@ -1644,16 +1648,19 @@ namespace Google.ProtocolBuffers.TestProtos {
set { SetFred(value); }
}
public Builder SetFred(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4 value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasFred = true;
result.fred_ = value;
return this;
}
public Builder SetFred(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.hasFred = true;
result.fred_ = builderForValue.Build();
return this;
}
public Builder MergeFred(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4 value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
if (result.HasFred &&
result.fred_ != global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.DefaultInstance) {
result.fred_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.CreateBuilder(result.fred_).MergeFrom(value).BuildPartial();
......@@ -1925,16 +1932,19 @@ namespace Google.ProtocolBuffers.TestProtos {
set { SetComplexOptionType5(value); }
}
public Builder SetComplexOptionType5(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5 value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasComplexOptionType5 = true;
result.complexOptionType5_ = value;
return this;
}
public Builder SetComplexOptionType5(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.hasComplexOptionType5 = true;
result.complexOptionType5_ = builderForValue.Build();
return this;
}
public Builder MergeComplexOptionType5(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5 value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
if (result.HasComplexOptionType5 &&
result.complexOptionType5_ != global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.DefaultInstance) {
result.complexOptionType5_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.CreateBuilder(result.complexOptionType5_).MergeFrom(value).BuildPartial();
......
......@@ -256,16 +256,19 @@ namespace Google.ProtocolBuffers.TestProtos {
set { SetOptionalMessage(value); }
}
public Builder SetOptionalMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasOptionalMessage = true;
result.optionalMessage_ = value;
return this;
}
public Builder SetOptionalMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.hasOptionalMessage = true;
result.optionalMessage_ = builderForValue.Build();
return this;
}
public Builder MergeOptionalMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
if (result.HasOptionalMessage &&
result.optionalMessage_ != global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.DefaultInstance) {
result.optionalMessage_ = global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.CreateBuilder(result.optionalMessage_).MergeFrom(value).BuildPartial();
......@@ -291,18 +294,22 @@ namespace Google.ProtocolBuffers.TestProtos {
return result.GetRepeatedMessage(index);
}
public Builder SetRepeatedMessage(int index, global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.repeatedMessage_[index] = value;
return this;
}
public Builder SetRepeatedMessage(int index, global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.repeatedMessage_[index] = builderForValue.Build();
return this;
}
public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.repeatedMessage_.Add(value);
return this;
}
public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.repeatedMessage_.Add(builderForValue.Build());
return this;
}
......
......@@ -410,16 +410,19 @@ namespace Google.ProtocolBuffers.TestProtos {
set { SetMessageSet(value); }
}
public Builder SetMessageSet(global::Google.ProtocolBuffers.TestProtos.TestMessageSet value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasMessageSet = true;
result.messageSet_ = value;
return this;
}
public Builder SetMessageSet(global::Google.ProtocolBuffers.TestProtos.TestMessageSet.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.hasMessageSet = true;
result.messageSet_ = builderForValue.Build();
return this;
}
public Builder MergeMessageSet(global::Google.ProtocolBuffers.TestProtos.TestMessageSet value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
if (result.HasMessageSet &&
result.messageSet_ != global::Google.ProtocolBuffers.TestProtos.TestMessageSet.DefaultInstance) {
result.messageSet_ = global::Google.ProtocolBuffers.TestProtos.TestMessageSet.CreateBuilder(result.messageSet_).MergeFrom(value).BuildPartial();
......@@ -813,6 +816,7 @@ namespace Google.ProtocolBuffers.TestProtos {
set { SetStr(value); }
}
public Builder SetStr(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasStr = true;
result.str_ = value;
return this;
......@@ -1071,6 +1075,7 @@ namespace Google.ProtocolBuffers.TestProtos {
set { SetMessage(value); }
}
public Builder SetMessage(pb::ByteString value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasMessage = true;
result.message_ = value;
return this;
......@@ -1251,18 +1256,22 @@ namespace Google.ProtocolBuffers.TestProtos {
return result.GetItem(index);
}
public Builder SetItem(int index, global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.item_[index] = value;
return this;
}
public Builder SetItem(int index, global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.item_[index] = builderForValue.Build();
return this;
}
public Builder AddItem(global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.item_.Add(value);
return this;
}
public Builder AddItem(global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.item_.Add(builderForValue.Build());
return this;
}
......
......@@ -189,16 +189,19 @@ namespace Google.ProtocolBuffers.TestProtos {
set { SetMsg(value); }
}
public Builder SetMsg(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasMsg = true;
result.msg_ = value;
return this;
}
public Builder SetMsg(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.hasMsg = true;
result.msg_ = builderForValue.Build();
return this;
}
public Builder MergeMsg(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
if (result.HasMsg &&
result.msg_ != global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance) {
result.msg_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder(result.msg_).MergeFrom(value).BuildPartial();
......@@ -438,16 +441,19 @@ namespace Google.ProtocolBuffers.TestProtos {
set { SetO(value); }
}
public Builder SetO(global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasO = true;
result.o_ = value;
return this;
}
public Builder SetO(global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.Builder builderForValue) {
pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
result.hasO = true;
result.o_ = builderForValue.Build();
return this;
}
public Builder MergeO(global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
if (result.HasO &&
result.o_ != global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.DefaultInstance) {
result.o_ = global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.CreateBuilder(result.o_).MergeFrom(value).BuildPartial();
......
......@@ -1383,5 +1383,14 @@ namespace Google.ProtocolBuffers {
}
return bytes;
}
internal static void AssertArgumentNullException(Action action) {
try {
action();
Assert.Fail("Exception was not thrown");
} catch (ArgumentNullException) {
// We expect this exception.
}
}
}
}
......@@ -499,5 +499,29 @@ namespace Google.ProtocolBuffers {
AssertFormatException(() => TextFormat.ParseUInt64("-1"));
AssertFormatException(() => TextFormat.ParseInt32("abcd"));
}
[Test]
public void ParseLongString() {
string longText =
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890" +
"123456789012345678901234567890123456789012345678901234567890";
TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
TextFormat.Merge("optional_string: \"" + longText + "\"", builder);
Assert.AreEqual(longText, builder.OptionalString);
}
}
}
......@@ -192,6 +192,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
set { SetNamespace(value); }
}
public Builder SetNamespace(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasNamespace = true;
result.namespace_ = value;
return this;
......@@ -210,6 +211,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
set { SetUmbrellaClassname(value); }
}
public Builder SetUmbrellaClassname(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasUmbrellaClassname = true;
result.umbrellaClassname_ = value;
return this;
......@@ -381,6 +383,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
set { SetPropertyName(value); }
}
public Builder SetPropertyName(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasPropertyName = true;
result.propertyName_ = value;
return this;
......
......@@ -66,10 +66,12 @@ namespace Google.ProtocolBuffers.FieldAccess {
}
public override void AddRepeated(TBuilder builder, object value) {
base.AddRepeated(builder, ((EnumValueDescriptor) value).Number);
ThrowHelper.ThrowIfNull(value, "value");
base.AddRepeated(builder, ((EnumValueDescriptor)value).Number);
}
public override void SetRepeated(TBuilder builder, int index, object value) {
ThrowHelper.ThrowIfNull(value, "value");
base.SetRepeated(builder, index, ((EnumValueDescriptor) value).Number);
}
}
......
......@@ -64,7 +64,7 @@ namespace Google.ProtocolBuffers.FieldAccess {
/// which may already be of the right type or may be a dynamic message.
/// </summary>
private object CoerceType(object value) {
ThrowHelper.ThrowIfNull(value, "value");
// If it's already of the right type, we're done
if (ClrType.IsInstanceOfType(value)) {
return value;
......
......@@ -122,10 +122,12 @@ namespace Google.ProtocolBuffers.FieldAccess {
}
public virtual void SetRepeated(TBuilder builder, int index, object value) {
setElementMethod.Invoke(builder, new object[] {index, value} );
ThrowHelper.ThrowIfNull(value, "value");
setElementMethod.Invoke(builder, new object[] { index, value });
}
public virtual void AddRepeated(TBuilder builder, object value) {
ThrowHelper.ThrowIfNull(value, "value");
addValueDelegate(builder, value);
}
......
......@@ -63,6 +63,7 @@ namespace Google.ProtocolBuffers.FieldAccess {
/// from an EnumValueDescriptor parameter.
/// </summary>
public override void SetValue(TBuilder builder, object value) {
ThrowHelper.ThrowIfNull(value, "value");
EnumValueDescriptor valueDescriptor = (EnumValueDescriptor) value;
base.SetValue(builder, valueDescriptor.Number);
}
......
......@@ -60,7 +60,7 @@ namespace Google.ProtocolBuffers.FieldAccess {
/// which may already be of the right type or may be a dynamic message.
/// </summary>
private object CoerceType(object value) {
ThrowHelper.ThrowIfNull(value, "value");
// If it's already of the right type, we're done
if (ClrType.IsInstanceOfType(value)) {
return value;
......
......@@ -413,7 +413,9 @@ namespace Google.ProtocolBuffers {
/// element type, not whether it's a list.
/// </remarks>
/// <exception cref="ArgumentException">The value is not of the right type.</exception>
/// <exception cref="ArgumentNullException">The value is null.</exception>
private static void VerifyType(FieldDescriptor field, object value) {
ThrowHelper.ThrowIfNull(value, "value");
bool isValid = false;
switch (field.MappedType) {
case MappedType.Int32: isValid = value is int; break;
......
......@@ -78,7 +78,13 @@ namespace Google.ProtocolBuffers {
/// <summary>
/// Adds all of the specified values to the given collection.
/// </summary>
/// <exception cref="ArgumentNullException">Any element of the list is null</exception>
protected void AddRange<T>(IEnumerable<T> source, IList<T> destination) {
ThrowHelper.ThrowIfNull(source);
// We only need to check this for nullable types.
if (default(T) == null) {
ThrowHelper.ThrowIfAnyNull(source);
}
List<T> list = destination as List<T>;
if (list != null) {
list.AddRange(source);
......
......@@ -104,6 +104,7 @@
<Compile Include="TextFormat.cs" />
<Compile Include="TextGenerator.cs" />
<Compile Include="TextTokenizer.cs" />
<Compile Include="ThrowHelper.cs" />
<Compile Include="UninitializedMessageException.cs" />
<Compile Include="UnknownField.cs" />
<Compile Include="UnknownFieldSet.cs" />
......
using System;
using System.Collections.Generic;
using System.Text;
namespace Google.ProtocolBuffers {
/// <summary>
/// Helper methods for throwing exceptions
/// </summary>
public static class ThrowHelper {
/// <summary>
/// Throws an ArgumentNullException if the given value is null.
/// </summary>
public static void ThrowIfNull(object value, string name) {
if (value == null) {
throw new ArgumentNullException(name);
}
}
/// <summary>
/// Throws an ArgumentNullException if the given value is null.
/// </summary>
public static void ThrowIfNull(object value) {
if (value == null) {
throw new ArgumentNullException();
}
}
/// <summary>
/// Throws an ArgumentNullException if the given value or any element within it is null.
/// </summary>
public static void ThrowIfAnyNull<T>(IEnumerable<T> sequence) {
foreach (T t in sequence) {
if (t == null) {
throw new ArgumentNullException();
}
}
}
}
}
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