Commit f26f8dce authored by Jon Skeet's avatar Jon Skeet

The great generics revisiting.

parent 9134a21f
...@@ -10,15 +10,13 @@ namespace Google.ProtocolBuffers { ...@@ -10,15 +10,13 @@ namespace Google.ProtocolBuffers {
[Test] [Test]
public void Clear() { public void Clear() {
AbstractMessageWrapper message = (AbstractMessageWrapper) AbstractMessageWrapper message = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(TestUtil.GetAllSet())).Clear().Build();
new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(TestUtil.GetAllSet())).Clear().Build();
TestUtil.AssertClear((TestAllTypes) message.WrappedMessage); TestUtil.AssertClear((TestAllTypes) message.WrappedMessage);
} }
[Test] [Test]
public void Copy() { public void Copy() {
AbstractMessageWrapper message = (AbstractMessageWrapper) AbstractMessageWrapper message = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder()).MergeFrom(TestUtil.GetAllSet()).Build();
new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder()).MergeFrom(TestUtil.GetAllSet()).Build();
TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage); TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
} }
...@@ -40,7 +38,7 @@ namespace Google.ProtocolBuffers { ...@@ -40,7 +38,7 @@ namespace Google.ProtocolBuffers {
[Test] [Test]
public void Parsing() { public void Parsing() {
IBuilder builder = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder()); IBuilder builder = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder());
AbstractMessageWrapper message = (AbstractMessageWrapper) builder.MergeFrom(TestUtil.GetAllSet().ToByteString()).Build(); AbstractMessageWrapper message = (AbstractMessageWrapper) builder.WeakMergeFrom(TestUtil.GetAllSet().ToByteString()).WeakBuild();
TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage); TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
} }
...@@ -177,7 +175,7 @@ namespace Google.ProtocolBuffers { ...@@ -177,7 +175,7 @@ namespace Google.ProtocolBuffers {
Assert.AreEqual(message, message); Assert.AreEqual(message, message);
// Object should be equal to a dynamic copy of itself. // Object should be equal to a dynamic copy of itself.
DynamicMessage dynamic = (DynamicMessage) ((IBuilder) DynamicMessage.CreateBuilder(message)).Build(); DynamicMessage dynamic = DynamicMessage.CreateBuilder(message).Build();
Assert.AreEqual(message, dynamic); Assert.AreEqual(message, dynamic);
Assert.AreEqual(dynamic, message); Assert.AreEqual(dynamic, message);
Assert.AreEqual(dynamic.GetHashCode(), message.GetHashCode()); Assert.AreEqual(dynamic.GetHashCode(), message.GetHashCode());
...@@ -207,7 +205,7 @@ namespace Google.ProtocolBuffers { ...@@ -207,7 +205,7 @@ namespace Google.ProtocolBuffers {
/// test that AbstractMessage's implementations work even if the wrapped /// test that AbstractMessage's implementations work even if the wrapped
/// object does not use them. /// object does not use them.
/// </summary> /// </summary>
private class AbstractMessageWrapper : AbstractMessage { private class AbstractMessageWrapper : AbstractMessage<AbstractMessageWrapper, AbstractMessageWrapper.Builder> {
private readonly IMessage wrappedMessage; private readonly IMessage wrappedMessage;
public IMessage WrappedMessage { public IMessage WrappedMessage {
...@@ -222,8 +220,8 @@ namespace Google.ProtocolBuffers { ...@@ -222,8 +220,8 @@ namespace Google.ProtocolBuffers {
get { return wrappedMessage.DescriptorForType; } get { return wrappedMessage.DescriptorForType; }
} }
protected override IMessage DefaultInstanceForTypeImpl { public override AbstractMessageWrapper DefaultInstanceForType {
get { return new AbstractMessageWrapper(wrappedMessage.DefaultInstanceForType); } get { return new AbstractMessageWrapper(wrappedMessage.WeakDefaultInstanceForType); }
} }
public override IDictionary<FieldDescriptor, object> AllFields { public override IDictionary<FieldDescriptor, object> AllFields {
...@@ -250,17 +248,26 @@ namespace Google.ProtocolBuffers { ...@@ -250,17 +248,26 @@ namespace Google.ProtocolBuffers {
get { return wrappedMessage.UnknownFields; } get { return wrappedMessage.UnknownFields; }
} }
protected override IBuilder CreateBuilderForTypeImpl() { public override Builder CreateBuilderForType() {
return new Builder(wrappedMessage.CreateBuilderForType()); return new Builder(wrappedMessage.WeakCreateBuilderForType());
} }
internal class Builder : AbstractBuilder { internal class Builder : AbstractBuilder<AbstractMessageWrapper, Builder> {
private readonly IBuilder wrappedBuilder; private readonly IBuilder wrappedBuilder;
protected override Builder ThisBuilder {
get { return this; }
}
internal Builder(IBuilder wrappedBuilder) { internal Builder(IBuilder wrappedBuilder) {
this.wrappedBuilder = wrappedBuilder; this.wrappedBuilder = wrappedBuilder;
} }
public override Builder MergeFrom(AbstractMessageWrapper other) {
wrappedBuilder.WeakMergeFrom(other.wrappedMessage);
return this;
}
public override bool IsInitialized { public override bool IsInitialized {
get { return wrappedBuilder.IsInitialized; } get { return wrappedBuilder.IsInitialized; }
} }
...@@ -296,29 +303,29 @@ namespace Google.ProtocolBuffers { ...@@ -296,29 +303,29 @@ namespace Google.ProtocolBuffers {
set { wrappedBuilder.UnknownFields = value; } set { wrappedBuilder.UnknownFields = value; }
} }
protected override IMessage BuildImpl() { public override AbstractMessageWrapper Build() {
return new AbstractMessageWrapper(wrappedBuilder.Build()); return new AbstractMessageWrapper(wrappedBuilder.WeakBuild());
} }
protected override IMessage BuildPartialImpl() { public override AbstractMessageWrapper BuildPartial() {
return new AbstractMessageWrapper(wrappedBuilder.BuildPartial()); return new AbstractMessageWrapper(wrappedBuilder.WeakBuildPartial());
} }
protected override IBuilder CloneImpl() { public override Builder Clone() {
return new Builder(wrappedBuilder.Clone()); return new Builder(wrappedBuilder.WeakClone());
} }
protected override IMessage DefaultInstanceForTypeImpl { public override AbstractMessageWrapper DefaultInstanceForType {
get { return wrappedBuilder.DefaultInstanceForType; } get { return new AbstractMessageWrapper(wrappedBuilder.WeakDefaultInstanceForType); }
} }
protected override IBuilder ClearFieldImpl(FieldDescriptor field) { public override Builder ClearField(FieldDescriptor field) {
wrappedBuilder.ClearField(field); wrappedBuilder.WeakClearField(field);
return this; return this;
} }
protected override IBuilder AddRepeatedFieldImpl(FieldDescriptor field, object value) { public override Builder AddRepeatedField(FieldDescriptor field, object value) {
wrappedBuilder.AddRepeatedField(field, value); wrappedBuilder.WeakAddRepeatedField(field, value);
return this; return this;
} }
...@@ -327,13 +334,13 @@ namespace Google.ProtocolBuffers { ...@@ -327,13 +334,13 @@ namespace Google.ProtocolBuffers {
return this; return this;
} }
public override IBuilder MergeFrom(IMessage other) { public override Builder MergeFrom(IMessage other) {
wrappedBuilder.MergeFrom(other); wrappedBuilder.WeakMergeFrom(other);
return this; return this;
} }
protected override IBuilder MergeFromImpl(CodedInputStream input, ExtensionRegistry extensionRegistry) { public override Builder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
wrappedBuilder.MergeFrom(input, extensionRegistry); wrappedBuilder.WeakMergeFrom(input, extensionRegistry);
return this; return this;
} }
} }
......
...@@ -21,7 +21,7 @@ namespace Google.ProtocolBuffers { ...@@ -21,7 +21,7 @@ namespace Google.ProtocolBuffers {
public void DynamicMessageAccessors() { public void DynamicMessageAccessors() {
IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor); IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
reflectionTester.SetAllFieldsViaReflection(builder); reflectionTester.SetAllFieldsViaReflection(builder);
IMessage message = builder.Build(); IMessage message = builder.WeakBuild();
reflectionTester.AssertAllFieldsSetViaReflection(message); reflectionTester.AssertAllFieldsSetViaReflection(message);
} }
...@@ -32,7 +32,7 @@ namespace Google.ProtocolBuffers { ...@@ -32,7 +32,7 @@ namespace Google.ProtocolBuffers {
// It treats them just like any other fields. // It treats them just like any other fields.
IBuilder builder = DynamicMessage.CreateBuilder(TestAllExtensions.Descriptor); IBuilder builder = DynamicMessage.CreateBuilder(TestAllExtensions.Descriptor);
extensionsReflectionTester.SetAllFieldsViaReflection(builder); extensionsReflectionTester.SetAllFieldsViaReflection(builder);
IMessage message = builder.Build(); IMessage message = builder.WeakBuild();
extensionsReflectionTester.AssertAllFieldsSetViaReflection(message); extensionsReflectionTester.AssertAllFieldsSetViaReflection(message);
} }
...@@ -41,7 +41,7 @@ namespace Google.ProtocolBuffers { ...@@ -41,7 +41,7 @@ namespace Google.ProtocolBuffers {
IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor); IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
reflectionTester.SetAllFieldsViaReflection(builder); reflectionTester.SetAllFieldsViaReflection(builder);
reflectionTester.ModifyRepeatedFieldsViaReflection(builder); reflectionTester.ModifyRepeatedFieldsViaReflection(builder);
IMessage message = builder.Build(); IMessage message = builder.WeakBuild();
reflectionTester.AssertRepeatedFieldsModifiedViaReflection(message); reflectionTester.AssertRepeatedFieldsModifiedViaReflection(message);
} }
...@@ -57,7 +57,7 @@ namespace Google.ProtocolBuffers { ...@@ -57,7 +57,7 @@ namespace Google.ProtocolBuffers {
IBuilder dynamicBuilder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor); IBuilder dynamicBuilder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
reflectionTester.SetAllFieldsViaReflection(dynamicBuilder); reflectionTester.SetAllFieldsViaReflection(dynamicBuilder);
IMessage dynamicMessage = dynamicBuilder.Build(); IMessage dynamicMessage = dynamicBuilder.WeakBuild();
Assert.AreEqual(message.SerializedSize, dynamicMessage.SerializedSize); Assert.AreEqual(message.SerializedSize, dynamicMessage.SerializedSize);
} }
...@@ -66,7 +66,7 @@ namespace Google.ProtocolBuffers { ...@@ -66,7 +66,7 @@ namespace Google.ProtocolBuffers {
public void DynamicMessageSerialization() { public void DynamicMessageSerialization() {
IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor); IBuilder builder = DynamicMessage.CreateBuilder(TestAllTypes.Descriptor);
reflectionTester.SetAllFieldsViaReflection(builder); reflectionTester.SetAllFieldsViaReflection(builder);
IMessage message = builder.Build(); IMessage message = builder.WeakBuild();
ByteString rawBytes = message.ToByteString(); ByteString rawBytes = message.ToByteString();
TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes); TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
......
...@@ -153,8 +153,7 @@ namespace Google.ProtocolBuffers { ...@@ -153,8 +153,7 @@ namespace Google.ProtocolBuffers {
builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredInitialized; builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredInitialized;
Assert.IsTrue(builder.IsInitialized); Assert.IsTrue(builder.IsInitialized);
// TODO(jonskeet): Remove this nastiness by making IBuilder always generic. builder.AddRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), TestRequiredUninitialized);
((IBuilder) builder).AddRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), TestRequiredUninitialized);
Assert.IsFalse(builder.IsInitialized); Assert.IsFalse(builder.IsInitialized);
builder.SetRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), 0, TestRequiredInitialized); builder.SetRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), 0, TestRequiredInitialized);
...@@ -266,8 +265,7 @@ namespace Google.ProtocolBuffers { ...@@ -266,8 +265,7 @@ namespace Google.ProtocolBuffers {
[Test] [Test]
public void DynamicBuildPartial() { public void DynamicBuildPartial() {
// We're mostly testing that no exception is thrown. // We're mostly testing that no exception is thrown.
// TODO(jonskeet): Fix this ghastly casting mess DynamicMessage message = DynamicMessage.CreateBuilder(TestRequired.Descriptor).BuildPartial();
DynamicMessage message = (DynamicMessage) ((IBuilder) DynamicMessage.CreateBuilder(TestRequired.Descriptor)).BuildPartial();
Assert.IsFalse(message.Initialized); Assert.IsFalse(message.Initialized);
} }
......
...@@ -95,12 +95,16 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -95,12 +95,16 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public static Builder CreateBuilder() { return new Builder(); } public static Builder CreateBuilder() { return new Builder(); }
public override IBuilder<self::MessageWithNoOuter.Types.NestedMessage> CreateBuilderForType() { return new Builder(); } public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(self::MessageWithNoOuter.Types.NestedMessage prototype) { public static Builder CreateBuilder(self::MessageWithNoOuter.Types.NestedMessage prototype) {
return (Builder) new Builder().MergeFrom(prototype); return (Builder) new Builder().MergeFrom(prototype);
} }
public sealed partial class Builder : pb::GeneratedBuilder<self::MessageWithNoOuter.Types.NestedMessage, Builder> { public sealed partial class Builder : pb::GeneratedBuilder<self::MessageWithNoOuter.Types.NestedMessage, Builder> {
protected override Builder ThisBuilder {
get { return this; }
}
// Construct using self::MessageWithNoOuter.Types.NestedMessage.CreateBuilder() // Construct using self::MessageWithNoOuter.Types.NestedMessage.CreateBuilder()
internal Builder() {} internal Builder() {}
...@@ -110,12 +114,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -110,12 +114,12 @@ namespace Google.ProtocolBuffers.TestProtos {
get { return result; } get { return result; }
} }
public override IBuilder<self::MessageWithNoOuter.Types.NestedMessage> Clear() { public override Builder Clear() {
result = new self::MessageWithNoOuter.Types.NestedMessage(); result = new self::MessageWithNoOuter.Types.NestedMessage();
return this; return this;
} }
public override IBuilder<self::MessageWithNoOuter.Types.NestedMessage> Clone() { public override Builder Clone() {
return new Builder().MergeFrom(result); return new Builder().MergeFrom(result);
} }
...@@ -231,12 +235,16 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -231,12 +235,16 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public static Builder CreateBuilder() { return new Builder(); } public static Builder CreateBuilder() { return new Builder(); }
public override IBuilder<self::MessageWithNoOuter> CreateBuilderForType() { return new Builder(); } public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(self::MessageWithNoOuter prototype) { public static Builder CreateBuilder(self::MessageWithNoOuter prototype) {
return (Builder) new Builder().MergeFrom(prototype); return (Builder) new Builder().MergeFrom(prototype);
} }
public sealed partial class Builder : pb::GeneratedBuilder<self::MessageWithNoOuter, Builder> { public sealed partial class Builder : pb::GeneratedBuilder<self::MessageWithNoOuter, Builder> {
protected override Builder ThisBuilder {
get { return this; }
}
// Construct using self::MessageWithNoOuter.CreateBuilder() // Construct using self::MessageWithNoOuter.CreateBuilder()
internal Builder() {} internal Builder() {}
...@@ -246,12 +254,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -246,12 +254,12 @@ namespace Google.ProtocolBuffers.TestProtos {
get { return result; } get { return result; }
} }
public override IBuilder<self::MessageWithNoOuter> Clear() { public override Builder Clear() {
result = new self::MessageWithNoOuter(); result = new self::MessageWithNoOuter();
return this; return this;
} }
public override IBuilder<self::MessageWithNoOuter> Clone() { public override Builder Clone() {
return new Builder().MergeFrom(result); return new Builder().MergeFrom(result);
} }
......
...@@ -59,8 +59,8 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -59,8 +59,8 @@ namespace Google.ProtocolBuffers.TestProtos {
#endregion #endregion
#region Extensions #region Extensions
public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, int> ExtensionWithOuter = public static readonly pb::GeneratedExtensionBase<int> ExtensionWithOuter =
pb::GeneratedSingleExtension<self::TestAllExtensions, int>.CreateInstance(Descriptor.Extensions[0]); pb::GeneratedSingleExtension<int>.CreateInstance(Descriptor.Extensions[0]);
#endregion #endregion
#region Static variables #region Static variables
......
...@@ -95,7 +95,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -95,7 +95,7 @@ namespace Google.ProtocolBuffers.TestProtos {
controller, controller,
request, request,
self::TestAllTypes.DefaultInstance, self::TestAllTypes.DefaultInstance,
pb::RpcUtil.GeneralizeCallback(done, self::TestAllTypes.DefaultInstance)); pb::RpcUtil.GeneralizeCallback<self::TestAllTypes, self::TestAllTypes.Builder>(done, self::TestAllTypes.DefaultInstance));
} }
} }
} }
......
...@@ -174,12 +174,16 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -174,12 +174,16 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public static Builder CreateBuilder() { return new Builder(); } public static Builder CreateBuilder() { return new Builder(); }
public override IBuilder<self::TestEmbedOptimizedForSize> CreateBuilderForType() { return new Builder(); } public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(self::TestEmbedOptimizedForSize prototype) { public static Builder CreateBuilder(self::TestEmbedOptimizedForSize prototype) {
return (Builder) new Builder().MergeFrom(prototype); return (Builder) new Builder().MergeFrom(prototype);
} }
public sealed partial class Builder : pb::GeneratedBuilder<self::TestEmbedOptimizedForSize, Builder> { public sealed partial class Builder : pb::GeneratedBuilder<self::TestEmbedOptimizedForSize, Builder> {
protected override Builder ThisBuilder {
get { return this; }
}
// Construct using self::TestEmbedOptimizedForSize.CreateBuilder() // Construct using self::TestEmbedOptimizedForSize.CreateBuilder()
internal Builder() {} internal Builder() {}
...@@ -189,12 +193,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -189,12 +193,12 @@ namespace Google.ProtocolBuffers.TestProtos {
get { return result; } get { return result; }
} }
public override IBuilder<self::TestEmbedOptimizedForSize> Clear() { public override Builder Clear() {
result = new self::TestEmbedOptimizedForSize(); result = new self::TestEmbedOptimizedForSize();
return this; return this;
} }
public override IBuilder<self::TestEmbedOptimizedForSize> Clone() { public override Builder Clone() {
return new Builder().MergeFrom(result); return new Builder().MergeFrom(result);
} }
...@@ -215,11 +219,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -215,11 +219,7 @@ namespace Google.ProtocolBuffers.TestProtos {
return returnMe; return returnMe;
} }
protected override IBuilder MergeFromImpl(CodedInputStream data, ExtensionRegistry extensionRegistry) { public override Builder MergeFrom(pb::IMessage other) {
return MergeFrom(data, extensionRegistry);
}
public override IBuilder MergeFrom(pb::IMessage other) {
if (other is self::TestEmbedOptimizedForSize) { if (other is self::TestEmbedOptimizedForSize) {
return MergeFrom((self::TestEmbedOptimizedForSize) other); return MergeFrom((self::TestEmbedOptimizedForSize) other);
} else { } else {
...@@ -228,7 +228,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -228,7 +228,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
} }
public override IBuilder<self::TestEmbedOptimizedForSize> MergeFrom(self::TestEmbedOptimizedForSize other) { public override Builder MergeFrom(self::TestEmbedOptimizedForSize other) {
if (other == self::TestEmbedOptimizedForSize.DefaultInstance) return this; if (other == self::TestEmbedOptimizedForSize.DefaultInstance) return this;
if (other.HasOptionalMessage) { if (other.HasOptionalMessage) {
MergeOptionalMessage(other.OptionalMessage); MergeOptionalMessage(other.OptionalMessage);
...@@ -243,11 +243,11 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -243,11 +243,11 @@ namespace Google.ProtocolBuffers.TestProtos {
return this; return this;
} }
public override IBuilder<self::TestEmbedOptimizedForSize> MergeFrom(pb::CodedInputStream input) { public override Builder MergeFrom(pb::CodedInputStream input) {
return MergeFrom(input, pb::ExtensionRegistry.Empty); return MergeFrom(input, pb::ExtensionRegistry.Empty);
} }
public override IBuilder<self::TestEmbedOptimizedForSize> MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) { public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.Builder unknownFields =
pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
while (true) { while (true) {
......
...@@ -150,12 +150,16 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -150,12 +150,16 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public static Builder CreateBuilder() { return new Builder(); } public static Builder CreateBuilder() { return new Builder(); }
public override IBuilder<self::ImportMessage> CreateBuilderForType() { return new Builder(); } public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(self::ImportMessage prototype) { public static Builder CreateBuilder(self::ImportMessage prototype) {
return (Builder) new Builder().MergeFrom(prototype); return (Builder) new Builder().MergeFrom(prototype);
} }
public sealed partial class Builder : pb::GeneratedBuilder<self::ImportMessage, Builder> { public sealed partial class Builder : pb::GeneratedBuilder<self::ImportMessage, Builder> {
protected override Builder ThisBuilder {
get { return this; }
}
// Construct using self::ImportMessage.CreateBuilder() // Construct using self::ImportMessage.CreateBuilder()
internal Builder() {} internal Builder() {}
...@@ -165,12 +169,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -165,12 +169,12 @@ namespace Google.ProtocolBuffers.TestProtos {
get { return result; } get { return result; }
} }
public override IBuilder<self::ImportMessage> Clear() { public override Builder Clear() {
result = new self::ImportMessage(); result = new self::ImportMessage();
return this; return this;
} }
public override IBuilder<self::ImportMessage> Clone() { public override Builder Clone() {
return new Builder().MergeFrom(result); return new Builder().MergeFrom(result);
} }
...@@ -188,11 +192,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -188,11 +192,7 @@ namespace Google.ProtocolBuffers.TestProtos {
return returnMe; return returnMe;
} }
protected override IBuilder MergeFromImpl(CodedInputStream data, ExtensionRegistry extensionRegistry) { public override Builder MergeFrom(pb::IMessage other) {
return MergeFrom(data, extensionRegistry);
}
public override IBuilder MergeFrom(pb::IMessage other) {
if (other is self::ImportMessage) { if (other is self::ImportMessage) {
return MergeFrom((self::ImportMessage) other); return MergeFrom((self::ImportMessage) other);
} else { } else {
...@@ -201,7 +201,7 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -201,7 +201,7 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
} }
public override IBuilder<self::ImportMessage> MergeFrom(self::ImportMessage other) { public override Builder MergeFrom(self::ImportMessage other) {
if (other == self::ImportMessage.DefaultInstance) return this; if (other == self::ImportMessage.DefaultInstance) return this;
if (other.HasD) { if (other.HasD) {
D = other.D; D = other.D;
...@@ -210,11 +210,11 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -210,11 +210,11 @@ namespace Google.ProtocolBuffers.TestProtos {
return this; return this;
} }
public override IBuilder<self::ImportMessage> MergeFrom(pb::CodedInputStream input) { public override Builder MergeFrom(pb::CodedInputStream input) {
return MergeFrom(input, pb::ExtensionRegistry.Empty); return MergeFrom(input, pb::ExtensionRegistry.Empty);
} }
public override IBuilder<self::ImportMessage> MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) { public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.Builder unknownFields =
pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
while (true) { while (true) {
......
...@@ -77,8 +77,8 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -77,8 +77,8 @@ namespace Google.ProtocolBuffers.TestProtos {
#region Nested types #region Nested types
public static class Types { public static class Types {
public static readonly pb::GeneratedExtensionBase<self::TestOptimizedForSize, int> TestExtension = public static readonly pb::GeneratedExtensionBase<int> TestExtension =
pb::GeneratedSingleExtension<self::TestOptimizedForSize, int>.CreateInstance(Descriptor.Extensions[0]); pb::GeneratedSingleExtension<int>.CreateInstance(Descriptor.Extensions[0]);
} }
#endregion #endregion
...@@ -137,12 +137,16 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -137,12 +137,16 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public static Builder CreateBuilder() { return new Builder(); } public static Builder CreateBuilder() { return new Builder(); }
public override IBuilder<self::TestOptimizedForSize> CreateBuilderForType() { return new Builder(); } public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(self::TestOptimizedForSize prototype) { public static Builder CreateBuilder(self::TestOptimizedForSize prototype) {
return (Builder) new Builder().MergeFrom(prototype); return (Builder) new Builder().MergeFrom(prototype);
} }
public sealed partial class Builder : pb::ExtendableBuilder<self::TestOptimizedForSize, self::TestOptimizedForSize.Builder> { public sealed partial class Builder : pb::ExtendableBuilder<self::TestOptimizedForSize, self::TestOptimizedForSize.Builder> {
protected override Builder ThisBuilder {
get { return this; }
}
// Construct using self::TestOptimizedForSize.CreateBuilder() // Construct using self::TestOptimizedForSize.CreateBuilder()
internal Builder() {} internal Builder() {}
...@@ -152,12 +156,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -152,12 +156,12 @@ namespace Google.ProtocolBuffers.TestProtos {
get { return result; } get { return result; }
} }
public override IBuilder<self::TestOptimizedForSize> Clear() { public override Builder Clear() {
result = new self::TestOptimizedForSize(); result = new self::TestOptimizedForSize();
return this; return this;
} }
public override IBuilder<self::TestOptimizedForSize> Clone() { public override Builder Clone() {
return new Builder().MergeFrom(result); return new Builder().MergeFrom(result);
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
...@@ -23,7 +23,9 @@ namespace Google.ProtocolBuffers { ...@@ -23,7 +23,9 @@ namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Implementation of the non-generic IMessage interface as far as possible. /// Implementation of the non-generic IMessage interface as far as possible.
/// </summary> /// </summary>
public abstract class AbstractMessage : IMessage { public abstract class AbstractMessage<TMessage, TBuilder> : IMessage<TMessage, TBuilder>
where TMessage : AbstractMessage<TMessage, TBuilder>
where TBuilder : AbstractBuilder<TMessage, TBuilder> {
// TODO(jonskeet): Cleaner to use a Nullable<int>? // TODO(jonskeet): Cleaner to use a Nullable<int>?
/// <summary> /// <summary>
/// The serialized size if it's already been computed, or -1 /// The serialized size if it's already been computed, or -1
...@@ -39,21 +41,17 @@ namespace Google.ProtocolBuffers { ...@@ -39,21 +41,17 @@ namespace Google.ProtocolBuffers {
public abstract int GetRepeatedFieldCount(FieldDescriptor field); public abstract int GetRepeatedFieldCount(FieldDescriptor field);
public abstract object this[FieldDescriptor field, int index] { get; } public abstract object this[FieldDescriptor field, int index] { get; }
public abstract UnknownFieldSet UnknownFields { get; } public abstract UnknownFieldSet UnknownFields { get; }
public abstract TMessage DefaultInstanceForType { get; }
public abstract TBuilder CreateBuilderForType();
#endregion #endregion
#region New abstract methods to be overridden by implementations, allow explicit interface implementation public IBuilder WeakCreateBuilderForType() {
protected abstract IMessage DefaultInstanceForTypeImpl { get; } return CreateBuilderForType();
protected abstract IBuilder CreateBuilderForTypeImpl();
#endregion
#region Methods simply proxying to the "Impl" methods, explicitly implementing IMessage
IMessage IMessage.DefaultInstanceForType {
get { return DefaultInstanceForTypeImpl; }
} }
IBuilder IMessage.CreateBuilderForType() {
return CreateBuilderForTypeImpl(); public IMessage WeakDefaultInstanceForType {
get { return DefaultInstanceForType; }
} }
#endregion
public virtual bool IsInitialized { public virtual bool IsInitialized {
get { get {
...@@ -71,7 +69,7 @@ namespace Google.ProtocolBuffers { ...@@ -71,7 +69,7 @@ namespace Google.ProtocolBuffers {
if (field.IsRepeated) { if (field.IsRepeated) {
// We know it's an IList<T>, but not the exact type - so // We know it's an IList<T>, but not the exact type - so
// IEnumerable is the best we can do. (C# generics aren't covariant yet.) // IEnumerable is the best we can do. (C# generics aren't covariant yet.)
foreach (IMessage element in (IEnumerable)entry.Value) { foreach (IMessage element in (IEnumerable) entry.Value) {
if (!element.IsInitialized) { if (!element.IsInitialized) {
return false; return false;
} }
...@@ -124,7 +122,7 @@ namespace Google.ProtocolBuffers { ...@@ -124,7 +122,7 @@ namespace Google.ProtocolBuffers {
foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields) { foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields) {
FieldDescriptor field = entry.Key; FieldDescriptor field = entry.Key;
if (field.IsRepeated) { if (field.IsRepeated) {
foreach (object element in (IEnumerable)entry.Value) { foreach (object element in (IEnumerable) entry.Value) {
size += CodedOutputStream.ComputeFieldSize(field.FieldType, field.FieldNumber, element); size += CodedOutputStream.ComputeFieldSize(field.FieldType, field.FieldNumber, element);
} }
} else { } else {
......
...@@ -224,7 +224,7 @@ namespace Google.ProtocolBuffers { ...@@ -224,7 +224,7 @@ namespace Google.ProtocolBuffers {
throw InvalidProtocolBufferException.RecursionLimitExceeded(); throw InvalidProtocolBufferException.RecursionLimitExceeded();
} }
++recursionDepth; ++recursionDepth;
builder.MergeFrom(this, extensionRegistry); builder.WeakMergeFrom(this, extensionRegistry);
CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup)); CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
--recursionDepth; --recursionDepth;
} }
...@@ -253,7 +253,7 @@ namespace Google.ProtocolBuffers { ...@@ -253,7 +253,7 @@ namespace Google.ProtocolBuffers {
} }
int oldLimit = PushLimit(length); int oldLimit = PushLimit(length);
++recursionDepth; ++recursionDepth;
builder.MergeFrom(this, extensionRegistry); builder.WeakMergeFrom(this, extensionRegistry);
CheckLastTagWas(0); CheckLastTagWas(0);
--recursionDepth; --recursionDepth;
PopLimit(oldLimit); PopLimit(oldLimit);
......
This diff is collapsed.
...@@ -13,57 +13,55 @@ namespace Google.ProtocolBuffers { ...@@ -13,57 +13,55 @@ namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Checks if a singular extension is present /// Checks if a singular extension is present
/// </summary> /// </summary>
public bool HasExtension<TExtension>(GeneratedExtensionBase<TMessage, TExtension> extension) { public bool HasExtension<TExtension>(GeneratedExtensionBase<TExtension> extension) {
return MessageBeingBuilt.HasExtension(extension); return MessageBeingBuilt.HasExtension(extension);
} }
/// <summary> /// <summary>
/// Returns the number of elements in a repeated extension. /// Returns the number of elements in a repeated extension.
/// </summary> /// </summary>
public int GetExtensionCount<TExtension>(GeneratedExtensionBase<TMessage, IList<TExtension>> extension) { public int GetExtensionCount<TExtension>(GeneratedExtensionBase<IList<TExtension>> extension) {
return MessageBeingBuilt.GetExtensionCount(extension); return MessageBeingBuilt.GetExtensionCount(extension);
} }
/// <summary> /// <summary>
/// Returns the value of an extension. /// Returns the value of an extension.
/// </summary> /// </summary>
public TExtension GetExtension<TExtension>(GeneratedExtensionBase<TMessage, TExtension> extension) { public TExtension GetExtension<TExtension>(GeneratedExtensionBase<TExtension> extension) {
return MessageBeingBuilt.GetExtension(extension); return MessageBeingBuilt.GetExtension(extension);
} }
/// <summary> /// <summary>
/// Returns one element of a repeated extension. /// Returns one element of a repeated extension.
/// </summary> /// </summary>
public TExtension GetExtension<TExtension>(GeneratedExtensionBase<TMessage, IList<TExtension>> extension, int index) { public TExtension GetExtension<TExtension>(GeneratedExtensionBase<IList<TExtension>> extension, int index) {
return MessageBeingBuilt.GetExtension(extension, index); return MessageBeingBuilt.GetExtension(extension, index);
} }
/// <summary> /// <summary>
/// Sets the value of an extension. /// Sets the value of an extension.
/// </summary> /// </summary>
public ExtendableBuilder<TMessage, TBuilder> SetExtension<TExtension>(GeneratedExtensionBase<TMessage, TExtension> extension, TExtension value) { public TBuilder SetExtension<TExtension>(GeneratedExtensionBase<TExtension> extension, TExtension value) {
ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt; ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt;
message.VerifyExtensionContainingType(extension); message.VerifyExtensionContainingType(extension);
message.Extensions[extension.Descriptor] = extension.ToReflectionType(value); message.Extensions[extension.Descriptor] = extension.ToReflectionType(value);
return this; return ThisBuilder;
} }
/// <summary> /// <summary>
/// Sets the value of one element of a repeated extension. /// Sets the value of one element of a repeated extension.
/// </summary> /// </summary>
public ExtendableBuilder<TMessage, TBuilder> SetExtension<TExtension>( public TBuilder SetExtension<TExtension>(GeneratedExtensionBase<IList<TExtension>> extension, int index, TExtension value) {
GeneratedExtensionBase<TMessage, IList<TExtension>> extension, int index, TExtension value) {
ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt; ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt;
message.VerifyExtensionContainingType(extension); message.VerifyExtensionContainingType(extension);
message.Extensions[extension.Descriptor, index] = extension.SingularToReflectionType(value); message.Extensions[extension.Descriptor, index] = extension.SingularToReflectionType(value);
return this; return ThisBuilder;
} }
/// <summary> /// <summary>
/// Appends a value to a repeated extension. /// Appends a value to a repeated extension.
/// </summary> /// </summary>
public ExtendableBuilder<TMessage, TBuilder> AddExtension<TExtension>( public ExtendableBuilder<TMessage, TBuilder> AddExtension<TExtension>(GeneratedExtensionBase<IList<TExtension>> extension, TExtension value) {
GeneratedExtensionBase<TMessage, IList<TExtension>> extension, TExtension value) {
ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt; ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt;
message.VerifyExtensionContainingType(extension); message.VerifyExtensionContainingType(extension);
message.Extensions.AddRepeatedField(extension.Descriptor, extension.SingularToReflectionType(value)); message.Extensions.AddRepeatedField(extension.Descriptor, extension.SingularToReflectionType(value));
...@@ -73,8 +71,7 @@ namespace Google.ProtocolBuffers { ...@@ -73,8 +71,7 @@ namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Clears an extension. /// Clears an extension.
/// </summary> /// </summary>
public ExtendableBuilder<TMessage, TBuilder> ClearExtension<TExtension>( public ExtendableBuilder<TMessage, TBuilder> ClearExtension<TExtension>(GeneratedExtensionBase<TExtension> extension) {
GeneratedExtensionBase<TMessage, TExtension> extension) {
ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt; ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt;
message.VerifyExtensionContainingType(extension); message.VerifyExtensionContainingType(extension);
message.Extensions.ClearField(extension.Descriptor); message.Extensions.ClearField(extension.Descriptor);
...@@ -121,23 +118,23 @@ namespace Google.ProtocolBuffers { ...@@ -121,23 +118,23 @@ namespace Google.ProtocolBuffers {
} }
} }
public override IBuilder<TMessage> ClearField(FieldDescriptor field) { public override TBuilder ClearField(FieldDescriptor field) {
if (field.IsExtension) { if (field.IsExtension) {
ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt; ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt;
message.VerifyContainingType(field); message.VerifyContainingType(field);
message.Extensions.ClearField(field); message.Extensions.ClearField(field);
return this; return ThisBuilder;
} else { } else {
return base.ClearField(field); return base.ClearField(field);
} }
} }
public override IBuilder<TMessage> AddRepeatedField(FieldDescriptor field, object value) { public override TBuilder AddRepeatedField(FieldDescriptor field, object value) {
if (field.IsExtension) { if (field.IsExtension) {
ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt; ExtendableMessage<TMessage, TBuilder> message = MessageBeingBuilt;
message.VerifyContainingType(field); message.VerifyContainingType(field);
message.Extensions.AddRepeatedField(field, value); message.Extensions.AddRepeatedField(field, value);
return this; return ThisBuilder;
} else { } else {
return base.AddRepeatedField(field, value); return base.AddRepeatedField(field, value);
} }
......
...@@ -5,9 +5,9 @@ using Google.ProtocolBuffers.Descriptors; ...@@ -5,9 +5,9 @@ using Google.ProtocolBuffers.Descriptors;
using Google.ProtocolBuffers.Collections; using Google.ProtocolBuffers.Collections;
namespace Google.ProtocolBuffers { namespace Google.ProtocolBuffers {
public abstract class ExtendableMessage<TMessage,TBuilder> : GeneratedMessage<TMessage,TBuilder> public abstract class ExtendableMessage<TMessage, TBuilder> : GeneratedMessage<TMessage, TBuilder>
where TMessage : GeneratedMessage<TMessage, TBuilder> where TMessage : GeneratedMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage> { where TBuilder : GeneratedBuilder<TMessage, TBuilder> {
protected ExtendableMessage() {} protected ExtendableMessage() {}
private readonly FieldSet extensions = FieldSet.CreateFieldSet(); private readonly FieldSet extensions = FieldSet.CreateFieldSet();
...@@ -22,21 +22,21 @@ namespace Google.ProtocolBuffers { ...@@ -22,21 +22,21 @@ namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Checks if a singular extension is present. /// Checks if a singular extension is present.
/// </summary> /// </summary>
public bool HasExtension<TExtension>(GeneratedExtensionBase<TMessage, TExtension> extension) { public bool HasExtension<TExtension>(GeneratedExtensionBase<TExtension> extension) {
return extensions.HasField(extension.Descriptor); return extensions.HasField(extension.Descriptor);
} }
/// <summary> /// <summary>
/// Returns the number of elements in a repeated extension. /// Returns the number of elements in a repeated extension.
/// </summary> /// </summary>
public int GetExtensionCount<TExtension>(GeneratedExtensionBase<TMessage, IList<TExtension>> extension) { public int GetExtensionCount<TExtension>(GeneratedExtensionBase<IList<TExtension>> extension) {
return extensions.GetRepeatedFieldCount(extension.Descriptor); return extensions.GetRepeatedFieldCount(extension.Descriptor);
} }
/// <summary> /// <summary>
/// Returns the value of an extension. /// Returns the value of an extension.
/// </summary> /// </summary>
public TExtension GetExtension<TExtension>(GeneratedExtensionBase<TMessage, TExtension> extension) { public TExtension GetExtension<TExtension>(GeneratedExtensionBase<TExtension> extension) {
object value = extensions[extension.Descriptor]; object value = extensions[extension.Descriptor];
if (value == null) { if (value == null) {
return (TExtension) extension.MessageDefaultInstance; return (TExtension) extension.MessageDefaultInstance;
...@@ -48,7 +48,7 @@ namespace Google.ProtocolBuffers { ...@@ -48,7 +48,7 @@ namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Returns one element of a repeated extension. /// Returns one element of a repeated extension.
/// </summary> /// </summary>
public TExtension GetExtension<TExtension>(GeneratedExtensionBase<TMessage, IList<TExtension>> extension, int index) { public TExtension GetExtension<TExtension>(GeneratedExtensionBase<IList<TExtension>> extension, int index) {
return (TExtension) extension.SingularFromReflectionType(extensions[extension.Descriptor, index]); return (TExtension) extension.SingularFromReflectionType(extensions[extension.Descriptor, index]);
} }
...@@ -169,7 +169,7 @@ namespace Google.ProtocolBuffers { ...@@ -169,7 +169,7 @@ namespace Google.ProtocolBuffers {
get { return extensions.SerializedSize; } get { return extensions.SerializedSize; }
} }
internal void VerifyExtensionContainingType<TExtension>(GeneratedExtensionBase<TMessage, TExtension> extension) { internal void VerifyExtensionContainingType<TExtension>(GeneratedExtensionBase<TExtension> extension) {
if (extension.Descriptor.ContainingType != DescriptorForType) { if (extension.Descriptor.ContainingType != DescriptorForType) {
// This can only happen if someone uses unchecked operations. // This can only happen if someone uses unchecked operations.
throw new ArgumentException("Extension is for type \"" + extension.Descriptor.ContainingType.FullName throw new ArgumentException("Extension is for type \"" + extension.Descriptor.ContainingType.FullName
......
...@@ -88,8 +88,7 @@ namespace Google.ProtocolBuffers { ...@@ -88,8 +88,7 @@ namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Add an extension from a generated file to the registry. /// Add an extension from a generated file to the registry.
/// </summary> /// </summary>
public void Add<TContainer, TExtension> (GeneratedExtensionBase<TContainer, TExtension> extension) public void Add<TExtension> (GeneratedExtensionBase<TExtension> extension) {
where TContainer : IMessage<TContainer> {
if (extension.Descriptor.MappedType == MappedType.Message) { if (extension.Descriptor.MappedType == MappedType.Message) {
Add(new ExtensionInfo(extension.Descriptor, extension.MessageDefaultInstance)); Add(new ExtensionInfo(extension.Descriptor, extension.MessageDefaultInstance));
} else { } else {
......
...@@ -40,7 +40,7 @@ namespace Google.ProtocolBuffers.FieldAccess { ...@@ -40,7 +40,7 @@ namespace Google.ProtocolBuffers.FieldAccess {
// No... so let's create a builder of the right type, and merge the value in. // No... so let's create a builder of the right type, and merge the value in.
IMessage message = (IMessage) value; IMessage message = (IMessage) value;
return CreateBuilder().MergeFrom(message).Build(); return CreateBuilder().WeakMergeFrom(message).WeakBuild();
} }
public override void SetRepeated(IBuilder builder, int index, object value) { public override void SetRepeated(IBuilder builder, int index, object value) {
......
...@@ -38,7 +38,7 @@ namespace Google.ProtocolBuffers.FieldAccess { ...@@ -38,7 +38,7 @@ namespace Google.ProtocolBuffers.FieldAccess {
// No... so let's create a builder of the right type, and merge the value in. // No... so let's create a builder of the right type, and merge the value in.
IMessage message = (IMessage) value; IMessage message = (IMessage) value;
return CreateBuilder().MergeFrom(message).Build(); return CreateBuilder().WeakMergeFrom(message).WeakBuild();
} }
public override void SetValue(IBuilder builder, object value) { public override void SetValue(IBuilder builder, object value) {
......
...@@ -154,19 +154,19 @@ namespace Google.ProtocolBuffers { ...@@ -154,19 +154,19 @@ namespace Google.ProtocolBuffers {
case FieldType.Message: { case FieldType.Message: {
IBuilder subBuilder; IBuilder subBuilder;
if (defaultFieldInstance != null) { if (defaultFieldInstance != null) {
subBuilder = defaultFieldInstance.CreateBuilderForType(); subBuilder = defaultFieldInstance.WeakCreateBuilderForType();
} else { } else {
subBuilder = builder.CreateBuilderForField(field); subBuilder = builder.CreateBuilderForField(field);
} }
if (!field.IsRepeated) { if (!field.IsRepeated) {
subBuilder.MergeFrom((IMessage) builder[field]); subBuilder.WeakMergeFrom((IMessage) builder[field]);
} }
if (field.FieldType == FieldType.Group) { if (field.FieldType == FieldType.Group) {
input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry); input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);
} else { } else {
input.ReadMessage(subBuilder, extensionRegistry); input.ReadMessage(subBuilder, extensionRegistry);
} }
value = subBuilder.Build(); value = subBuilder.WeakBuild();
break; break;
} }
case FieldType.Enum: { case FieldType.Enum: {
...@@ -185,7 +185,7 @@ namespace Google.ProtocolBuffers { ...@@ -185,7 +185,7 @@ namespace Google.ProtocolBuffers {
break; break;
} }
if (field.IsRepeated) { if (field.IsRepeated) {
builder.AddRepeatedField(field, value); builder.WeakAddRepeatedField(field, value);
} else { } else {
builder[field] = value; builder[field] = value;
} }
...@@ -236,16 +236,16 @@ namespace Google.ProtocolBuffers { ...@@ -236,16 +236,16 @@ namespace Google.ProtocolBuffers {
ExtensionInfo extension = extensionRegistry[type, typeId]; ExtensionInfo extension = extensionRegistry[type, typeId];
if (extension != null) { if (extension != null) {
field = extension.Descriptor; field = extension.Descriptor;
subBuilder = extension.DefaultInstance.CreateBuilderForType(); subBuilder = extension.DefaultInstance.WeakCreateBuilderForType();
IMessage originalMessage = (IMessage) builder[field]; IMessage originalMessage = (IMessage) builder[field];
if (originalMessage != null) { if (originalMessage != null) {
subBuilder.MergeFrom(originalMessage); subBuilder.WeakMergeFrom(originalMessage);
} }
if (rawBytes != null) { if (rawBytes != null) {
// We already encountered the message. Parse it now. // We already encountered the message. Parse it now.
// TODO(jonskeet): Check this is okay. It's subtly different from the Java, as it doesn't create an input stream from rawBytes. // TODO(jonskeet): Check this is okay. It's subtly different from the Java, as it doesn't create an input stream from rawBytes.
// In fact, why don't we just call MergeFrom(rawBytes)? And what about the extension registry? // In fact, why don't we just call MergeFrom(rawBytes)? And what about the extension registry?
subBuilder.MergeFrom(rawBytes.CreateCodedInput()); subBuilder.WeakMergeFrom(rawBytes.CreateCodedInput());
rawBytes = null; rawBytes = null;
} }
} else { } else {
...@@ -286,7 +286,7 @@ namespace Google.ProtocolBuffers { ...@@ -286,7 +286,7 @@ namespace Google.ProtocolBuffers {
input.CheckLastTagWas(WireFormat.MessageSetTag.ItemEnd); input.CheckLastTagWas(WireFormat.MessageSetTag.ItemEnd);
if (subBuilder != null) { if (subBuilder != null) {
builder[field] = subBuilder.Build(); builder[field] = subBuilder.WeakBuild();
} }
} }
...@@ -381,7 +381,7 @@ namespace Google.ProtocolBuffers { ...@@ -381,7 +381,7 @@ namespace Google.ProtocolBuffers {
} }
/// <summary> /// <summary>
/// See <see cref="IBuilder.AddRepeatedField" /> /// See <see cref="IBuilder{TMessage, TBuilder}.AddRepeatedField" />
/// </summary> /// </summary>
internal void AddRepeatedField(FieldDescriptor field, object value) { internal void AddRepeatedField(FieldDescriptor field, object value) {
if (!field.IsRepeated) { if (!field.IsRepeated) {
...@@ -449,7 +449,7 @@ namespace Google.ProtocolBuffers { ...@@ -449,7 +449,7 @@ namespace Google.ProtocolBuffers {
} }
/// <summary> /// <summary>
/// See <see cref="IBuilder.ClearField" /> /// See <see cref="IBuilder{TMessage, TBuilder}.ClearField" />
/// </summary> /// </summary>
public void ClearField(FieldDescriptor field) { public void ClearField(FieldDescriptor field) {
fields.Remove(field); fields.Remove(field);
...@@ -495,10 +495,10 @@ namespace Google.ProtocolBuffers { ...@@ -495,10 +495,10 @@ namespace Google.ProtocolBuffers {
} }
} else if (field.MappedType == MappedType.Message && existingValue != null) { } else if (field.MappedType == MappedType.Message && existingValue != null) {
IMessage existingMessage = (IMessage)existingValue; IMessage existingMessage = (IMessage)existingValue;
IMessage merged = existingMessage.CreateBuilderForType() IMessage merged = existingMessage.WeakCreateBuilderForType()
.MergeFrom(existingMessage) .WeakMergeFrom(existingMessage)
.MergeFrom((IMessage)entry.Value) .WeakMergeFrom((IMessage) entry.Value)
.Build(); .WeakBuild();
this[field] = merged; this[field] = merged;
} else { } else {
this[field] = entry.Value; this[field] = entry.Value;
......
...@@ -13,9 +13,9 @@ namespace Google.ProtocolBuffers { ...@@ -13,9 +13,9 @@ namespace Google.ProtocolBuffers {
/// most of the IBuilder interface using reflection. Users can ignore this class /// most of the IBuilder interface using reflection. Users can ignore this class
/// as an implementation detail. /// as an implementation detail.
/// </summary> /// </summary>
public abstract class GeneratedBuilder<TMessage, TBuilder> : AbstractBuilder, IBuilder<TMessage> public abstract class GeneratedBuilder<TMessage, TBuilder> : AbstractBuilder<TMessage, TBuilder>
where TMessage : GeneratedMessage <TMessage, TBuilder> where TMessage : GeneratedMessage <TMessage, TBuilder>
where TBuilder : GeneratedBuilder<TMessage, TBuilder>, IBuilder<TMessage> { where TBuilder : GeneratedBuilder<TMessage, TBuilder> {
/// <summary> /// <summary>
/// Returns the message being built at the moment. /// Returns the message being built at the moment.
...@@ -43,7 +43,7 @@ namespace Google.ProtocolBuffers { ...@@ -43,7 +43,7 @@ namespace Google.ProtocolBuffers {
: MessageBeingBuilt[field]; : MessageBeingBuilt[field];
} }
set { set {
InternalFieldAccessors[field].SetValue(this, value); InternalFieldAccessors[field].SetValue(ThisBuilder, value);
} }
} }
...@@ -87,40 +87,16 @@ namespace Google.ProtocolBuffers { ...@@ -87,40 +87,16 @@ namespace Google.ProtocolBuffers {
return MessageBeingBuilt.HasField(field); return MessageBeingBuilt.HasField(field);
} }
protected override IMessage BuildImpl() {
return Build();
}
protected override IMessage BuildPartialImpl() {
return BuildPartial();
}
protected override IBuilder CloneImpl() {
return Clone();
}
protected override IMessage DefaultInstanceForTypeImpl {
get { return DefaultInstanceForType; }
}
public override IBuilder CreateBuilderForField(FieldDescriptor field) { public override IBuilder CreateBuilderForField(FieldDescriptor field) {
return InternalFieldAccessors[field].CreateBuilder(); return InternalFieldAccessors[field].CreateBuilder();
} }
protected override IBuilder ClearFieldImpl(FieldDescriptor field) { public override TBuilder ClearField(FieldDescriptor field) {
return ClearField(field);
}
protected override IBuilder AddRepeatedFieldImpl(FieldDescriptor field, object value) {
return AddRepeatedField(field, value);
}
public virtual IBuilder<TMessage> ClearField(FieldDescriptor field) {
InternalFieldAccessors[field].Clear(this); InternalFieldAccessors[field].Clear(this);
return this; return ThisBuilder;
} }
public virtual IBuilder<TMessage> MergeFrom(TMessage other) { public override TBuilder MergeFrom(TMessage other) {
if (other.DescriptorForType != InternalFieldAccessors.Descriptor) { if (other.DescriptorForType != InternalFieldAccessors.Descriptor) {
throw new ArgumentException("Message type mismatch"); throw new ArgumentException("Message type mismatch");
} }
...@@ -135,77 +111,31 @@ namespace Google.ProtocolBuffers { ...@@ -135,77 +111,31 @@ namespace Google.ProtocolBuffers {
} else if (field.MappedType == MappedType.Message && HasField(field)) { } else if (field.MappedType == MappedType.Message && HasField(field)) {
// Merge singular embedded messages // Merge singular embedded messages
IMessage oldValue = (IMessage)this[field]; IMessage oldValue = (IMessage)this[field];
this[field] = oldValue.CreateBuilderForType() this[field] = oldValue.WeakCreateBuilderForType()
.MergeFrom(oldValue) .WeakMergeFrom(oldValue)
.MergeFrom((IMessage)entry.Value) .WeakMergeFrom((IMessage)entry.Value)
.BuildPartial(); .WeakBuildPartial();
} else { } else {
// Just overwrite // Just overwrite
this[field] = entry.Value; this[field] = entry.Value;
} }
} }
return this; return ThisBuilder;
} }
public virtual IBuilder<TMessage> MergeUnknownFields(UnknownFieldSet unknownFields) { public override TBuilder MergeUnknownFields(UnknownFieldSet unknownFields) {
TMessage result = MessageBeingBuilt; TMessage result = MessageBeingBuilt;
result.SetUnknownFields(UnknownFieldSet.CreateBuilder(result.UnknownFields) result.SetUnknownFields(UnknownFieldSet.CreateBuilder(result.UnknownFields)
.MergeFrom(unknownFields) .MergeFrom(unknownFields)
.Build()); .Build());
return this; return ThisBuilder;
} }
public virtual IBuilder<TMessage> AddRepeatedField(FieldDescriptor field, object value) { public override TBuilder AddRepeatedField(FieldDescriptor field, object value) {
InternalFieldAccessors[field].AddRepeated(this, value); InternalFieldAccessors[field].AddRepeated(this, value);
return this; return ThisBuilder;
}
public IBuilder<TMessage> MergeFrom(ByteString data) {
((IBuilder) this).MergeFrom(data);
return this;
}
public IBuilder<TMessage> MergeFrom(ByteString data, ExtensionRegistry extensionRegistry) {
((IBuilder) this).MergeFrom(data, extensionRegistry);
return this;
}
public IBuilder<TMessage> MergeFrom(byte[] data) {
((IBuilder) this).MergeFrom(data);
return this;
}
public IBuilder<TMessage> MergeFrom(byte[] data, ExtensionRegistry extensionRegistry) {
((IBuilder) this).MergeFrom(data, extensionRegistry);
return this;
}
public IBuilder<TMessage> MergeFrom(Stream input) {
((IBuilder) this).MergeFrom(input);
return this;
}
public IBuilder<TMessage> MergeFrom(Stream input, ExtensionRegistry extensionRegistry) {
((IBuilder) this).MergeFrom(input, extensionRegistry);
return this;
} }
/// <summary>
/// Overridden when optimized for speed.
/// </summary>
public virtual IBuilder<TMessage> MergeFrom(CodedInputStream input) {
((IBuilder)this).MergeFrom(input);
return this;
}
/// <summary>
/// Overridden when optimized for speed.
/// </summary>
public virtual IBuilder<TMessage> MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
((IBuilder)this).MergeFrom(input, extensionRegistry);
return this;
}
/// <summary> /// <summary>
/// Like Build(), but will wrap UninitializedMessageException in /// Like Build(), but will wrap UninitializedMessageException in
/// InvalidProtocolBufferException. /// InvalidProtocolBufferException.
...@@ -219,10 +149,10 @@ namespace Google.ProtocolBuffers { ...@@ -219,10 +149,10 @@ namespace Google.ProtocolBuffers {
} }
/// <summary> /// <summary>
/// Implementation of <see cref="IBuilder{T}.Build" />. /// Implementation of <see cref="IBuilder{TMessage, TBuilder}.Build" />.
/// TODO(jonskeet): This used to be generated for each class. Find out why. /// TODO(jonskeet): This used to be generated for each class. Find out why.
/// </summary> /// </summary>
public TMessage Build() { public override TMessage Build() {
if (!IsInitialized) { if (!IsInitialized) {
throw new UninitializedMessageException(MessageBeingBuilt); throw new UninitializedMessageException(MessageBeingBuilt);
} }
...@@ -233,13 +163,5 @@ namespace Google.ProtocolBuffers { ...@@ -233,13 +163,5 @@ namespace Google.ProtocolBuffers {
get { return MessageBeingBuilt.UnknownFields; } get { return MessageBeingBuilt.UnknownFields; }
set { MessageBeingBuilt.SetUnknownFields(value); } set { MessageBeingBuilt.SetUnknownFields(value); }
} }
public abstract TMessage BuildPartial();
public abstract IBuilder<TMessage> Clone();
public abstract new IBuilder<TMessage> Clear();
public abstract TMessage DefaultInstanceForType { get; }
public abstract class ExtendableBuilder : GeneratedBuilder<TMessage, TBuilder> {
}
} }
} }
...@@ -29,7 +29,7 @@ namespace Google.ProtocolBuffers { ...@@ -29,7 +29,7 @@ namespace Google.ProtocolBuffers {
/// The interface implemented by both GeneratedException and GeneratedRepeatException, /// The interface implemented by both GeneratedException and GeneratedRepeatException,
/// to make it easier to cope with repeats separately. /// to make it easier to cope with repeats separately.
/// </remarks> /// </remarks>
public abstract class GeneratedExtensionBase<TContainer, TExtension> { public abstract class GeneratedExtensionBase<TExtension> {
private readonly FieldDescriptor descriptor; private readonly FieldDescriptor descriptor;
private readonly IMessage messageDefaultInstance; private readonly IMessage messageDefaultInstance;
...@@ -73,8 +73,8 @@ namespace Google.ProtocolBuffers { ...@@ -73,8 +73,8 @@ namespace Google.ProtocolBuffers {
// GeneratedExtension manually and gives it a different type. // GeneratedExtension manually and gives it a different type.
// This should not happen in normal use. But, to be nice, we'll // This should not happen in normal use. But, to be nice, we'll
// copy the message to whatever type the caller was expecting. // copy the message to whatever type the caller was expecting.
return MessageDefaultInstance.CreateBuilderForType() return MessageDefaultInstance.WeakCreateBuilderForType()
.MergeFrom((IMessage)value).Build(); .WeakMergeFrom((IMessage)value).WeakBuild();
} }
case MappedType.Enum: case MappedType.Enum:
// Just return a boxed int - that can be unboxed to the enum // Just return a boxed int - that can be unboxed to the enum
......
...@@ -13,9 +13,9 @@ namespace Google.ProtocolBuffers { ...@@ -13,9 +13,9 @@ namespace Google.ProtocolBuffers {
/// most of the IMessage interface using reflection. Users /// most of the IMessage interface using reflection. Users
/// can ignore this class as an implementation detail. /// can ignore this class as an implementation detail.
/// </summary> /// </summary>
public abstract class GeneratedMessage<TMessage, TBuilder> : AbstractMessage, IMessage<TMessage> public abstract class GeneratedMessage<TMessage, TBuilder> : AbstractMessage<TMessage, TBuilder>
where TMessage : GeneratedMessage<TMessage, TBuilder> where TMessage : GeneratedMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage> { where TBuilder : GeneratedBuilder<TMessage, TBuilder> {
private UnknownFieldSet unknownFields = UnknownFieldSet.DefaultInstance; private UnknownFieldSet unknownFields = UnknownFieldSet.DefaultInstance;
...@@ -29,18 +29,6 @@ namespace Google.ProtocolBuffers { ...@@ -29,18 +29,6 @@ namespace Google.ProtocolBuffers {
get { return InternalFieldAccessors.Descriptor; } get { return InternalFieldAccessors.Descriptor; }
} }
protected override IMessage DefaultInstanceForTypeImpl {
get { return DefaultInstanceForType; }
}
protected override IBuilder CreateBuilderForTypeImpl() {
return CreateBuilderForType();
}
public abstract TMessage DefaultInstanceForType { get; }
public abstract IBuilder<TMessage> CreateBuilderForType();
internal IDictionary<FieldDescriptor, Object> GetMutableFieldMap() { internal IDictionary<FieldDescriptor, Object> GetMutableFieldMap() {
// Use a SortedList so we'll end up serializing fields in order // Use a SortedList so we'll end up serializing fields in order
......
...@@ -7,15 +7,15 @@ namespace Google.ProtocolBuffers { ...@@ -7,15 +7,15 @@ namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Class used to represent repeat extensions in generated classes. /// Class used to represent repeat extensions in generated classes.
/// </summary> /// </summary>
public class GeneratedRepeatExtension<TContainer, TExtensionElement> : GeneratedExtensionBase<TContainer, IList<TExtensionElement>> { public class GeneratedRepeatExtension<TExtensionElement> : GeneratedExtensionBase<IList<TExtensionElement>> {
private GeneratedRepeatExtension(FieldDescriptor field) : base(field, typeof(TExtensionElement)) { private GeneratedRepeatExtension(FieldDescriptor field) : base(field, typeof(TExtensionElement)) {
} }
public static GeneratedExtensionBase<TContainer, IList<TExtensionElement>> CreateInstance(FieldDescriptor descriptor) { public static GeneratedExtensionBase<IList<TExtensionElement>> CreateInstance(FieldDescriptor descriptor) {
if (!descriptor.IsRepeated) { if (!descriptor.IsRepeated) {
throw new ArgumentException("Must call GeneratedRepeatExtension.CreateInstance() for repeated types."); throw new ArgumentException("Must call GeneratedRepeatExtension.CreateInstance() for repeated types.");
} }
return new GeneratedRepeatExtension<TContainer, TExtensionElement>(descriptor); return new GeneratedRepeatExtension<TExtensionElement>(descriptor);
} }
/// <summary> /// <summary>
......
...@@ -6,17 +6,15 @@ namespace Google.ProtocolBuffers { ...@@ -6,17 +6,15 @@ namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Generated extension for a singular field. /// Generated extension for a singular field.
/// </remarks> /// </remarks>
public class GeneratedSingleExtension<TContainer, TExtension> : GeneratedExtensionBase<TContainer, TExtension> public class GeneratedSingleExtension<TExtension> : GeneratedExtensionBase<TExtension> {
where TContainer : IMessage<TContainer> {
internal GeneratedSingleExtension(FieldDescriptor descriptor) : base(descriptor, typeof(TExtension)) { internal GeneratedSingleExtension(FieldDescriptor descriptor) : base(descriptor, typeof(TExtension)) {
} }
public static GeneratedSingleExtension<TContainer, TExtension> CreateInstance(FieldDescriptor descriptor) { public static GeneratedSingleExtension<TExtension> CreateInstance(FieldDescriptor descriptor) {
if (descriptor.IsRepeated) { if (descriptor.IsRepeated) {
throw new ArgumentException("Must call GeneratedRepeateExtension.CreateInstance() for repeated types."); throw new ArgumentException("Must call GeneratedRepeateExtension.CreateInstance() for repeated types.");
} }
return new GeneratedSingleExtension<TContainer, TExtension>(descriptor); return new GeneratedSingleExtension<TExtension>(descriptor);
} }
public override object FromReflectionType(object value) { public override object FromReflectionType(object value) {
......
This diff is collapsed.
...@@ -21,11 +21,8 @@ using Google.ProtocolBuffers.Descriptors; ...@@ -21,11 +21,8 @@ using Google.ProtocolBuffers.Descriptors;
namespace Google.ProtocolBuffers { namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Non-generic interface implemented by all Protocol Buffers messages. /// Non-generic interface used for all parts of the API which don't require
/// Some members are repeated in the generic interface but with a /// any type knowledge.
/// type-specific signature. Type-safe implementations
/// are encouraged to implement these non-generic members explicitly,
/// and the generic members implicitly.
/// </summary> /// </summary>
public interface IMessage { public interface IMessage {
/// <summary> /// <summary>
...@@ -152,27 +149,17 @@ namespace Google.ProtocolBuffers { ...@@ -152,27 +149,17 @@ namespace Google.ProtocolBuffers {
void WriteTo(Stream output); void WriteTo(Stream output);
#endregion #endregion
#region Weakly typed members
/// <summary> /// <summary>
/// Returns an instance of this message type with all fields set to /// Creates a builder for the type, but in a weakly typed manner. This
/// their default values. This may or may not be a singleton. This differs /// is typically implemented by strongly typed builders by just returning
/// from the DefaultInstance property of each generated message class in that this /// the result of CreateBuilderForType.
/// method is an abstract method of IMessage whereas DefaultInstance is
/// a static property of a specific class. They return the same thing.
/// </summary> /// </summary>
IMessage DefaultInstanceForType { get; } IBuilder WeakCreateBuilderForType();
/// <summary> IMessage WeakDefaultInstanceForType { get; }
/// Constructs a new builder for a message of the same type as this message.
/// </summary>
IBuilder CreateBuilderForType();
#endregion
} }
/// <summary> public interface IMessage<TMessage> : IMessage {
/// Type-safe interface for all generated messages to implement.
/// </summary>
public interface IMessage<T> : IMessage where T : IMessage<T> {
/// <summary> /// <summary>
/// Returns an instance of this message type with all fields set to /// Returns an instance of this message type with all fields set to
/// their default values. This may or may not be a singleton. This differs /// their default values. This may or may not be a singleton. This differs
...@@ -180,13 +167,20 @@ namespace Google.ProtocolBuffers { ...@@ -180,13 +167,20 @@ namespace Google.ProtocolBuffers {
/// method is an abstract method of IMessage whereas DefaultInstance is /// method is an abstract method of IMessage whereas DefaultInstance is
/// a static property of a specific class. They return the same thing. /// a static property of a specific class. They return the same thing.
/// </summary> /// </summary>
new T DefaultInstanceForType { get; } TMessage DefaultInstanceForType { get; }
}
/// <summary>
/// Type-safe interface for all generated messages to implement.
/// </summary>
public interface IMessage<TMessage, TBuilder> : IMessage<TMessage>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder> {
#region Builders #region Builders
/// <summary> /// <summary>
/// Constructs a new builder for a message of the same type as this message. /// Constructs a new builder for a message of the same type as this message.
/// </summary> /// </summary>
new IBuilder<T> CreateBuilderForType(); TBuilder CreateBuilderForType();
#endregion #endregion
} }
} }
...@@ -67,13 +67,13 @@ namespace Google.ProtocolBuffers { ...@@ -67,13 +67,13 @@ namespace Google.ProtocolBuffers {
internal static InvalidProtocolBufferException RecursionLimitExceeded() { internal static InvalidProtocolBufferException RecursionLimitExceeded() {
return new InvalidProtocolBufferException( return new InvalidProtocolBufferException(
"Protocol message had too many levels of nesting. May be malicious. " + "Protocol message had too many levels of nesting. May be malicious. " +
"Use CodedInputStream.setRecursionLimit() to increase the depth limit."); "Use CodedInputStream.SetRecursionLimit() to increase the depth limit.");
} }
internal static InvalidProtocolBufferException SizeLimitExceeded() { internal static InvalidProtocolBufferException SizeLimitExceeded() {
return new InvalidProtocolBufferException( return new InvalidProtocolBufferException(
"Protocol message was too large. May be malicious. " + "Protocol message was too large. May be malicious. " +
"Use CodedInputStream.setSizeLimit() to increase the size limit."); "Use CodedInputStream.SetSizeLimit() to increase the size limit.");
} }
} }
} }
...@@ -21,12 +21,13 @@ namespace Google.ProtocolBuffers { ...@@ -21,12 +21,13 @@ namespace Google.ProtocolBuffers {
/// callback is given a message with a different descriptor, an /// callback is given a message with a different descriptor, an
/// exception will be thrown. /// exception will be thrown.
/// </summary> /// </summary>
public static Action<IMessage> GeneralizeCallback<T>(Action<T> action, T defaultInstance) public static Action<IMessage> GeneralizeCallback<TMessage, TBuilder>(Action<TMessage> action, TMessage defaultInstance)
where T : class, IMessage<T> { where TMessage : class, IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder> {
return message => { return message => {
T castMessage = message as T; TMessage castMessage = message as TMessage;
if (castMessage == null) { if (castMessage == null) {
castMessage = (T) defaultInstance.CreateBuilderForType().MergeFrom(message).Build(); castMessage = defaultInstance.CreateBuilderForType().MergeFrom(message).Build();
} }
action(castMessage); action(castMessage);
}; };
......
...@@ -44,6 +44,7 @@ namespace Google.ProtocolBuffers { ...@@ -44,6 +44,7 @@ namespace Google.ProtocolBuffers {
} }
private static void Print(IMessage message, TextGenerator generator) { private static void Print(IMessage message, TextGenerator generator) {
// TODO(jonskeet): Check why descriptor is never used.
MessageDescriptor descriptor = message.DescriptorForType; MessageDescriptor descriptor = message.DescriptorForType;
foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields) { foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields) {
PrintField(entry.Key, entry.Value, generator); PrintField(entry.Key, entry.Value, generator);
......
...@@ -57,12 +57,12 @@ void ExtensionGenerator::Generate(io::Printer* printer) { ...@@ -57,12 +57,12 @@ void ExtensionGenerator::Generate(io::Printer* printer) {
if (descriptor_->is_repeated()) { if (descriptor_->is_repeated()) {
printer->Print(vars, printer->Print(vars,
"public static readonly\r\n" "public static readonly\r\n"
" pb::GeneratedExtensionBase<$containing_type$, scg::IList<$type$>> $name$ =\r\n" " pb::GeneratedExtensionBase<scg::IList<$type$>> $name$ =\r\n"
" pb::GeneratedRepeatExtension<$containing_type$, $type$>.CreateInstance(Descriptor.Extensions[$index$]);\r\n"); " pb::GeneratedRepeatExtension<$type$>.CreateInstance(Descriptor.Extensions[$index$]);\r\n");
} else { } else {
printer->Print(vars, printer->Print(vars,
"public static readonly pb::GeneratedExtensionBase<$containing_type$, $type$> $name$ =\r\n" "public static readonly pb::GeneratedExtensionBase<$type$> $name$ =\r\n"
" pb::GeneratedSingleExtension<$containing_type$, $type$>.CreateInstance(Descriptor.Extensions[$index$]);\r\n"); " pb::GeneratedSingleExtension<$type$>.CreateInstance(Descriptor.Extensions[$index$]);\r\n");
} }
} }
......
...@@ -423,7 +423,7 @@ void MessageGenerator::GenerateSerializeOneExtensionRange( ...@@ -423,7 +423,7 @@ void MessageGenerator::GenerateSerializeOneExtensionRange(
void MessageGenerator::GenerateBuilder(io::Printer* printer) { void MessageGenerator::GenerateBuilder(io::Printer* printer) {
printer->Print( printer->Print(
"public static Builder CreateBuilder() { return new Builder(); }\r\n" "public static Builder CreateBuilder() { return new Builder(); }\r\n"
"public override IBuilder<$classname$> CreateBuilderForType() { return new Builder(); }\r\n" "public override Builder CreateBuilderForType() { return new Builder(); }\r\n"
"public static Builder CreateBuilder($classname$ prototype) {\r\n" "public static Builder CreateBuilder($classname$ prototype) {\r\n"
" return (Builder) new Builder().MergeFrom(prototype);\r\n" " return (Builder) new Builder().MergeFrom(prototype);\r\n"
"}\r\n" "}\r\n"
...@@ -441,8 +441,14 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) { ...@@ -441,8 +441,14 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) {
"classname", ClassName(descriptor_), "classname", ClassName(descriptor_),
"access", ClassAccessLevel(descriptor_->file())); "access", ClassAccessLevel(descriptor_->file()));
} }
printer->Indent(); printer->Indent();
printer->Print(
"protected override Builder ThisBuilder {\r\n"
" get { return this; }\r\n"
"}\r\n\r\n");
GenerateCommonBuilderMethods(printer); GenerateCommonBuilderMethods(printer);
if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) { if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
...@@ -475,12 +481,12 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { ...@@ -475,12 +481,12 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
" get { return result; }\r\n" " get { return result; }\r\n"
"}\r\n" "}\r\n"
"\r\n" "\r\n"
"public override IBuilder<$classname$> Clear() {\r\n" "public override Builder Clear() {\r\n"
" result = new $classname$();\r\n" " result = new $classname$();\r\n"
" return this;\r\n" " return this;\r\n"
"}\r\n" "}\r\n"
"\r\n" "\r\n"
"public override IBuilder<$classname$> Clone() {\r\n" "public override Builder Clone() {\r\n"
" return new Builder().MergeFrom(result);\r\n" " return new Builder().MergeFrom(result);\r\n"
"}\r\n" "}\r\n"
"\r\n" "\r\n"
...@@ -516,14 +522,14 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { ...@@ -516,14 +522,14 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
// ----------------------------------------------------------------- // -----------------------------------------------------------------
//TODO(jonskeet): Work out what this is really for...
if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) { if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
printer->Print( printer->Print(
"protected override IBuilder MergeFromImpl(CodedInputStream data, ExtensionRegistry extensionRegistry) {\r\n" /*
"protected override Builder MergeFrom(CodedInputStream data, ExtensionRegistry extensionRegistry) {\r\n"
" return MergeFrom(data, extensionRegistry);\r\n" " return MergeFrom(data, extensionRegistry);\r\n"
"}\r\n" "}\r\n"
"\r\n" "\r\n"*/
"public override IBuilder MergeFrom(pb::IMessage other) {\r\n" "public override Builder MergeFrom(pb::IMessage other) {\r\n"
" if (other is $classname$) {\r\n" " if (other is $classname$) {\r\n"
" return MergeFrom(($classname$) other);\r\n" " return MergeFrom(($classname$) other);\r\n"
" } else {\r\n" " } else {\r\n"
...@@ -532,7 +538,7 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { ...@@ -532,7 +538,7 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
" }\r\n" " }\r\n"
"}\r\n" "}\r\n"
"\r\n" "\r\n"
"public override IBuilder<$classname$> MergeFrom($classname$ other) {\r\n" "public override Builder MergeFrom($classname$ other) {\r\n"
// Optimization: If other is the default instance, we know none of its // Optimization: If other is the default instance, we know none of its
// fields are set so we can skip the merge. // fields are set so we can skip the merge.
" if (other == $classname$.DefaultInstance) return this;\r\n", " if (other == $classname$.DefaultInstance) return this;\r\n",
...@@ -559,11 +565,11 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { ...@@ -559,11 +565,11 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
SortFieldsByNumber(descriptor_)); SortFieldsByNumber(descriptor_));
printer->Print( printer->Print(
"public override IBuilder<$classname$> MergeFrom(pb::CodedInputStream input) {\r\n" "public override Builder MergeFrom(pb::CodedInputStream input) {\r\n"
" return MergeFrom(input, pb::ExtensionRegistry.Empty);\r\n" " return MergeFrom(input, pb::ExtensionRegistry.Empty);\r\n"
"}\r\n" "}\r\n"
"\r\n" "\r\n"
"public override IBuilder<$classname$> MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {\r\n", "public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {\r\n",
"classname", ClassName(descriptor_)); "classname", ClassName(descriptor_));
printer->Indent(); printer->Indent();
......
...@@ -199,7 +199,7 @@ void ServiceGenerator::GenerateStub(io::Printer* printer) { ...@@ -199,7 +199,7 @@ void ServiceGenerator::GenerateStub(io::Printer* printer) {
" controller,\r\n" " controller,\r\n"
" request,\r\n" " request,\r\n"
" $output$.DefaultInstance,\r\n" " $output$.DefaultInstance,\r\n"
" pb::RpcUtil.GeneralizeCallback(done, $output$.DefaultInstance));\r\n" " pb::RpcUtil.GeneralizeCallback<$output$, $output$.Builder>(done, $output$.DefaultInstance));\r\n"
"}\r\n"); "}\r\n");
} }
......
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