blob: e27dff727385c227875ad8c56d86366f14378004 [file] [log] [blame]
csharptest980ba8d2010-11-07 16:30:39 -06001#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 Google.ProtocolBuffers.Collections;
csharptest804b6d82010-11-07 10:49:33 -060038using Google.ProtocolBuffers.Descriptors;
csharptestd9c59e62010-11-04 19:36:28 -050039
40namespace Google.ProtocolBuffers {
41
42 public interface IGeneratedExtensionLite {
43 int Number { get; }
44 object ContainingType { get; }
45 IMessageLite MessageDefaultInstance { get; }
46 }
csharptest804b6d82010-11-07 10:49:33 -060047
csharptest980ba8d2010-11-07 16:30:39 -060048 public class ExtensionDescriptorLite : IFieldDescriptorLite {
49 /// <summary>
50 /// Immutable mapping from field type to mapped type. Built using the attributes on
51 /// FieldType values.
52 /// </summary>
53 public static readonly IDictionary<FieldType, MappedType> FieldTypeToMappedTypeMap = MapFieldTypes();
54
55 private static IDictionary<FieldType, MappedType> MapFieldTypes() {
56 var map = new Dictionary<FieldType, MappedType>();
57 foreach (System.Reflection.FieldInfo field in typeof(FieldType).GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)) {
58 FieldType fieldType = (FieldType)field.GetValue(null);
59 FieldMappingAttribute mapping = (FieldMappingAttribute)field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0];
60 map[fieldType] = mapping.MappedType;
61 }
62 return Dictionaries.AsReadOnly(map);
63 }
64
65 private readonly IEnumLiteMap enumTypeMap;
csharptest804b6d82010-11-07 10:49:33 -060066 private readonly int number;
67 private readonly FieldType type;
68 private readonly bool isRepeated;
69 private readonly bool isPacked;
csharptest980ba8d2010-11-07 16:30:39 -060070 private readonly MappedType mapType;
71 private readonly object defaultValue;
csharptest804b6d82010-11-07 10:49:33 -060072
csharptest980ba8d2010-11-07 16:30:39 -060073 public ExtensionDescriptorLite(IEnumLiteMap enumTypeMap, int number, FieldType type, object defaultValue, bool isRepeated, bool isPacked) {
csharptest804b6d82010-11-07 10:49:33 -060074 this.enumTypeMap = enumTypeMap;
75 this.number = number;
76 this.type = type;
csharptest980ba8d2010-11-07 16:30:39 -060077 this.mapType = FieldTypeToMappedTypeMap[type];
csharptest804b6d82010-11-07 10:49:33 -060078 this.isRepeated = isRepeated;
79 this.isPacked = isPacked;
csharptest980ba8d2010-11-07 16:30:39 -060080 this.defaultValue = defaultValue;
csharptest804b6d82010-11-07 10:49:33 -060081 }
82
csharptest980ba8d2010-11-07 16:30:39 -060083 public bool IsRepeated {
84 get { return isRepeated; }
85 }
86
87 public bool IsRequired {
88 get { return false; }
89 }
90
91 public bool IsPacked {
92 get { return isPacked; }
93 }
94
95 public bool IsExtension {
96 get { return true; }
97 }
98
99#warning ToDo - Discover the meaning and purpose of this durring serialization and return the correct value
100 public bool MessageSetWireFormat {
101 get { return true; }
102 }
103
104 public int FieldNumber {
csharptest804b6d82010-11-07 10:49:33 -0600105 get { return number; }
106 }
csharptest980ba8d2010-11-07 16:30:39 -0600107
108 public IEnumLiteMap EnumType {
109 get { return enumTypeMap; }
110 }
111
112 public FieldType FieldType {
113 get { return type; }
114 }
115
116 public MappedType MappedType {
117 get { return mapType; }
118 }
119
120 public object DefaultValue {
121 get { return defaultValue; }
122 }
123
124 public int CompareTo(IFieldDescriptorLite other) {
125 return FieldNumber.CompareTo(other.FieldNumber);
126 }
csharptest804b6d82010-11-07 10:49:33 -0600127 }
128
csharptest804b6d82010-11-07 10:49:33 -0600129 public class GeneratedExtensionLite<TContainingType, TExtensionType> : IGeneratedExtensionLite
130 where TContainingType : IMessageLite {
131
132 private readonly TContainingType containingTypeDefaultInstance;
133 private readonly TExtensionType defaultValue;
134 private readonly IMessageLite messageDefaultInstance;
135 private readonly ExtensionDescriptorLite descriptor;
136
137 // We can't always initialize a GeneratedExtension when we first construct
138 // it due to initialization order difficulties (namely, the default
139 // instances may not have been constructed yet). So, we construct an
140 // uninitialized GeneratedExtension once, then call internalInit() on it
141 // later. Generated code will always call internalInit() on all extensions
142 // as part of the static initialization code, and internalInit() throws an
143 // exception if called more than once, so this method is useless to users.
144 protected GeneratedExtensionLite(
145 TContainingType containingTypeDefaultInstance,
146 TExtensionType defaultValue,
147 IMessageLite messageDefaultInstance,
148 ExtensionDescriptorLite descriptor) {
149 this.containingTypeDefaultInstance = containingTypeDefaultInstance;
150 this.messageDefaultInstance = messageDefaultInstance;
151 this.defaultValue = defaultValue;
152 this.descriptor = descriptor;
153 }
154
155 /** For use by generated code only. */
156 public GeneratedExtensionLite(
157 TContainingType containingTypeDefaultInstance,
158 TExtensionType defaultValue,
159 IMessageLite messageDefaultInstance,
csharptest980ba8d2010-11-07 16:30:39 -0600160 IEnumLiteMap enumTypeMap,
csharptest804b6d82010-11-07 10:49:33 -0600161 int number,
162 FieldType type)
163 : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance,
csharptest980ba8d2010-11-07 16:30:39 -0600164 new ExtensionDescriptorLite(enumTypeMap, number, type, defaultValue,
csharptest804b6d82010-11-07 10:49:33 -0600165 false /* isRepeated */, false /* isPacked */)) {
166 }
167
168 /** For use by generated code only. */
169 public GeneratedExtensionLite(
170 TContainingType containingTypeDefaultInstance,
171 TExtensionType defaultValue,
172 IMessageLite messageDefaultInstance,
csharptest980ba8d2010-11-07 16:30:39 -0600173 IEnumLiteMap enumTypeMap,
csharptest804b6d82010-11-07 10:49:33 -0600174 int number,
175 FieldType type,
176 bool isPacked)
177 : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance,
csharptest980ba8d2010-11-07 16:30:39 -0600178 new ExtensionDescriptorLite(enumTypeMap, number, type, defaultValue,
csharptest804b6d82010-11-07 10:49:33 -0600179 true /* isRepeated */, isPacked)) {
180 }
181
182 /// <summary>
csharptest980ba8d2010-11-07 16:30:39 -0600183 /// Returns information about this extension
184 /// </summary>
185 public IFieldDescriptorLite Descriptor {
186 get { return descriptor; }
187 }
188
189 /// <summary>
190 /// Returns the default value for this extension
191 /// </summary>
192 public TExtensionType DefaultValue {
193 get { return defaultValue; }
194 }
195
196 /// <summary>
csharptest804b6d82010-11-07 10:49:33 -0600197 /// used for the extension registry
198 /// </summary>
199 object IGeneratedExtensionLite.ContainingType {
200 get { return ContainingTypeDefaultInstance; }
201 }
202 /**
203 * Default instance of the type being extended, used to identify that type.
204 */
205 public TContainingType ContainingTypeDefaultInstance {
206 get {
207 return containingTypeDefaultInstance;
208 }
209 }
210
211 /** Get the field number. */
212 public int Number {
213 get {
csharptest980ba8d2010-11-07 16:30:39 -0600214 return descriptor.FieldNumber;
csharptest804b6d82010-11-07 10:49:33 -0600215 }
216 }
217 /**
218 * If the extension is an embedded message, this is the default instance of
219 * that type.
220 */
221 public IMessageLite MessageDefaultInstance {
222 get {
223 return messageDefaultInstance;
224 }
225 }
csharptest980ba8d2010-11-07 16:30:39 -0600226
227 public object SingularFromReflectionType(object value) {
228 return value;
229 }
csharptest804b6d82010-11-07 10:49:33 -0600230 }
csharptestd9c59e62010-11-04 19:36:28 -0500231}