diff options
author | Jisi Liu <jisi.liu@gmail.com> | 2015-10-05 11:59:43 -0700 |
---|---|---|
committer | Jisi Liu <jisi.liu@gmail.com> | 2015-10-05 11:59:43 -0700 |
commit | 46e8ff63cb67a6520711da5317aaaef04d0414d0 (patch) | |
tree | 64370726fe469f8dfca7b14f8b8cb80b6cc856f6 /python/google/protobuf/pyext/descriptor_pool.cc | |
parent | 0087da9d4775f79c67362cc89c653f3a33a9bae2 (diff) |
Down-integrate from google internal.
Diffstat (limited to 'python/google/protobuf/pyext/descriptor_pool.cc')
-rw-r--r-- | python/google/protobuf/pyext/descriptor_pool.cc | 112 |
1 files changed, 93 insertions, 19 deletions
diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc index 7aed651d..6443a7d5 100644 --- a/python/google/protobuf/pyext/descriptor_pool.cc +++ b/python/google/protobuf/pyext/descriptor_pool.cc @@ -108,6 +108,7 @@ static void Dealloc(PyDescriptorPool* self) { Py_DECREF(it->second); } delete self->descriptor_options; + delete self->pool; delete self->message_factory; Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); } @@ -131,22 +132,9 @@ PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* arg) { } // Add a message class to our database. -const Descriptor* RegisterMessageClass( - PyDescriptorPool* self, PyObject *message_class, PyObject* descriptor) { - ScopedPyObjectPtr full_message_name( - PyObject_GetAttrString(descriptor, "full_name")); - Py_ssize_t name_size; - char* name; - if (PyString_AsStringAndSize(full_message_name, &name, &name_size) < 0) { - return NULL; - } - const Descriptor *message_descriptor = - self->pool->FindMessageTypeByName(string(name, name_size)); - if (!message_descriptor) { - PyErr_Format(PyExc_TypeError, "Could not find C++ descriptor for '%s'", - name); - return NULL; - } +int RegisterMessageClass(PyDescriptorPool* self, + const Descriptor *message_descriptor, + PyObject *message_class) { Py_INCREF(message_class); typedef PyDescriptorPool::ClassesByMessageMap::iterator iterator; std::pair<iterator, bool> ret = self->classes_by_descriptor->insert( @@ -156,7 +144,7 @@ const Descriptor* RegisterMessageClass( Py_DECREF(ret.first->second); ret.first->second = message_class; } - return message_descriptor; + return 0; } // Retrieve the message class added to our database. @@ -260,6 +248,80 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) { return PyOneofDescriptor_FromDescriptor(oneof_descriptor); } +PyObject* FindFileContainingSymbol(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->FindFileContainingSymbol(string(name, name_size)); + if (file_descriptor == NULL) { + PyErr_Format(PyExc_KeyError, "Couldn't find symbol %.200s", name); + return NULL; + } + + return PyFileDescriptor_FromDescriptor(file_descriptor); +} + +// These functions should not exist -- the only valid way to create +// descriptors is to call Add() or AddSerializedFile(). +// But these AddDescriptor() functions were created in Python and some people +// call them, so we support them for now for compatibility. +// However we do check that the existing descriptor already exists in the pool, +// which appears to always be true for existing calls -- but then why do people +// call a function that will just be a no-op? +// TODO(amauryfa): Need to investigate further. + +PyObject* AddFileDescriptor(PyDescriptorPool* self, PyObject* descriptor) { + const FileDescriptor* file_descriptor = + PyFileDescriptor_AsDescriptor(descriptor); + if (!file_descriptor) { + return NULL; + } + if (file_descriptor != + self->pool->FindFileByName(file_descriptor->name())) { + PyErr_Format(PyExc_ValueError, + "The file descriptor %s does not belong to this pool", + file_descriptor->name().c_str()); + return NULL; + } + Py_RETURN_NONE; +} + +PyObject* AddDescriptor(PyDescriptorPool* self, PyObject* descriptor) { + const Descriptor* message_descriptor = + PyMessageDescriptor_AsDescriptor(descriptor); + if (!message_descriptor) { + return NULL; + } + if (message_descriptor != + self->pool->FindMessageTypeByName(message_descriptor->full_name())) { + PyErr_Format(PyExc_ValueError, + "The message descriptor %s does not belong to this pool", + message_descriptor->full_name().c_str()); + return NULL; + } + Py_RETURN_NONE; +} + +PyObject* AddEnumDescriptor(PyDescriptorPool* self, PyObject* descriptor) { + const EnumDescriptor* enum_descriptor = + PyEnumDescriptor_AsDescriptor(descriptor); + if (!enum_descriptor) { + return NULL; + } + if (enum_descriptor != + self->pool->FindEnumTypeByName(enum_descriptor->full_name())) { + PyErr_Format(PyExc_ValueError, + "The enum descriptor %s does not belong to this pool", + enum_descriptor->full_name().c_str()); + return NULL; + } + Py_RETURN_NONE; +} + // The code below loads new Descriptors from a serialized FileDescriptorProto. @@ -341,6 +403,15 @@ static PyMethodDef Methods[] = { { "AddSerializedFile", (PyCFunction)AddSerializedFile, METH_O, "Adds a serialized FileDescriptorProto to this pool." }, + // TODO(amauryfa): Understand why the Python implementation differs from + // this one, ask users to use another API and deprecate these functions. + { "AddFileDescriptor", (PyCFunction)AddFileDescriptor, METH_O, + "No-op. Add() must have been called before." }, + { "AddDescriptor", (PyCFunction)AddDescriptor, METH_O, + "No-op. Add() must have been called before." }, + { "AddEnumDescriptor", (PyCFunction)AddEnumDescriptor, METH_O, + "No-op. Add() must have been called before." }, + { "FindFileByName", (PyCFunction)FindFileByName, METH_O, "Searches for a file descriptor by its .proto name." }, { "FindMessageTypeByName", (PyCFunction)FindMessageByName, METH_O, @@ -353,6 +424,9 @@ static PyMethodDef Methods[] = { "Searches for enum type descriptor by full name." }, { "FindOneofByName", (PyCFunction)FindOneofByName, METH_O, "Searches for oneof descriptor by full name." }, + + { "FindFileContainingSymbol", (PyCFunction)FindFileContainingSymbol, METH_O, + "Gets the FileDescriptor containing the specified symbol." }, {NULL} }; @@ -420,7 +494,7 @@ bool InitDescriptorPool() { return true; } -PyDescriptorPool* GetDescriptorPool() { +PyDescriptorPool* GetDefaultDescriptorPool() { return python_generated_pool; } @@ -432,7 +506,7 @@ PyDescriptorPool* GetDescriptorPool_FromPool(const DescriptorPool* pool) { } hash_map<const DescriptorPool*, PyDescriptorPool*>::iterator it = descriptor_pool_map.find(pool); - if (it != descriptor_pool_map.end()) { + if (it == descriptor_pool_map.end()) { PyErr_SetString(PyExc_KeyError, "Unknown descriptor pool"); return NULL; } |