descriptor_pool.cc
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 // Implements the DescriptorPool, which collects all descriptors.
32 
33 #include <unordered_map>
34 
35 #include <Python.h>
36 
45 
46 #if PY_MAJOR_VERSION >= 3
47  #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
48  #if PY_VERSION_HEX < 0x03030000
49  #error "Python 3.0 - 3.2 are not supported."
50  #endif
51 #define PyString_AsStringAndSize(ob, charpp, sizep) \
52  (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \
53  PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
54  ? -1 \
55  : 0) \
56  : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
57 #endif
58 
59 namespace google {
60 namespace protobuf {
61 namespace python {
62 
63 // A map to cache Python Pools per C++ pointer.
64 // Pointers are not owned here, and belong to the PyDescriptorPool.
65 static std::unordered_map<const DescriptorPool*, PyDescriptorPool*>*
67 
68 namespace cdescriptor_pool {
69 
70 // Collects errors that occur during proto file building to allow them to be
71 // propagated in the python exception instead of only living in ERROR logs.
72 class BuildFileErrorCollector : public DescriptorPool::ErrorCollector {
73  public:
75 
76  void AddError(const string& filename, const string& element_name,
78  const string& message) override {
79  // Replicates the logging behavior that happens in the C++ implementation
80  // when an error collector is not passed in.
81  if (!had_errors_) {
82  error_message +=
83  ("Invalid proto descriptor for file \"" + filename + "\":\n");
84  had_errors_ = true;
85  }
86  // As this only happens on failure and will result in the program not
87  // running at all, no effort is made to optimize this string manipulation.
88  error_message += (" " + element_name + ": " + message + "\n");
89  }
90 
91  void Clear() {
92  had_errors_ = false;
93  error_message = "";
94  }
95 
96  string error_message;
97 
98  private:
100 };
101 
102 // Create a Python DescriptorPool object, but does not fill the "pool"
103 // attribute.
105  PyDescriptorPool* cpool = PyObject_GC_New(
107  if (cpool == NULL) {
108  return NULL;
109  }
110 
111  cpool->error_collector = nullptr;
112  cpool->underlay = NULL;
113  cpool->database = NULL;
114 
115  cpool->descriptor_options = new std::unordered_map<const void*, PyObject*>();
116 
118  &PyMessageFactory_Type, cpool);
119  if (cpool->py_message_factory == NULL) {
120  Py_DECREF(cpool);
121  return NULL;
122  }
123 
124  PyObject_GC_Track(cpool);
125 
126  return cpool;
127 }
128 
129 // Create a Python DescriptorPool, using the given pool as an underlay:
130 // new messages will be added to a custom pool, not to the underlay.
131 //
132 // Ownership of the underlay is not transferred, its pointer should
133 // stay alive.
135  const DescriptorPool* underlay) {
137  if (cpool == NULL) {
138  return NULL;
139  }
140  cpool->pool = new DescriptorPool(underlay);
141  cpool->underlay = underlay;
142 
143  if (!descriptor_pool_map->insert(
144  std::make_pair(cpool->pool, cpool)).second) {
145  // Should never happen -- would indicate an internal error / bug.
146  PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered");
147  return NULL;
148  }
149 
150  return cpool;
151 }
152 
156  if (cpool == NULL) {
157  return NULL;
158  }
159  if (database != NULL) {
161  cpool->pool = new DescriptorPool(database, cpool->error_collector);
162  cpool->database = database;
163  } else {
164  cpool->pool = new DescriptorPool();
165  }
166 
167  if (!descriptor_pool_map->insert(std::make_pair(cpool->pool, cpool)).second) {
168  // Should never happen -- would indicate an internal error / bug.
169  PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered");
170  return NULL;
171  }
172 
173  return cpool;
174 }
175 
176 // The public DescriptorPool constructor.
177 static PyObject* New(PyTypeObject* type,
178  PyObject* args, PyObject* kwargs) {
179  static char* kwlist[] = {"descriptor_db", 0};
180  PyObject* py_database = NULL;
181  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &py_database)) {
182  return NULL;
183  }
185  if (py_database && py_database != Py_None) {
186  database = new PyDescriptorDatabase(py_database);
187  }
188  return reinterpret_cast<PyObject*>(
190 }
191 
192 static void Dealloc(PyObject* pself) {
193  PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself);
194  descriptor_pool_map->erase(self->pool);
195  Py_CLEAR(self->py_message_factory);
196  for (std::unordered_map<const void*, PyObject*>::iterator it =
197  self->descriptor_options->begin();
198  it != self->descriptor_options->end(); ++it) {
199  Py_DECREF(it->second);
200  }
201  delete self->descriptor_options;
202  delete self->database;
203  delete self->pool;
204  delete self->error_collector;
205  Py_TYPE(self)->tp_free(pself);
206 }
207 
208 static int GcTraverse(PyObject* pself, visitproc visit, void* arg) {
209  PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself);
210  Py_VISIT(self->py_message_factory);
211  return 0;
212 }
213 
214 static int GcClear(PyObject* pself) {
215  PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself);
216  Py_CLEAR(self->py_message_factory);
217  return 0;
218 }
219 
220 PyObject* SetErrorFromCollector(DescriptorPool::ErrorCollector* self,
221  char* name, char* error_type) {
222  BuildFileErrorCollector* error_collector =
223  reinterpret_cast<BuildFileErrorCollector*>(self);
224  if (error_collector && !error_collector->error_message.empty()) {
225  PyErr_Format(PyExc_KeyError, "Couldn't build file for %s %.200s\n%s",
226  error_type, name, error_collector->error_message.c_str());
227  error_collector->Clear();
228  return NULL;
229  }
230  PyErr_Format(PyExc_KeyError, "Couldn't find %s %.200s", error_type, name);
231  return NULL;
232 }
233 
234 static PyObject* FindMessageByName(PyObject* self, PyObject* arg) {
235  Py_ssize_t name_size;
236  char* name;
237  if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
238  return NULL;
239  }
240 
241  const Descriptor* message_descriptor =
242  reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMessageTypeByName(
243  string(name, name_size));
244 
245  if (message_descriptor == NULL) {
246  return SetErrorFromCollector(
247  reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
248  "message");
249  }
250 
251 
252  return PyMessageDescriptor_FromDescriptor(message_descriptor);
253 }
254 
255 
256 
257 
258 static PyObject* FindFileByName(PyObject* self, PyObject* arg) {
259  Py_ssize_t name_size;
260  char* name;
261  if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
262  return NULL;
263  }
264 
265  PyDescriptorPool* py_pool = reinterpret_cast<PyDescriptorPool*>(self);
266  const FileDescriptor* file_descriptor =
267  py_pool->pool->FindFileByName(string(name, name_size));
268 
269  if (file_descriptor == NULL) {
270  return SetErrorFromCollector(py_pool->error_collector, name, "file");
271  }
272  return PyFileDescriptor_FromDescriptor(file_descriptor);
273 }
274 
275 PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* arg) {
276  Py_ssize_t name_size;
277  char* name;
278  if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
279  return NULL;
280  }
281 
282  const FieldDescriptor* field_descriptor =
283  self->pool->FindFieldByName(string(name, name_size));
284  if (field_descriptor == NULL) {
285  return SetErrorFromCollector(self->error_collector, name, "field");
286  }
287 
288 
289  return PyFieldDescriptor_FromDescriptor(field_descriptor);
290 }
291 
292 static PyObject* FindFieldByNameMethod(PyObject* self, PyObject* arg) {
293  return FindFieldByName(reinterpret_cast<PyDescriptorPool*>(self), arg);
294 }
295 
296 PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) {
297  Py_ssize_t name_size;
298  char* name;
299  if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
300  return NULL;
301  }
302 
303  const FieldDescriptor* field_descriptor =
304  self->pool->FindExtensionByName(string(name, name_size));
305  if (field_descriptor == NULL) {
306  return SetErrorFromCollector(self->error_collector, name,
307  "extension field");
308  }
309 
310 
311  return PyFieldDescriptor_FromDescriptor(field_descriptor);
312 }
313 
314 static PyObject* FindExtensionByNameMethod(PyObject* self, PyObject* arg) {
315  return FindExtensionByName(reinterpret_cast<PyDescriptorPool*>(self), arg);
316 }
317 
318 PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) {
319  Py_ssize_t name_size;
320  char* name;
321  if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
322  return NULL;
323  }
324 
326  self->pool->FindEnumTypeByName(string(name, name_size));
327  if (enum_descriptor == NULL) {
328  return SetErrorFromCollector(self->error_collector, name, "enum");
329  }
330 
331 
333 }
334 
335 static PyObject* FindEnumTypeByNameMethod(PyObject* self, PyObject* arg) {
336  return FindEnumTypeByName(reinterpret_cast<PyDescriptorPool*>(self), arg);
337 }
338 
339 PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) {
340  Py_ssize_t name_size;
341  char* name;
342  if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
343  return NULL;
344  }
345 
346  const OneofDescriptor* oneof_descriptor =
347  self->pool->FindOneofByName(string(name, name_size));
348  if (oneof_descriptor == NULL) {
349  return SetErrorFromCollector(self->error_collector, name, "oneof");
350  }
351 
352 
353  return PyOneofDescriptor_FromDescriptor(oneof_descriptor);
354 }
355 
356 static PyObject* FindOneofByNameMethod(PyObject* self, PyObject* arg) {
357  return FindOneofByName(reinterpret_cast<PyDescriptorPool*>(self), arg);
358 }
359 
360 static PyObject* FindServiceByName(PyObject* self, PyObject* arg) {
361  Py_ssize_t name_size;
362  char* name;
363  if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
364  return NULL;
365  }
366 
367  const ServiceDescriptor* service_descriptor =
368  reinterpret_cast<PyDescriptorPool*>(self)->pool->FindServiceByName(
369  string(name, name_size));
370  if (service_descriptor == NULL) {
371  return SetErrorFromCollector(
372  reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
373  "service");
374  }
375 
376 
377  return PyServiceDescriptor_FromDescriptor(service_descriptor);
378 }
379 
380 static PyObject* FindMethodByName(PyObject* self, PyObject* arg) {
381  Py_ssize_t name_size;
382  char* name;
383  if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
384  return NULL;
385  }
386 
387  const MethodDescriptor* method_descriptor =
388  reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMethodByName(
389  string(name, name_size));
390  if (method_descriptor == NULL) {
391  return SetErrorFromCollector(
392  reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
393  "method");
394  }
395 
396 
397  return PyMethodDescriptor_FromDescriptor(method_descriptor);
398 }
399 
400 static PyObject* FindFileContainingSymbol(PyObject* self, PyObject* arg) {
401  Py_ssize_t name_size;
402  char* name;
403  if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
404  return NULL;
405  }
406 
407  const FileDescriptor* file_descriptor =
408  reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileContainingSymbol(
409  string(name, name_size));
410  if (file_descriptor == NULL) {
411  return SetErrorFromCollector(
412  reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
413  "symbol");
414  }
415 
416 
417  return PyFileDescriptor_FromDescriptor(file_descriptor);
418 }
419 
420 static PyObject* FindExtensionByNumber(PyObject* self, PyObject* args) {
421  PyObject* message_descriptor;
422  int number;
423  if (!PyArg_ParseTuple(args, "Oi", &message_descriptor, &number)) {
424  return NULL;
425  }
427  message_descriptor);
428  if (descriptor == NULL) {
429  return NULL;
430  }
431 
432  const FieldDescriptor* extension_descriptor =
433  reinterpret_cast<PyDescriptorPool*>(self)->pool->FindExtensionByNumber(
434  descriptor, number);
435  if (extension_descriptor == NULL) {
436  BuildFileErrorCollector* error_collector =
437  reinterpret_cast<BuildFileErrorCollector*>(
438  reinterpret_cast<PyDescriptorPool*>(self)->error_collector);
439  if (error_collector && !error_collector->error_message.empty()) {
440  PyErr_Format(PyExc_KeyError, "Couldn't build file for Extension %.d\n%s",
441  number, error_collector->error_message.c_str());
442  error_collector->Clear();
443  return NULL;
444  }
445  PyErr_Format(PyExc_KeyError, "Couldn't find Extension %d", number);
446  return NULL;
447  }
448 
449 
450  return PyFieldDescriptor_FromDescriptor(extension_descriptor);
451 }
452 
453 static PyObject* FindAllExtensions(PyObject* self, PyObject* arg) {
455  if (descriptor == NULL) {
456  return NULL;
457  }
458 
459  std::vector<const FieldDescriptor*> extensions;
460  reinterpret_cast<PyDescriptorPool*>(self)->pool->FindAllExtensions(
461  descriptor, &extensions);
462 
463  ScopedPyObjectPtr result(PyList_New(extensions.size()));
464  if (result == NULL) {
465  return NULL;
466  }
467  for (int i = 0; i < extensions.size(); i++) {
468  PyObject* extension = PyFieldDescriptor_FromDescriptor(extensions[i]);
469  if (extension == NULL) {
470  return NULL;
471  }
472  PyList_SET_ITEM(result.get(), i, extension); // Steals the reference.
473  }
474  return result.release();
475 }
476 
477 // These functions should not exist -- the only valid way to create
478 // descriptors is to call Add() or AddSerializedFile().
479 // But these AddDescriptor() functions were created in Python and some people
480 // call them, so we support them for now for compatibility.
481 // However we do check that the existing descriptor already exists in the pool,
482 // which appears to always be true for existing calls -- but then why do people
483 // call a function that will just be a no-op?
484 // TODO(amauryfa): Need to investigate further.
485 
486 static PyObject* AddFileDescriptor(PyObject* self, PyObject* descriptor) {
487  const FileDescriptor* file_descriptor =
489  if (!file_descriptor) {
490  return NULL;
491  }
492  if (file_descriptor !=
493  reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileByName(
494  file_descriptor->name())) {
495  PyErr_Format(PyExc_ValueError,
496  "The file descriptor %s does not belong to this pool",
497  file_descriptor->name().c_str());
498  return NULL;
499  }
500  Py_RETURN_NONE;
501 }
502 
503 static PyObject* AddDescriptor(PyObject* self, PyObject* descriptor) {
504  const Descriptor* message_descriptor =
506  if (!message_descriptor) {
507  return NULL;
508  }
509  if (message_descriptor !=
510  reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMessageTypeByName(
511  message_descriptor->full_name())) {
512  PyErr_Format(PyExc_ValueError,
513  "The message descriptor %s does not belong to this pool",
514  message_descriptor->full_name().c_str());
515  return NULL;
516  }
517  Py_RETURN_NONE;
518 }
519 
520 static PyObject* AddEnumDescriptor(PyObject* self, PyObject* descriptor) {
523  if (!enum_descriptor) {
524  return NULL;
525  }
526  if (enum_descriptor !=
527  reinterpret_cast<PyDescriptorPool*>(self)->pool->FindEnumTypeByName(
528  enum_descriptor->full_name())) {
529  PyErr_Format(PyExc_ValueError,
530  "The enum descriptor %s does not belong to this pool",
531  enum_descriptor->full_name().c_str());
532  return NULL;
533  }
534  Py_RETURN_NONE;
535 }
536 
537 static PyObject* AddExtensionDescriptor(PyObject* self, PyObject* descriptor) {
538  const FieldDescriptor* extension_descriptor =
540  if (!extension_descriptor) {
541  return NULL;
542  }
543  if (extension_descriptor !=
544  reinterpret_cast<PyDescriptorPool*>(self)->pool->FindExtensionByName(
545  extension_descriptor->full_name())) {
546  PyErr_Format(PyExc_ValueError,
547  "The extension descriptor %s does not belong to this pool",
548  extension_descriptor->full_name().c_str());
549  return NULL;
550  }
551  Py_RETURN_NONE;
552 }
553 
554 static PyObject* AddServiceDescriptor(PyObject* self, PyObject* descriptor) {
555  const ServiceDescriptor* service_descriptor =
557  if (!service_descriptor) {
558  return NULL;
559  }
560  if (service_descriptor !=
561  reinterpret_cast<PyDescriptorPool*>(self)->pool->FindServiceByName(
562  service_descriptor->full_name())) {
563  PyErr_Format(PyExc_ValueError,
564  "The service descriptor %s does not belong to this pool",
565  service_descriptor->full_name().c_str());
566  return NULL;
567  }
568  Py_RETURN_NONE;
569 }
570 
571 // The code below loads new Descriptors from a serialized FileDescriptorProto.
572 static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) {
573  PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself);
574  char* message_type;
575  Py_ssize_t message_len;
576 
577  if (self->database != NULL) {
578  PyErr_SetString(
579  PyExc_ValueError,
580  "Cannot call Add on a DescriptorPool that uses a DescriptorDatabase. "
581  "Add your file to the underlying database.");
582  return NULL;
583  }
584 
585  if (PyBytes_AsStringAndSize(serialized_pb, &message_type, &message_len) < 0) {
586  return NULL;
587  }
588 
589  FileDescriptorProto file_proto;
590  if (!file_proto.ParseFromArray(message_type, message_len)) {
591  PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!");
592  return NULL;
593  }
594 
595  // If the file was already part of a C++ library, all its descriptors are in
596  // the underlying pool. No need to do anything else.
597  const FileDescriptor* generated_file = NULL;
598  if (self->underlay) {
599  generated_file = self->underlay->FindFileByName(file_proto.name());
600  }
601  if (generated_file != NULL) {
603  generated_file, serialized_pb);
604  }
605 
606  BuildFileErrorCollector error_collector;
607  const FileDescriptor* descriptor =
608  self->pool->BuildFileCollectingErrors(file_proto,
609  &error_collector);
610  if (descriptor == NULL) {
611  PyErr_Format(PyExc_TypeError,
612  "Couldn't build proto file into descriptor pool!\n%s",
613  error_collector.error_message.c_str());
614  return NULL;
615  }
616 
618  descriptor, serialized_pb);
619 }
620 
621 static PyObject* Add(PyObject* self, PyObject* file_descriptor_proto) {
622  ScopedPyObjectPtr serialized_pb(
623  PyObject_CallMethod(file_descriptor_proto, "SerializeToString", NULL));
624  if (serialized_pb == NULL) {
625  return NULL;
626  }
627  return AddSerializedFile(self, serialized_pb.get());
628 }
629 
630 static PyMethodDef Methods[] = {
631  { "Add", Add, METH_O,
632  "Adds the FileDescriptorProto and its types to this pool." },
633  { "AddSerializedFile", AddSerializedFile, METH_O,
634  "Adds a serialized FileDescriptorProto to this pool." },
635 
636  // TODO(amauryfa): Understand why the Python implementation differs from
637  // this one, ask users to use another API and deprecate these functions.
638  { "AddFileDescriptor", AddFileDescriptor, METH_O,
639  "No-op. Add() must have been called before." },
640  { "AddDescriptor", AddDescriptor, METH_O,
641  "No-op. Add() must have been called before." },
642  { "AddEnumDescriptor", AddEnumDescriptor, METH_O,
643  "No-op. Add() must have been called before." },
644  { "AddExtensionDescriptor", AddExtensionDescriptor, METH_O,
645  "No-op. Add() must have been called before." },
646  { "AddServiceDescriptor", AddServiceDescriptor, METH_O,
647  "No-op. Add() must have been called before." },
648 
649  { "FindFileByName", FindFileByName, METH_O,
650  "Searches for a file descriptor by its .proto name." },
651  { "FindMessageTypeByName", FindMessageByName, METH_O,
652  "Searches for a message descriptor by full name." },
653  { "FindFieldByName", FindFieldByNameMethod, METH_O,
654  "Searches for a field descriptor by full name." },
655  { "FindExtensionByName", FindExtensionByNameMethod, METH_O,
656  "Searches for extension descriptor by full name." },
657  { "FindEnumTypeByName", FindEnumTypeByNameMethod, METH_O,
658  "Searches for enum type descriptor by full name." },
659  { "FindOneofByName", FindOneofByNameMethod, METH_O,
660  "Searches for oneof descriptor by full name." },
661  { "FindServiceByName", FindServiceByName, METH_O,
662  "Searches for service descriptor by full name." },
663  { "FindMethodByName", FindMethodByName, METH_O,
664  "Searches for method descriptor by full name." },
665 
666  { "FindFileContainingSymbol", FindFileContainingSymbol, METH_O,
667  "Gets the FileDescriptor containing the specified symbol." },
668  { "FindExtensionByNumber", FindExtensionByNumber, METH_VARARGS,
669  "Gets the extension descriptor for the given number." },
670  { "FindAllExtensions", FindAllExtensions, METH_O,
671  "Gets all known extensions of the given message descriptor." },
672  {NULL}
673 };
674 
675 } // namespace cdescriptor_pool
676 
677 PyTypeObject PyDescriptorPool_Type = {
678  PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
679  ".DescriptorPool", // tp_name
680  sizeof(PyDescriptorPool), // tp_basicsize
681  0, // tp_itemsize
682  cdescriptor_pool::Dealloc, // tp_dealloc
683  0, // tp_print
684  0, // tp_getattr
685  0, // tp_setattr
686  0, // tp_compare
687  0, // tp_repr
688  0, // tp_as_number
689  0, // tp_as_sequence
690  0, // tp_as_mapping
691  0, // tp_hash
692  0, // tp_call
693  0, // tp_str
694  0, // tp_getattro
695  0, // tp_setattro
696  0, // tp_as_buffer
697  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
698  "A Descriptor Pool", // tp_doc
699  cdescriptor_pool::GcTraverse, // tp_traverse
700  cdescriptor_pool::GcClear, // tp_clear
701  0, // tp_richcompare
702  0, // tp_weaklistoffset
703  0, // tp_iter
704  0, // tp_iternext
705  cdescriptor_pool::Methods, // tp_methods
706  0, // tp_members
707  0, // tp_getset
708  0, // tp_base
709  0, // tp_dict
710  0, // tp_descr_get
711  0, // tp_descr_set
712  0, // tp_dictoffset
713  0, // tp_init
714  0, // tp_alloc
715  cdescriptor_pool::New, // tp_new
716  PyObject_GC_Del, // tp_free
717 };
718 
719 // This is the DescriptorPool which contains all the definitions from the
720 // generated _pb2.py modules.
722 
724  if (PyType_Ready(&PyDescriptorPool_Type) < 0)
725  return false;
726 
727  // The Pool of messages declared in Python libraries.
728  // generated_pool() contains all messages already linked in C++ libraries, and
729  // is used as underlay.
731  new std::unordered_map<const DescriptorPool*, PyDescriptorPool*>;
734  if (python_generated_pool == NULL) {
735  delete descriptor_pool_map;
736  return false;
737  }
738 
739  // Register this pool to be found for C++-generated descriptors.
740  descriptor_pool_map->insert(
741  std::make_pair(DescriptorPool::generated_pool(),
743 
744  return true;
745 }
746 
747 // The default DescriptorPool used everywhere in this module.
748 // Today it's the python_generated_pool.
749 // TODO(amauryfa): Remove all usages of this function: the pool should be
750 // derived from the context.
752  return python_generated_pool;
753 }
754 
756  // Fast path for standard descriptors.
757  if (pool == python_generated_pool->pool ||
759  return python_generated_pool;
760  }
761  std::unordered_map<const DescriptorPool*, PyDescriptorPool*>::iterator it =
762  descriptor_pool_map->find(pool);
763  if (it == descriptor_pool_map->end()) {
764  PyErr_SetString(PyExc_KeyError, "Unknown descriptor pool");
765  return NULL;
766  }
767  return it->second;
768 }
769 
770 } // namespace python
771 } // namespace protobuf
772 } // namespace google
google::protobuf::Descriptor::full_name
const std::string & full_name() const
FileDescriptorProto::name
const std::string & name() const
Definition: descriptor.pb.h:6576
google::protobuf::python::cdescriptor_pool::FindEnumTypeByName
PyObject * FindEnumTypeByName(PyDescriptorPool *self, PyObject *arg)
Definition: descriptor_pool.cc:318
google::protobuf::python::cdescriptor_pool::AddEnumDescriptor
static PyObject * AddEnumDescriptor(PyObject *self, PyObject *descriptor)
Definition: descriptor_pool.cc:520
google::protobuf::DescriptorPool::FindFileByName
const FileDescriptor * FindFileByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1389
google::protobuf::python::cdescriptor_pool::_CreateDescriptorPool
static PyDescriptorPool * _CreateDescriptorPool()
Definition: descriptor_pool.cc:104
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
google::protobuf::python::cdescriptor_pool::FindOneofByName
PyObject * FindOneofByName(PyDescriptorPool *self, PyObject *arg)
Definition: descriptor_pool.cc:339
google::protobuf::FieldDescriptor
Definition: src/google/protobuf/descriptor.h:515
google::protobuf::python::cdescriptor_pool::FindMessageByName
static PyObject * FindMessageByName(PyObject *self, PyObject *arg)
Definition: descriptor_pool.cc:234
google::protobuf::extension
const Descriptor::ReservedRange const EnumValueDescriptor const MethodDescriptor extension
Definition: src/google/protobuf/descriptor.h:2001
NULL
NULL
Definition: test_security_zap.cpp:405
google::protobuf::python::cdescriptor_pool::FindFileByName
static PyObject * FindFileByName(PyObject *self, PyObject *arg)
Definition: descriptor_pool.cc:258
message_factory.h
google::protobuf::FieldDescriptor::full_name
const std::string & full_name() const
google::protobuf::python::PyServiceDescriptor_FromDescriptor
PyObject * PyServiceDescriptor_FromDescriptor(const ServiceDescriptor *service_descriptor)
Definition: python/google/protobuf/pyext/descriptor.cc:1765
google::protobuf::python::GetDefaultDescriptorPool
PyDescriptorPool * GetDefaultDescriptorPool()
Definition: descriptor_pool.cc:751
google::protobuf::python::ScopedPythonPtr::get
PyObjectStruct * get() const
Definition: scoped_pyobject_ptr.h:76
google::protobuf::ServiceDescriptor::full_name
const std::string & full_name() const
self
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern self
Definition: php/ext/google/protobuf/map.c:543
google::protobuf::python::PyFieldDescriptor_AsDescriptor
const FieldDescriptor * PyFieldDescriptor_AsDescriptor(PyObject *obj)
Definition: python/google/protobuf/pyext/descriptor.cc:1043
google::protobuf::python::PyMethodDescriptor_FromDescriptor
PyObject * PyMethodDescriptor_FromDescriptor(const MethodDescriptor *method_descriptor)
Definition: python/google/protobuf/pyext/descriptor.cc:1877
google::protobuf::python::PyDescriptorPool
struct google::protobuf::python::PyDescriptorPool PyDescriptorPool
google::protobuf::python::cdescriptor_pool::FindEnumTypeByNameMethod
static PyObject * FindEnumTypeByNameMethod(PyObject *self, PyObject *arg)
Definition: descriptor_pool.cc:335
google::protobuf::python::cdescriptor_pool::AddServiceDescriptor
static PyObject * AddServiceDescriptor(PyObject *self, PyObject *descriptor)
Definition: descriptor_pool.cc:554
google::protobuf::OneofDescriptor
Definition: src/google/protobuf/descriptor.h:843
google::protobuf::python::cdescriptor_pool::Add
static PyObject * Add(PyObject *self, PyObject *file_descriptor_proto)
Definition: descriptor_pool.cc:621
google::protobuf::python::cdescriptor_pool::PyDescriptorPool_NewWithDatabase
static PyDescriptorPool * PyDescriptorPool_NewWithDatabase(DescriptorDatabase *database)
Definition: descriptor_pool.cc:153
google::protobuf::python::ScopedPythonPtr
Definition: scoped_pyobject_ptr.h:46
google::protobuf::python::PyDescriptorPool
Definition: descriptor_pool.h:56
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
google::protobuf::python::ScopedPythonPtr::release
PyObjectStruct * release()
Definition: scoped_pyobject_ptr.h:70
Py_TYPE
#define Py_TYPE(ob)
Definition: python/google/protobuf/pyext/descriptor.cc:164
google::protobuf::python::cdescriptor_pool::FindServiceByName
static PyObject * FindServiceByName(PyObject *self, PyObject *arg)
Definition: descriptor_pool.cc:360
google::protobuf::python::cdescriptor_pool::AddSerializedFile
static PyObject * AddSerializedFile(PyObject *pself, PyObject *serialized_pb)
Definition: descriptor_pool.cc:572
google::protobuf::python::PyEnumDescriptor_FromDescriptor
PyObject * PyEnumDescriptor_FromDescriptor(const EnumDescriptor *enum_descriptor)
Definition: python/google/protobuf/pyext/descriptor.cc:1192
google::protobuf::python::PyFieldDescriptor_FromDescriptor
PyObject * PyFieldDescriptor_FromDescriptor(const FieldDescriptor *field_descriptor)
Definition: python/google/protobuf/pyext/descriptor.cc:1037
google::protobuf::python::PyMessageDescriptor_FromDescriptor
PyObject * PyMessageDescriptor_FromDescriptor(const Descriptor *message_descriptor)
Definition: python/google/protobuf/pyext/descriptor.cc:722
google::protobuf::python::cdescriptor_pool::AddFileDescriptor
static PyObject * AddFileDescriptor(PyObject *self, PyObject *descriptor)
Definition: descriptor_pool.cc:486
google::protobuf::python::cdescriptor_pool::GcClear
static int GcClear(PyObject *pself)
Definition: descriptor_pool.cc:214
message_type
zend_class_entry * message_type
Definition: php/ext/google/protobuf/message.c:45
google::protobuf::ServiceDescriptor
Definition: src/google/protobuf/descriptor.h:1152
google::protobuf::python::cdescriptor_pool::FindFileContainingSymbol
static PyObject * FindFileContainingSymbol(PyObject *self, PyObject *arg)
Definition: descriptor_pool.cc:400
google::protobuf::python::python_generated_pool
static PyDescriptorPool * python_generated_pool
Definition: descriptor_pool.cc:721
google::protobuf::python::cdescriptor_pool::FindExtensionByNameMethod
static PyObject * FindExtensionByNameMethod(PyObject *self, PyObject *arg)
Definition: descriptor_pool.cc:314
google::protobuf::python::PyDescriptorPool::database
const DescriptorDatabase * database
Definition: descriptor_pool.h:72
google::protobuf::python::cdescriptor_pool::FindExtensionByNumber
static PyObject * FindExtensionByNumber(PyObject *self, PyObject *args)
Definition: descriptor_pool.cc:420
google::protobuf::python::GetDescriptorPool_FromPool
PyDescriptorPool * GetDescriptorPool_FromPool(const DescriptorPool *pool)
Definition: descriptor_pool.cc:755
google::protobuf::python::PyMessageDescriptor_AsDescriptor
const Descriptor * PyMessageDescriptor_AsDescriptor(PyObject *obj)
Definition: python/google/protobuf/pyext/descriptor.cc:728
database
database
Definition: .ycm_extra_conf.py:35
PyVarObject_HEAD_INIT
#define PyVarObject_HEAD_INIT(type, size)
Definition: python/google/protobuf/pyext/descriptor.cc:161
google::protobuf::python::PyDescriptorPool::descriptor_options
std::unordered_map< const void *, PyObject * > * descriptor_options
Definition: descriptor_pool.h:82
google::protobuf::python::cdescriptor_pool::FindFieldByName
PyObject * FindFieldByName(PyDescriptorPool *self, PyObject *arg)
Definition: descriptor_pool.cc:275
google::protobuf::python::cdescriptor_pool::FindFieldByNameMethod
static PyObject * FindFieldByNameMethod(PyObject *self, PyObject *arg)
Definition: descriptor_pool.cc:292
google::protobuf::python::cdescriptor_pool::FindExtensionByName
PyObject * FindExtensionByName(PyDescriptorPool *self, PyObject *arg)
Definition: descriptor_pool.cc:296
scoped_pyobject_ptr.h
google::protobuf::python::cdescriptor_pool::New
static PyObject * New(PyTypeObject *type, PyObject *args, PyObject *kwargs)
Definition: descriptor_pool.cc:177
google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation
ErrorLocation
Definition: src/google/protobuf/descriptor.h:1638
google::protobuf::python::cdescriptor_pool::SetErrorFromCollector
PyObject * SetErrorFromCollector(DescriptorPool::ErrorCollector *self, char *name, char *error_type)
Definition: descriptor_pool.cc:220
google::protobuf::DescriptorPool
Definition: src/google/protobuf/descriptor.h:1539
google::protobuf::python::PyDescriptorDatabase
Definition: python/google/protobuf/pyext/descriptor_database.h:42
google::protobuf::python::cdescriptor_pool::AddDescriptor
static PyObject * AddDescriptor(PyObject *self, PyObject *descriptor)
Definition: descriptor_pool.cc:503
FULL_MODULE_NAME
#define FULL_MODULE_NAME
Definition: python/google/protobuf/pyext/message.h:340
google::protobuf::python::cdescriptor_pool::Methods
static PyMethodDef Methods[]
Definition: descriptor_pool.cc:630
google::protobuf::python::cdescriptor_pool::FindOneofByNameMethod
static PyObject * FindOneofByNameMethod(PyObject *self, PyObject *arg)
Definition: descriptor_pool.cc:356
FileDescriptorProto
Definition: descriptor.pb.h:501
google::protobuf::python::cdescriptor_pool::BuildFileErrorCollector::Clear
void Clear()
Definition: descriptor_pool.cc:91
google::protobuf::python::cdescriptor_pool::GcTraverse
static int GcTraverse(PyObject *pself, visitproc visit, void *arg)
Definition: descriptor_pool.cc:208
google::protobuf::python::PyMessageFactory_Type
PyTypeObject PyMessageFactory_Type
Definition: message_factory.cc:251
google::protobuf::MethodDescriptor
Definition: src/google/protobuf/descriptor.h:1234
google::protobuf::DescriptorDatabase
Definition: src/google/protobuf/descriptor_database.h:71
location
GLint location
Definition: glcorearb.h:3074
google::protobuf::python::cdescriptor_pool::BuildFileErrorCollector::error_message
string error_message
Definition: descriptor_pool.cc:96
descriptor_pool.h
pool
InternalDescriptorPool * pool
Definition: php/ext/google/protobuf/protobuf.h:798
google::protobuf::python::PyDescriptorPool_Type
PyTypeObject PyDescriptorPool_Type
Definition: descriptor_pool.cc:677
i
int i
Definition: gmock-matchers_test.cc:764
google::protobuf::python::PyFileDescriptor_FromDescriptor
PyObject * PyFileDescriptor_FromDescriptor(const FileDescriptor *file_descriptor)
Definition: python/google/protobuf/pyext/descriptor.cc:1496
google::protobuf::FileDescriptor::name
const std::string & name() const
descriptor.h
type
GLenum type
Definition: glcorearb.h:2695
google::protobuf::Message
Definition: src/google/protobuf/message.h:205
google::protobuf::python::PyFileDescriptor_AsDescriptor
const FileDescriptor * PyFileDescriptor_AsDescriptor(PyObject *obj)
Definition: python/google/protobuf/pyext/descriptor.cc:1522
google::protobuf::python::PyDescriptorPool::py_message_factory
PyMessageFactory * py_message_factory
Definition: descriptor_pool.h:77
google::protobuf::python::PyOneofDescriptor_FromDescriptor
PyObject * PyOneofDescriptor_FromDescriptor(const OneofDescriptor *oneof_descriptor)
Definition: python/google/protobuf/pyext/descriptor.cc:1647
google::protobuf::python::descriptor_pool_map
static std::unordered_map< const DescriptorPool *, PyDescriptorPool * > * descriptor_pool_map
Definition: descriptor_pool.cc:66
google::protobuf::python::cdescriptor_pool::PyDescriptorPool_NewWithUnderlay
static PyDescriptorPool * PyDescriptorPool_NewWithUnderlay(const DescriptorPool *underlay)
Definition: descriptor_pool.cc:134
enum_descriptor
VALUE enum_descriptor(VALUE self)
Definition: ruby/ext/google/protobuf_c/message.c:801
google::protobuf::python::message_factory::NewMessageFactory
PyMessageFactory * NewMessageFactory(PyTypeObject *type, PyDescriptorPool *pool)
Definition: message_factory.cc:59
google::protobuf::python::PyEnumDescriptor_AsDescriptor
const EnumDescriptor * PyEnumDescriptor_AsDescriptor(PyObject *obj)
Definition: python/google/protobuf/pyext/descriptor.cc:1198
google::protobuf::python::PyFileDescriptor_FromDescriptorWithSerializedPb
PyObject * PyFileDescriptor_FromDescriptorWithSerializedPb(const FileDescriptor *file_descriptor, PyObject *serialized_pb)
Definition: python/google/protobuf/pyext/descriptor.cc:1502
google::protobuf::python::InitDescriptorPool
bool InitDescriptorPool()
Definition: descriptor_pool.cc:723
google::protobuf::python::PyServiceDescriptor_AsDescriptor
const ServiceDescriptor * PyServiceDescriptor_AsDescriptor(PyObject *obj)
Definition: python/google/protobuf/pyext/descriptor.cc:1771
google::protobuf::python::PyDescriptorPool::pool
PyObject_HEAD DescriptorPool * pool
Definition: descriptor_pool.h:60
google::protobuf::DescriptorPool::generated_pool
static const DescriptorPool * generated_pool()
Definition: src/google/protobuf/descriptor.cc:1346
google::protobuf::python::cdescriptor_pool::FindAllExtensions
static PyObject * FindAllExtensions(PyObject *self, PyObject *arg)
Definition: descriptor_pool.cc:453
google::protobuf::Descriptor
Definition: src/google/protobuf/descriptor.h:231
google::protobuf::python::PyDescriptorPool::error_collector
DescriptorPool::ErrorCollector * error_collector
Definition: descriptor_pool.h:64
hash.h
element_name
std::string element_name
Definition: src/google/protobuf/descriptor.cc:3116
visit
static void visit(const upb_refcounted *r, upb_refcounted_visit *v, void *closure)
Definition: ruby/ext/google/protobuf_c/upb.c:5811
google::protobuf::python::cdescriptor_pool::AddExtensionDescriptor
static PyObject * AddExtensionDescriptor(PyObject *self, PyObject *descriptor)
Definition: descriptor_pool.cc:537
google::protobuf::FileDescriptor
Definition: src/google/protobuf/descriptor.h:1320
google::protobuf::python::PyDescriptorPool::underlay
const DescriptorPool * underlay
Definition: descriptor_pool.h:68
google::protobuf::python::cdescriptor_pool::BuildFileErrorCollector::had_errors_
bool had_errors_
Definition: descriptor_pool.cc:99
message.h
descriptor_database.h
descriptor.pb.h
google::protobuf::python::cdescriptor_pool::Dealloc
static void Dealloc(PyObject *pself)
Definition: descriptor_pool.cc:192
google::protobuf::python::cdescriptor_pool::BuildFileErrorCollector::AddError
void AddError(const string &filename, const string &element_name, const Message *descriptor, ErrorLocation location, const string &message) override
Definition: descriptor_pool.cc:76
google::protobuf::python::cdescriptor_pool::BuildFileErrorCollector::BuildFileErrorCollector
BuildFileErrorCollector()
Definition: descriptor_pool.cc:74
google::protobuf::EnumDescriptor
Definition: src/google/protobuf/descriptor.h:918
false
#define false
Definition: cJSON.c:70
DescriptorPool
struct DescriptorPool DescriptorPool
Definition: php/ext/google/protobuf/protobuf.h:629
number
double number
Definition: cJSON.h:326
it
MapIter it
Definition: php/ext/google/protobuf/map.c:205
google
Definition: data_proto2_to_proto3_util.h:11
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
google::protobuf::python::cdescriptor_pool::BuildFileErrorCollector
Definition: descriptor_pool.cc:72
benchmarks.python.py_benchmark.args
args
Definition: py_benchmark.py:24
google::protobuf::python::cdescriptor_pool::FindMethodByName
static PyObject * FindMethodByName(PyObject *self, PyObject *arg)
Definition: descriptor_pool.cc:380


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:50