// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: petar@google.com (Petar Petrov)

#include <Python.h>
#include <frameobject.h>
#include <string>
#include <unordered_map>

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/pyext/descriptor.h>
#include <google/protobuf/pyext/descriptor_containers.h>
#include <google/protobuf/pyext/descriptor_pool.h>
#include <google/protobuf/pyext/message.h>
#include <google/protobuf/pyext/message_factory.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
#include <google/protobuf/stubs/hash.h>

#if PY_MAJOR_VERSION >= 3
  #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
  #define PyString_Check PyUnicode_Check
  #define PyString_InternFromString PyUnicode_InternFromString
  #define PyInt_FromLong PyLong_FromLong
  #define PyInt_FromSize_t PyLong_FromSize_t
  #if PY_VERSION_HEX < 0x03030000
    #error "Python 3.0 - 3.2 are not supported."
  #endif
#define PyString_AsStringAndSize(ob, charpp, sizep)                           \
  (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
                               PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
                              ? -1                                            \
                              : 0)                                            \
                       : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
#endif

namespace google {
namespace protobuf {
namespace python {

// Store interned descriptors, so that the same C++ descriptor yields the same
// Python object. Objects are not immortal: this map does not own the
// references, and items are deleted when the last reference to the object is
// released.
// This is enough to support the "is" operator on live objects.
// All descriptors are stored here.
std::unordered_map<const void*, PyObject*>* interned_descriptors;

PyObject* PyString_FromCppString(const string& str) {
  return PyString_FromStringAndSize(str.c_str(), str.size());
}

// Check that the calling Python code is the global scope of a _pb2.py module.
// This function is used to support the current code generated by the proto
// compiler, which creates descriptors, then update some properties.
// For example:
//   message_descriptor = Descriptor(
//       name='Message',
//       fields = [FieldDescriptor(name='field')]
//   message_descriptor.fields[0].containing_type = message_descriptor
//
// This code is still executed, but the descriptors now have no other storage
// than the (const) C++ pointer, and are immutable.
// So we let this code pass, by simply ignoring the new value.
//
// From user code, descriptors still look immutable.
//
// TODO(amauryfa): Change the proto2 compiler to remove the assignments, and
// remove this hack.
bool _CalledFromGeneratedFile(int stacklevel) {
#ifndef PYPY_VERSION
  // This check is not critical and is somewhat difficult to implement correctly
  // in PyPy.
  PyFrameObject* frame = PyEval_GetFrame();
  if (frame == NULL) {
    return false;
  }
  while (stacklevel-- > 0) {
    frame = frame->f_back;
    if (frame == NULL) {
      return false;
    }
  }

  if (frame->f_code->co_filename == NULL) {
    return false;
  }
  char* filename;
  Py_ssize_t filename_size;
  if (PyString_AsStringAndSize(frame->f_code->co_filename,
                               &filename, &filename_size) < 0) {
    // filename is not a string.
    PyErr_Clear();
    return false;
  }
  if ((filename_size < 3) ||
      (strcmp(&filename[filename_size - 3], ".py") != 0)) {
    // Cython's stack does not have .py file name and is not at global module
    // scope.
    return true;
  }
  if (filename_size < 7) {
    // filename is too short.
    return false;
  }
  if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) {
    // Filename is not ending with _pb2.
    return false;
  }

  if (frame->f_globals != frame->f_locals) {
    // Not at global module scope
    return false;
  }
#endif
  return true;
}

// If the calling code is not a _pb2.py file, raise AttributeError.
// To be used in attribute setters.
static int CheckCalledFromGeneratedFile(const char* attr_name) {
  if (_CalledFromGeneratedFile(0)) {
    return 0;
  }
  PyErr_Format(PyExc_AttributeError,
               "attribute is not writable: %s", attr_name);
  return -1;
}


#ifndef PyVarObject_HEAD_INIT
#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
#endif
#ifndef Py_TYPE
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#endif


// Helper functions for descriptor objects.

// A set of templates to retrieve the C++ FileDescriptor of any descriptor.
template<class DescriptorClass>
const FileDescriptor* GetFileDescriptor(const DescriptorClass* descriptor) {
  return descriptor->file();
}
template<>
const FileDescriptor* GetFileDescriptor(const FileDescriptor* descriptor) {
  return descriptor;
}
template<>
const FileDescriptor* GetFileDescriptor(const EnumValueDescriptor* descriptor) {
  return descriptor->type()->file();
}
template<>
const FileDescriptor* GetFileDescriptor(const OneofDescriptor* descriptor) {
  return descriptor->containing_type()->file();
}
template<>
const FileDescriptor* GetFileDescriptor(const MethodDescriptor* descriptor) {
  return descriptor->service()->file();
}

bool Reparse(
    PyMessageFactory* message_factory, const Message& from, Message* to) {
  // Reparse message.
  string serialized;
  from.SerializeToString(&serialized);
  io::CodedInputStream input(
      reinterpret_cast<const uint8*>(serialized.c_str()), serialized.size());
  input.SetExtensionRegistry(message_factory->pool->pool,
                             message_factory->message_factory);
  bool success = to->ParseFromCodedStream(&input);
  if (!success) {
    return false;
  }
  return true;
}
// Converts options into a Python protobuf, and cache the result.
//
// This is a bit tricky because options can contain extension fields defined in
// the same proto file. In this case the options parsed from the serialized_pb
// have unknown fields, and we need to parse them again.
//
// Always returns a new reference.
template<class DescriptorClass>
static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
  // Options are cached in the pool that owns the descriptor.
  // First search in the cache.
  PyDescriptorPool* caching_pool = GetDescriptorPool_FromPool(
      GetFileDescriptor(descriptor)->pool());
  std::unordered_map<const void*, PyObject*>* descriptor_options =
      caching_pool->descriptor_options;
  if (descriptor_options->find(descriptor) != descriptor_options->end()) {
    PyObject *value = (*descriptor_options)[descriptor];
    Py_INCREF(value);
    return value;
  }

  // Similar to the C++ implementation, we return an Options object from the
  // default (generated) factory, so that client code know that they can use
  // extensions from generated files:
  //    d.GetOptions().Extensions[some_pb2.extension]
  //
  // The consequence is that extensions not defined in the default pool won't
  // be available.  If needed, we could add an optional 'message_factory'
  // parameter to the GetOptions() function.
  PyMessageFactory* message_factory =
      GetDefaultDescriptorPool()->py_message_factory;

  // Build the Options object: get its Python class, and make a copy of the C++
  // read-only instance.
  const Message& options(descriptor->options());
  const Descriptor *message_type = options.GetDescriptor();
  CMessageClass* message_class = message_factory::GetOrCreateMessageClass(
      message_factory, message_type);
  if (message_class == NULL) {
    PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s",
                 message_type->full_name().c_str());
    return NULL;
  }
  ScopedPyObjectPtr value(
      PyEval_CallObject(message_class->AsPyObject(), NULL));
  Py_DECREF(message_class);
  if (value == NULL) {
    return NULL;
  }
  if (!PyObject_TypeCheck(value.get(), CMessage_Type)) {
      PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s",
                   message_type->full_name().c_str(),
                   Py_TYPE(value.get())->tp_name);
      return NULL;
  }
  CMessage* cmsg = reinterpret_cast<CMessage*>(value.get());

  const Reflection* reflection = options.GetReflection();
  const UnknownFieldSet& unknown_fields(reflection->GetUnknownFields(options));
  if (unknown_fields.empty()) {
    cmsg->message->CopyFrom(options);
  } else {
    // Reparse options string!  XXX call cmessage::MergeFromString
    if (!Reparse(message_factory, options, cmsg->message)) {
      PyErr_Format(PyExc_ValueError, "Error reparsing Options message");
      return NULL;
    }
  }

  // Cache the result.
  Py_INCREF(value.get());
  (*descriptor_options)[descriptor] = value.get();

  return value.release();
}

// Copy the C++ descriptor to a Python message.
// The Python message is an instance of descriptor_pb2.DescriptorProto
// or similar.
template<class DescriptorProtoClass, class DescriptorClass>
static PyObject* CopyToPythonProto(const DescriptorClass *descriptor,
                                   PyObject *target) {
  const Descriptor* self_descriptor =
      DescriptorProtoClass::default_instance().GetDescriptor();
  CMessage* message = reinterpret_cast<CMessage*>(target);
  if (!PyObject_TypeCheck(target, CMessage_Type) ||
      message->message->GetDescriptor() != self_descriptor) {
    PyErr_Format(PyExc_TypeError, "Not a %s message",
                 self_descriptor->full_name().c_str());
    return NULL;
  }
  cmessage::AssureWritable(message);
  DescriptorProtoClass* descriptor_message =
      static_cast<DescriptorProtoClass*>(message->message);
  descriptor->CopyTo(descriptor_message);
  // Custom options might in unknown extensions. Reparse
  // the descriptor_message. Can't skip reparse when options unknown
  // fields is empty, because they might in sub descriptors' options.
  PyMessageFactory* message_factory =
      GetDefaultDescriptorPool()->py_message_factory;
  if (!Reparse(message_factory, *descriptor_message, descriptor_message)) {
    PyErr_Format(PyExc_ValueError, "Error reparsing descriptor message");
    return nullptr;
  }

  Py_RETURN_NONE;
}

// All Descriptors classes share the same memory layout.
typedef struct PyBaseDescriptor {
  PyObject_HEAD

  // Pointer to the C++ proto2 descriptor.
  // Like all descriptors, it is owned by the global DescriptorPool.
  const void* descriptor;

  // Owned reference to the DescriptorPool, to ensure it is kept alive.
  PyDescriptorPool* pool;
} PyBaseDescriptor;


// FileDescriptor structure "inherits" from the base descriptor.
typedef struct PyFileDescriptor {
  PyBaseDescriptor base;

  // The cached version of serialized pb. Either NULL, or a Bytes string.
  // We own the reference.
  PyObject *serialized_pb;
} PyFileDescriptor;


namespace descriptor {

// Creates or retrieve a Python descriptor of the specified type.
// Objects are interned: the same descriptor will return the same object if it
// was kept alive.
// 'was_created' is an optional pointer to a bool, and is set to true if a new
// object was allocated.
// Always return a new reference.
template<class DescriptorClass>
PyObject* NewInternedDescriptor(PyTypeObject* type,
                                const DescriptorClass* descriptor,
                                bool* was_created) {
  if (was_created) {
    *was_created = false;
  }
  if (descriptor == NULL) {
    PyErr_BadInternalCall();
    return NULL;
  }

  // See if the object is in the map of interned descriptors
  std::unordered_map<const void*, PyObject*>::iterator it =
      interned_descriptors->find(descriptor);
  if (it != interned_descriptors->end()) {
    GOOGLE_DCHECK(Py_TYPE(it->second) == type);
    Py_INCREF(it->second);
    return it->second;
  }
  // Create a new descriptor object
  PyBaseDescriptor* py_descriptor = PyObject_GC_New(
      PyBaseDescriptor, type);
  if (py_descriptor == NULL) {
    return NULL;
  }
  py_descriptor->descriptor = descriptor;

  // and cache it.
  interned_descriptors->insert(
      std::make_pair(descriptor, reinterpret_cast<PyObject*>(py_descriptor)));

  // Ensures that the DescriptorPool stays alive.
  PyDescriptorPool* pool = GetDescriptorPool_FromPool(
      GetFileDescriptor(descriptor)->pool());
  if (pool == NULL) {
    // Don't DECREF, the object is not fully initialized.
    PyObject_Del(py_descriptor);
    return NULL;
  }
  Py_INCREF(pool);
  py_descriptor->pool = pool;

  PyObject_GC_Track(py_descriptor);

  if (was_created) {
    *was_created = true;
  }
  return reinterpret_cast<PyObject*>(py_descriptor);
}

static void Dealloc(PyBaseDescriptor* self) {
  // Remove from interned dictionary
  interned_descriptors->erase(self->descriptor);
  Py_CLEAR(self->pool);
  Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
}

static int GcTraverse(PyObject* pself, visitproc visit, void* arg) {
  PyBaseDescriptor* self = reinterpret_cast<PyBaseDescriptor*>(pself);
  Py_VISIT(self->pool);
  return 0;
}

static int GcClear(PyObject* pself) {
  PyBaseDescriptor* self = reinterpret_cast<PyBaseDescriptor*>(pself);
  Py_CLEAR(self->pool);
  return 0;
}

static PyGetSetDef Getters[] = {
  {NULL}
};

PyTypeObject PyBaseDescriptor_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
    ".DescriptorBase",                        // tp_name
    sizeof(PyBaseDescriptor),                 // tp_basicsize
    0,                                        // tp_itemsize
    (destructor)Dealloc,                      // tp_dealloc
    0,                                        // tp_print
    0,                                        // tp_getattr
    0,                                        // tp_setattr
    0,                                        // tp_compare
    0,                                        // tp_repr
    0,                                        // tp_as_number
    0,                                        // tp_as_sequence
    0,                                        // tp_as_mapping
    0,                                        // tp_hash
    0,                                        // tp_call
    0,                                        // tp_str
    0,                                        // tp_getattro
    0,                                        // tp_setattro
    0,                                        // tp_as_buffer
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,  // tp_flags
    "Descriptors base class",                 // tp_doc
    GcTraverse,                               // tp_traverse
    GcClear,                                  // tp_clear
    0,                                        // tp_richcompare
    0,                                        // tp_weaklistoffset
    0,                                        // tp_iter
    0,                                        // tp_iternext
    0,                                        // tp_methods
    0,                                        // tp_members
    Getters,                                  // tp_getset
};

}  // namespace descriptor

const void* PyDescriptor_AsVoidPtr(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &descriptor::PyBaseDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a BaseDescriptor");
    return NULL;
  }
  return reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor;
}

namespace message_descriptor {

// Unchecked accessor to the C++ pointer.
static const Descriptor* _GetDescriptor(PyBaseDescriptor* self) {
  return reinterpret_cast<const Descriptor*>(self->descriptor);
}

static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->full_name());
}

static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
  return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
}

static PyObject* GetConcreteClass(PyBaseDescriptor* self, void *closure) {
  // Retuns the canonical class for the given descriptor.
  // This is the class that was registered with the primary descriptor pool
  // which contains this descriptor.
  // This might not be the one you expect! For example the returned object does
  // not know about extensions defined in a custom pool.
  CMessageClass* concrete_class(message_factory::GetMessageClass(
      GetDescriptorPool_FromPool(
          _GetDescriptor(self)->file()->pool())->py_message_factory,
      _GetDescriptor(self)));
  Py_XINCREF(concrete_class);
  return concrete_class->AsPyObject();
}

static PyObject* GetFieldsByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageFieldsByName(_GetDescriptor(self));
}

static PyObject* GetFieldsByCamelcaseName(PyBaseDescriptor* self,
                                          void *closure) {
  return NewMessageFieldsByCamelcaseName(_GetDescriptor(self));
}

static PyObject* GetFieldsByNumber(PyBaseDescriptor* self, void *closure) {
  return NewMessageFieldsByNumber(_GetDescriptor(self));
}

static PyObject* GetFieldsSeq(PyBaseDescriptor* self, void *closure) {
  return NewMessageFieldsSeq(_GetDescriptor(self));
}

static PyObject* GetNestedTypesByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageNestedTypesByName(_GetDescriptor(self));
}

static PyObject* GetNestedTypesSeq(PyBaseDescriptor* self, void *closure) {
  return NewMessageNestedTypesSeq(_GetDescriptor(self));
}

static PyObject* GetExtensionsByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageExtensionsByName(_GetDescriptor(self));
}

static PyObject* GetExtensions(PyBaseDescriptor* self, void *closure) {
  return NewMessageExtensionsSeq(_GetDescriptor(self));
}

static PyObject* GetEnumsSeq(PyBaseDescriptor* self, void *closure) {
  return NewMessageEnumsSeq(_GetDescriptor(self));
}

static PyObject* GetEnumTypesByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageEnumsByName(_GetDescriptor(self));
}

static PyObject* GetEnumValuesByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageEnumValuesByName(_GetDescriptor(self));
}

static PyObject* GetOneofsByName(PyBaseDescriptor* self, void *closure) {
  return NewMessageOneofsByName(_GetDescriptor(self));
}

static PyObject* GetOneofsSeq(PyBaseDescriptor* self, void *closure) {
  return NewMessageOneofsSeq(_GetDescriptor(self));
}

static PyObject* IsExtendable(PyBaseDescriptor *self, void *closure) {
  if (_GetDescriptor(self)->extension_range_count() > 0) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}

static PyObject* GetExtensionRanges(PyBaseDescriptor *self, void *closure) {
  const Descriptor* descriptor = _GetDescriptor(self);
  PyObject* range_list = PyList_New(descriptor->extension_range_count());

  for (int i = 0; i < descriptor->extension_range_count(); i++) {
    const Descriptor::ExtensionRange* range = descriptor->extension_range(i);
    PyObject* start = PyInt_FromLong(range->start);
    PyObject* end = PyInt_FromLong(range->end);
    PyList_SetItem(range_list, i, PyTuple_Pack(2, start, end));
  }

  return range_list;
}

static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* containing_type =
      _GetDescriptor(self)->containing_type();
  if (containing_type) {
    return PyMessageDescriptor_FromDescriptor(containing_type);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
                             void *closure) {
  return CheckCalledFromGeneratedFile("containing_type");
}

static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
  const MessageOptions& options(_GetDescriptor(self)->options());
  if (&options != &MessageOptions::default_instance()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}
static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
                             void *closure) {
  return CheckCalledFromGeneratedFile("has_options");
}

static PyObject* GetOptions(PyBaseDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static int SetOptions(PyBaseDescriptor *self, PyObject *value,
                      void *closure) {
  return CheckCalledFromGeneratedFile("_options");
}

static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
                                void *closure) {
  return CheckCalledFromGeneratedFile("_serialized_options");
}

static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
  return CopyToPythonProto<DescriptorProto>(_GetDescriptor(self), target);
}

static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) {
  const char *enum_name;
  int number;
  if (!PyArg_ParseTuple(args, "si", &enum_name, &number))
    return NULL;
  const EnumDescriptor *enum_type =
      _GetDescriptor(self)->FindEnumTypeByName(enum_name);
  if (enum_type == NULL) {
    PyErr_SetString(PyExc_KeyError, enum_name);
    return NULL;
  }
  const EnumValueDescriptor *enum_value =
      enum_type->FindValueByNumber(number);
  if (enum_value == NULL) {
    PyErr_Format(PyExc_KeyError, "%d", number);
    return NULL;
  }
  return PyString_FromCppString(enum_value->name());
}

static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) {
  return PyString_InternFromString(
      FileDescriptor::SyntaxName(_GetDescriptor(self)->file()->syntax()));
}

static PyGetSetDef Getters[] = {
  { "name", (getter)GetName, NULL, "Last name"},
  { "full_name", (getter)GetFullName, NULL, "Full name"},
  { "_concrete_class", (getter)GetConcreteClass, NULL, "concrete class"},
  { "file", (getter)GetFile, NULL, "File descriptor"},

  { "fields", (getter)GetFieldsSeq, NULL, "Fields sequence"},
  { "fields_by_name", (getter)GetFieldsByName, NULL, "Fields by name"},
  { "fields_by_camelcase_name", (getter)GetFieldsByCamelcaseName, NULL,
    "Fields by camelCase name"},
  { "fields_by_number", (getter)GetFieldsByNumber, NULL, "Fields by number"},
  { "nested_types", (getter)GetNestedTypesSeq, NULL, "Nested types sequence"},
  { "nested_types_by_name", (getter)GetNestedTypesByName, NULL,
    "Nested types by name"},
  { "extensions", (getter)GetExtensions, NULL, "Extensions Sequence"},
  { "extensions_by_name", (getter)GetExtensionsByName, NULL,
    "Extensions by name"},
  { "extension_ranges", (getter)GetExtensionRanges, NULL, "Extension ranges"},
  { "enum_types", (getter)GetEnumsSeq, NULL, "Enum sequence"},
  { "enum_types_by_name", (getter)GetEnumTypesByName, NULL,
    "Enum types by name"},
  { "enum_values_by_name", (getter)GetEnumValuesByName, NULL,
    "Enum values by name"},
  { "oneofs_by_name", (getter)GetOneofsByName, NULL, "Oneofs by name"},
  { "oneofs", (getter)GetOneofsSeq, NULL, "Oneofs by name"},
  { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
    "Containing type"},
  { "is_extendable", (getter)IsExtendable, (setter)NULL},
  { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
  { "_options", (getter)NULL, (setter)SetOptions, "Options"},
  { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
    "Serialized Options"},
  { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
  {NULL}
};

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
  { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
  { "EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS, },
  {NULL}
};

}  // namespace message_descriptor

PyTypeObject PyMessageDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".MessageDescriptor",  // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // tp_dealloc
  0,                                    // tp_print
  0,                                    // tp_getattr
  0,                                    // tp_setattr
  0,                                    // tp_compare
  0,                                    // tp_repr
  0,                                    // tp_as_number
  0,                                    // tp_as_sequence
  0,                                    // tp_as_mapping
  0,                                    // tp_hash
  0,                                    // tp_call
  0,                                    // tp_str
  0,                                    // tp_getattro
  0,                                    // tp_setattro
  0,                                    // tp_as_buffer
  Py_TPFLAGS_DEFAULT,                   // tp_flags
  "A Message Descriptor",               // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  message_descriptor::Methods,          // tp_methods
  0,                                    // tp_members
  message_descriptor::Getters,          // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyMessageDescriptor_FromDescriptor(
    const Descriptor* message_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyMessageDescriptor_Type, message_descriptor, NULL);
}

const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyMessageDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a MessageDescriptor");
    return NULL;
  }
  return reinterpret_cast<const Descriptor*>(
      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
}

namespace field_descriptor {

// Unchecked accessor to the C++ pointer.
static const FieldDescriptor* _GetDescriptor(
    PyBaseDescriptor *self) {
  return reinterpret_cast<const FieldDescriptor*>(self->descriptor);
}

static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->full_name());
}

static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetCamelcaseName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->camelcase_name());
}

static PyObject* GetJsonName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->json_name());
}

static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
  return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
}

static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->type());
}

static PyObject* GetCppType(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->cpp_type());
}

static PyObject* GetLabel(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->label());
}

static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->number());
}

static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->index());
}

static PyObject* GetID(PyBaseDescriptor *self, void *closure) {
  return PyLong_FromVoidPtr(self);
}

static PyObject* IsExtension(PyBaseDescriptor *self, void *closure) {
  return PyBool_FromLong(_GetDescriptor(self)->is_extension());
}

static PyObject* HasDefaultValue(PyBaseDescriptor *self, void *closure) {
  return PyBool_FromLong(_GetDescriptor(self)->has_default_value());
}

static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) {
  PyObject *result;

  if (_GetDescriptor(self)->is_repeated()) {
    return PyList_New(0);
  }


  switch (_GetDescriptor(self)->cpp_type()) {
    case FieldDescriptor::CPPTYPE_INT32: {
      int32 value = _GetDescriptor(self)->default_value_int32();
      result = PyInt_FromLong(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_INT64: {
      int64 value = _GetDescriptor(self)->default_value_int64();
      result = PyLong_FromLongLong(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_UINT32: {
      uint32 value = _GetDescriptor(self)->default_value_uint32();
      result = PyInt_FromSize_t(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_UINT64: {
      uint64 value = _GetDescriptor(self)->default_value_uint64();
      result = PyLong_FromUnsignedLongLong(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_FLOAT: {
      float value = _GetDescriptor(self)->default_value_float();
      result = PyFloat_FromDouble(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_DOUBLE: {
      double value = _GetDescriptor(self)->default_value_double();
      result = PyFloat_FromDouble(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_BOOL: {
      bool value = _GetDescriptor(self)->default_value_bool();
      result = PyBool_FromLong(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_STRING: {
      const string& value = _GetDescriptor(self)->default_value_string();
      result = ToStringObject(_GetDescriptor(self), value);
      break;
    }
    case FieldDescriptor::CPPTYPE_ENUM: {
      const EnumValueDescriptor* value =
          _GetDescriptor(self)->default_value_enum();
      result = PyInt_FromLong(value->number());
      break;
    }
    case FieldDescriptor::CPPTYPE_MESSAGE: {
      Py_RETURN_NONE;
      break;
    }
    default:
      PyErr_Format(PyExc_NotImplementedError, "default value for %s",
                   _GetDescriptor(self)->full_name().c_str());
      return NULL;
  }
  return result;
}

static PyObject* GetCDescriptor(PyObject *self, void *closure) {
  Py_INCREF(self);
  return self;
}

static PyObject *GetEnumType(PyBaseDescriptor *self, void *closure) {
  const EnumDescriptor* enum_type = _GetDescriptor(self)->enum_type();
  if (enum_type) {
    return PyEnumDescriptor_FromDescriptor(enum_type);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetEnumType(PyBaseDescriptor *self, PyObject *value, void *closure) {
  return CheckCalledFromGeneratedFile("enum_type");
}

static PyObject *GetMessageType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* message_type = _GetDescriptor(self)->message_type();
  if (message_type) {
    return PyMessageDescriptor_FromDescriptor(message_type);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetMessageType(PyBaseDescriptor *self, PyObject *value,
                          void *closure) {
  return CheckCalledFromGeneratedFile("message_type");
}

static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* containing_type =
      _GetDescriptor(self)->containing_type();
  if (containing_type) {
    return PyMessageDescriptor_FromDescriptor(containing_type);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
                             void *closure) {
  return CheckCalledFromGeneratedFile("containing_type");
}

static PyObject* GetExtensionScope(PyBaseDescriptor *self, void *closure) {
  const Descriptor* extension_scope =
      _GetDescriptor(self)->extension_scope();
  if (extension_scope) {
    return PyMessageDescriptor_FromDescriptor(extension_scope);
  } else {
    Py_RETURN_NONE;
  }
}

static PyObject* GetContainingOneof(PyBaseDescriptor *self, void *closure) {
  const OneofDescriptor* containing_oneof =
      _GetDescriptor(self)->containing_oneof();
  if (containing_oneof) {
    return PyOneofDescriptor_FromDescriptor(containing_oneof);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetContainingOneof(PyBaseDescriptor *self, PyObject *value,
                              void *closure) {
  return CheckCalledFromGeneratedFile("containing_oneof");
}

static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
  const FieldOptions& options(_GetDescriptor(self)->options());
  if (&options != &FieldOptions::default_instance()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}
static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
                         void *closure) {
  return CheckCalledFromGeneratedFile("has_options");
}

static PyObject* GetOptions(PyBaseDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static int SetOptions(PyBaseDescriptor *self, PyObject *value,
                      void *closure) {
  return CheckCalledFromGeneratedFile("_options");
}

static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
                                void *closure) {
  return CheckCalledFromGeneratedFile("_serialized_options");
}

static PyGetSetDef Getters[] = {
  { "full_name", (getter)GetFullName, NULL, "Full name"},
  { "name", (getter)GetName, NULL, "Unqualified name"},
  { "camelcase_name", (getter)GetCamelcaseName, NULL, "Camelcase name"},
  { "json_name", (getter)GetJsonName, NULL, "Json name"},
  { "file", (getter)GetFile, NULL, "File Descriptor"},
  { "type", (getter)GetType, NULL, "C++ Type"},
  { "cpp_type", (getter)GetCppType, NULL, "C++ Type"},
  { "label", (getter)GetLabel, NULL, "Label"},
  { "number", (getter)GetNumber, NULL, "Number"},
  { "index", (getter)GetIndex, NULL, "Index"},
  { "default_value", (getter)GetDefaultValue, NULL, "Default Value"},
  { "has_default_value", (getter)HasDefaultValue},
  { "is_extension", (getter)IsExtension, NULL, "ID"},
  { "id", (getter)GetID, NULL, "ID"},
  { "_cdescriptor", (getter)GetCDescriptor, NULL, "HAACK REMOVE ME"},

  { "message_type", (getter)GetMessageType, (setter)SetMessageType,
    "Message type"},
  { "enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"},
  { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
    "Containing type"},
  { "extension_scope", (getter)GetExtensionScope, (setter)NULL,
    "Extension scope"},
  { "containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof,
    "Containing oneof"},
  { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
  { "_options", (getter)NULL, (setter)SetOptions, "Options"},
  { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
    "Serialized Options"},
  {NULL}
};

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
  {NULL}
};

}  // namespace field_descriptor

PyTypeObject PyFieldDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".FieldDescriptor",  // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // tp_dealloc
  0,                                    // tp_print
  0,                                    // tp_getattr
  0,                                    // tp_setattr
  0,                                    // tp_compare
  0,                                    // tp_repr
  0,                                    // tp_as_number
  0,                                    // tp_as_sequence
  0,                                    // tp_as_mapping
  0,                                    // tp_hash
  0,                                    // tp_call
  0,                                    // tp_str
  0,                                    // tp_getattro
  0,                                    // tp_setattro
  0,                                    // tp_as_buffer
  Py_TPFLAGS_DEFAULT,                   // tp_flags
  "A Field Descriptor",                 // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  field_descriptor::Methods,            // tp_methods
  0,                                    // tp_members
  field_descriptor::Getters,            // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyFieldDescriptor_FromDescriptor(
    const FieldDescriptor* field_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyFieldDescriptor_Type, field_descriptor, NULL);
}

const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyFieldDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a FieldDescriptor");
    return NULL;
  }
  return reinterpret_cast<const FieldDescriptor*>(
      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
}

namespace enum_descriptor {

// Unchecked accessor to the C++ pointer.
static const EnumDescriptor* _GetDescriptor(
    PyBaseDescriptor *self) {
  return reinterpret_cast<const EnumDescriptor*>(self->descriptor);
}

static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->full_name());
}

static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
  return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
}

static PyObject* GetEnumvaluesByName(PyBaseDescriptor* self, void *closure) {
  return NewEnumValuesByName(_GetDescriptor(self));
}

static PyObject* GetEnumvaluesByNumber(PyBaseDescriptor* self, void *closure) {
  return NewEnumValuesByNumber(_GetDescriptor(self));
}

static PyObject* GetEnumvaluesSeq(PyBaseDescriptor* self, void *closure) {
  return NewEnumValuesSeq(_GetDescriptor(self));
}

static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* containing_type =
      _GetDescriptor(self)->containing_type();
  if (containing_type) {
    return PyMessageDescriptor_FromDescriptor(containing_type);
  } else {
    Py_RETURN_NONE;
  }
}

static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
                             void *closure) {
  return CheckCalledFromGeneratedFile("containing_type");
}


static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
  const EnumOptions& options(_GetDescriptor(self)->options());
  if (&options != &EnumOptions::default_instance()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}
static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
                         void *closure) {
  return CheckCalledFromGeneratedFile("has_options");
}

static PyObject* GetOptions(PyBaseDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static int SetOptions(PyBaseDescriptor *self, PyObject *value,
                      void *closure) {
  return CheckCalledFromGeneratedFile("_options");
}

static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
                                void *closure) {
  return CheckCalledFromGeneratedFile("_serialized_options");
}

static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
  return CopyToPythonProto<EnumDescriptorProto>(_GetDescriptor(self), target);
}

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
  { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
  {NULL}
};

static PyGetSetDef Getters[] = {
  { "full_name", (getter)GetFullName, NULL, "Full name"},
  { "name", (getter)GetName, NULL, "last name"},
  { "file", (getter)GetFile, NULL, "File descriptor"},
  { "values", (getter)GetEnumvaluesSeq, NULL, "values"},
  { "values_by_name", (getter)GetEnumvaluesByName, NULL,
    "Enum values by name"},
  { "values_by_number", (getter)GetEnumvaluesByNumber, NULL,
    "Enum values by number"},

  { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
    "Containing type"},
  { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
  { "_options", (getter)NULL, (setter)SetOptions, "Options"},
  { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
    "Serialized Options"},
  {NULL}
};

}  // namespace enum_descriptor

PyTypeObject PyEnumDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".EnumDescriptor",   // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // tp_dealloc
  0,                                    // tp_print
  0,                                    // tp_getattr
  0,                                    // tp_setattr
  0,                                    // tp_compare
  0,                                    // tp_repr
  0,                                    // tp_as_number
  0,                                    // tp_as_sequence
  0,                                    // tp_as_mapping
  0,                                    // tp_hash
  0,                                    // tp_call
  0,                                    // tp_str
  0,                                    // tp_getattro
  0,                                    // tp_setattro
  0,                                    // tp_as_buffer
  Py_TPFLAGS_DEFAULT,                   // tp_flags
  "A Enum Descriptor",                  // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  enum_descriptor::Methods,             // tp_methods
  0,                                    // tp_members
  enum_descriptor::Getters,             // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyEnumDescriptor_FromDescriptor(
    const EnumDescriptor* enum_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyEnumDescriptor_Type, enum_descriptor, NULL);
}

const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyEnumDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not an EnumDescriptor");
    return NULL;
  }
  return reinterpret_cast<const EnumDescriptor*>(
      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
}

namespace enumvalue_descriptor {

// Unchecked accessor to the C++ pointer.
static const EnumValueDescriptor* _GetDescriptor(
    PyBaseDescriptor *self) {
  return reinterpret_cast<const EnumValueDescriptor*>(self->descriptor);
}

static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->number());
}

static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->index());
}

static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
  return PyEnumDescriptor_FromDescriptor(_GetDescriptor(self)->type());
}

static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
  const EnumValueOptions& options(_GetDescriptor(self)->options());
  if (&options != &EnumValueOptions::default_instance()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}
static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
                         void *closure) {
  return CheckCalledFromGeneratedFile("has_options");
}

static PyObject* GetOptions(PyBaseDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static int SetOptions(PyBaseDescriptor *self, PyObject *value,
                      void *closure) {
  return CheckCalledFromGeneratedFile("_options");
}

static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
                                void *closure) {
  return CheckCalledFromGeneratedFile("_serialized_options");
}

static PyGetSetDef Getters[] = {
  { "name", (getter)GetName, NULL, "name"},
  { "number", (getter)GetNumber, NULL, "number"},
  { "index", (getter)GetIndex, NULL, "index"},
  { "type", (getter)GetType, NULL, "index"},

  { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
  { "_options", (getter)NULL, (setter)SetOptions, "Options"},
  { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
    "Serialized Options"},
  {NULL}
};

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
  {NULL}
};

}  // namespace enumvalue_descriptor

PyTypeObject PyEnumValueDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".EnumValueDescriptor",  // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // tp_dealloc
  0,                                    // tp_print
  0,                                    // tp_getattr
  0,                                    // tp_setattr
  0,                                    // tp_compare
  0,                                    // tp_repr
  0,                                    // tp_as_number
  0,                                    // tp_as_sequence
  0,                                    // tp_as_mapping
  0,                                    // tp_hash
  0,                                    // tp_call
  0,                                    // tp_str
  0,                                    // tp_getattro
  0,                                    // tp_setattro
  0,                                    // tp_as_buffer
  Py_TPFLAGS_DEFAULT,                   // tp_flags
  "A EnumValue Descriptor",             // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  enumvalue_descriptor::Methods,        // tp_methods
  0,                                    // tp_members
  enumvalue_descriptor::Getters,        // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyEnumValueDescriptor_FromDescriptor(
    const EnumValueDescriptor* enumvalue_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyEnumValueDescriptor_Type, enumvalue_descriptor, NULL);
}

namespace file_descriptor {

// Unchecked accessor to the C++ pointer.
static const FileDescriptor* _GetDescriptor(PyFileDescriptor *self) {
  return reinterpret_cast<const FileDescriptor*>(self->base.descriptor);
}

static void Dealloc(PyFileDescriptor* self) {
  Py_XDECREF(self->serialized_pb);
  descriptor::Dealloc(&self->base);
}

static PyObject* GetPool(PyFileDescriptor *self, void *closure) {
  PyObject* pool = reinterpret_cast<PyObject*>(
      GetDescriptorPool_FromPool(_GetDescriptor(self)->pool()));
  Py_XINCREF(pool);
  return pool;
}

static PyObject* GetName(PyFileDescriptor *self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetPackage(PyFileDescriptor *self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->package());
}

static PyObject* GetSerializedPb(PyFileDescriptor *self, void *closure) {
  PyObject *serialized_pb = self->serialized_pb;
  if (serialized_pb != NULL) {
    Py_INCREF(serialized_pb);
    return serialized_pb;
  }
  FileDescriptorProto file_proto;
  _GetDescriptor(self)->CopyTo(&file_proto);
  string contents;
  file_proto.SerializePartialToString(&contents);
  self->serialized_pb = PyBytes_FromStringAndSize(
      contents.c_str(), contents.size());
  if (self->serialized_pb == NULL) {
    return NULL;
  }
  Py_INCREF(self->serialized_pb);
  return self->serialized_pb;
}

static PyObject* GetMessageTypesByName(PyFileDescriptor* self, void *closure) {
  return NewFileMessageTypesByName(_GetDescriptor(self));
}

static PyObject* GetEnumTypesByName(PyFileDescriptor* self, void *closure) {
  return NewFileEnumTypesByName(_GetDescriptor(self));
}

static PyObject* GetExtensionsByName(PyFileDescriptor* self, void *closure) {
  return NewFileExtensionsByName(_GetDescriptor(self));
}

static PyObject* GetServicesByName(PyFileDescriptor* self, void *closure) {
  return NewFileServicesByName(_GetDescriptor(self));
}

static PyObject* GetDependencies(PyFileDescriptor* self, void *closure) {
  return NewFileDependencies(_GetDescriptor(self));
}

static PyObject* GetPublicDependencies(PyFileDescriptor* self, void *closure) {
  return NewFilePublicDependencies(_GetDescriptor(self));
}

static PyObject* GetHasOptions(PyFileDescriptor *self, void *closure) {
  const FileOptions& options(_GetDescriptor(self)->options());
  if (&options != &FileOptions::default_instance()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}
static int SetHasOptions(PyFileDescriptor *self, PyObject *value,
                         void *closure) {
  return CheckCalledFromGeneratedFile("has_options");
}

static PyObject* GetOptions(PyFileDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static int SetOptions(PyFileDescriptor *self, PyObject *value,
                      void *closure) {
  return CheckCalledFromGeneratedFile("_options");
}

static int SetSerializedOptions(PyFileDescriptor *self, PyObject *value,
                                void *closure) {
  return CheckCalledFromGeneratedFile("_serialized_options");
}

static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) {
  return PyString_InternFromString(
      FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax()));
}

static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) {
  return CopyToPythonProto<FileDescriptorProto>(_GetDescriptor(self), target);
}

static PyGetSetDef Getters[] = {
  { "pool", (getter)GetPool, NULL, "pool"},
  { "name", (getter)GetName, NULL, "name"},
  { "package", (getter)GetPackage, NULL, "package"},
  { "serialized_pb", (getter)GetSerializedPb},
  { "message_types_by_name", (getter)GetMessageTypesByName, NULL,
    "Messages by name"},
  { "enum_types_by_name", (getter)GetEnumTypesByName, NULL, "Enums by name"},
  { "extensions_by_name", (getter)GetExtensionsByName, NULL,
    "Extensions by name"},
  { "services_by_name", (getter)GetServicesByName, NULL, "Services by name"},
  { "dependencies", (getter)GetDependencies, NULL, "Dependencies"},
  { "public_dependencies", (getter)GetPublicDependencies, NULL, "Dependencies"},

  { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
  { "_options", (getter)NULL, (setter)SetOptions, "Options"},
  { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
    "Serialized Options"},
  { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
  {NULL}
};

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
  { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
  {NULL}
};

}  // namespace file_descriptor

PyTypeObject PyFileDescriptor_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME
    ".FileDescriptor",                     // tp_name
    sizeof(PyFileDescriptor),              // tp_basicsize
    0,                                     // tp_itemsize
    (destructor)file_descriptor::Dealloc,  // tp_dealloc
    0,                                     // tp_print
    0,                                     // tp_getattr
    0,                                     // tp_setattr
    0,                                     // tp_compare
    0,                                     // tp_repr
    0,                                     // tp_as_number
    0,                                     // tp_as_sequence
    0,                                     // tp_as_mapping
    0,                                     // tp_hash
    0,                                     // tp_call
    0,                                     // tp_str
    0,                                     // tp_getattro
    0,                                     // tp_setattro
    0,                                     // tp_as_buffer
    Py_TPFLAGS_DEFAULT,                    // tp_flags
    "A File Descriptor",                   // tp_doc
    0,                                     // tp_traverse
    0,                                     // tp_clear
    0,                                     // tp_richcompare
    0,                                     // tp_weaklistoffset
    0,                                     // tp_iter
    0,                                     // tp_iternext
    file_descriptor::Methods,              // tp_methods
    0,                                     // tp_members
    file_descriptor::Getters,              // tp_getset
    &descriptor::PyBaseDescriptor_Type,    // tp_base
    0,                                     // tp_dict
    0,                                     // tp_descr_get
    0,                                     // tp_descr_set
    0,                                     // tp_dictoffset
    0,                                     // tp_init
    0,                                     // tp_alloc
    0,                                     // tp_new
    PyObject_GC_Del,                       // tp_free
};

PyObject* PyFileDescriptor_FromDescriptor(
    const FileDescriptor* file_descriptor) {
  return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor,
                                                         NULL);
}

PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb(
    const FileDescriptor* file_descriptor, PyObject *serialized_pb) {
  bool was_created;
  PyObject* py_descriptor = descriptor::NewInternedDescriptor(
      &PyFileDescriptor_Type, file_descriptor, &was_created);
  if (py_descriptor == NULL) {
    return NULL;
  }
  if (was_created) {
    PyFileDescriptor* cfile_descriptor =
        reinterpret_cast<PyFileDescriptor*>(py_descriptor);
    Py_XINCREF(serialized_pb);
    cfile_descriptor->serialized_pb = serialized_pb;
  }
  // TODO(amauryfa): In the case of a cached object, check that serialized_pb
  // is the same as before.

  return py_descriptor;
}

const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyFileDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a FileDescriptor");
    return NULL;
  }
  return reinterpret_cast<const FileDescriptor*>(
      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
}

namespace oneof_descriptor {

// Unchecked accessor to the C++ pointer.
static const OneofDescriptor* _GetDescriptor(
    PyBaseDescriptor *self) {
  return reinterpret_cast<const OneofDescriptor*>(self->descriptor);
}

static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->full_name());
}

static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->index());
}

static PyObject* GetFields(PyBaseDescriptor* self, void *closure) {
  return NewOneofFieldsSeq(_GetDescriptor(self));
}

static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* containing_type =
      _GetDescriptor(self)->containing_type();
  if (containing_type) {
    return PyMessageDescriptor_FromDescriptor(containing_type);
  } else {
    Py_RETURN_NONE;
  }
}

static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
  const OneofOptions& options(_GetDescriptor(self)->options());
  if (&options != &OneofOptions::default_instance()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}
static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
                         void *closure) {
  return CheckCalledFromGeneratedFile("has_options");
}

static PyObject* GetOptions(PyBaseDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static int SetOptions(PyBaseDescriptor *self, PyObject *value,
                      void *closure) {
  return CheckCalledFromGeneratedFile("_options");
}

static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value,
                                void *closure) {
  return CheckCalledFromGeneratedFile("_serialized_options");
}

static PyGetSetDef Getters[] = {
  { "name", (getter)GetName, NULL, "Name"},
  { "full_name", (getter)GetFullName, NULL, "Full name"},
  { "index", (getter)GetIndex, NULL, "Index"},

  { "containing_type", (getter)GetContainingType, NULL, "Containing type"},
  { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
  { "_options", (getter)NULL, (setter)SetOptions, "Options"},
  { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions,
    "Serialized Options"},
  { "fields", (getter)GetFields, NULL, "Fields"},
  {NULL}
};

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS },
  {NULL}
};

}  // namespace oneof_descriptor

PyTypeObject PyOneofDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".OneofDescriptor",  // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // tp_dealloc
  0,                                    // tp_print
  0,                                    // tp_getattr
  0,                                    // tp_setattr
  0,                                    // tp_compare
  0,                                    // tp_repr
  0,                                    // tp_as_number
  0,                                    // tp_as_sequence
  0,                                    // tp_as_mapping
  0,                                    // tp_hash
  0,                                    // tp_call
  0,                                    // tp_str
  0,                                    // tp_getattro
  0,                                    // tp_setattro
  0,                                    // tp_as_buffer
  Py_TPFLAGS_DEFAULT,                   // tp_flags
  "A Oneof Descriptor",                 // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  oneof_descriptor::Methods,            // tp_methods
  0,                                    // tp_members
  oneof_descriptor::Getters,            // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyOneofDescriptor_FromDescriptor(
    const OneofDescriptor* oneof_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyOneofDescriptor_Type, oneof_descriptor, NULL);
}

namespace service_descriptor {

// Unchecked accessor to the C++ pointer.
static const ServiceDescriptor* _GetDescriptor(
    PyBaseDescriptor *self) {
  return reinterpret_cast<const ServiceDescriptor*>(self->descriptor);
}

static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->full_name());
}

static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
  return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
}

static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->index());
}

static PyObject* GetMethods(PyBaseDescriptor* self, void *closure) {
  return NewServiceMethodsSeq(_GetDescriptor(self));
}

static PyObject* GetMethodsByName(PyBaseDescriptor* self, void *closure) {
  return NewServiceMethodsByName(_GetDescriptor(self));
}

static PyObject* FindMethodByName(PyBaseDescriptor *self, PyObject* arg) {
  Py_ssize_t name_size;
  char* name;
  if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
    return NULL;
  }

  const MethodDescriptor* method_descriptor =
      _GetDescriptor(self)->FindMethodByName(string(name, name_size));
  if (method_descriptor == NULL) {
    PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
    return NULL;
  }

  return PyMethodDescriptor_FromDescriptor(method_descriptor);
}

static PyObject* GetOptions(PyBaseDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
  return CopyToPythonProto<ServiceDescriptorProto>(_GetDescriptor(self),
                                                   target);
}

static PyGetSetDef Getters[] = {
  { "name", (getter)GetName, NULL, "Name", NULL},
  { "full_name", (getter)GetFullName, NULL, "Full name", NULL},
  { "file", (getter)GetFile, NULL, "File descriptor"},
  { "index", (getter)GetIndex, NULL, "Index", NULL},

  { "methods", (getter)GetMethods, NULL, "Methods", NULL},
  { "methods_by_name", (getter)GetMethodsByName, NULL, "Methods by name", NULL},
  {NULL}
};

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS },
  { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
  { "FindMethodByName", (PyCFunction)FindMethodByName, METH_O },
  {NULL}
};

}  // namespace service_descriptor

PyTypeObject PyServiceDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".ServiceDescriptor",  // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // tp_dealloc
  0,                                    // tp_print
  0,                                    // tp_getattr
  0,                                    // tp_setattr
  0,                                    // tp_compare
  0,                                    // tp_repr
  0,                                    // tp_as_number
  0,                                    // tp_as_sequence
  0,                                    // tp_as_mapping
  0,                                    // tp_hash
  0,                                    // tp_call
  0,                                    // tp_str
  0,                                    // tp_getattro
  0,                                    // tp_setattro
  0,                                    // tp_as_buffer
  Py_TPFLAGS_DEFAULT,                   // tp_flags
  "A Service Descriptor",               // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  service_descriptor::Methods,          // tp_methods
  0,                                    // tp_members
  service_descriptor::Getters,          // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyServiceDescriptor_FromDescriptor(
    const ServiceDescriptor* service_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyServiceDescriptor_Type, service_descriptor, NULL);
}

const ServiceDescriptor* PyServiceDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyServiceDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a ServiceDescriptor");
    return NULL;
  }
  return reinterpret_cast<const ServiceDescriptor*>(
      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
}

namespace method_descriptor {

// Unchecked accessor to the C++ pointer.
static const MethodDescriptor* _GetDescriptor(
    PyBaseDescriptor *self) {
  return reinterpret_cast<const MethodDescriptor*>(self->descriptor);
}

static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->name());
}

static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
  return PyString_FromCppString(_GetDescriptor(self)->full_name());
}

static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
  return PyInt_FromLong(_GetDescriptor(self)->index());
}

static PyObject* GetContainingService(PyBaseDescriptor *self, void *closure) {
  const ServiceDescriptor* containing_service =
      _GetDescriptor(self)->service();
  return PyServiceDescriptor_FromDescriptor(containing_service);
}

static PyObject* GetInputType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* input_type = _GetDescriptor(self)->input_type();
  return PyMessageDescriptor_FromDescriptor(input_type);
}

static PyObject* GetOutputType(PyBaseDescriptor *self, void *closure) {
  const Descriptor* output_type = _GetDescriptor(self)->output_type();
  return PyMessageDescriptor_FromDescriptor(output_type);
}

static PyObject* GetOptions(PyBaseDescriptor *self) {
  return GetOrBuildOptions(_GetDescriptor(self));
}

static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
  return CopyToPythonProto<MethodDescriptorProto>(_GetDescriptor(self), target);
}

static PyGetSetDef Getters[] = {
  { "name", (getter)GetName, NULL, "Name", NULL},
  { "full_name", (getter)GetFullName, NULL, "Full name", NULL},
  { "index", (getter)GetIndex, NULL, "Index", NULL},
  { "containing_service", (getter)GetContainingService, NULL,
    "Containing service", NULL},
  { "input_type", (getter)GetInputType, NULL, "Input type", NULL},
  { "output_type", (getter)GetOutputType, NULL, "Output type", NULL},
  {NULL}
};

static PyMethodDef Methods[] = {
  { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
  { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
  {NULL}
};

}  // namespace method_descriptor

PyTypeObject PyMethodDescriptor_Type = {
  PyVarObject_HEAD_INIT(&PyType_Type, 0)
  FULL_MODULE_NAME ".MethodDescriptor",  // tp_name
  sizeof(PyBaseDescriptor),             // tp_basicsize
  0,                                    // tp_itemsize
  0,                                    // tp_dealloc
  0,                                    // tp_print
  0,                                    // tp_getattr
  0,                                    // tp_setattr
  0,                                    // tp_compare
  0,                                    // tp_repr
  0,                                    // tp_as_number
  0,                                    // tp_as_sequence
  0,                                    // tp_as_mapping
  0,                                    // tp_hash
  0,                                    // tp_call
  0,                                    // tp_str
  0,                                    // tp_getattro
  0,                                    // tp_setattro
  0,                                    // tp_as_buffer
  Py_TPFLAGS_DEFAULT,                   // tp_flags
  "A Method Descriptor",                // tp_doc
  0,                                    // tp_traverse
  0,                                    // tp_clear
  0,                                    // tp_richcompare
  0,                                    // tp_weaklistoffset
  0,                                    // tp_iter
  0,                                    // tp_iternext
  method_descriptor::Methods,           // tp_methods
  0,                                    // tp_members
  method_descriptor::Getters,           // tp_getset
  &descriptor::PyBaseDescriptor_Type,   // tp_base
};

PyObject* PyMethodDescriptor_FromDescriptor(
    const MethodDescriptor* method_descriptor) {
  return descriptor::NewInternedDescriptor(
      &PyMethodDescriptor_Type, method_descriptor, NULL);
}

const MethodDescriptor* PyMethodDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyMethodDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a MethodDescriptor");
    return NULL;
  }
  return reinterpret_cast<const MethodDescriptor*>(
      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
}

// Add a enum values to a type dictionary.
static bool AddEnumValues(PyTypeObject *type,
                          const EnumDescriptor* enum_descriptor) {
  for (int i = 0; i < enum_descriptor->value_count(); ++i) {
    const EnumValueDescriptor* value = enum_descriptor->value(i);
    ScopedPyObjectPtr obj(PyInt_FromLong(value->number()));
    if (obj == NULL) {
      return false;
    }
    if (PyDict_SetItemString(type->tp_dict, value->name().c_str(), obj.get()) <
        0) {
      return false;
    }
  }
  return true;
}

static bool AddIntConstant(PyTypeObject *type, const char* name, int value) {
  ScopedPyObjectPtr obj(PyInt_FromLong(value));
  if (PyDict_SetItemString(type->tp_dict, name, obj.get()) < 0) {
    return false;
  }
  return true;
}


bool InitDescriptor() {
  if (PyType_Ready(&PyMessageDescriptor_Type) < 0)
    return false;

  if (PyType_Ready(&PyFieldDescriptor_Type) < 0)
    return false;

  if (!AddEnumValues(&PyFieldDescriptor_Type,
                     FieldDescriptorProto::Label_descriptor())) {
    return false;
  }
  if (!AddEnumValues(&PyFieldDescriptor_Type,
                     FieldDescriptorProto::Type_descriptor())) {
    return false;
  }
#define ADD_FIELDDESC_CONSTANT(NAME) AddIntConstant( \
    &PyFieldDescriptor_Type, #NAME, FieldDescriptor::NAME)
  if (!ADD_FIELDDESC_CONSTANT(CPPTYPE_INT32) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_INT64) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT32) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT64) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_DOUBLE) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_FLOAT) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_BOOL) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_ENUM) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_STRING) ||
      !ADD_FIELDDESC_CONSTANT(CPPTYPE_MESSAGE)) {
    return false;
  }
#undef ADD_FIELDDESC_CONSTANT

  if (PyType_Ready(&PyEnumDescriptor_Type) < 0)
    return false;

  if (PyType_Ready(&PyEnumValueDescriptor_Type) < 0)
    return false;

  if (PyType_Ready(&PyFileDescriptor_Type) < 0)
    return false;

  if (PyType_Ready(&PyOneofDescriptor_Type) < 0)
    return false;

  if (PyType_Ready(&PyServiceDescriptor_Type) < 0)
    return false;

  if (PyType_Ready(&PyMethodDescriptor_Type) < 0)
    return false;

  if (!InitDescriptorMappingTypes())
    return false;

  // Initialize globals defined in this file.
  interned_descriptors = new std::unordered_map<const void*, PyObject*>;

  return true;
}

}  // namespace python
}  // namespace protobuf
}  // namespace google
