• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Collections.Generic;
34 using System.Collections.ObjectModel;
35 using System.Linq;
36 
37 namespace Google.Protobuf.Reflection
38 {
39     /// <summary>
40     /// A collection to simplify retrieving the descriptors of extensions in a descriptor for a message
41     /// </summary>
42     public class ExtensionCollection
43     {
44         private IDictionary<MessageDescriptor, IList<FieldDescriptor>> extensionsByTypeInDeclarationOrder;
45         private IDictionary<MessageDescriptor, IList<FieldDescriptor>> extensionsByTypeInNumberOrder;
46 
ExtensionCollection(FileDescriptor file, Extension[] extensions)47         internal ExtensionCollection(FileDescriptor file, Extension[] extensions)
48         {
49             UnorderedExtensions = DescriptorUtil.ConvertAndMakeReadOnly(
50                 file.Proto.Extension,
51                 (extension, i) => new FieldDescriptor(extension, file, null, i, null, extensions?[i]));
52         }
53 
ExtensionCollection(MessageDescriptor message, Extension[] extensions)54         internal ExtensionCollection(MessageDescriptor message, Extension[] extensions)
55         {
56             UnorderedExtensions = DescriptorUtil.ConvertAndMakeReadOnly(
57                 message.Proto.Extension,
58                 (extension, i) => new FieldDescriptor(extension, message.File, message, i, null, extensions?[i]));
59         }
60 
61         /// <summary>
62         /// Returns a readonly list of all the extensions defined in this type in
63         /// the order they were defined in the source .proto file
64         /// </summary>
65         public IList<FieldDescriptor> UnorderedExtensions { get; }
66 
67         /// <summary>
68         /// Returns a readonly list of all the extensions define in this type that extend
69         /// the provided descriptor type in the order they were defined in the source .proto file
70         /// </summary>
GetExtensionsInDeclarationOrder(MessageDescriptor descriptor)71         public IList<FieldDescriptor> GetExtensionsInDeclarationOrder(MessageDescriptor descriptor)
72         {
73             return extensionsByTypeInDeclarationOrder[descriptor];
74         }
75 
76         /// <summary>
77         /// Returns a readonly list of all the extensions define in this type that extend
78         /// the provided descriptor type in accending field order
79         /// </summary>
GetExtensionsInNumberOrder(MessageDescriptor descriptor)80         public IList<FieldDescriptor> GetExtensionsInNumberOrder(MessageDescriptor descriptor)
81         {
82             return extensionsByTypeInNumberOrder[descriptor];
83         }
84 
CrossLink()85         internal void CrossLink()
86         {
87             Dictionary<MessageDescriptor, IList<FieldDescriptor>> declarationOrder = new Dictionary<MessageDescriptor, IList<FieldDescriptor>>();
88             foreach (FieldDescriptor descriptor in UnorderedExtensions)
89             {
90                 descriptor.CrossLink();
91 
92                 IList<FieldDescriptor> _;
93                 if (!declarationOrder.TryGetValue(descriptor.ExtendeeType, out _))
94                     declarationOrder.Add(descriptor.ExtendeeType, new List<FieldDescriptor>());
95 
96                 declarationOrder[descriptor.ExtendeeType].Add(descriptor);
97             }
98 
99             extensionsByTypeInDeclarationOrder = declarationOrder
100                 .ToDictionary(kvp => kvp.Key, kvp => (IList<FieldDescriptor>)new ReadOnlyCollection<FieldDescriptor>(kvp.Value));
101             extensionsByTypeInNumberOrder = declarationOrder
102                 .ToDictionary(kvp => kvp.Key, kvp => (IList<FieldDescriptor>)new ReadOnlyCollection<FieldDescriptor>(kvp.Value.OrderBy(field => field.FieldNumber).ToArray()));
103         }
104     }
105 }
106