Commit a03ea11c authored by Jon Skeet's avatar Jon Skeet

Finish implementing GeneratedBuilder.

parent 4d276b6c
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Google.ProtocolBuffers.Collections;
using Google.ProtocolBuffers.Descriptors;
using System.IO;
using Google.ProtocolBuffers.FieldAccess;
namespace Google.ProtocolBuffers {
/// <summary>
......@@ -20,6 +22,10 @@ namespace Google.ProtocolBuffers {
/// </summary>
protected abstract TMessage MessageBeingBuilt { get; }
protected internal FieldAccessorTable InternalFieldAccessors {
get { return MessageBeingBuilt.InternalFieldAccessors; }
}
public override bool Initialized {
get { return MessageBeingBuilt.IsInitialized; }
}
......@@ -33,11 +39,11 @@ namespace Google.ProtocolBuffers {
// For repeated fields, the underlying list object is still modifiable at this point.
// Make sure not to expose the modifiable list to the caller.
return field.IsRepeated
? MessageBeingBuilt.InternalFieldAccessors[field].GetRepeatedWrapper(this)
? InternalFieldAccessors[field].GetRepeatedWrapper(this)
: MessageBeingBuilt[field];
}
set {
MessageBeingBuilt.InternalFieldAccessors[field].SetValue(this, value);
InternalFieldAccessors[field].SetValue(this, value);
}
}
......@@ -74,7 +80,7 @@ namespace Google.ProtocolBuffers {
public override object this[FieldDescriptor field, int 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) {
......@@ -98,7 +104,7 @@ namespace Google.ProtocolBuffers {
}
public override IBuilder CreateBuilderForField(FieldDescriptor field) {
return MessageBeingBuilt.InternalFieldAccessors[field].CreateBuilder();
return InternalFieldAccessors[field].CreateBuilder();
}
protected override IBuilder ClearFieldImpl(FieldDescriptor field) {
......@@ -110,16 +116,47 @@ namespace Google.ProtocolBuffers {
}
public IBuilder<TMessage> ClearField(FieldDescriptor field) {
MessageBeingBuilt.InternalFieldAccessors[field].Clear(this);
InternalFieldAccessors[field].Clear(this);
return this;
}
// FIXME: Implement!
public virtual IBuilder<TMessage> MergeFrom(TMessage other) { return this; }
public virtual IBuilder<TMessage> MergeUnknownFields(UnknownFieldSet unknownFields) { return this; }
public virtual IBuilder<TMessage> MergeFrom(TMessage other) {
if (other.DescriptorForType != InternalFieldAccessors.Descriptor) {
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) {
MessageBeingBuilt.InternalFieldAccessors[field].AddRepeated(this, value);
InternalFieldAccessors[field].AddRepeated(this, value);
return this;
}
......
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Google.ProtocolBuffers.Collections;
using Google.ProtocolBuffers.Descriptors;
using Google.ProtocolBuffers.FieldAccess;
......@@ -14,7 +16,7 @@ namespace Google.ProtocolBuffers {
public abstract class GeneratedMessage<TMessage, TBuilder> : AbstractMessage, IMessage<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; }
......@@ -72,5 +74,15 @@ namespace Google.ProtocolBuffers {
public override UnknownFieldSet 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 @@
<Compile Include="Collections\Dictionaries.cs" />
<Compile Include="Collections\Lists.cs" />
<Compile Include="Collections\ReadOnlyDictionary.cs" />
<Compile Include="DescriptorProtos\Autogenerated.cs" />
<Compile Include="DescriptorProtos\DescriptorProtoFile.cs" />
<Compile Include="DescriptorProtos\IDescriptorProto.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