Commit a03ea11c authored by Jon Skeet's avatar Jon Skeet

Finish implementing GeneratedBuilder.

parent 4d276b6c
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Google.ProtocolBuffers.Collections; using Google.ProtocolBuffers.Collections;
using Google.ProtocolBuffers.Descriptors; using Google.ProtocolBuffers.Descriptors;
using System.IO; using System.IO;
using Google.ProtocolBuffers.FieldAccess;
namespace Google.ProtocolBuffers { namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
...@@ -20,6 +22,10 @@ namespace Google.ProtocolBuffers { ...@@ -20,6 +22,10 @@ namespace Google.ProtocolBuffers {
/// </summary> /// </summary>
protected abstract TMessage MessageBeingBuilt { get; } protected abstract TMessage MessageBeingBuilt { get; }
protected internal FieldAccessorTable InternalFieldAccessors {
get { return MessageBeingBuilt.InternalFieldAccessors; }
}
public override bool Initialized { public override bool Initialized {
get { return MessageBeingBuilt.IsInitialized; } get { return MessageBeingBuilt.IsInitialized; }
} }
...@@ -33,11 +39,11 @@ namespace Google.ProtocolBuffers { ...@@ -33,11 +39,11 @@ namespace Google.ProtocolBuffers {
// For repeated fields, the underlying list object is still modifiable at this point. // For repeated fields, the underlying list object is still modifiable at this point.
// Make sure not to expose the modifiable list to the caller. // Make sure not to expose the modifiable list to the caller.
return field.IsRepeated return field.IsRepeated
? MessageBeingBuilt.InternalFieldAccessors[field].GetRepeatedWrapper(this) ? InternalFieldAccessors[field].GetRepeatedWrapper(this)
: MessageBeingBuilt[field]; : MessageBeingBuilt[field];
} }
set { set {
MessageBeingBuilt.InternalFieldAccessors[field].SetValue(this, value); InternalFieldAccessors[field].SetValue(this, value);
} }
} }
...@@ -74,7 +80,7 @@ namespace Google.ProtocolBuffers { ...@@ -74,7 +80,7 @@ namespace Google.ProtocolBuffers {
public override object this[FieldDescriptor field, int index] { public override object this[FieldDescriptor field, int index] {
get { return MessageBeingBuilt[field, index]; } get { return MessageBeingBuilt[field, index]; }
set { MessageBeingBuilt.InternalFieldAccessors[field].SetRepeated(this, index, value); } set { InternalFieldAccessors[field].SetRepeated(this, index, value); }
} }
public override bool HasField(FieldDescriptor field) { public override bool HasField(FieldDescriptor field) {
...@@ -98,7 +104,7 @@ namespace Google.ProtocolBuffers { ...@@ -98,7 +104,7 @@ namespace Google.ProtocolBuffers {
} }
public override IBuilder CreateBuilderForField(FieldDescriptor field) { public override IBuilder CreateBuilderForField(FieldDescriptor field) {
return MessageBeingBuilt.InternalFieldAccessors[field].CreateBuilder(); return InternalFieldAccessors[field].CreateBuilder();
} }
protected override IBuilder ClearFieldImpl(FieldDescriptor field) { protected override IBuilder ClearFieldImpl(FieldDescriptor field) {
...@@ -110,16 +116,47 @@ namespace Google.ProtocolBuffers { ...@@ -110,16 +116,47 @@ namespace Google.ProtocolBuffers {
} }
public IBuilder<TMessage> ClearField(FieldDescriptor field) { public IBuilder<TMessage> ClearField(FieldDescriptor field) {
MessageBeingBuilt.InternalFieldAccessors[field].Clear(this); InternalFieldAccessors[field].Clear(this);
return this; return this;
} }
// FIXME: Implement! public virtual IBuilder<TMessage> MergeFrom(TMessage other) {
public virtual IBuilder<TMessage> MergeFrom(TMessage other) { return this; } if (other.DescriptorForType != InternalFieldAccessors.Descriptor) {
public virtual IBuilder<TMessage> MergeUnknownFields(UnknownFieldSet unknownFields) { return this; } throw new ArgumentException("Message type mismatch");
}
foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields) {
FieldDescriptor field = entry.Key;
if (field.IsRepeated) {
// Concatenate repeated fields
foreach (object element in (IEnumerable)entry.Value) {
AddRepeatedField(field, element);
}
} else if (field.MappedType == MappedType.Message && HasField(field)) {
// Merge singular embedded messages
IMessage oldValue = (IMessage)this[field];
this[field] = oldValue.CreateBuilderForType()
.MergeFrom(oldValue)
.MergeFrom((IMessage)entry.Value)
.BuildPartial();
} else {
// Just overwrite
this[field] = entry.Value;
}
}
return this;
}
public virtual IBuilder<TMessage> MergeUnknownFields(UnknownFieldSet unknownFields) {
TMessage result = MessageBeingBuilt;
result.SetUnknownFields(UnknownFieldSet.CreateBuilder(result.UnknownFields)
.MergeFrom(unknownFields)
.Build());
return this;
}
public IBuilder<TMessage> AddRepeatedField(FieldDescriptor field, object value) { public IBuilder<TMessage> AddRepeatedField(FieldDescriptor field, object value) {
MessageBeingBuilt.InternalFieldAccessors[field].AddRepeated(this, value); InternalFieldAccessors[field].AddRepeated(this, value);
return this; return this;
} }
......
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using Google.ProtocolBuffers.Collections; using Google.ProtocolBuffers.Collections;
using Google.ProtocolBuffers.Descriptors; using Google.ProtocolBuffers.Descriptors;
using Google.ProtocolBuffers.FieldAccess; using Google.ProtocolBuffers.FieldAccess;
...@@ -14,7 +16,7 @@ namespace Google.ProtocolBuffers { ...@@ -14,7 +16,7 @@ namespace Google.ProtocolBuffers {
public abstract class GeneratedMessage<TMessage, TBuilder> : AbstractMessage, IMessage<TMessage> public abstract class GeneratedMessage<TMessage, TBuilder> : AbstractMessage, IMessage<TMessage>
where TMessage : GeneratedMessage<TMessage, TBuilder> where TBuilder : IBuilder<TMessage> { where TMessage : GeneratedMessage<TMessage, TBuilder> where TBuilder : IBuilder<TMessage> {
private readonly UnknownFieldSet unknownFields = UnknownFieldSet.DefaultInstance; private UnknownFieldSet unknownFields = UnknownFieldSet.DefaultInstance;
protected internal abstract FieldAccessorTable InternalFieldAccessors { get; } protected internal abstract FieldAccessorTable InternalFieldAccessors { get; }
...@@ -72,5 +74,15 @@ namespace Google.ProtocolBuffers { ...@@ -72,5 +74,15 @@ namespace Google.ProtocolBuffers {
public override UnknownFieldSet UnknownFields { public override UnknownFieldSet UnknownFields {
get { return unknownFields; } get { return unknownFields; }
} }
/// <summary>
/// Replaces the set of unknown fields for this message. This should
/// only be used before a message is built, by the builder. (In the
/// Java code it is private, but the builder is nested so has access
/// to it.)
/// </summary>
internal void SetUnknownFields(UnknownFieldSet fieldSet) {
unknownFields = fieldSet;
}
} }
} }
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
<Compile Include="Collections\Dictionaries.cs" /> <Compile Include="Collections\Dictionaries.cs" />
<Compile Include="Collections\Lists.cs" /> <Compile Include="Collections\Lists.cs" />
<Compile Include="Collections\ReadOnlyDictionary.cs" /> <Compile Include="Collections\ReadOnlyDictionary.cs" />
<Compile Include="DescriptorProtos\Autogenerated.cs" />
<Compile Include="DescriptorProtos\DescriptorProtoFile.cs" /> <Compile Include="DescriptorProtos\DescriptorProtoFile.cs" />
<Compile Include="DescriptorProtos\IDescriptorProto.cs" /> <Compile Include="DescriptorProtos\IDescriptorProto.cs" />
<Compile Include="DescriptorProtos\PartialClasses.cs" /> <Compile Include="DescriptorProtos\PartialClasses.cs" />
......
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