Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ProtobufCS/0.9.1/ProtobufCS/src/ProtocolBuffers/DynamicMessage.cs @ 7489

Last change on this file since 7489 was 3857, checked in by abeham, 15 years ago

#866

  • Added protobuf-csharp-port project source to ExtLibs
File size: 15.1 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.Generic;
37using System.IO;
38using Google.ProtocolBuffers.Descriptors;
39
40namespace Google.ProtocolBuffers {
41
42  /// <summary>
43  /// An implementation of IMessage that can represent arbitrary types, given a MessageaDescriptor.
44  /// </summary>
45  public sealed class DynamicMessage : AbstractMessage<DynamicMessage, DynamicMessage.Builder> {
46
47    private readonly MessageDescriptor type;
48    private readonly FieldSet fields;
49    private readonly UnknownFieldSet unknownFields;
50    private int memoizedSize = -1;
51
52    /// <summary>
53    /// Creates a DynamicMessage with the given FieldSet.
54    /// </summary>
55    /// <param name="type"></param>
56    /// <param name="fields"></param>
57    /// <param name="unknownFields"></param>
58    private DynamicMessage(MessageDescriptor type, FieldSet fields, UnknownFieldSet unknownFields) {
59      this.type = type;
60      this.fields = fields;
61      this.unknownFields = unknownFields;
62    }
63
64    /// <summary>
65    /// Returns a DynamicMessage representing the default instance of the given type.
66    /// </summary>
67    /// <param name="type"></param>
68    /// <returns></returns>
69    public static DynamicMessage GetDefaultInstance(MessageDescriptor type) {
70      return new DynamicMessage(type, FieldSet.DefaultInstance, UnknownFieldSet.DefaultInstance);
71    }
72
73    /// <summary>
74    /// Parses a message of the given type from the given stream.
75    /// </summary>
76    public static DynamicMessage ParseFrom(MessageDescriptor type, CodedInputStream input) {
77      Builder builder = CreateBuilder(type);
78      Builder dynamicBuilder = builder.MergeFrom(input);
79      return dynamicBuilder.BuildParsed();
80    }
81
82    /// <summary>
83    /// Parse a message of the given type from the given stream and extension registry.
84    /// </summary>
85    /// <param name="type"></param>
86    /// <param name="input"></param>
87    /// <param name="extensionRegistry"></param>
88    /// <returns></returns>
89    public static DynamicMessage ParseFrom(MessageDescriptor type, CodedInputStream input, ExtensionRegistry extensionRegistry) {
90      Builder builder = CreateBuilder(type);
91      Builder dynamicBuilder = builder.MergeFrom(input, extensionRegistry);
92      return dynamicBuilder.BuildParsed();
93    }
94
95    /// <summary>
96    /// Parses a message of the given type from the given stream.
97    /// </summary>
98    public static DynamicMessage ParseFrom(MessageDescriptor type, Stream input) {
99      Builder builder = CreateBuilder(type);
100      Builder dynamicBuilder = builder.MergeFrom(input);
101      return dynamicBuilder.BuildParsed();
102    }
103
104    /// <summary>
105    /// Parse a message of the given type from the given stream and extension registry.
106    /// </summary>
107    /// <param name="type"></param>
108    /// <param name="input"></param>
109    /// <param name="extensionRegistry"></param>
110    /// <returns></returns>
111    public static DynamicMessage ParseFrom(MessageDescriptor type, Stream input, ExtensionRegistry extensionRegistry) {
112      Builder builder = CreateBuilder(type);
113      Builder dynamicBuilder = builder.MergeFrom(input, extensionRegistry);
114      return dynamicBuilder.BuildParsed();
115    }
116
117    /// <summary>
118    /// Parse <paramref name="data"/> as a message of the given type and return it.
119    /// </summary>
120    public static DynamicMessage ParseFrom(MessageDescriptor type, ByteString data) {
121      Builder builder = CreateBuilder(type);
122      Builder dynamicBuilder = builder.MergeFrom(data);
123      return dynamicBuilder.BuildParsed();
124    }
125
126    /// <summary>
127    /// Parse <paramref name="data"/> as a message of the given type and return it.
128    /// </summary>
129    public static DynamicMessage ParseFrom(MessageDescriptor type, ByteString data, ExtensionRegistry extensionRegistry) {
130      Builder builder = CreateBuilder(type);
131      Builder dynamicBuilder = builder.MergeFrom(data, extensionRegistry);
132      return dynamicBuilder.BuildParsed();
133
134    }
135
136    /// <summary>
137    /// Parse <paramref name="data"/> as a message of the given type and return it.
138    /// </summary>
139    public static DynamicMessage ParseFrom(MessageDescriptor type, byte[] data) {
140      Builder builder = CreateBuilder(type);
141      Builder dynamicBuilder = builder.MergeFrom(data);
142      return dynamicBuilder.BuildParsed();
143    }
144
145    /// <summary>
146    /// Parse <paramref name="data"/> as a message of the given type and return it.
147    /// </summary>
148    public static DynamicMessage ParseFrom(MessageDescriptor type, byte[] data, ExtensionRegistry extensionRegistry) {
149      Builder builder = CreateBuilder(type);
150      Builder dynamicBuilder = builder.MergeFrom(data, extensionRegistry);
151      return dynamicBuilder.BuildParsed();
152    }
153
154    /// <summary>
155    /// Constructs a builder for the given type.
156    /// </summary>
157    public static Builder CreateBuilder(MessageDescriptor type) {
158      return new Builder(type);
159    }
160
161    /// <summary>
162    /// Constructs a builder for a message of the same type as <paramref name="prototype"/>,
163    /// and initializes it with the same contents.
164    /// </summary>
165    /// <param name="prototype"></param>
166    /// <returns></returns>
167    public static Builder CreateBuilder(IMessage prototype) {
168      return new Builder(prototype.DescriptorForType).MergeFrom(prototype);
169    }
170
171    // -----------------------------------------------------------------
172    // Implementation of IMessage interface.
173
174    public override MessageDescriptor DescriptorForType {
175      get { return type; }
176    }
177
178    public override DynamicMessage DefaultInstanceForType {
179      get { return GetDefaultInstance(type); }
180    }
181
182    public override IDictionary<FieldDescriptor, object> AllFields {
183      get { return fields.AllFields; }
184    }
185
186    public override bool HasField(FieldDescriptor field) {
187      VerifyContainingType(field);
188      return fields.HasField(field);
189    }
190
191    public override object this[FieldDescriptor field] {
192      get {
193        VerifyContainingType(field);
194        object result = fields[field];
195        if (result == null) {
196          result = GetDefaultInstance(field.MessageType);
197        }
198        return result;
199      }
200    }
201
202    public override int GetRepeatedFieldCount(FieldDescriptor field) {
203      VerifyContainingType(field);
204      return fields.GetRepeatedFieldCount(field);
205    }
206
207    public override object this[FieldDescriptor field, int index] {
208      get {
209        VerifyContainingType(field);
210        return fields[field, index];
211      }
212    }
213
214    public override UnknownFieldSet UnknownFields {
215      get { return unknownFields; }
216    }
217
218    public bool Initialized {
219      get { return fields.IsInitializedWithRespectTo(type); }
220    }
221
222    public override void WriteTo(CodedOutputStream output) {
223      fields.WriteTo(output);
224      if (type.Options.MessageSetWireFormat) {
225        unknownFields.WriteAsMessageSetTo(output);
226      } else {
227        unknownFields.WriteTo(output);
228      }
229    }
230
231    public override int SerializedSize {
232      get {
233        int size = memoizedSize;
234        if (size != -1) return size;
235
236        size = fields.SerializedSize;
237        if (type.Options.MessageSetWireFormat) {
238          size += unknownFields.SerializedSizeAsMessageSet;
239        } else {
240          size += unknownFields.SerializedSize;
241        }
242
243        memoizedSize = size;
244        return size;
245      }
246    }
247
248    public override Builder CreateBuilderForType() {
249      return new Builder(type);
250    }
251
252    public override Builder ToBuilder() {
253      return CreateBuilderForType().MergeFrom(this);
254    }
255
256    /// <summary>
257    /// Verifies that the field is a field of this message.
258    /// </summary>
259    private void VerifyContainingType(FieldDescriptor field) {
260      if (field.ContainingType != type) {
261        throw new ArgumentException("FieldDescriptor does not match message type.");
262      }
263    }
264
265    /// <summary>
266    /// Builder for dynamic messages. Instances are created with DynamicMessage.CreateBuilder.
267    /// </summary>
268    public sealed class Builder : AbstractBuilder<DynamicMessage, Builder> {
269      private readonly MessageDescriptor type;
270      private FieldSet fields;
271      private UnknownFieldSet unknownFields;
272
273      internal Builder(MessageDescriptor type) {
274        this.type = type;
275        this.fields = FieldSet.CreateInstance();
276        this.unknownFields = UnknownFieldSet.DefaultInstance;
277      }
278
279      protected override Builder ThisBuilder {
280        get { return this; }
281      }
282
283      public override Builder Clear() {
284        fields.Clear();
285        return this;
286      }
287
288      public override Builder MergeFrom(IMessage other) {
289        if (other.DescriptorForType != type) {
290          throw new ArgumentException("MergeFrom(IMessage) can only merge messages of the same type.");
291        }
292        fields.MergeFrom(other);
293        MergeUnknownFields(other.UnknownFields);
294        return this;
295      }
296
297      public override Builder MergeFrom(DynamicMessage other) {
298        return MergeFrom((IMessage)other);
299      }
300
301      public override DynamicMessage Build() {
302        if (fields != null && !IsInitialized) {
303          throw new UninitializedMessageException(new DynamicMessage(type, fields, unknownFields));
304        }
305        return BuildPartial();
306      }
307
308      /// <summary>
309      /// Helper for DynamicMessage.ParseFrom() methods to call. Throws
310      /// InvalidProtocolBufferException
311      /// </summary>
312      /// <returns></returns>
313      internal DynamicMessage BuildParsed() {
314        if (!IsInitialized) {
315          throw new UninitializedMessageException(new DynamicMessage(type, fields, unknownFields)).AsInvalidProtocolBufferException();
316        }
317        return BuildPartial();
318      }
319
320      public override DynamicMessage BuildPartial() {
321        if (fields == null) {
322          throw new InvalidOperationException("Build() has already been called on this Builder.");
323        }
324        fields.MakeImmutable();
325        DynamicMessage result = new DynamicMessage(type, fields, unknownFields);
326        fields = null;
327        unknownFields = null;
328        return result;
329      }
330
331      public override Builder Clone() {
332        Builder result = new Builder(type);
333        result.fields.MergeFrom(fields);
334        return result;
335      }
336
337      public override bool IsInitialized {
338        get { return fields.IsInitializedWithRespectTo(type); }
339      }
340
341      public override Builder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
342        UnknownFieldSet.Builder unknownFieldsBuilder = UnknownFieldSet.CreateBuilder(unknownFields);
343        unknownFieldsBuilder.MergeFrom(input, extensionRegistry, this);
344        unknownFields = unknownFieldsBuilder.Build();
345        return this;
346      }
347
348      public override MessageDescriptor DescriptorForType {
349        get { return type; }
350      }
351
352      public override DynamicMessage DefaultInstanceForType {
353        get { return GetDefaultInstance(type); }
354      }
355
356      public override IDictionary<FieldDescriptor, object> AllFields {
357        get { return fields.AllFields; }
358      }
359
360      public override IBuilder CreateBuilderForField(FieldDescriptor field) {
361        VerifyContainingType(field);
362        if (field.MappedType != MappedType.Message) {
363          throw new ArgumentException("CreateBuilderForField is only valid for fields with message type.");
364        }
365        return new Builder(field.MessageType);     
366      }
367
368      public override bool HasField(FieldDescriptor field) {
369        VerifyContainingType(field);
370        return fields.HasField(field);
371      }
372
373      public override object this[FieldDescriptor field, int index] {
374        get {
375          VerifyContainingType(field);
376          return fields[field, index];
377        }
378        set {
379          VerifyContainingType(field);
380          fields[field, index] = value;
381        }
382      }
383
384      public override object this[FieldDescriptor field] {
385        get {
386          VerifyContainingType(field);
387          object result = fields[field];
388          if (result == null) {
389            result = GetDefaultInstance(field.MessageType);
390          }
391          return result;
392        }
393        set {
394          VerifyContainingType(field);
395          fields[field] = value;
396        }
397      }
398
399      public override Builder ClearField(FieldDescriptor field) {
400        VerifyContainingType(field);
401        fields.ClearField(field);
402        return this;
403      }
404
405      public override int GetRepeatedFieldCount(FieldDescriptor field) {
406        VerifyContainingType(field);
407        return fields.GetRepeatedFieldCount(field);
408      }
409
410      public override Builder AddRepeatedField(FieldDescriptor field, object value) {
411        VerifyContainingType(field);
412        fields.AddRepeatedField(field, value);
413        return this;
414      }
415
416      public override UnknownFieldSet UnknownFields {
417        get {
418          return unknownFields;
419        }
420        set {
421          unknownFields = value;
422        }
423      }
424
425      /// <summary>
426      /// Verifies that the field is a field of this message.
427      /// </summary>
428      /// <param name="field"></param>
429      private void VerifyContainingType(FieldDescriptor field) {
430        if (field.ContainingType != type) {
431          throw new ArgumentException("FieldDescriptor does not match message type.");
432        }
433      }
434    }
435  }
436}
Note: See TracBrowser for help on using the repository browser.