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

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

Issue 1291903002: Pull new version of protobuf sources. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 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
37 namespace Google.Protobuf.Reflection
38 {
39 /// <summary>
40 /// Describes a .proto file, including everything defined within.
41 /// IDescriptor is implemented such that the File property returns this desc riptor,
42 /// and the FullName is the same as the Name.
43 /// </summary>
44 public sealed class FileDescriptor : IDescriptor
45 {
46 private readonly ByteString descriptorData;
47 private readonly FileDescriptorProto proto;
48 private readonly IList<MessageDescriptor> messageTypes;
49 private readonly IList<EnumDescriptor> enumTypes;
50 private readonly IList<ServiceDescriptor> services;
51 private readonly IList<FileDescriptor> dependencies;
52 private readonly IList<FileDescriptor> publicDependencies;
53 private readonly DescriptorPool pool;
54
55 private FileDescriptor(ByteString descriptorData, FileDescriptorProto pr oto, FileDescriptor[] dependencies, DescriptorPool pool, bool allowUnknownDepend encies, GeneratedCodeInfo generatedCodeInfo)
56 {
57 this.descriptorData = descriptorData;
58 this.pool = pool;
59 this.proto = proto;
60 this.dependencies = new ReadOnlyCollection<FileDescriptor>((FileDesc riptor[]) dependencies.Clone());
61
62 publicDependencies = DeterminePublicDependencies(this, proto, depend encies, allowUnknownDependencies);
63
64 pool.AddPackage(Package, this);
65
66 messageTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.MessageTy pe,
67 (message, index ) =>
68 new MessageDesc riptor(message, this, null, index, generatedCodeInfo == null ? null : generatedC odeInfo.NestedTypes[index]));
69
70 enumTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.EnumType,
71 (enumType, index) =>
72 new EnumDescriptor (enumType, this, null, index, generatedCodeInfo == null ? null : generatedCodeIn fo.NestedEnums[index]));
73
74 services = DescriptorUtil.ConvertAndMakeReadOnly(proto.Service,
75 (service, index) =>
76 new ServiceDescript or(service, this, index));
77 }
78
79 /// <summary>
80 /// Computes the full name of a descriptor within this file, with an opt ional parent message.
81 /// </summary>
82 internal string ComputeFullName(MessageDescriptor parent, string name)
83 {
84 if (parent != null)
85 {
86 return parent.FullName + "." + name;
87 }
88 if (Package.Length > 0)
89 {
90 return Package + "." + name;
91 }
92 return name;
93 }
94
95 /// <summary>
96 /// Extracts public dependencies from direct dependencies. This is a sta tic method despite its
97 /// first parameter, as the value we're in the middle of constructing is only used for exceptions.
98 /// </summary>
99 private static IList<FileDescriptor> DeterminePublicDependencies(FileDes criptor @this, FileDescriptorProto proto, FileDescriptor[] dependencies, bool al lowUnknownDependencies)
100 {
101 var nameToFileMap = new Dictionary<string, FileDescriptor>();
102 foreach (var file in dependencies)
103 {
104 nameToFileMap[file.Name] = file;
105 }
106 var publicDependencies = new List<FileDescriptor>();
107 for (int i = 0; i < proto.PublicDependency.Count; i++)
108 {
109 int index = proto.PublicDependency[i];
110 if (index < 0 || index >= proto.Dependency.Count)
111 {
112 throw new DescriptorValidationException(@this, "Invalid publ ic dependency index.");
113 }
114 string name = proto.Dependency[index];
115 FileDescriptor file = nameToFileMap[name];
116 if (file == null)
117 {
118 if (!allowUnknownDependencies)
119 {
120 throw new DescriptorValidationException(@this, "Invalid public dependency: " + name);
121 }
122 // Ignore unknown dependencies.
123 }
124 else
125 {
126 publicDependencies.Add(file);
127 }
128 }
129 return new ReadOnlyCollection<FileDescriptor>(publicDependencies);
130 }
131
132 /// <value>
133 /// The descriptor in its protocol message representation.
134 /// </value>
135 internal FileDescriptorProto Proto
136 {
137 get { return proto; }
138 }
139
140 /// <value>
141 /// The file name.
142 /// </value>
143 public string Name
144 {
145 get { return proto.Name; }
146 }
147
148 /// <summary>
149 /// The package as declared in the .proto file. This may or may not
150 /// be equivalent to the .NET namespace of the generated classes.
151 /// </summary>
152 public string Package
153 {
154 get { return proto.Package; }
155 }
156
157 /// <value>
158 /// Unmodifiable list of top-level message types declared in this file.
159 /// </value>
160 public IList<MessageDescriptor> MessageTypes
161 {
162 get { return messageTypes; }
163 }
164
165 /// <value>
166 /// Unmodifiable list of top-level enum types declared in this file.
167 /// </value>
168 public IList<EnumDescriptor> EnumTypes
169 {
170 get { return enumTypes; }
171 }
172
173 /// <value>
174 /// Unmodifiable list of top-level services declared in this file.
175 /// </value>
176 public IList<ServiceDescriptor> Services
177 {
178 get { return services; }
179 }
180
181 /// <value>
182 /// Unmodifiable list of this file's dependencies (imports).
183 /// </value>
184 public IList<FileDescriptor> Dependencies
185 {
186 get { return dependencies; }
187 }
188
189 /// <value>
190 /// Unmodifiable list of this file's public dependencies (public imports ).
191 /// </value>
192 public IList<FileDescriptor> PublicDependencies
193 {
194 get { return publicDependencies; }
195 }
196
197 /// <value>
198 /// The original serialized binary form of this descriptor.
199 /// </value>
200 public ByteString SerializedData
201 {
202 get { return descriptorData; }
203 }
204
205 /// <value>
206 /// Implementation of IDescriptor.FullName - just returns the same as Na me.
207 /// </value>
208 string IDescriptor.FullName
209 {
210 get { return Name; }
211 }
212
213 /// <value>
214 /// Implementation of IDescriptor.File - just returns this descriptor.
215 /// </value>
216 FileDescriptor IDescriptor.File
217 {
218 get { return this; }
219 }
220
221 /// <value>
222 /// Pool containing symbol descriptors.
223 /// </value>
224 internal DescriptorPool DescriptorPool
225 {
226 get { return pool; }
227 }
228
229 /// <summary>
230 /// Finds a type (message, enum, service or extension) in the file by na me. Does not find nested types.
231 /// </summary>
232 /// <param name="name">The unqualified type name to look for.</param>
233 /// <typeparam name="T">The type of descriptor to look for</typeparam>
234 /// <returns>The type's descriptor, or null if not found.</returns>
235 public T FindTypeByName<T>(String name)
236 where T : class, IDescriptor
237 {
238 // Don't allow looking up nested types. This will make optimization
239 // easier later.
240 if (name.IndexOf('.') != -1)
241 {
242 return null;
243 }
244 if (Package.Length > 0)
245 {
246 name = Package + "." + name;
247 }
248 T result = pool.FindSymbol<T>(name);
249 if (result != null && result.File == this)
250 {
251 return result;
252 }
253 return null;
254 }
255
256 /// <summary>
257 /// Builds a FileDescriptor from its protocol buffer representation.
258 /// </summary>
259 /// <param name="descriptorData">The original serialized descriptor data .
260 /// We have only limited proto2 support, so serializing FileDescriptorPr oto
261 /// would not necessarily give us this.</param>
262 /// <param name="proto">The protocol message form of the FileDescriptor. </param>
263 /// <param name="dependencies">FileDescriptors corresponding to all of t he
264 /// file's dependencies, in the exact order listed in the .proto file. M ay be null,
265 /// in which case it is treated as an empty array.</param>
266 /// <param name="allowUnknownDependencies">Whether unknown dependencies are ignored (true) or cause an exception to be thrown (false).</param>
267 /// <param name="generatedCodeInfo">Reflection information, if any. May be null, specifically for non-generated code.</param>
268 /// <exception cref="DescriptorValidationException">If <paramref name="p roto"/> is not
269 /// a valid descriptor. This can occur for a number of reasons, such as a field
270 /// having an undefined type or because two messages were defined with t he same name.</exception>
271 private static FileDescriptor BuildFrom(ByteString descriptorData, FileD escriptorProto proto, FileDescriptor[] dependencies, bool allowUnknownDependenci es, GeneratedCodeInfo generatedCodeInfo)
272 {
273 // Building descriptors involves two steps: translating and linking.
274 // In the translation step (implemented by FileDescriptor's
275 // constructor), we build an object tree mirroring the
276 // FileDescriptorProto's tree and put all of the descriptors into th e
277 // DescriptorPool's lookup tables. In the linking step, we look up all
278 // type references in the DescriptorPool, so that, for example, a
279 // FieldDescriptor for an embedded message contains a pointer direct ly
280 // to the Descriptor for that message's type. We also detect undefi ned
281 // types in the linking step.
282 if (dependencies == null)
283 {
284 dependencies = new FileDescriptor[0];
285 }
286
287 DescriptorPool pool = new DescriptorPool(dependencies);
288 FileDescriptor result = new FileDescriptor(descriptorData, proto, de pendencies, pool, allowUnknownDependencies, generatedCodeInfo);
289
290 // Validate that the dependencies we've been passed (as FileDescript ors) are actually the ones we
291 // need.
292 if (dependencies.Length != proto.Dependency.Count)
293 {
294 throw new DescriptorValidationException(result,
295 "Dependencies passed to FileDescriptor.BuildFrom() don't match " +
296 "those listed in the Fil eDescriptorProto.");
297 }
298 for (int i = 0; i < proto.Dependency.Count; i++)
299 {
300 if (dependencies[i].Name != proto.Dependency[i])
301 {
302 throw new DescriptorValidationException(result,
303 "Dependencies passed to FileDescriptor.BuildFrom() don't match " +
304 "those listed in the FileDescriptorProto.");
305 }
306 }
307
308 result.CrossLink();
309 return result;
310 }
311
312 private void CrossLink()
313 {
314 foreach (MessageDescriptor message in messageTypes)
315 {
316 message.CrossLink();
317 }
318
319 foreach (ServiceDescriptor service in services)
320 {
321 service.CrossLink();
322 }
323 }
324
325 /// <summary>
326 /// Creates an instance for generated code.
327 /// </summary>
328 /// <remarks>
329 /// The <paramref name="generatedCodeInfo"/> parameter should be null fo r descriptors which don't correspond to
330 /// generated types. Otherwise, it should be a <see cref="GeneratedCodeI nfo"/> with nested types and nested
331 /// enums corresponding to the types and enums contained within the file descriptor.
332 /// </remarks>
333 public static FileDescriptor InternalBuildGeneratedFileFrom(byte[] descr iptorData,
334 FileDescript or[] dependencies,
335 GeneratedCod eInfo generatedCodeInfo)
336 {
337 FileDescriptorProto proto;
338 try
339 {
340 proto = FileDescriptorProto.Parser.ParseFrom(descriptorData);
341 }
342 catch (InvalidProtocolBufferException e)
343 {
344 throw new ArgumentException("Failed to parse protocol buffer des criptor for generated code.", e);
345 }
346
347
348
349 try
350 {
351 // When building descriptors for generated code, we allow unknow n
352 // dependencies by default.
353 return BuildFrom(ByteString.CopyFrom(descriptorData), proto, dep endencies, true, generatedCodeInfo);
354 }
355 catch (DescriptorValidationException e)
356 {
357 throw new ArgumentException("Invalid embedded descriptor for \"" + proto.Name + "\".", e);
358 }
359 }
360
361 /// <summary>
362 /// Returns a <see cref="System.String" /> that represents this instance .
363 /// </summary>
364 /// <returns>
365 /// A <see cref="System.String" /> that represents this instance.
366 /// </returns>
367 public override string ToString()
368 {
369 return "FileDescriptor for " + proto.Name;
370 }
371 }
372 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698