• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 // Copyright 2015 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 #endregion
16 
17 using System.Collections.Generic;
18 using Grpc.Core.Utils;
19 using Google.Protobuf.Reflection;
20 
21 namespace Grpc.Reflection
22 {
23     /// <summary>Registry of protobuf symbols</summary>
24     public class SymbolRegistry
25     {
26         private readonly Dictionary<string, FileDescriptor> filesByName;
27         private readonly Dictionary<string, FileDescriptor> filesBySymbol;
28 
SymbolRegistry(Dictionary<string, FileDescriptor> filesByName, Dictionary<string, FileDescriptor> filesBySymbol)29         private SymbolRegistry(Dictionary<string, FileDescriptor> filesByName, Dictionary<string, FileDescriptor> filesBySymbol)
30         {
31             this.filesByName = new Dictionary<string, FileDescriptor>(filesByName);
32             this.filesBySymbol = new Dictionary<string, FileDescriptor>(filesBySymbol);
33         }
34 
35         /// <summary>
36         /// Creates a symbol registry from the specified set of file descriptors.
37         /// </summary>
38         /// <param name="fileDescriptors">The set of files to include in the registry. Must not contain null values.</param>
39         /// <returns>A symbol registry for the given files.</returns>
FromFiles(IEnumerable<FileDescriptor> fileDescriptors)40         public static SymbolRegistry FromFiles(IEnumerable<FileDescriptor> fileDescriptors)
41         {
42             GrpcPreconditions.CheckNotNull(fileDescriptors);
43             var builder = new Builder();
44             foreach (var file in fileDescriptors)
45             {
46                 builder.AddFile(file);
47             }
48             return builder.Build();
49         }
50 
51         /// <summary>
52         /// Gets file descriptor for given file name (including package path). Returns <c>null</c> if not found.
53         /// </summary>
FileByName(string filename)54         public FileDescriptor FileByName(string filename)
55         {
56             FileDescriptor file;
57             filesByName.TryGetValue(filename, out file);
58             return file;
59         }
60 
61         /// <summary>
62         /// Gets file descriptor that contains definition of given symbol full name (including package path). Returns <c>null</c> if not found.
63         /// </summary>
FileContainingSymbol(string symbol)64         public FileDescriptor FileContainingSymbol(string symbol)
65         {
66             FileDescriptor file;
67             filesBySymbol.TryGetValue(symbol, out file);
68             return file;
69         }
70 
71         /// <summary>
72         /// Builder class which isn't exposed, but acts as a convenient alternative to passing round two dictionaries in recursive calls.
73         /// </summary>
74         private class Builder
75         {
76             private readonly Dictionary<string, FileDescriptor> filesByName;
77             private readonly Dictionary<string, FileDescriptor> filesBySymbol;
78 
79 
Builder()80             internal Builder()
81             {
82                 filesByName = new Dictionary<string, FileDescriptor>();
83                 filesBySymbol = new Dictionary<string, FileDescriptor>();
84             }
85 
AddFile(FileDescriptor fileDescriptor)86             internal void AddFile(FileDescriptor fileDescriptor)
87             {
88                 if (filesByName.ContainsKey(fileDescriptor.Name))
89                 {
90                     return;
91                 }
92                 filesByName.Add(fileDescriptor.Name, fileDescriptor);
93 
94                 foreach (var dependency in fileDescriptor.Dependencies)
95                 {
96                     AddFile(dependency);
97                 }
98                 foreach (var enumeration in fileDescriptor.EnumTypes)
99                 {
100                     AddEnum(enumeration);
101                 }
102                 foreach (var message in fileDescriptor.MessageTypes)
103                 {
104                     AddMessage(message);
105                 }
106                 foreach (var service in fileDescriptor.Services)
107                 {
108                     AddService(service);
109                 }
110             }
111 
AddEnum(EnumDescriptor enumDescriptor)112             private void AddEnum(EnumDescriptor enumDescriptor)
113             {
114                 filesBySymbol[enumDescriptor.FullName] = enumDescriptor.File;
115             }
116 
AddMessage(MessageDescriptor messageDescriptor)117             private void AddMessage(MessageDescriptor messageDescriptor)
118             {
119                 foreach (var nestedEnum in messageDescriptor.EnumTypes)
120                 {
121                     AddEnum(nestedEnum);
122                 }
123                 foreach (var nestedType in messageDescriptor.NestedTypes)
124                 {
125                     AddMessage(nestedType);
126                 }
127                 filesBySymbol[messageDescriptor.FullName] = messageDescriptor.File;
128             }
129 
AddService(ServiceDescriptor serviceDescriptor)130             private void AddService(ServiceDescriptor serviceDescriptor)
131             {
132                 foreach (var method in serviceDescriptor.Methods)
133                 {
134                     filesBySymbol[method.FullName] = method.File;
135                 }
136                 filesBySymbol[serviceDescriptor.FullName] = serviceDescriptor.File;
137             }
138 
Build()139             internal SymbolRegistry Build()
140             {
141                 return new SymbolRegistry(filesByName, filesBySymbol);
142             }
143         }
144     }
145 }
146