diff options
Diffstat (limited to 'csharp')
-rw-r--r-- | csharp/ProtocolBuffers/GeneratedBuilder.cs | 55 | ||||
-rw-r--r-- | csharp/ProtocolBuffers/GeneratedMessage.cs | 14 | ||||
-rw-r--r-- | csharp/ProtocolBuffers/ProtocolBuffers.csproj | 1 |
3 files changed, 59 insertions, 11 deletions
diff --git a/csharp/ProtocolBuffers/GeneratedBuilder.cs b/csharp/ProtocolBuffers/GeneratedBuilder.cs index f11ed452..821dc7e7 100644 --- a/csharp/ProtocolBuffers/GeneratedBuilder.cs +++ b/csharp/ProtocolBuffers/GeneratedBuilder.cs @@ -1,9 +1,11 @@ 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; } diff --git a/csharp/ProtocolBuffers/GeneratedMessage.cs b/csharp/ProtocolBuffers/GeneratedMessage.cs index c22b9416..f43e2e9d 100644 --- a/csharp/ProtocolBuffers/GeneratedMessage.cs +++ b/csharp/ProtocolBuffers/GeneratedMessage.cs @@ -1,5 +1,7 @@ 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; + } } } diff --git a/csharp/ProtocolBuffers/ProtocolBuffers.csproj b/csharp/ProtocolBuffers/ProtocolBuffers.csproj index d1f7ad26..f0fb7ab3 100644 --- a/csharp/ProtocolBuffers/ProtocolBuffers.csproj +++ b/csharp/ProtocolBuffers/ProtocolBuffers.csproj @@ -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" /> |