// 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 #include #include #include #include #include #include #include #include #include #include #define C(str) const_cast(str) #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) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \ PyBytes_AsStringAndSize(ob, (charpp), (sizep))) #endif namespace google { namespace protobuf { namespace python { 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) { PyThreadState *state = PyThreadState_GET(); if (state == NULL) { return false; } PyFrameObject* frame = state->frame; if (frame == NULL) { return false; } while (stacklevel-- > 0) { frame = frame->f_back; if (frame == NULL) { return false; } } if (frame->f_globals != frame->f_locals) { // Not at global module scope 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 < 7) { // filename is too short. return false; } if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) { // Filename is not ending with _pb2. return false; } 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. // 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 unkown fields, and we need to parse them again. // // Always returns a new reference. template static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { hash_map* descriptor_options = GetDescriptorPool()->descriptor_options; // First search in the cache. if (descriptor_options->find(descriptor) != descriptor_options->end()) { PyObject *value = (*descriptor_options)[descriptor]; Py_INCREF(value); return value; } // 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(); PyObject* message_class(cdescriptor_pool::GetMessageClass( GetDescriptorPool(), 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, NULL)); if (value == NULL) { return NULL; } CMessage* cmsg = reinterpret_cast(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 string serialized; options.SerializeToString(&serialized); io::CodedInputStream input( reinterpret_cast(serialized.c_str()), serialized.size()); input.SetExtensionRegistry(GetDescriptorPool()->pool, cmessage::GetMessageFactory()); bool success = cmsg->message->MergePartialFromCodedStream(&input); if (!success) { PyErr_Format(PyExc_ValueError, "Error parsing Options message"); return NULL; } } // Cache the result. Py_INCREF(value); (*GetDescriptorPool()->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 static PyObject* CopyToPythonProto(const DescriptorClass *descriptor, PyObject *target) { const Descriptor* self_descriptor = DescriptorProtoClass::default_instance().GetDescriptor(); CMessage* message = reinterpret_cast(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(message->message); descriptor->CopyTo(descriptor_message); 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; } 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. // Always return a new reference. PyObject* NewInternedDescriptor(PyTypeObject* type, const void* descriptor) { if (descriptor == NULL) { PyErr_BadInternalCall(); return NULL; } // See if the object is in the map of interned descriptors hash_map::iterator it = GetDescriptorPool()->interned_descriptors->find(descriptor); if (it != GetDescriptorPool()->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_New( PyBaseDescriptor, type); if (py_descriptor == NULL) { return NULL; } py_descriptor->descriptor = descriptor; // and cache it. GetDescriptorPool()->interned_descriptors->insert( std::make_pair(descriptor, reinterpret_cast(py_descriptor))); return reinterpret_cast(py_descriptor); } static void Dealloc(PyBaseDescriptor* self) { // Remove from interned dictionary GetDescriptorPool()->interned_descriptors->erase(self->descriptor); Py_TYPE(self)->tp_free(reinterpret_cast(self)); } static PyGetSetDef Getters[] = { {NULL} }; PyTypeObject PyBaseDescriptor_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) // Keep the fully qualified _message symbol in a line for opensource. "google.protobuf.internal._message." "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, // tp_flags "Descriptors base class", // tp_doc 0, // tp_traverse 0, // 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(obj)->descriptor; } namespace message_descriptor { // Unchecked accessor to the C++ pointer. static const Descriptor* _GetDescriptor(PyBaseDescriptor* self) { return reinterpret_cast(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_New(_GetDescriptor(self)->file()); } static PyObject* GetConcreteClass(PyBaseDescriptor* self, void *closure) { PyObject* concrete_class(cdescriptor_pool::GetMessageClass( GetDescriptorPool(), _GetDescriptor(self))); Py_XINCREF(concrete_class); return concrete_class; } static int SetConcreteClass(PyBaseDescriptor *self, PyObject *value, void *closure) { // This attribute is also set from reflection.py. Check that it's actually a // no-op. if (value != cdescriptor_pool::GetMessageClass( GetDescriptorPool(), _GetDescriptor(self))) { PyErr_SetString(PyExc_AttributeError, "Cannot change _concrete_class"); } return 0; } static PyObject* GetFieldsByName(PyBaseDescriptor* self, void *closure) { return NewMessageFieldsByName(_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_New(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 PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { return CopyToPythonProto(_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[] = { { C("name"), (getter)GetName, NULL, "Last name", NULL}, { C("full_name"), (getter)GetFullName, NULL, "Full name", NULL}, { C("_concrete_class"), (getter)GetConcreteClass, (setter)SetConcreteClass, "concrete class", NULL}, { C("file"), (getter)GetFile, NULL, "File descriptor", NULL}, { C("fields"), (getter)GetFieldsSeq, NULL, "Fields sequence", NULL}, { C("fields_by_name"), (getter)GetFieldsByName, NULL, "Fields by name", NULL}, { C("fields_by_number"), (getter)GetFieldsByNumber, NULL, "Fields by number", NULL}, { C("nested_types"), (getter)GetNestedTypesSeq, NULL, "Nested types sequence", NULL}, { C("nested_types_by_name"), (getter)GetNestedTypesByName, NULL, "Nested types by name", NULL}, { C("extensions"), (getter)GetExtensions, NULL, "Extensions Sequence", NULL}, { C("extensions_by_name"), (getter)GetExtensionsByName, NULL, "Extensions by name", NULL}, { C("extension_ranges"), (getter)GetExtensionRanges, NULL, "Extension ranges", NULL}, { C("enum_types"), (getter)GetEnumsSeq, NULL, "Enum sequence", NULL}, { C("enum_types_by_name"), (getter)GetEnumTypesByName, NULL, "Enum types by name", NULL}, { C("enum_values_by_name"), (getter)GetEnumValuesByName, NULL, "Enum values by name", NULL}, { C("oneofs_by_name"), (getter)GetOneofsByName, NULL, "Oneofs by name", NULL}, { C("oneofs"), (getter)GetOneofsSeq, NULL, "Oneofs by name", NULL}, { C("containing_type"), (getter)GetContainingType, (setter)SetContainingType, "Containing type", NULL}, { C("is_extendable"), (getter)IsExtendable, (setter)NULL, NULL, NULL}, { C("has_options"), (getter)GetHasOptions, (setter)SetHasOptions, "Has Options", NULL}, { C("_options"), (getter)NULL, (setter)SetOptions, "Options", NULL}, { C("syntax"), (getter)GetSyntax, (setter)NULL, "Syntax", NULL}, {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) // Keep the fully qualified _message symbol in a line for opensource. C("google.protobuf.internal._message." "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 C("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_New( const Descriptor* message_descriptor) { return descriptor::NewInternedDescriptor( &PyMessageDescriptor_Type, message_descriptor); } const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyMessageDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a MessageDescriptor"); return NULL; } return reinterpret_cast( reinterpret_cast(obj)->descriptor); } namespace field_descriptor { // Unchecked accessor to the C++ pointer. static const FieldDescriptor* _GetDescriptor( PyBaseDescriptor *self) { return reinterpret_cast(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* 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; 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: { 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; } 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_New(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_New(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_New(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_New(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_New(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 PyGetSetDef Getters[] = { { C("full_name"), (getter)GetFullName, NULL, "Full name", NULL}, { C("name"), (getter)GetName, NULL, "Unqualified name", NULL}, { C("type"), (getter)GetType, NULL, "C++ Type", NULL}, { C("cpp_type"), (getter)GetCppType, NULL, "C++ Type", NULL}, { C("label"), (getter)GetLabel, NULL, "Label", NULL}, { C("number"), (getter)GetNumber, NULL, "Number", NULL}, { C("index"), (getter)GetIndex, NULL, "Index", NULL}, { C("default_value"), (getter)GetDefaultValue, NULL, "Default Value", NULL}, { C("has_default_value"), (getter)HasDefaultValue, NULL, NULL, NULL}, { C("is_extension"), (getter)IsExtension, NULL, "ID", NULL}, { C("id"), (getter)GetID, NULL, "ID", NULL}, { C("_cdescriptor"), (getter)GetCDescriptor, NULL, "HAACK REMOVE ME", NULL}, { C("message_type"), (getter)GetMessageType, (setter)SetMessageType, "Message type", NULL}, { C("enum_type"), (getter)GetEnumType, (setter)SetEnumType, "Enum type", NULL}, { C("containing_type"), (getter)GetContainingType, (setter)SetContainingType, "Containing type", NULL}, { C("extension_scope"), (getter)GetExtensionScope, (setter)NULL, "Extension scope", NULL}, { C("containing_oneof"), (getter)GetContainingOneof, (setter)SetContainingOneof, "Containing oneof", NULL}, { C("has_options"), (getter)GetHasOptions, (setter)SetHasOptions, "Has Options", NULL}, { C("_options"), (getter)NULL, (setter)SetOptions, "Options", NULL}, {NULL} }; static PyMethodDef Methods[] = { { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, {NULL} }; } // namespace field_descriptor PyTypeObject PyFieldDescriptor_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) C("google.protobuf.internal." "_message.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 C("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_New( const FieldDescriptor* field_descriptor) { return descriptor::NewInternedDescriptor( &PyFieldDescriptor_Type, field_descriptor); } const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyFieldDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a FieldDescriptor"); return NULL; } return reinterpret_cast( reinterpret_cast(obj)->descriptor); } namespace enum_descriptor { // Unchecked accessor to the C++ pointer. static const EnumDescriptor* _GetDescriptor( PyBaseDescriptor *self) { return reinterpret_cast(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_New(_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_New(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 PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { return CopyToPythonProto(_GetDescriptor(self), target); } static PyMethodDef Methods[] = { { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, {NULL} }; static PyGetSetDef Getters[] = { { C("full_name"), (getter)GetFullName, NULL, "Full name", NULL}, { C("name"), (getter)GetName, NULL, "last name", NULL}, { C("file"), (getter)GetFile, NULL, "File descriptor", NULL}, { C("values"), (getter)GetEnumvaluesSeq, NULL, "values", NULL}, { C("values_by_name"), (getter)GetEnumvaluesByName, NULL, "Enumvalues by name", NULL}, { C("values_by_number"), (getter)GetEnumvaluesByNumber, NULL, "Enumvalues by number", NULL}, { C("containing_type"), (getter)GetContainingType, (setter)SetContainingType, "Containing type", NULL}, { C("has_options"), (getter)GetHasOptions, (setter)SetHasOptions, "Has Options", NULL}, { C("_options"), (getter)NULL, (setter)SetOptions, "Options", NULL}, {NULL} }; } // namespace enum_descriptor PyTypeObject PyEnumDescriptor_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) // Keep the fully qualified _message symbol in a line for opensource. C("google.protobuf.internal._message." "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 C("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_getset 0, // tp_members enum_descriptor::Getters, // tp_getset &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyEnumDescriptor_New( const EnumDescriptor* enum_descriptor) { return descriptor::NewInternedDescriptor( &PyEnumDescriptor_Type, enum_descriptor); } namespace enumvalue_descriptor { // Unchecked accessor to the C++ pointer. static const EnumValueDescriptor* _GetDescriptor( PyBaseDescriptor *self) { return reinterpret_cast(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_New(_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 PyGetSetDef Getters[] = { { C("name"), (getter)GetName, NULL, "name", NULL}, { C("number"), (getter)GetNumber, NULL, "number", NULL}, { C("index"), (getter)GetIndex, NULL, "index", NULL}, { C("type"), (getter)GetType, NULL, "index", NULL}, { C("has_options"), (getter)GetHasOptions, (setter)SetHasOptions, "Has Options", NULL}, { C("_options"), (getter)NULL, (setter)SetOptions, "Options", NULL}, {NULL} }; static PyMethodDef Methods[] = { { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, {NULL} }; } // namespace enumvalue_descriptor PyTypeObject PyEnumValueDescriptor_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) C("google.protobuf.internal." "_message.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 C("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_New( const EnumValueDescriptor* enumvalue_descriptor) { return descriptor::NewInternedDescriptor( &PyEnumValueDescriptor_Type, enumvalue_descriptor); } namespace file_descriptor { // Unchecked accessor to the C++ pointer. static const FileDescriptor* _GetDescriptor(PyFileDescriptor *self) { return reinterpret_cast(self->base.descriptor); } static void Dealloc(PyFileDescriptor* self) { Py_XDECREF(self->serialized_pb); descriptor::Dealloc(&self->base); } 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* 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 PyObject* GetSyntax(PyFileDescriptor *self, void *closure) { return PyString_InternFromString( FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax())); } static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) { return CopyToPythonProto(_GetDescriptor(self), target); } static PyGetSetDef Getters[] = { { C("name"), (getter)GetName, NULL, "name", NULL}, { C("package"), (getter)GetPackage, NULL, "package", NULL}, { C("serialized_pb"), (getter)GetSerializedPb, NULL, NULL, NULL}, { C("message_types_by_name"), (getter)GetMessageTypesByName, NULL, "Messages by name", NULL}, { C("enum_types_by_name"), (getter)GetEnumTypesByName, NULL, "Enums by name", NULL}, { C("extensions_by_name"), (getter)GetExtensionsByName, NULL, "Extensions by name", NULL}, { C("dependencies"), (getter)GetDependencies, NULL, "Dependencies", NULL}, { C("public_dependencies"), (getter)GetPublicDependencies, NULL, "Dependencies", NULL}, { C("has_options"), (getter)GetHasOptions, (setter)SetHasOptions, "Has Options", NULL}, { C("_options"), (getter)NULL, (setter)SetOptions, "Options", NULL}, { C("syntax"), (getter)GetSyntax, (setter)NULL, "Syntax", NULL}, {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) C("google.protobuf.internal." "_message.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 C("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 PyType_GenericAlloc, // tp_alloc PyType_GenericNew, // tp_new PyObject_Del, // tp_free }; PyObject* PyFileDescriptor_New(const FileDescriptor* file_descriptor) { return descriptor::NewInternedDescriptor( &PyFileDescriptor_Type, file_descriptor); } PyObject* PyFileDescriptor_NewWithPb( const FileDescriptor* file_descriptor, PyObject *serialized_pb) { PyObject* py_descriptor = PyFileDescriptor_New(file_descriptor); if (py_descriptor == NULL) { return NULL; } if (serialized_pb != NULL) { PyFileDescriptor* cfile_descriptor = reinterpret_cast(py_descriptor); Py_XINCREF(serialized_pb); cfile_descriptor->serialized_pb = serialized_pb; } return py_descriptor; } namespace oneof_descriptor { // Unchecked accessor to the C++ pointer. static const OneofDescriptor* _GetDescriptor( PyBaseDescriptor *self) { return reinterpret_cast(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_New(containing_type); } else { Py_RETURN_NONE; } } static PyGetSetDef Getters[] = { { C("name"), (getter)GetName, NULL, "Name", NULL}, { C("full_name"), (getter)GetFullName, NULL, "Full name", NULL}, { C("index"), (getter)GetIndex, NULL, "Index", NULL}, { C("containing_type"), (getter)GetContainingType, NULL, "Containing type", NULL}, { C("fields"), (getter)GetFields, NULL, "Fields", NULL}, {NULL} }; } // namespace oneof_descriptor PyTypeObject PyOneofDescriptor_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) C("google.protobuf.internal." "_message.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 C("A Oneof Descriptor"), // tp_doc 0, // tp_traverse 0, // tp_clear 0, // tp_richcompare 0, // tp_weaklistoffset 0, // tp_iter 0, // tp_iternext 0, // tp_methods 0, // tp_members oneof_descriptor::Getters, // tp_getset &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyOneofDescriptor_New( const OneofDescriptor* oneof_descriptor) { return descriptor::NewInternedDescriptor( &PyOneofDescriptor_Type, oneof_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) < 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) < 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 (!InitDescriptorMappingTypes()) return false; return true; } } // namespace python } // namespace protobuf } // namespace google