Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: third_party/protobuf/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs

Issue 1322483002: Revert https://codereview.chromium.org/1291903002 (protobuf roll). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #region Copyright notice and license
2 // Protocol Buffers - Google's data interchange format
3 // Copyright 2008 Google Inc. All rights reserved.
4 // https://developers.google.com/protocol-buffers/
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
15 // distribution.
16 // * Neither the name of Google Inc. nor the names of its
17 // contributors may be used to endorse or promote products derived from
18 // this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #endregion
32
33 using System;
34 using System.Linq;
35 using Google.Protobuf.Compatibility;
36
37 namespace Google.Protobuf.Reflection
38 {
39 /// <summary>
40 /// Descriptor for a field or extension within a message in a .proto file.
41 /// </summary>
42 public sealed class FieldDescriptor : DescriptorBase, IComparable<FieldDescr iptor>
43 {
44 private readonly FieldDescriptorProto proto;
45 private EnumDescriptor enumType;
46 private MessageDescriptor messageType;
47 private readonly MessageDescriptor containingType;
48 private readonly OneofDescriptor containingOneof;
49 private FieldType fieldType;
50 private readonly string propertyName; // Annoyingly, needed in Crosslink .
51 private IFieldAccessor accessor;
52
53 internal FieldDescriptor(FieldDescriptorProto proto, FileDescriptor file ,
54 MessageDescriptor parent, int index, string pro pertyName)
55 : base(file, file.ComputeFullName(parent, proto.Name), index)
56 {
57 this.proto = proto;
58 if (proto.Type != 0)
59 {
60 fieldType = GetFieldTypeFromProtoType(proto.Type);
61 }
62
63 if (FieldNumber <= 0)
64 {
65 throw new DescriptorValidationException(this,
66 "Field numbers must be p ositive integers.");
67 }
68 containingType = parent;
69 // OneofIndex "defaults" to -1 due to a hack in FieldDescriptor.OnCo nstruction.
70 if (proto.OneofIndex != -1)
71 {
72 if (proto.OneofIndex < 0 || proto.OneofIndex >= parent.Proto.One ofDecl.Count)
73 {
74 throw new DescriptorValidationException(this,
75 "FieldDescriptorProto.oneof_index is out of range for ty pe " + parent.Name);
76 }
77 containingOneof = parent.Oneofs[proto.OneofIndex];
78 }
79
80 file.DescriptorPool.AddSymbol(this);
81 // We can't create the accessor until we've cross-linked, unfortunat ely, as we
82 // may not know whether the type of the field is a map or not. Remem ber the property name
83 // for later.
84 // We could trust the generated code and check whether the type of t he property is
85 // a MapField, but that feels a tad nasty.
86 this.propertyName = propertyName;
87 }
88
89 /// <summary>
90 /// The brief name of the descriptor's target.
91 /// </summary>
92 public override string Name { get { return proto.Name; } }
93
94 internal FieldDescriptorProto Proto { get { return proto; } }
95
96 /// <summary>
97 /// Returns the accessor for this field, or <c>null</c> if this descript or does
98 /// not support reflective access.
99 /// </summary>
100 /// <remarks>
101 /// While a <see cref="FieldDescriptor"/> describes the field, it does n ot provide
102 /// any way of obtaining or changing the value of the field within a spe cific message;
103 /// that is the responsibility of the accessor.
104 /// </remarks>
105 public IFieldAccessor Accessor { get { return accessor; } }
106
107 /// <summary>
108 /// Maps a field type as included in the .proto file to a FieldType.
109 /// </summary>
110 private static FieldType GetFieldTypeFromProtoType(FieldDescriptorProto. Types.Type type)
111 {
112 switch (type)
113 {
114 case FieldDescriptorProto.Types.Type.TYPE_DOUBLE:
115 return FieldType.Double;
116 case FieldDescriptorProto.Types.Type.TYPE_FLOAT:
117 return FieldType.Float;
118 case FieldDescriptorProto.Types.Type.TYPE_INT64:
119 return FieldType.Int64;
120 case FieldDescriptorProto.Types.Type.TYPE_UINT64:
121 return FieldType.UInt64;
122 case FieldDescriptorProto.Types.Type.TYPE_INT32:
123 return FieldType.Int32;
124 case FieldDescriptorProto.Types.Type.TYPE_FIXED64:
125 return FieldType.Fixed64;
126 case FieldDescriptorProto.Types.Type.TYPE_FIXED32:
127 return FieldType.Fixed32;
128 case FieldDescriptorProto.Types.Type.TYPE_BOOL:
129 return FieldType.Bool;
130 case FieldDescriptorProto.Types.Type.TYPE_STRING:
131 return FieldType.String;
132 case FieldDescriptorProto.Types.Type.TYPE_GROUP:
133 return FieldType.Group;
134 case FieldDescriptorProto.Types.Type.TYPE_MESSAGE:
135 return FieldType.Message;
136 case FieldDescriptorProto.Types.Type.TYPE_BYTES:
137 return FieldType.Bytes;
138 case FieldDescriptorProto.Types.Type.TYPE_UINT32:
139 return FieldType.UInt32;
140 case FieldDescriptorProto.Types.Type.TYPE_ENUM:
141 return FieldType.Enum;
142 case FieldDescriptorProto.Types.Type.TYPE_SFIXED32:
143 return FieldType.SFixed32;
144 case FieldDescriptorProto.Types.Type.TYPE_SFIXED64:
145 return FieldType.SFixed64;
146 case FieldDescriptorProto.Types.Type.TYPE_SINT32:
147 return FieldType.SInt32;
148 case FieldDescriptorProto.Types.Type.TYPE_SINT64:
149 return FieldType.SInt64;
150 default:
151 throw new ArgumentException("Invalid type specified");
152 }
153 }
154
155 /// <summary>
156 /// Returns <c>true</c> if this field is a repeated field; <c>false</c> otherwise.
157 /// </summary>
158 public bool IsRepeated
159 {
160 get { return Proto.Label == FieldDescriptorProto.Types.Label.LABEL_R EPEATED; }
161 }
162
163 /// <summary>
164 /// Returns <c>true</c> if this field is a map field; <c>false</c> other wise.
165 /// </summary>
166 public bool IsMap
167 {
168 get { return fieldType == FieldType.Message && messageType.Proto.Opt ions != null && messageType.Proto.Options.MapEntry; }
169 }
170
171 /// <summary>
172 /// Returns <c>true</c> if this field is a packed, repeated field; <c>fa lse</c> otherwise.
173 /// </summary>
174 public bool IsPacked
175 {
176 // Note the || rather than && here - we're effectively defaulting to packed, because that *is*
177 // the default in proto3, which is all we support. We may give the w rong result for the protos
178 // within descriptor.proto, but that's okay, as they're never expose d and we don't use IsPacked
179 // within the runtime.
180 get { return Proto.Options == null || Proto.Options.Packed; }
181 }
182
183 /// <summary>
184 /// Get the field's containing message type.
185 /// </summary>
186 public MessageDescriptor ContainingType
187 {
188 get { return containingType; }
189 }
190
191 /// <summary>
192 /// Returns the oneof containing this field, or <c>null</c> if it is not part of a oneof.
193 /// </summary>
194 public OneofDescriptor ContainingOneof
195 {
196 get { return containingOneof; }
197 }
198
199 /// <summary>
200 /// Returns the type of the field.
201 /// </summary>
202 public FieldType FieldType
203 {
204 get { return fieldType; }
205 }
206
207 /// <summary>
208 /// Returns the field number declared in the proto file.
209 /// </summary>
210 public int FieldNumber
211 {
212 get { return Proto.Number; }
213 }
214
215 /// <summary>
216 /// Compares this descriptor with another one, ordering in "canonical" o rder
217 /// which simply means ascending order by field number. <paramref name=" other"/>
218 /// must be a field of the same type, i.e. the <see cref="ContainingType "/> of
219 /// both fields must be the same.
220 /// </summary>
221 public int CompareTo(FieldDescriptor other)
222 {
223 if (other.containingType != containingType)
224 {
225 throw new ArgumentException("FieldDescriptors can only be compar ed to other FieldDescriptors " +
226 "for fields of the same message type .");
227 }
228 return FieldNumber - other.FieldNumber;
229 }
230
231 /// <summary>
232 /// For enum fields, returns the field's type.
233 /// </summary>
234 public EnumDescriptor EnumType
235 {
236 get
237 {
238 if (fieldType != FieldType.Enum)
239 {
240 throw new InvalidOperationException("EnumType is only valid for enum fields.");
241 }
242 return enumType;
243 }
244 }
245
246 /// <summary>
247 /// For embedded message and group fields, returns the field's type.
248 /// </summary>
249 public MessageDescriptor MessageType
250 {
251 get
252 {
253 if (fieldType != FieldType.Message)
254 {
255 throw new InvalidOperationException("MessageType is only val id for enum fields.");
256 }
257 return messageType;
258 }
259 }
260
261 /// <summary>
262 /// Look up and cross-link all field types etc.
263 /// </summary>
264 internal void CrossLink()
265 {
266 if (Proto.TypeName != "")
267 {
268 IDescriptor typeDescriptor =
269 File.DescriptorPool.LookupSymbol(Proto.TypeName, this);
270
271 if (Proto.Type != 0)
272 {
273 // Choose field type based on symbol.
274 if (typeDescriptor is MessageDescriptor)
275 {
276 fieldType = FieldType.Message;
277 }
278 else if (typeDescriptor is EnumDescriptor)
279 {
280 fieldType = FieldType.Enum;
281 }
282 else
283 {
284 throw new DescriptorValidationException(this, "\"" + Pro to.TypeName + "\" is not a type.");
285 }
286 }
287
288 if (fieldType == FieldType.Message)
289 {
290 if (!(typeDescriptor is MessageDescriptor))
291 {
292 throw new DescriptorValidationException(this,
293 "\"" + Proto.Typ eName + "\" is not a message type.");
294 }
295 messageType = (MessageDescriptor) typeDescriptor;
296
297 if (Proto.DefaultValue != "")
298 {
299 throw new DescriptorValidationException(this, "Messages can't have default values.");
300 }
301 }
302 else if (fieldType == FieldType.Enum)
303 {
304 if (!(typeDescriptor is EnumDescriptor))
305 {
306 throw new DescriptorValidationException(this, "\"" + Pro to.TypeName + "\" is not an enum type.");
307 }
308 enumType = (EnumDescriptor) typeDescriptor;
309 }
310 else
311 {
312 throw new DescriptorValidationException(this, "Field with pr imitive type has type_name.");
313 }
314 }
315 else
316 {
317 if (fieldType == FieldType.Message || fieldType == FieldType.Enu m)
318 {
319 throw new DescriptorValidationException(this, "Field with me ssage or enum type missing type_name.");
320 }
321 }
322
323 // Note: no attempt to perform any default value parsing
324
325 File.DescriptorPool.AddFieldByNumber(this);
326
327 if (containingType != null && containingType.Proto.Options != null & & containingType.Proto.Options.MessageSetWireFormat)
328 {
329 throw new DescriptorValidationException(this, "MessageSet format is not supported.");
330 }
331 accessor = CreateAccessor(propertyName);
332 }
333
334 private IFieldAccessor CreateAccessor(string propertyName)
335 {
336 if (containingType.GeneratedType == null || propertyName == null)
337 {
338 return null;
339 }
340 var property = containingType.GeneratedType.GetProperty(propertyName );
341 if (property == null)
342 {
343 throw new DescriptorValidationException(this, "Property " + prop ertyName + " not found in " + containingType.GeneratedType);
344 }
345 return IsMap ? new MapFieldAccessor(property, this)
346 : IsRepeated ? new RepeatedFieldAccessor(property, this)
347 : (IFieldAccessor) new SingleFieldAccessor(property, this);
348 }
349 }
350 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698