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

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

Powered by Google App Engine
This is Rietveld 408576698