Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3026_IntegrationIntoSymSpace/HeuristicLab.ExtLibs/HeuristicLab.ProtobufCS/2.4.1/ProtobufCS/src/ProtocolBuffers/ExtensionRegistry.cs

Last change on this file 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.1 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.Descriptors;
40
41namespace Google.ProtocolBuffers
42{
43    /// <summary>
44    /// A table of known extensions, searchable by name or field number.  When
45    /// parsing a protocol message that might have extensions, you must provide
46    /// an <see cref="ExtensionRegistry"/> in which you have registered any extensions
47    /// that you want to be able to parse.  Otherwise, those extensions will just
48    /// be treated like unknown fields.
49    /// </summary>
50    /// <example>
51    /// For example, if you had the <c>.proto</c> file:
52    /// <code>
53    /// option java_class = "MyProto";
54    ///
55    /// message Foo {
56    ///   extensions 1000 to max;
57    /// }
58    ///
59    /// extend Foo {
60    ///   optional int32 bar;
61    /// }
62    /// </code>
63    ///
64    /// Then you might write code like:
65    ///
66    /// <code>
67    /// ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
68    /// registry.Add(MyProto.Bar);
69    /// MyProto.Foo message = MyProto.Foo.ParseFrom(input, registry);
70    /// </code>
71    /// </example>
72    ///
73    /// <remarks>
74    /// <para>You might wonder why this is necessary. Two alternatives might come to
75    /// mind. First, you might imagine a system where generated extensions are
76    /// automatically registered when their containing classes are loaded. This
77    /// is a popular technique, but is bad design; among other things, it creates a
78    /// situation where behavior can change depending on what classes happen to be
79    /// loaded. It also introduces a security vulnerability, because an
80    /// unprivileged class could cause its code to be called unexpectedly from a
81    /// privileged class by registering itself as an extension of the right type.
82    /// </para>
83    /// <para>Another option you might consider is lazy parsing: do not parse an
84    /// extension until it is first requested, at which point the caller must
85    /// provide a type to use. This introduces a different set of problems. First,
86    /// it would require a mutex lock any time an extension was accessed, which
87    /// would be slow. Second, corrupt data would not be detected until first
88    /// access, at which point it would be much harder to deal with it. Third, it
89    /// could violate the expectation that message objects are immutable, since the
90    /// type provided could be any arbitrary message class. An unprivileged user
91    /// could take advantage of this to inject a mutable object into a message
92    /// belonging to privileged code and create mischief.</para>
93    /// </remarks>
94    public sealed partial class ExtensionRegistry
95    {
96        /// <summary>
97        /// Finds an extension by fully-qualified field name, in the
98        /// proto namespace, i.e. result.Descriptor.FullName will match
99        /// <paramref name="fullName"/> if a match is found. A null
100        /// reference is returned if the extension can't be found.
101        /// </summary>
102        [Obsolete("Please use the FindByName method instead.", true)]
103        public ExtensionInfo this[string fullName]
104        {
105            get
106            {
107                foreach (IGeneratedExtensionLite ext in extensionsByNumber.Values)
108                {
109                    if (StringComparer.Ordinal.Equals(ext.Descriptor.FullName, fullName))
110                    {
111                        return ext as ExtensionInfo;
112                    }
113                }
114                return null;
115            }
116        }
117
118#if !LITE
119        /// <summary>
120        /// Finds an extension by containing type and field number.
121        /// A null reference is returned if the extension can't be found.
122        /// </summary>
123        public ExtensionInfo this[MessageDescriptor containingType, int fieldNumber]
124        {
125            get
126            {
127                IGeneratedExtensionLite ret;
128                extensionsByNumber.TryGetValue(new ExtensionIntPair(containingType, fieldNumber), out ret);
129                return ret as ExtensionInfo;
130            }
131        }
132
133        public ExtensionInfo FindByName(MessageDescriptor containingType, string fieldName)
134        {
135            return FindExtensionByName(containingType, fieldName) as ExtensionInfo;
136        }
137#endif
138
139        /// <summary>
140        /// Add an extension from a generated file to the registry.
141        /// </summary>
142        public void Add<TExtension>(GeneratedExtensionBase<TExtension> extension)
143        {
144            if (extension.Descriptor.MappedType == MappedType.Message)
145            {
146                Add(new ExtensionInfo(extension.Descriptor, extension.MessageDefaultInstance));
147            }
148            else
149            {
150                Add(new ExtensionInfo(extension.Descriptor, null));
151            }
152        }
153
154        /// <summary>
155        /// Adds a non-message-type extension to the registry by descriptor.
156        /// </summary>
157        /// <param name="type"></param>
158        public void Add(FieldDescriptor type)
159        {
160            if (type.MappedType == MappedType.Message)
161            {
162                throw new ArgumentException("ExtensionRegistry.Add() must be provided a default instance "
163                                            + "when adding an embedded message extension.");
164            }
165            Add(new ExtensionInfo(type, null));
166        }
167
168        /// <summary>
169        /// Adds a message-type-extension to the registry by descriptor.
170        /// </summary>
171        /// <param name="type"></param>
172        /// <param name="defaultInstance"></param>
173        public void Add(FieldDescriptor type, IMessage defaultInstance)
174        {
175            if (type.MappedType != MappedType.Message)
176            {
177                throw new ArgumentException("ExtensionRegistry.Add() provided a default instance for a "
178                                            + "non-message extension.");
179            }
180            Add(new ExtensionInfo(type, defaultInstance));
181        }
182
183        private void Add(ExtensionInfo extension)
184        {
185            if (readOnly)
186            {
187                throw new InvalidOperationException("Cannot add entries to a read-only extension registry");
188            }
189            if (!extension.Descriptor.IsExtension)
190            {
191                throw new ArgumentException("ExtensionRegistry.add() was given a FieldDescriptor for a "
192                                            + "regular (non-extension) field.");
193            }
194
195            IGeneratedExtensionLite liteExtension = extension;
196            Add(liteExtension);
197
198            FieldDescriptor field = extension.Descriptor;
199            if (field.ContainingType.Options.MessageSetWireFormat
200                && field.FieldType == FieldType.Message
201                && field.IsOptional
202                && field.ExtensionScope == field.MessageType)
203            {
204                // This is an extension of a MessageSet type defined within the extension
205                // type's own scope. For backwards-compatibility, allow it to be looked
206                // up by type name.
207                Dictionary<string, IGeneratedExtensionLite> map;
208                if (extensionsByName.TryGetValue(liteExtension.ContainingType, out map))
209                {
210                    map[field.MessageType.FullName] = extension;
211                }
212            }
213        }
214    }
215}
Note: See TracBrowser for help on using the repository browser.