descriptor_containers.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. /*
  2. * Copyright (c) 2009-2021, Google LLC
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of Google LLC nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
  20. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "descriptor_containers.h"
  28. #include "descriptor.h"
  29. #include "protobuf.h"
  30. #include "upb/def.h"
  31. // -----------------------------------------------------------------------------
  32. // DescriptorIterator
  33. // -----------------------------------------------------------------------------
  34. typedef struct {
  35. PyObject_HEAD;
  36. const PyUpb_GenericSequence_Funcs* funcs;
  37. const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
  38. PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
  39. int index; // Current iterator index.
  40. } PyUpb_DescriptorIterator;
  41. PyUpb_DescriptorIterator* PyUpb_DescriptorIterator_Self(PyObject* obj) {
  42. assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->descriptor_iterator_type);
  43. return (PyUpb_DescriptorIterator*)obj;
  44. }
  45. static void PyUpb_DescriptorIterator_Dealloc(PyObject* _self) {
  46. PyUpb_DescriptorIterator* self = PyUpb_DescriptorIterator_Self(_self);
  47. Py_DECREF(self->parent_obj);
  48. PyUpb_Dealloc(self);
  49. }
  50. PyObject* PyUpb_DescriptorIterator_New(const PyUpb_GenericSequence_Funcs* funcs,
  51. const void* parent,
  52. PyObject* parent_obj) {
  53. PyUpb_ModuleState* s = PyUpb_ModuleState_Get();
  54. PyUpb_DescriptorIterator* iter =
  55. (void*)PyType_GenericAlloc(s->descriptor_iterator_type, 0);
  56. iter->funcs = funcs;
  57. iter->parent = parent;
  58. iter->parent_obj = parent_obj;
  59. iter->index = 0;
  60. Py_INCREF(iter->parent_obj);
  61. return &iter->ob_base;
  62. }
  63. PyObject* PyUpb_DescriptorIterator_IterNext(PyObject* _self) {
  64. PyUpb_DescriptorIterator* self = PyUpb_DescriptorIterator_Self(_self);
  65. int size = self->funcs->get_elem_count(self->parent);
  66. if (self->index >= size) return NULL;
  67. const void* elem = self->funcs->index(self->parent, self->index);
  68. self->index++;
  69. return self->funcs->get_elem_wrapper(elem);
  70. }
  71. static PyType_Slot PyUpb_DescriptorIterator_Slots[] = {
  72. {Py_tp_dealloc, PyUpb_DescriptorIterator_Dealloc},
  73. {Py_tp_iter, PyObject_SelfIter},
  74. {Py_tp_iternext, PyUpb_DescriptorIterator_IterNext},
  75. {0, NULL}};
  76. static PyType_Spec PyUpb_DescriptorIterator_Spec = {
  77. PYUPB_MODULE_NAME ".DescriptorIterator", // tp_name
  78. sizeof(PyUpb_DescriptorIterator), // tp_basicsize
  79. 0, // tp_itemsize
  80. Py_TPFLAGS_DEFAULT, // tp_flags
  81. PyUpb_DescriptorIterator_Slots,
  82. };
  83. // -----------------------------------------------------------------------------
  84. // GenericSequence
  85. // -----------------------------------------------------------------------------
  86. typedef struct {
  87. PyObject_HEAD;
  88. const PyUpb_GenericSequence_Funcs* funcs;
  89. const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
  90. PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
  91. } PyUpb_GenericSequence;
  92. PyUpb_GenericSequence* PyUpb_GenericSequence_Self(PyObject* obj) {
  93. assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->generic_sequence_type);
  94. return (PyUpb_GenericSequence*)obj;
  95. }
  96. static void PyUpb_GenericSequence_Dealloc(PyObject* _self) {
  97. PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
  98. Py_CLEAR(self->parent_obj);
  99. PyUpb_Dealloc(self);
  100. }
  101. PyObject* PyUpb_GenericSequence_New(const PyUpb_GenericSequence_Funcs* funcs,
  102. const void* parent, PyObject* parent_obj) {
  103. PyUpb_ModuleState* s = PyUpb_ModuleState_Get();
  104. PyUpb_GenericSequence* seq =
  105. (PyUpb_GenericSequence*)PyType_GenericAlloc(s->generic_sequence_type, 0);
  106. seq->funcs = funcs;
  107. seq->parent = parent;
  108. seq->parent_obj = parent_obj;
  109. Py_INCREF(parent_obj);
  110. return &seq->ob_base;
  111. }
  112. static Py_ssize_t PyUpb_GenericSequence_Length(PyObject* _self) {
  113. PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
  114. return self->funcs->get_elem_count(self->parent);
  115. }
  116. static PyObject* PyUpb_GenericSequence_GetItem(PyObject* _self,
  117. Py_ssize_t index) {
  118. PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
  119. Py_ssize_t size = self->funcs->get_elem_count(self->parent);
  120. if (index < 0 || index >= size) {
  121. PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index);
  122. return NULL;
  123. }
  124. const void* elem = self->funcs->index(self->parent, index);
  125. return self->funcs->get_elem_wrapper(elem);
  126. }
  127. // A sequence container can only be equal to another sequence container, or (for
  128. // backward compatibility) to a list containing the same items.
  129. // Returns 1 if equal, 0 if unequal, -1 on error.
  130. static int PyUpb_GenericSequence_IsEqual(PyUpb_GenericSequence* self,
  131. PyObject* other) {
  132. // Check the identity of C++ pointers.
  133. if (PyObject_TypeCheck(other, Py_TYPE(self))) {
  134. PyUpb_GenericSequence* other_seq = (void*)other;
  135. return self->parent == other_seq->parent && self->funcs == other_seq->funcs;
  136. }
  137. if (!PyList_Check(other)) return 0;
  138. // return list(self) == other
  139. // We can clamp `i` to int because GenericSequence uses int for size (this
  140. // is useful when we do int iteration below).
  141. int n = PyUpb_GenericSequence_Length((PyObject*)self);
  142. if ((Py_ssize_t)n != PyList_Size(other)) {
  143. return false;
  144. }
  145. PyObject* item1;
  146. for (int i = 0; i < n; i++) {
  147. item1 = PyUpb_GenericSequence_GetItem((PyObject*)self, i);
  148. PyObject* item2 = PyList_GetItem(other, i);
  149. if (!item1 || !item2) goto error;
  150. int cmp = PyObject_RichCompareBool(item1, item2, Py_EQ);
  151. Py_DECREF(item1);
  152. if (cmp != 1) return cmp;
  153. }
  154. // All items were found and equal
  155. return 1;
  156. error:
  157. Py_XDECREF(item1);
  158. return -1;
  159. }
  160. static PyObject* PyUpb_GenericSequence_RichCompare(PyObject* _self,
  161. PyObject* other, int opid) {
  162. PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
  163. if (opid != Py_EQ && opid != Py_NE) {
  164. Py_RETURN_NOTIMPLEMENTED;
  165. }
  166. bool ret = PyUpb_GenericSequence_IsEqual(self, other);
  167. if (opid == Py_NE) ret = !ret;
  168. return PyBool_FromLong(ret);
  169. }
  170. // Linear search. Could optimize this in some cases (defs that have index),
  171. // but not all (FileDescriptor.dependencies).
  172. static int PyUpb_GenericSequence_Find(PyObject* _self, PyObject* item) {
  173. PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
  174. const void* item_ptr = PyUpb_AnyDescriptor_GetDef(item);
  175. int count = self->funcs->get_elem_count(self->parent);
  176. for (int i = 0; i < count; i++) {
  177. if (self->funcs->index(self->parent, i) == item_ptr) {
  178. return i;
  179. }
  180. }
  181. return -1;
  182. }
  183. static PyObject* PyUpb_GenericSequence_Index(PyObject* self, PyObject* item) {
  184. int position = PyUpb_GenericSequence_Find(self, item);
  185. if (position < 0) {
  186. PyErr_SetNone(PyExc_ValueError);
  187. return NULL;
  188. } else {
  189. return PyLong_FromLong(position);
  190. }
  191. }
  192. static PyObject* PyUpb_GenericSequence_Count(PyObject* _self, PyObject* item) {
  193. PyUpb_GenericSequence* self = PyUpb_GenericSequence_Self(_self);
  194. const void* item_ptr = PyUpb_AnyDescriptor_GetDef(item);
  195. int n = self->funcs->get_elem_count(self->parent);
  196. int count = 0;
  197. for (int i = 0; i < n; i++) {
  198. if (self->funcs->index(self->parent, i) == item_ptr) {
  199. count++;
  200. }
  201. }
  202. return PyLong_FromLong(count);
  203. }
  204. static PyObject* PyUpb_GenericSequence_Append(PyObject* self, PyObject* args) {
  205. PyErr_Format(PyExc_TypeError, "'%R' is not a mutable sequence", self);
  206. return NULL;
  207. }
  208. static PyMethodDef PyUpb_GenericSequence_Methods[] = {
  209. {"index", PyUpb_GenericSequence_Index, METH_O},
  210. {"count", PyUpb_GenericSequence_Count, METH_O},
  211. {"append", PyUpb_GenericSequence_Append, METH_O},
  212. // This was implemented for Python/C++ but so far has not been required.
  213. //{ "__reversed__", (PyCFunction)Reversed, METH_NOARGS, },
  214. {NULL}};
  215. static PyType_Slot PyUpb_GenericSequence_Slots[] = {
  216. {Py_tp_dealloc, &PyUpb_GenericSequence_Dealloc},
  217. {Py_tp_methods, &PyUpb_GenericSequence_Methods},
  218. {Py_sq_length, PyUpb_GenericSequence_Length},
  219. {Py_sq_item, PyUpb_GenericSequence_GetItem},
  220. {Py_tp_richcompare, &PyUpb_GenericSequence_RichCompare},
  221. // These were implemented for Python/C++ but so far have not been required.
  222. // {Py_tp_repr, &PyUpb_GenericSequence_Repr},
  223. // {Py_sq_contains, PyUpb_GenericSequence_Contains},
  224. // {Py_mp_subscript, PyUpb_GenericSequence_Subscript},
  225. // {Py_mp_ass_subscript, PyUpb_GenericSequence_AssignSubscript},
  226. {0, NULL},
  227. };
  228. static PyType_Spec PyUpb_GenericSequence_Spec = {
  229. PYUPB_MODULE_NAME "._GenericSequence", // tp_name
  230. sizeof(PyUpb_GenericSequence), // tp_basicsize
  231. 0, // tp_itemsize
  232. Py_TPFLAGS_DEFAULT, // tp_flags
  233. PyUpb_GenericSequence_Slots,
  234. };
  235. // -----------------------------------------------------------------------------
  236. // ByNameMap
  237. // -----------------------------------------------------------------------------
  238. typedef struct {
  239. PyObject_HEAD;
  240. const PyUpb_ByNameMap_Funcs* funcs;
  241. const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
  242. PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
  243. } PyUpb_ByNameMap;
  244. PyUpb_ByNameMap* PyUpb_ByNameMap_Self(PyObject* obj) {
  245. assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->by_name_map_type);
  246. return (PyUpb_ByNameMap*)obj;
  247. }
  248. static void PyUpb_ByNameMap_Dealloc(PyObject* _self) {
  249. PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
  250. Py_DECREF(self->parent_obj);
  251. PyUpb_Dealloc(self);
  252. }
  253. PyObject* PyUpb_ByNameMap_New(const PyUpb_ByNameMap_Funcs* funcs,
  254. const void* parent, PyObject* parent_obj) {
  255. PyUpb_ModuleState* s = PyUpb_ModuleState_Get();
  256. PyUpb_ByNameMap* map = (void*)PyType_GenericAlloc(s->by_name_map_type, 0);
  257. map->funcs = funcs;
  258. map->parent = parent;
  259. map->parent_obj = parent_obj;
  260. Py_INCREF(parent_obj);
  261. return &map->ob_base;
  262. }
  263. static Py_ssize_t PyUpb_ByNameMap_Length(PyObject* _self) {
  264. PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
  265. return self->funcs->base.get_elem_count(self->parent);
  266. }
  267. static PyObject* PyUpb_ByNameMap_Subscript(PyObject* _self, PyObject* key) {
  268. PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
  269. const char* name = PyUpb_GetStrData(key);
  270. const void* elem = name ? self->funcs->lookup(self->parent, name) : NULL;
  271. if (elem) {
  272. return self->funcs->base.get_elem_wrapper(elem);
  273. } else {
  274. PyErr_SetObject(PyExc_KeyError, key);
  275. return NULL;
  276. }
  277. }
  278. static int PyUpb_ByNameMap_AssignSubscript(PyObject* self, PyObject* key,
  279. PyObject* value) {
  280. PyErr_Format(PyExc_TypeError, PYUPB_MODULE_NAME
  281. ".ByNameMap' object does not support item assignment");
  282. return -1;
  283. }
  284. static int PyUpb_ByNameMap_Contains(PyObject* _self, PyObject* key) {
  285. PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
  286. const char* name = PyUpb_GetStrData(key);
  287. const void* elem = name ? self->funcs->lookup(self->parent, name) : NULL;
  288. return elem ? 1 : 0;
  289. }
  290. static PyObject* PyUpb_ByNameMap_Get(PyObject* _self, PyObject* args) {
  291. PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
  292. PyObject* key;
  293. PyObject* default_value = Py_None;
  294. if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
  295. return NULL;
  296. }
  297. const char* name = PyUpb_GetStrData(key);
  298. const void* elem = name ? self->funcs->lookup(self->parent, name) : NULL;
  299. if (elem) {
  300. return self->funcs->base.get_elem_wrapper(elem);
  301. } else {
  302. Py_INCREF(default_value);
  303. return default_value;
  304. }
  305. }
  306. static PyObject* PyUpb_ByNameMap_GetIter(PyObject* _self) {
  307. PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
  308. return PyUpb_DescriptorIterator_New(&self->funcs->base, self->parent,
  309. self->parent_obj);
  310. }
  311. static PyObject* PyUpb_ByNameMap_Keys(PyObject* _self, PyObject* args) {
  312. PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
  313. int n = self->funcs->base.get_elem_count(self->parent);
  314. PyObject* ret = PyList_New(n);
  315. if (!ret) return NULL;
  316. for (int i = 0; i < n; i++) {
  317. const void* elem = self->funcs->base.index(self->parent, i);
  318. PyObject* key = PyUnicode_FromString(self->funcs->get_elem_name(elem));
  319. if (!key) goto error;
  320. PyList_SetItem(ret, i, key);
  321. }
  322. return ret;
  323. error:
  324. Py_XDECREF(ret);
  325. return NULL;
  326. }
  327. static PyObject* PyUpb_ByNameMap_Values(PyObject* _self, PyObject* args) {
  328. PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
  329. int n = self->funcs->base.get_elem_count(self->parent);
  330. PyObject* ret = PyList_New(n);
  331. if (!ret) return NULL;
  332. for (int i = 0; i < n; i++) {
  333. const void* elem = self->funcs->base.index(self->parent, i);
  334. PyObject* py_elem = self->funcs->base.get_elem_wrapper(elem);
  335. if (!py_elem) goto error;
  336. PyList_SetItem(ret, i, py_elem);
  337. }
  338. return ret;
  339. error:
  340. Py_XDECREF(ret);
  341. return NULL;
  342. }
  343. static PyObject* PyUpb_ByNameMap_Items(PyObject* _self, PyObject* args) {
  344. PyUpb_ByNameMap* self = (PyUpb_ByNameMap*)_self;
  345. int n = self->funcs->base.get_elem_count(self->parent);
  346. PyObject* ret = PyList_New(n);
  347. PyObject* item;
  348. PyObject* py_elem;
  349. if (!ret) return NULL;
  350. for (int i = 0; i < n; i++) {
  351. const void* elem = self->funcs->base.index(self->parent, i);
  352. item = PyTuple_New(2);
  353. py_elem = self->funcs->base.get_elem_wrapper(elem);
  354. if (!item || !py_elem) goto error;
  355. PyTuple_SetItem(item, 0,
  356. PyUnicode_FromString(self->funcs->get_elem_name(elem)));
  357. PyTuple_SetItem(item, 1, py_elem);
  358. PyList_SetItem(ret, i, item);
  359. }
  360. return ret;
  361. error:
  362. Py_XDECREF(py_elem);
  363. Py_XDECREF(item);
  364. Py_XDECREF(ret);
  365. return NULL;
  366. }
  367. // A mapping container can only be equal to another mapping container, or (for
  368. // backward compatibility) to a dict containing the same items.
  369. // Returns 1 if equal, 0 if unequal, -1 on error.
  370. static int PyUpb_ByNameMap_IsEqual(PyUpb_ByNameMap* self, PyObject* other) {
  371. // Check the identity of C++ pointers.
  372. if (PyObject_TypeCheck(other, Py_TYPE(self))) {
  373. PyUpb_ByNameMap* other_map = (void*)other;
  374. return self->parent == other_map->parent && self->funcs == other_map->funcs;
  375. }
  376. if (!PyDict_Check(other)) return 0;
  377. PyObject* self_dict = PyDict_New();
  378. PyDict_Merge(self_dict, (PyObject*)self, 0);
  379. int eq = PyObject_RichCompareBool(self_dict, other, Py_EQ);
  380. Py_DECREF(self_dict);
  381. return eq;
  382. }
  383. static PyObject* PyUpb_ByNameMap_RichCompare(PyObject* _self, PyObject* other,
  384. int opid) {
  385. PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
  386. if (opid != Py_EQ && opid != Py_NE) {
  387. Py_RETURN_NOTIMPLEMENTED;
  388. }
  389. bool ret = PyUpb_ByNameMap_IsEqual(self, other);
  390. if (opid == Py_NE) ret = !ret;
  391. return PyBool_FromLong(ret);
  392. }
  393. static PyMethodDef PyUpb_ByNameMap_Methods[] = {
  394. {"get", (PyCFunction)&PyUpb_ByNameMap_Get, METH_VARARGS},
  395. {"keys", PyUpb_ByNameMap_Keys, METH_NOARGS},
  396. {"values", PyUpb_ByNameMap_Values, METH_NOARGS},
  397. {"items", PyUpb_ByNameMap_Items, METH_NOARGS},
  398. {NULL}};
  399. static PyType_Slot PyUpb_ByNameMap_Slots[] = {
  400. {Py_mp_ass_subscript, PyUpb_ByNameMap_AssignSubscript},
  401. {Py_mp_length, PyUpb_ByNameMap_Length},
  402. {Py_mp_subscript, PyUpb_ByNameMap_Subscript},
  403. {Py_sq_contains, &PyUpb_ByNameMap_Contains},
  404. {Py_tp_dealloc, &PyUpb_ByNameMap_Dealloc},
  405. {Py_tp_iter, PyUpb_ByNameMap_GetIter},
  406. {Py_tp_methods, &PyUpb_ByNameMap_Methods},
  407. {Py_tp_richcompare, &PyUpb_ByNameMap_RichCompare},
  408. {0, NULL},
  409. };
  410. static PyType_Spec PyUpb_ByNameMap_Spec = {
  411. PYUPB_MODULE_NAME "._ByNameMap", // tp_name
  412. sizeof(PyUpb_ByNameMap), // tp_basicsize
  413. 0, // tp_itemsize
  414. Py_TPFLAGS_DEFAULT, // tp_flags
  415. PyUpb_ByNameMap_Slots,
  416. };
  417. // -----------------------------------------------------------------------------
  418. // ByNumberMap
  419. // -----------------------------------------------------------------------------
  420. typedef struct {
  421. PyObject_HEAD;
  422. const PyUpb_ByNumberMap_Funcs* funcs;
  423. const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
  424. PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
  425. } PyUpb_ByNumberMap;
  426. PyUpb_ByNumberMap* PyUpb_ByNumberMap_Self(PyObject* obj) {
  427. assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->by_number_map_type);
  428. return (PyUpb_ByNumberMap*)obj;
  429. }
  430. PyObject* PyUpb_ByNumberMap_New(const PyUpb_ByNumberMap_Funcs* funcs,
  431. const void* parent, PyObject* parent_obj) {
  432. PyUpb_ModuleState* s = PyUpb_ModuleState_Get();
  433. PyUpb_ByNumberMap* map = (void*)PyType_GenericAlloc(s->by_number_map_type, 0);
  434. map->funcs = funcs;
  435. map->parent = parent;
  436. map->parent_obj = parent_obj;
  437. Py_INCREF(parent_obj);
  438. return &map->ob_base;
  439. }
  440. static void PyUpb_ByNumberMap_Dealloc(PyObject* _self) {
  441. PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
  442. Py_DECREF(self->parent_obj);
  443. PyUpb_Dealloc(self);
  444. }
  445. static Py_ssize_t PyUpb_ByNumberMap_Length(PyObject* _self) {
  446. PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
  447. return self->funcs->base.get_elem_count(self->parent);
  448. }
  449. static const void* PyUpb_ByNumberMap_LookupHelper(PyUpb_ByNumberMap* self,
  450. PyObject* key) {
  451. long num = PyLong_AsLong(key);
  452. if (num == -1 && PyErr_Occurred()) {
  453. PyErr_Clear();
  454. return NULL;
  455. } else {
  456. return self->funcs->lookup(self->parent, num);
  457. }
  458. }
  459. static PyObject* PyUpb_ByNumberMap_Subscript(PyObject* _self, PyObject* key) {
  460. PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
  461. const void* elem = PyUpb_ByNumberMap_LookupHelper(self, key);
  462. if (elem) {
  463. return self->funcs->base.get_elem_wrapper(elem);
  464. } else {
  465. PyErr_SetObject(PyExc_KeyError, key);
  466. return NULL;
  467. }
  468. }
  469. static int PyUpb_ByNumberMap_AssignSubscript(PyObject* self, PyObject* key,
  470. PyObject* value) {
  471. PyErr_Format(PyExc_TypeError, PYUPB_MODULE_NAME
  472. ".ByNumberMap' object does not support item assignment");
  473. return -1;
  474. }
  475. static PyObject* PyUpb_ByNumberMap_Get(PyObject* _self, PyObject* args) {
  476. PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
  477. PyObject* key;
  478. PyObject* default_value = Py_None;
  479. if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
  480. return NULL;
  481. }
  482. const void* elem = PyUpb_ByNumberMap_LookupHelper(self, key);
  483. if (elem) {
  484. return self->funcs->base.get_elem_wrapper(elem);
  485. } else {
  486. return PyUpb_NewRef(default_value);
  487. }
  488. }
  489. static PyObject* PyUpb_ByNumberMap_GetIter(PyObject* _self) {
  490. PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
  491. return PyUpb_DescriptorIterator_New(&self->funcs->base, self->parent,
  492. self->parent_obj);
  493. }
  494. static PyObject* PyUpb_ByNumberMap_Keys(PyObject* _self, PyObject* args) {
  495. PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
  496. int n = self->funcs->base.get_elem_count(self->parent);
  497. PyObject* ret = PyList_New(n);
  498. if (!ret) return NULL;
  499. for (int i = 0; i < n; i++) {
  500. const void* elem = self->funcs->base.index(self->parent, i);
  501. PyObject* key = PyLong_FromLong(self->funcs->get_elem_num(elem));
  502. if (!key) goto error;
  503. PyList_SetItem(ret, i, key);
  504. }
  505. return ret;
  506. error:
  507. Py_XDECREF(ret);
  508. return NULL;
  509. }
  510. static PyObject* PyUpb_ByNumberMap_Values(PyObject* _self, PyObject* args) {
  511. PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
  512. int n = self->funcs->base.get_elem_count(self->parent);
  513. PyObject* ret = PyList_New(n);
  514. if (!ret) return NULL;
  515. for (int i = 0; i < n; i++) {
  516. const void* elem = self->funcs->base.index(self->parent, i);
  517. PyObject* py_elem = self->funcs->base.get_elem_wrapper(elem);
  518. if (!py_elem) goto error;
  519. PyList_SetItem(ret, i, py_elem);
  520. }
  521. return ret;
  522. error:
  523. Py_XDECREF(ret);
  524. return NULL;
  525. }
  526. static PyObject* PyUpb_ByNumberMap_Items(PyObject* _self, PyObject* args) {
  527. PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
  528. int n = self->funcs->base.get_elem_count(self->parent);
  529. PyObject* ret = PyList_New(n);
  530. PyObject* item;
  531. PyObject* py_elem;
  532. if (!ret) return NULL;
  533. for (int i = 0; i < n; i++) {
  534. const void* elem = self->funcs->base.index(self->parent, i);
  535. int number = self->funcs->get_elem_num(elem);
  536. item = PyTuple_New(2);
  537. py_elem = self->funcs->base.get_elem_wrapper(elem);
  538. if (!item || !py_elem) goto error;
  539. PyTuple_SetItem(item, 0, PyLong_FromLong(number));
  540. PyTuple_SetItem(item, 1, py_elem);
  541. PyList_SetItem(ret, i, item);
  542. }
  543. return ret;
  544. error:
  545. Py_XDECREF(py_elem);
  546. Py_XDECREF(item);
  547. Py_XDECREF(ret);
  548. return NULL;
  549. }
  550. static int PyUpb_ByNumberMap_Contains(PyObject* _self, PyObject* key) {
  551. PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
  552. const void* elem = PyUpb_ByNumberMap_LookupHelper(self, key);
  553. return elem ? 1 : 0;
  554. }
  555. // A mapping container can only be equal to another mapping container, or (for
  556. // backward compatibility) to a dict containing the same items.
  557. // Returns 1 if equal, 0 if unequal, -1 on error.
  558. static int PyUpb_ByNumberMap_IsEqual(PyUpb_ByNumberMap* self, PyObject* other) {
  559. // Check the identity of C++ pointers.
  560. if (PyObject_TypeCheck(other, Py_TYPE(self))) {
  561. PyUpb_ByNumberMap* other_map = (void*)other;
  562. return self->parent == other_map->parent && self->funcs == other_map->funcs;
  563. }
  564. if (!PyDict_Check(other)) return 0;
  565. PyObject* self_dict = PyDict_New();
  566. PyDict_Merge(self_dict, (PyObject*)self, 0);
  567. int eq = PyObject_RichCompareBool(self_dict, other, Py_EQ);
  568. Py_DECREF(self_dict);
  569. return eq;
  570. }
  571. static PyObject* PyUpb_ByNumberMap_RichCompare(PyObject* _self, PyObject* other,
  572. int opid) {
  573. PyUpb_ByNumberMap* self = PyUpb_ByNumberMap_Self(_self);
  574. if (opid != Py_EQ && opid != Py_NE) {
  575. Py_RETURN_NOTIMPLEMENTED;
  576. }
  577. bool ret = PyUpb_ByNumberMap_IsEqual(self, other);
  578. if (opid == Py_NE) ret = !ret;
  579. return PyBool_FromLong(ret);
  580. }
  581. static PyMethodDef PyUpb_ByNumberMap_Methods[] = {
  582. {"get", (PyCFunction)&PyUpb_ByNumberMap_Get, METH_VARARGS},
  583. {"keys", PyUpb_ByNumberMap_Keys, METH_NOARGS},
  584. {"values", PyUpb_ByNumberMap_Values, METH_NOARGS},
  585. {"items", PyUpb_ByNumberMap_Items, METH_NOARGS},
  586. {NULL}};
  587. static PyType_Slot PyUpb_ByNumberMap_Slots[] = {
  588. {Py_mp_ass_subscript, PyUpb_ByNumberMap_AssignSubscript},
  589. {Py_mp_length, PyUpb_ByNumberMap_Length},
  590. {Py_mp_subscript, PyUpb_ByNumberMap_Subscript},
  591. {Py_sq_contains, &PyUpb_ByNumberMap_Contains},
  592. {Py_tp_dealloc, &PyUpb_ByNumberMap_Dealloc},
  593. {Py_tp_iter, PyUpb_ByNumberMap_GetIter},
  594. {Py_tp_methods, &PyUpb_ByNumberMap_Methods},
  595. {Py_tp_richcompare, &PyUpb_ByNumberMap_RichCompare},
  596. {0, NULL},
  597. };
  598. static PyType_Spec PyUpb_ByNumberMap_Spec = {
  599. PYUPB_MODULE_NAME "._ByNumberMap", // tp_name
  600. sizeof(PyUpb_ByNumberMap), // tp_basicsize
  601. 0, // tp_itemsize
  602. Py_TPFLAGS_DEFAULT, // tp_flags
  603. PyUpb_ByNumberMap_Slots,
  604. };
  605. // -----------------------------------------------------------------------------
  606. // Top Level
  607. // -----------------------------------------------------------------------------
  608. bool PyUpb_InitDescriptorContainers(PyObject* m) {
  609. PyUpb_ModuleState* s = PyUpb_ModuleState_GetFromModule(m);
  610. s->by_name_map_type = PyUpb_AddClass(m, &PyUpb_ByNameMap_Spec);
  611. s->by_number_map_type = PyUpb_AddClass(m, &PyUpb_ByNumberMap_Spec);
  612. s->descriptor_iterator_type =
  613. PyUpb_AddClass(m, &PyUpb_DescriptorIterator_Spec);
  614. s->generic_sequence_type = PyUpb_AddClass(m, &PyUpb_GenericSequence_Spec);
  615. return s->by_name_map_type && s->by_number_map_type &&
  616. s->descriptor_iterator_type && s->generic_sequence_type;
  617. }