1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 // Author: petar@google.com (Petar Petrov)
9
10 #include "google/protobuf/pyext/descriptor.h"
11
12 #define PY_SSIZE_T_CLEAN
13 #include <Python.h>
14 #include <frameobject.h>
15
16 #include <cstdint>
17 #include <string>
18 #include <unordered_map>
19
20 #include "google/protobuf/descriptor.pb.h"
21 #include "absl/container/flat_hash_map.h"
22 #include "absl/log/absl_check.h"
23 #include "absl/strings/string_view.h"
24 #include "google/protobuf/descriptor.h"
25 #include "google/protobuf/dynamic_message.h"
26 #include "google/protobuf/io/coded_stream.h"
27 #include "google/protobuf/pyext/descriptor_containers.h"
28 #include "google/protobuf/pyext/descriptor_pool.h"
29 #include "google/protobuf/pyext/message.h"
30 #include "google/protobuf/pyext/message_factory.h"
31 #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
32
33 #define PyString_AsStringAndSize(ob, charpp, sizep) \
34 (PyUnicode_Check(ob) \
35 ? ((*(charpp) = const_cast<char*>( \
36 PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \
37 ? -1 \
38 : 0) \
39 : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
40
41 #if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
PyFrame_GetCode(PyFrameObject * frame)42 static PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
43 {
44 Py_INCREF(frame->f_code);
45 return frame->f_code;
46 }
47
PyFrame_GetBack(PyFrameObject * frame)48 static PyFrameObject* PyFrame_GetBack(PyFrameObject *frame)
49 {
50 Py_XINCREF(frame->f_back);
51 return frame->f_back;
52 }
53 #endif
54
55 #if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION)
PyFrame_GetLocals(PyFrameObject * frame)56 static PyObject* PyFrame_GetLocals(PyFrameObject *frame)
57 {
58 if (PyFrame_FastToLocalsWithError(frame) < 0) {
59 return NULL;
60 }
61 Py_INCREF(frame->f_locals);
62 return frame->f_locals;
63 }
64
PyFrame_GetGlobals(PyFrameObject * frame)65 static PyObject* PyFrame_GetGlobals(PyFrameObject *frame)
66 {
67 Py_INCREF(frame->f_globals);
68 return frame->f_globals;
69 }
70 #endif
71
72 namespace google {
73 namespace protobuf {
74 namespace python {
75
76 // Store interned descriptors, so that the same C++ descriptor yields the same
77 // Python object. Objects are not immortal: this map does not own the
78 // references, and items are deleted when the last reference to the object is
79 // released.
80 // This is enough to support the "is" operator on live objects.
81 // All descriptors are stored here.
82 std::unordered_map<const void*, PyObject*>* interned_descriptors;
83
PyString_FromCppString(absl::string_view str)84 PyObject* PyString_FromCppString(absl::string_view str) {
85 return PyUnicode_FromStringAndSize(str.data(), str.size());
86 }
87
88 // Check that the calling Python code is the global scope of a _pb2.py module.
89 // This function is used to support the current code generated by the proto
90 // compiler, which creates descriptors, then update some properties.
91 // For example:
92 // message_descriptor = Descriptor(
93 // name='Message',
94 // fields = [FieldDescriptor(name='field')]
95 // message_descriptor.fields[0].containing_type = message_descriptor
96 //
97 // This code is still executed, but the descriptors now have no other storage
98 // than the (const) C++ pointer, and are immutable.
99 // So we let this code pass, by simply ignoring the new value.
100 //
101 // From user code, descriptors still look immutable.
102 //
103 // TODO: Change the proto2 compiler to remove the assignments, and
104 // remove this hack.
_CalledFromGeneratedFile(int stacklevel)105 bool _CalledFromGeneratedFile(int stacklevel) {
106 #ifdef PYPY_VERSION
107 return true;
108 #else
109 // This check is not critical and is somewhat difficult to implement correctly
110 // in PyPy.
111 PyFrameObject* frame = PyEval_GetFrame();
112 PyCodeObject* frame_code = nullptr;
113 PyObject* frame_globals = nullptr;
114 PyObject* frame_locals = nullptr;
115 bool result = false;
116
117 if (frame == nullptr) {
118 goto exit;
119 }
120 Py_INCREF(frame);
121 while (stacklevel-- > 0) {
122 PyFrameObject* next_frame = PyFrame_GetBack(frame);
123 Py_DECREF(frame);
124 frame = next_frame;
125 if (frame == nullptr) {
126 goto exit;
127 }
128 }
129
130 frame_code = PyFrame_GetCode(frame);
131 if (frame_code->co_filename == nullptr) {
132 goto exit;
133 }
134 char* filename;
135 Py_ssize_t filename_size;
136 if (PyString_AsStringAndSize(frame_code->co_filename,
137 &filename, &filename_size) < 0) {
138 // filename is not a string.
139 PyErr_Clear();
140 goto exit;
141 }
142 if ((filename_size < 3) ||
143 (strcmp(&filename[filename_size - 3], ".py") != 0)) {
144 // Cython's stack does not have .py file name and is not at global module
145 // scope.
146 result = true;
147 goto exit;
148 }
149 if (filename_size < 7) {
150 // filename is too short.
151 goto exit;
152 }
153 if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) {
154 // Filename is not ending with _pb2.
155 goto exit;
156 }
157
158 frame_globals = PyFrame_GetGlobals(frame);
159 frame_locals = PyFrame_GetLocals(frame);
160 if (frame_globals != frame_locals) {
161 // Not at global module scope
162 goto exit;
163 }
164 result = true;
165 exit:
166 Py_XDECREF(frame_globals);
167 Py_XDECREF(frame_locals);
168 Py_XDECREF(frame_code);
169 Py_XDECREF(frame);
170 return result;
171 #endif
172 }
173
174 // If the calling code is not a _pb2.py file, raise AttributeError.
175 // To be used in attribute setters.
CheckCalledFromGeneratedFile(const char * attr_name)176 static int CheckCalledFromGeneratedFile(const char* attr_name) {
177 if (_CalledFromGeneratedFile(0)) {
178 return 0;
179 }
180 PyErr_Format(PyExc_AttributeError,
181 "attribute is not writable: %s", attr_name);
182 return -1;
183 }
184
185
186 #ifndef PyVarObject_HEAD_INIT
187 #define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
188 #endif
189 #ifndef Py_TYPE
190 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
191 #endif
192
193
194 // Helper functions for descriptor objects.
195
196 // A set of templates to retrieve the C++ FileDescriptor of any descriptor.
197 template<class DescriptorClass>
GetFileDescriptor(const DescriptorClass * descriptor)198 const FileDescriptor* GetFileDescriptor(const DescriptorClass* descriptor) {
199 return descriptor->file();
200 }
201 template<>
GetFileDescriptor(const FileDescriptor * descriptor)202 const FileDescriptor* GetFileDescriptor(const FileDescriptor* descriptor) {
203 return descriptor;
204 }
205 template<>
GetFileDescriptor(const EnumValueDescriptor * descriptor)206 const FileDescriptor* GetFileDescriptor(const EnumValueDescriptor* descriptor) {
207 return descriptor->type()->file();
208 }
209 template<>
GetFileDescriptor(const OneofDescriptor * descriptor)210 const FileDescriptor* GetFileDescriptor(const OneofDescriptor* descriptor) {
211 return descriptor->containing_type()->file();
212 }
213 template<>
GetFileDescriptor(const MethodDescriptor * descriptor)214 const FileDescriptor* GetFileDescriptor(const MethodDescriptor* descriptor) {
215 return descriptor->service()->file();
216 }
217
Reparse(PyMessageFactory * message_factory,const Message & from,Message * to)218 bool Reparse(
219 PyMessageFactory* message_factory, const Message& from, Message* to) {
220 // Reparse message.
221 std::string serialized;
222 from.SerializeToString(&serialized);
223 io::CodedInputStream input(
224 reinterpret_cast<const uint8_t*>(serialized.c_str()), serialized.size());
225 input.SetExtensionRegistry(message_factory->pool->pool,
226 message_factory->message_factory);
227 bool success = to->ParseFromCodedStream(&input);
228 if (!success) {
229 return false;
230 }
231 return true;
232 }
233
234 // Converts descriptor messages into a Python protobuf, and cache the result.
235 //
236 // This is a bit tricky because options can contain extension fields defined in
237 // the same proto file. In this case the options parsed from the serialized_pb
238 // have unknown fields, and we need to parse them again.
239 //
240 // Always returns a new reference.
GetOrBuildMessageInDefaultPool(absl::flat_hash_map<const void *,PyObject * > & cache,const void * key,const Message & message)241 static PyObject* GetOrBuildMessageInDefaultPool(
242 absl::flat_hash_map<const void*, PyObject*>& cache, const void* key,
243 const Message& message) {
244 // First search in the cache.
245 if (cache.find(key) != cache.end()) {
246 PyObject* value = cache[key];
247 Py_INCREF(value);
248 return value;
249 }
250
251 // Similar to the C++ implementation, we return a message object from the
252 // default (generated) factory, so that client code know that they can use
253 // extensions from generated files:
254 // d.GetOptions().Extensions[some_pb2.extension]
255 //
256 // The consequence is that extensions not defined in the default pool won't
257 // be available. If needed, we could add an optional 'message_factory'
258 // parameter to the GetOptions() function.
259 PyMessageFactory* message_factory =
260 GetDefaultDescriptorPool()->py_message_factory;
261
262 // Build the message object: get its Python class, and make a copy of the C++
263 // read-only instance.
264 const Descriptor* message_type = message.GetDescriptor();
265 CMessageClass* message_class =
266 message_factory::GetOrCreateMessageClass(message_factory, message_type);
267 if (message_class == nullptr) {
268 PyErr_Format(PyExc_TypeError, "Could not retrieve class for: %s",
269 std::string(message_type->full_name()).c_str());
270 return nullptr;
271 }
272 ScopedPyObjectPtr args(PyTuple_New(0));
273 ScopedPyObjectPtr value(
274 PyObject_Call(message_class->AsPyObject(), args.get(), nullptr));
275 Py_DECREF(message_class);
276 if (value == nullptr) {
277 return nullptr;
278 }
279 if (!PyObject_TypeCheck(value.get(), CMessage_Type)) {
280 PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s",
281 std::string(message_type->full_name()).c_str(),
282 Py_TYPE(value.get())->tp_name);
283 return nullptr;
284 }
285 CMessage* cmsg = reinterpret_cast<CMessage*>(value.get());
286
287 const Reflection* reflection = message.GetReflection();
288 const UnknownFieldSet& unknown_fields(reflection->GetUnknownFields(message));
289 if (unknown_fields.empty()) {
290 cmsg->message->CopyFrom(message);
291 } else {
292 // Reparse options string! XXX call cmessage::MergeFromString
293 if (!Reparse(message_factory, message, cmsg->message)) {
294 PyErr_Format(PyExc_ValueError, "Error reparsing Options message");
295 return nullptr;
296 }
297 }
298
299 // Cache the result.
300 Py_INCREF(value.get());
301 cache[key] = value.get();
302
303 return value.release();
304 }
305
306 template <class DescriptorClass>
GetOrBuildOptions(const DescriptorClass * descriptor)307 static PyObject* GetOrBuildOptions(const DescriptorClass* descriptor) {
308 // Options are cached in the pool that owns the descriptor.
309 PyDescriptorPool* caching_pool =
310 GetDescriptorPool_FromPool(GetFileDescriptor(descriptor)->pool());
311 return GetOrBuildMessageInDefaultPool(*caching_pool->descriptor_options,
312 descriptor, descriptor->options());
313 }
314
315 template <class DescriptorClass>
GetFeaturesImpl(const DescriptorClass * descriptor)316 static PyObject* GetFeaturesImpl(const DescriptorClass* descriptor) {
317 if (descriptor == nullptr) {
318 return nullptr;
319 }
320 const FeatureSet& features =
321 internal::InternalFeatureHelper::GetFeatures(*descriptor);
322
323 // Features are cached in the pool that owns the descriptor.
324 PyDescriptorPool* caching_pool =
325 GetDescriptorPool_FromPool(GetFileDescriptor(descriptor)->pool());
326 return GetOrBuildMessageInDefaultPool(*caching_pool->descriptor_features,
327 descriptor, features);
328 }
329
330 // Copy the C++ descriptor to a Python message.
331 // The Python message is an instance of descriptor_pb2.DescriptorProto
332 // or similar.
333 template<class DescriptorProtoClass, class DescriptorClass>
CopyToPythonProto(const DescriptorClass * descriptor,PyObject * target)334 static PyObject* CopyToPythonProto(const DescriptorClass *descriptor,
335 PyObject *target) {
336 const Descriptor* self_descriptor =
337 DescriptorProtoClass::default_instance().GetDescriptor();
338 CMessage* message = reinterpret_cast<CMessage*>(target);
339 if (!PyObject_TypeCheck(target, CMessage_Type) ||
340 message->message->GetDescriptor() != self_descriptor) {
341 PyErr_Format(PyExc_TypeError, "Not a %s message",
342 std::string(self_descriptor->full_name()).c_str());
343 return nullptr;
344 }
345 cmessage::AssureWritable(message);
346 DescriptorProtoClass* descriptor_message =
347 static_cast<DescriptorProtoClass*>(message->message);
348 descriptor->CopyTo(descriptor_message);
349 // Custom options might in unknown extensions. Reparse
350 // the descriptor_message. Can't skip reparse when options unknown
351 // fields is empty, because they might in sub descriptors' options.
352 PyMessageFactory* message_factory =
353 GetDefaultDescriptorPool()->py_message_factory;
354 if (!Reparse(message_factory, *descriptor_message, descriptor_message)) {
355 PyErr_Format(PyExc_ValueError, "Error reparsing descriptor message");
356 return nullptr;
357 }
358
359 Py_RETURN_NONE;
360 }
361
362 // All Descriptors classes share the same memory layout.
363 typedef struct PyBaseDescriptor {
364 PyObject_HEAD
365
366 // Pointer to the C++ proto2 descriptor.
367 // Like all descriptors, it is owned by the global DescriptorPool.
368 const void* descriptor;
369
370 // Owned reference to the DescriptorPool, to ensure it is kept alive.
371 PyDescriptorPool* pool;
372 } PyBaseDescriptor;
373
374
375 // FileDescriptor structure "inherits" from the base descriptor.
376 typedef struct PyFileDescriptor {
377 PyBaseDescriptor base;
378
379 // The cached version of serialized pb. Either null, or a Bytes string.
380 // We own the reference.
381 PyObject *serialized_pb;
382 } PyFileDescriptor;
383
384
385 namespace descriptor {
386
387 // Creates or retrieve a Python descriptor of the specified type.
388 // Objects are interned: the same descriptor will return the same object if it
389 // was kept alive.
390 // 'was_created' is an optional pointer to a bool, and is set to true if a new
391 // object was allocated.
392 // Always return a new reference.
393 template<class DescriptorClass>
NewInternedDescriptor(PyTypeObject * type,const DescriptorClass * descriptor,bool * was_created)394 PyObject* NewInternedDescriptor(PyTypeObject* type,
395 const DescriptorClass* descriptor,
396 bool* was_created) {
397 if (was_created) {
398 *was_created = false;
399 }
400 if (descriptor == nullptr) {
401 PyErr_BadInternalCall();
402 return nullptr;
403 }
404
405 // See if the object is in the map of interned descriptors
406 std::unordered_map<const void*, PyObject*>::iterator it =
407 interned_descriptors->find(descriptor);
408 if (it != interned_descriptors->end()) {
409 ABSL_DCHECK(Py_TYPE(it->second) == type);
410 Py_INCREF(it->second);
411 return it->second;
412 }
413 // Create a new descriptor object
414 PyBaseDescriptor* py_descriptor = PyObject_GC_New(
415 PyBaseDescriptor, type);
416 if (py_descriptor == nullptr) {
417 return nullptr;
418 }
419 py_descriptor->descriptor = descriptor;
420
421 // and cache it.
422 interned_descriptors->insert(
423 std::make_pair(descriptor, reinterpret_cast<PyObject*>(py_descriptor)));
424
425 // Ensures that the DescriptorPool stays alive.
426 PyDescriptorPool* pool = GetDescriptorPool_FromPool(
427 GetFileDescriptor(descriptor)->pool());
428 if (pool == nullptr) {
429 // Don't DECREF, the object is not fully initialized.
430 PyObject_Del(py_descriptor);
431 return nullptr;
432 }
433 Py_INCREF(pool);
434 py_descriptor->pool = pool;
435
436 PyObject_GC_Track(py_descriptor);
437
438 if (was_created) {
439 *was_created = true;
440 }
441 return reinterpret_cast<PyObject*>(py_descriptor);
442 }
443
Dealloc(PyObject * pself)444 static void Dealloc(PyObject* pself) {
445 PyBaseDescriptor* self = reinterpret_cast<PyBaseDescriptor*>(pself);
446 // Remove from interned dictionary
447 interned_descriptors->erase(self->descriptor);
448 Py_CLEAR(self->pool);
449 Py_TYPE(self)->tp_free(pself);
450 }
451
GcTraverse(PyObject * pself,visitproc visit,void * arg)452 static int GcTraverse(PyObject* pself, visitproc visit, void* arg) {
453 PyBaseDescriptor* self = reinterpret_cast<PyBaseDescriptor*>(pself);
454 Py_VISIT(self->pool);
455 return 0;
456 }
457
GcClear(PyObject * pself)458 static int GcClear(PyObject* pself) {
459 PyBaseDescriptor* self = reinterpret_cast<PyBaseDescriptor*>(pself);
460 Py_CLEAR(self->pool);
461 return 0;
462 }
463
464 static PyGetSetDef Getters[] = {
465 {nullptr},
466 };
467
468 PyTypeObject PyBaseDescriptor_Type = {
469 PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
470 ".DescriptorBase", // tp_name
471 sizeof(PyBaseDescriptor), // tp_basicsize
472 0, // tp_itemsize
473 (destructor)Dealloc, // tp_dealloc
474 #if PY_VERSION_HEX < 0x03080000
475 nullptr, // tp_print
476 #else
477 0, // tp_vectorcall_offset
478 #endif
479 nullptr, // tp_getattr
480 nullptr, // tp_setattr
481 nullptr, // tp_compare
482 nullptr, // tp_repr
483 nullptr, // tp_as_number
484 nullptr, // tp_as_sequence
485 nullptr, // tp_as_mapping
486 nullptr, // tp_hash
487 nullptr, // tp_call
488 nullptr, // tp_str
489 nullptr, // tp_getattro
490 nullptr, // tp_setattro
491 nullptr, // tp_as_buffer
492 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
493 "Descriptors base class", // tp_doc
494 GcTraverse, // tp_traverse
495 GcClear, // tp_clear
496 nullptr, // tp_richcompare
497 0, // tp_weaklistoffset
498 nullptr, // tp_iter
499 nullptr, // tp_iternext
500 nullptr, // tp_methods
501 nullptr, // tp_members
502 Getters, // tp_getset
503 };
504
505 } // namespace descriptor
506
PyDescriptor_AsVoidPtr(PyObject * obj)507 const void* PyDescriptor_AsVoidPtr(PyObject* obj) {
508 if (!PyObject_TypeCheck(obj, &descriptor::PyBaseDescriptor_Type)) {
509 PyErr_SetString(PyExc_TypeError, "Not a BaseDescriptor");
510 return nullptr;
511 }
512 return reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor;
513 }
514
515 namespace message_descriptor {
516
517 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)518 static const Descriptor* _GetDescriptor(PyBaseDescriptor* self) {
519 return reinterpret_cast<const Descriptor*>(self->descriptor);
520 }
521
GetName(PyBaseDescriptor * self,void * closure)522 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
523 return PyString_FromCppString(_GetDescriptor(self)->name());
524 }
525
GetFullName(PyBaseDescriptor * self,void * closure)526 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
527 return PyString_FromCppString(_GetDescriptor(self)->full_name());
528 }
529
GetFile(PyBaseDescriptor * self,void * closure)530 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
531 return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
532 }
533
GetConcreteClass(PyBaseDescriptor * self,void * closure)534 static PyObject* GetConcreteClass(PyBaseDescriptor* self, void *closure) {
535 // Returns the canonical class for the given descriptor.
536 // This is the class that was registered with the primary descriptor pool
537 // which contains this descriptor.
538 // This might not be the one you expect! For example the returned object does
539 // not know about extensions defined in a custom pool.
540 CMessageClass* concrete_class(message_factory::GetMessageClass(
541 GetDescriptorPool_FromPool(
542 _GetDescriptor(self)->file()->pool())->py_message_factory,
543 _GetDescriptor(self)));
544
545 if (concrete_class == nullptr) {
546 PyErr_Clear();
547 return nullptr;
548 }
549
550 Py_XINCREF(concrete_class);
551 return concrete_class->AsPyObject();
552 }
553
GetFieldsByName(PyBaseDescriptor * self,void * closure)554 static PyObject* GetFieldsByName(PyBaseDescriptor* self, void *closure) {
555 return NewMessageFieldsByName(_GetDescriptor(self));
556 }
557
GetFieldsByCamelcaseName(PyBaseDescriptor * self,void * closure)558 static PyObject* GetFieldsByCamelcaseName(PyBaseDescriptor* self,
559 void *closure) {
560 return NewMessageFieldsByCamelcaseName(_GetDescriptor(self));
561 }
562
GetFieldsByNumber(PyBaseDescriptor * self,void * closure)563 static PyObject* GetFieldsByNumber(PyBaseDescriptor* self, void *closure) {
564 return NewMessageFieldsByNumber(_GetDescriptor(self));
565 }
566
GetFieldsSeq(PyBaseDescriptor * self,void * closure)567 static PyObject* GetFieldsSeq(PyBaseDescriptor* self, void *closure) {
568 return NewMessageFieldsSeq(_GetDescriptor(self));
569 }
570
GetNestedTypesByName(PyBaseDescriptor * self,void * closure)571 static PyObject* GetNestedTypesByName(PyBaseDescriptor* self, void *closure) {
572 return NewMessageNestedTypesByName(_GetDescriptor(self));
573 }
574
GetNestedTypesSeq(PyBaseDescriptor * self,void * closure)575 static PyObject* GetNestedTypesSeq(PyBaseDescriptor* self, void *closure) {
576 return NewMessageNestedTypesSeq(_GetDescriptor(self));
577 }
578
GetExtensionsByName(PyBaseDescriptor * self,void * closure)579 static PyObject* GetExtensionsByName(PyBaseDescriptor* self, void *closure) {
580 return NewMessageExtensionsByName(_GetDescriptor(self));
581 }
582
GetExtensions(PyBaseDescriptor * self,void * closure)583 static PyObject* GetExtensions(PyBaseDescriptor* self, void *closure) {
584 return NewMessageExtensionsSeq(_GetDescriptor(self));
585 }
586
GetEnumsSeq(PyBaseDescriptor * self,void * closure)587 static PyObject* GetEnumsSeq(PyBaseDescriptor* self, void *closure) {
588 return NewMessageEnumsSeq(_GetDescriptor(self));
589 }
590
GetEnumTypesByName(PyBaseDescriptor * self,void * closure)591 static PyObject* GetEnumTypesByName(PyBaseDescriptor* self, void *closure) {
592 return NewMessageEnumsByName(_GetDescriptor(self));
593 }
594
GetEnumValuesByName(PyBaseDescriptor * self,void * closure)595 static PyObject* GetEnumValuesByName(PyBaseDescriptor* self, void *closure) {
596 return NewMessageEnumValuesByName(_GetDescriptor(self));
597 }
598
GetOneofsByName(PyBaseDescriptor * self,void * closure)599 static PyObject* GetOneofsByName(PyBaseDescriptor* self, void *closure) {
600 return NewMessageOneofsByName(_GetDescriptor(self));
601 }
602
GetOneofsSeq(PyBaseDescriptor * self,void * closure)603 static PyObject* GetOneofsSeq(PyBaseDescriptor* self, void *closure) {
604 return NewMessageOneofsSeq(_GetDescriptor(self));
605 }
606
IsExtendable(PyBaseDescriptor * self,void * closure)607 static PyObject* IsExtendable(PyBaseDescriptor *self, void *closure) {
608 if (_GetDescriptor(self)->extension_range_count() > 0) {
609 Py_RETURN_TRUE;
610 } else {
611 Py_RETURN_FALSE;
612 }
613 }
614
GetExtensionRanges(PyBaseDescriptor * self,void * closure)615 static PyObject* GetExtensionRanges(PyBaseDescriptor *self, void *closure) {
616 const Descriptor* descriptor = _GetDescriptor(self);
617 PyObject* range_list = PyList_New(descriptor->extension_range_count());
618
619 for (int i = 0; i < descriptor->extension_range_count(); i++) {
620 const Descriptor::ExtensionRange* range = descriptor->extension_range(i);
621 PyObject* start = PyLong_FromLong(range->start_number());
622 PyObject* end = PyLong_FromLong(range->end_number());
623 PyList_SetItem(range_list, i, PyTuple_Pack(2, start, end));
624 }
625
626 return range_list;
627 }
628
GetContainingType(PyBaseDescriptor * self,void * closure)629 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
630 const Descriptor* containing_type =
631 _GetDescriptor(self)->containing_type();
632 if (containing_type) {
633 return PyMessageDescriptor_FromDescriptor(containing_type);
634 } else {
635 Py_RETURN_NONE;
636 }
637 }
638
SetContainingType(PyBaseDescriptor * self,PyObject * value,void * closure)639 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
640 void *closure) {
641 return CheckCalledFromGeneratedFile("containing_type");
642 }
643
GetHasOptions(PyBaseDescriptor * self,void * closure)644 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
645 const MessageOptions& options(_GetDescriptor(self)->options());
646 if (&options != &MessageOptions::default_instance()) {
647 Py_RETURN_TRUE;
648 } else {
649 Py_RETURN_FALSE;
650 }
651 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)652 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
653 void *closure) {
654 return CheckCalledFromGeneratedFile("has_options");
655 }
656
GetOptions(PyBaseDescriptor * self)657 static PyObject* GetOptions(PyBaseDescriptor *self) {
658 return GetOrBuildOptions(_GetDescriptor(self));
659 }
660
GetFeatures(PyBaseDescriptor * self)661 static PyObject* GetFeatures(PyBaseDescriptor* self) {
662 return GetFeaturesImpl(_GetDescriptor(self));
663 }
664
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)665 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
666 void *closure) {
667 return CheckCalledFromGeneratedFile("_options");
668 }
669
SetSerializedOptions(PyBaseDescriptor * self,PyObject * value,void * closure)670 static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
671 void *closure) {
672 return CheckCalledFromGeneratedFile("_serialized_options");
673 }
674
CopyToProto(PyBaseDescriptor * self,PyObject * target)675 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
676 return CopyToPythonProto<DescriptorProto>(_GetDescriptor(self), target);
677 }
678
EnumValueName(PyBaseDescriptor * self,PyObject * args)679 static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) {
680 const char *enum_name;
681 int number;
682 if (!PyArg_ParseTuple(args, "si", &enum_name, &number)) return nullptr;
683 const EnumDescriptor *enum_type =
684 _GetDescriptor(self)->FindEnumTypeByName(enum_name);
685 if (enum_type == nullptr) {
686 PyErr_SetString(PyExc_KeyError, enum_name);
687 return nullptr;
688 }
689 const EnumValueDescriptor *enum_value =
690 enum_type->FindValueByNumber(number);
691 if (enum_value == nullptr) {
692 PyErr_Format(PyExc_KeyError, "%d", number);
693 return nullptr;
694 }
695 return PyString_FromCppString(enum_value->name());
696 }
697
698 static PyGetSetDef Getters[] = {
699 {"name", (getter)GetName, nullptr, "Last name"},
700 {"full_name", (getter)GetFullName, nullptr, "Full name"},
701 {"_concrete_class", (getter)GetConcreteClass, nullptr, "concrete class"},
702 {"file", (getter)GetFile, nullptr, "File descriptor"},
703
704 {"fields", (getter)GetFieldsSeq, nullptr, "Fields sequence"},
705 {"fields_by_name", (getter)GetFieldsByName, nullptr, "Fields by name"},
706 {"fields_by_camelcase_name", (getter)GetFieldsByCamelcaseName, nullptr,
707 "Fields by camelCase name"},
708 {"fields_by_number", (getter)GetFieldsByNumber, nullptr,
709 "Fields by number"},
710 {"nested_types", (getter)GetNestedTypesSeq, nullptr,
711 "Nested types sequence"},
712 {"nested_types_by_name", (getter)GetNestedTypesByName, nullptr,
713 "Nested types by name"},
714 {"extensions", (getter)GetExtensions, nullptr, "Extensions Sequence"},
715 {"extensions_by_name", (getter)GetExtensionsByName, nullptr,
716 "Extensions by name"},
717 {"extension_ranges", (getter)GetExtensionRanges, nullptr,
718 "Extension ranges"},
719 {"enum_types", (getter)GetEnumsSeq, nullptr, "Enum sequence"},
720 {"enum_types_by_name", (getter)GetEnumTypesByName, nullptr,
721 "Enum types by name"},
722 {"enum_values_by_name", (getter)GetEnumValuesByName, nullptr,
723 "Enum values by name"},
724 {"oneofs_by_name", (getter)GetOneofsByName, nullptr, "Oneofs by name"},
725 {"oneofs", (getter)GetOneofsSeq, nullptr, "Oneofs by name"},
726 {"containing_type", (getter)GetContainingType, (setter)SetContainingType,
727 "Containing type"},
728 {"is_extendable", (getter)IsExtendable, (setter) nullptr},
729 {"has_options", (getter)GetHasOptions, (setter)SetHasOptions,
730 "Has Options"},
731 {"_options", (getter) nullptr, (setter)SetOptions, "Options"},
732 {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
733 "Serialized Options"},
734 {nullptr},
735 };
736
737 static PyMethodDef Methods[] = {
738 {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS},
739 {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS},
740 {"CopyToProto", (PyCFunction)CopyToProto, METH_O},
741 {"EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS},
742 {nullptr},
743 };
744
745 } // namespace message_descriptor
746
747 PyTypeObject PyMessageDescriptor_Type = {
748 PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
749 ".MessageDescriptor", // tp_name
750 sizeof(PyBaseDescriptor), // tp_basicsize
751 0, // tp_itemsize
752 nullptr, // tp_dealloc
753 #if PY_VERSION_HEX < 0x03080000
754 nullptr, // tp_print
755 #else
756 0, // tp_vectorcall_offset
757 #endif
758 nullptr, // tp_getattr
759 nullptr, // tp_setattr
760 nullptr, // tp_compare
761 nullptr, // tp_repr
762 nullptr, // tp_as_number
763 nullptr, // tp_as_sequence
764 nullptr, // tp_as_mapping
765 nullptr, // tp_hash
766 nullptr, // tp_call
767 nullptr, // tp_str
768 nullptr, // tp_getattro
769 nullptr, // tp_setattro
770 nullptr, // tp_as_buffer
771 Py_TPFLAGS_DEFAULT, // tp_flags
772 "A Message Descriptor", // tp_doc
773 nullptr, // tp_traverse
774 nullptr, // tp_clear
775 nullptr, // tp_richcompare
776 0, // tp_weaklistoffset
777 nullptr, // tp_iter
778 nullptr, // tp_iternext
779 message_descriptor::Methods, // tp_methods
780 nullptr, // tp_members
781 message_descriptor::Getters, // tp_getset
782 &descriptor::PyBaseDescriptor_Type, // tp_base
783 };
784
PyMessageDescriptor_FromDescriptor(const Descriptor * message_descriptor)785 PyObject* PyMessageDescriptor_FromDescriptor(
786 const Descriptor* message_descriptor) {
787 return descriptor::NewInternedDescriptor(&PyMessageDescriptor_Type,
788 message_descriptor, nullptr);
789 }
790
PyMessageDescriptor_AsDescriptor(PyObject * obj)791 const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj) {
792 if (!PyObject_TypeCheck(obj, &PyMessageDescriptor_Type)) {
793 PyErr_SetString(PyExc_TypeError, "Not a MessageDescriptor");
794 return nullptr;
795 }
796 return reinterpret_cast<const Descriptor*>(
797 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
798 }
799
800 namespace field_descriptor {
801
802 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)803 static const FieldDescriptor* _GetDescriptor(
804 PyBaseDescriptor *self) {
805 return reinterpret_cast<const FieldDescriptor*>(self->descriptor);
806 }
807
GetFullName(PyBaseDescriptor * self,void * closure)808 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
809 return PyString_FromCppString(_GetDescriptor(self)->full_name());
810 }
811
GetName(PyBaseDescriptor * self,void * closure)812 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
813 return PyString_FromCppString(_GetDescriptor(self)->name());
814 }
815
GetCamelcaseName(PyBaseDescriptor * self,void * closure)816 static PyObject* GetCamelcaseName(PyBaseDescriptor* self, void *closure) {
817 return PyString_FromCppString(_GetDescriptor(self)->camelcase_name());
818 }
819
GetJsonName(PyBaseDescriptor * self,void * closure)820 static PyObject* GetJsonName(PyBaseDescriptor* self, void *closure) {
821 return PyString_FromCppString(_GetDescriptor(self)->json_name());
822 }
823
GetFile(PyBaseDescriptor * self,void * closure)824 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
825 return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
826 }
827
GetType(PyBaseDescriptor * self,void * closure)828 static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
829 return PyLong_FromLong(_GetDescriptor(self)->type());
830 }
831
GetCppType(PyBaseDescriptor * self,void * closure)832 static PyObject* GetCppType(PyBaseDescriptor *self, void *closure) {
833 return PyLong_FromLong(_GetDescriptor(self)->cpp_type());
834 }
835
GetLabel(PyBaseDescriptor * self,void * closure)836 static PyObject* GetLabel(PyBaseDescriptor *self, void *closure) {
837 return PyLong_FromLong(_GetDescriptor(self)->label());
838 }
839
GetNumber(PyBaseDescriptor * self,void * closure)840 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
841 return PyLong_FromLong(_GetDescriptor(self)->number());
842 }
843
GetIndex(PyBaseDescriptor * self,void * closure)844 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
845 return PyLong_FromLong(_GetDescriptor(self)->index());
846 }
847
GetID(PyBaseDescriptor * self,void * closure)848 static PyObject* GetID(PyBaseDescriptor *self, void *closure) {
849 return PyLong_FromVoidPtr(self);
850 }
851
IsExtension(PyBaseDescriptor * self,void * closure)852 static PyObject* IsExtension(PyBaseDescriptor *self, void *closure) {
853 return PyBool_FromLong(_GetDescriptor(self)->is_extension());
854 }
855
IsPacked(PyBaseDescriptor * self,void * closure)856 static PyObject* IsPacked(PyBaseDescriptor* self, void* closure) {
857 return PyBool_FromLong(_GetDescriptor(self)->is_packed());
858 }
859
HasDefaultValue(PyBaseDescriptor * self,void * closure)860 static PyObject* HasDefaultValue(PyBaseDescriptor *self, void *closure) {
861 return PyBool_FromLong(_GetDescriptor(self)->has_default_value());
862 }
863
GetDefaultValue(PyBaseDescriptor * self,void * closure)864 static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) {
865 PyObject *result;
866
867 if (_GetDescriptor(self)->is_repeated()) {
868 return PyList_New(0);
869 }
870
871
872 switch (_GetDescriptor(self)->cpp_type()) {
873 case FieldDescriptor::CPPTYPE_INT32: {
874 int32_t value = _GetDescriptor(self)->default_value_int32();
875 result = PyLong_FromLong(value);
876 break;
877 }
878 case FieldDescriptor::CPPTYPE_INT64: {
879 int64_t value = _GetDescriptor(self)->default_value_int64();
880 result = PyLong_FromLongLong(value);
881 break;
882 }
883 case FieldDescriptor::CPPTYPE_UINT32: {
884 uint32_t value = _GetDescriptor(self)->default_value_uint32();
885 result = PyLong_FromSsize_t(value);
886 break;
887 }
888 case FieldDescriptor::CPPTYPE_UINT64: {
889 uint64_t value = _GetDescriptor(self)->default_value_uint64();
890 result = PyLong_FromUnsignedLongLong(value);
891 break;
892 }
893 case FieldDescriptor::CPPTYPE_FLOAT: {
894 float value = _GetDescriptor(self)->default_value_float();
895 result = PyFloat_FromDouble(value);
896 break;
897 }
898 case FieldDescriptor::CPPTYPE_DOUBLE: {
899 double value = _GetDescriptor(self)->default_value_double();
900 result = PyFloat_FromDouble(value);
901 break;
902 }
903 case FieldDescriptor::CPPTYPE_BOOL: {
904 bool value = _GetDescriptor(self)->default_value_bool();
905 result = PyBool_FromLong(value);
906 break;
907 }
908 case FieldDescriptor::CPPTYPE_STRING: {
909 result = ToStringObject(_GetDescriptor(self),
910 _GetDescriptor(self)->default_value_string());
911 break;
912 }
913 case FieldDescriptor::CPPTYPE_ENUM: {
914 const EnumValueDescriptor* value =
915 _GetDescriptor(self)->default_value_enum();
916 result = PyLong_FromLong(value->number());
917 break;
918 }
919 case FieldDescriptor::CPPTYPE_MESSAGE: {
920 Py_RETURN_NONE;
921 break;
922 }
923 default:
924 PyErr_Format(PyExc_NotImplementedError, "default value for %s",
925 std::string(_GetDescriptor(self)->full_name()).c_str());
926 return nullptr;
927 }
928 return result;
929 }
930
GetCDescriptor(PyObject * self,void * closure)931 static PyObject* GetCDescriptor(PyObject *self, void *closure) {
932 Py_INCREF(self);
933 return self;
934 }
935
GetEnumType(PyBaseDescriptor * self,void * closure)936 static PyObject *GetEnumType(PyBaseDescriptor *self, void *closure) {
937 const EnumDescriptor* enum_type = _GetDescriptor(self)->enum_type();
938 if (enum_type) {
939 return PyEnumDescriptor_FromDescriptor(enum_type);
940 } else {
941 Py_RETURN_NONE;
942 }
943 }
944
SetEnumType(PyBaseDescriptor * self,PyObject * value,void * closure)945 static int SetEnumType(PyBaseDescriptor *self, PyObject *value, void *closure) {
946 return CheckCalledFromGeneratedFile("enum_type");
947 }
948
GetMessageType(PyBaseDescriptor * self,void * closure)949 static PyObject *GetMessageType(PyBaseDescriptor *self, void *closure) {
950 const Descriptor* message_type = _GetDescriptor(self)->message_type();
951 if (message_type) {
952 return PyMessageDescriptor_FromDescriptor(message_type);
953 } else {
954 Py_RETURN_NONE;
955 }
956 }
957
SetMessageType(PyBaseDescriptor * self,PyObject * value,void * closure)958 static int SetMessageType(PyBaseDescriptor *self, PyObject *value,
959 void *closure) {
960 return CheckCalledFromGeneratedFile("message_type");
961 }
962
GetContainingType(PyBaseDescriptor * self,void * closure)963 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
964 const Descriptor* containing_type =
965 _GetDescriptor(self)->containing_type();
966 if (containing_type) {
967 return PyMessageDescriptor_FromDescriptor(containing_type);
968 } else {
969 Py_RETURN_NONE;
970 }
971 }
972
SetContainingType(PyBaseDescriptor * self,PyObject * value,void * closure)973 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
974 void *closure) {
975 return CheckCalledFromGeneratedFile("containing_type");
976 }
977
GetExtensionScope(PyBaseDescriptor * self,void * closure)978 static PyObject* GetExtensionScope(PyBaseDescriptor *self, void *closure) {
979 const auto* desc = _GetDescriptor(self);
980 const Descriptor* extension_scope =
981 desc->is_extension() ? desc->extension_scope() : nullptr;
982 if (extension_scope) {
983 return PyMessageDescriptor_FromDescriptor(extension_scope);
984 } else {
985 Py_RETURN_NONE;
986 }
987 }
988
GetContainingOneof(PyBaseDescriptor * self,void * closure)989 static PyObject* GetContainingOneof(PyBaseDescriptor *self, void *closure) {
990 const OneofDescriptor* containing_oneof =
991 _GetDescriptor(self)->containing_oneof();
992 if (containing_oneof) {
993 return PyOneofDescriptor_FromDescriptor(containing_oneof);
994 } else {
995 Py_RETURN_NONE;
996 }
997 }
998
SetContainingOneof(PyBaseDescriptor * self,PyObject * value,void * closure)999 static int SetContainingOneof(PyBaseDescriptor *self, PyObject *value,
1000 void *closure) {
1001 return CheckCalledFromGeneratedFile("containing_oneof");
1002 }
1003
GetHasOptions(PyBaseDescriptor * self,void * closure)1004 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
1005 const FieldOptions& options(_GetDescriptor(self)->options());
1006 if (&options != &FieldOptions::default_instance()) {
1007 Py_RETURN_TRUE;
1008 } else {
1009 Py_RETURN_FALSE;
1010 }
1011 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1012 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
1013 void *closure) {
1014 return CheckCalledFromGeneratedFile("has_options");
1015 }
1016
GetHasPresence(PyBaseDescriptor * self,void * closure)1017 static PyObject* GetHasPresence(PyBaseDescriptor* self, void* closure) {
1018 if (_GetDescriptor(self)->has_presence()) {
1019 Py_RETURN_TRUE;
1020 } else {
1021 Py_RETURN_FALSE;
1022 }
1023 }
1024
GetOptions(PyBaseDescriptor * self)1025 static PyObject* GetOptions(PyBaseDescriptor *self) {
1026 return GetOrBuildOptions(_GetDescriptor(self));
1027 }
1028
GetFeatures(PyBaseDescriptor * self)1029 static PyObject* GetFeatures(PyBaseDescriptor* self) {
1030 return GetFeaturesImpl(_GetDescriptor(self));
1031 }
1032
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1033 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
1034 void *closure) {
1035 return CheckCalledFromGeneratedFile("_options");
1036 }
1037
SetSerializedOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1038 static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
1039 void *closure) {
1040 return CheckCalledFromGeneratedFile("_serialized_options");
1041 }
1042
1043 static PyGetSetDef Getters[] = {
1044 {"full_name", (getter)GetFullName, nullptr, "Full name"},
1045 {"name", (getter)GetName, nullptr, "Unqualified name"},
1046 {"camelcase_name", (getter)GetCamelcaseName, nullptr, "Camelcase name"},
1047 {"json_name", (getter)GetJsonName, nullptr, "Json name"},
1048 {"file", (getter)GetFile, nullptr, "File Descriptor"},
1049 {"type", (getter)GetType, nullptr, "C++ Type"},
1050 {"cpp_type", (getter)GetCppType, nullptr, "C++ Type"},
1051 {"label", (getter)GetLabel, nullptr, "Label"},
1052 {"number", (getter)GetNumber, nullptr, "Number"},
1053 {"index", (getter)GetIndex, nullptr, "Index"},
1054 {"default_value", (getter)GetDefaultValue, nullptr, "Default Value"},
1055 {"has_default_value", (getter)HasDefaultValue},
1056 {"is_extension", (getter)IsExtension, nullptr, "ID"},
1057 {"is_packed", (getter)IsPacked, nullptr, "Is Packed"},
1058 {"id", (getter)GetID, nullptr, "ID"},
1059 {"_cdescriptor", (getter)GetCDescriptor, nullptr, "HAACK REMOVE ME"},
1060
1061 {"message_type", (getter)GetMessageType, (setter)SetMessageType,
1062 "Message type"},
1063 {"enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"},
1064 {"containing_type", (getter)GetContainingType, (setter)SetContainingType,
1065 "Containing type"},
1066 {"extension_scope", (getter)GetExtensionScope, (setter) nullptr,
1067 "Extension scope"},
1068 {"containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof,
1069 "Containing oneof"},
1070 {"has_options", (getter)GetHasOptions, (setter)SetHasOptions,
1071 "Has Options"},
1072 {"has_presence", (getter)GetHasPresence, (setter) nullptr, "Has Presence"},
1073 {"_options", (getter) nullptr, (setter)SetOptions, "Options"},
1074 {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
1075 "Serialized Options"},
1076 {nullptr},
1077 };
1078
1079 static PyMethodDef Methods[] = {
1080 {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS},
1081 {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS},
1082 {nullptr},
1083 };
1084
1085 } // namespace field_descriptor
1086
1087 PyTypeObject PyFieldDescriptor_Type = {
1088 PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
1089 ".FieldDescriptor", // tp_name
1090 sizeof(PyBaseDescriptor), // tp_basicsize
1091 0, // tp_itemsize
1092 nullptr, // tp_dealloc
1093 #if PY_VERSION_HEX < 0x03080000
1094 nullptr, // tp_print
1095 #else
1096 0, // tp_vectorcall_offset
1097 #endif
1098 nullptr, // tp_getattr
1099 nullptr, // tp_setattr
1100 nullptr, // tp_compare
1101 nullptr, // tp_repr
1102 nullptr, // tp_as_number
1103 nullptr, // tp_as_sequence
1104 nullptr, // tp_as_mapping
1105 nullptr, // tp_hash
1106 nullptr, // tp_call
1107 nullptr, // tp_str
1108 nullptr, // tp_getattro
1109 nullptr, // tp_setattro
1110 nullptr, // tp_as_buffer
1111 Py_TPFLAGS_DEFAULT, // tp_flags
1112 "A Field Descriptor", // tp_doc
1113 nullptr, // tp_traverse
1114 nullptr, // tp_clear
1115 nullptr, // tp_richcompare
1116 0, // tp_weaklistoffset
1117 nullptr, // tp_iter
1118 nullptr, // tp_iternext
1119 field_descriptor::Methods, // tp_methods
1120 nullptr, // tp_members
1121 field_descriptor::Getters, // tp_getset
1122 &descriptor::PyBaseDescriptor_Type, // tp_base
1123 };
1124
PyFieldDescriptor_FromDescriptor(const FieldDescriptor * field_descriptor)1125 PyObject* PyFieldDescriptor_FromDescriptor(
1126 const FieldDescriptor* field_descriptor) {
1127 return descriptor::NewInternedDescriptor(&PyFieldDescriptor_Type,
1128 field_descriptor, nullptr);
1129 }
1130
PyFieldDescriptor_AsDescriptor(PyObject * obj)1131 const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj) {
1132 if (!PyObject_TypeCheck(obj, &PyFieldDescriptor_Type)) {
1133 PyErr_SetString(PyExc_TypeError, "Not a FieldDescriptor");
1134 return nullptr;
1135 }
1136 return reinterpret_cast<const FieldDescriptor*>(
1137 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
1138 }
1139
1140 namespace enum_descriptor {
1141
1142 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)1143 static const EnumDescriptor* _GetDescriptor(
1144 PyBaseDescriptor *self) {
1145 return reinterpret_cast<const EnumDescriptor*>(self->descriptor);
1146 }
1147
GetFullName(PyBaseDescriptor * self,void * closure)1148 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
1149 return PyString_FromCppString(_GetDescriptor(self)->full_name());
1150 }
1151
GetName(PyBaseDescriptor * self,void * closure)1152 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
1153 return PyString_FromCppString(_GetDescriptor(self)->name());
1154 }
1155
GetFile(PyBaseDescriptor * self,void * closure)1156 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
1157 return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
1158 }
1159
GetEnumvaluesByName(PyBaseDescriptor * self,void * closure)1160 static PyObject* GetEnumvaluesByName(PyBaseDescriptor* self, void *closure) {
1161 return NewEnumValuesByName(_GetDescriptor(self));
1162 }
1163
GetEnumvaluesByNumber(PyBaseDescriptor * self,void * closure)1164 static PyObject* GetEnumvaluesByNumber(PyBaseDescriptor* self, void *closure) {
1165 return NewEnumValuesByNumber(_GetDescriptor(self));
1166 }
1167
GetEnumvaluesSeq(PyBaseDescriptor * self,void * closure)1168 static PyObject* GetEnumvaluesSeq(PyBaseDescriptor* self, void *closure) {
1169 return NewEnumValuesSeq(_GetDescriptor(self));
1170 }
1171
GetContainingType(PyBaseDescriptor * self,void * closure)1172 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
1173 const Descriptor* containing_type =
1174 _GetDescriptor(self)->containing_type();
1175 if (containing_type) {
1176 return PyMessageDescriptor_FromDescriptor(containing_type);
1177 } else {
1178 Py_RETURN_NONE;
1179 }
1180 }
1181
SetContainingType(PyBaseDescriptor * self,PyObject * value,void * closure)1182 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
1183 void *closure) {
1184 return CheckCalledFromGeneratedFile("containing_type");
1185 }
1186
1187
GetHasOptions(PyBaseDescriptor * self,void * closure)1188 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
1189 const EnumOptions& options(_GetDescriptor(self)->options());
1190 if (&options != &EnumOptions::default_instance()) {
1191 Py_RETURN_TRUE;
1192 } else {
1193 Py_RETURN_FALSE;
1194 }
1195 }
1196
GetIsClosed(PyBaseDescriptor * self,void * closure)1197 static PyObject* GetIsClosed(PyBaseDescriptor* self, void* closure) {
1198 return PyBool_FromLong(_GetDescriptor(self)->is_closed());
1199 }
1200
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1201 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
1202 void *closure) {
1203 return CheckCalledFromGeneratedFile("has_options");
1204 }
1205
GetOptions(PyBaseDescriptor * self)1206 static PyObject* GetOptions(PyBaseDescriptor *self) {
1207 return GetOrBuildOptions(_GetDescriptor(self));
1208 }
1209
GetFeatures(PyBaseDescriptor * self)1210 static PyObject* GetFeatures(PyBaseDescriptor* self) {
1211 return GetFeaturesImpl(_GetDescriptor(self));
1212 }
1213
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1214 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
1215 void *closure) {
1216 return CheckCalledFromGeneratedFile("_options");
1217 }
1218
SetSerializedOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1219 static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
1220 void *closure) {
1221 return CheckCalledFromGeneratedFile("_serialized_options");
1222 }
1223
CopyToProto(PyBaseDescriptor * self,PyObject * target)1224 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
1225 return CopyToPythonProto<EnumDescriptorProto>(_GetDescriptor(self), target);
1226 }
1227
1228 static PyMethodDef Methods[] = {
1229 {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS},
1230 {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS},
1231 {"CopyToProto", (PyCFunction)CopyToProto, METH_O},
1232 {nullptr},
1233 };
1234
1235 static PyGetSetDef Getters[] = {
1236 {"full_name", (getter)GetFullName, nullptr, "Full name"},
1237 {"name", (getter)GetName, nullptr, "last name"},
1238 {"file", (getter)GetFile, nullptr, "File descriptor"},
1239 {"values", (getter)GetEnumvaluesSeq, nullptr, "values"},
1240 {"values_by_name", (getter)GetEnumvaluesByName, nullptr,
1241 "Enum values by name"},
1242 {"values_by_number", (getter)GetEnumvaluesByNumber, nullptr,
1243 "Enum values by number"},
1244
1245 {"containing_type", (getter)GetContainingType, (setter)SetContainingType,
1246 "Containing type"},
1247 {"has_options", (getter)GetHasOptions, (setter)SetHasOptions,
1248 "Has Options"},
1249 {"is_closed", (getter)GetIsClosed, nullptr, "If the enum is closed"},
1250 {"_options", (getter) nullptr, (setter)SetOptions, "Options"},
1251 {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
1252 "Serialized Options"},
1253 {nullptr},
1254 };
1255
1256 } // namespace enum_descriptor
1257
1258 PyTypeObject PyEnumDescriptor_Type = {
1259 PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
1260 ".EnumDescriptor", // tp_name
1261 sizeof(PyBaseDescriptor), // tp_basicsize
1262 0, // tp_itemsize
1263 nullptr, // tp_dealloc
1264 #if PY_VERSION_HEX < 0x03080000
1265 nullptr, // tp_print
1266 #else
1267 0, // tp_vectorcall_offset
1268 #endif
1269 nullptr, // tp_getattr
1270 nullptr, // tp_setattr
1271 nullptr, // tp_compare
1272 nullptr, // tp_repr
1273 nullptr, // tp_as_number
1274 nullptr, // tp_as_sequence
1275 nullptr, // tp_as_mapping
1276 nullptr, // tp_hash
1277 nullptr, // tp_call
1278 nullptr, // tp_str
1279 nullptr, // tp_getattro
1280 nullptr, // tp_setattro
1281 nullptr, // tp_as_buffer
1282 Py_TPFLAGS_DEFAULT, // tp_flags
1283 "A Enum Descriptor", // tp_doc
1284 nullptr, // tp_traverse
1285 nullptr, // tp_clear
1286 nullptr, // tp_richcompare
1287 0, // tp_weaklistoffset
1288 nullptr, // tp_iter
1289 nullptr, // tp_iternext
1290 enum_descriptor::Methods, // tp_methods
1291 nullptr, // tp_members
1292 enum_descriptor::Getters, // tp_getset
1293 &descriptor::PyBaseDescriptor_Type, // tp_base
1294 };
1295
PyEnumDescriptor_FromDescriptor(const EnumDescriptor * enum_descriptor)1296 PyObject* PyEnumDescriptor_FromDescriptor(
1297 const EnumDescriptor* enum_descriptor) {
1298 return descriptor::NewInternedDescriptor(&PyEnumDescriptor_Type,
1299 enum_descriptor, nullptr);
1300 }
1301
PyEnumDescriptor_AsDescriptor(PyObject * obj)1302 const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj) {
1303 if (!PyObject_TypeCheck(obj, &PyEnumDescriptor_Type)) {
1304 PyErr_SetString(PyExc_TypeError, "Not an EnumDescriptor");
1305 return nullptr;
1306 }
1307 return reinterpret_cast<const EnumDescriptor*>(
1308 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
1309 }
1310
1311 namespace enumvalue_descriptor {
1312
1313 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)1314 static const EnumValueDescriptor* _GetDescriptor(
1315 PyBaseDescriptor *self) {
1316 return reinterpret_cast<const EnumValueDescriptor*>(self->descriptor);
1317 }
1318
GetName(PyBaseDescriptor * self,void * closure)1319 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
1320 return PyString_FromCppString(_GetDescriptor(self)->name());
1321 }
1322
GetNumber(PyBaseDescriptor * self,void * closure)1323 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
1324 return PyLong_FromLong(_GetDescriptor(self)->number());
1325 }
1326
GetIndex(PyBaseDescriptor * self,void * closure)1327 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
1328 return PyLong_FromLong(_GetDescriptor(self)->index());
1329 }
1330
GetType(PyBaseDescriptor * self,void * closure)1331 static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
1332 return PyEnumDescriptor_FromDescriptor(_GetDescriptor(self)->type());
1333 }
1334
GetHasOptions(PyBaseDescriptor * self,void * closure)1335 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
1336 const EnumValueOptions& options(_GetDescriptor(self)->options());
1337 if (&options != &EnumValueOptions::default_instance()) {
1338 Py_RETURN_TRUE;
1339 } else {
1340 Py_RETURN_FALSE;
1341 }
1342 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1343 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
1344 void *closure) {
1345 return CheckCalledFromGeneratedFile("has_options");
1346 }
1347
GetOptions(PyBaseDescriptor * self)1348 static PyObject* GetOptions(PyBaseDescriptor *self) {
1349 return GetOrBuildOptions(_GetDescriptor(self));
1350 }
1351
GetFeatures(PyBaseDescriptor * self)1352 static PyObject* GetFeatures(PyBaseDescriptor* self) {
1353 return GetFeaturesImpl(_GetDescriptor(self));
1354 }
1355
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1356 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
1357 void *closure) {
1358 return CheckCalledFromGeneratedFile("_options");
1359 }
1360
SetSerializedOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1361 static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
1362 void *closure) {
1363 return CheckCalledFromGeneratedFile("_serialized_options");
1364 }
1365
1366 static PyGetSetDef Getters[] = {
1367 {"name", (getter)GetName, nullptr, "name"},
1368 {"number", (getter)GetNumber, nullptr, "number"},
1369 {"index", (getter)GetIndex, nullptr, "index"},
1370 {"type", (getter)GetType, nullptr, "index"},
1371
1372 {"has_options", (getter)GetHasOptions, (setter)SetHasOptions,
1373 "Has Options"},
1374 {"_options", (getter) nullptr, (setter)SetOptions, "Options"},
1375 {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
1376 "Serialized Options"},
1377 {nullptr},
1378 };
1379
1380 static PyMethodDef Methods[] = {
1381 {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS},
1382 {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS},
1383 {nullptr},
1384 };
1385
1386 } // namespace enumvalue_descriptor
1387
1388 PyTypeObject PyEnumValueDescriptor_Type = {
1389 PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
1390 ".EnumValueDescriptor", // tp_name
1391 sizeof(PyBaseDescriptor), // tp_basicsize
1392 0, // tp_itemsize
1393 nullptr, // tp_dealloc
1394 #if PY_VERSION_HEX < 0x03080000
1395 nullptr, // tp_print
1396 #else
1397 0, // tp_vectorcall_offset
1398 #endif
1399 nullptr, // tp_getattr
1400 nullptr, // tp_setattr
1401 nullptr, // tp_compare
1402 nullptr, // tp_repr
1403 nullptr, // tp_as_number
1404 nullptr, // tp_as_sequence
1405 nullptr, // tp_as_mapping
1406 nullptr, // tp_hash
1407 nullptr, // tp_call
1408 nullptr, // tp_str
1409 nullptr, // tp_getattro
1410 nullptr, // tp_setattro
1411 nullptr, // tp_as_buffer
1412 Py_TPFLAGS_DEFAULT, // tp_flags
1413 "A EnumValue Descriptor", // tp_doc
1414 nullptr, // tp_traverse
1415 nullptr, // tp_clear
1416 nullptr, // tp_richcompare
1417 0, // tp_weaklistoffset
1418 nullptr, // tp_iter
1419 nullptr, // tp_iternext
1420 enumvalue_descriptor::Methods, // tp_methods
1421 nullptr, // tp_members
1422 enumvalue_descriptor::Getters, // tp_getset
1423 &descriptor::PyBaseDescriptor_Type, // tp_base
1424 };
1425
PyEnumValueDescriptor_FromDescriptor(const EnumValueDescriptor * enumvalue_descriptor)1426 PyObject* PyEnumValueDescriptor_FromDescriptor(
1427 const EnumValueDescriptor* enumvalue_descriptor) {
1428 return descriptor::NewInternedDescriptor(&PyEnumValueDescriptor_Type,
1429 enumvalue_descriptor, nullptr);
1430 }
1431
1432 namespace file_descriptor {
1433
1434 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyFileDescriptor * self)1435 static const FileDescriptor* _GetDescriptor(PyFileDescriptor *self) {
1436 return reinterpret_cast<const FileDescriptor*>(self->base.descriptor);
1437 }
1438
Dealloc(PyFileDescriptor * self)1439 static void Dealloc(PyFileDescriptor* self) {
1440 Py_XDECREF(self->serialized_pb);
1441 descriptor::Dealloc(reinterpret_cast<PyObject*>(self));
1442 }
1443
GetPool(PyFileDescriptor * self,void * closure)1444 static PyObject* GetPool(PyFileDescriptor *self, void *closure) {
1445 PyObject* pool = reinterpret_cast<PyObject*>(
1446 GetDescriptorPool_FromPool(_GetDescriptor(self)->pool()));
1447 Py_XINCREF(pool);
1448 return pool;
1449 }
1450
GetName(PyFileDescriptor * self,void * closure)1451 static PyObject* GetName(PyFileDescriptor *self, void *closure) {
1452 return PyString_FromCppString(_GetDescriptor(self)->name());
1453 }
1454
GetPackage(PyFileDescriptor * self,void * closure)1455 static PyObject* GetPackage(PyFileDescriptor *self, void *closure) {
1456 return PyString_FromCppString(_GetDescriptor(self)->package());
1457 }
1458
GetSerializedPb(PyFileDescriptor * self,void * closure)1459 static PyObject* GetSerializedPb(PyFileDescriptor *self, void *closure) {
1460 PyObject *serialized_pb = self->serialized_pb;
1461 if (serialized_pb != nullptr) {
1462 Py_INCREF(serialized_pb);
1463 return serialized_pb;
1464 }
1465 FileDescriptorProto file_proto;
1466 _GetDescriptor(self)->CopyTo(&file_proto);
1467 std::string contents;
1468 file_proto.SerializePartialToString(&contents);
1469 self->serialized_pb = PyBytes_FromStringAndSize(
1470 contents.c_str(), contents.size());
1471 if (self->serialized_pb == nullptr) {
1472 return nullptr;
1473 }
1474 Py_INCREF(self->serialized_pb);
1475 return self->serialized_pb;
1476 }
1477
GetMessageTypesByName(PyFileDescriptor * self,void * closure)1478 static PyObject* GetMessageTypesByName(PyFileDescriptor* self, void *closure) {
1479 return NewFileMessageTypesByName(_GetDescriptor(self));
1480 }
1481
GetEnumTypesByName(PyFileDescriptor * self,void * closure)1482 static PyObject* GetEnumTypesByName(PyFileDescriptor* self, void *closure) {
1483 return NewFileEnumTypesByName(_GetDescriptor(self));
1484 }
1485
GetExtensionsByName(PyFileDescriptor * self,void * closure)1486 static PyObject* GetExtensionsByName(PyFileDescriptor* self, void *closure) {
1487 return NewFileExtensionsByName(_GetDescriptor(self));
1488 }
1489
GetServicesByName(PyFileDescriptor * self,void * closure)1490 static PyObject* GetServicesByName(PyFileDescriptor* self, void *closure) {
1491 return NewFileServicesByName(_GetDescriptor(self));
1492 }
1493
GetDependencies(PyFileDescriptor * self,void * closure)1494 static PyObject* GetDependencies(PyFileDescriptor* self, void *closure) {
1495 return NewFileDependencies(_GetDescriptor(self));
1496 }
1497
GetPublicDependencies(PyFileDescriptor * self,void * closure)1498 static PyObject* GetPublicDependencies(PyFileDescriptor* self, void *closure) {
1499 return NewFilePublicDependencies(_GetDescriptor(self));
1500 }
1501
GetHasOptions(PyFileDescriptor * self,void * closure)1502 static PyObject* GetHasOptions(PyFileDescriptor *self, void *closure) {
1503 const FileOptions& options(_GetDescriptor(self)->options());
1504 if (&options != &FileOptions::default_instance()) {
1505 Py_RETURN_TRUE;
1506 } else {
1507 Py_RETURN_FALSE;
1508 }
1509 }
SetHasOptions(PyFileDescriptor * self,PyObject * value,void * closure)1510 static int SetHasOptions(PyFileDescriptor *self, PyObject *value,
1511 void *closure) {
1512 return CheckCalledFromGeneratedFile("has_options");
1513 }
1514
GetDebugString(PyFileDescriptor * self)1515 static PyObject* GetDebugString(PyFileDescriptor* self) {
1516 PyErr_Warn(nullptr,
1517 "GetDebugString() API is deprecated. This API only "
1518 "exists in protobuf c++ and does not exists in pure python, upb "
1519 "or any other languages. GetDebugString() for python cpp "
1520 "extension will be removed in Jan 2025");
1521 return PyString_FromCppString(_GetDescriptor(self)->DebugString());
1522 }
1523
GetOptions(PyFileDescriptor * self)1524 static PyObject* GetOptions(PyFileDescriptor *self) {
1525 return GetOrBuildOptions(_GetDescriptor(self));
1526 }
1527
GetFeatures(PyFileDescriptor * self)1528 static PyObject* GetFeatures(PyFileDescriptor* self) {
1529 return GetFeaturesImpl(_GetDescriptor(self));
1530 }
1531
SetOptions(PyFileDescriptor * self,PyObject * value,void * closure)1532 static int SetOptions(PyFileDescriptor *self, PyObject *value,
1533 void *closure) {
1534 return CheckCalledFromGeneratedFile("_options");
1535 }
1536
SetSerializedOptions(PyFileDescriptor * self,PyObject * value,void * closure)1537 static int SetSerializedOptions(PyFileDescriptor *self, PyObject *value,
1538 void *closure) {
1539 return CheckCalledFromGeneratedFile("_serialized_options");
1540 }
1541
CopyToProto(PyFileDescriptor * self,PyObject * target)1542 static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) {
1543 return CopyToPythonProto<FileDescriptorProto>(_GetDescriptor(self), target);
1544 }
1545
1546 static PyGetSetDef Getters[] = {
1547 {"pool", (getter)GetPool, nullptr, "pool"},
1548 {"name", (getter)GetName, nullptr, "name"},
1549 {"package", (getter)GetPackage, nullptr, "package"},
1550 {"serialized_pb", (getter)GetSerializedPb},
1551 {"message_types_by_name", (getter)GetMessageTypesByName, nullptr,
1552 "Messages by name"},
1553 {"enum_types_by_name", (getter)GetEnumTypesByName, nullptr,
1554 "Enums by name"},
1555 {"extensions_by_name", (getter)GetExtensionsByName, nullptr,
1556 "Extensions by name"},
1557 {"services_by_name", (getter)GetServicesByName, nullptr,
1558 "Services by name"},
1559 {"dependencies", (getter)GetDependencies, nullptr, "Dependencies"},
1560 {"public_dependencies", (getter)GetPublicDependencies, nullptr,
1561 "Dependencies"},
1562
1563 {"has_options", (getter)GetHasOptions, (setter)SetHasOptions,
1564 "Has Options"},
1565 {"_options", (getter) nullptr, (setter)SetOptions, "Options"},
1566 {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
1567 "Serialized Options"},
1568 {nullptr},
1569 };
1570
1571 static PyMethodDef Methods[] = {
1572 {"GetDebugString", (PyCFunction)GetDebugString, METH_NOARGS},
1573 {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS},
1574 {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS},
1575 {"CopyToProto", (PyCFunction)CopyToProto, METH_O},
1576 {nullptr},
1577 };
1578
1579 } // namespace file_descriptor
1580
1581 PyTypeObject PyFileDescriptor_Type = {
1582 PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
1583 ".FileDescriptor", // tp_name
1584 sizeof(PyFileDescriptor), // tp_basicsize
1585 0, // tp_itemsize
1586 (destructor)file_descriptor::Dealloc, // tp_dealloc
1587 #if PY_VERSION_HEX < 0x03080000
1588 nullptr, // tp_print
1589 #else
1590 0, // tp_vectorcall_offset
1591 #endif
1592 nullptr, // tp_getattr
1593 nullptr, // tp_setattr
1594 nullptr, // tp_compare
1595 nullptr, // tp_repr
1596 nullptr, // tp_as_number
1597 nullptr, // tp_as_sequence
1598 nullptr, // tp_as_mapping
1599 nullptr, // tp_hash
1600 nullptr, // tp_call
1601 nullptr, // tp_str
1602 nullptr, // tp_getattro
1603 nullptr, // tp_setattro
1604 nullptr, // tp_as_buffer
1605 Py_TPFLAGS_DEFAULT, // tp_flags
1606 "A File Descriptor", // tp_doc
1607 nullptr, // tp_traverse
1608 nullptr, // tp_clear
1609 nullptr, // tp_richcompare
1610 0, // tp_weaklistoffset
1611 nullptr, // tp_iter
1612 nullptr, // tp_iternext
1613 file_descriptor::Methods, // tp_methods
1614 nullptr, // tp_members
1615 file_descriptor::Getters, // tp_getset
1616 &descriptor::PyBaseDescriptor_Type, // tp_base
1617 nullptr, // tp_dict
1618 nullptr, // tp_descr_get
1619 nullptr, // tp_descr_set
1620 0, // tp_dictoffset
1621 nullptr, // tp_init
1622 nullptr, // tp_alloc
1623 nullptr, // tp_new
1624 PyObject_GC_Del, // tp_free
1625 };
1626
PyFileDescriptor_FromDescriptor(const FileDescriptor * file_descriptor)1627 PyObject* PyFileDescriptor_FromDescriptor(
1628 const FileDescriptor* file_descriptor) {
1629 return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor,
1630 nullptr);
1631 }
1632
PyFileDescriptor_FromDescriptorWithSerializedPb(const FileDescriptor * file_descriptor,PyObject * serialized_pb)1633 PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb(
1634 const FileDescriptor* file_descriptor, PyObject *serialized_pb) {
1635 bool was_created;
1636 PyObject* py_descriptor = descriptor::NewInternedDescriptor(
1637 &PyFileDescriptor_Type, file_descriptor, &was_created);
1638 if (py_descriptor == nullptr) {
1639 return nullptr;
1640 }
1641 if (was_created) {
1642 PyFileDescriptor* cfile_descriptor =
1643 reinterpret_cast<PyFileDescriptor*>(py_descriptor);
1644 Py_XINCREF(serialized_pb);
1645 cfile_descriptor->serialized_pb = serialized_pb;
1646 }
1647 // TODO: In the case of a cached object, check that serialized_pb
1648 // is the same as before.
1649
1650 return py_descriptor;
1651 }
1652
PyFileDescriptor_AsDescriptor(PyObject * obj)1653 const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj) {
1654 if (!PyObject_TypeCheck(obj, &PyFileDescriptor_Type)) {
1655 PyErr_SetString(PyExc_TypeError, "Not a FileDescriptor");
1656 return nullptr;
1657 }
1658 return reinterpret_cast<const FileDescriptor*>(
1659 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
1660 }
1661
1662 namespace oneof_descriptor {
1663
1664 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)1665 static const OneofDescriptor* _GetDescriptor(
1666 PyBaseDescriptor *self) {
1667 return reinterpret_cast<const OneofDescriptor*>(self->descriptor);
1668 }
1669
GetName(PyBaseDescriptor * self,void * closure)1670 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
1671 return PyString_FromCppString(_GetDescriptor(self)->name());
1672 }
1673
GetFullName(PyBaseDescriptor * self,void * closure)1674 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
1675 return PyString_FromCppString(_GetDescriptor(self)->full_name());
1676 }
1677
GetIndex(PyBaseDescriptor * self,void * closure)1678 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
1679 return PyLong_FromLong(_GetDescriptor(self)->index());
1680 }
1681
GetFields(PyBaseDescriptor * self,void * closure)1682 static PyObject* GetFields(PyBaseDescriptor* self, void *closure) {
1683 return NewOneofFieldsSeq(_GetDescriptor(self));
1684 }
1685
GetContainingType(PyBaseDescriptor * self,void * closure)1686 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
1687 const Descriptor* containing_type =
1688 _GetDescriptor(self)->containing_type();
1689 if (containing_type) {
1690 return PyMessageDescriptor_FromDescriptor(containing_type);
1691 } else {
1692 Py_RETURN_NONE;
1693 }
1694 }
1695
GetHasOptions(PyBaseDescriptor * self,void * closure)1696 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
1697 const OneofOptions& options(_GetDescriptor(self)->options());
1698 if (&options != &OneofOptions::default_instance()) {
1699 Py_RETURN_TRUE;
1700 } else {
1701 Py_RETURN_FALSE;
1702 }
1703 }
1704
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1705 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
1706 void *closure) {
1707 return CheckCalledFromGeneratedFile("has_options");
1708 }
1709
GetOptions(PyBaseDescriptor * self)1710 static PyObject* GetOptions(PyBaseDescriptor *self) {
1711 return GetOrBuildOptions(_GetDescriptor(self));
1712 }
1713
GetFeatures(PyBaseDescriptor * self)1714 static PyObject* GetFeatures(PyBaseDescriptor* self) {
1715 return GetFeaturesImpl(_GetDescriptor(self));
1716 }
1717
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1718 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
1719 void *closure) {
1720 return CheckCalledFromGeneratedFile("_options");
1721 }
1722
SetSerializedOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1723 static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
1724 void *closure) {
1725 return CheckCalledFromGeneratedFile("_serialized_options");
1726 }
1727
1728 static PyGetSetDef Getters[] = {
1729 {"name", (getter)GetName, nullptr, "Name"},
1730 {"full_name", (getter)GetFullName, nullptr, "Full name"},
1731 {"index", (getter)GetIndex, nullptr, "Index"},
1732
1733 {"containing_type", (getter)GetContainingType, nullptr, "Containing type"},
1734 {"has_options", (getter)GetHasOptions, (setter)SetHasOptions,
1735 "Has Options"},
1736 {"_options", (getter) nullptr, (setter)SetOptions, "Options"},
1737 {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
1738 "Serialized Options"},
1739 {"fields", (getter)GetFields, nullptr, "Fields"},
1740 {nullptr},
1741 };
1742
1743 static PyMethodDef Methods[] = {
1744 {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS},
1745 {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS},
1746 {nullptr},
1747 };
1748
1749 } // namespace oneof_descriptor
1750
1751 PyTypeObject PyOneofDescriptor_Type = {
1752 PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
1753 ".OneofDescriptor", // tp_name
1754 sizeof(PyBaseDescriptor), // tp_basicsize
1755 0, // tp_itemsize
1756 nullptr, // tp_dealloc
1757 #if PY_VERSION_HEX < 0x03080000
1758 nullptr, // tp_print
1759 #else
1760 0, // tp_vectorcall_offset
1761 #endif
1762 nullptr, // tp_getattr
1763 nullptr, // tp_setattr
1764 nullptr, // tp_compare
1765 nullptr, // tp_repr
1766 nullptr, // tp_as_number
1767 nullptr, // tp_as_sequence
1768 nullptr, // tp_as_mapping
1769 nullptr, // tp_hash
1770 nullptr, // tp_call
1771 nullptr, // tp_str
1772 nullptr, // tp_getattro
1773 nullptr, // tp_setattro
1774 nullptr, // tp_as_buffer
1775 Py_TPFLAGS_DEFAULT, // tp_flags
1776 "A Oneof Descriptor", // tp_doc
1777 nullptr, // tp_traverse
1778 nullptr, // tp_clear
1779 nullptr, // tp_richcompare
1780 0, // tp_weaklistoffset
1781 nullptr, // tp_iter
1782 nullptr, // tp_iternext
1783 oneof_descriptor::Methods, // tp_methods
1784 nullptr, // tp_members
1785 oneof_descriptor::Getters, // tp_getset
1786 &descriptor::PyBaseDescriptor_Type, // tp_base
1787 };
1788
PyOneofDescriptor_FromDescriptor(const OneofDescriptor * oneof_descriptor)1789 PyObject* PyOneofDescriptor_FromDescriptor(
1790 const OneofDescriptor* oneof_descriptor) {
1791 return descriptor::NewInternedDescriptor(&PyOneofDescriptor_Type,
1792 oneof_descriptor, nullptr);
1793 }
1794
1795 namespace service_descriptor {
1796
1797 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)1798 static const ServiceDescriptor* _GetDescriptor(
1799 PyBaseDescriptor *self) {
1800 return reinterpret_cast<const ServiceDescriptor*>(self->descriptor);
1801 }
1802
GetName(PyBaseDescriptor * self,void * closure)1803 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
1804 return PyString_FromCppString(_GetDescriptor(self)->name());
1805 }
1806
GetFullName(PyBaseDescriptor * self,void * closure)1807 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
1808 return PyString_FromCppString(_GetDescriptor(self)->full_name());
1809 }
1810
GetFile(PyBaseDescriptor * self,void * closure)1811 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
1812 return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
1813 }
1814
GetIndex(PyBaseDescriptor * self,void * closure)1815 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
1816 return PyLong_FromLong(_GetDescriptor(self)->index());
1817 }
1818
GetMethods(PyBaseDescriptor * self,void * closure)1819 static PyObject* GetMethods(PyBaseDescriptor* self, void *closure) {
1820 return NewServiceMethodsSeq(_GetDescriptor(self));
1821 }
1822
GetMethodsByName(PyBaseDescriptor * self,void * closure)1823 static PyObject* GetMethodsByName(PyBaseDescriptor* self, void *closure) {
1824 return NewServiceMethodsByName(_GetDescriptor(self));
1825 }
1826
FindMethodByName(PyBaseDescriptor * self,PyObject * arg)1827 static PyObject* FindMethodByName(PyBaseDescriptor *self, PyObject* arg) {
1828 Py_ssize_t name_size;
1829 char* name;
1830 if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
1831 return nullptr;
1832 }
1833
1834 const MethodDescriptor* method_descriptor =
1835 _GetDescriptor(self)->FindMethodByName(
1836 absl::string_view(name, name_size));
1837 if (method_descriptor == nullptr) {
1838 PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
1839 return nullptr;
1840 }
1841
1842 return PyMethodDescriptor_FromDescriptor(method_descriptor);
1843 }
1844
GetOptions(PyBaseDescriptor * self)1845 static PyObject* GetOptions(PyBaseDescriptor *self) {
1846 return GetOrBuildOptions(_GetDescriptor(self));
1847 }
1848
GetFeatures(PyBaseDescriptor * self)1849 static PyObject* GetFeatures(PyBaseDescriptor* self) {
1850 return GetFeaturesImpl(_GetDescriptor(self));
1851 }
1852
CopyToProto(PyBaseDescriptor * self,PyObject * target)1853 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
1854 return CopyToPythonProto<ServiceDescriptorProto>(_GetDescriptor(self),
1855 target);
1856 }
1857
1858 static PyGetSetDef Getters[] = {
1859 {"name", (getter)GetName, nullptr, "Name", nullptr},
1860 {"full_name", (getter)GetFullName, nullptr, "Full name", nullptr},
1861 {"file", (getter)GetFile, nullptr, "File descriptor"},
1862 {"index", (getter)GetIndex, nullptr, "Index", nullptr},
1863 {"methods", (getter)GetMethods, nullptr, "Methods", nullptr},
1864 {"methods_by_name", (getter)GetMethodsByName, nullptr, "Methods by name",
1865 nullptr},
1866 {nullptr},
1867 };
1868
1869 static PyMethodDef Methods[] = {
1870 {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS},
1871 {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS},
1872 {"CopyToProto", (PyCFunction)CopyToProto, METH_O},
1873 {"FindMethodByName", (PyCFunction)FindMethodByName, METH_O},
1874 {nullptr},
1875 };
1876
1877 } // namespace service_descriptor
1878
1879 PyTypeObject PyServiceDescriptor_Type = {
1880 PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
1881 ".ServiceDescriptor", // tp_name
1882 sizeof(PyBaseDescriptor), // tp_basicsize
1883 0, // tp_itemsize
1884 nullptr, // tp_dealloc
1885 #if PY_VERSION_HEX < 0x03080000
1886 nullptr, // tp_print
1887 #else
1888 0, // tp_vectorcall_offset
1889 #endif
1890 nullptr, // tp_getattr
1891 nullptr, // tp_setattr
1892 nullptr, // tp_compare
1893 nullptr, // tp_repr
1894 nullptr, // tp_as_number
1895 nullptr, // tp_as_sequence
1896 nullptr, // tp_as_mapping
1897 nullptr, // tp_hash
1898 nullptr, // tp_call
1899 nullptr, // tp_str
1900 nullptr, // tp_getattro
1901 nullptr, // tp_setattro
1902 nullptr, // tp_as_buffer
1903 Py_TPFLAGS_DEFAULT, // tp_flags
1904 "A Service Descriptor", // tp_doc
1905 nullptr, // tp_traverse
1906 nullptr, // tp_clear
1907 nullptr, // tp_richcompare
1908 0, // tp_weaklistoffset
1909 nullptr, // tp_iter
1910 nullptr, // tp_iternext
1911 service_descriptor::Methods, // tp_methods
1912 nullptr, // tp_members
1913 service_descriptor::Getters, // tp_getset
1914 &descriptor::PyBaseDescriptor_Type, // tp_base
1915 };
1916
PyServiceDescriptor_FromDescriptor(const ServiceDescriptor * service_descriptor)1917 PyObject* PyServiceDescriptor_FromDescriptor(
1918 const ServiceDescriptor* service_descriptor) {
1919 return descriptor::NewInternedDescriptor(&PyServiceDescriptor_Type,
1920 service_descriptor, nullptr);
1921 }
1922
PyServiceDescriptor_AsDescriptor(PyObject * obj)1923 const ServiceDescriptor* PyServiceDescriptor_AsDescriptor(PyObject* obj) {
1924 if (!PyObject_TypeCheck(obj, &PyServiceDescriptor_Type)) {
1925 PyErr_SetString(PyExc_TypeError, "Not a ServiceDescriptor");
1926 return nullptr;
1927 }
1928 return reinterpret_cast<const ServiceDescriptor*>(
1929 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
1930 }
1931
1932 namespace method_descriptor {
1933
1934 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)1935 static const MethodDescriptor* _GetDescriptor(
1936 PyBaseDescriptor *self) {
1937 return reinterpret_cast<const MethodDescriptor*>(self->descriptor);
1938 }
1939
GetName(PyBaseDescriptor * self,void * closure)1940 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
1941 return PyString_FromCppString(_GetDescriptor(self)->name());
1942 }
1943
GetFullName(PyBaseDescriptor * self,void * closure)1944 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
1945 return PyString_FromCppString(_GetDescriptor(self)->full_name());
1946 }
1947
GetIndex(PyBaseDescriptor * self,void * closure)1948 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
1949 return PyLong_FromLong(_GetDescriptor(self)->index());
1950 }
1951
GetContainingService(PyBaseDescriptor * self,void * closure)1952 static PyObject* GetContainingService(PyBaseDescriptor *self, void *closure) {
1953 const ServiceDescriptor* containing_service =
1954 _GetDescriptor(self)->service();
1955 return PyServiceDescriptor_FromDescriptor(containing_service);
1956 }
1957
GetInputType(PyBaseDescriptor * self,void * closure)1958 static PyObject* GetInputType(PyBaseDescriptor *self, void *closure) {
1959 const Descriptor* input_type = _GetDescriptor(self)->input_type();
1960 return PyMessageDescriptor_FromDescriptor(input_type);
1961 }
1962
GetOutputType(PyBaseDescriptor * self,void * closure)1963 static PyObject* GetOutputType(PyBaseDescriptor *self, void *closure) {
1964 const Descriptor* output_type = _GetDescriptor(self)->output_type();
1965 return PyMessageDescriptor_FromDescriptor(output_type);
1966 }
1967
GetClientStreaming(PyBaseDescriptor * self,void * closure)1968 static PyObject* GetClientStreaming(PyBaseDescriptor* self, void* closure) {
1969 return PyBool_FromLong(_GetDescriptor(self)->client_streaming() ? 1 : 0);
1970 }
1971
GetServerStreaming(PyBaseDescriptor * self,void * closure)1972 static PyObject* GetServerStreaming(PyBaseDescriptor* self, void* closure) {
1973 return PyBool_FromLong(_GetDescriptor(self)->server_streaming() ? 1 : 0);
1974 }
1975
GetOptions(PyBaseDescriptor * self)1976 static PyObject* GetOptions(PyBaseDescriptor *self) {
1977 return GetOrBuildOptions(_GetDescriptor(self));
1978 }
1979
GetFeatures(PyBaseDescriptor * self)1980 static PyObject* GetFeatures(PyBaseDescriptor* self) {
1981 return GetFeaturesImpl(_GetDescriptor(self));
1982 }
1983
CopyToProto(PyBaseDescriptor * self,PyObject * target)1984 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
1985 return CopyToPythonProto<MethodDescriptorProto>(_GetDescriptor(self), target);
1986 }
1987
1988 static PyGetSetDef Getters[] = {
1989 {"name", (getter)GetName, nullptr, "Name", nullptr},
1990 {"full_name", (getter)GetFullName, nullptr, "Full name", nullptr},
1991 {"index", (getter)GetIndex, nullptr, "Index", nullptr},
1992 {"containing_service", (getter)GetContainingService, nullptr,
1993 "Containing service", nullptr},
1994 {"input_type", (getter)GetInputType, nullptr, "Input type", nullptr},
1995 {"output_type", (getter)GetOutputType, nullptr, "Output type", nullptr},
1996 {"client_streaming", (getter)GetClientStreaming, nullptr,
1997 "Client streaming", nullptr},
1998 {"server_streaming", (getter)GetServerStreaming, nullptr,
1999 "Server streaming", nullptr},
2000 {nullptr},
2001 };
2002
2003 static PyMethodDef Methods[] = {
2004 {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS},
2005 {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS},
2006 {"CopyToProto", (PyCFunction)CopyToProto, METH_O},
2007 {nullptr},
2008 };
2009
2010 } // namespace method_descriptor
2011
2012 PyTypeObject PyMethodDescriptor_Type = {
2013 PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
2014 ".MethodDescriptor", // tp_name
2015 sizeof(PyBaseDescriptor), // tp_basicsize
2016 0, // tp_itemsize
2017 nullptr, // tp_dealloc
2018 #if PY_VERSION_HEX < 0x03080000
2019 nullptr, // tp_print
2020 #else
2021 0, // tp_vectorcall_offset
2022 #endif
2023 nullptr, // tp_getattr
2024 nullptr, // tp_setattr
2025 nullptr, // tp_compare
2026 nullptr, // tp_repr
2027 nullptr, // tp_as_number
2028 nullptr, // tp_as_sequence
2029 nullptr, // tp_as_mapping
2030 nullptr, // tp_hash
2031 nullptr, // tp_call
2032 nullptr, // tp_str
2033 nullptr, // tp_getattro
2034 nullptr, // tp_setattro
2035 nullptr, // tp_as_buffer
2036 Py_TPFLAGS_DEFAULT, // tp_flags
2037 "A Method Descriptor", // tp_doc
2038 nullptr, // tp_traverse
2039 nullptr, // tp_clear
2040 nullptr, // tp_richcompare
2041 0, // tp_weaklistoffset
2042 nullptr, // tp_iter
2043 nullptr, // tp_iternext
2044 method_descriptor::Methods, // tp_methods
2045 nullptr, // tp_members
2046 method_descriptor::Getters, // tp_getset
2047 &descriptor::PyBaseDescriptor_Type, // tp_base
2048 };
2049
PyMethodDescriptor_FromDescriptor(const MethodDescriptor * method_descriptor)2050 PyObject* PyMethodDescriptor_FromDescriptor(
2051 const MethodDescriptor* method_descriptor) {
2052 return descriptor::NewInternedDescriptor(&PyMethodDescriptor_Type,
2053 method_descriptor, nullptr);
2054 }
2055
2056 // Add a enum values to a type dictionary.
AddEnumValues(PyTypeObject * type,const EnumDescriptor * enum_descriptor)2057 static bool AddEnumValues(PyTypeObject *type,
2058 const EnumDescriptor* enum_descriptor) {
2059 for (int i = 0; i < enum_descriptor->value_count(); ++i) {
2060 const EnumValueDescriptor* value = enum_descriptor->value(i);
2061 ScopedPyObjectPtr obj(PyLong_FromLong(value->number()));
2062 if (obj == nullptr) {
2063 return false;
2064 }
2065 if (PyDict_SetItemString(type->tp_dict, std::string(value->name()).c_str(),
2066 obj.get()) < 0) {
2067 return false;
2068 }
2069 }
2070 return true;
2071 }
2072
AddIntConstant(PyTypeObject * type,const char * name,int value)2073 static bool AddIntConstant(PyTypeObject *type, const char* name, int value) {
2074 ScopedPyObjectPtr obj(PyLong_FromLong(value));
2075 if (PyDict_SetItemString(type->tp_dict, name, obj.get()) < 0) {
2076 return false;
2077 }
2078 return true;
2079 }
2080
2081
InitDescriptor()2082 bool InitDescriptor() {
2083 if (PyType_Ready(&PyMessageDescriptor_Type) < 0)
2084 return false;
2085
2086 if (PyType_Ready(&PyFieldDescriptor_Type) < 0)
2087 return false;
2088
2089 if (!AddEnumValues(&PyFieldDescriptor_Type,
2090 FieldDescriptorProto::Label_descriptor())) {
2091 return false;
2092 }
2093 if (!AddEnumValues(&PyFieldDescriptor_Type,
2094 FieldDescriptorProto::Type_descriptor())) {
2095 return false;
2096 }
2097 #define ADD_FIELDDESC_CONSTANT(NAME) AddIntConstant( \
2098 &PyFieldDescriptor_Type, #NAME, FieldDescriptor::NAME)
2099 if (!ADD_FIELDDESC_CONSTANT(CPPTYPE_INT32) ||
2100 !ADD_FIELDDESC_CONSTANT(CPPTYPE_INT64) ||
2101 !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT32) ||
2102 !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT64) ||
2103 !ADD_FIELDDESC_CONSTANT(CPPTYPE_DOUBLE) ||
2104 !ADD_FIELDDESC_CONSTANT(CPPTYPE_FLOAT) ||
2105 !ADD_FIELDDESC_CONSTANT(CPPTYPE_BOOL) ||
2106 !ADD_FIELDDESC_CONSTANT(CPPTYPE_ENUM) ||
2107 !ADD_FIELDDESC_CONSTANT(CPPTYPE_STRING) ||
2108 !ADD_FIELDDESC_CONSTANT(CPPTYPE_MESSAGE)) {
2109 return false;
2110 }
2111 #undef ADD_FIELDDESC_CONSTANT
2112
2113 if (PyType_Ready(&PyEnumDescriptor_Type) < 0)
2114 return false;
2115
2116 if (PyType_Ready(&PyEnumValueDescriptor_Type) < 0)
2117 return false;
2118
2119 if (PyType_Ready(&PyFileDescriptor_Type) < 0)
2120 return false;
2121
2122 if (PyType_Ready(&PyOneofDescriptor_Type) < 0)
2123 return false;
2124
2125 if (PyType_Ready(&PyServiceDescriptor_Type) < 0)
2126 return false;
2127
2128 if (PyType_Ready(&PyMethodDescriptor_Type) < 0)
2129 return false;
2130
2131 if (!InitDescriptorMappingTypes())
2132 return false;
2133
2134 // Initialize globals defined in this file.
2135 interned_descriptors = new std::unordered_map<const void*, PyObject*>;
2136
2137 return true;
2138 }
2139
2140 } // namespace python
2141 } // namespace protobuf
2142 } // namespace google
2143