diff options
Diffstat (limited to 'python/google/protobuf/pyext/descriptor_pool.cc')
-rw-r--r-- | python/google/protobuf/pyext/descriptor_pool.cc | 185 |
1 files changed, 111 insertions, 74 deletions
diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc index bc3077bc..ecd90847 100644 --- a/python/google/protobuf/pyext/descriptor_pool.cc +++ b/python/google/protobuf/pyext/descriptor_pool.cc @@ -35,10 +35,9 @@ #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/pyext/descriptor_pool.h> #include <google/protobuf/pyext/descriptor.h> +#include <google/protobuf/pyext/message.h> #include <google/protobuf/pyext/scoped_pyobject_ptr.h> -#define C(str) const_cast<char*>(str) - #if PY_MAJOR_VERSION >= 3 #define PyString_FromStringAndSize PyUnicode_FromStringAndSize #if PY_VERSION_HEX < 0x03030000 @@ -108,11 +107,11 @@ PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* arg) { self->pool->FindMessageTypeByName(string(name, name_size)); if (message_descriptor == NULL) { - PyErr_Format(PyExc_TypeError, "Couldn't find message %.200s", name); + PyErr_Format(PyExc_KeyError, "Couldn't find message %.200s", name); return NULL; } - return PyMessageDescriptor_New(message_descriptor); + return PyMessageDescriptor_FromDescriptor(message_descriptor); } // Add a message class to our database. @@ -158,6 +157,24 @@ PyObject *GetMessageClass(PyDescriptorPool* self, } } +PyObject* FindFileByName(PyDescriptorPool* self, PyObject* arg) { + Py_ssize_t name_size; + char* name; + if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { + return NULL; + } + + const FileDescriptor* file_descriptor = + self->pool->FindFileByName(string(name, name_size)); + if (file_descriptor == NULL) { + PyErr_Format(PyExc_KeyError, "Couldn't find file %.200s", + name); + return NULL; + } + + return PyFileDescriptor_FromDescriptor(file_descriptor); +} + PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; @@ -168,12 +185,12 @@ PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* arg) { const FieldDescriptor* field_descriptor = self->pool->FindFieldByName(string(name, name_size)); if (field_descriptor == NULL) { - PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s", + PyErr_Format(PyExc_KeyError, "Couldn't find field %.200s", name); return NULL; } - return PyFieldDescriptor_New(field_descriptor); + return PyFieldDescriptor_FromDescriptor(field_descriptor); } PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) { @@ -186,11 +203,11 @@ PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) { const FieldDescriptor* field_descriptor = self->pool->FindExtensionByName(string(name, name_size)); if (field_descriptor == NULL) { - PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s", name); + PyErr_Format(PyExc_KeyError, "Couldn't find extension field %.200s", name); return NULL; } - return PyFieldDescriptor_New(field_descriptor); + return PyFieldDescriptor_FromDescriptor(field_descriptor); } PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) { @@ -203,11 +220,11 @@ PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) { const EnumDescriptor* enum_descriptor = self->pool->FindEnumTypeByName(string(name, name_size)); if (enum_descriptor == NULL) { - PyErr_Format(PyExc_TypeError, "Couldn't find enum %.200s", name); + PyErr_Format(PyExc_KeyError, "Couldn't find enum %.200s", name); return NULL; } - return PyEnumDescriptor_New(enum_descriptor); + return PyEnumDescriptor_FromDescriptor(enum_descriptor); } PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) { @@ -220,70 +237,13 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) { const OneofDescriptor* oneof_descriptor = self->pool->FindOneofByName(string(name, name_size)); if (oneof_descriptor == NULL) { - PyErr_Format(PyExc_TypeError, "Couldn't find oneof %.200s", name); + PyErr_Format(PyExc_KeyError, "Couldn't find oneof %.200s", name); return NULL; } - return PyOneofDescriptor_New(oneof_descriptor); + return PyOneofDescriptor_FromDescriptor(oneof_descriptor); } -static PyMethodDef Methods[] = { - { C("FindFieldByName"), - (PyCFunction)FindFieldByName, - METH_O, - C("Searches for a field descriptor by full name.") }, - { C("FindExtensionByName"), - (PyCFunction)FindExtensionByName, - METH_O, - C("Searches for extension descriptor by full name.") }, - {NULL} -}; - -} // namespace cdescriptor_pool - -PyTypeObject PyDescriptorPool_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - C("google.protobuf.internal." - "_message.DescriptorPool"), // tp_name - sizeof(PyDescriptorPool), // tp_basicsize - 0, // tp_itemsize - (destructor)cdescriptor_pool::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 Descriptor Pool"), // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - cdescriptor_pool::Methods, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc - 0, // tp_new - PyObject_Del, // tp_free -}; - // The code below loads new Descriptors from a serialized FileDescriptorProto. @@ -301,6 +261,7 @@ class BuildFileErrorCollector : public DescriptorPool::ErrorCollector { if (!had_errors) { error_message += ("Invalid proto descriptor for file \"" + filename + "\":\n"); + had_errors = true; } // As this only happens on failure and will result in the program not // running at all, no effort is made to optimize this string manipulation. @@ -311,7 +272,7 @@ class BuildFileErrorCollector : public DescriptorPool::ErrorCollector { bool had_errors; }; -PyObject* Python_BuildFile(PyObject* ignored, PyObject* serialized_pb) { +PyObject* AddSerializedFile(PyDescriptorPool* self, PyObject* serialized_pb) { char* message_type; Py_ssize_t message_len; @@ -330,13 +291,14 @@ PyObject* Python_BuildFile(PyObject* ignored, PyObject* serialized_pb) { const FileDescriptor* generated_file = DescriptorPool::generated_pool()->FindFileByName(file_proto.name()); if (generated_file != NULL) { - return PyFileDescriptor_NewWithPb(generated_file, serialized_pb); + return PyFileDescriptor_FromDescriptorWithSerializedPb( + generated_file, serialized_pb); } BuildFileErrorCollector error_collector; const FileDescriptor* descriptor = - GetDescriptorPool()->pool->BuildFileCollectingErrors(file_proto, - &error_collector); + self->pool->BuildFileCollectingErrors(file_proto, + &error_collector); if (descriptor == NULL) { PyErr_Format(PyExc_TypeError, "Couldn't build proto file into descriptor pool!\n%s", @@ -344,9 +306,84 @@ PyObject* Python_BuildFile(PyObject* ignored, PyObject* serialized_pb) { return NULL; } - return PyFileDescriptor_NewWithPb(descriptor, serialized_pb); + return PyFileDescriptor_FromDescriptorWithSerializedPb( + descriptor, serialized_pb); +} + +PyObject* Add(PyDescriptorPool* self, PyObject* file_descriptor_proto) { + ScopedPyObjectPtr serialized_pb( + PyObject_CallMethod(file_descriptor_proto, "SerializeToString", NULL)); + if (serialized_pb == NULL) { + return NULL; + } + return AddSerializedFile(self, serialized_pb); } +static PyMethodDef Methods[] = { + { "Add", (PyCFunction)Add, METH_O, + "Adds the FileDescriptorProto and its types to this pool." }, + { "AddSerializedFile", (PyCFunction)AddSerializedFile, METH_O, + "Adds a serialized FileDescriptorProto to this pool." }, + + { "FindFileByName", (PyCFunction)FindFileByName, METH_O, + "Searches for a file descriptor by its .proto name." }, + { "FindMessageTypeByName", (PyCFunction)FindMessageByName, METH_O, + "Searches for a message descriptor by full name." }, + { "FindFieldByName", (PyCFunction)FindFieldByName, METH_O, + "Searches for a field descriptor by full name." }, + { "FindExtensionByName", (PyCFunction)FindExtensionByName, METH_O, + "Searches for extension descriptor by full name." }, + { "FindEnumTypeByName", (PyCFunction)FindEnumTypeByName, METH_O, + "Searches for enum type descriptor by full name." }, + { "FindOneofByName", (PyCFunction)FindOneofByName, METH_O, + "Searches for oneof descriptor by full name." }, + {NULL} +}; + +} // namespace cdescriptor_pool + +PyTypeObject PyDescriptorPool_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + FULL_MODULE_NAME ".DescriptorPool", // tp_name + sizeof(PyDescriptorPool), // tp_basicsize + 0, // tp_itemsize + (destructor)cdescriptor_pool::Dealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Descriptor Pool", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + cdescriptor_pool::Methods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + 0, // tp_new + PyObject_Del, // tp_free +}; + static PyDescriptorPool* global_cdescriptor_pool = NULL; bool InitDescriptorPool() { |