• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: petar@google.com (Petar Petrov)
32 
33 #include <Python.h>
34 #include <frameobject.h>
35 #include <string>
36 
37 #include <google/protobuf/io/coded_stream.h>
38 #include <google/protobuf/descriptor.pb.h>
39 #include <google/protobuf/dynamic_message.h>
40 #include <google/protobuf/pyext/descriptor.h>
41 #include <google/protobuf/pyext/descriptor_containers.h>
42 #include <google/protobuf/pyext/descriptor_pool.h>
43 #include <google/protobuf/pyext/message.h>
44 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
45 
46 #if PY_MAJOR_VERSION >= 3
47   #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
48   #define PyString_Check PyUnicode_Check
49   #define PyString_InternFromString PyUnicode_InternFromString
50   #define PyInt_FromLong PyLong_FromLong
51   #define PyInt_FromSize_t PyLong_FromSize_t
52   #if PY_VERSION_HEX < 0x03030000
53     #error "Python 3.0 - 3.2 are not supported."
54   #endif
55   #define PyString_AsStringAndSize(ob, charpp, sizep) \
56     (PyUnicode_Check(ob)? \
57        ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
58        PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
59 #endif
60 
61 namespace google {
62 namespace protobuf {
63 namespace python {
64 
65 // Store interned descriptors, so that the same C++ descriptor yields the same
66 // Python object. Objects are not immortal: this map does not own the
67 // references, and items are deleted when the last reference to the object is
68 // released.
69 // This is enough to support the "is" operator on live objects.
70 // All descriptors are stored here.
71 hash_map<const void*, PyObject*> interned_descriptors;
72 
PyString_FromCppString(const string & str)73 PyObject* PyString_FromCppString(const string& str) {
74   return PyString_FromStringAndSize(str.c_str(), str.size());
75 }
76 
77 // Check that the calling Python code is the global scope of a _pb2.py module.
78 // This function is used to support the current code generated by the proto
79 // compiler, which creates descriptors, then update some properties.
80 // For example:
81 //   message_descriptor = Descriptor(
82 //       name='Message',
83 //       fields = [FieldDescriptor(name='field')]
84 //   message_descriptor.fields[0].containing_type = message_descriptor
85 //
86 // This code is still executed, but the descriptors now have no other storage
87 // than the (const) C++ pointer, and are immutable.
88 // So we let this code pass, by simply ignoring the new value.
89 //
90 // From user code, descriptors still look immutable.
91 //
92 // TODO(amauryfa): Change the proto2 compiler to remove the assignments, and
93 // remove this hack.
_CalledFromGeneratedFile(int stacklevel)94 bool _CalledFromGeneratedFile(int stacklevel) {
95 #ifndef PYPY_VERSION
96   // This check is not critical and is somewhat difficult to implement correctly
97   // in PyPy.
98   PyFrameObject* frame = PyEval_GetFrame();
99   if (frame == NULL) {
100     return false;
101   }
102   while (stacklevel-- > 0) {
103     frame = frame->f_back;
104     if (frame == NULL) {
105       return false;
106     }
107   }
108   if (frame->f_globals != frame->f_locals) {
109     // Not at global module scope
110     return false;
111   }
112 
113   if (frame->f_code->co_filename == NULL) {
114     return false;
115   }
116   char* filename;
117   Py_ssize_t filename_size;
118   if (PyString_AsStringAndSize(frame->f_code->co_filename,
119                                &filename, &filename_size) < 0) {
120     // filename is not a string.
121     PyErr_Clear();
122     return false;
123   }
124   if (filename_size < 7) {
125     // filename is too short.
126     return false;
127   }
128   if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) {
129     // Filename is not ending with _pb2.
130     return false;
131   }
132 #endif
133   return true;
134 }
135 
136 // If the calling code is not a _pb2.py file, raise AttributeError.
137 // To be used in attribute setters.
CheckCalledFromGeneratedFile(const char * attr_name)138 static int CheckCalledFromGeneratedFile(const char* attr_name) {
139   if (_CalledFromGeneratedFile(0)) {
140     return 0;
141   }
142   PyErr_Format(PyExc_AttributeError,
143                "attribute is not writable: %s", attr_name);
144   return -1;
145 }
146 
147 
148 #ifndef PyVarObject_HEAD_INIT
149 #define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
150 #endif
151 #ifndef Py_TYPE
152 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
153 #endif
154 
155 
156 // Helper functions for descriptor objects.
157 
158 // A set of templates to retrieve the C++ FileDescriptor of any descriptor.
159 template<class DescriptorClass>
GetFileDescriptor(const DescriptorClass * descriptor)160 const FileDescriptor* GetFileDescriptor(const DescriptorClass* descriptor) {
161   return descriptor->file();
162 }
163 template<>
GetFileDescriptor(const FileDescriptor * descriptor)164 const FileDescriptor* GetFileDescriptor(const FileDescriptor* descriptor) {
165   return descriptor;
166 }
167 template<>
GetFileDescriptor(const EnumValueDescriptor * descriptor)168 const FileDescriptor* GetFileDescriptor(const EnumValueDescriptor* descriptor) {
169   return descriptor->type()->file();
170 }
171 template<>
GetFileDescriptor(const OneofDescriptor * descriptor)172 const FileDescriptor* GetFileDescriptor(const OneofDescriptor* descriptor) {
173   return descriptor->containing_type()->file();
174 }
175 
176 // Converts options into a Python protobuf, and cache the result.
177 //
178 // This is a bit tricky because options can contain extension fields defined in
179 // the same proto file. In this case the options parsed from the serialized_pb
180 // have unkown fields, and we need to parse them again.
181 //
182 // Always returns a new reference.
183 template<class DescriptorClass>
GetOrBuildOptions(const DescriptorClass * descriptor)184 static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
185   // Options (and their extensions) are completely resolved in the proto file
186   // containing the descriptor.
187   PyDescriptorPool* pool = GetDescriptorPool_FromPool(
188       GetFileDescriptor(descriptor)->pool());
189 
190   hash_map<const void*, PyObject*>* descriptor_options =
191       pool->descriptor_options;
192   // First search in the cache.
193   if (descriptor_options->find(descriptor) != descriptor_options->end()) {
194     PyObject *value = (*descriptor_options)[descriptor];
195     Py_INCREF(value);
196     return value;
197   }
198 
199   // Build the Options object: get its Python class, and make a copy of the C++
200   // read-only instance.
201   const Message& options(descriptor->options());
202   const Descriptor *message_type = options.GetDescriptor();
203   CMessageClass* message_class(
204       cdescriptor_pool::GetMessageClass(pool, message_type));
205   if (message_class == NULL) {
206     // The Options message was not found in the current DescriptorPool.
207     // In this case, there cannot be extensions to these options, and we can
208     // try to use the basic pool instead.
209     PyErr_Clear();
210     message_class = cdescriptor_pool::GetMessageClass(
211       GetDefaultDescriptorPool(), message_type);
212   }
213   if (message_class == NULL) {
214     PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s",
215                  message_type->full_name().c_str());
216     return NULL;
217   }
218   ScopedPyObjectPtr value(
219       PyEval_CallObject(message_class->AsPyObject(), NULL));
220   if (value == NULL) {
221     return NULL;
222   }
223   if (!PyObject_TypeCheck(value.get(), &CMessage_Type)) {
224       PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s",
225                    message_type->full_name().c_str(),
226                    Py_TYPE(value.get())->tp_name);
227       return NULL;
228   }
229   CMessage* cmsg = reinterpret_cast<CMessage*>(value.get());
230 
231   const Reflection* reflection = options.GetReflection();
232   const UnknownFieldSet& unknown_fields(reflection->GetUnknownFields(options));
233   if (unknown_fields.empty()) {
234     cmsg->message->CopyFrom(options);
235   } else {
236     // Reparse options string!  XXX call cmessage::MergeFromString
237     string serialized;
238     options.SerializeToString(&serialized);
239     io::CodedInputStream input(
240         reinterpret_cast<const uint8*>(serialized.c_str()), serialized.size());
241     input.SetExtensionRegistry(pool->pool, pool->message_factory);
242     bool success = cmsg->message->MergePartialFromCodedStream(&input);
243     if (!success) {
244       PyErr_Format(PyExc_ValueError, "Error parsing Options message");
245       return NULL;
246     }
247   }
248 
249   // Cache the result.
250   Py_INCREF(value.get());
251   (*pool->descriptor_options)[descriptor] = value.get();
252 
253   return value.release();
254 }
255 
256 // Copy the C++ descriptor to a Python message.
257 // The Python message is an instance of descriptor_pb2.DescriptorProto
258 // or similar.
259 template<class DescriptorProtoClass, class DescriptorClass>
CopyToPythonProto(const DescriptorClass * descriptor,PyObject * target)260 static PyObject* CopyToPythonProto(const DescriptorClass *descriptor,
261                                    PyObject *target) {
262   const Descriptor* self_descriptor =
263       DescriptorProtoClass::default_instance().GetDescriptor();
264   CMessage* message = reinterpret_cast<CMessage*>(target);
265   if (!PyObject_TypeCheck(target, &CMessage_Type) ||
266       message->message->GetDescriptor() != self_descriptor) {
267     PyErr_Format(PyExc_TypeError, "Not a %s message",
268                  self_descriptor->full_name().c_str());
269     return NULL;
270   }
271   cmessage::AssureWritable(message);
272   DescriptorProtoClass* descriptor_message =
273       static_cast<DescriptorProtoClass*>(message->message);
274   descriptor->CopyTo(descriptor_message);
275   Py_RETURN_NONE;
276 }
277 
278 // All Descriptors classes share the same memory layout.
279 typedef struct PyBaseDescriptor {
280   PyObject_HEAD
281 
282   // Pointer to the C++ proto2 descriptor.
283   // Like all descriptors, it is owned by the global DescriptorPool.
284   const void* descriptor;
285 
286   // Owned reference to the DescriptorPool, to ensure it is kept alive.
287   PyDescriptorPool* pool;
288 } PyBaseDescriptor;
289 
290 
291 // FileDescriptor structure "inherits" from the base descriptor.
292 typedef struct PyFileDescriptor {
293   PyBaseDescriptor base;
294 
295   // The cached version of serialized pb. Either NULL, or a Bytes string.
296   // We own the reference.
297   PyObject *serialized_pb;
298 } PyFileDescriptor;
299 
300 
301 namespace descriptor {
302 
303 // Creates or retrieve a Python descriptor of the specified type.
304 // Objects are interned: the same descriptor will return the same object if it
305 // was kept alive.
306 // 'was_created' is an optional pointer to a bool, and is set to true if a new
307 // object was allocated.
308 // Always return a new reference.
309 template<class DescriptorClass>
NewInternedDescriptor(PyTypeObject * type,const DescriptorClass * descriptor,bool * was_created)310 PyObject* NewInternedDescriptor(PyTypeObject* type,
311                                 const DescriptorClass* descriptor,
312                                 bool* was_created) {
313   if (was_created) {
314     *was_created = false;
315   }
316   if (descriptor == NULL) {
317     PyErr_BadInternalCall();
318     return NULL;
319   }
320 
321   // See if the object is in the map of interned descriptors
322   hash_map<const void*, PyObject*>::iterator it =
323       interned_descriptors.find(descriptor);
324   if (it != interned_descriptors.end()) {
325     GOOGLE_DCHECK(Py_TYPE(it->second) == type);
326     Py_INCREF(it->second);
327     return it->second;
328   }
329   // Create a new descriptor object
330   PyBaseDescriptor* py_descriptor = PyObject_New(
331       PyBaseDescriptor, type);
332   if (py_descriptor == NULL) {
333     return NULL;
334   }
335   py_descriptor->descriptor = descriptor;
336 
337   // and cache it.
338   interned_descriptors.insert(
339       std::make_pair(descriptor, reinterpret_cast<PyObject*>(py_descriptor)));
340 
341   // Ensures that the DescriptorPool stays alive.
342   PyDescriptorPool* pool = GetDescriptorPool_FromPool(
343       GetFileDescriptor(descriptor)->pool());
344   if (pool == NULL) {
345     // Don't DECREF, the object is not fully initialized.
346     PyObject_Del(py_descriptor);
347     return NULL;
348   }
349   Py_INCREF(pool);
350   py_descriptor->pool = pool;
351 
352   if (was_created) {
353     *was_created = true;
354   }
355   return reinterpret_cast<PyObject*>(py_descriptor);
356 }
357 
Dealloc(PyBaseDescriptor * self)358 static void Dealloc(PyBaseDescriptor* self) {
359   // Remove from interned dictionary
360   interned_descriptors.erase(self->descriptor);
361   Py_CLEAR(self->pool);
362   Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
363 }
364 
365 static PyGetSetDef Getters[] = {
366   {NULL}
367 };
368 
369 PyTypeObject PyBaseDescriptor_Type = {
370   PyVarObject_HEAD_INIT(&PyType_Type, 0)
371   FULL_MODULE_NAME ".DescriptorBase",   // tp_name
372   sizeof(PyBaseDescriptor),             // tp_basicsize
373   0,                                    // tp_itemsize
374   (destructor)Dealloc,                  // tp_dealloc
375   0,                                    // tp_print
376   0,                                    // tp_getattr
377   0,                                    // tp_setattr
378   0,                                    // tp_compare
379   0,                                    // tp_repr
380   0,                                    // tp_as_number
381   0,                                    // tp_as_sequence
382   0,                                    // tp_as_mapping
383   0,                                    // tp_hash
384   0,                                    // tp_call
385   0,                                    // tp_str
386   0,                                    // tp_getattro
387   0,                                    // tp_setattro
388   0,                                    // tp_as_buffer
389   Py_TPFLAGS_DEFAULT,                   // tp_flags
390   "Descriptors base class",             // tp_doc
391   0,                                    // tp_traverse
392   0,                                    // tp_clear
393   0,                                    // tp_richcompare
394   0,                                    // tp_weaklistoffset
395   0,                                    // tp_iter
396   0,                                    // tp_iternext
397   0,                                    // tp_methods
398   0,                                    // tp_members
399   Getters,                              // tp_getset
400 };
401 
402 }  // namespace descriptor
403 
PyDescriptor_AsVoidPtr(PyObject * obj)404 const void* PyDescriptor_AsVoidPtr(PyObject* obj) {
405   if (!PyObject_TypeCheck(obj, &descriptor::PyBaseDescriptor_Type)) {
406     PyErr_SetString(PyExc_TypeError, "Not a BaseDescriptor");
407     return NULL;
408   }
409   return reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor;
410 }
411 
412 namespace message_descriptor {
413 
414 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)415 static const Descriptor* _GetDescriptor(PyBaseDescriptor* self) {
416   return reinterpret_cast<const Descriptor*>(self->descriptor);
417 }
418 
GetName(PyBaseDescriptor * self,void * closure)419 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
420   return PyString_FromCppString(_GetDescriptor(self)->name());
421 }
422 
GetFullName(PyBaseDescriptor * self,void * closure)423 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
424   return PyString_FromCppString(_GetDescriptor(self)->full_name());
425 }
426 
GetFile(PyBaseDescriptor * self,void * closure)427 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
428   return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
429 }
430 
GetConcreteClass(PyBaseDescriptor * self,void * closure)431 static PyObject* GetConcreteClass(PyBaseDescriptor* self, void *closure) {
432   // Retuns the canonical class for the given descriptor.
433   // This is the class that was registered with the primary descriptor pool
434   // which contains this descriptor.
435   // This might not be the one you expect! For example the returned object does
436   // not know about extensions defined in a custom pool.
437   CMessageClass* concrete_class(cdescriptor_pool::GetMessageClass(
438       GetDescriptorPool_FromPool(_GetDescriptor(self)->file()->pool()),
439       _GetDescriptor(self)));
440   Py_XINCREF(concrete_class);
441   return concrete_class->AsPyObject();
442 }
443 
GetFieldsByName(PyBaseDescriptor * self,void * closure)444 static PyObject* GetFieldsByName(PyBaseDescriptor* self, void *closure) {
445   return NewMessageFieldsByName(_GetDescriptor(self));
446 }
447 
GetFieldsByCamelcaseName(PyBaseDescriptor * self,void * closure)448 static PyObject* GetFieldsByCamelcaseName(PyBaseDescriptor* self,
449                                           void *closure) {
450   return NewMessageFieldsByCamelcaseName(_GetDescriptor(self));
451 }
452 
GetFieldsByNumber(PyBaseDescriptor * self,void * closure)453 static PyObject* GetFieldsByNumber(PyBaseDescriptor* self, void *closure) {
454   return NewMessageFieldsByNumber(_GetDescriptor(self));
455 }
456 
GetFieldsSeq(PyBaseDescriptor * self,void * closure)457 static PyObject* GetFieldsSeq(PyBaseDescriptor* self, void *closure) {
458   return NewMessageFieldsSeq(_GetDescriptor(self));
459 }
460 
GetNestedTypesByName(PyBaseDescriptor * self,void * closure)461 static PyObject* GetNestedTypesByName(PyBaseDescriptor* self, void *closure) {
462   return NewMessageNestedTypesByName(_GetDescriptor(self));
463 }
464 
GetNestedTypesSeq(PyBaseDescriptor * self,void * closure)465 static PyObject* GetNestedTypesSeq(PyBaseDescriptor* self, void *closure) {
466   return NewMessageNestedTypesSeq(_GetDescriptor(self));
467 }
468 
GetExtensionsByName(PyBaseDescriptor * self,void * closure)469 static PyObject* GetExtensionsByName(PyBaseDescriptor* self, void *closure) {
470   return NewMessageExtensionsByName(_GetDescriptor(self));
471 }
472 
GetExtensions(PyBaseDescriptor * self,void * closure)473 static PyObject* GetExtensions(PyBaseDescriptor* self, void *closure) {
474   return NewMessageExtensionsSeq(_GetDescriptor(self));
475 }
476 
GetEnumsSeq(PyBaseDescriptor * self,void * closure)477 static PyObject* GetEnumsSeq(PyBaseDescriptor* self, void *closure) {
478   return NewMessageEnumsSeq(_GetDescriptor(self));
479 }
480 
GetEnumTypesByName(PyBaseDescriptor * self,void * closure)481 static PyObject* GetEnumTypesByName(PyBaseDescriptor* self, void *closure) {
482   return NewMessageEnumsByName(_GetDescriptor(self));
483 }
484 
GetEnumValuesByName(PyBaseDescriptor * self,void * closure)485 static PyObject* GetEnumValuesByName(PyBaseDescriptor* self, void *closure) {
486   return NewMessageEnumValuesByName(_GetDescriptor(self));
487 }
488 
GetOneofsByName(PyBaseDescriptor * self,void * closure)489 static PyObject* GetOneofsByName(PyBaseDescriptor* self, void *closure) {
490   return NewMessageOneofsByName(_GetDescriptor(self));
491 }
492 
GetOneofsSeq(PyBaseDescriptor * self,void * closure)493 static PyObject* GetOneofsSeq(PyBaseDescriptor* self, void *closure) {
494   return NewMessageOneofsSeq(_GetDescriptor(self));
495 }
496 
IsExtendable(PyBaseDescriptor * self,void * closure)497 static PyObject* IsExtendable(PyBaseDescriptor *self, void *closure) {
498   if (_GetDescriptor(self)->extension_range_count() > 0) {
499     Py_RETURN_TRUE;
500   } else {
501     Py_RETURN_FALSE;
502   }
503 }
504 
GetExtensionRanges(PyBaseDescriptor * self,void * closure)505 static PyObject* GetExtensionRanges(PyBaseDescriptor *self, void *closure) {
506   const Descriptor* descriptor = _GetDescriptor(self);
507   PyObject* range_list = PyList_New(descriptor->extension_range_count());
508 
509   for (int i = 0; i < descriptor->extension_range_count(); i++) {
510     const Descriptor::ExtensionRange* range = descriptor->extension_range(i);
511     PyObject* start = PyInt_FromLong(range->start);
512     PyObject* end = PyInt_FromLong(range->end);
513     PyList_SetItem(range_list, i, PyTuple_Pack(2, start, end));
514   }
515 
516   return range_list;
517 }
518 
GetContainingType(PyBaseDescriptor * self,void * closure)519 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
520   const Descriptor* containing_type =
521       _GetDescriptor(self)->containing_type();
522   if (containing_type) {
523     return PyMessageDescriptor_FromDescriptor(containing_type);
524   } else {
525     Py_RETURN_NONE;
526   }
527 }
528 
SetContainingType(PyBaseDescriptor * self,PyObject * value,void * closure)529 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
530                              void *closure) {
531   return CheckCalledFromGeneratedFile("containing_type");
532 }
533 
GetHasOptions(PyBaseDescriptor * self,void * closure)534 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
535   const MessageOptions& options(_GetDescriptor(self)->options());
536   if (&options != &MessageOptions::default_instance()) {
537     Py_RETURN_TRUE;
538   } else {
539     Py_RETURN_FALSE;
540   }
541 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)542 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
543                              void *closure) {
544   return CheckCalledFromGeneratedFile("has_options");
545 }
546 
GetOptions(PyBaseDescriptor * self)547 static PyObject* GetOptions(PyBaseDescriptor *self) {
548   return GetOrBuildOptions(_GetDescriptor(self));
549 }
550 
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)551 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
552                       void *closure) {
553   return CheckCalledFromGeneratedFile("_options");
554 }
555 
CopyToProto(PyBaseDescriptor * self,PyObject * target)556 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
557   return CopyToPythonProto<DescriptorProto>(_GetDescriptor(self), target);
558 }
559 
EnumValueName(PyBaseDescriptor * self,PyObject * args)560 static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) {
561   const char *enum_name;
562   int number;
563   if (!PyArg_ParseTuple(args, "si", &enum_name, &number))
564     return NULL;
565   const EnumDescriptor *enum_type =
566       _GetDescriptor(self)->FindEnumTypeByName(enum_name);
567   if (enum_type == NULL) {
568     PyErr_SetString(PyExc_KeyError, enum_name);
569     return NULL;
570   }
571   const EnumValueDescriptor *enum_value =
572       enum_type->FindValueByNumber(number);
573   if (enum_value == NULL) {
574     PyErr_Format(PyExc_KeyError, "%d", number);
575     return NULL;
576   }
577   return PyString_FromCppString(enum_value->name());
578 }
579 
GetSyntax(PyBaseDescriptor * self,void * closure)580 static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) {
581   return PyString_InternFromString(
582       FileDescriptor::SyntaxName(_GetDescriptor(self)->file()->syntax()));
583 }
584 
585 static PyGetSetDef Getters[] = {
586   { "name", (getter)GetName, NULL, "Last name"},
587   { "full_name", (getter)GetFullName, NULL, "Full name"},
588   { "_concrete_class", (getter)GetConcreteClass, NULL, "concrete class"},
589   { "file", (getter)GetFile, NULL, "File descriptor"},
590 
591   { "fields", (getter)GetFieldsSeq, NULL, "Fields sequence"},
592   { "fields_by_name", (getter)GetFieldsByName, NULL, "Fields by name"},
593   { "fields_by_camelcase_name", (getter)GetFieldsByCamelcaseName, NULL,
594     "Fields by camelCase name"},
595   { "fields_by_number", (getter)GetFieldsByNumber, NULL, "Fields by number"},
596   { "nested_types", (getter)GetNestedTypesSeq, NULL, "Nested types sequence"},
597   { "nested_types_by_name", (getter)GetNestedTypesByName, NULL,
598     "Nested types by name"},
599   { "extensions", (getter)GetExtensions, NULL, "Extensions Sequence"},
600   { "extensions_by_name", (getter)GetExtensionsByName, NULL,
601     "Extensions by name"},
602   { "extension_ranges", (getter)GetExtensionRanges, NULL, "Extension ranges"},
603   { "enum_types", (getter)GetEnumsSeq, NULL, "Enum sequence"},
604   { "enum_types_by_name", (getter)GetEnumTypesByName, NULL,
605     "Enum types by name"},
606   { "enum_values_by_name", (getter)GetEnumValuesByName, NULL,
607     "Enum values by name"},
608   { "oneofs_by_name", (getter)GetOneofsByName, NULL, "Oneofs by name"},
609   { "oneofs", (getter)GetOneofsSeq, NULL, "Oneofs by name"},
610   { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
611     "Containing type"},
612   { "is_extendable", (getter)IsExtendable, (setter)NULL},
613   { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
614   { "_options", (getter)NULL, (setter)SetOptions, "Options"},
615   { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
616   {NULL}
617 };
618 
619 static PyMethodDef Methods[] = {
620   { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
621   { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
622   { "EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS, },
623   {NULL}
624 };
625 
626 }  // namespace message_descriptor
627 
628 PyTypeObject PyMessageDescriptor_Type = {
629   PyVarObject_HEAD_INIT(&PyType_Type, 0)
630   FULL_MODULE_NAME ".MessageDescriptor",  // tp_name
631   sizeof(PyBaseDescriptor),             // tp_basicsize
632   0,                                    // tp_itemsize
633   0,                                    // tp_dealloc
634   0,                                    // tp_print
635   0,                                    // tp_getattr
636   0,                                    // tp_setattr
637   0,                                    // tp_compare
638   0,                                    // tp_repr
639   0,                                    // tp_as_number
640   0,                                    // tp_as_sequence
641   0,                                    // tp_as_mapping
642   0,                                    // tp_hash
643   0,                                    // tp_call
644   0,                                    // tp_str
645   0,                                    // tp_getattro
646   0,                                    // tp_setattro
647   0,                                    // tp_as_buffer
648   Py_TPFLAGS_DEFAULT,                   // tp_flags
649   "A Message Descriptor",               // tp_doc
650   0,                                    // tp_traverse
651   0,                                    // tp_clear
652   0,                                    // tp_richcompare
653   0,                                    // tp_weaklistoffset
654   0,                                    // tp_iter
655   0,                                    // tp_iternext
656   message_descriptor::Methods,          // tp_methods
657   0,                                    // tp_members
658   message_descriptor::Getters,          // tp_getset
659   &descriptor::PyBaseDescriptor_Type,   // tp_base
660 };
661 
PyMessageDescriptor_FromDescriptor(const Descriptor * message_descriptor)662 PyObject* PyMessageDescriptor_FromDescriptor(
663     const Descriptor* message_descriptor) {
664   return descriptor::NewInternedDescriptor(
665       &PyMessageDescriptor_Type, message_descriptor, NULL);
666 }
667 
PyMessageDescriptor_AsDescriptor(PyObject * obj)668 const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj) {
669   if (!PyObject_TypeCheck(obj, &PyMessageDescriptor_Type)) {
670     PyErr_SetString(PyExc_TypeError, "Not a MessageDescriptor");
671     return NULL;
672   }
673   return reinterpret_cast<const Descriptor*>(
674       reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
675 }
676 
677 namespace field_descriptor {
678 
679 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)680 static const FieldDescriptor* _GetDescriptor(
681     PyBaseDescriptor *self) {
682   return reinterpret_cast<const FieldDescriptor*>(self->descriptor);
683 }
684 
GetFullName(PyBaseDescriptor * self,void * closure)685 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
686   return PyString_FromCppString(_GetDescriptor(self)->full_name());
687 }
688 
GetName(PyBaseDescriptor * self,void * closure)689 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
690   return PyString_FromCppString(_GetDescriptor(self)->name());
691 }
692 
GetCamelcaseName(PyBaseDescriptor * self,void * closure)693 static PyObject* GetCamelcaseName(PyBaseDescriptor* self, void *closure) {
694   return PyString_FromCppString(_GetDescriptor(self)->camelcase_name());
695 }
696 
GetType(PyBaseDescriptor * self,void * closure)697 static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
698   return PyInt_FromLong(_GetDescriptor(self)->type());
699 }
700 
GetCppType(PyBaseDescriptor * self,void * closure)701 static PyObject* GetCppType(PyBaseDescriptor *self, void *closure) {
702   return PyInt_FromLong(_GetDescriptor(self)->cpp_type());
703 }
704 
GetLabel(PyBaseDescriptor * self,void * closure)705 static PyObject* GetLabel(PyBaseDescriptor *self, void *closure) {
706   return PyInt_FromLong(_GetDescriptor(self)->label());
707 }
708 
GetNumber(PyBaseDescriptor * self,void * closure)709 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
710   return PyInt_FromLong(_GetDescriptor(self)->number());
711 }
712 
GetIndex(PyBaseDescriptor * self,void * closure)713 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
714   return PyInt_FromLong(_GetDescriptor(self)->index());
715 }
716 
GetID(PyBaseDescriptor * self,void * closure)717 static PyObject* GetID(PyBaseDescriptor *self, void *closure) {
718   return PyLong_FromVoidPtr(self);
719 }
720 
IsExtension(PyBaseDescriptor * self,void * closure)721 static PyObject* IsExtension(PyBaseDescriptor *self, void *closure) {
722   return PyBool_FromLong(_GetDescriptor(self)->is_extension());
723 }
724 
HasDefaultValue(PyBaseDescriptor * self,void * closure)725 static PyObject* HasDefaultValue(PyBaseDescriptor *self, void *closure) {
726   return PyBool_FromLong(_GetDescriptor(self)->has_default_value());
727 }
728 
GetDefaultValue(PyBaseDescriptor * self,void * closure)729 static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) {
730   PyObject *result;
731 
732   switch (_GetDescriptor(self)->cpp_type()) {
733     case FieldDescriptor::CPPTYPE_INT32: {
734       int32 value = _GetDescriptor(self)->default_value_int32();
735       result = PyInt_FromLong(value);
736       break;
737     }
738     case FieldDescriptor::CPPTYPE_INT64: {
739       int64 value = _GetDescriptor(self)->default_value_int64();
740       result = PyLong_FromLongLong(value);
741       break;
742     }
743     case FieldDescriptor::CPPTYPE_UINT32: {
744       uint32 value = _GetDescriptor(self)->default_value_uint32();
745       result = PyInt_FromSize_t(value);
746       break;
747     }
748     case FieldDescriptor::CPPTYPE_UINT64: {
749       uint64 value = _GetDescriptor(self)->default_value_uint64();
750       result = PyLong_FromUnsignedLongLong(value);
751       break;
752     }
753     case FieldDescriptor::CPPTYPE_FLOAT: {
754       float value = _GetDescriptor(self)->default_value_float();
755       result = PyFloat_FromDouble(value);
756       break;
757     }
758     case FieldDescriptor::CPPTYPE_DOUBLE: {
759       double value = _GetDescriptor(self)->default_value_double();
760       result = PyFloat_FromDouble(value);
761       break;
762     }
763     case FieldDescriptor::CPPTYPE_BOOL: {
764       bool value = _GetDescriptor(self)->default_value_bool();
765       result = PyBool_FromLong(value);
766       break;
767     }
768     case FieldDescriptor::CPPTYPE_STRING: {
769       string value = _GetDescriptor(self)->default_value_string();
770       result = ToStringObject(_GetDescriptor(self), value);
771       break;
772     }
773     case FieldDescriptor::CPPTYPE_ENUM: {
774       const EnumValueDescriptor* value =
775           _GetDescriptor(self)->default_value_enum();
776       result = PyInt_FromLong(value->number());
777       break;
778     }
779     default:
780       PyErr_Format(PyExc_NotImplementedError, "default value for %s",
781                    _GetDescriptor(self)->full_name().c_str());
782       return NULL;
783   }
784   return result;
785 }
786 
GetCDescriptor(PyObject * self,void * closure)787 static PyObject* GetCDescriptor(PyObject *self, void *closure) {
788   Py_INCREF(self);
789   return self;
790 }
791 
GetEnumType(PyBaseDescriptor * self,void * closure)792 static PyObject *GetEnumType(PyBaseDescriptor *self, void *closure) {
793   const EnumDescriptor* enum_type = _GetDescriptor(self)->enum_type();
794   if (enum_type) {
795     return PyEnumDescriptor_FromDescriptor(enum_type);
796   } else {
797     Py_RETURN_NONE;
798   }
799 }
800 
SetEnumType(PyBaseDescriptor * self,PyObject * value,void * closure)801 static int SetEnumType(PyBaseDescriptor *self, PyObject *value, void *closure) {
802   return CheckCalledFromGeneratedFile("enum_type");
803 }
804 
GetMessageType(PyBaseDescriptor * self,void * closure)805 static PyObject *GetMessageType(PyBaseDescriptor *self, void *closure) {
806   const Descriptor* message_type = _GetDescriptor(self)->message_type();
807   if (message_type) {
808     return PyMessageDescriptor_FromDescriptor(message_type);
809   } else {
810     Py_RETURN_NONE;
811   }
812 }
813 
SetMessageType(PyBaseDescriptor * self,PyObject * value,void * closure)814 static int SetMessageType(PyBaseDescriptor *self, PyObject *value,
815                           void *closure) {
816   return CheckCalledFromGeneratedFile("message_type");
817 }
818 
GetContainingType(PyBaseDescriptor * self,void * closure)819 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
820   const Descriptor* containing_type =
821       _GetDescriptor(self)->containing_type();
822   if (containing_type) {
823     return PyMessageDescriptor_FromDescriptor(containing_type);
824   } else {
825     Py_RETURN_NONE;
826   }
827 }
828 
SetContainingType(PyBaseDescriptor * self,PyObject * value,void * closure)829 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
830                              void *closure) {
831   return CheckCalledFromGeneratedFile("containing_type");
832 }
833 
GetExtensionScope(PyBaseDescriptor * self,void * closure)834 static PyObject* GetExtensionScope(PyBaseDescriptor *self, void *closure) {
835   const Descriptor* extension_scope =
836       _GetDescriptor(self)->extension_scope();
837   if (extension_scope) {
838     return PyMessageDescriptor_FromDescriptor(extension_scope);
839   } else {
840     Py_RETURN_NONE;
841   }
842 }
843 
GetContainingOneof(PyBaseDescriptor * self,void * closure)844 static PyObject* GetContainingOneof(PyBaseDescriptor *self, void *closure) {
845   const OneofDescriptor* containing_oneof =
846       _GetDescriptor(self)->containing_oneof();
847   if (containing_oneof) {
848     return PyOneofDescriptor_FromDescriptor(containing_oneof);
849   } else {
850     Py_RETURN_NONE;
851   }
852 }
853 
SetContainingOneof(PyBaseDescriptor * self,PyObject * value,void * closure)854 static int SetContainingOneof(PyBaseDescriptor *self, PyObject *value,
855                               void *closure) {
856   return CheckCalledFromGeneratedFile("containing_oneof");
857 }
858 
GetHasOptions(PyBaseDescriptor * self,void * closure)859 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
860   const FieldOptions& options(_GetDescriptor(self)->options());
861   if (&options != &FieldOptions::default_instance()) {
862     Py_RETURN_TRUE;
863   } else {
864     Py_RETURN_FALSE;
865   }
866 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)867 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
868                          void *closure) {
869   return CheckCalledFromGeneratedFile("has_options");
870 }
871 
GetOptions(PyBaseDescriptor * self)872 static PyObject* GetOptions(PyBaseDescriptor *self) {
873   return GetOrBuildOptions(_GetDescriptor(self));
874 }
875 
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)876 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
877                       void *closure) {
878   return CheckCalledFromGeneratedFile("_options");
879 }
880 
881 
882 static PyGetSetDef Getters[] = {
883   { "full_name", (getter)GetFullName, NULL, "Full name"},
884   { "name", (getter)GetName, NULL, "Unqualified name"},
885   { "camelcase_name", (getter)GetCamelcaseName, NULL, "Camelcase name"},
886   { "type", (getter)GetType, NULL, "C++ Type"},
887   { "cpp_type", (getter)GetCppType, NULL, "C++ Type"},
888   { "label", (getter)GetLabel, NULL, "Label"},
889   { "number", (getter)GetNumber, NULL, "Number"},
890   { "index", (getter)GetIndex, NULL, "Index"},
891   { "default_value", (getter)GetDefaultValue, NULL, "Default Value"},
892   { "has_default_value", (getter)HasDefaultValue},
893   { "is_extension", (getter)IsExtension, NULL, "ID"},
894   { "id", (getter)GetID, NULL, "ID"},
895   { "_cdescriptor", (getter)GetCDescriptor, NULL, "HAACK REMOVE ME"},
896 
897   { "message_type", (getter)GetMessageType, (setter)SetMessageType,
898     "Message type"},
899   { "enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"},
900   { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
901     "Containing type"},
902   { "extension_scope", (getter)GetExtensionScope, (setter)NULL,
903     "Extension scope"},
904   { "containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof,
905     "Containing oneof"},
906   { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
907   { "_options", (getter)NULL, (setter)SetOptions, "Options"},
908   {NULL}
909 };
910 
911 static PyMethodDef Methods[] = {
912   { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
913   {NULL}
914 };
915 
916 }  // namespace field_descriptor
917 
918 PyTypeObject PyFieldDescriptor_Type = {
919   PyVarObject_HEAD_INIT(&PyType_Type, 0)
920   FULL_MODULE_NAME ".FieldDescriptor",  // tp_name
921   sizeof(PyBaseDescriptor),             // tp_basicsize
922   0,                                    // tp_itemsize
923   0,                                    // tp_dealloc
924   0,                                    // tp_print
925   0,                                    // tp_getattr
926   0,                                    // tp_setattr
927   0,                                    // tp_compare
928   0,                                    // tp_repr
929   0,                                    // tp_as_number
930   0,                                    // tp_as_sequence
931   0,                                    // tp_as_mapping
932   0,                                    // tp_hash
933   0,                                    // tp_call
934   0,                                    // tp_str
935   0,                                    // tp_getattro
936   0,                                    // tp_setattro
937   0,                                    // tp_as_buffer
938   Py_TPFLAGS_DEFAULT,                   // tp_flags
939   "A Field Descriptor",                 // tp_doc
940   0,                                    // tp_traverse
941   0,                                    // tp_clear
942   0,                                    // tp_richcompare
943   0,                                    // tp_weaklistoffset
944   0,                                    // tp_iter
945   0,                                    // tp_iternext
946   field_descriptor::Methods,            // tp_methods
947   0,                                    // tp_members
948   field_descriptor::Getters,            // tp_getset
949   &descriptor::PyBaseDescriptor_Type,   // tp_base
950 };
951 
PyFieldDescriptor_FromDescriptor(const FieldDescriptor * field_descriptor)952 PyObject* PyFieldDescriptor_FromDescriptor(
953     const FieldDescriptor* field_descriptor) {
954   return descriptor::NewInternedDescriptor(
955       &PyFieldDescriptor_Type, field_descriptor, NULL);
956 }
957 
PyFieldDescriptor_AsDescriptor(PyObject * obj)958 const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj) {
959   if (!PyObject_TypeCheck(obj, &PyFieldDescriptor_Type)) {
960     PyErr_SetString(PyExc_TypeError, "Not a FieldDescriptor");
961     return NULL;
962   }
963   return reinterpret_cast<const FieldDescriptor*>(
964       reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
965 }
966 
967 namespace enum_descriptor {
968 
969 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)970 static const EnumDescriptor* _GetDescriptor(
971     PyBaseDescriptor *self) {
972   return reinterpret_cast<const EnumDescriptor*>(self->descriptor);
973 }
974 
GetFullName(PyBaseDescriptor * self,void * closure)975 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
976   return PyString_FromCppString(_GetDescriptor(self)->full_name());
977 }
978 
GetName(PyBaseDescriptor * self,void * closure)979 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
980   return PyString_FromCppString(_GetDescriptor(self)->name());
981 }
982 
GetFile(PyBaseDescriptor * self,void * closure)983 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
984   return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
985 }
986 
GetEnumvaluesByName(PyBaseDescriptor * self,void * closure)987 static PyObject* GetEnumvaluesByName(PyBaseDescriptor* self, void *closure) {
988   return NewEnumValuesByName(_GetDescriptor(self));
989 }
990 
GetEnumvaluesByNumber(PyBaseDescriptor * self,void * closure)991 static PyObject* GetEnumvaluesByNumber(PyBaseDescriptor* self, void *closure) {
992   return NewEnumValuesByNumber(_GetDescriptor(self));
993 }
994 
GetEnumvaluesSeq(PyBaseDescriptor * self,void * closure)995 static PyObject* GetEnumvaluesSeq(PyBaseDescriptor* self, void *closure) {
996   return NewEnumValuesSeq(_GetDescriptor(self));
997 }
998 
GetContainingType(PyBaseDescriptor * self,void * closure)999 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
1000   const Descriptor* containing_type =
1001       _GetDescriptor(self)->containing_type();
1002   if (containing_type) {
1003     return PyMessageDescriptor_FromDescriptor(containing_type);
1004   } else {
1005     Py_RETURN_NONE;
1006   }
1007 }
1008 
SetContainingType(PyBaseDescriptor * self,PyObject * value,void * closure)1009 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
1010                              void *closure) {
1011   return CheckCalledFromGeneratedFile("containing_type");
1012 }
1013 
1014 
GetHasOptions(PyBaseDescriptor * self,void * closure)1015 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
1016   const EnumOptions& options(_GetDescriptor(self)->options());
1017   if (&options != &EnumOptions::default_instance()) {
1018     Py_RETURN_TRUE;
1019   } else {
1020     Py_RETURN_FALSE;
1021   }
1022 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1023 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
1024                          void *closure) {
1025   return CheckCalledFromGeneratedFile("has_options");
1026 }
1027 
GetOptions(PyBaseDescriptor * self)1028 static PyObject* GetOptions(PyBaseDescriptor *self) {
1029   return GetOrBuildOptions(_GetDescriptor(self));
1030 }
1031 
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1032 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
1033                       void *closure) {
1034   return CheckCalledFromGeneratedFile("_options");
1035 }
1036 
CopyToProto(PyBaseDescriptor * self,PyObject * target)1037 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
1038   return CopyToPythonProto<EnumDescriptorProto>(_GetDescriptor(self), target);
1039 }
1040 
1041 static PyMethodDef Methods[] = {
1042   { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
1043   { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
1044   {NULL}
1045 };
1046 
1047 static PyGetSetDef Getters[] = {
1048   { "full_name", (getter)GetFullName, NULL, "Full name"},
1049   { "name", (getter)GetName, NULL, "last name"},
1050   { "file", (getter)GetFile, NULL, "File descriptor"},
1051   { "values", (getter)GetEnumvaluesSeq, NULL, "values"},
1052   { "values_by_name", (getter)GetEnumvaluesByName, NULL,
1053     "Enum values by name"},
1054   { "values_by_number", (getter)GetEnumvaluesByNumber, NULL,
1055     "Enum values by number"},
1056 
1057   { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
1058     "Containing type"},
1059   { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
1060   { "_options", (getter)NULL, (setter)SetOptions, "Options"},
1061   {NULL}
1062 };
1063 
1064 }  // namespace enum_descriptor
1065 
1066 PyTypeObject PyEnumDescriptor_Type = {
1067   PyVarObject_HEAD_INIT(&PyType_Type, 0)
1068   FULL_MODULE_NAME ".EnumDescriptor",   // tp_name
1069   sizeof(PyBaseDescriptor),             // tp_basicsize
1070   0,                                    // tp_itemsize
1071   0,                                    // tp_dealloc
1072   0,                                    // tp_print
1073   0,                                    // tp_getattr
1074   0,                                    // tp_setattr
1075   0,                                    // tp_compare
1076   0,                                    // tp_repr
1077   0,                                    // tp_as_number
1078   0,                                    // tp_as_sequence
1079   0,                                    // tp_as_mapping
1080   0,                                    // tp_hash
1081   0,                                    // tp_call
1082   0,                                    // tp_str
1083   0,                                    // tp_getattro
1084   0,                                    // tp_setattro
1085   0,                                    // tp_as_buffer
1086   Py_TPFLAGS_DEFAULT,                   // tp_flags
1087   "A Enum Descriptor",                  // tp_doc
1088   0,                                    // tp_traverse
1089   0,                                    // tp_clear
1090   0,                                    // tp_richcompare
1091   0,                                    // tp_weaklistoffset
1092   0,                                    // tp_iter
1093   0,                                    // tp_iternext
1094   enum_descriptor::Methods,             // tp_getset
1095   0,                                    // tp_members
1096   enum_descriptor::Getters,             // tp_getset
1097   &descriptor::PyBaseDescriptor_Type,   // tp_base
1098 };
1099 
PyEnumDescriptor_FromDescriptor(const EnumDescriptor * enum_descriptor)1100 PyObject* PyEnumDescriptor_FromDescriptor(
1101     const EnumDescriptor* enum_descriptor) {
1102   return descriptor::NewInternedDescriptor(
1103       &PyEnumDescriptor_Type, enum_descriptor, NULL);
1104 }
1105 
PyEnumDescriptor_AsDescriptor(PyObject * obj)1106 const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj) {
1107   if (!PyObject_TypeCheck(obj, &PyEnumDescriptor_Type)) {
1108     PyErr_SetString(PyExc_TypeError, "Not an EnumDescriptor");
1109     return NULL;
1110   }
1111   return reinterpret_cast<const EnumDescriptor*>(
1112       reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
1113 }
1114 
1115 namespace enumvalue_descriptor {
1116 
1117 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)1118 static const EnumValueDescriptor* _GetDescriptor(
1119     PyBaseDescriptor *self) {
1120   return reinterpret_cast<const EnumValueDescriptor*>(self->descriptor);
1121 }
1122 
GetName(PyBaseDescriptor * self,void * closure)1123 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
1124   return PyString_FromCppString(_GetDescriptor(self)->name());
1125 }
1126 
GetNumber(PyBaseDescriptor * self,void * closure)1127 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
1128   return PyInt_FromLong(_GetDescriptor(self)->number());
1129 }
1130 
GetIndex(PyBaseDescriptor * self,void * closure)1131 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
1132   return PyInt_FromLong(_GetDescriptor(self)->index());
1133 }
1134 
GetType(PyBaseDescriptor * self,void * closure)1135 static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
1136   return PyEnumDescriptor_FromDescriptor(_GetDescriptor(self)->type());
1137 }
1138 
GetHasOptions(PyBaseDescriptor * self,void * closure)1139 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
1140   const EnumValueOptions& options(_GetDescriptor(self)->options());
1141   if (&options != &EnumValueOptions::default_instance()) {
1142     Py_RETURN_TRUE;
1143   } else {
1144     Py_RETURN_FALSE;
1145   }
1146 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1147 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
1148                          void *closure) {
1149   return CheckCalledFromGeneratedFile("has_options");
1150 }
1151 
GetOptions(PyBaseDescriptor * self)1152 static PyObject* GetOptions(PyBaseDescriptor *self) {
1153   return GetOrBuildOptions(_GetDescriptor(self));
1154 }
1155 
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1156 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
1157                       void *closure) {
1158   return CheckCalledFromGeneratedFile("_options");
1159 }
1160 
1161 
1162 static PyGetSetDef Getters[] = {
1163   { "name", (getter)GetName, NULL, "name"},
1164   { "number", (getter)GetNumber, NULL, "number"},
1165   { "index", (getter)GetIndex, NULL, "index"},
1166   { "type", (getter)GetType, NULL, "index"},
1167 
1168   { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
1169   { "_options", (getter)NULL, (setter)SetOptions, "Options"},
1170   {NULL}
1171 };
1172 
1173 static PyMethodDef Methods[] = {
1174   { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
1175   {NULL}
1176 };
1177 
1178 }  // namespace enumvalue_descriptor
1179 
1180 PyTypeObject PyEnumValueDescriptor_Type = {
1181   PyVarObject_HEAD_INIT(&PyType_Type, 0)
1182   FULL_MODULE_NAME ".EnumValueDescriptor",  // tp_name
1183   sizeof(PyBaseDescriptor),             // tp_basicsize
1184   0,                                    // tp_itemsize
1185   0,                                    // tp_dealloc
1186   0,                                    // tp_print
1187   0,                                    // tp_getattr
1188   0,                                    // tp_setattr
1189   0,                                    // tp_compare
1190   0,                                    // tp_repr
1191   0,                                    // tp_as_number
1192   0,                                    // tp_as_sequence
1193   0,                                    // tp_as_mapping
1194   0,                                    // tp_hash
1195   0,                                    // tp_call
1196   0,                                    // tp_str
1197   0,                                    // tp_getattro
1198   0,                                    // tp_setattro
1199   0,                                    // tp_as_buffer
1200   Py_TPFLAGS_DEFAULT,                   // tp_flags
1201   "A EnumValue Descriptor",             // tp_doc
1202   0,                                    // tp_traverse
1203   0,                                    // tp_clear
1204   0,                                    // tp_richcompare
1205   0,                                    // tp_weaklistoffset
1206   0,                                    // tp_iter
1207   0,                                    // tp_iternext
1208   enumvalue_descriptor::Methods,        // tp_methods
1209   0,                                    // tp_members
1210   enumvalue_descriptor::Getters,        // tp_getset
1211   &descriptor::PyBaseDescriptor_Type,   // tp_base
1212 };
1213 
PyEnumValueDescriptor_FromDescriptor(const EnumValueDescriptor * enumvalue_descriptor)1214 PyObject* PyEnumValueDescriptor_FromDescriptor(
1215     const EnumValueDescriptor* enumvalue_descriptor) {
1216   return descriptor::NewInternedDescriptor(
1217       &PyEnumValueDescriptor_Type, enumvalue_descriptor, NULL);
1218 }
1219 
1220 namespace file_descriptor {
1221 
1222 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyFileDescriptor * self)1223 static const FileDescriptor* _GetDescriptor(PyFileDescriptor *self) {
1224   return reinterpret_cast<const FileDescriptor*>(self->base.descriptor);
1225 }
1226 
Dealloc(PyFileDescriptor * self)1227 static void Dealloc(PyFileDescriptor* self) {
1228   Py_XDECREF(self->serialized_pb);
1229   descriptor::Dealloc(&self->base);
1230 }
1231 
GetPool(PyFileDescriptor * self,void * closure)1232 static PyObject* GetPool(PyFileDescriptor *self, void *closure) {
1233   PyObject* pool = reinterpret_cast<PyObject*>(
1234       GetDescriptorPool_FromPool(_GetDescriptor(self)->pool()));
1235   Py_XINCREF(pool);
1236   return pool;
1237 }
1238 
GetName(PyFileDescriptor * self,void * closure)1239 static PyObject* GetName(PyFileDescriptor *self, void *closure) {
1240   return PyString_FromCppString(_GetDescriptor(self)->name());
1241 }
1242 
GetPackage(PyFileDescriptor * self,void * closure)1243 static PyObject* GetPackage(PyFileDescriptor *self, void *closure) {
1244   return PyString_FromCppString(_GetDescriptor(self)->package());
1245 }
1246 
GetSerializedPb(PyFileDescriptor * self,void * closure)1247 static PyObject* GetSerializedPb(PyFileDescriptor *self, void *closure) {
1248   PyObject *serialized_pb = self->serialized_pb;
1249   if (serialized_pb != NULL) {
1250     Py_INCREF(serialized_pb);
1251     return serialized_pb;
1252   }
1253   FileDescriptorProto file_proto;
1254   _GetDescriptor(self)->CopyTo(&file_proto);
1255   string contents;
1256   file_proto.SerializePartialToString(&contents);
1257   self->serialized_pb = PyBytes_FromStringAndSize(
1258       contents.c_str(), contents.size());
1259   if (self->serialized_pb == NULL) {
1260     return NULL;
1261   }
1262   Py_INCREF(self->serialized_pb);
1263   return self->serialized_pb;
1264 }
1265 
GetMessageTypesByName(PyFileDescriptor * self,void * closure)1266 static PyObject* GetMessageTypesByName(PyFileDescriptor* self, void *closure) {
1267   return NewFileMessageTypesByName(_GetDescriptor(self));
1268 }
1269 
GetEnumTypesByName(PyFileDescriptor * self,void * closure)1270 static PyObject* GetEnumTypesByName(PyFileDescriptor* self, void *closure) {
1271   return NewFileEnumTypesByName(_GetDescriptor(self));
1272 }
1273 
GetExtensionsByName(PyFileDescriptor * self,void * closure)1274 static PyObject* GetExtensionsByName(PyFileDescriptor* self, void *closure) {
1275   return NewFileExtensionsByName(_GetDescriptor(self));
1276 }
1277 
GetDependencies(PyFileDescriptor * self,void * closure)1278 static PyObject* GetDependencies(PyFileDescriptor* self, void *closure) {
1279   return NewFileDependencies(_GetDescriptor(self));
1280 }
1281 
GetPublicDependencies(PyFileDescriptor * self,void * closure)1282 static PyObject* GetPublicDependencies(PyFileDescriptor* self, void *closure) {
1283   return NewFilePublicDependencies(_GetDescriptor(self));
1284 }
1285 
GetHasOptions(PyFileDescriptor * self,void * closure)1286 static PyObject* GetHasOptions(PyFileDescriptor *self, void *closure) {
1287   const FileOptions& options(_GetDescriptor(self)->options());
1288   if (&options != &FileOptions::default_instance()) {
1289     Py_RETURN_TRUE;
1290   } else {
1291     Py_RETURN_FALSE;
1292   }
1293 }
SetHasOptions(PyFileDescriptor * self,PyObject * value,void * closure)1294 static int SetHasOptions(PyFileDescriptor *self, PyObject *value,
1295                          void *closure) {
1296   return CheckCalledFromGeneratedFile("has_options");
1297 }
1298 
GetOptions(PyFileDescriptor * self)1299 static PyObject* GetOptions(PyFileDescriptor *self) {
1300   return GetOrBuildOptions(_GetDescriptor(self));
1301 }
1302 
SetOptions(PyFileDescriptor * self,PyObject * value,void * closure)1303 static int SetOptions(PyFileDescriptor *self, PyObject *value,
1304                       void *closure) {
1305   return CheckCalledFromGeneratedFile("_options");
1306 }
1307 
GetSyntax(PyFileDescriptor * self,void * closure)1308 static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) {
1309   return PyString_InternFromString(
1310       FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax()));
1311 }
1312 
CopyToProto(PyFileDescriptor * self,PyObject * target)1313 static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) {
1314   return CopyToPythonProto<FileDescriptorProto>(_GetDescriptor(self), target);
1315 }
1316 
1317 static PyGetSetDef Getters[] = {
1318   { "pool", (getter)GetPool, NULL, "pool"},
1319   { "name", (getter)GetName, NULL, "name"},
1320   { "package", (getter)GetPackage, NULL, "package"},
1321   { "serialized_pb", (getter)GetSerializedPb},
1322   { "message_types_by_name", (getter)GetMessageTypesByName, NULL,
1323     "Messages by name"},
1324   { "enum_types_by_name", (getter)GetEnumTypesByName, NULL, "Enums by name"},
1325   { "extensions_by_name", (getter)GetExtensionsByName, NULL,
1326     "Extensions by name"},
1327   { "dependencies", (getter)GetDependencies, NULL, "Dependencies"},
1328   { "public_dependencies", (getter)GetPublicDependencies, NULL, "Dependencies"},
1329 
1330   { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
1331   { "_options", (getter)NULL, (setter)SetOptions, "Options"},
1332   { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
1333   {NULL}
1334 };
1335 
1336 static PyMethodDef Methods[] = {
1337   { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
1338   { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
1339   {NULL}
1340 };
1341 
1342 }  // namespace file_descriptor
1343 
1344 PyTypeObject PyFileDescriptor_Type = {
1345   PyVarObject_HEAD_INIT(&PyType_Type, 0)
1346   FULL_MODULE_NAME ".FileDescriptor",   // tp_name
1347   sizeof(PyFileDescriptor),             // tp_basicsize
1348   0,                                    // tp_itemsize
1349   (destructor)file_descriptor::Dealloc,  // tp_dealloc
1350   0,                                    // tp_print
1351   0,                                    // tp_getattr
1352   0,                                    // tp_setattr
1353   0,                                    // tp_compare
1354   0,                                    // tp_repr
1355   0,                                    // tp_as_number
1356   0,                                    // tp_as_sequence
1357   0,                                    // tp_as_mapping
1358   0,                                    // tp_hash
1359   0,                                    // tp_call
1360   0,                                    // tp_str
1361   0,                                    // tp_getattro
1362   0,                                    // tp_setattro
1363   0,                                    // tp_as_buffer
1364   Py_TPFLAGS_DEFAULT,                   // tp_flags
1365   "A File Descriptor",                  // tp_doc
1366   0,                                    // tp_traverse
1367   0,                                    // tp_clear
1368   0,                                    // tp_richcompare
1369   0,                                    // tp_weaklistoffset
1370   0,                                    // tp_iter
1371   0,                                    // tp_iternext
1372   file_descriptor::Methods,             // tp_methods
1373   0,                                    // tp_members
1374   file_descriptor::Getters,             // tp_getset
1375   &descriptor::PyBaseDescriptor_Type,   // tp_base
1376   0,                                    // tp_dict
1377   0,                                    // tp_descr_get
1378   0,                                    // tp_descr_set
1379   0,                                    // tp_dictoffset
1380   0,                                    // tp_init
1381   0,                                    // tp_alloc
1382   0,                                    // tp_new
1383   PyObject_Del,                         // tp_free
1384 };
1385 
PyFileDescriptor_FromDescriptor(const FileDescriptor * file_descriptor)1386 PyObject* PyFileDescriptor_FromDescriptor(
1387     const FileDescriptor* file_descriptor) {
1388   return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor,
1389                                                          NULL);
1390 }
1391 
PyFileDescriptor_FromDescriptorWithSerializedPb(const FileDescriptor * file_descriptor,PyObject * serialized_pb)1392 PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb(
1393     const FileDescriptor* file_descriptor, PyObject *serialized_pb) {
1394   bool was_created;
1395   PyObject* py_descriptor = descriptor::NewInternedDescriptor(
1396       &PyFileDescriptor_Type, file_descriptor, &was_created);
1397   if (py_descriptor == NULL) {
1398     return NULL;
1399   }
1400   if (was_created) {
1401     PyFileDescriptor* cfile_descriptor =
1402         reinterpret_cast<PyFileDescriptor*>(py_descriptor);
1403     Py_XINCREF(serialized_pb);
1404     cfile_descriptor->serialized_pb = serialized_pb;
1405   }
1406   // TODO(amauryfa): In the case of a cached object, check that serialized_pb
1407   // is the same as before.
1408 
1409   return py_descriptor;
1410 }
1411 
PyFileDescriptor_AsDescriptor(PyObject * obj)1412 const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj) {
1413   if (!PyObject_TypeCheck(obj, &PyFileDescriptor_Type)) {
1414     PyErr_SetString(PyExc_TypeError, "Not a FileDescriptor");
1415     return NULL;
1416   }
1417   return reinterpret_cast<const FileDescriptor*>(
1418       reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
1419 }
1420 
1421 namespace oneof_descriptor {
1422 
1423 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)1424 static const OneofDescriptor* _GetDescriptor(
1425     PyBaseDescriptor *self) {
1426   return reinterpret_cast<const OneofDescriptor*>(self->descriptor);
1427 }
1428 
GetName(PyBaseDescriptor * self,void * closure)1429 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
1430   return PyString_FromCppString(_GetDescriptor(self)->name());
1431 }
1432 
GetFullName(PyBaseDescriptor * self,void * closure)1433 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
1434   return PyString_FromCppString(_GetDescriptor(self)->full_name());
1435 }
1436 
GetIndex(PyBaseDescriptor * self,void * closure)1437 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
1438   return PyInt_FromLong(_GetDescriptor(self)->index());
1439 }
1440 
GetFields(PyBaseDescriptor * self,void * closure)1441 static PyObject* GetFields(PyBaseDescriptor* self, void *closure) {
1442   return NewOneofFieldsSeq(_GetDescriptor(self));
1443 }
1444 
GetContainingType(PyBaseDescriptor * self,void * closure)1445 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
1446   const Descriptor* containing_type =
1447       _GetDescriptor(self)->containing_type();
1448   if (containing_type) {
1449     return PyMessageDescriptor_FromDescriptor(containing_type);
1450   } else {
1451     Py_RETURN_NONE;
1452   }
1453 }
1454 
1455 static PyGetSetDef Getters[] = {
1456   { "name", (getter)GetName, NULL, "Name"},
1457   { "full_name", (getter)GetFullName, NULL, "Full name"},
1458   { "index", (getter)GetIndex, NULL, "Index"},
1459 
1460   { "containing_type", (getter)GetContainingType, NULL, "Containing type"},
1461   { "fields", (getter)GetFields, NULL, "Fields"},
1462   {NULL}
1463 };
1464 
1465 }  // namespace oneof_descriptor
1466 
1467 PyTypeObject PyOneofDescriptor_Type = {
1468   PyVarObject_HEAD_INIT(&PyType_Type, 0)
1469   FULL_MODULE_NAME ".OneofDescriptor",  // tp_name
1470   sizeof(PyBaseDescriptor),             // tp_basicsize
1471   0,                                    // tp_itemsize
1472   0,                                    // tp_dealloc
1473   0,                                    // tp_print
1474   0,                                    // tp_getattr
1475   0,                                    // tp_setattr
1476   0,                                    // tp_compare
1477   0,                                    // tp_repr
1478   0,                                    // tp_as_number
1479   0,                                    // tp_as_sequence
1480   0,                                    // tp_as_mapping
1481   0,                                    // tp_hash
1482   0,                                    // tp_call
1483   0,                                    // tp_str
1484   0,                                    // tp_getattro
1485   0,                                    // tp_setattro
1486   0,                                    // tp_as_buffer
1487   Py_TPFLAGS_DEFAULT,                   // tp_flags
1488   "A Oneof Descriptor",                 // tp_doc
1489   0,                                    // tp_traverse
1490   0,                                    // tp_clear
1491   0,                                    // tp_richcompare
1492   0,                                    // tp_weaklistoffset
1493   0,                                    // tp_iter
1494   0,                                    // tp_iternext
1495   0,                                    // tp_methods
1496   0,                                    // tp_members
1497   oneof_descriptor::Getters,            // tp_getset
1498   &descriptor::PyBaseDescriptor_Type,   // tp_base
1499 };
1500 
PyOneofDescriptor_FromDescriptor(const OneofDescriptor * oneof_descriptor)1501 PyObject* PyOneofDescriptor_FromDescriptor(
1502     const OneofDescriptor* oneof_descriptor) {
1503   return descriptor::NewInternedDescriptor(
1504       &PyOneofDescriptor_Type, oneof_descriptor, NULL);
1505 }
1506 
1507 // Add a enum values to a type dictionary.
AddEnumValues(PyTypeObject * type,const EnumDescriptor * enum_descriptor)1508 static bool AddEnumValues(PyTypeObject *type,
1509                           const EnumDescriptor* enum_descriptor) {
1510   for (int i = 0; i < enum_descriptor->value_count(); ++i) {
1511     const EnumValueDescriptor* value = enum_descriptor->value(i);
1512     ScopedPyObjectPtr obj(PyInt_FromLong(value->number()));
1513     if (obj == NULL) {
1514       return false;
1515     }
1516     if (PyDict_SetItemString(type->tp_dict, value->name().c_str(), obj.get()) <
1517         0) {
1518       return false;
1519     }
1520   }
1521   return true;
1522 }
1523 
AddIntConstant(PyTypeObject * type,const char * name,int value)1524 static bool AddIntConstant(PyTypeObject *type, const char* name, int value) {
1525   ScopedPyObjectPtr obj(PyInt_FromLong(value));
1526   if (PyDict_SetItemString(type->tp_dict, name, obj.get()) < 0) {
1527     return false;
1528   }
1529   return true;
1530 }
1531 
1532 
InitDescriptor()1533 bool InitDescriptor() {
1534   if (PyType_Ready(&PyMessageDescriptor_Type) < 0)
1535     return false;
1536 
1537   if (PyType_Ready(&PyFieldDescriptor_Type) < 0)
1538     return false;
1539 
1540   if (!AddEnumValues(&PyFieldDescriptor_Type,
1541                      FieldDescriptorProto::Label_descriptor())) {
1542     return false;
1543   }
1544   if (!AddEnumValues(&PyFieldDescriptor_Type,
1545                      FieldDescriptorProto::Type_descriptor())) {
1546     return false;
1547   }
1548 #define ADD_FIELDDESC_CONSTANT(NAME) AddIntConstant( \
1549     &PyFieldDescriptor_Type, #NAME, FieldDescriptor::NAME)
1550   if (!ADD_FIELDDESC_CONSTANT(CPPTYPE_INT32) ||
1551       !ADD_FIELDDESC_CONSTANT(CPPTYPE_INT64) ||
1552       !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT32) ||
1553       !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT64) ||
1554       !ADD_FIELDDESC_CONSTANT(CPPTYPE_DOUBLE) ||
1555       !ADD_FIELDDESC_CONSTANT(CPPTYPE_FLOAT) ||
1556       !ADD_FIELDDESC_CONSTANT(CPPTYPE_BOOL) ||
1557       !ADD_FIELDDESC_CONSTANT(CPPTYPE_ENUM) ||
1558       !ADD_FIELDDESC_CONSTANT(CPPTYPE_STRING) ||
1559       !ADD_FIELDDESC_CONSTANT(CPPTYPE_MESSAGE)) {
1560     return false;
1561   }
1562 #undef ADD_FIELDDESC_CONSTANT
1563 
1564   if (PyType_Ready(&PyEnumDescriptor_Type) < 0)
1565     return false;
1566 
1567   if (PyType_Ready(&PyEnumValueDescriptor_Type) < 0)
1568     return false;
1569 
1570   if (PyType_Ready(&PyFileDescriptor_Type) < 0)
1571     return false;
1572 
1573   if (PyType_Ready(&PyOneofDescriptor_Type) < 0)
1574     return false;
1575 
1576   if (!InitDescriptorMappingTypes())
1577     return false;
1578 
1579   return true;
1580 }
1581 
1582 }  // namespace python
1583 }  // namespace protobuf
1584 }  // namespace google
1585