// 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 "google/protobuf/pyext/descriptor.h"

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <frameobject.h>

#include <cstdint>
#include <string>
#include <unordered_map>

#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/dynamic_message.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 "absl/strings/string_view.h"
#include "google/protobuf/io/coded_stream.h"

#define PyString_AsStringAndSize(ob, charpp, sizep)              \
  (PyUnicode_Check(ob)                                           \
       ? ((*(charpp) = const_cast<char*>(                        \
               PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \
              ? -1                                               \
              : 0)                                               \
       : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))

#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
static PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
{
    Py_INCREF(frame->f_code);
    return frame->f_code;
}

static PyFrameObject* PyFrame_GetBack(PyFrameObject *frame)
{
    Py_XINCREF(frame->f_back);
    return frame->f_back;
}
#endif

#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION)
static PyObject* PyFrame_GetLocals(PyFrameObject *frame)
{
    if (PyFrame_FastToLocalsWithError(frame) < 0) {
        return NULL;
    }
    Py_INCREF(frame->f_locals);
    return frame->f_locals;
}

static PyObject* PyFrame_GetGlobals(PyFrameObject *frame)
{
    Py_INCREF(frame->f_globals);
    return frame->f_globals;
}
#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 std::string& str) {
  return PyUnicode_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();
  PyCodeObject* frame_code = nullptr;
  PyObject* frame_globals = nullptr;
  PyObject* frame_locals = nullptr;
  bool result = false;

  if (frame == nullptr) {
    goto exit;
  }
  Py_INCREF(frame);
  while (stacklevel-- > 0) {
    PyFrameObject* next_frame = PyFrame_GetBack(frame);
    Py_DECREF(frame);
    frame = next_frame;
    if (frame == nullptr) {
      goto exit;
    }
  }

  frame_code = PyFrame_GetCode(frame);
  if (frame_code->co_filename == nullptr) {
    goto exit;
  }
  char* filename;
  Py_ssize_t filename_size;
  if (PyString_AsStringAndSize(frame_code->co_filename,
                               &filename, &filename_size) < 0) {
    // filename is not a string.
    PyErr_Clear();
    goto exit;
  }
  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.
    result = true;
    goto exit;
  }
  if (filename_size < 7) {
    // filename is too short.
    goto exit;
  }
  if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) {
    // Filename is not ending with _pb2.
    goto exit;
  }

  frame_globals = PyFrame_GetGlobals(frame);
  frame_locals = PyFrame_GetLocals(frame);
  if (frame_globals != frame_locals) {
    // Not at global module scope
    goto exit;
  }
#endif
  result = true;
exit:
  Py_XDECREF(frame_globals);
  Py_XDECREF(frame_locals);
  Py_XDECREF(frame_code);
  Py_XDECREF(frame);
  return result;
}

// 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.
  std::string serialized;
  from.SerializeToString(&serialized);
  io::CodedInputStream input(
      reinterpret_cast<const uint8_t*>(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 == nullptr) {
    PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s",
                 message_type->full_name().c_str());
    return nullptr;
  }
  ScopedPyObjectPtr args(PyTuple_New(0));
  ScopedPyObjectPtr value(
      PyObject_Call(message_class->AsPyObject(), args.get(), nullptr));
  Py_DECREF(message_class);
  if (value == nullptr) {
    return nullptr;
  }
  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 nullptr;
  }
  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 nullptr;
    }
  }

  // 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 nullptr;
  }
  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 == nullptr) {
    PyErr_BadInternalCall();
    return nullptr;
  }

  // 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 == nullptr) {
    return nullptr;
  }
  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 == nullptr) {
    // Don't DECREF, the object is not fully initialized.
    PyObject_Del(py_descriptor);
    return nullptr;
  }
  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(PyObject* pself) {
  PyBaseDescriptor* self = reinterpret_cast<PyBaseDescriptor*>(pself);
  // Remove from interned dictionary
  interned_descriptors->erase(self->descriptor);
  Py_CLEAR(self->pool);
  Py_TYPE(self)->tp_free(pself);
}

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[] = {
    {nullptr},
};

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
#if PY_VERSION_HEX < 0x03080000
    nullptr,  // tp_print
#else
    0,  // tp_vectorcall_offset
#endif
    nullptr,                                  // tp_getattr
    nullptr,                                  // tp_setattr
    nullptr,                                  // tp_compare
    nullptr,                                  // tp_repr
    nullptr,                                  // tp_as_number
    nullptr,                                  // tp_as_sequence
    nullptr,                                  // tp_as_mapping
    nullptr,                                  // tp_hash
    nullptr,                                  // tp_call
    nullptr,                                  // tp_str
    nullptr,                                  // tp_getattro
    nullptr,                                  // tp_setattro
    nullptr,                                  // tp_as_buffer
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,  // tp_flags
    "Descriptors base class",                 // tp_doc
    GcTraverse,                               // tp_traverse
    GcClear,                                  // tp_clear
    nullptr,                                  // tp_richcompare
    0,                                        // tp_weaklistoffset
    nullptr,                                  // tp_iter
    nullptr,                                  // tp_iternext
    nullptr,                                  // tp_methods
    nullptr,                                  // 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 nullptr;
  }
  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) {
  // Returns 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)));

  if (concrete_class == nullptr) {
    PyErr_Clear();
    return nullptr;
  }

  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 = PyLong_FromLong(range->start);
    PyObject* end = PyLong_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 nullptr;
  const EnumDescriptor *enum_type =
      _GetDescriptor(self)->FindEnumTypeByName(enum_name);
  if (enum_type == nullptr) {
    PyErr_SetString(PyExc_KeyError, enum_name);
    return nullptr;
  }
  const EnumValueDescriptor *enum_value =
      enum_type->FindValueByNumber(number);
  if (enum_value == nullptr) {
    PyErr_Format(PyExc_KeyError, "%d", number);
    return nullptr;
  }
  return PyString_FromCppString(enum_value->name());
}

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

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

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

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

}  // 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
    nullptr,                   // tp_dealloc
#if PY_VERSION_HEX < 0x03080000
    nullptr,  // tp_print
#else
    0,  // tp_vectorcall_offset
#endif
    nullptr,                             // tp_getattr
    nullptr,                             // tp_setattr
    nullptr,                             // tp_compare
    nullptr,                             // tp_repr
    nullptr,                             // tp_as_number
    nullptr,                             // tp_as_sequence
    nullptr,                             // tp_as_mapping
    nullptr,                             // tp_hash
    nullptr,                             // tp_call
    nullptr,                             // tp_str
    nullptr,                             // tp_getattro
    nullptr,                             // tp_setattro
    nullptr,                             // tp_as_buffer
    Py_TPFLAGS_DEFAULT,                  // tp_flags
    "A Message Descriptor",              // tp_doc
    nullptr,                             // tp_traverse
    nullptr,                             // tp_clear
    nullptr,                             // tp_richcompare
    0,                                   // tp_weaklistoffset
    nullptr,                             // tp_iter
    nullptr,                             // tp_iternext
    message_descriptor::Methods,         // tp_methods
    nullptr,                             // 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, nullptr);
}

const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyMessageDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a MessageDescriptor");
    return nullptr;
  }
  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 PyLong_FromLong(_GetDescriptor(self)->type());
}

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

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

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

static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
  return PyLong_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_t value = _GetDescriptor(self)->default_value_int32();
      result = PyLong_FromLong(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_INT64: {
      int64_t value = _GetDescriptor(self)->default_value_int64();
      result = PyLong_FromLongLong(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_UINT32: {
      uint32_t value = _GetDescriptor(self)->default_value_uint32();
      result = PyLong_FromSsize_t(value);
      break;
    }
    case FieldDescriptor::CPPTYPE_UINT64: {
      uint64_t 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 std::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 = PyLong_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 nullptr;
  }
  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 auto* desc = _GetDescriptor(self);
  const Descriptor* extension_scope =
      desc->is_extension() ? desc->extension_scope() : nullptr;
  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* GetHasPresence(PyBaseDescriptor* self, void* closure) {
  if (_GetDescriptor(self)->has_presence()) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}

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, nullptr, "Full name"},
    {"name", (getter)GetName, nullptr, "Unqualified name"},
    {"camelcase_name", (getter)GetCamelcaseName, nullptr, "Camelcase name"},
    {"json_name", (getter)GetJsonName, nullptr, "Json name"},
    {"file", (getter)GetFile, nullptr, "File Descriptor"},
    {"type", (getter)GetType, nullptr, "C++ Type"},
    {"cpp_type", (getter)GetCppType, nullptr, "C++ Type"},
    {"label", (getter)GetLabel, nullptr, "Label"},
    {"number", (getter)GetNumber, nullptr, "Number"},
    {"index", (getter)GetIndex, nullptr, "Index"},
    {"default_value", (getter)GetDefaultValue, nullptr, "Default Value"},
    {"has_default_value", (getter)HasDefaultValue},
    {"is_extension", (getter)IsExtension, nullptr, "ID"},
    {"id", (getter)GetID, nullptr, "ID"},
    {"_cdescriptor", (getter)GetCDescriptor, nullptr, "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) nullptr,
     "Extension scope"},
    {"containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof,
     "Containing oneof"},
    {"has_options", (getter)GetHasOptions, (setter)SetHasOptions,
     "Has Options"},
    {"has_presence", (getter)GetHasPresence, (setter) nullptr, "Has Presence"},
    {"_options", (getter) nullptr, (setter)SetOptions, "Options"},
    {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
     "Serialized Options"},
    {nullptr},
};

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

}  // 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
    nullptr,                   // tp_dealloc
#if PY_VERSION_HEX < 0x03080000
    nullptr,  // tp_print
#else
    0,  // tp_vectorcall_offset
#endif
    nullptr,                             // tp_getattr
    nullptr,                             // tp_setattr
    nullptr,                             // tp_compare
    nullptr,                             // tp_repr
    nullptr,                             // tp_as_number
    nullptr,                             // tp_as_sequence
    nullptr,                             // tp_as_mapping
    nullptr,                             // tp_hash
    nullptr,                             // tp_call
    nullptr,                             // tp_str
    nullptr,                             // tp_getattro
    nullptr,                             // tp_setattro
    nullptr,                             // tp_as_buffer
    Py_TPFLAGS_DEFAULT,                  // tp_flags
    "A Field Descriptor",                // tp_doc
    nullptr,                             // tp_traverse
    nullptr,                             // tp_clear
    nullptr,                             // tp_richcompare
    0,                                   // tp_weaklistoffset
    nullptr,                             // tp_iter
    nullptr,                             // tp_iternext
    field_descriptor::Methods,           // tp_methods
    nullptr,                             // 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, nullptr);
}

const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyFieldDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a FieldDescriptor");
    return nullptr;
  }
  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 PyObject* GetIsClosed(PyBaseDescriptor* self, void* closure) {
  return PyBool_FromLong(_GetDescriptor(self)->is_closed());
}

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},
    {nullptr},
};

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

    {"containing_type", (getter)GetContainingType, (setter)SetContainingType,
     "Containing type"},
    {"has_options", (getter)GetHasOptions, (setter)SetHasOptions,
     "Has Options"},
    {"is_closed", (getter)GetIsClosed, nullptr, "If the enum is closed"},
    {"_options", (getter) nullptr, (setter)SetOptions, "Options"},
    {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
     "Serialized Options"},
    {nullptr},
};

}  // 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
    nullptr,                   // tp_dealloc
#if PY_VERSION_HEX < 0x03080000
    nullptr,  // tp_print
#else
    0,  // tp_vectorcall_offset
#endif
    nullptr,                             // tp_getattr
    nullptr,                             // tp_setattr
    nullptr,                             // tp_compare
    nullptr,                             // tp_repr
    nullptr,                             // tp_as_number
    nullptr,                             // tp_as_sequence
    nullptr,                             // tp_as_mapping
    nullptr,                             // tp_hash
    nullptr,                             // tp_call
    nullptr,                             // tp_str
    nullptr,                             // tp_getattro
    nullptr,                             // tp_setattro
    nullptr,                             // tp_as_buffer
    Py_TPFLAGS_DEFAULT,                  // tp_flags
    "A Enum Descriptor",                 // tp_doc
    nullptr,                             // tp_traverse
    nullptr,                             // tp_clear
    nullptr,                             // tp_richcompare
    0,                                   // tp_weaklistoffset
    nullptr,                             // tp_iter
    nullptr,                             // tp_iternext
    enum_descriptor::Methods,            // tp_methods
    nullptr,                             // 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, nullptr);
}

const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyEnumDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not an EnumDescriptor");
    return nullptr;
  }
  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 PyLong_FromLong(_GetDescriptor(self)->number());
}

static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
  return PyLong_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, nullptr, "name"},
    {"number", (getter)GetNumber, nullptr, "number"},
    {"index", (getter)GetIndex, nullptr, "index"},
    {"type", (getter)GetType, nullptr, "index"},

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

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

}  // 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
    nullptr,                   // tp_dealloc
#if PY_VERSION_HEX < 0x03080000
    nullptr,  // tp_print
#else
    0,  // tp_vectorcall_offset
#endif
    nullptr,                             // tp_getattr
    nullptr,                             // tp_setattr
    nullptr,                             // tp_compare
    nullptr,                             // tp_repr
    nullptr,                             // tp_as_number
    nullptr,                             // tp_as_sequence
    nullptr,                             // tp_as_mapping
    nullptr,                             // tp_hash
    nullptr,                             // tp_call
    nullptr,                             // tp_str
    nullptr,                             // tp_getattro
    nullptr,                             // tp_setattro
    nullptr,                             // tp_as_buffer
    Py_TPFLAGS_DEFAULT,                  // tp_flags
    "A EnumValue Descriptor",            // tp_doc
    nullptr,                             // tp_traverse
    nullptr,                             // tp_clear
    nullptr,                             // tp_richcompare
    0,                                   // tp_weaklistoffset
    nullptr,                             // tp_iter
    nullptr,                             // tp_iternext
    enumvalue_descriptor::Methods,       // tp_methods
    nullptr,                             // 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, nullptr);
}

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(reinterpret_cast<PyObject*>(self));
}

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 != nullptr) {
    Py_INCREF(serialized_pb);
    return serialized_pb;
  }
  FileDescriptorProto file_proto;
  _GetDescriptor(self)->CopyTo(&file_proto);
  std::string contents;
  file_proto.SerializePartialToString(&contents);
  self->serialized_pb = PyBytes_FromStringAndSize(
      contents.c_str(), contents.size());
  if (self->serialized_pb == nullptr) {
    return nullptr;
  }
  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* GetDebugString(PyFileDescriptor* self) {
  return PyString_FromCppString(_GetDescriptor(self)->DebugString());
}

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 PyUnicode_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, nullptr, "pool"},
    {"name", (getter)GetName, nullptr, "name"},
    {"package", (getter)GetPackage, nullptr, "package"},
    {"serialized_pb", (getter)GetSerializedPb},
    {"message_types_by_name", (getter)GetMessageTypesByName, nullptr,
     "Messages by name"},
    {"enum_types_by_name", (getter)GetEnumTypesByName, nullptr,
     "Enums by name"},
    {"extensions_by_name", (getter)GetExtensionsByName, nullptr,
     "Extensions by name"},
    {"services_by_name", (getter)GetServicesByName, nullptr,
     "Services by name"},
    {"dependencies", (getter)GetDependencies, nullptr, "Dependencies"},
    {"public_dependencies", (getter)GetPublicDependencies, nullptr,
     "Dependencies"},

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

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

}  // 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
#if PY_VERSION_HEX < 0x03080000
    nullptr,  // tp_print
#else
    0,  // tp_vectorcall_offset
#endif
    nullptr,                             // tp_getattr
    nullptr,                             // tp_setattr
    nullptr,                             // tp_compare
    nullptr,                             // tp_repr
    nullptr,                             // tp_as_number
    nullptr,                             // tp_as_sequence
    nullptr,                             // tp_as_mapping
    nullptr,                             // tp_hash
    nullptr,                             // tp_call
    nullptr,                             // tp_str
    nullptr,                             // tp_getattro
    nullptr,                             // tp_setattro
    nullptr,                             // tp_as_buffer
    Py_TPFLAGS_DEFAULT,                  // tp_flags
    "A File Descriptor",                 // tp_doc
    nullptr,                             // tp_traverse
    nullptr,                             // tp_clear
    nullptr,                             // tp_richcompare
    0,                                   // tp_weaklistoffset
    nullptr,                             // tp_iter
    nullptr,                             // tp_iternext
    file_descriptor::Methods,            // tp_methods
    nullptr,                             // tp_members
    file_descriptor::Getters,            // tp_getset
    &descriptor::PyBaseDescriptor_Type,  // tp_base
    nullptr,                             // tp_dict
    nullptr,                             // tp_descr_get
    nullptr,                             // tp_descr_set
    0,                                   // tp_dictoffset
    nullptr,                             // tp_init
    nullptr,                             // tp_alloc
    nullptr,                             // tp_new
    PyObject_GC_Del,                     // tp_free
};

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

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 == nullptr) {
    return nullptr;
  }
  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 nullptr;
  }
  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 PyLong_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, nullptr, "Name"},
    {"full_name", (getter)GetFullName, nullptr, "Full name"},
    {"index", (getter)GetIndex, nullptr, "Index"},

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

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

}  // 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
    nullptr,                   // tp_dealloc
#if PY_VERSION_HEX < 0x03080000
    nullptr,  // tp_print
#else
    0,  // tp_vectorcall_offset
#endif
    nullptr,                             // tp_getattr
    nullptr,                             // tp_setattr
    nullptr,                             // tp_compare
    nullptr,                             // tp_repr
    nullptr,                             // tp_as_number
    nullptr,                             // tp_as_sequence
    nullptr,                             // tp_as_mapping
    nullptr,                             // tp_hash
    nullptr,                             // tp_call
    nullptr,                             // tp_str
    nullptr,                             // tp_getattro
    nullptr,                             // tp_setattro
    nullptr,                             // tp_as_buffer
    Py_TPFLAGS_DEFAULT,                  // tp_flags
    "A Oneof Descriptor",                // tp_doc
    nullptr,                             // tp_traverse
    nullptr,                             // tp_clear
    nullptr,                             // tp_richcompare
    0,                                   // tp_weaklistoffset
    nullptr,                             // tp_iter
    nullptr,                             // tp_iternext
    oneof_descriptor::Methods,           // tp_methods
    nullptr,                             // 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, nullptr);
}

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 PyLong_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 nullptr;
  }

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

  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, nullptr, "Name", nullptr},
    {"full_name", (getter)GetFullName, nullptr, "Full name", nullptr},
    {"file", (getter)GetFile, nullptr, "File descriptor"},
    {"index", (getter)GetIndex, nullptr, "Index", nullptr},
    {"methods", (getter)GetMethods, nullptr, "Methods", nullptr},
    {"methods_by_name", (getter)GetMethodsByName, nullptr, "Methods by name",
     nullptr},
    {nullptr},
};

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

}  // 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
    nullptr,                   // tp_dealloc
#if PY_VERSION_HEX < 0x03080000
    nullptr,  // tp_print
#else
    0,  // tp_vectorcall_offset
#endif
    nullptr,                             // tp_getattr
    nullptr,                             // tp_setattr
    nullptr,                             // tp_compare
    nullptr,                             // tp_repr
    nullptr,                             // tp_as_number
    nullptr,                             // tp_as_sequence
    nullptr,                             // tp_as_mapping
    nullptr,                             // tp_hash
    nullptr,                             // tp_call
    nullptr,                             // tp_str
    nullptr,                             // tp_getattro
    nullptr,                             // tp_setattro
    nullptr,                             // tp_as_buffer
    Py_TPFLAGS_DEFAULT,                  // tp_flags
    "A Service Descriptor",              // tp_doc
    nullptr,                             // tp_traverse
    nullptr,                             // tp_clear
    nullptr,                             // tp_richcompare
    0,                                   // tp_weaklistoffset
    nullptr,                             // tp_iter
    nullptr,                             // tp_iternext
    service_descriptor::Methods,         // tp_methods
    nullptr,                             // 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, nullptr);
}

const ServiceDescriptor* PyServiceDescriptor_AsDescriptor(PyObject* obj) {
  if (!PyObject_TypeCheck(obj, &PyServiceDescriptor_Type)) {
    PyErr_SetString(PyExc_TypeError, "Not a ServiceDescriptor");
    return nullptr;
  }
  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 PyLong_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* GetClientStreaming(PyBaseDescriptor* self, void* closure) {
  return PyBool_FromLong(_GetDescriptor(self)->client_streaming() ? 1 : 0);
}

static PyObject* GetServerStreaming(PyBaseDescriptor* self, void* closure) {
  return PyBool_FromLong(_GetDescriptor(self)->server_streaming() ? 1 : 0);
}

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, nullptr, "Name", nullptr},
    {"full_name", (getter)GetFullName, nullptr, "Full name", nullptr},
    {"index", (getter)GetIndex, nullptr, "Index", nullptr},
    {"containing_service", (getter)GetContainingService, nullptr,
     "Containing service", nullptr},
    {"input_type", (getter)GetInputType, nullptr, "Input type", nullptr},
    {"output_type", (getter)GetOutputType, nullptr, "Output type", nullptr},
    {"client_streaming", (getter)GetClientStreaming, nullptr,
     "Client streaming", nullptr},
    {"server_streaming", (getter)GetServerStreaming, nullptr,
     "Server streaming", nullptr},
    {nullptr},
};

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

}  // 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
    nullptr,                   // tp_dealloc
#if PY_VERSION_HEX < 0x03080000
    nullptr,  // tp_print
#else
    0,  // tp_vectorcall_offset
#endif
    nullptr,                             // tp_getattr
    nullptr,                             // tp_setattr
    nullptr,                             // tp_compare
    nullptr,                             // tp_repr
    nullptr,                             // tp_as_number
    nullptr,                             // tp_as_sequence
    nullptr,                             // tp_as_mapping
    nullptr,                             // tp_hash
    nullptr,                             // tp_call
    nullptr,                             // tp_str
    nullptr,                             // tp_getattro
    nullptr,                             // tp_setattro
    nullptr,                             // tp_as_buffer
    Py_TPFLAGS_DEFAULT,                  // tp_flags
    "A Method Descriptor",               // tp_doc
    nullptr,                             // tp_traverse
    nullptr,                             // tp_clear
    nullptr,                             // tp_richcompare
    0,                                   // tp_weaklistoffset
    nullptr,                             // tp_iter
    nullptr,                             // tp_iternext
    method_descriptor::Methods,          // tp_methods
    nullptr,                             // 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, nullptr);
}

// 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(PyLong_FromLong(value->number()));
    if (obj == nullptr) {
      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(PyLong_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
