Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ProtobufCS/0.9.1/ProtobufCS/src/ProtocolBuffers/GeneratedBuilder.cs @ 4095

Last change on this file since 4095 was 3857, checked in by abeham, 14 years ago

#866

  • Added protobuf-csharp-port project source to ExtLibs
File size: 8.0 KB
Line 
1#region Copyright notice and license
2// Protocol Buffers - Google's data interchange format
3// Copyright 2008 Google Inc.  All rights reserved.
4// http://github.com/jskeet/dotnet-protobufs/
5// Original C++/Java/Python code:
6// http://code.google.com/p/protobuf/
7//
8// Redistribution and use in source and binary forms, with or without
9// modification, are permitted provided that the following conditions are
10// met:
11//
12//     * Redistributions of source code must retain the above copyright
13// notice, this list of conditions and the following disclaimer.
14//     * Redistributions in binary form must reproduce the above
15// copyright notice, this list of conditions and the following disclaimer
16// in the documentation and/or other materials provided with the
17// distribution.
18//     * Neither the name of Google Inc. nor the names of its
19// contributors may be used to endorse or promote products derived from
20// this software without specific prior written permission.
21//
22// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33#endregion
34
35using System;
36using System.Collections;
37using System.Collections.Generic;
38using Google.ProtocolBuffers.Descriptors;
39using Google.ProtocolBuffers.FieldAccess;
40
41namespace Google.ProtocolBuffers {
42  /// <summary>
43  /// All generated protocol message builder classes extend this class. It implements
44  /// most of the IBuilder interface using reflection. Users can ignore this class
45  /// as an implementation detail.
46  /// </summary>
47  public abstract class GeneratedBuilder<TMessage, TBuilder> : AbstractBuilder<TMessage, TBuilder>
48      where TMessage : GeneratedMessage <TMessage, TBuilder>
49      where TBuilder : GeneratedBuilder<TMessage, TBuilder> {
50
51    /// <summary>
52    /// Returns the message being built at the moment.
53    /// </summary>
54    protected abstract TMessage MessageBeingBuilt { get; }
55
56    protected internal FieldAccessorTable<TMessage, TBuilder> InternalFieldAccessors {
57      get { return MessageBeingBuilt.FieldAccessorsFromBuilder; }
58    }
59
60    public override bool IsInitialized {
61      get { return MessageBeingBuilt.IsInitialized; }
62    }
63
64    public override IDictionary<FieldDescriptor, object> AllFields {
65      get { return MessageBeingBuilt.AllFields; }
66    }
67
68    public override object this[FieldDescriptor field] {
69      get {
70        // For repeated fields, the underlying list object is still modifiable at this point.
71        // Make sure not to expose the modifiable list to the caller.
72        return field.IsRepeated
73          ? InternalFieldAccessors[field].GetRepeatedWrapper(ThisBuilder)
74          : MessageBeingBuilt[field];
75      }
76      set {
77        InternalFieldAccessors[field].SetValue(ThisBuilder, value);
78      }
79    }
80
81    /// <summary>
82    /// Adds all of the specified values to the given collection.
83    /// </summary>
84    /// <exception cref="ArgumentNullException">Any element of the list is null</exception>
85    protected void AddRange<T>(IEnumerable<T> source, IList<T> destination) {
86      ThrowHelper.ThrowIfNull(source);
87      // We only need to check this for nullable types.
88      if (default(T) == null) {
89        ThrowHelper.ThrowIfAnyNull(source);
90      }
91      List<T> list = destination as List<T>;
92      if (list != null) {
93        list.AddRange(source);
94      } else {
95        foreach (T element in source) {
96          destination.Add(element);
97        }
98      }
99    }
100
101    /// <summary>
102    /// Called by derived classes to parse an unknown field.
103    /// </summary>
104    /// <returns>true unless the tag is an end-group tag</returns>
105    [CLSCompliant(false)]
106    protected virtual bool ParseUnknownField(CodedInputStream input, UnknownFieldSet.Builder unknownFields,
107                                     ExtensionRegistry extensionRegistry, uint tag) {
108      return unknownFields.MergeFieldFrom(tag, input);
109    }
110
111    public override MessageDescriptor DescriptorForType {
112      get { return MessageBeingBuilt.DescriptorForType; }
113    }
114
115    public override int GetRepeatedFieldCount(FieldDescriptor field) {
116      return MessageBeingBuilt.GetRepeatedFieldCount(field);
117    }
118
119    public override object this[FieldDescriptor field, int index] {
120      get { return MessageBeingBuilt[field, index]; }
121      set { InternalFieldAccessors[field].SetRepeated(ThisBuilder, index, value); }
122    }
123
124    public override bool HasField(FieldDescriptor field) {
125      return MessageBeingBuilt.HasField(field);
126    }
127
128    public override IBuilder CreateBuilderForField(FieldDescriptor field) {
129      return InternalFieldAccessors[field].CreateBuilder();
130    }
131
132    public override TBuilder ClearField(FieldDescriptor field) {
133      InternalFieldAccessors[field].Clear(ThisBuilder);
134      return ThisBuilder;
135    }
136
137    public override TBuilder MergeFrom(TMessage other) {
138      if (other.DescriptorForType != InternalFieldAccessors.Descriptor) {
139        throw new ArgumentException("Message type mismatch");
140      }
141
142      foreach (KeyValuePair<FieldDescriptor, object> entry in other.AllFields) {
143        FieldDescriptor field = entry.Key;
144        if (field.IsRepeated) {
145          // Concatenate repeated fields
146          foreach (object element in (IEnumerable)entry.Value) {
147            AddRepeatedField(field, element);
148          }
149        } else if (field.MappedType == MappedType.Message && HasField(field)) {
150          // Merge singular embedded messages
151          IMessage oldValue = (IMessage)this[field];
152          this[field] = oldValue.WeakCreateBuilderForType()
153              .WeakMergeFrom(oldValue)
154              .WeakMergeFrom((IMessage)entry.Value)
155              .WeakBuildPartial();
156        } else {
157          // Just overwrite
158          this[field] = entry.Value;
159        }
160      }
161      return ThisBuilder;
162    }
163
164    public override TBuilder MergeUnknownFields(UnknownFieldSet unknownFields) {
165      if (unknownFields != UnknownFieldSet.DefaultInstance) {
166        TMessage result = MessageBeingBuilt;
167        result.SetUnknownFields(UnknownFieldSet.CreateBuilder(result.UnknownFields)
168            .MergeFrom(unknownFields)
169            .Build());
170      }
171      return ThisBuilder;
172    }
173
174    public override TBuilder AddRepeatedField(FieldDescriptor field, object value) {
175      InternalFieldAccessors[field].AddRepeated(ThisBuilder, value);
176      return ThisBuilder;
177    }
178
179    /// <summary>
180    /// Like Build(), but will wrap UninitializedMessageException in
181    /// InvalidProtocolBufferException.
182    /// </summary>
183    public TMessage BuildParsed() {
184      if (!IsInitialized) {
185        throw new UninitializedMessageException(MessageBeingBuilt).AsInvalidProtocolBufferException();
186      }
187      return BuildPartial();
188    }
189
190    /// <summary>
191    /// Implementation of <see cref="IBuilder{TMessage, TBuilder}.Build" />.
192    /// </summary>
193    public override TMessage Build() {
194      // If the message is null, we'll throw a more appropriate exception in BuildPartial.
195      if (MessageBeingBuilt != null && !IsInitialized) {
196        throw new UninitializedMessageException(MessageBeingBuilt);
197      }
198      return BuildPartial();
199    }
200
201    public override UnknownFieldSet UnknownFields {
202      get { return MessageBeingBuilt.UnknownFields; }
203      set { MessageBeingBuilt.SetUnknownFields(value); }
204    }
205  }
206}
Note: See TracBrowser for help on using the repository browser.