protobuf/src/google/protobuf/descriptor_database.h
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34 //
35 // Interface for manipulating databases of descriptors.
36 
37 #ifndef GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
38 #define GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
39 
40 #include <map>
41 #include <string>
42 #include <utility>
43 #include <vector>
44 #include <google/protobuf/stubs/common.h>
45 #include <google/protobuf/descriptor.h>
46 
47 #include <google/protobuf/port_def.inc>
48 
49 #ifdef SWIG
50 #error "You cannot SWIG proto headers"
51 #endif
52 
53 namespace google {
54 namespace protobuf {
55 
56 // Defined in this file.
57 class DescriptorDatabase;
59 class EncodedDescriptorDatabase;
62 
63 // Abstract interface for a database of descriptors.
64 //
65 // This is useful if you want to create a DescriptorPool which loads
66 // descriptors on-demand from some sort of large database. If the database
67 // is large, it may be inefficient to enumerate every .proto file inside it
68 // calling DescriptorPool::BuildFile() for each one. Instead, a DescriptorPool
69 // can be created which wraps a DescriptorDatabase and only builds particular
70 // descriptors when they are needed.
71 class PROTOBUF_EXPORT DescriptorDatabase {
72  public:
73  inline DescriptorDatabase() {}
74  virtual ~DescriptorDatabase();
75 
76  // Find a file by file name. Fills in in *output and returns true if found.
77  // Otherwise, returns false, leaving the contents of *output undefined.
78  virtual bool FindFileByName(const std::string& filename,
80 
81  // Find the file that declares the given fully-qualified symbol name.
82  // If found, fills in *output and returns true, otherwise returns false
83  // and leaves *output undefined.
84  virtual bool FindFileContainingSymbol(const std::string& symbol_name,
86 
87  // Find the file which defines an extension extending the given message type
88  // with the given field number. If found, fills in *output and returns true,
89  // otherwise returns false and leaves *output undefined. containing_type
90  // must be a fully-qualified type name.
91  virtual bool FindFileContainingExtension(const std::string& containing_type,
92  int field_number,
94 
95  // Finds the tag numbers used by all known extensions of
96  // extendee_type, and appends them to output in an undefined
97  // order. This method is best-effort: it's not guaranteed that the
98  // database will find all extensions, and it's not guaranteed that
99  // FindFileContainingExtension will return true on all of the found
100  // numbers. Returns true if the search was successful, otherwise
101  // returns false and leaves output unchanged.
102  //
103  // This method has a default implementation that always returns
104  // false.
105  virtual bool FindAllExtensionNumbers(const std::string& /* extendee_type */,
106  std::vector<int>* /* output */) {
107  return false;
108  }
109 
110 
111  // Finds the file names and appends them to the output in an
112  // undefined order. This method is best-effort: it's not guaranteed that the
113  // database will find all files. Returns true if the database supports
114  // searching all file names, otherwise returns false and leaves output
115  // unchanged.
116  //
117  // This method has a default implementation that always returns
118  // false.
119  virtual bool FindAllFileNames(std::vector<std::string>* /*output*/) {
120  return false;
121  }
122 
123  // Finds the package names and appends them to the output in an
124  // undefined order. This method is best-effort: it's not guaranteed that the
125  // database will find all packages. Returns true if the database supports
126  // searching all package names, otherwise returns false and leaves output
127  // unchanged.
128  bool FindAllPackageNames(std::vector<std::string>* output);
129 
130  // Finds the message names and appends them to the output in an
131  // undefined order. This method is best-effort: it's not guaranteed that the
132  // database will find all messages. Returns true if the database supports
133  // searching all message names, otherwise returns false and leaves output
134  // unchanged.
135  bool FindAllMessageNames(std::vector<std::string>* output);
136 
137  private:
139 };
140 
141 // A DescriptorDatabase into which you can insert files manually.
142 //
143 // FindFileContainingSymbol() is fully-implemented. When you add a file, its
144 // symbols will be indexed for this purpose. Note that the implementation
145 // may return false positives, but only if it isn't possible for the symbol
146 // to be defined in any other file. In particular, if a file defines a symbol
147 // "Foo", then searching for "Foo.[anything]" will match that file. This way,
148 // the database does not need to aggressively index all children of a symbol.
149 //
150 // FindFileContainingExtension() is mostly-implemented. It works if and only
151 // if the original FieldDescriptorProto defining the extension has a
152 // fully-qualified type name in its "extendee" field (i.e. starts with a '.').
153 // If the extendee is a relative name, SimpleDescriptorDatabase will not
154 // attempt to resolve the type, so it will not know what type the extension is
155 // extending. Therefore, calling FindFileContainingExtension() with the
156 // extension's containing type will never actually find that extension. Note
157 // that this is an unlikely problem, as all FileDescriptorProtos created by the
158 // protocol compiler (as well as ones created by calling
159 // FileDescriptor::CopyTo()) will always use fully-qualified names for all
160 // types. You only need to worry if you are constructing FileDescriptorProtos
161 // yourself, or are calling compiler::Parser directly.
162 class PROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
163  public:
165  ~SimpleDescriptorDatabase() override;
166 
167  // Adds the FileDescriptorProto to the database, making a copy. The object
168  // can be deleted after Add() returns. Returns false if the file conflicted
169  // with a file already in the database, in which case an error will have
170  // been written to GOOGLE_LOG(ERROR).
171  bool Add(const FileDescriptorProto& file);
172 
173  // Adds the FileDescriptorProto to the database and takes ownership of it.
174  bool AddAndOwn(const FileDescriptorProto* file);
175 
176  // implements DescriptorDatabase -----------------------------------
177  bool FindFileByName(const std::string& filename,
178  FileDescriptorProto* output) override;
179  bool FindFileContainingSymbol(const std::string& symbol_name,
180  FileDescriptorProto* output) override;
181  bool FindFileContainingExtension(const std::string& containing_type,
182  int field_number,
183  FileDescriptorProto* output) override;
184  bool FindAllExtensionNumbers(const std::string& extendee_type,
185  std::vector<int>* output) override;
186 
187  bool FindAllFileNames(std::vector<std::string>* output) override;
188 
189  private:
190  // An index mapping file names, symbol names, and extension numbers to
191  // some sort of values.
192  template <typename Value>
193  class DescriptorIndex {
194  public:
195  // Helpers to recursively add particular descriptors and all their contents
196  // to the index.
198  bool AddSymbol(const std::string& name, Value value);
199  bool AddNestedExtensions(const std::string& filename,
201  bool AddExtension(const std::string& filename,
203 
204  Value FindFile(const std::string& filename);
205  Value FindSymbol(const std::string& name);
206  Value FindExtension(const std::string& containing_type, int field_number);
207  bool FindAllExtensionNumbers(const std::string& containing_type,
208  std::vector<int>* output);
209  void FindAllFileNames(std::vector<std::string>* output);
210 
211  private:
212  std::map<std::string, Value> by_name_;
213  std::map<std::string, Value> by_symbol_;
214  std::map<std::pair<std::string, int>, Value> by_extension_;
215 
216  // Invariant: The by_symbol_ map does not contain any symbols which are
217  // prefixes of other symbols in the map. For example, "foo.bar" is a
218  // prefix of "foo.bar.baz" (but is not a prefix of "foo.barbaz").
219  //
220  // This invariant is important because it means that given a symbol name,
221  // we can find a key in the map which is a prefix of the symbol in O(lg n)
222  // time, and we know that there is at most one such key.
223  //
224  // The prefix lookup algorithm works like so:
225  // 1) Find the last key in the map which is less than or equal to the
226  // search key.
227  // 2) If the found key is a prefix of the search key, then return it.
228  // Otherwise, there is no match.
229  //
230  // I am sure this algorithm has been described elsewhere, but since I
231  // wasn't able to find it quickly I will instead prove that it works
232  // myself. The key to the algorithm is that if a match exists, step (1)
233  // will find it. Proof:
234  // 1) Define the "search key" to be the key we are looking for, the "found
235  // key" to be the key found in step (1), and the "match key" to be the
236  // key which actually matches the search key (i.e. the key we're trying
237  // to find).
238  // 2) The found key must be less than or equal to the search key by
239  // definition.
240  // 3) The match key must also be less than or equal to the search key
241  // (because it is a prefix).
242  // 4) The match key cannot be greater than the found key, because if it
243  // were, then step (1) of the algorithm would have returned the match
244  // key instead (since it finds the *greatest* key which is less than or
245  // equal to the search key).
246  // 5) Therefore, the found key must be between the match key and the search
247  // key, inclusive.
248  // 6) Since the search key must be a sub-symbol of the match key, if it is
249  // not equal to the match key, then search_key[match_key.size()] must
250  // be '.'.
251  // 7) Since '.' sorts before any other character that is valid in a symbol
252  // name, then if the found key is not equal to the match key, then
253  // found_key[match_key.size()] must also be '.', because any other value
254  // would make it sort after the search key.
255  // 8) Therefore, if the found key is not equal to the match key, then the
256  // found key must be a sub-symbol of the match key. However, this would
257  // contradict our map invariant which says that no symbol in the map is
258  // a sub-symbol of any other.
259  // 9) Therefore, the found key must match the match key.
260  //
261  // The above proof assumes the match key exists. In the case that the
262  // match key does not exist, then step (1) will return some other symbol.
263  // That symbol cannot be a super-symbol of the search key since if it were,
264  // then it would be a match, and we're assuming the match key doesn't exist.
265  // Therefore, step 2 will correctly return no match.
266  };
267 
268  DescriptorIndex<const FileDescriptorProto*> index_;
269  std::vector<std::unique_ptr<const FileDescriptorProto>> files_to_delete_;
270 
271  // If file is non-nullptr, copy it into *output and return true, otherwise
272  // return false.
273  bool MaybeCopy(const FileDescriptorProto* file, FileDescriptorProto* output);
274 
276 };
277 
278 // Very similar to SimpleDescriptorDatabase, but stores all the descriptors
279 // as raw bytes and generally tries to use as little memory as possible.
280 //
281 // The same caveats regarding FindFileContainingExtension() apply as with
282 // SimpleDescriptorDatabase.
283 class PROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
284  public:
285  EncodedDescriptorDatabase();
286  ~EncodedDescriptorDatabase() override;
287 
288  // Adds the FileDescriptorProto to the database. The descriptor is provided
289  // in encoded form. The database does not make a copy of the bytes, nor
290  // does it take ownership; it's up to the caller to make sure the bytes
291  // remain valid for the life of the database. Returns false and logs an error
292  // if the bytes are not a valid FileDescriptorProto or if the file conflicted
293  // with a file already in the database.
294  bool Add(const void* encoded_file_descriptor, int size);
295 
296  // Like Add(), but makes a copy of the data, so that the caller does not
297  // need to keep it around.
298  bool AddCopy(const void* encoded_file_descriptor, int size);
299 
300  // Like FindFileContainingSymbol but returns only the name of the file.
301  bool FindNameOfFileContainingSymbol(const std::string& symbol_name,
303 
304  // implements DescriptorDatabase -----------------------------------
305  bool FindFileByName(const std::string& filename,
306  FileDescriptorProto* output) override;
307  bool FindFileContainingSymbol(const std::string& symbol_name,
308  FileDescriptorProto* output) override;
309  bool FindFileContainingExtension(const std::string& containing_type,
310  int field_number,
311  FileDescriptorProto* output) override;
312  bool FindAllExtensionNumbers(const std::string& extendee_type,
313  std::vector<int>* output) override;
314  bool FindAllFileNames(std::vector<std::string>* output) override;
315 
316  private:
318  // Keep DescriptorIndex by pointer to hide the implementation to keep a
319  // cleaner header.
320  std::unique_ptr<DescriptorIndex> index_;
321  std::vector<void*> files_to_delete_;
322 
323  // If encoded_file.first is non-nullptr, parse the data into *output and
324  // return true, otherwise return false.
325  bool MaybeParse(std::pair<const void*, int> encoded_file,
327 
329 };
330 
331 // A DescriptorDatabase that fetches files from a given pool.
332 class PROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase {
333  public:
334  explicit DescriptorPoolDatabase(const DescriptorPool& pool);
335  ~DescriptorPoolDatabase() override;
336 
337  // implements DescriptorDatabase -----------------------------------
338  bool FindFileByName(const std::string& filename,
339  FileDescriptorProto* output) override;
340  bool FindFileContainingSymbol(const std::string& symbol_name,
341  FileDescriptorProto* output) override;
342  bool FindFileContainingExtension(const std::string& containing_type,
343  int field_number,
344  FileDescriptorProto* output) override;
345  bool FindAllExtensionNumbers(const std::string& extendee_type,
346  std::vector<int>* output) override;
347 
348  private:
349  const DescriptorPool& pool_;
351 };
352 
353 // A DescriptorDatabase that wraps two or more others. It first searches the
354 // first database and, if that fails, tries the second, and so on.
355 class PROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
356  public:
357  // Merge just two databases. The sources remain property of the caller.
359  DescriptorDatabase* source2);
360  // Merge more than two databases. The sources remain property of the caller.
361  // The vector may be deleted after the constructor returns but the
362  // DescriptorDatabases need to stick around.
363  explicit MergedDescriptorDatabase(
364  const std::vector<DescriptorDatabase*>& sources);
365  ~MergedDescriptorDatabase() override;
366 
367  // implements DescriptorDatabase -----------------------------------
368  bool FindFileByName(const std::string& filename,
369  FileDescriptorProto* output) override;
370  bool FindFileContainingSymbol(const std::string& symbol_name,
371  FileDescriptorProto* output) override;
372  bool FindFileContainingExtension(const std::string& containing_type,
373  int field_number,
374  FileDescriptorProto* output) override;
375  // Merges the results of calling all databases. Returns true iff any
376  // of the databases returned true.
377  bool FindAllExtensionNumbers(const std::string& extendee_type,
378  std::vector<int>* output) override;
379 
380 
381  private:
382  std::vector<DescriptorDatabase*> sources_;
384 };
385 
386 } // namespace protobuf
387 } // namespace google
388 
389 #include <google/protobuf/port_undef.inc>
390 
391 #endif // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
grpc::protobuf::DescriptorPoolDatabase
GRPC_CUSTOM_DESCRIPTORPOOLDATABASE DescriptorPoolDatabase
Definition: config_grpc_cli.h:56
filename
const char * filename
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:135
google::protobuf::value
const Descriptor::ReservedRange value
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1954
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/macros.h:40
google::protobuf::python::cdescriptor_pool::FindFileByName
static PyObject * FindFileByName(PyObject *self, PyObject *arg)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:258
google::protobuf::descriptor_unittest::AddExtension
FieldDescriptorProto * AddExtension(FileDescriptorProto *file, const std::string &extendee, const std::string &name, int number, FieldDescriptorProto::Label label, FieldDescriptorProto::Type type)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc:119
phone_pb2.message_type
message_type
Definition: phone_pb2.py:200
google::protobuf::DescriptorDatabase::FindAllFileNames
virtual bool FindAllFileNames(std::vector< std::string > *)
Definition: protobuf/src/google/protobuf/descriptor_database.h:119
grpc::protobuf::MergedDescriptorDatabase
GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE MergedDescriptorDatabase
Definition: config_grpc_cli.h:57
FieldDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1851
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
google::protobuf::compiler::annotation_test_util::AddFile
void AddFile(const std::string &filename, const std::string &data)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.cc:72
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc:181
setup.name
name
Definition: setup.py:542
google::protobuf::python::cdescriptor_pool::Add
static PyObject * Add(PyObject *self, PyObject *file_descriptor_proto)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:621
grpc::protobuf::SimpleDescriptorDatabase
GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE SimpleDescriptorDatabase
Definition: include/grpcpp/impl/codegen/config_protobuf.h:89
google::protobuf::python::cdescriptor_pool::FindFileContainingSymbol
static PyObject * FindFileContainingSymbol(PyObject *self, PyObject *arg)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:400
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
google::protobuf::DescriptorDatabase::FindAllExtensionNumbers
virtual bool FindAllExtensionNumbers(const std::string &, std::vector< int > *)
Definition: protobuf/src/google/protobuf/descriptor_database.h:105
google::protobuf::DescriptorPool
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1539
index_
size_t index_
Definition: xds_cluster_resolver.cc:169
grpc::protobuf::DescriptorDatabase
GRPC_CUSTOM_DESCRIPTORDATABASE DescriptorDatabase
Definition: include/grpcpp/impl/codegen/config_protobuf.h:83
phone_pb2.containing_type
containing_type
Definition: phone_pb2.py:199
FileDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:501
google::protobuf::DescriptorDatabase
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_database.h:71
gen_build_yaml.sources
sources
Definition: src/boringssl/gen_build_yaml.py:27
field
const FieldDescriptor * field
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc:2692
google::protobuf::EncodedDescriptorDatabase::DescriptorIndex
Definition: protobuf/src/google/protobuf/descriptor_database.cc:391
google::protobuf::EncodedDescriptorDatabase::index_
std::unique_ptr< DescriptorIndex > index_
Definition: protobuf/src/google/protobuf/descriptor_database.h:317
google::protobuf::DescriptorPoolDatabase
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_database.h:348
DescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1312
pool
InternalDescriptorPool * pool
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:807
google::protobuf::DescriptorDatabase::DescriptorDatabase
DescriptorDatabase()
Definition: protobuf/src/google/protobuf/descriptor_database.h:73
Value
struct Value Value
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:676
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
google::protobuf::EncodedDescriptorDatabase
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_database.h:301
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:14