123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704 |
- /*
- * Copyright (c) 2009-2021, Google LLC
- * All rights reserved.
- *
- * 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 LLC 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 Google LLC 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.
- */
- #include "descriptor_containers.h"
- #include "descriptor.h"
- #include "protobuf.h"
- #include "upb/def.h"
- // -----------------------------------------------------------------------------
- // DescriptorIterator
- // -----------------------------------------------------------------------------
- typedef struct {
- PyObject_HEAD;
- const PyUpb_GenericSequence_Funcs* funcs;
- const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
- PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
- int index; // Current iterator index.
- } PyUpb_DescriptorIterator;
- PyUpb_DescriptorIterator* PyUpb_DescriptorIterator_Self(PyObject* obj) {
- assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->descriptor_iterator_type);
- return (PyUpb_DescriptorIterator*)obj;
- }
- static void PyUpb_DescriptorIterator_Dealloc(PyObject* _self) {
- PyUpb_DescriptorIterator* self = PyUpb_DescriptorIterator_Self(_self);
- Py_DECREF(self->parent_obj);
- PyUpb_Dealloc(self);
- }
- PyObject* PyUpb_DescriptorIterator_New(const PyUpb_GenericSequence_Funcs* funcs,
- const void* parent,
- PyObject* parent_obj) {
- PyUpb_ModuleState* s = PyUpb_ModuleState_Get();
- PyUpb_DescriptorIterator* iter =
- (void*)PyType_GenericAlloc(s->descriptor_iterator_type, 0);
- iter->funcs = funcs;
- iter->parent = parent;
- iter->parent_obj = parent_obj;
- iter->index = 0;
- Py_INCREF(iter->parent_obj);
- return &iter->ob_base;
- }
- PyObject* PyUpb_DescriptorIterator_IterNext(PyObject* _self) {
- PyUpb_DescriptorIterator* self = PyUpb_DescriptorIterator_Self(_self);
- int size = self->funcs->get_elem_count(self->parent);
- if (self->index >= size) return NULL;
- const void* elem = self->funcs->index(self->parent, self->index);
- self->index++;
- return self->funcs->get_elem_wrapper(elem);
- }
- static PyType_Slot PyUpb_DescriptorIterator_Slots[] = {
- {Py_tp_dealloc, PyUpb_DescriptorIterator_Dealloc},
- {Py_tp_iter, PyObject_SelfIter},
- {Py_tp_iternext, PyUpb_DescriptorIterator_IterNext},
- {0, NULL}};
- static PyType_Spec PyUpb_DescriptorIterator_Spec = {
- PYUPB_MODULE_NAME ".DescriptorIterator", // tp_name
- sizeof(PyUpb_DescriptorIterator), // tp_basicsize
- 0, // tp_itemsize
- Py_TPFLAGS_DEFAULT, // tp_flags
- PyUpb_DescriptorIterator_Slots,
- };
- // -----------------------------------------------------------------------------
- // GenericSequence
- // -----------------------------------------------------------------------------
- typedef struct {
- PyObject_HEAD;
- const PyUpb_GenericSequence_Funcs* funcs;
- const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
- PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
- } PyUpb_GenericSequence;
- PyUpb_GenericSequence* PyUpb_GenericSequence_Self(PyObject* obj) {
- assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->generic_sequence_type);
- return (PyUpb_GenericSequence*)obj;
- }
- static void PyUpb_GenericSequence_Dealloc(PyObject* _self) {
- PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
- Py_CLEAR(self->parent_obj);
- PyUpb_Dealloc(self);
- }
- PyObject* PyUpb_GenericSequence_New(const PyUpb_GenericSequence_Funcs* funcs,
- const void* parent, PyObject* parent_obj) {
- PyUpb_ModuleState* s = PyUpb_ModuleState_Get();
- PyUpb_GenericSequence* seq =
- (PyUpb_GenericSequence*)PyType_GenericAlloc(s->generic_sequence_type, 0);
- seq->funcs = funcs;
- seq->parent = parent;
- seq->parent_obj = parent_obj;
- Py_INCREF(parent_obj);
- return &seq->ob_base;
- }
- static Py_ssize_t PyUpb_GenericSequence_Length(PyObject* _self) {
- PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
- return self->funcs->get_elem_count(self->parent);
- }
- static PyObject* PyUpb_GenericSequence_GetItem(PyObject* _self,
- Py_ssize_t index) {
- PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
- Py_ssize_t size = self->funcs->get_elem_count(self->parent);
- if (index < 0 || index >= size) {
- PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index);
- return NULL;
- }
- const void* elem = self->funcs->index(self->parent, index);
- return self->funcs->get_elem_wrapper(elem);
- }
- // 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 PyUpb_GenericSequence_IsEqual(PyUpb_GenericSequence* self,
- PyObject* other) {
- // Check the identity of C++ pointers.
- if (PyObject_TypeCheck(other, Py_TYPE(self))) {
- PyUpb_GenericSequence* other_seq = (void*)other;
- return self->parent == other_seq->parent && self->funcs == other_seq->funcs;
- }
- if (!PyList_Check(other)) return 0;
- // return list(self) == other
- // We can clamp `i` to int because GenericSequence uses int for size (this
- // is useful when we do int iteration below).
- int n = PyUpb_GenericSequence_Length((PyObject*)self);
- if ((Py_ssize_t)n != PyList_Size(other)) {
- return false;
- }
- PyObject* item1;
- for (int i = 0; i < n; i++) {
- item1 = PyUpb_GenericSequence_GetItem((PyObject*)self, i);
- PyObject* item2 = PyList_GetItem(other, i);
- if (!item1 || !item2) goto error;
- int cmp = PyObject_RichCompareBool(item1, item2, Py_EQ);
- Py_DECREF(item1);
- if (cmp != 1) return cmp;
- }
- // All items were found and equal
- return 1;
- error:
- Py_XDECREF(item1);
- return -1;
- }
- static PyObject* PyUpb_GenericSequence_RichCompare(PyObject* _self,
- PyObject* other, int opid) {
- PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
- if (opid != Py_EQ && opid != Py_NE) {
- Py_RETURN_NOTIMPLEMENTED;
- }
- bool ret = PyUpb_GenericSequence_IsEqual(self, other);
- if (opid == Py_NE) ret = !ret;
- return PyBool_FromLong(ret);
- }
- // Linear search. Could optimize this in some cases (defs that have index),
- // but not all (FileDescriptor.dependencies).
- static int PyUpb_GenericSequence_Find(PyObject* _self, PyObject* item) {
- PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
- const void* item_ptr = PyUpb_AnyDescriptor_GetDef(item);
- int count = self->funcs->get_elem_count(self->parent);
- for (int i = 0; i < count; i++) {
- if (self->funcs->index(self->parent, i) == item_ptr) {
- return i;
- }
- }
- return -1;
- }
- static PyObject* PyUpb_GenericSequence_Index(PyObject* self, PyObject* item) {
- int position = PyUpb_GenericSequence_Find(self, item);
- if (position < 0) {
- PyErr_SetNone(PyExc_ValueError);
- return NULL;
- } else {
- return PyLong_FromLong(position);
- }
- }
- static PyObject* PyUpb_GenericSequence_Count(PyObject* _self, PyObject* item) {
- PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
- const void* item_ptr = PyUpb_AnyDescriptor_GetDef(item);
- int n = self->funcs->get_elem_count(self->parent);
- int count = 0;
- for (int i = 0; i < n; i++) {
- if (self->funcs->index(self->parent, i) == item_ptr) {
- count++;
- }
- }
- return PyLong_FromLong(count);
- }
- static PyObject* PyUpb_GenericSequence_Append(PyObject* self, PyObject* args) {
- PyErr_Format(PyExc_TypeError, "'%R' is not a mutable sequence", self);
- return NULL;
- }
- static PyMethodDef PyUpb_GenericSequence_Methods[] = {
- {"index", PyUpb_GenericSequence_Index, METH_O},
- {"count", PyUpb_GenericSequence_Count, METH_O},
- {"append", PyUpb_GenericSequence_Append, METH_O},
- // This was implemented for Python/C++ but so far has not been required.
- //{ "__reversed__", (PyCFunction)Reversed, METH_NOARGS, },
- {NULL}};
- static PyType_Slot PyUpb_GenericSequence_Slots[] = {
- {Py_tp_dealloc, &PyUpb_GenericSequence_Dealloc},
- {Py_tp_methods, &PyUpb_GenericSequence_Methods},
- {Py_sq_length, PyUpb_GenericSequence_Length},
- {Py_sq_item, PyUpb_GenericSequence_GetItem},
- {Py_tp_richcompare, &PyUpb_GenericSequence_RichCompare},
- // These were implemented for Python/C++ but so far have not been required.
- // {Py_tp_repr, &PyUpb_GenericSequence_Repr},
- // {Py_sq_contains, PyUpb_GenericSequence_Contains},
- // {Py_mp_subscript, PyUpb_GenericSequence_Subscript},
- // {Py_mp_ass_subscript, PyUpb_GenericSequence_AssignSubscript},
- {0, NULL},
- };
- static PyType_Spec PyUpb_GenericSequence_Spec = {
- PYUPB_MODULE_NAME "._GenericSequence", // tp_name
- sizeof(PyUpb_GenericSequence), // tp_basicsize
- 0, // tp_itemsize
- Py_TPFLAGS_DEFAULT, // tp_flags
- PyUpb_GenericSequence_Slots,
- };
- // -----------------------------------------------------------------------------
- // ByNameMap
- // -----------------------------------------------------------------------------
- typedef struct {
- PyObject_HEAD;
- const PyUpb_ByNameMap_Funcs* funcs;
- const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
- PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
- } PyUpb_ByNameMap;
- PyUpb_ByNameMap* PyUpb_ByNameMap_Self(PyObject* obj) {
- assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->by_name_map_type);
- return (PyUpb_ByNameMap*)obj;
- }
- static void PyUpb_ByNameMap_Dealloc(PyObject* _self) {
- PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
- Py_DECREF(self->parent_obj);
- PyUpb_Dealloc(self);
- }
- PyObject* PyUpb_ByNameMap_New(const PyUpb_ByNameMap_Funcs* funcs,
- const void* parent, PyObject* parent_obj) {
- PyUpb_ModuleState* s = PyUpb_ModuleState_Get();
- PyUpb_ByNameMap* map = (void*)PyType_GenericAlloc(s->by_name_map_type, 0);
- map->funcs = funcs;
- map->parent = parent;
- map->parent_obj = parent_obj;
- Py_INCREF(parent_obj);
- return &map->ob_base;
- }
- static Py_ssize_t PyUpb_ByNameMap_Length(PyObject* _self) {
- PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
- return self->funcs->base.get_elem_count(self->parent);
- }
- static PyObject* PyUpb_ByNameMap_Subscript(PyObject* _self, PyObject* key) {
- PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
- const char* name = PyUpb_GetStrData(key);
- const void* elem = name ? self->funcs->lookup(self->parent, name) : NULL;
- if (elem) {
- return self->funcs->base.get_elem_wrapper(elem);
- } else {
- PyErr_SetObject(PyExc_KeyError, key);
- return NULL;
- }
- }
- static int PyUpb_ByNameMap_AssignSubscript(PyObject* self, PyObject* key,
- PyObject* value) {
- PyErr_Format(PyExc_TypeError, PYUPB_MODULE_NAME
- ".ByNameMap' object does not support item assignment");
- return -1;
- }
- static int PyUpb_ByNameMap_Contains(PyObject* _self, PyObject* key) {
- PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
- const char* name = PyUpb_GetStrData(key);
- const void* elem = name ? self->funcs->lookup(self->parent, name) : NULL;
- return elem ? 1 : 0;
- }
- static PyObject* PyUpb_ByNameMap_Get(PyObject* _self, PyObject* args) {
- PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
- PyObject* key;
- PyObject* default_value = Py_None;
- if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
- return NULL;
- }
- const char* name = PyUpb_GetStrData(key);
- const void* elem = name ? self->funcs->lookup(self->parent, name) : NULL;
- if (elem) {
- return self->funcs->base.get_elem_wrapper(elem);
- } else {
- Py_INCREF(default_value);
- return default_value;
- }
- }
- static PyObject* PyUpb_ByNameMap_GetIter(PyObject* _self) {
- PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
- return PyUpb_DescriptorIterator_New(&self->funcs->base, self->parent,
- self->parent_obj);
- }
- static PyObject* PyUpb_ByNameMap_Keys(PyObject* _self, PyObject* args) {
- PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
- int n = self->funcs->base.get_elem_count(self->parent);
- PyObject* ret = PyList_New(n);
- if (!ret) return NULL;
- for (int i = 0; i < n; i++) {
- const void* elem = self->funcs->base.index(self->parent, i);
- PyObject* key = PyUnicode_FromString(self->funcs->get_elem_name(elem));
- if (!key) goto error;
- PyList_SetItem(ret, i, key);
- }
- return ret;
- error:
- Py_XDECREF(ret);
- return NULL;
- }
- static PyObject* PyUpb_ByNameMap_Values(PyObject* _self, PyObject* args) {
- PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
- int n = self->funcs->base.get_elem_count(self->parent);
- PyObject* ret = PyList_New(n);
- if (!ret) return NULL;
- for (int i = 0; i < n; i++) {
- const void* elem = self->funcs->base.index(self->parent, i);
- PyObject* py_elem = self->funcs->base.get_elem_wrapper(elem);
- if (!py_elem) goto error;
- PyList_SetItem(ret, i, py_elem);
- }
- return ret;
- error:
- Py_XDECREF(ret);
- return NULL;
- }
- static PyObject* PyUpb_ByNameMap_Items(PyObject* _self, PyObject* args) {
- PyUpb_ByNameMap* self = (PyUpb_ByNameMap*)_self;
- int n = self->funcs->base.get_elem_count(self->parent);
- PyObject* ret = PyList_New(n);
- PyObject* item;
- PyObject* py_elem;
- if (!ret) return NULL;
- for (int i = 0; i < n; i++) {
- const void* elem = self->funcs->base.index(self->parent, i);
- item = PyTuple_New(2);
- py_elem = self->funcs->base.get_elem_wrapper(elem);
- if (!item || !py_elem) goto error;
- PyTuple_SetItem(item, 0,
- PyUnicode_FromString(self->funcs->get_elem_name(elem)));
- PyTuple_SetItem(item, 1, py_elem);
- PyList_SetItem(ret, i, item);
- }
- return ret;
- error:
- Py_XDECREF(py_elem);
- Py_XDECREF(item);
- Py_XDECREF(ret);
- return NULL;
- }
- // 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 PyUpb_ByNameMap_IsEqual(PyUpb_ByNameMap* self, PyObject* other) {
- // Check the identity of C++ pointers.
- if (PyObject_TypeCheck(other, Py_TYPE(self))) {
- PyUpb_ByNameMap* other_map = (void*)other;
- return self->parent == other_map->parent && self->funcs == other_map->funcs;
- }
- if (!PyDict_Check(other)) return 0;
- PyObject* self_dict = PyDict_New();
- PyDict_Merge(self_dict, (PyObject*)self, 0);
- int eq = PyObject_RichCompareBool(self_dict, other, Py_EQ);
- Py_DECREF(self_dict);
- return eq;
- }
- static PyObject* PyUpb_ByNameMap_RichCompare(PyObject* _self, PyObject* other,
- int opid) {
- PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
- if (opid != Py_EQ && opid != Py_NE) {
- Py_RETURN_NOTIMPLEMENTED;
- }
- bool ret = PyUpb_ByNameMap_IsEqual(self, other);
- if (opid == Py_NE) ret = !ret;
- return PyBool_FromLong(ret);
- }
- static PyMethodDef PyUpb_ByNameMap_Methods[] = {
- {"get", (PyCFunction)&PyUpb_ByNameMap_Get, METH_VARARGS},
- {"keys", PyUpb_ByNameMap_Keys, METH_NOARGS},
- {"values", PyUpb_ByNameMap_Values, METH_NOARGS},
- {"items", PyUpb_ByNameMap_Items, METH_NOARGS},
- {NULL}};
- static PyType_Slot PyUpb_ByNameMap_Slots[] = {
- {Py_mp_ass_subscript, PyUpb_ByNameMap_AssignSubscript},
- {Py_mp_length, PyUpb_ByNameMap_Length},
- {Py_mp_subscript, PyUpb_ByNameMap_Subscript},
- {Py_sq_contains, &PyUpb_ByNameMap_Contains},
- {Py_tp_dealloc, &PyUpb_ByNameMap_Dealloc},
- {Py_tp_iter, PyUpb_ByNameMap_GetIter},
- {Py_tp_methods, &PyUpb_ByNameMap_Methods},
- {Py_tp_richcompare, &PyUpb_ByNameMap_RichCompare},
- {0, NULL},
- };
- static PyType_Spec PyUpb_ByNameMap_Spec = {
- PYUPB_MODULE_NAME "._ByNameMap", // tp_name
- sizeof(PyUpb_ByNameMap), // tp_basicsize
- 0, // tp_itemsize
- Py_TPFLAGS_DEFAULT, // tp_flags
- PyUpb_ByNameMap_Slots,
- };
- // -----------------------------------------------------------------------------
- // ByNumberMap
- // -----------------------------------------------------------------------------
- typedef struct {
- PyObject_HEAD;
- const PyUpb_ByNumberMap_Funcs* funcs;
- const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
- PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
- } PyUpb_ByNumberMap;
- PyUpb_ByNumberMap* PyUpb_ByNumberMap_Self(PyObject* obj) {
- assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->by_number_map_type);
- return (PyUpb_ByNumberMap*)obj;
- }
- PyObject* PyUpb_ByNumberMap_New(const PyUpb_ByNumberMap_Funcs* funcs,
- const void* parent, PyObject* parent_obj) {
- PyUpb_ModuleState* s = PyUpb_ModuleState_Get();
- PyUpb_ByNumberMap* map = (void*)PyType_GenericAlloc(s->by_number_map_type, 0);
- map->funcs = funcs;
- map->parent = parent;
- map->parent_obj = parent_obj;
- Py_INCREF(parent_obj);
- return &map->ob_base;
- }
- static void PyUpb_ByNumberMap_Dealloc(PyObject* _self) {
- PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
- Py_DECREF(self->parent_obj);
- PyUpb_Dealloc(self);
- }
- static Py_ssize_t PyUpb_ByNumberMap_Length(PyObject* _self) {
- PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
- return self->funcs->base.get_elem_count(self->parent);
- }
- static const void* PyUpb_ByNumberMap_LookupHelper(PyUpb_ByNumberMap* self,
- PyObject* key) {
- long num = PyLong_AsLong(key);
- if (num == -1 && PyErr_Occurred()) {
- PyErr_Clear();
- return NULL;
- } else {
- return self->funcs->lookup(self->parent, num);
- }
- }
- static PyObject* PyUpb_ByNumberMap_Subscript(PyObject* _self, PyObject* key) {
- PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
- const void* elem = PyUpb_ByNumberMap_LookupHelper(self, key);
- if (elem) {
- return self->funcs->base.get_elem_wrapper(elem);
- } else {
- PyErr_SetObject(PyExc_KeyError, key);
- return NULL;
- }
- }
- static int PyUpb_ByNumberMap_AssignSubscript(PyObject* self, PyObject* key,
- PyObject* value) {
- PyErr_Format(PyExc_TypeError, PYUPB_MODULE_NAME
- ".ByNumberMap' object does not support item assignment");
- return -1;
- }
- static PyObject* PyUpb_ByNumberMap_Get(PyObject* _self, PyObject* args) {
- PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
- PyObject* key;
- PyObject* default_value = Py_None;
- if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
- return NULL;
- }
- const void* elem = PyUpb_ByNumberMap_LookupHelper(self, key);
- if (elem) {
- return self->funcs->base.get_elem_wrapper(elem);
- } else {
- return PyUpb_NewRef(default_value);
- }
- }
- static PyObject* PyUpb_ByNumberMap_GetIter(PyObject* _self) {
- PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
- return PyUpb_DescriptorIterator_New(&self->funcs->base, self->parent,
- self->parent_obj);
- }
- static PyObject* PyUpb_ByNumberMap_Keys(PyObject* _self, PyObject* args) {
- PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
- int n = self->funcs->base.get_elem_count(self->parent);
- PyObject* ret = PyList_New(n);
- if (!ret) return NULL;
- for (int i = 0; i < n; i++) {
- const void* elem = self->funcs->base.index(self->parent, i);
- PyObject* key = PyLong_FromLong(self->funcs->get_elem_num(elem));
- if (!key) goto error;
- PyList_SetItem(ret, i, key);
- }
- return ret;
- error:
- Py_XDECREF(ret);
- return NULL;
- }
- static PyObject* PyUpb_ByNumberMap_Values(PyObject* _self, PyObject* args) {
- PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
- int n = self->funcs->base.get_elem_count(self->parent);
- PyObject* ret = PyList_New(n);
- if (!ret) return NULL;
- for (int i = 0; i < n; i++) {
- const void* elem = self->funcs->base.index(self->parent, i);
- PyObject* py_elem = self->funcs->base.get_elem_wrapper(elem);
- if (!py_elem) goto error;
- PyList_SetItem(ret, i, py_elem);
- }
- return ret;
- error:
- Py_XDECREF(ret);
- return NULL;
- }
- static PyObject* PyUpb_ByNumberMap_Items(PyObject* _self, PyObject* args) {
- PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
- int n = self->funcs->base.get_elem_count(self->parent);
- PyObject* ret = PyList_New(n);
- PyObject* item;
- PyObject* py_elem;
- if (!ret) return NULL;
- for (int i = 0; i < n; i++) {
- const void* elem = self->funcs->base.index(self->parent, i);
- int number = self->funcs->get_elem_num(elem);
- item = PyTuple_New(2);
- py_elem = self->funcs->base.get_elem_wrapper(elem);
- if (!item || !py_elem) goto error;
- PyTuple_SetItem(item, 0, PyLong_FromLong(number));
- PyTuple_SetItem(item, 1, py_elem);
- PyList_SetItem(ret, i, item);
- }
- return ret;
- error:
- Py_XDECREF(py_elem);
- Py_XDECREF(item);
- Py_XDECREF(ret);
- return NULL;
- }
- static int PyUpb_ByNumberMap_Contains(PyObject* _self, PyObject* key) {
- PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
- const void* elem = PyUpb_ByNumberMap_LookupHelper(self, key);
- return elem ? 1 : 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 PyUpb_ByNumberMap_IsEqual(PyUpb_ByNumberMap* self, PyObject* other) {
- // Check the identity of C++ pointers.
- if (PyObject_TypeCheck(other, Py_TYPE(self))) {
- PyUpb_ByNumberMap* other_map = (void*)other;
- return self->parent == other_map->parent && self->funcs == other_map->funcs;
- }
- if (!PyDict_Check(other)) return 0;
- PyObject* self_dict = PyDict_New();
- PyDict_Merge(self_dict, (PyObject*)self, 0);
- int eq = PyObject_RichCompareBool(self_dict, other, Py_EQ);
- Py_DECREF(self_dict);
- return eq;
- }
- static PyObject* PyUpb_ByNumberMap_RichCompare(PyObject* _self, PyObject* other,
- int opid) {
- PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
- if (opid != Py_EQ && opid != Py_NE) {
- Py_RETURN_NOTIMPLEMENTED;
- }
- bool ret = PyUpb_ByNumberMap_IsEqual(self, other);
- if (opid == Py_NE) ret = !ret;
- return PyBool_FromLong(ret);
- }
- static PyMethodDef PyUpb_ByNumberMap_Methods[] = {
- {"get", (PyCFunction)&PyUpb_ByNumberMap_Get, METH_VARARGS},
- {"keys", PyUpb_ByNumberMap_Keys, METH_NOARGS},
- {"values", PyUpb_ByNumberMap_Values, METH_NOARGS},
- {"items", PyUpb_ByNumberMap_Items, METH_NOARGS},
- {NULL}};
- static PyType_Slot PyUpb_ByNumberMap_Slots[] = {
- {Py_mp_ass_subscript, PyUpb_ByNumberMap_AssignSubscript},
- {Py_mp_length, PyUpb_ByNumberMap_Length},
- {Py_mp_subscript, PyUpb_ByNumberMap_Subscript},
- {Py_sq_contains, &PyUpb_ByNumberMap_Contains},
- {Py_tp_dealloc, &PyUpb_ByNumberMap_Dealloc},
- {Py_tp_iter, PyUpb_ByNumberMap_GetIter},
- {Py_tp_methods, &PyUpb_ByNumberMap_Methods},
- {Py_tp_richcompare, &PyUpb_ByNumberMap_RichCompare},
- {0, NULL},
- };
- static PyType_Spec PyUpb_ByNumberMap_Spec = {
- PYUPB_MODULE_NAME "._ByNumberMap", // tp_name
- sizeof(PyUpb_ByNumberMap), // tp_basicsize
- 0, // tp_itemsize
- Py_TPFLAGS_DEFAULT, // tp_flags
- PyUpb_ByNumberMap_Slots,
- };
- // -----------------------------------------------------------------------------
- // Top Level
- // -----------------------------------------------------------------------------
- bool PyUpb_InitDescriptorContainers(PyObject* m) {
- PyUpb_ModuleState* s = PyUpb_ModuleState_GetFromModule(m);
- s->by_name_map_type = PyUpb_AddClass(m, &PyUpb_ByNameMap_Spec);
- s->by_number_map_type = PyUpb_AddClass(m, &PyUpb_ByNumberMap_Spec);
- s->descriptor_iterator_type =
- PyUpb_AddClass(m, &PyUpb_DescriptorIterator_Spec);
- s->generic_sequence_type = PyUpb_AddClass(m, &PyUpb_GenericSequence_Spec);
- return s->by_name_map_type && s->by_number_map_type &&
- s->descriptor_iterator_type && s->generic_sequence_type;
- }
|