| Index: third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc
|
| diff --git a/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc b/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc
|
| index 1faff96bc2e44c40a3aa8da0550f947cd67b40df..fa66bf9ace7091c59d36db93f463d27c8a3557e8 100644
|
| --- a/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc
|
| +++ b/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc
|
| @@ -33,11 +33,11 @@
|
| #include <Python.h>
|
|
|
| #include <google/protobuf/descriptor.pb.h>
|
| -#include <google/protobuf/dynamic_message.h>
|
| #include <google/protobuf/pyext/descriptor.h>
|
| #include <google/protobuf/pyext/descriptor_database.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>
|
|
|
| #if PY_MAJOR_VERSION >= 3
|
| @@ -73,18 +73,16 @@ static PyDescriptorPool* _CreateDescriptorPool() {
|
| cpool->underlay = NULL;
|
| cpool->database = NULL;
|
|
|
| - DynamicMessageFactory* message_factory = new DynamicMessageFactory();
|
| - // This option might be the default some day.
|
| - message_factory->SetDelegateToGeneratedFactory(true);
|
| - cpool->message_factory = message_factory;
|
| -
|
| - // TODO(amauryfa): Rewrite the SymbolDatabase in C so that it uses the same
|
| - // storage.
|
| - cpool->classes_by_descriptor =
|
| - new PyDescriptorPool::ClassesByMessageMap();
|
| cpool->descriptor_options =
|
| new hash_map<const void*, PyObject *>();
|
|
|
| + cpool->py_message_factory = message_factory::NewMessageFactory(
|
| + &PyMessageFactory_Type, cpool);
|
| + if (cpool->py_message_factory == NULL) {
|
| + Py_DECREF(cpool);
|
| + return NULL;
|
| + }
|
| +
|
| return cpool;
|
| }
|
|
|
| @@ -151,20 +149,14 @@ static PyObject* New(PyTypeObject* type,
|
| }
|
|
|
| static void Dealloc(PyDescriptorPool* self) {
|
| - typedef PyDescriptorPool::ClassesByMessageMap::iterator iterator;
|
| descriptor_pool_map.erase(self->pool);
|
| - for (iterator it = self->classes_by_descriptor->begin();
|
| - it != self->classes_by_descriptor->end(); ++it) {
|
| - Py_DECREF(it->second);
|
| - }
|
| - delete self->classes_by_descriptor;
|
| + Py_CLEAR(self->py_message_factory);
|
| for (hash_map<const void*, PyObject*>::iterator it =
|
| self->descriptor_options->begin();
|
| it != self->descriptor_options->end(); ++it) {
|
| Py_DECREF(it->second);
|
| }
|
| delete self->descriptor_options;
|
| - delete self->message_factory;
|
| delete self->database;
|
| delete self->pool;
|
| Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
|
| @@ -188,35 +180,8 @@ PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* arg) {
|
| return PyMessageDescriptor_FromDescriptor(message_descriptor);
|
| }
|
|
|
| -// Add a message class to our database.
|
| -int RegisterMessageClass(PyDescriptorPool* self,
|
| - const Descriptor* message_descriptor,
|
| - CMessageClass* message_class) {
|
| - Py_INCREF(message_class);
|
| - typedef PyDescriptorPool::ClassesByMessageMap::iterator iterator;
|
| - std::pair<iterator, bool> ret = self->classes_by_descriptor->insert(
|
| - std::make_pair(message_descriptor, message_class));
|
| - if (!ret.second) {
|
| - // Update case: DECREF the previous value.
|
| - Py_DECREF(ret.first->second);
|
| - ret.first->second = message_class;
|
| - }
|
| - return 0;
|
| -}
|
|
|
| -// Retrieve the message class added to our database.
|
| -CMessageClass* GetMessageClass(PyDescriptorPool* self,
|
| - const Descriptor* message_descriptor) {
|
| - typedef PyDescriptorPool::ClassesByMessageMap::iterator iterator;
|
| - iterator ret = self->classes_by_descriptor->find(message_descriptor);
|
| - if (ret == self->classes_by_descriptor->end()) {
|
| - PyErr_Format(PyExc_TypeError, "No message class registered for '%s'",
|
| - message_descriptor->full_name().c_str());
|
| - return NULL;
|
| - } else {
|
| - return ret->second;
|
| - }
|
| -}
|
| +
|
|
|
| PyObject* FindFileByName(PyDescriptorPool* self, PyObject* arg) {
|
| Py_ssize_t name_size;
|
| @@ -228,11 +193,9 @@ PyObject* FindFileByName(PyDescriptorPool* self, PyObject* arg) {
|
| 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);
|
| + PyErr_Format(PyExc_KeyError, "Couldn't find file %.200s", name);
|
| return NULL;
|
| }
|
| -
|
| return PyFileDescriptor_FromDescriptor(file_descriptor);
|
| }
|
|
|
| @@ -305,6 +268,40 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) {
|
| return PyOneofDescriptor_FromDescriptor(oneof_descriptor);
|
| }
|
|
|
| +PyObject* FindServiceByName(PyDescriptorPool* self, PyObject* arg) {
|
| + Py_ssize_t name_size;
|
| + char* name;
|
| + if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
|
| + return NULL;
|
| + }
|
| +
|
| + const ServiceDescriptor* service_descriptor =
|
| + self->pool->FindServiceByName(string(name, name_size));
|
| + if (service_descriptor == NULL) {
|
| + PyErr_Format(PyExc_KeyError, "Couldn't find service %.200s", name);
|
| + return NULL;
|
| + }
|
| +
|
| + return PyServiceDescriptor_FromDescriptor(service_descriptor);
|
| +}
|
| +
|
| +PyObject* FindMethodByName(PyDescriptorPool* self, PyObject* arg) {
|
| + Py_ssize_t name_size;
|
| + char* name;
|
| + if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
|
| + return NULL;
|
| + }
|
| +
|
| + const MethodDescriptor* method_descriptor =
|
| + self->pool->FindMethodByName(string(name, name_size));
|
| + if (method_descriptor == NULL) {
|
| + PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
|
| + return NULL;
|
| + }
|
| +
|
| + return PyMethodDescriptor_FromDescriptor(method_descriptor);
|
| +}
|
| +
|
| PyObject* FindFileContainingSymbol(PyDescriptorPool* self, PyObject* arg) {
|
| Py_ssize_t name_size;
|
| char* name;
|
| @@ -322,6 +319,51 @@ PyObject* FindFileContainingSymbol(PyDescriptorPool* self, PyObject* arg) {
|
| return PyFileDescriptor_FromDescriptor(file_descriptor);
|
| }
|
|
|
| +PyObject* FindExtensionByNumber(PyDescriptorPool* self, PyObject* args) {
|
| + PyObject* message_descriptor;
|
| + int number;
|
| + if (!PyArg_ParseTuple(args, "Oi", &message_descriptor, &number)) {
|
| + return NULL;
|
| + }
|
| + const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor(
|
| + message_descriptor);
|
| + if (descriptor == NULL) {
|
| + return NULL;
|
| + }
|
| +
|
| + const FieldDescriptor* extension_descriptor =
|
| + self->pool->FindExtensionByNumber(descriptor, number);
|
| + if (extension_descriptor == NULL) {
|
| + PyErr_Format(PyExc_KeyError, "Couldn't find extension %d", number);
|
| + return NULL;
|
| + }
|
| +
|
| + return PyFieldDescriptor_FromDescriptor(extension_descriptor);
|
| +}
|
| +
|
| +PyObject* FindAllExtensions(PyDescriptorPool* self, PyObject* arg) {
|
| + const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor(arg);
|
| + if (descriptor == NULL) {
|
| + return NULL;
|
| + }
|
| +
|
| + std::vector<const FieldDescriptor*> extensions;
|
| + self->pool->FindAllExtensions(descriptor, &extensions);
|
| +
|
| + ScopedPyObjectPtr result(PyList_New(extensions.size()));
|
| + if (result == NULL) {
|
| + return NULL;
|
| + }
|
| + for (int i = 0; i < extensions.size(); i++) {
|
| + PyObject* extension = PyFieldDescriptor_FromDescriptor(extensions[i]);
|
| + if (extension == NULL) {
|
| + return NULL;
|
| + }
|
| + PyList_SET_ITEM(result.get(), i, extension); // Steals the reference.
|
| + }
|
| + return result.release();
|
| +}
|
| +
|
| // 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
|
| @@ -379,6 +421,22 @@ PyObject* AddEnumDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
| Py_RETURN_NONE;
|
| }
|
|
|
| +PyObject* AddExtensionDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
|
| + const FieldDescriptor* extension_descriptor =
|
| + PyFieldDescriptor_AsDescriptor(descriptor);
|
| + if (!extension_descriptor) {
|
| + return NULL;
|
| + }
|
| + if (extension_descriptor !=
|
| + self->pool->FindExtensionByName(extension_descriptor->full_name())) {
|
| + PyErr_Format(PyExc_ValueError,
|
| + "The extension descriptor %s does not belong to this pool",
|
| + extension_descriptor->full_name().c_str());
|
| + return NULL;
|
| + }
|
| + Py_RETURN_NONE;
|
| +}
|
| +
|
| // The code below loads new Descriptors from a serialized FileDescriptorProto.
|
|
|
|
|
| @@ -478,6 +536,8 @@ static PyMethodDef Methods[] = {
|
| "No-op. Add() must have been called before." },
|
| { "AddEnumDescriptor", (PyCFunction)AddEnumDescriptor, METH_O,
|
| "No-op. Add() must have been called before." },
|
| + { "AddExtensionDescriptor", (PyCFunction)AddExtensionDescriptor, METH_O,
|
| + "No-op. Add() must have been called before." },
|
|
|
| { "FindFileByName", (PyCFunction)FindFileByName, METH_O,
|
| "Searches for a file descriptor by its .proto name." },
|
| @@ -491,9 +551,17 @@ static PyMethodDef Methods[] = {
|
| "Searches for enum type descriptor by full name." },
|
| { "FindOneofByName", (PyCFunction)FindOneofByName, METH_O,
|
| "Searches for oneof descriptor by full name." },
|
| + { "FindServiceByName", (PyCFunction)FindServiceByName, METH_O,
|
| + "Searches for service descriptor by full name." },
|
| + { "FindMethodByName", (PyCFunction)FindMethodByName, METH_O,
|
| + "Searches for method descriptor by full name." },
|
|
|
| { "FindFileContainingSymbol", (PyCFunction)FindFileContainingSymbol, METH_O,
|
| "Gets the FileDescriptor containing the specified symbol." },
|
| + { "FindExtensionByNumber", (PyCFunction)FindExtensionByNumber, METH_VARARGS,
|
| + "Gets the extension descriptor for the given number." },
|
| + { "FindAllExtensions", (PyCFunction)FindAllExtensions, METH_O,
|
| + "Gets all known extensions of the given message descriptor." },
|
| {NULL}
|
| };
|
|
|
|
|