Home | History | Annotate | Download | only in pyext
      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 (at) 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 
     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.
     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.
    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>
    160 const FileDescriptor* GetFileDescriptor(const DescriptorClass* descriptor) {
    161   return descriptor->file();
    162 }
    163 template<>
    164 const FileDescriptor* GetFileDescriptor(const FileDescriptor* descriptor) {
    165   return descriptor;
    166 }
    167 template<>
    168 const FileDescriptor* GetFileDescriptor(const EnumValueDescriptor* descriptor) {
    169   return descriptor->type()->file();
    170 }
    171 template<>
    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>
    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>
    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>
    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 
    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 
    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.
    415 static const Descriptor* _GetDescriptor(PyBaseDescriptor* self) {
    416   return reinterpret_cast<const Descriptor*>(self->descriptor);
    417 }
    418 
    419 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
    420   return PyString_FromCppString(_GetDescriptor(self)->name());
    421 }
    422 
    423 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
    424   return PyString_FromCppString(_GetDescriptor(self)->full_name());
    425 }
    426 
    427 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
    428   return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
    429 }
    430 
    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 
    444 static PyObject* GetFieldsByName(PyBaseDescriptor* self, void *closure) {
    445   return NewMessageFieldsByName(_GetDescriptor(self));
    446 }
    447 
    448 static PyObject* GetFieldsByCamelcaseName(PyBaseDescriptor* self,
    449                                           void *closure) {
    450   return NewMessageFieldsByCamelcaseName(_GetDescriptor(self));
    451 }
    452 
    453 static PyObject* GetFieldsByNumber(PyBaseDescriptor* self, void *closure) {
    454   return NewMessageFieldsByNumber(_GetDescriptor(self));
    455 }
    456 
    457 static PyObject* GetFieldsSeq(PyBaseDescriptor* self, void *closure) {
    458   return NewMessageFieldsSeq(_GetDescriptor(self));
    459 }
    460 
    461 static PyObject* GetNestedTypesByName(PyBaseDescriptor* self, void *closure) {
    462   return NewMessageNestedTypesByName(_GetDescriptor(self));
    463 }
    464 
    465 static PyObject* GetNestedTypesSeq(PyBaseDescriptor* self, void *closure) {
    466   return NewMessageNestedTypesSeq(_GetDescriptor(self));
    467 }
    468 
    469 static PyObject* GetExtensionsByName(PyBaseDescriptor* self, void *closure) {
    470   return NewMessageExtensionsByName(_GetDescriptor(self));
    471 }
    472 
    473 static PyObject* GetExtensions(PyBaseDescriptor* self, void *closure) {
    474   return NewMessageExtensionsSeq(_GetDescriptor(self));
    475 }
    476 
    477 static PyObject* GetEnumsSeq(PyBaseDescriptor* self, void *closure) {
    478   return NewMessageEnumsSeq(_GetDescriptor(self));
    479 }
    480 
    481 static PyObject* GetEnumTypesByName(PyBaseDescriptor* self, void *closure) {
    482   return NewMessageEnumsByName(_GetDescriptor(self));
    483 }
    484 
    485 static PyObject* GetEnumValuesByName(PyBaseDescriptor* self, void *closure) {
    486   return NewMessageEnumValuesByName(_GetDescriptor(self));
    487 }
    488 
    489 static PyObject* GetOneofsByName(PyBaseDescriptor* self, void *closure) {
    490   return NewMessageOneofsByName(_GetDescriptor(self));
    491 }
    492 
    493 static PyObject* GetOneofsSeq(PyBaseDescriptor* self, void *closure) {
    494   return NewMessageOneofsSeq(_GetDescriptor(self));
    495 }
    496 
    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 
    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 
    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 
    529 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
    530                              void *closure) {
    531   return CheckCalledFromGeneratedFile("containing_type");
    532 }
    533 
    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 }
    542 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
    543                              void *closure) {
    544   return CheckCalledFromGeneratedFile("has_options");
    545 }
    546 
    547 static PyObject* GetOptions(PyBaseDescriptor *self) {
    548   return GetOrBuildOptions(_GetDescriptor(self));
    549 }
    550 
    551 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
    552                       void *closure) {
    553   return CheckCalledFromGeneratedFile("_options");
    554 }
    555 
    556 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
    557   return CopyToPythonProto<DescriptorProto>(_GetDescriptor(self), target);
    558 }
    559 
    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 
    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 
    662 PyObject* PyMessageDescriptor_FromDescriptor(
    663     const Descriptor* message_descriptor) {
    664   return descriptor::NewInternedDescriptor(
    665       &PyMessageDescriptor_Type, message_descriptor, NULL);
    666 }
    667 
    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.
    680 static const FieldDescriptor* _GetDescriptor(
    681     PyBaseDescriptor *self) {
    682   return reinterpret_cast<const FieldDescriptor*>(self->descriptor);
    683 }
    684 
    685 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
    686   return PyString_FromCppString(_GetDescriptor(self)->full_name());
    687 }
    688 
    689 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
    690   return PyString_FromCppString(_GetDescriptor(self)->name());
    691 }
    692 
    693 static PyObject* GetCamelcaseName(PyBaseDescriptor* self, void *closure) {
    694   return PyString_FromCppString(_GetDescriptor(self)->camelcase_name());
    695 }
    696 
    697 static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
    698   return PyInt_FromLong(_GetDescriptor(self)->type());
    699 }
    700 
    701 static PyObject* GetCppType(PyBaseDescriptor *self, void *closure) {
    702   return PyInt_FromLong(_GetDescriptor(self)->cpp_type());
    703 }
    704 
    705 static PyObject* GetLabel(PyBaseDescriptor *self, void *closure) {
    706   return PyInt_FromLong(_GetDescriptor(self)->label());
    707 }
    708 
    709 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
    710   return PyInt_FromLong(_GetDescriptor(self)->number());
    711 }
    712 
    713 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
    714   return PyInt_FromLong(_GetDescriptor(self)->index());
    715 }
    716 
    717 static PyObject* GetID(PyBaseDescriptor *self, void *closure) {
    718   return PyLong_FromVoidPtr(self);
    719 }
    720 
    721 static PyObject* IsExtension(PyBaseDescriptor *self, void *closure) {
    722   return PyBool_FromLong(_GetDescriptor(self)->is_extension());
    723 }
    724 
    725 static PyObject* HasDefaultValue(PyBaseDescriptor *self, void *closure) {
    726   return PyBool_FromLong(_GetDescriptor(self)->has_default_value());
    727 }
    728 
    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 
    787 static PyObject* GetCDescriptor(PyObject *self, void *closure) {
    788   Py_INCREF(self);
    789   return self;
    790 }
    791 
    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 
    801 static int SetEnumType(PyBaseDescriptor *self, PyObject *value, void *closure) {
    802   return CheckCalledFromGeneratedFile("enum_type");
    803 }
    804 
    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 
    814 static int SetMessageType(PyBaseDescriptor *self, PyObject *value,
    815                           void *closure) {
    816   return CheckCalledFromGeneratedFile("message_type");
    817 }
    818 
    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 
    829 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
    830                              void *closure) {
    831   return CheckCalledFromGeneratedFile("containing_type");
    832 }
    833 
    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 
    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 
    854 static int SetContainingOneof(PyBaseDescriptor *self, PyObject *value,
    855                               void *closure) {
    856   return CheckCalledFromGeneratedFile("containing_oneof");
    857 }
    858 
    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 }
    867 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
    868                          void *closure) {
    869   return CheckCalledFromGeneratedFile("has_options");
    870 }
    871 
    872 static PyObject* GetOptions(PyBaseDescriptor *self) {
    873   return GetOrBuildOptions(_GetDescriptor(self));
    874 }
    875 
    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 
    952 PyObject* PyFieldDescriptor_FromDescriptor(
    953     const FieldDescriptor* field_descriptor) {
    954   return descriptor::NewInternedDescriptor(
    955       &PyFieldDescriptor_Type, field_descriptor, NULL);
    956 }
    957 
    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.
    970 static const EnumDescriptor* _GetDescriptor(
    971     PyBaseDescriptor *self) {
    972   return reinterpret_cast<const EnumDescriptor*>(self->descriptor);
    973 }
    974 
    975 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
    976   return PyString_FromCppString(_GetDescriptor(self)->full_name());
    977 }
    978 
    979 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
    980   return PyString_FromCppString(_GetDescriptor(self)->name());
    981 }
    982 
    983 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
    984   return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
    985 }
    986 
    987 static PyObject* GetEnumvaluesByName(PyBaseDescriptor* self, void *closure) {
    988   return NewEnumValuesByName(_GetDescriptor(self));
    989 }
    990 
    991 static PyObject* GetEnumvaluesByNumber(PyBaseDescriptor* self, void *closure) {
    992   return NewEnumValuesByNumber(_GetDescriptor(self));
    993 }
    994 
    995 static PyObject* GetEnumvaluesSeq(PyBaseDescriptor* self, void *closure) {
    996   return NewEnumValuesSeq(_GetDescriptor(self));
    997 }
    998 
    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 
   1009 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
   1010                              void *closure) {
   1011   return CheckCalledFromGeneratedFile("containing_type");
   1012 }
   1013 
   1014 
   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 }
   1023 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
   1024                          void *closure) {
   1025   return CheckCalledFromGeneratedFile("has_options");
   1026 }
   1027 
   1028 static PyObject* GetOptions(PyBaseDescriptor *self) {
   1029   return GetOrBuildOptions(_GetDescriptor(self));
   1030 }
   1031 
   1032 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
   1033                       void *closure) {
   1034   return CheckCalledFromGeneratedFile("_options");
   1035 }
   1036 
   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 
   1100 PyObject* PyEnumDescriptor_FromDescriptor(
   1101     const EnumDescriptor* enum_descriptor) {
   1102   return descriptor::NewInternedDescriptor(
   1103       &PyEnumDescriptor_Type, enum_descriptor, NULL);
   1104 }
   1105 
   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.
   1118 static const EnumValueDescriptor* _GetDescriptor(
   1119     PyBaseDescriptor *self) {
   1120   return reinterpret_cast<const EnumValueDescriptor*>(self->descriptor);
   1121 }
   1122 
   1123 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
   1124   return PyString_FromCppString(_GetDescriptor(self)->name());
   1125 }
   1126 
   1127 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
   1128   return PyInt_FromLong(_GetDescriptor(self)->number());
   1129 }
   1130 
   1131 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
   1132   return PyInt_FromLong(_GetDescriptor(self)->index());
   1133 }
   1134 
   1135 static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
   1136   return PyEnumDescriptor_FromDescriptor(_GetDescriptor(self)->type());
   1137 }
   1138 
   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 }
   1147 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
   1148                          void *closure) {
   1149   return CheckCalledFromGeneratedFile("has_options");
   1150 }
   1151 
   1152 static PyObject* GetOptions(PyBaseDescriptor *self) {
   1153   return GetOrBuildOptions(_GetDescriptor(self));
   1154 }
   1155 
   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 
   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.
   1223 static const FileDescriptor* _GetDescriptor(PyFileDescriptor *self) {
   1224   return reinterpret_cast<const FileDescriptor*>(self->base.descriptor);
   1225 }
   1226 
   1227 static void Dealloc(PyFileDescriptor* self) {
   1228   Py_XDECREF(self->serialized_pb);
   1229   descriptor::Dealloc(&self->base);
   1230 }
   1231 
   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 
   1239 static PyObject* GetName(PyFileDescriptor *self, void *closure) {
   1240   return PyString_FromCppString(_GetDescriptor(self)->name());
   1241 }
   1242 
   1243 static PyObject* GetPackage(PyFileDescriptor *self, void *closure) {
   1244   return PyString_FromCppString(_GetDescriptor(self)->package());
   1245 }
   1246 
   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 
   1266 static PyObject* GetMessageTypesByName(PyFileDescriptor* self, void *closure) {
   1267   return NewFileMessageTypesByName(_GetDescriptor(self));
   1268 }
   1269 
   1270 static PyObject* GetEnumTypesByName(PyFileDescriptor* self, void *closure) {
   1271   return NewFileEnumTypesByName(_GetDescriptor(self));
   1272 }
   1273 
   1274 static PyObject* GetExtensionsByName(PyFileDescriptor* self, void *closure) {
   1275   return NewFileExtensionsByName(_GetDescriptor(self));
   1276 }
   1277 
   1278 static PyObject* GetDependencies(PyFileDescriptor* self, void *closure) {
   1279   return NewFileDependencies(_GetDescriptor(self));
   1280 }
   1281 
   1282 static PyObject* GetPublicDependencies(PyFileDescriptor* self, void *closure) {
   1283   return NewFilePublicDependencies(_GetDescriptor(self));
   1284 }
   1285 
   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 }
   1294 static int SetHasOptions(PyFileDescriptor *self, PyObject *value,
   1295                          void *closure) {
   1296   return CheckCalledFromGeneratedFile("has_options");
   1297 }
   1298 
   1299 static PyObject* GetOptions(PyFileDescriptor *self) {
   1300   return GetOrBuildOptions(_GetDescriptor(self));
   1301 }
   1302 
   1303 static int SetOptions(PyFileDescriptor *self, PyObject *value,
   1304                       void *closure) {
   1305   return CheckCalledFromGeneratedFile("_options");
   1306 }
   1307 
   1308 static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) {
   1309   return PyString_InternFromString(
   1310       FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax()));
   1311 }
   1312 
   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 
   1386 PyObject* PyFileDescriptor_FromDescriptor(
   1387     const FileDescriptor* file_descriptor) {
   1388   return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor,
   1389                                                          NULL);
   1390 }
   1391 
   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 
   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.
   1424 static const OneofDescriptor* _GetDescriptor(
   1425     PyBaseDescriptor *self) {
   1426   return reinterpret_cast<const OneofDescriptor*>(self->descriptor);
   1427 }
   1428 
   1429 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
   1430   return PyString_FromCppString(_GetDescriptor(self)->name());
   1431 }
   1432 
   1433 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
   1434   return PyString_FromCppString(_GetDescriptor(self)->full_name());
   1435 }
   1436 
   1437 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
   1438   return PyInt_FromLong(_GetDescriptor(self)->index());
   1439 }
   1440 
   1441 static PyObject* GetFields(PyBaseDescriptor* self, void *closure) {
   1442   return NewOneofFieldsSeq(_GetDescriptor(self));
   1443 }
   1444 
   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 
   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.
   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 
   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 
   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