Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ProtobufCS/2.4.1/ProtobufCS/src/ProtocolBuffers/ExtendableMessage.cs @ 15529

Last change on this file since 15529 was 8295, checked in by abeham, 12 years ago

#1897:

  • Removed protocol buffers 0.9.1
  • Added protocol buffers 2.4.1
  • Updated proto processing command
File size: 9.8 KB
Line 
1#region Copyright notice and license
2
3// Protocol Buffers - Google's data interchange format
4// Copyright 2008 Google Inc.  All rights reserved.
5// http://github.com/jskeet/dotnet-protobufs/
6// Original C++/Java/Python code:
7// http://code.google.com/p/protobuf/
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are
11// met:
12//
13//     * Redistributions of source code must retain the above copyright
14// notice, this list of conditions and the following disclaimer.
15//     * Redistributions in binary form must reproduce the above
16// copyright notice, this list of conditions and the following disclaimer
17// in the documentation and/or other materials provided with the
18// distribution.
19//     * Neither the name of Google Inc. nor the names of its
20// contributors may be used to endorse or promote products derived from
21// this software without specific prior written permission.
22//
23// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35#endregion
36
37using System;
38using System.Collections.Generic;
39using Google.ProtocolBuffers.Collections;
40using Google.ProtocolBuffers.Descriptors;
41
42namespace Google.ProtocolBuffers
43{
44    public abstract partial class ExtendableMessage<TMessage, TBuilder> : GeneratedMessage<TMessage, TBuilder>
45        where TMessage : GeneratedMessage<TMessage, TBuilder>
46        where TBuilder : GeneratedBuilder<TMessage, TBuilder>, new()
47    {
48        protected ExtendableMessage()
49        {
50        }
51
52        private readonly FieldSet extensions = FieldSet.CreateInstance();
53
54        /// <summary>
55        /// Access for the builder.
56        /// </summary>
57        internal FieldSet Extensions
58        {
59            get { return extensions; }
60        }
61
62        /// <summary>
63        /// Checks if a singular extension is present.
64        /// </summary>
65        public bool HasExtension<TExtension>(GeneratedExtensionBase<TExtension> extension)
66        {
67            return extensions.HasField(extension.Descriptor);
68        }
69
70        /// <summary>
71        /// Returns the number of elements in a repeated extension.
72        /// </summary>
73        public int GetExtensionCount<TExtension>(GeneratedExtensionBase<IList<TExtension>> extension)
74        {
75            return extensions.GetRepeatedFieldCount(extension.Descriptor);
76        }
77
78        /// <summary>
79        /// Returns the value of an extension.
80        /// </summary>
81        public TExtension GetExtension<TExtension>(GeneratedExtensionBase<TExtension> extension)
82        {
83            object value = extensions[extension.Descriptor];
84            if (value == null)
85            {
86                return (TExtension) extension.MessageDefaultInstance;
87            }
88            else
89            {
90                return (TExtension) extension.FromReflectionType(value);
91            }
92        }
93
94        /// <summary>
95        /// Returns one element of a repeated extension.
96        /// </summary>
97        public TExtension GetExtension<TExtension>(GeneratedExtensionBase<IList<TExtension>> extension, int index)
98        {
99            return (TExtension) extension.SingularFromReflectionType(extensions[extension.Descriptor, index]);
100        }
101
102        /// <summary>
103        /// Called to check if all extensions are initialized.
104        /// </summary>
105        protected bool ExtensionsAreInitialized
106        {
107            get { return extensions.IsInitialized; }
108        }
109
110        public override bool IsInitialized
111        {
112            get { return base.IsInitialized && ExtensionsAreInitialized; }
113        }
114
115        #region Reflection
116
117        public override IDictionary<FieldDescriptor, object> AllFields
118        {
119            get
120            {
121                IDictionary<FieldDescriptor, object> result = GetMutableFieldMap();
122                foreach (KeyValuePair<IFieldDescriptorLite, object> entry in extensions.AllFields)
123                {
124                    result[(FieldDescriptor) entry.Key] = entry.Value;
125                }
126                return Dictionaries.AsReadOnly(result);
127            }
128        }
129
130        public override bool HasField(FieldDescriptor field)
131        {
132            if (field.IsExtension)
133            {
134                VerifyContainingType(field);
135                return extensions.HasField(field);
136            }
137            else
138            {
139                return base.HasField(field);
140            }
141        }
142
143        public override object this[FieldDescriptor field]
144        {
145            get
146            {
147                if (field.IsExtension)
148                {
149                    VerifyContainingType(field);
150                    object value = extensions[field];
151                    if (value == null)
152                    {
153                        // Lacking an ExtensionRegistry, we have no way to determine the
154                        // extension's real type, so we return a DynamicMessage.
155                        // TODO(jonskeet): Work out what this means
156                        return DynamicMessage.GetDefaultInstance(field.MessageType);
157                    }
158                    else
159                    {
160                        return value;
161                    }
162                }
163                else
164                {
165                    return base[field];
166                }
167            }
168        }
169
170        public override int GetRepeatedFieldCount(FieldDescriptor field)
171        {
172            if (field.IsExtension)
173            {
174                VerifyContainingType(field);
175                return extensions.GetRepeatedFieldCount(field);
176            }
177            else
178            {
179                return base.GetRepeatedFieldCount(field);
180            }
181        }
182
183        public override object this[FieldDescriptor field, int index]
184        {
185            get
186            {
187                if (field.IsExtension)
188                {
189                    VerifyContainingType(field);
190                    return extensions[field, index];
191                }
192                else
193                {
194                    return base[field, index];
195                }
196            }
197        }
198
199        internal void VerifyContainingType(FieldDescriptor field)
200        {
201            if (field.ContainingType != DescriptorForType)
202            {
203                throw new ArgumentException("FieldDescriptor does not match message type.");
204            }
205        }
206
207        #endregion
208
209        /// <summary>
210        /// Used by subclasses to serialize extensions. Extension ranges may be
211        /// interleaves with field numbers, but we must write them in canonical
212        /// (sorted by field number) order. This class helps us to write individual
213        /// ranges of extensions at once.
214        ///
215        /// TODO(jonskeet): See if we can improve this in terms of readability.
216        /// </summary>
217        protected class ExtensionWriter
218        {
219            private readonly IEnumerator<KeyValuePair<IFieldDescriptorLite, object>> iterator;
220            private readonly FieldSet extensions;
221            private KeyValuePair<IFieldDescriptorLite, object>? next = null;
222
223            internal ExtensionWriter(ExtendableMessage<TMessage, TBuilder> message)
224            {
225                extensions = message.extensions;
226                iterator = message.extensions.GetEnumerator();
227                if (iterator.MoveNext())
228                {
229                    next = iterator.Current;
230                }
231            }
232
233            public void WriteUntil(int end, ICodedOutputStream output)
234            {
235                while (next != null && next.Value.Key.FieldNumber < end)
236                {
237                    extensions.WriteField(next.Value.Key, next.Value.Value, output);
238                    if (iterator.MoveNext())
239                    {
240                        next = iterator.Current;
241                    }
242                    else
243                    {
244                        next = null;
245                    }
246                }
247            }
248        }
249
250        protected ExtensionWriter CreateExtensionWriter(ExtendableMessage<TMessage, TBuilder> message)
251        {
252            return new ExtensionWriter(message);
253        }
254
255        /// <summary>
256        /// Called by subclasses to compute the size of extensions.
257        /// </summary>
258        protected int ExtensionsSerializedSize
259        {
260            get { return extensions.SerializedSize; }
261        }
262
263        internal void VerifyExtensionContainingType<TExtension>(GeneratedExtensionBase<TExtension> extension)
264        {
265            if (extension.Descriptor.ContainingType != DescriptorForType)
266            {
267                // This can only happen if someone uses unchecked operations.
268                throw new ArgumentException("Extension is for type \"" + extension.Descriptor.ContainingType.FullName
269                                            + "\" which does not match message type \"" + DescriptorForType.FullName +
270                                            "\".");
271            }
272        }
273    }
274}
Note: See TracBrowser for help on using the repository browser.