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

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

Issue 1842653006: Update //third_party/protobuf to version 3. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge Created 4 years, 8 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.Collections.Generic;
35 using System.Collections.ObjectModel;
36 using System.Linq;
37
38 namespace Google.Protobuf.Reflection
39 {
40 /// <summary>
41 /// Describes a message type.
42 /// </summary>
43 public sealed class MessageDescriptor : DescriptorBase
44 {
45 private static readonly HashSet<string> WellKnownTypeNames = new HashSet <string>
46 {
47 "google/protobuf/any.proto",
48 "google/protobuf/api.proto",
49 "google/protobuf/duration.proto",
50 "google/protobuf/empty.proto",
51 "google/protobuf/wrappers.proto",
52 "google/protobuf/timestamp.proto",
53 "google/protobuf/field_mask.proto",
54 "google/protobuf/source_context.proto",
55 "google/protobuf/struct.proto",
56 "google/protobuf/type.proto",
57 };
58
59 private readonly IList<FieldDescriptor> fieldsInDeclarationOrder;
60 private readonly IList<FieldDescriptor> fieldsInNumberOrder;
61 private readonly IDictionary<string, FieldDescriptor> jsonFieldMap;
62
63 internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, M essageDescriptor parent, int typeIndex, GeneratedCodeInfo generatedCodeInfo)
64 : base(file, file.ComputeFullName(parent, proto.Name), typeIndex)
65 {
66 Proto = proto;
67 Parser = generatedCodeInfo?.Parser;
68 ClrType = generatedCodeInfo?.ClrType;
69 ContainingType = parent;
70
71 // Note use of generatedCodeInfo. rather than generatedCodeInfo?. he re... we don't expect
72 // to see any nested oneofs, types or enums in "not actually generat ed" code... we do
73 // expect fields though (for map entry messages).
74 Oneofs = DescriptorUtil.ConvertAndMakeReadOnly(
75 proto.OneofDecl,
76 (oneof, index) =>
77 new OneofDescriptor(oneof, file, this, index, generatedCodeInfo. OneofNames[index]));
78
79 NestedTypes = DescriptorUtil.ConvertAndMakeReadOnly(
80 proto.NestedType,
81 (type, index) =>
82 new MessageDescriptor(type, file, this, index, generatedCodeInfo .NestedTypes[index]));
83
84 EnumTypes = DescriptorUtil.ConvertAndMakeReadOnly(
85 proto.EnumType,
86 (type, index) =>
87 new EnumDescriptor(type, file, this, index, generatedCodeInfo.Ne stedEnums[index]));
88
89 fieldsInDeclarationOrder = DescriptorUtil.ConvertAndMakeReadOnly(
90 proto.Field,
91 (field, index) =>
92 new FieldDescriptor(field, file, this, index, generatedCodeInfo? .PropertyNames[index]));
93 fieldsInNumberOrder = new ReadOnlyCollection<FieldDescriptor>(fields InDeclarationOrder.OrderBy(field => field.FieldNumber).ToArray());
94 // TODO: Use field => field.Proto.JsonName when we're confident it's appropriate. (And then use it in the formatter, too.)
95 jsonFieldMap = new ReadOnlyDictionary<string, FieldDescriptor>(field sInNumberOrder.ToDictionary(field => JsonFormatter.ToCamelCase(field.Name)));
96 file.DescriptorPool.AddSymbol(this);
97 Fields = new FieldCollection(this);
98 }
99
100 /// <summary>
101 /// The brief name of the descriptor's target.
102 /// </summary>
103 public override string Name => Proto.Name;
104
105 internal DescriptorProto Proto { get; }
106
107 /// <summary>
108 /// The CLR type used to represent message instances from this descripto r.
109 /// </summary>
110 /// <remarks>
111 /// <para>
112 /// The value returned by this property will be non-null for all regular fields. However,
113 /// if a message containing a map field is introspected, the list of nes ted messages will include
114 /// an auto-generated nested key/value pair message for the field. This is not represented in any
115 /// generated type, so this property will return null in such cases.
116 /// </para>
117 /// <para>
118 /// For wrapper types (<see cref="Google.Protobuf.WellKnownTypes.StringV alue"/> and the like), the type returned here
119 /// will be the generated message type, not the native type used by refl ection for fields of those types. Code
120 /// using reflection should call <see cref="IsWrapperType"/> to determin e whether a message descriptor represents
121 /// a wrapper type, and handle the result appropriately.
122 /// </para>
123 /// </remarks>
124 public Type ClrType { get; }
125
126 /// <summary>
127 /// A parser for this message type.
128 /// </summary>
129 /// <remarks>
130 /// <para>
131 /// As <see cref="MessageDescriptor"/> is not generic, this cannot be st atically
132 /// typed to the relevant type, but it should produce objects of a type compatible with <see cref="ClrType"/>.
133 /// </para>
134 /// <para>
135 /// The value returned by this property will be non-null for all regular fields. However,
136 /// if a message containing a map field is introspected, the list of nes ted messages will include
137 /// an auto-generated nested key/value pair message for the field. No me ssage parser object is created for
138 /// such messages, so this property will return null in such cases.
139 /// </para>
140 /// <para>
141 /// For wrapper types (<see cref="Google.Protobuf.WellKnownTypes.StringV alue"/> and the like), the parser returned here
142 /// will be the generated message type, not the native type used by refl ection for fields of those types. Code
143 /// using reflection should call <see cref="IsWrapperType"/> to determin e whether a message descriptor represents
144 /// a wrapper type, and handle the result appropriately.
145 /// </para>
146 /// </remarks>
147 public MessageParser Parser { get; }
148
149 /// <summary>
150 /// Returns whether this message is one of the "well known types" which may have runtime/protoc support.
151 /// </summary>
152 internal bool IsWellKnownType => File.Package == "google.protobuf" && We llKnownTypeNames.Contains(File.Name);
153
154 /// <summary>
155 /// Returns whether this message is one of the "wrapper types" used for fields which represent primitive values
156 /// with the addition of presence.
157 /// </summary>
158 internal bool IsWrapperType => File.Package == "google.protobuf" && File .Name == "google/protobuf/wrappers.proto";
159
160 /// <value>
161 /// If this is a nested type, get the outer descriptor, otherwise null.
162 /// </value>
163 public MessageDescriptor ContainingType { get; }
164
165 /// <value>
166 /// A collection of fields, which can be retrieved by name or field numb er.
167 /// </value>
168 public FieldCollection Fields { get; }
169
170 /// <value>
171 /// An unmodifiable list of this message type's nested types.
172 /// </value>
173 public IList<MessageDescriptor> NestedTypes { get; }
174
175 /// <value>
176 /// An unmodifiable list of this message type's enum types.
177 /// </value>
178 public IList<EnumDescriptor> EnumTypes { get; }
179
180 /// <value>
181 /// An unmodifiable list of the "oneof" field collections in this messag e type.
182 /// </value>
183 public IList<OneofDescriptor> Oneofs { get; }
184
185 /// <summary>
186 /// Finds a field by field name.
187 /// </summary>
188 /// <param name="name">The unqualified name of the field (e.g. "foo").</ param>
189 /// <returns>The field's descriptor, or null if not found.</returns>
190 public FieldDescriptor FindFieldByName(String name) => File.DescriptorPo ol.FindSymbol<FieldDescriptor>(FullName + "." + name);
191
192 /// <summary>
193 /// Finds a field by field number.
194 /// </summary>
195 /// <param name="number">The field number within this message type.</par am>
196 /// <returns>The field's descriptor, or null if not found.</returns>
197 public FieldDescriptor FindFieldByNumber(int number) => File.DescriptorP ool.FindFieldByNumber(this, number);
198
199 /// <summary>
200 /// Finds a nested descriptor by name. The is valid for fields, nested
201 /// message types, oneofs and enums.
202 /// </summary>
203 /// <param name="name">The unqualified name of the descriptor, e.g. "Foo "</param>
204 /// <returns>The descriptor, or null if not found.</returns>
205 public T FindDescriptor<T>(string name) where T : class, IDescriptor =>
206 File.DescriptorPool.FindSymbol<T>(FullName + "." + name);
207
208 /// <summary>
209 /// Looks up and cross-links all fields and nested types.
210 /// </summary>
211 internal void CrossLink()
212 {
213 foreach (MessageDescriptor message in NestedTypes)
214 {
215 message.CrossLink();
216 }
217
218 foreach (FieldDescriptor field in fieldsInDeclarationOrder)
219 {
220 field.CrossLink();
221 }
222
223 foreach (OneofDescriptor oneof in Oneofs)
224 {
225 oneof.CrossLink();
226 }
227 }
228
229 /// <summary>
230 /// A collection to simplify retrieving the field accessor for a particu lar field.
231 /// </summary>
232 public sealed class FieldCollection
233 {
234 private readonly MessageDescriptor messageDescriptor;
235
236 internal FieldCollection(MessageDescriptor messageDescriptor)
237 {
238 this.messageDescriptor = messageDescriptor;
239 }
240
241 /// <value>
242 /// Returns the fields in the message as an immutable list, in the o rder in which they
243 /// are declared in the source .proto file.
244 /// </value>
245 public IList<FieldDescriptor> InDeclarationOrder() => messageDescrip tor.fieldsInDeclarationOrder;
246
247 /// <value>
248 /// Returns the fields in the message as an immutable list, in ascen ding field number
249 /// order. Field numbers need not be contiguous, so there is no dire ct mapping from the
250 /// index in the list to the field number; to retrieve a field by fi eld number, it is better
251 /// to use the <see cref="FieldCollection"/> indexer.
252 /// </value>
253 public IList<FieldDescriptor> InFieldNumberOrder() => messageDescrip tor.fieldsInNumberOrder;
254
255 // TODO: consider making this public in the future. (Being conservat ive for now...)
256
257 /// <value>
258 /// Returns a read-only dictionary mapping the field names in this m essage as they're used
259 /// in the JSON representation to the field descriptors. For example , a field <c>foo_bar</c>
260 /// in the message would result in an entry with a key <c>fooBar</c> .
261 /// </value>
262 internal IDictionary<string, FieldDescriptor> ByJsonName() => messag eDescriptor.jsonFieldMap;
263
264 /// <summary>
265 /// Retrieves the descriptor for the field with the given number.
266 /// </summary>
267 /// <param name="number">Number of the field to retrieve the descrip tor for</param>
268 /// <returns>The accessor for the given field</returns>
269 /// <exception cref="KeyNotFoundException">The message descriptor do es not contain a field
270 /// with the given number</exception>
271 public FieldDescriptor this[int number]
272 {
273 get
274 {
275 var fieldDescriptor = messageDescriptor.FindFieldByNumber(nu mber);
276 if (fieldDescriptor == null)
277 {
278 throw new KeyNotFoundException("No such field number");
279 }
280 return fieldDescriptor;
281 }
282 }
283
284 /// <summary>
285 /// Retrieves the descriptor for the field with the given name.
286 /// </summary>
287 /// <param name="name">Name of the field to retrieve the descriptor for</param>
288 /// <returns>The descriptor for the given field</returns>
289 /// <exception cref="KeyNotFoundException">The message descriptor do es not contain a field
290 /// with the given name</exception>
291 public FieldDescriptor this[string name]
292 {
293 get
294 {
295 var fieldDescriptor = messageDescriptor.FindFieldByName(name );
296 if (fieldDescriptor == null)
297 {
298 throw new KeyNotFoundException("No such field name");
299 }
300 return fieldDescriptor;
301 }
302 }
303 }
304 }
305 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698