| Index: third_party/protobuf/python/google/protobuf/pyext/extension_dict.cc
|
| diff --git a/third_party/protobuf/python/google/protobuf/pyext/extension_dict.cc b/third_party/protobuf/python/google/protobuf/pyext/extension_dict.cc
|
| index 9423c1d890b102ff014fa769abd89435b81d8e76..21bbb8c2b1d3d7e0f2073f5bf3b4e072716fa37f 100644
|
| --- a/third_party/protobuf/python/google/protobuf/pyext/extension_dict.cc
|
| +++ b/third_party/protobuf/python/google/protobuf/pyext/extension_dict.cc
|
| @@ -38,25 +38,14 @@
|
| #include <google/protobuf/descriptor.h>
|
| #include <google/protobuf/dynamic_message.h>
|
| #include <google/protobuf/message.h>
|
| -#include <google/protobuf/descriptor.pb.h>
|
| #include <google/protobuf/pyext/descriptor.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/repeated_composite_container.h>
|
| #include <google/protobuf/pyext/repeated_scalar_container.h>
|
| #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
|
| #include <google/protobuf/stubs/shared_ptr.h>
|
|
|
| -#if PY_MAJOR_VERSION >= 3
|
| - #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 {
|
| @@ -71,6 +60,35 @@ PyObject* len(ExtensionDict* self) {
|
| #endif
|
| }
|
|
|
| +// TODO(tibell): Use VisitCompositeField.
|
| +int ReleaseExtension(ExtensionDict* self,
|
| + PyObject* extension,
|
| + const FieldDescriptor* descriptor) {
|
| + if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
|
| + if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
|
| + if (repeated_composite_container::Release(
|
| + reinterpret_cast<RepeatedCompositeContainer*>(
|
| + extension)) < 0) {
|
| + return -1;
|
| + }
|
| + } else {
|
| + if (repeated_scalar_container::Release(
|
| + reinterpret_cast<RepeatedScalarContainer*>(
|
| + extension)) < 0) {
|
| + return -1;
|
| + }
|
| + }
|
| + } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
|
| + if (cmessage::ReleaseSubMessage(
|
| + self->parent, descriptor,
|
| + reinterpret_cast<CMessage*>(extension)) < 0) {
|
| + return -1;
|
| + }
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| PyObject* subscript(ExtensionDict* self, PyObject* key) {
|
| const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key);
|
| if (descriptor == NULL) {
|
| @@ -101,7 +119,6 @@ PyObject* subscript(ExtensionDict* self, PyObject* key) {
|
|
|
| if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
|
| descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
|
| - // TODO(plabatut): consider building the class on the fly!
|
| PyObject* sub_message = cmessage::InternalGetSubMessage(
|
| self->parent, descriptor);
|
| if (sub_message == NULL) {
|
| @@ -113,18 +130,8 @@ PyObject* subscript(ExtensionDict* self, PyObject* key) {
|
|
|
| if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
|
| if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
|
| - // On the fly message class creation is needed to support the following
|
| - // situation:
|
| - // 1- add FileDescriptor to the pool that contains extensions of a message
|
| - // defined by another proto file. Do not create any message classes.
|
| - // 2- instantiate an extended message, and access the extension using
|
| - // the field descriptor.
|
| - // 3- the extension submessage fails to be returned, because no class has
|
| - // been created.
|
| - // It happens when deserializing text proto format, or when enumerating
|
| - // fields of a deserialized message.
|
| - CMessageClass* message_class = message_factory::GetOrCreateMessageClass(
|
| - cmessage::GetFactoryForMessage(self->parent),
|
| + CMessageClass* message_class = cdescriptor_pool::GetMessageClass(
|
| + cmessage::GetDescriptorPoolForMessage(self->parent),
|
| descriptor->message_type());
|
| if (message_class == NULL) {
|
| return NULL;
|
| @@ -176,51 +183,75 @@ int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value) {
|
| return 0;
|
| }
|
|
|
| -PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) {
|
| - char* name;
|
| - Py_ssize_t name_size;
|
| - if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
|
| +PyObject* ClearExtension(ExtensionDict* self, PyObject* extension) {
|
| + const FieldDescriptor* descriptor =
|
| + cmessage::GetExtensionDescriptor(extension);
|
| + if (descriptor == NULL) {
|
| return NULL;
|
| }
|
| -
|
| - PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool;
|
| - const FieldDescriptor* message_extension =
|
| - pool->pool->FindExtensionByName(string(name, name_size));
|
| - if (message_extension == NULL) {
|
| - // Is is the name of a message set extension?
|
| - const Descriptor* message_descriptor = pool->pool->FindMessageTypeByName(
|
| - string(name, name_size));
|
| - if (message_descriptor && message_descriptor->extension_count() > 0) {
|
| - const FieldDescriptor* extension = message_descriptor->extension(0);
|
| - if (extension->is_extension() &&
|
| - extension->containing_type()->options().message_set_wire_format() &&
|
| - extension->type() == FieldDescriptor::TYPE_MESSAGE &&
|
| - extension->label() == FieldDescriptor::LABEL_OPTIONAL) {
|
| - message_extension = extension;
|
| + PyObject* value = PyDict_GetItem(self->values, extension);
|
| + if (self->parent) {
|
| + if (value != NULL) {
|
| + if (ReleaseExtension(self, value, descriptor) < 0) {
|
| + return NULL;
|
| }
|
| }
|
| + if (ScopedPyObjectPtr(cmessage::ClearFieldByDescriptor(
|
| + self->parent, descriptor)) == NULL) {
|
| + return NULL;
|
| + }
|
| }
|
| - if (message_extension == NULL) {
|
| - Py_RETURN_NONE;
|
| + if (PyDict_DelItem(self->values, extension) < 0) {
|
| + PyErr_Clear();
|
| }
|
| -
|
| - return PyFieldDescriptor_FromDescriptor(message_extension);
|
| + Py_RETURN_NONE;
|
| }
|
|
|
| -PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* arg) {
|
| - int64 number = PyLong_AsLong(arg);
|
| - if (number == -1 && PyErr_Occurred()) {
|
| +PyObject* HasExtension(ExtensionDict* self, PyObject* extension) {
|
| + const FieldDescriptor* descriptor =
|
| + cmessage::GetExtensionDescriptor(extension);
|
| + if (descriptor == NULL) {
|
| return NULL;
|
| }
|
| + if (self->parent) {
|
| + return cmessage::HasFieldByDescriptor(self->parent, descriptor);
|
| + } else {
|
| + int exists = PyDict_Contains(self->values, extension);
|
| + if (exists < 0) {
|
| + return NULL;
|
| + }
|
| + return PyBool_FromLong(exists);
|
| + }
|
| +}
|
|
|
| - PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool;
|
| - const FieldDescriptor* message_extension = pool->pool->FindExtensionByNumber(
|
| - self->parent->message->GetDescriptor(), number);
|
| - if (message_extension == NULL) {
|
| +PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name) {
|
| + ScopedPyObjectPtr extensions_by_name(PyObject_GetAttrString(
|
| + reinterpret_cast<PyObject*>(self->parent), "_extensions_by_name"));
|
| + if (extensions_by_name == NULL) {
|
| + return NULL;
|
| + }
|
| + PyObject* result = PyDict_GetItem(extensions_by_name.get(), name);
|
| + if (result == NULL) {
|
| Py_RETURN_NONE;
|
| + } else {
|
| + Py_INCREF(result);
|
| + return result;
|
| }
|
| +}
|
|
|
| - return PyFieldDescriptor_FromDescriptor(message_extension);
|
| +PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* number) {
|
| + ScopedPyObjectPtr extensions_by_number(PyObject_GetAttrString(
|
| + reinterpret_cast<PyObject*>(self->parent), "_extensions_by_number"));
|
| + if (extensions_by_number == NULL) {
|
| + return NULL;
|
| + }
|
| + PyObject* result = PyDict_GetItem(extensions_by_number.get(), number);
|
| + if (result == NULL) {
|
| + Py_RETURN_NONE;
|
| + } else {
|
| + Py_INCREF(result);
|
| + return result;
|
| + }
|
| }
|
|
|
| ExtensionDict* NewExtensionDict(CMessage *parent) {
|
| @@ -251,6 +282,8 @@ static PyMappingMethods MpMethods = {
|
|
|
| #define EDMETHOD(name, args, doc) { #name, (PyCFunction)name, args, doc }
|
| static PyMethodDef Methods[] = {
|
| + EDMETHOD(ClearExtension, METH_O, "Clears an extension from the object."),
|
| + EDMETHOD(HasExtension, METH_O, "Checks if the object has an extension."),
|
| EDMETHOD(_FindExtensionByName, METH_O,
|
| "Finds an extension by name."),
|
| EDMETHOD(_FindExtensionByNumber, METH_O,
|
|
|