| Index: third_party/protobuf/python/google/protobuf/pyext/descriptor_containers.cc
|
| diff --git a/third_party/protobuf/python/google/protobuf/pyext/descriptor_containers.cc b/third_party/protobuf/python/google/protobuf/pyext/descriptor_containers.cc
|
| deleted file mode 100644
|
| index 92e11e31220109675b4aa9b7601340da0df4f056..0000000000000000000000000000000000000000
|
| --- a/third_party/protobuf/python/google/protobuf/pyext/descriptor_containers.cc
|
| +++ /dev/null
|
| @@ -1,1564 +0,0 @@
|
| -// 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.
|
| -
|
| -// Mappings and Sequences of descriptors.
|
| -// Used by Descriptor.fields_by_name, EnumDescriptor.values...
|
| -//
|
| -// They avoid the allocation of a full dictionary or a full list: they simply
|
| -// store a pointer to the parent descriptor, use the C++ Descriptor methods (see
|
| -// google/protobuf/descriptor.h) to retrieve other descriptors, and create
|
| -// Python objects on the fly.
|
| -//
|
| -// The containers fully conform to abc.Mapping and abc.Sequence, and behave just
|
| -// like read-only dictionaries and lists.
|
| -//
|
| -// Because the interface of C++ Descriptors is quite regular, this file actually
|
| -// defines only three types, the exact behavior of a container is controlled by
|
| -// a DescriptorContainerDef structure, which contains functions that uses the
|
| -// public Descriptor API.
|
| -//
|
| -// Note: This DescriptorContainerDef is similar to the "virtual methods table"
|
| -// that a C++ compiler generates for a class. We have to make it explicit
|
| -// because the Python API is based on C, and does not play well with C++
|
| -// inheritance.
|
| -
|
| -#include <Python.h>
|
| -
|
| -#include <google/protobuf/descriptor.h>
|
| -#include <google/protobuf/pyext/descriptor_containers.h>
|
| -#include <google/protobuf/pyext/descriptor_pool.h>
|
| -#include <google/protobuf/pyext/descriptor.h>
|
| -#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
|
| -
|
| -#if PY_MAJOR_VERSION >= 3
|
| - #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
|
| - #define PyString_FromFormat PyUnicode_FromFormat
|
| - #define PyInt_FromLong PyLong_FromLong
|
| - #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 {
|
| -
|
| -struct PyContainer;
|
| -
|
| -typedef int (*CountMethod)(PyContainer* self);
|
| -typedef const void* (*GetByIndexMethod)(PyContainer* self, int index);
|
| -typedef const void* (*GetByNameMethod)(PyContainer* self, const string& name);
|
| -typedef const void* (*GetByNumberMethod)(PyContainer* self, int index);
|
| -typedef PyObject* (*NewObjectFromItemMethod)(const void* descriptor);
|
| -typedef const string& (*GetItemNameMethod)(const void* descriptor);
|
| -typedef int (*GetItemNumberMethod)(const void* descriptor);
|
| -typedef int (*GetItemIndexMethod)(const void* descriptor);
|
| -
|
| -struct DescriptorContainerDef {
|
| - const char* mapping_name;
|
| - // Returns the number of items in the container.
|
| - CountMethod count_fn;
|
| - // Retrieve item by index (usually the order of declaration in the proto file)
|
| - // Used by sequences, but also iterators. 0 <= index < Count().
|
| - GetByIndexMethod get_by_index_fn;
|
| - // Retrieve item by name (usually a call to some 'FindByName' method).
|
| - // Used by "by_name" mappings.
|
| - GetByNameMethod get_by_name_fn;
|
| - // Retrieve item by declared number (field tag, or enum value).
|
| - // Used by "by_number" mappings.
|
| - GetByNumberMethod get_by_number_fn;
|
| - // Converts a item C++ descriptor to a Python object. Returns a new reference.
|
| - NewObjectFromItemMethod new_object_from_item_fn;
|
| - // Retrieve the name of an item. Used by iterators on "by_name" mappings.
|
| - GetItemNameMethod get_item_name_fn;
|
| - // Retrieve the number of an item. Used by iterators on "by_number" mappings.
|
| - GetItemNumberMethod get_item_number_fn;
|
| - // Retrieve the index of an item for the container type.
|
| - // Used by "__contains__".
|
| - // If not set, "x in sequence" will do a linear search.
|
| - GetItemIndexMethod get_item_index_fn;
|
| -};
|
| -
|
| -struct PyContainer {
|
| - PyObject_HEAD
|
| -
|
| - // The proto2 descriptor this container belongs to the global DescriptorPool.
|
| - const void* descriptor;
|
| -
|
| - // A pointer to a static structure with function pointers that control the
|
| - // behavior of the container. Very similar to the table of virtual functions
|
| - // of a C++ class.
|
| - const DescriptorContainerDef* container_def;
|
| -
|
| - // The kind of container: list, or dict by name or value.
|
| - enum ContainerKind {
|
| - KIND_SEQUENCE,
|
| - KIND_BYNAME,
|
| - KIND_BYNUMBER,
|
| - } kind;
|
| -};
|
| -
|
| -struct PyContainerIterator {
|
| - PyObject_HEAD
|
| -
|
| - // The container we are iterating over. Own a reference.
|
| - PyContainer* container;
|
| -
|
| - // The current index in the iterator.
|
| - int index;
|
| -
|
| - // The kind of container: list, or dict by name or value.
|
| - enum IterKind {
|
| - KIND_ITERKEY,
|
| - KIND_ITERVALUE,
|
| - KIND_ITERITEM,
|
| - KIND_ITERVALUE_REVERSED, // For sequences
|
| - } kind;
|
| -};
|
| -
|
| -namespace descriptor {
|
| -
|
| -// Returns the C++ item descriptor for a given Python key.
|
| -// When the descriptor is found, return true and set *item.
|
| -// When the descriptor is not found, return true, but set *item to NULL.
|
| -// On error, returns false with an exception set.
|
| -static bool _GetItemByKey(PyContainer* self, PyObject* key, const void** item) {
|
| - switch (self->kind) {
|
| - case PyContainer::KIND_BYNAME:
|
| - {
|
| - char* name;
|
| - Py_ssize_t name_size;
|
| - if (PyString_AsStringAndSize(key, &name, &name_size) < 0) {
|
| - if (PyErr_ExceptionMatches(PyExc_TypeError)) {
|
| - // Not a string, cannot be in the container.
|
| - PyErr_Clear();
|
| - *item = NULL;
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| - *item = self->container_def->get_by_name_fn(
|
| - self, string(name, name_size));
|
| - return true;
|
| - }
|
| - case PyContainer::KIND_BYNUMBER:
|
| - {
|
| - Py_ssize_t number = PyNumber_AsSsize_t(key, NULL);
|
| - if (number == -1 && PyErr_Occurred()) {
|
| - if (PyErr_ExceptionMatches(PyExc_TypeError)) {
|
| - // Not a number, cannot be in the container.
|
| - PyErr_Clear();
|
| - *item = NULL;
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| - *item = self->container_def->get_by_number_fn(self, number);
|
| - return true;
|
| - }
|
| - default:
|
| - PyErr_SetNone(PyExc_NotImplementedError);
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -// Returns the key of the object at the given index.
|
| -// Used when iterating over mappings.
|
| -static PyObject* _NewKey_ByIndex(PyContainer* self, Py_ssize_t index) {
|
| - const void* item = self->container_def->get_by_index_fn(self, index);
|
| - switch (self->kind) {
|
| - case PyContainer::KIND_BYNAME:
|
| - {
|
| - const string& name(self->container_def->get_item_name_fn(item));
|
| - return PyString_FromStringAndSize(name.c_str(), name.size());
|
| - }
|
| - case PyContainer::KIND_BYNUMBER:
|
| - {
|
| - int value = self->container_def->get_item_number_fn(item);
|
| - return PyInt_FromLong(value);
|
| - }
|
| - default:
|
| - PyErr_SetNone(PyExc_NotImplementedError);
|
| - return NULL;
|
| - }
|
| -}
|
| -
|
| -// Returns the object at the given index.
|
| -// Also used when iterating over mappings.
|
| -static PyObject* _NewObj_ByIndex(PyContainer* self, Py_ssize_t index) {
|
| - return self->container_def->new_object_from_item_fn(
|
| - self->container_def->get_by_index_fn(self, index));
|
| -}
|
| -
|
| -static Py_ssize_t Length(PyContainer* self) {
|
| - return self->container_def->count_fn(self);
|
| -}
|
| -
|
| -// The DescriptorMapping type.
|
| -
|
| -static PyObject* Subscript(PyContainer* self, PyObject* key) {
|
| - const void* item = NULL;
|
| - if (!_GetItemByKey(self, key, &item)) {
|
| - return NULL;
|
| - }
|
| - if (!item) {
|
| - PyErr_SetObject(PyExc_KeyError, key);
|
| - return NULL;
|
| - }
|
| - return self->container_def->new_object_from_item_fn(item);
|
| -}
|
| -
|
| -static int AssSubscript(PyContainer* self, PyObject* key, PyObject* value) {
|
| - if (_CalledFromGeneratedFile(0)) {
|
| - return 0;
|
| - }
|
| - PyErr_Format(PyExc_TypeError,
|
| - "'%.200s' object does not support item assignment",
|
| - Py_TYPE(self)->tp_name);
|
| - return -1;
|
| -}
|
| -
|
| -static PyMappingMethods MappingMappingMethods = {
|
| - (lenfunc)Length, // mp_length
|
| - (binaryfunc)Subscript, // mp_subscript
|
| - (objobjargproc)AssSubscript, // mp_ass_subscript
|
| -};
|
| -
|
| -static int Contains(PyContainer* self, PyObject* key) {
|
| - const void* item = NULL;
|
| - if (!_GetItemByKey(self, key, &item)) {
|
| - return -1;
|
| - }
|
| - if (item) {
|
| - return 1;
|
| - } else {
|
| - return 0;
|
| - }
|
| -}
|
| -
|
| -static PyObject* ContainerRepr(PyContainer* self) {
|
| - const char* kind = "";
|
| - switch (self->kind) {
|
| - case PyContainer::KIND_SEQUENCE:
|
| - kind = "sequence";
|
| - break;
|
| - case PyContainer::KIND_BYNAME:
|
| - kind = "mapping by name";
|
| - break;
|
| - case PyContainer::KIND_BYNUMBER:
|
| - kind = "mapping by number";
|
| - break;
|
| - }
|
| - return PyString_FromFormat(
|
| - "<%s %s>", self->container_def->mapping_name, kind);
|
| -}
|
| -
|
| -extern PyTypeObject DescriptorMapping_Type;
|
| -extern PyTypeObject DescriptorSequence_Type;
|
| -
|
| -// A sequence container can only be equal to another sequence container, or (for
|
| -// backward compatibility) to a list containing the same items.
|
| -// Returns 1 if equal, 0 if unequal, -1 on error.
|
| -static int DescriptorSequence_Equal(PyContainer* self, PyObject* other) {
|
| - // Check the identity of C++ pointers.
|
| - if (PyObject_TypeCheck(other, &DescriptorSequence_Type)) {
|
| - PyContainer* other_container = reinterpret_cast<PyContainer*>(other);
|
| - if (self->descriptor == other_container->descriptor &&
|
| - self->container_def == other_container->container_def &&
|
| - self->kind == other_container->kind) {
|
| - return 1;
|
| - } else {
|
| - return 0;
|
| - }
|
| - }
|
| -
|
| - // If other is a list
|
| - if (PyList_Check(other)) {
|
| - // return list(self) == other
|
| - int size = Length(self);
|
| - if (size != PyList_Size(other)) {
|
| - return false;
|
| - }
|
| - for (int index = 0; index < size; index++) {
|
| - ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index));
|
| - if (value1 == NULL) {
|
| - return -1;
|
| - }
|
| - PyObject* value2 = PyList_GetItem(other, index);
|
| - if (value2 == NULL) {
|
| - return -1;
|
| - }
|
| - int cmp = PyObject_RichCompareBool(value1, value2, Py_EQ);
|
| - if (cmp != 1) // error or not equal
|
| - return cmp;
|
| - }
|
| - // All items were found and equal
|
| - return 1;
|
| - }
|
| -
|
| - // Any other object is different.
|
| - return 0;
|
| -}
|
| -
|
| -// A mapping container can only be equal to another mapping container, or (for
|
| -// backward compatibility) to a dict containing the same items.
|
| -// Returns 1 if equal, 0 if unequal, -1 on error.
|
| -static int DescriptorMapping_Equal(PyContainer* self, PyObject* other) {
|
| - // Check the identity of C++ pointers.
|
| - if (PyObject_TypeCheck(other, &DescriptorMapping_Type)) {
|
| - PyContainer* other_container = reinterpret_cast<PyContainer*>(other);
|
| - if (self->descriptor == other_container->descriptor &&
|
| - self->container_def == other_container->container_def &&
|
| - self->kind == other_container->kind) {
|
| - return 1;
|
| - } else {
|
| - return 0;
|
| - }
|
| - }
|
| -
|
| - // If other is a dict
|
| - if (PyDict_Check(other)) {
|
| - // equivalent to dict(self.items()) == other
|
| - int size = Length(self);
|
| - if (size != PyDict_Size(other)) {
|
| - return false;
|
| - }
|
| - for (int index = 0; index < size; index++) {
|
| - ScopedPyObjectPtr key(_NewKey_ByIndex(self, index));
|
| - if (key == NULL) {
|
| - return -1;
|
| - }
|
| - ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index));
|
| - if (value1 == NULL) {
|
| - return -1;
|
| - }
|
| - PyObject* value2 = PyDict_GetItem(other, key);
|
| - if (value2 == NULL) {
|
| - // Not found in the other dictionary
|
| - return 0;
|
| - }
|
| - int cmp = PyObject_RichCompareBool(value1, value2, Py_EQ);
|
| - if (cmp != 1) // error or not equal
|
| - return cmp;
|
| - }
|
| - // All items were found and equal
|
| - return 1;
|
| - }
|
| -
|
| - // Any other object is different.
|
| - return 0;
|
| -}
|
| -
|
| -static PyObject* RichCompare(PyContainer* self, PyObject* other, int opid) {
|
| - if (opid != Py_EQ && opid != Py_NE) {
|
| - Py_INCREF(Py_NotImplemented);
|
| - return Py_NotImplemented;
|
| - }
|
| -
|
| - int result;
|
| -
|
| - if (self->kind == PyContainer::KIND_SEQUENCE) {
|
| - result = DescriptorSequence_Equal(self, other);
|
| - } else {
|
| - result = DescriptorMapping_Equal(self, other);
|
| - }
|
| - if (result < 0) {
|
| - return NULL;
|
| - }
|
| - if (result ^ (opid == Py_NE)) {
|
| - Py_RETURN_TRUE;
|
| - } else {
|
| - Py_RETURN_FALSE;
|
| - }
|
| -}
|
| -
|
| -static PySequenceMethods MappingSequenceMethods = {
|
| - 0, // sq_length
|
| - 0, // sq_concat
|
| - 0, // sq_repeat
|
| - 0, // sq_item
|
| - 0, // sq_slice
|
| - 0, // sq_ass_item
|
| - 0, // sq_ass_slice
|
| - (objobjproc)Contains, // sq_contains
|
| -};
|
| -
|
| -static PyObject* Get(PyContainer* self, PyObject* args) {
|
| - PyObject* key;
|
| - PyObject* default_value = Py_None;
|
| - if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
|
| - return NULL;
|
| - }
|
| -
|
| - const void* item;
|
| - if (!_GetItemByKey(self, key, &item)) {
|
| - return NULL;
|
| - }
|
| - if (item == NULL) {
|
| - Py_INCREF(default_value);
|
| - return default_value;
|
| - }
|
| - return self->container_def->new_object_from_item_fn(item);
|
| -}
|
| -
|
| -static PyObject* Keys(PyContainer* self, PyObject* args) {
|
| - Py_ssize_t count = Length(self);
|
| - ScopedPyObjectPtr list(PyList_New(count));
|
| - if (list == NULL) {
|
| - return NULL;
|
| - }
|
| - for (Py_ssize_t index = 0; index < count; ++index) {
|
| - PyObject* key = _NewKey_ByIndex(self, index);
|
| - if (key == NULL) {
|
| - return NULL;
|
| - }
|
| - PyList_SET_ITEM(list.get(), index, key);
|
| - }
|
| - return list.release();
|
| -}
|
| -
|
| -static PyObject* Values(PyContainer* self, PyObject* args) {
|
| - Py_ssize_t count = Length(self);
|
| - ScopedPyObjectPtr list(PyList_New(count));
|
| - if (list == NULL) {
|
| - return NULL;
|
| - }
|
| - for (Py_ssize_t index = 0; index < count; ++index) {
|
| - PyObject* value = _NewObj_ByIndex(self, index);
|
| - if (value == NULL) {
|
| - return NULL;
|
| - }
|
| - PyList_SET_ITEM(list.get(), index, value);
|
| - }
|
| - return list.release();
|
| -}
|
| -
|
| -static PyObject* Items(PyContainer* self, PyObject* args) {
|
| - Py_ssize_t count = Length(self);
|
| - ScopedPyObjectPtr list(PyList_New(count));
|
| - if (list == NULL) {
|
| - return NULL;
|
| - }
|
| - for (Py_ssize_t index = 0; index < count; ++index) {
|
| - ScopedPyObjectPtr obj(PyTuple_New(2));
|
| - if (obj == NULL) {
|
| - return NULL;
|
| - }
|
| - PyObject* key = _NewKey_ByIndex(self, index);
|
| - if (key == NULL) {
|
| - return NULL;
|
| - }
|
| - PyTuple_SET_ITEM(obj.get(), 0, key);
|
| - PyObject* value = _NewObj_ByIndex(self, index);
|
| - if (value == NULL) {
|
| - return NULL;
|
| - }
|
| - PyTuple_SET_ITEM(obj.get(), 1, value);
|
| - PyList_SET_ITEM(list.get(), index, obj.release());
|
| - }
|
| - return list.release();
|
| -}
|
| -
|
| -static PyObject* NewContainerIterator(PyContainer* mapping,
|
| - PyContainerIterator::IterKind kind);
|
| -
|
| -static PyObject* Iter(PyContainer* self) {
|
| - return NewContainerIterator(self, PyContainerIterator::KIND_ITERKEY);
|
| -}
|
| -static PyObject* IterKeys(PyContainer* self, PyObject* args) {
|
| - return NewContainerIterator(self, PyContainerIterator::KIND_ITERKEY);
|
| -}
|
| -static PyObject* IterValues(PyContainer* self, PyObject* args) {
|
| - return NewContainerIterator(self, PyContainerIterator::KIND_ITERVALUE);
|
| -}
|
| -static PyObject* IterItems(PyContainer* self, PyObject* args) {
|
| - return NewContainerIterator(self, PyContainerIterator::KIND_ITERITEM);
|
| -}
|
| -
|
| -static PyMethodDef MappingMethods[] = {
|
| - { "get", (PyCFunction)Get, METH_VARARGS, },
|
| - { "keys", (PyCFunction)Keys, METH_NOARGS, },
|
| - { "values", (PyCFunction)Values, METH_NOARGS, },
|
| - { "items", (PyCFunction)Items, METH_NOARGS, },
|
| - { "iterkeys", (PyCFunction)IterKeys, METH_NOARGS, },
|
| - { "itervalues", (PyCFunction)IterValues, METH_NOARGS, },
|
| - { "iteritems", (PyCFunction)IterItems, METH_NOARGS, },
|
| - {NULL}
|
| -};
|
| -
|
| -PyTypeObject DescriptorMapping_Type = {
|
| - PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
| - "DescriptorMapping", // tp_name
|
| - sizeof(PyContainer), // tp_basicsize
|
| - 0, // tp_itemsize
|
| - 0, // tp_dealloc
|
| - 0, // tp_print
|
| - 0, // tp_getattr
|
| - 0, // tp_setattr
|
| - 0, // tp_compare
|
| - (reprfunc)ContainerRepr, // tp_repr
|
| - 0, // tp_as_number
|
| - &MappingSequenceMethods, // tp_as_sequence
|
| - &MappingMappingMethods, // 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
|
| - 0, // tp_doc
|
| - 0, // tp_traverse
|
| - 0, // tp_clear
|
| - (richcmpfunc)RichCompare, // tp_richcompare
|
| - 0, // tp_weaklistoffset
|
| - (getiterfunc)Iter, // tp_iter
|
| - 0, // tp_iternext
|
| - MappingMethods, // 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
|
| - 0, // tp_free
|
| -};
|
| -
|
| -// The DescriptorSequence type.
|
| -
|
| -static PyObject* GetItem(PyContainer* self, Py_ssize_t index) {
|
| - if (index < 0) {
|
| - index += Length(self);
|
| - }
|
| - if (index < 0 || index >= Length(self)) {
|
| - PyErr_SetString(PyExc_IndexError, "index out of range");
|
| - return NULL;
|
| - }
|
| - return _NewObj_ByIndex(self, index);
|
| -}
|
| -
|
| -// Returns the position of the item in the sequence, of -1 if not found.
|
| -// This function never fails.
|
| -int Find(PyContainer* self, PyObject* item) {
|
| - // The item can only be in one position: item.index.
|
| - // Check that self[item.index] == item, it's faster than a linear search.
|
| - //
|
| - // This assumes that sequences are only defined by syntax of the .proto file:
|
| - // a specific item belongs to only one sequence, depending on its position in
|
| - // the .proto file definition.
|
| - const void* descriptor_ptr = PyDescriptor_AsVoidPtr(item);
|
| - if (descriptor_ptr == NULL) {
|
| - // Not a descriptor, it cannot be in the list.
|
| - return -1;
|
| - }
|
| - if (self->container_def->get_item_index_fn) {
|
| - int index = self->container_def->get_item_index_fn(descriptor_ptr);
|
| - if (index < 0 || index >= Length(self)) {
|
| - // This index is not from this collection.
|
| - return -1;
|
| - }
|
| - if (self->container_def->get_by_index_fn(self, index) != descriptor_ptr) {
|
| - // The descriptor at this index is not the same.
|
| - return -1;
|
| - }
|
| - // self[item.index] == item, so return the index.
|
| - return index;
|
| - } else {
|
| - // Fall back to linear search.
|
| - int length = Length(self);
|
| - for (int index=0; index < length; index++) {
|
| - if (self->container_def->get_by_index_fn(self, index) == descriptor_ptr) {
|
| - return index;
|
| - }
|
| - }
|
| - // Not found
|
| - return -1;
|
| - }
|
| -}
|
| -
|
| -// Implements list.index(): the position of the item is in the sequence.
|
| -static PyObject* Index(PyContainer* self, PyObject* item) {
|
| - int position = Find(self, item);
|
| - if (position < 0) {
|
| - // Not found
|
| - PyErr_SetNone(PyExc_ValueError);
|
| - return NULL;
|
| - } else {
|
| - return PyInt_FromLong(position);
|
| - }
|
| -}
|
| -// Implements "list.__contains__()": is the object in the sequence.
|
| -static int SeqContains(PyContainer* self, PyObject* item) {
|
| - int position = Find(self, item);
|
| - if (position < 0) {
|
| - return 0;
|
| - } else {
|
| - return 1;
|
| - }
|
| -}
|
| -
|
| -// Implements list.count(): number of occurrences of the item in the sequence.
|
| -// An item can only appear once in a sequence. If it exists, return 1.
|
| -static PyObject* Count(PyContainer* self, PyObject* item) {
|
| - int position = Find(self, item);
|
| - if (position < 0) {
|
| - return PyInt_FromLong(0);
|
| - } else {
|
| - return PyInt_FromLong(1);
|
| - }
|
| -}
|
| -
|
| -static PyObject* Append(PyContainer* self, PyObject* args) {
|
| - if (_CalledFromGeneratedFile(0)) {
|
| - Py_RETURN_NONE;
|
| - }
|
| - PyErr_Format(PyExc_TypeError,
|
| - "'%.200s' object is not a mutable sequence",
|
| - Py_TYPE(self)->tp_name);
|
| - return NULL;
|
| -}
|
| -
|
| -static PyObject* Reversed(PyContainer* self, PyObject* args) {
|
| - return NewContainerIterator(self,
|
| - PyContainerIterator::KIND_ITERVALUE_REVERSED);
|
| -}
|
| -
|
| -static PyMethodDef SeqMethods[] = {
|
| - { "index", (PyCFunction)Index, METH_O, },
|
| - { "count", (PyCFunction)Count, METH_O, },
|
| - { "append", (PyCFunction)Append, METH_O, },
|
| - { "__reversed__", (PyCFunction)Reversed, METH_NOARGS, },
|
| - {NULL}
|
| -};
|
| -
|
| -static PySequenceMethods SeqSequenceMethods = {
|
| - (lenfunc)Length, // sq_length
|
| - 0, // sq_concat
|
| - 0, // sq_repeat
|
| - (ssizeargfunc)GetItem, // sq_item
|
| - 0, // sq_slice
|
| - 0, // sq_ass_item
|
| - 0, // sq_ass_slice
|
| - (objobjproc)SeqContains, // sq_contains
|
| -};
|
| -
|
| -PyTypeObject DescriptorSequence_Type = {
|
| - PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
| - "DescriptorSequence", // tp_name
|
| - sizeof(PyContainer), // tp_basicsize
|
| - 0, // tp_itemsize
|
| - 0, // tp_dealloc
|
| - 0, // tp_print
|
| - 0, // tp_getattr
|
| - 0, // tp_setattr
|
| - 0, // tp_compare
|
| - (reprfunc)ContainerRepr, // tp_repr
|
| - 0, // tp_as_number
|
| - &SeqSequenceMethods, // 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
|
| - 0, // tp_doc
|
| - 0, // tp_traverse
|
| - 0, // tp_clear
|
| - (richcmpfunc)RichCompare, // tp_richcompare
|
| - 0, // tp_weaklistoffset
|
| - 0, // tp_iter
|
| - 0, // tp_iternext
|
| - SeqMethods, // 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
|
| - 0, // tp_free
|
| -};
|
| -
|
| -static PyObject* NewMappingByName(
|
| - DescriptorContainerDef* container_def, const void* descriptor) {
|
| - PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
|
| - if (self == NULL) {
|
| - return NULL;
|
| - }
|
| - self->descriptor = descriptor;
|
| - self->container_def = container_def;
|
| - self->kind = PyContainer::KIND_BYNAME;
|
| - return reinterpret_cast<PyObject*>(self);
|
| -}
|
| -
|
| -static PyObject* NewMappingByNumber(
|
| - DescriptorContainerDef* container_def, const void* descriptor) {
|
| - if (container_def->get_by_number_fn == NULL ||
|
| - container_def->get_item_number_fn == NULL) {
|
| - PyErr_SetNone(PyExc_NotImplementedError);
|
| - return NULL;
|
| - }
|
| - PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
|
| - if (self == NULL) {
|
| - return NULL;
|
| - }
|
| - self->descriptor = descriptor;
|
| - self->container_def = container_def;
|
| - self->kind = PyContainer::KIND_BYNUMBER;
|
| - return reinterpret_cast<PyObject*>(self);
|
| -}
|
| -
|
| -static PyObject* NewSequence(
|
| - DescriptorContainerDef* container_def, const void* descriptor) {
|
| - PyContainer* self = PyObject_New(PyContainer, &DescriptorSequence_Type);
|
| - if (self == NULL) {
|
| - return NULL;
|
| - }
|
| - self->descriptor = descriptor;
|
| - self->container_def = container_def;
|
| - self->kind = PyContainer::KIND_SEQUENCE;
|
| - return reinterpret_cast<PyObject*>(self);
|
| -}
|
| -
|
| -// Implement iterators over PyContainers.
|
| -
|
| -static void Iterator_Dealloc(PyContainerIterator* self) {
|
| - Py_CLEAR(self->container);
|
| - Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
|
| -}
|
| -
|
| -static PyObject* Iterator_Next(PyContainerIterator* self) {
|
| - int count = self->container->container_def->count_fn(self->container);
|
| - if (self->index >= count) {
|
| - // Return NULL with no exception to indicate the end.
|
| - return NULL;
|
| - }
|
| - int index = self->index;
|
| - self->index += 1;
|
| - switch (self->kind) {
|
| - case PyContainerIterator::KIND_ITERKEY:
|
| - return _NewKey_ByIndex(self->container, index);
|
| - case PyContainerIterator::KIND_ITERVALUE:
|
| - return _NewObj_ByIndex(self->container, index);
|
| - case PyContainerIterator::KIND_ITERVALUE_REVERSED:
|
| - return _NewObj_ByIndex(self->container, count - index - 1);
|
| - case PyContainerIterator::KIND_ITERITEM:
|
| - {
|
| - PyObject* obj = PyTuple_New(2);
|
| - if (obj == NULL) {
|
| - return NULL;
|
| - }
|
| - PyObject* key = _NewKey_ByIndex(self->container, index);
|
| - if (key == NULL) {
|
| - Py_DECREF(obj);
|
| - return NULL;
|
| - }
|
| - PyTuple_SET_ITEM(obj, 0, key);
|
| - PyObject* value = _NewObj_ByIndex(self->container, index);
|
| - if (value == NULL) {
|
| - Py_DECREF(obj);
|
| - return NULL;
|
| - }
|
| - PyTuple_SET_ITEM(obj, 1, value);
|
| - return obj;
|
| - }
|
| - default:
|
| - PyErr_SetNone(PyExc_NotImplementedError);
|
| - return NULL;
|
| - }
|
| -}
|
| -
|
| -static PyTypeObject ContainerIterator_Type = {
|
| - PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
| - "DescriptorContainerIterator", // tp_name
|
| - sizeof(PyContainerIterator), // tp_basicsize
|
| - 0, // tp_itemsize
|
| - (destructor)Iterator_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
|
| - 0, // tp_doc
|
| - 0, // tp_traverse
|
| - 0, // tp_clear
|
| - 0, // tp_richcompare
|
| - 0, // tp_weaklistoffset
|
| - PyObject_SelfIter, // tp_iter
|
| - (iternextfunc)Iterator_Next, // tp_iternext
|
| - 0, // 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
|
| - 0, // tp_free
|
| -};
|
| -
|
| -static PyObject* NewContainerIterator(PyContainer* container,
|
| - PyContainerIterator::IterKind kind) {
|
| - PyContainerIterator* self = PyObject_New(PyContainerIterator,
|
| - &ContainerIterator_Type);
|
| - if (self == NULL) {
|
| - return NULL;
|
| - }
|
| - Py_INCREF(container);
|
| - self->container = container;
|
| - self->kind = kind;
|
| - self->index = 0;
|
| -
|
| - return reinterpret_cast<PyObject*>(self);
|
| -}
|
| -
|
| -} // namespace descriptor
|
| -
|
| -// Now define the real collections!
|
| -
|
| -namespace message_descriptor {
|
| -
|
| -typedef const Descriptor* ParentDescriptor;
|
| -
|
| -static ParentDescriptor GetDescriptor(PyContainer* self) {
|
| - return reinterpret_cast<ParentDescriptor>(self->descriptor);
|
| -}
|
| -
|
| -namespace fields {
|
| -
|
| -typedef const FieldDescriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->field_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByName(PyContainer* self, const string& name) {
|
| - return GetDescriptor(self)->FindFieldByName(name);
|
| -}
|
| -
|
| -static ItemDescriptor GetByNumber(PyContainer* self, int number) {
|
| - return GetDescriptor(self)->FindFieldByNumber(number);
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->field(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyFieldDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static const string& GetItemName(ItemDescriptor item) {
|
| - return item->name();
|
| -}
|
| -
|
| -static int GetItemNumber(ItemDescriptor item) {
|
| - return item->number();
|
| -}
|
| -
|
| -static int GetItemIndex(ItemDescriptor item) {
|
| - return item->index();
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "MessageFields",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)GetByName,
|
| - (GetByNumberMethod)GetByNumber,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)GetItemName,
|
| - (GetItemNumberMethod)GetItemNumber,
|
| - (GetItemIndexMethod)GetItemIndex,
|
| -};
|
| -
|
| -} // namespace fields
|
| -
|
| -PyObject* NewMessageFieldsByName(ParentDescriptor descriptor) {
|
| - return descriptor::NewMappingByName(&fields::ContainerDef, descriptor);
|
| -}
|
| -
|
| -PyObject* NewMessageFieldsByNumber(ParentDescriptor descriptor) {
|
| - return descriptor::NewMappingByNumber(&fields::ContainerDef, descriptor);
|
| -}
|
| -
|
| -PyObject* NewMessageFieldsSeq(ParentDescriptor descriptor) {
|
| - return descriptor::NewSequence(&fields::ContainerDef, descriptor);
|
| -}
|
| -
|
| -namespace nested_types {
|
| -
|
| -typedef const Descriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->nested_type_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByName(PyContainer* self, const string& name) {
|
| - return GetDescriptor(self)->FindNestedTypeByName(name);
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->nested_type(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyMessageDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static const string& GetItemName(ItemDescriptor item) {
|
| - return item->name();
|
| -}
|
| -
|
| -static int GetItemIndex(ItemDescriptor item) {
|
| - return item->index();
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "MessageNestedTypes",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)GetByName,
|
| - (GetByNumberMethod)NULL,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)GetItemName,
|
| - (GetItemNumberMethod)NULL,
|
| - (GetItemIndexMethod)GetItemIndex,
|
| -};
|
| -
|
| -} // namespace nested_types
|
| -
|
| -PyObject* NewMessageNestedTypesSeq(ParentDescriptor descriptor) {
|
| - return descriptor::NewSequence(&nested_types::ContainerDef, descriptor);
|
| -}
|
| -
|
| -PyObject* NewMessageNestedTypesByName(ParentDescriptor descriptor) {
|
| - return descriptor::NewMappingByName(&nested_types::ContainerDef, descriptor);
|
| -}
|
| -
|
| -namespace enums {
|
| -
|
| -typedef const EnumDescriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->enum_type_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByName(PyContainer* self, const string& name) {
|
| - return GetDescriptor(self)->FindEnumTypeByName(name);
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->enum_type(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyEnumDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static const string& GetItemName(ItemDescriptor item) {
|
| - return item->name();
|
| -}
|
| -
|
| -static int GetItemIndex(ItemDescriptor item) {
|
| - return item->index();
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "MessageNestedEnums",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)GetByName,
|
| - (GetByNumberMethod)NULL,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)GetItemName,
|
| - (GetItemNumberMethod)NULL,
|
| - (GetItemIndexMethod)GetItemIndex,
|
| -};
|
| -
|
| -} // namespace enums
|
| -
|
| -PyObject* NewMessageEnumsByName(ParentDescriptor descriptor) {
|
| - return descriptor::NewMappingByName(&enums::ContainerDef, descriptor);
|
| -}
|
| -
|
| -PyObject* NewMessageEnumsSeq(ParentDescriptor descriptor) {
|
| - return descriptor::NewSequence(&enums::ContainerDef, descriptor);
|
| -}
|
| -
|
| -namespace enumvalues {
|
| -
|
| -// This is the "enum_values_by_name" mapping, which collects values from all
|
| -// enum types in a message.
|
| -//
|
| -// Note that the behavior of the C++ descriptor is different: it will search and
|
| -// return the first value that matches the name, whereas the Python
|
| -// implementation retrieves the last one.
|
| -
|
| -typedef const EnumValueDescriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - int count = 0;
|
| - for (int i = 0; i < GetDescriptor(self)->enum_type_count(); ++i) {
|
| - count += GetDescriptor(self)->enum_type(i)->value_count();
|
| - }
|
| - return count;
|
| -}
|
| -
|
| -static ItemDescriptor GetByName(PyContainer* self, const string& name) {
|
| - return GetDescriptor(self)->FindEnumValueByName(name);
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - // This is not optimal, but the number of enums *types* in a given message
|
| - // is small. This function is only used when iterating over the mapping.
|
| - const EnumDescriptor* enum_type = NULL;
|
| - int enum_type_count = GetDescriptor(self)->enum_type_count();
|
| - for (int i = 0; i < enum_type_count; ++i) {
|
| - enum_type = GetDescriptor(self)->enum_type(i);
|
| - int enum_value_count = enum_type->value_count();
|
| - if (index < enum_value_count) {
|
| - // Found it!
|
| - break;
|
| - }
|
| - index -= enum_value_count;
|
| - }
|
| - // The next statement cannot overflow, because this function is only called by
|
| - // internal iterators which ensure that 0 <= index < Count().
|
| - return enum_type->value(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyEnumValueDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static const string& GetItemName(ItemDescriptor item) {
|
| - return item->name();
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "MessageEnumValues",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)GetByName,
|
| - (GetByNumberMethod)NULL,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)GetItemName,
|
| - (GetItemNumberMethod)NULL,
|
| - (GetItemIndexMethod)NULL,
|
| -};
|
| -
|
| -} // namespace enumvalues
|
| -
|
| -PyObject* NewMessageEnumValuesByName(ParentDescriptor descriptor) {
|
| - return descriptor::NewMappingByName(&enumvalues::ContainerDef, descriptor);
|
| -}
|
| -
|
| -namespace extensions {
|
| -
|
| -typedef const FieldDescriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->extension_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByName(PyContainer* self, const string& name) {
|
| - return GetDescriptor(self)->FindExtensionByName(name);
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->extension(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyFieldDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static const string& GetItemName(ItemDescriptor item) {
|
| - return item->name();
|
| -}
|
| -
|
| -static int GetItemIndex(ItemDescriptor item) {
|
| - return item->index();
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "MessageExtensions",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)GetByName,
|
| - (GetByNumberMethod)NULL,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)GetItemName,
|
| - (GetItemNumberMethod)NULL,
|
| - (GetItemIndexMethod)GetItemIndex,
|
| -};
|
| -
|
| -} // namespace extensions
|
| -
|
| -PyObject* NewMessageExtensionsByName(ParentDescriptor descriptor) {
|
| - return descriptor::NewMappingByName(&extensions::ContainerDef, descriptor);
|
| -}
|
| -
|
| -PyObject* NewMessageExtensionsSeq(ParentDescriptor descriptor) {
|
| - return descriptor::NewSequence(&extensions::ContainerDef, descriptor);
|
| -}
|
| -
|
| -namespace oneofs {
|
| -
|
| -typedef const OneofDescriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->oneof_decl_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByName(PyContainer* self, const string& name) {
|
| - return GetDescriptor(self)->FindOneofByName(name);
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->oneof_decl(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyOneofDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static const string& GetItemName(ItemDescriptor item) {
|
| - return item->name();
|
| -}
|
| -
|
| -static int GetItemIndex(ItemDescriptor item) {
|
| - return item->index();
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "MessageOneofs",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)GetByName,
|
| - (GetByNumberMethod)NULL,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)GetItemName,
|
| - (GetItemNumberMethod)NULL,
|
| - (GetItemIndexMethod)GetItemIndex,
|
| -};
|
| -
|
| -} // namespace oneofs
|
| -
|
| -PyObject* NewMessageOneofsByName(ParentDescriptor descriptor) {
|
| - return descriptor::NewMappingByName(&oneofs::ContainerDef, descriptor);
|
| -}
|
| -
|
| -PyObject* NewMessageOneofsSeq(ParentDescriptor descriptor) {
|
| - return descriptor::NewSequence(&oneofs::ContainerDef, descriptor);
|
| -}
|
| -
|
| -} // namespace message_descriptor
|
| -
|
| -namespace enum_descriptor {
|
| -
|
| -typedef const EnumDescriptor* ParentDescriptor;
|
| -
|
| -static ParentDescriptor GetDescriptor(PyContainer* self) {
|
| - return reinterpret_cast<ParentDescriptor>(self->descriptor);
|
| -}
|
| -
|
| -namespace enumvalues {
|
| -
|
| -typedef const EnumValueDescriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->value_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->value(index);
|
| -}
|
| -
|
| -static ItemDescriptor GetByName(PyContainer* self, const string& name) {
|
| - return GetDescriptor(self)->FindValueByName(name);
|
| -}
|
| -
|
| -static ItemDescriptor GetByNumber(PyContainer* self, int number) {
|
| - return GetDescriptor(self)->FindValueByNumber(number);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyEnumValueDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static const string& GetItemName(ItemDescriptor item) {
|
| - return item->name();
|
| -}
|
| -
|
| -static int GetItemNumber(ItemDescriptor item) {
|
| - return item->number();
|
| -}
|
| -
|
| -static int GetItemIndex(ItemDescriptor item) {
|
| - return item->index();
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "EnumValues",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)GetByName,
|
| - (GetByNumberMethod)GetByNumber,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)GetItemName,
|
| - (GetItemNumberMethod)GetItemNumber,
|
| - (GetItemIndexMethod)GetItemIndex,
|
| -};
|
| -
|
| -} // namespace enumvalues
|
| -
|
| -PyObject* NewEnumValuesByName(ParentDescriptor descriptor) {
|
| - return descriptor::NewMappingByName(&enumvalues::ContainerDef, descriptor);
|
| -}
|
| -
|
| -PyObject* NewEnumValuesByNumber(ParentDescriptor descriptor) {
|
| - return descriptor::NewMappingByNumber(&enumvalues::ContainerDef, descriptor);
|
| -}
|
| -
|
| -PyObject* NewEnumValuesSeq(ParentDescriptor descriptor) {
|
| - return descriptor::NewSequence(&enumvalues::ContainerDef, descriptor);
|
| -}
|
| -
|
| -} // namespace enum_descriptor
|
| -
|
| -namespace oneof_descriptor {
|
| -
|
| -typedef const OneofDescriptor* ParentDescriptor;
|
| -
|
| -static ParentDescriptor GetDescriptor(PyContainer* self) {
|
| - return reinterpret_cast<ParentDescriptor>(self->descriptor);
|
| -}
|
| -
|
| -namespace fields {
|
| -
|
| -typedef const FieldDescriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->field_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->field(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyFieldDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static int GetItemIndex(ItemDescriptor item) {
|
| - return item->index_in_oneof();
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "OneofFields",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)NULL,
|
| - (GetByNumberMethod)NULL,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)NULL,
|
| - (GetItemNumberMethod)NULL,
|
| - (GetItemIndexMethod)GetItemIndex,
|
| -};
|
| -
|
| -} // namespace fields
|
| -
|
| -PyObject* NewOneofFieldsSeq(ParentDescriptor descriptor) {
|
| - return descriptor::NewSequence(&fields::ContainerDef, descriptor);
|
| -}
|
| -
|
| -} // namespace oneof_descriptor
|
| -
|
| -namespace file_descriptor {
|
| -
|
| -typedef const FileDescriptor* ParentDescriptor;
|
| -
|
| -static ParentDescriptor GetDescriptor(PyContainer* self) {
|
| - return reinterpret_cast<ParentDescriptor>(self->descriptor);
|
| -}
|
| -
|
| -namespace messages {
|
| -
|
| -typedef const Descriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->message_type_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByName(PyContainer* self, const string& name) {
|
| - return GetDescriptor(self)->FindMessageTypeByName(name);
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->message_type(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyMessageDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static const string& GetItemName(ItemDescriptor item) {
|
| - return item->name();
|
| -}
|
| -
|
| -static int GetItemIndex(ItemDescriptor item) {
|
| - return item->index();
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "FileMessages",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)GetByName,
|
| - (GetByNumberMethod)NULL,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)GetItemName,
|
| - (GetItemNumberMethod)NULL,
|
| - (GetItemIndexMethod)GetItemIndex,
|
| -};
|
| -
|
| -} // namespace messages
|
| -
|
| -PyObject* NewFileMessageTypesByName(const FileDescriptor* descriptor) {
|
| - return descriptor::NewMappingByName(&messages::ContainerDef, descriptor);
|
| -}
|
| -
|
| -namespace enums {
|
| -
|
| -typedef const EnumDescriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->enum_type_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByName(PyContainer* self, const string& name) {
|
| - return GetDescriptor(self)->FindEnumTypeByName(name);
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->enum_type(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyEnumDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static const string& GetItemName(ItemDescriptor item) {
|
| - return item->name();
|
| -}
|
| -
|
| -static int GetItemIndex(ItemDescriptor item) {
|
| - return item->index();
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "FileEnums",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)GetByName,
|
| - (GetByNumberMethod)NULL,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)GetItemName,
|
| - (GetItemNumberMethod)NULL,
|
| - (GetItemIndexMethod)GetItemIndex,
|
| -};
|
| -
|
| -} // namespace enums
|
| -
|
| -PyObject* NewFileEnumTypesByName(const FileDescriptor* descriptor) {
|
| - return descriptor::NewMappingByName(&enums::ContainerDef, descriptor);
|
| -}
|
| -
|
| -namespace extensions {
|
| -
|
| -typedef const FieldDescriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->extension_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByName(PyContainer* self, const string& name) {
|
| - return GetDescriptor(self)->FindExtensionByName(name);
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->extension(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyFieldDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static const string& GetItemName(ItemDescriptor item) {
|
| - return item->name();
|
| -}
|
| -
|
| -static int GetItemIndex(ItemDescriptor item) {
|
| - return item->index();
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "FileExtensions",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)GetByName,
|
| - (GetByNumberMethod)NULL,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)GetItemName,
|
| - (GetItemNumberMethod)NULL,
|
| - (GetItemIndexMethod)GetItemIndex,
|
| -};
|
| -
|
| -} // namespace extensions
|
| -
|
| -PyObject* NewFileExtensionsByName(const FileDescriptor* descriptor) {
|
| - return descriptor::NewMappingByName(&extensions::ContainerDef, descriptor);
|
| -}
|
| -
|
| -namespace dependencies {
|
| -
|
| -typedef const FileDescriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->dependency_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->dependency(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyFileDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "FileDependencies",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)NULL,
|
| - (GetByNumberMethod)NULL,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)NULL,
|
| - (GetItemNumberMethod)NULL,
|
| - (GetItemIndexMethod)NULL,
|
| -};
|
| -
|
| -} // namespace dependencies
|
| -
|
| -PyObject* NewFileDependencies(const FileDescriptor* descriptor) {
|
| - return descriptor::NewSequence(&dependencies::ContainerDef, descriptor);
|
| -}
|
| -
|
| -namespace public_dependencies {
|
| -
|
| -typedef const FileDescriptor* ItemDescriptor;
|
| -
|
| -static int Count(PyContainer* self) {
|
| - return GetDescriptor(self)->public_dependency_count();
|
| -}
|
| -
|
| -static ItemDescriptor GetByIndex(PyContainer* self, int index) {
|
| - return GetDescriptor(self)->public_dependency(index);
|
| -}
|
| -
|
| -static PyObject* NewObjectFromItem(ItemDescriptor item) {
|
| - return PyFileDescriptor_FromDescriptor(item);
|
| -}
|
| -
|
| -static DescriptorContainerDef ContainerDef = {
|
| - "FilePublicDependencies",
|
| - (CountMethod)Count,
|
| - (GetByIndexMethod)GetByIndex,
|
| - (GetByNameMethod)NULL,
|
| - (GetByNumberMethod)NULL,
|
| - (NewObjectFromItemMethod)NewObjectFromItem,
|
| - (GetItemNameMethod)NULL,
|
| - (GetItemNumberMethod)NULL,
|
| - (GetItemIndexMethod)NULL,
|
| -};
|
| -
|
| -} // namespace public_dependencies
|
| -
|
| -PyObject* NewFilePublicDependencies(const FileDescriptor* descriptor) {
|
| - return descriptor::NewSequence(&public_dependencies::ContainerDef,
|
| - descriptor);
|
| -}
|
| -
|
| -} // namespace file_descriptor
|
| -
|
| -
|
| -// Register all implementations
|
| -
|
| -bool InitDescriptorMappingTypes() {
|
| - if (PyType_Ready(&descriptor::DescriptorMapping_Type) < 0)
|
| - return false;
|
| - if (PyType_Ready(&descriptor::DescriptorSequence_Type) < 0)
|
| - return false;
|
| - if (PyType_Ready(&descriptor::ContainerIterator_Type) < 0)
|
| - return false;
|
| - return true;
|
| -}
|
| -
|
| -} // namespace python
|
| -} // namespace protobuf
|
| -} // namespace google
|
|
|