descriptor_containers.cc 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // Mappings and Sequences of descriptors.
  31. // Used by Descriptor.fields_by_name, EnumDescriptor.values...
  32. //
  33. // They avoid the allocation of a full dictionary or a full list: they simply
  34. // store a pointer to the parent descriptor, use the C++ Descriptor methods (see
  35. // google/protobuf/descriptor.h) to retrieve other descriptors, and create
  36. // Python objects on the fly.
  37. //
  38. // The containers fully conform to abc.Mapping and abc.Sequence, and behave just
  39. // like read-only dictionaries and lists.
  40. //
  41. // Because the interface of C++ Descriptors is quite regular, this file actually
  42. // defines only three types, the exact behavior of a container is controlled by
  43. // a DescriptorContainerDef structure, which contains functions that uses the
  44. // public Descriptor API.
  45. //
  46. // Note: This DescriptorContainerDef is similar to the "virtual methods table"
  47. // that a C++ compiler generates for a class. We have to make it explicit
  48. // because the Python API is based on C, and does not play well with C++
  49. // inheritance.
  50. #include <Python.h>
  51. #include <google/protobuf/descriptor.h>
  52. #include <google/protobuf/pyext/descriptor_containers.h>
  53. #include <google/protobuf/pyext/descriptor_pool.h>
  54. #include <google/protobuf/pyext/descriptor.h>
  55. #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
  56. #if PY_MAJOR_VERSION >= 3
  57. #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
  58. #define PyString_FromFormat PyUnicode_FromFormat
  59. #define PyInt_FromLong PyLong_FromLong
  60. #if PY_VERSION_HEX < 0x03030000
  61. #error "Python 3.0 - 3.2 are not supported."
  62. #endif
  63. #define PyString_AsStringAndSize(ob, charpp, sizep) \
  64. (PyUnicode_Check(ob)? \
  65. ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
  66. PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
  67. #endif
  68. namespace google {
  69. namespace protobuf {
  70. namespace python {
  71. struct PyContainer;
  72. typedef int (*CountMethod)(PyContainer* self);
  73. typedef const void* (*GetByIndexMethod)(PyContainer* self, int index);
  74. typedef const void* (*GetByNameMethod)(PyContainer* self, const string& name);
  75. typedef const void* (*GetByNumberMethod)(PyContainer* self, int index);
  76. typedef PyObject* (*NewObjectFromItemMethod)(const void* descriptor);
  77. typedef const string& (*GetItemNameMethod)(const void* descriptor);
  78. typedef int (*GetItemNumberMethod)(const void* descriptor);
  79. typedef int (*GetItemIndexMethod)(const void* descriptor);
  80. struct DescriptorContainerDef {
  81. const char* mapping_name;
  82. // Returns the number of items in the container.
  83. CountMethod count_fn;
  84. // Retrieve item by index (usually the order of declaration in the proto file)
  85. // Used by sequences, but also iterators. 0 <= index < Count().
  86. GetByIndexMethod get_by_index_fn;
  87. // Retrieve item by name (usually a call to some 'FindByName' method).
  88. // Used by "by_name" mappings.
  89. GetByNameMethod get_by_name_fn;
  90. // Retrieve item by declared number (field tag, or enum value).
  91. // Used by "by_number" mappings.
  92. GetByNumberMethod get_by_number_fn;
  93. // Converts a item C++ descriptor to a Python object. Returns a new reference.
  94. NewObjectFromItemMethod new_object_from_item_fn;
  95. // Retrieve the name of an item. Used by iterators on "by_name" mappings.
  96. GetItemNameMethod get_item_name_fn;
  97. // Retrieve the number of an item. Used by iterators on "by_number" mappings.
  98. GetItemNumberMethod get_item_number_fn;
  99. // Retrieve the index of an item for the container type.
  100. // Used by "__contains__".
  101. // If not set, "x in sequence" will do a linear search.
  102. GetItemIndexMethod get_item_index_fn;
  103. };
  104. struct PyContainer {
  105. PyObject_HEAD
  106. // The proto2 descriptor this container belongs to the global DescriptorPool.
  107. const void* descriptor;
  108. // A pointer to a static structure with function pointers that control the
  109. // behavior of the container. Very similar to the table of virtual functions
  110. // of a C++ class.
  111. const DescriptorContainerDef* container_def;
  112. // The kind of container: list, or dict by name or value.
  113. enum ContainerKind {
  114. KIND_SEQUENCE,
  115. KIND_BYNAME,
  116. KIND_BYNUMBER,
  117. } kind;
  118. };
  119. struct PyContainerIterator {
  120. PyObject_HEAD
  121. // The container we are iterating over. Own a reference.
  122. PyContainer* container;
  123. // The current index in the iterator.
  124. int index;
  125. // The kind of container: list, or dict by name or value.
  126. enum IterKind {
  127. KIND_ITERKEY,
  128. KIND_ITERVALUE,
  129. KIND_ITERITEM,
  130. KIND_ITERVALUE_REVERSED, // For sequences
  131. } kind;
  132. };
  133. namespace descriptor {
  134. // Returns the C++ item descriptor for a given Python key.
  135. // When the descriptor is found, return true and set *item.
  136. // When the descriptor is not found, return true, but set *item to NULL.
  137. // On error, returns false with an exception set.
  138. static bool _GetItemByKey(PyContainer* self, PyObject* key, const void** item) {
  139. switch (self->kind) {
  140. case PyContainer::KIND_BYNAME:
  141. {
  142. char* name;
  143. Py_ssize_t name_size;
  144. if (PyString_AsStringAndSize(key, &name, &name_size) < 0) {
  145. if (PyErr_ExceptionMatches(PyExc_TypeError)) {
  146. // Not a string, cannot be in the container.
  147. PyErr_Clear();
  148. *item = NULL;
  149. return true;
  150. }
  151. return false;
  152. }
  153. *item = self->container_def->get_by_name_fn(
  154. self, string(name, name_size));
  155. return true;
  156. }
  157. case PyContainer::KIND_BYNUMBER:
  158. {
  159. Py_ssize_t number = PyNumber_AsSsize_t(key, NULL);
  160. if (number == -1 && PyErr_Occurred()) {
  161. if (PyErr_ExceptionMatches(PyExc_TypeError)) {
  162. // Not a number, cannot be in the container.
  163. PyErr_Clear();
  164. *item = NULL;
  165. return true;
  166. }
  167. return false;
  168. }
  169. *item = self->container_def->get_by_number_fn(self, number);
  170. return true;
  171. }
  172. default:
  173. PyErr_SetNone(PyExc_NotImplementedError);
  174. return false;
  175. }
  176. }
  177. // Returns the key of the object at the given index.
  178. // Used when iterating over mappings.
  179. static PyObject* _NewKey_ByIndex(PyContainer* self, Py_ssize_t index) {
  180. const void* item = self->container_def->get_by_index_fn(self, index);
  181. switch (self->kind) {
  182. case PyContainer::KIND_BYNAME:
  183. {
  184. const string& name(self->container_def->get_item_name_fn(item));
  185. return PyString_FromStringAndSize(name.c_str(), name.size());
  186. }
  187. case PyContainer::KIND_BYNUMBER:
  188. {
  189. int value = self->container_def->get_item_number_fn(item);
  190. return PyInt_FromLong(value);
  191. }
  192. default:
  193. PyErr_SetNone(PyExc_NotImplementedError);
  194. return NULL;
  195. }
  196. }
  197. // Returns the object at the given index.
  198. // Also used when iterating over mappings.
  199. static PyObject* _NewObj_ByIndex(PyContainer* self, Py_ssize_t index) {
  200. return self->container_def->new_object_from_item_fn(
  201. self->container_def->get_by_index_fn(self, index));
  202. }
  203. static Py_ssize_t Length(PyContainer* self) {
  204. return self->container_def->count_fn(self);
  205. }
  206. // The DescriptorMapping type.
  207. static PyObject* Subscript(PyContainer* self, PyObject* key) {
  208. const void* item = NULL;
  209. if (!_GetItemByKey(self, key, &item)) {
  210. return NULL;
  211. }
  212. if (!item) {
  213. PyErr_SetObject(PyExc_KeyError, key);
  214. return NULL;
  215. }
  216. return self->container_def->new_object_from_item_fn(item);
  217. }
  218. static int AssSubscript(PyContainer* self, PyObject* key, PyObject* value) {
  219. if (_CalledFromGeneratedFile(0)) {
  220. return 0;
  221. }
  222. PyErr_Format(PyExc_TypeError,
  223. "'%.200s' object does not support item assignment",
  224. Py_TYPE(self)->tp_name);
  225. return -1;
  226. }
  227. static PyMappingMethods MappingMappingMethods = {
  228. (lenfunc)Length, // mp_length
  229. (binaryfunc)Subscript, // mp_subscript
  230. (objobjargproc)AssSubscript, // mp_ass_subscript
  231. };
  232. static int Contains(PyContainer* self, PyObject* key) {
  233. const void* item = NULL;
  234. if (!_GetItemByKey(self, key, &item)) {
  235. return -1;
  236. }
  237. if (item) {
  238. return 1;
  239. } else {
  240. return 0;
  241. }
  242. }
  243. static PyObject* ContainerRepr(PyContainer* self) {
  244. const char* kind = "";
  245. switch (self->kind) {
  246. case PyContainer::KIND_SEQUENCE:
  247. kind = "sequence";
  248. break;
  249. case PyContainer::KIND_BYNAME:
  250. kind = "mapping by name";
  251. break;
  252. case PyContainer::KIND_BYNUMBER:
  253. kind = "mapping by number";
  254. break;
  255. }
  256. return PyString_FromFormat(
  257. "<%s %s>", self->container_def->mapping_name, kind);
  258. }
  259. extern PyTypeObject DescriptorMapping_Type;
  260. extern PyTypeObject DescriptorSequence_Type;
  261. // A sequence container can only be equal to another sequence container, or (for
  262. // backward compatibility) to a list containing the same items.
  263. // Returns 1 if equal, 0 if unequal, -1 on error.
  264. static int DescriptorSequence_Equal(PyContainer* self, PyObject* other) {
  265. // Check the identity of C++ pointers.
  266. if (PyObject_TypeCheck(other, &DescriptorSequence_Type)) {
  267. PyContainer* other_container = reinterpret_cast<PyContainer*>(other);
  268. if (self->descriptor == other_container->descriptor &&
  269. self->container_def == other_container->container_def &&
  270. self->kind == other_container->kind) {
  271. return 1;
  272. } else {
  273. return 0;
  274. }
  275. }
  276. // If other is a list
  277. if (PyList_Check(other)) {
  278. // return list(self) == other
  279. int size = Length(self);
  280. if (size != PyList_Size(other)) {
  281. return false;
  282. }
  283. for (int index = 0; index < size; index++) {
  284. ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index));
  285. if (value1 == NULL) {
  286. return -1;
  287. }
  288. PyObject* value2 = PyList_GetItem(other, index);
  289. if (value2 == NULL) {
  290. return -1;
  291. }
  292. int cmp = PyObject_RichCompareBool(value1, value2, Py_EQ);
  293. if (cmp != 1) // error or not equal
  294. return cmp;
  295. }
  296. // All items were found and equal
  297. return 1;
  298. }
  299. // Any other object is different.
  300. return 0;
  301. }
  302. // A mapping container can only be equal to another mapping container, or (for
  303. // backward compatibility) to a dict containing the same items.
  304. // Returns 1 if equal, 0 if unequal, -1 on error.
  305. static int DescriptorMapping_Equal(PyContainer* self, PyObject* other) {
  306. // Check the identity of C++ pointers.
  307. if (PyObject_TypeCheck(other, &DescriptorMapping_Type)) {
  308. PyContainer* other_container = reinterpret_cast<PyContainer*>(other);
  309. if (self->descriptor == other_container->descriptor &&
  310. self->container_def == other_container->container_def &&
  311. self->kind == other_container->kind) {
  312. return 1;
  313. } else {
  314. return 0;
  315. }
  316. }
  317. // If other is a dict
  318. if (PyDict_Check(other)) {
  319. // equivalent to dict(self.items()) == other
  320. int size = Length(self);
  321. if (size != PyDict_Size(other)) {
  322. return false;
  323. }
  324. for (int index = 0; index < size; index++) {
  325. ScopedPyObjectPtr key(_NewKey_ByIndex(self, index));
  326. if (key == NULL) {
  327. return -1;
  328. }
  329. ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index));
  330. if (value1 == NULL) {
  331. return -1;
  332. }
  333. PyObject* value2 = PyDict_GetItem(other, key);
  334. if (value2 == NULL) {
  335. // Not found in the other dictionary
  336. return 0;
  337. }
  338. int cmp = PyObject_RichCompareBool(value1, value2, Py_EQ);
  339. if (cmp != 1) // error or not equal
  340. return cmp;
  341. }
  342. // All items were found and equal
  343. return 1;
  344. }
  345. // Any other object is different.
  346. return 0;
  347. }
  348. static PyObject* RichCompare(PyContainer* self, PyObject* other, int opid) {
  349. if (opid != Py_EQ && opid != Py_NE) {
  350. Py_INCREF(Py_NotImplemented);
  351. return Py_NotImplemented;
  352. }
  353. int result;
  354. if (self->kind == PyContainer::KIND_SEQUENCE) {
  355. result = DescriptorSequence_Equal(self, other);
  356. } else {
  357. result = DescriptorMapping_Equal(self, other);
  358. }
  359. if (result < 0) {
  360. return NULL;
  361. }
  362. if (result ^ (opid == Py_NE)) {
  363. Py_RETURN_TRUE;
  364. } else {
  365. Py_RETURN_FALSE;
  366. }
  367. }
  368. static PySequenceMethods MappingSequenceMethods = {
  369. 0, // sq_length
  370. 0, // sq_concat
  371. 0, // sq_repeat
  372. 0, // sq_item
  373. 0, // sq_slice
  374. 0, // sq_ass_item
  375. 0, // sq_ass_slice
  376. (objobjproc)Contains, // sq_contains
  377. };
  378. static PyObject* Get(PyContainer* self, PyObject* args) {
  379. PyObject* key;
  380. PyObject* default_value = Py_None;
  381. if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
  382. return NULL;
  383. }
  384. const void* item;
  385. if (!_GetItemByKey(self, key, &item)) {
  386. return NULL;
  387. }
  388. if (item == NULL) {
  389. Py_INCREF(default_value);
  390. return default_value;
  391. }
  392. return self->container_def->new_object_from_item_fn(item);
  393. }
  394. static PyObject* Keys(PyContainer* self, PyObject* args) {
  395. Py_ssize_t count = Length(self);
  396. ScopedPyObjectPtr list(PyList_New(count));
  397. if (list == NULL) {
  398. return NULL;
  399. }
  400. for (Py_ssize_t index = 0; index < count; ++index) {
  401. PyObject* key = _NewKey_ByIndex(self, index);
  402. if (key == NULL) {
  403. return NULL;
  404. }
  405. PyList_SET_ITEM(list.get(), index, key);
  406. }
  407. return list.release();
  408. }
  409. static PyObject* Values(PyContainer* self, PyObject* args) {
  410. Py_ssize_t count = Length(self);
  411. ScopedPyObjectPtr list(PyList_New(count));
  412. if (list == NULL) {
  413. return NULL;
  414. }
  415. for (Py_ssize_t index = 0; index < count; ++index) {
  416. PyObject* value = _NewObj_ByIndex(self, index);
  417. if (value == NULL) {
  418. return NULL;
  419. }
  420. PyList_SET_ITEM(list.get(), index, value);
  421. }
  422. return list.release();
  423. }
  424. static PyObject* Items(PyContainer* self, PyObject* args) {
  425. Py_ssize_t count = Length(self);
  426. ScopedPyObjectPtr list(PyList_New(count));
  427. if (list == NULL) {
  428. return NULL;
  429. }
  430. for (Py_ssize_t index = 0; index < count; ++index) {
  431. ScopedPyObjectPtr obj(PyTuple_New(2));
  432. if (obj == NULL) {
  433. return NULL;
  434. }
  435. PyObject* key = _NewKey_ByIndex(self, index);
  436. if (key == NULL) {
  437. return NULL;
  438. }
  439. PyTuple_SET_ITEM(obj.get(), 0, key);
  440. PyObject* value = _NewObj_ByIndex(self, index);
  441. if (value == NULL) {
  442. return NULL;
  443. }
  444. PyTuple_SET_ITEM(obj.get(), 1, value);
  445. PyList_SET_ITEM(list.get(), index, obj.release());
  446. }
  447. return list.release();
  448. }
  449. static PyObject* NewContainerIterator(PyContainer* mapping,
  450. PyContainerIterator::IterKind kind);
  451. static PyObject* Iter(PyContainer* self) {
  452. return NewContainerIterator(self, PyContainerIterator::KIND_ITERKEY);
  453. }
  454. static PyObject* IterKeys(PyContainer* self, PyObject* args) {
  455. return NewContainerIterator(self, PyContainerIterator::KIND_ITERKEY);
  456. }
  457. static PyObject* IterValues(PyContainer* self, PyObject* args) {
  458. return NewContainerIterator(self, PyContainerIterator::KIND_ITERVALUE);
  459. }
  460. static PyObject* IterItems(PyContainer* self, PyObject* args) {
  461. return NewContainerIterator(self, PyContainerIterator::KIND_ITERITEM);
  462. }
  463. static PyMethodDef MappingMethods[] = {
  464. { "get", (PyCFunction)Get, METH_VARARGS, },
  465. { "keys", (PyCFunction)Keys, METH_NOARGS, },
  466. { "values", (PyCFunction)Values, METH_NOARGS, },
  467. { "items", (PyCFunction)Items, METH_NOARGS, },
  468. { "iterkeys", (PyCFunction)IterKeys, METH_NOARGS, },
  469. { "itervalues", (PyCFunction)IterValues, METH_NOARGS, },
  470. { "iteritems", (PyCFunction)IterItems, METH_NOARGS, },
  471. {NULL}
  472. };
  473. PyTypeObject DescriptorMapping_Type = {
  474. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  475. "DescriptorMapping", // tp_name
  476. sizeof(PyContainer), // tp_basicsize
  477. 0, // tp_itemsize
  478. 0, // tp_dealloc
  479. 0, // tp_print
  480. 0, // tp_getattr
  481. 0, // tp_setattr
  482. 0, // tp_compare
  483. (reprfunc)ContainerRepr, // tp_repr
  484. 0, // tp_as_number
  485. &MappingSequenceMethods, // tp_as_sequence
  486. &MappingMappingMethods, // tp_as_mapping
  487. 0, // tp_hash
  488. 0, // tp_call
  489. 0, // tp_str
  490. 0, // tp_getattro
  491. 0, // tp_setattro
  492. 0, // tp_as_buffer
  493. Py_TPFLAGS_DEFAULT, // tp_flags
  494. 0, // tp_doc
  495. 0, // tp_traverse
  496. 0, // tp_clear
  497. (richcmpfunc)RichCompare, // tp_richcompare
  498. 0, // tp_weaklistoffset
  499. (getiterfunc)Iter, // tp_iter
  500. 0, // tp_iternext
  501. MappingMethods, // tp_methods
  502. 0, // tp_members
  503. 0, // tp_getset
  504. 0, // tp_base
  505. 0, // tp_dict
  506. 0, // tp_descr_get
  507. 0, // tp_descr_set
  508. 0, // tp_dictoffset
  509. 0, // tp_init
  510. 0, // tp_alloc
  511. 0, // tp_new
  512. 0, // tp_free
  513. };
  514. // The DescriptorSequence type.
  515. static PyObject* GetItem(PyContainer* self, Py_ssize_t index) {
  516. if (index < 0) {
  517. index += Length(self);
  518. }
  519. if (index < 0 || index >= Length(self)) {
  520. PyErr_SetString(PyExc_IndexError, "index out of range");
  521. return NULL;
  522. }
  523. return _NewObj_ByIndex(self, index);
  524. }
  525. // Returns the position of the item in the sequence, of -1 if not found.
  526. // This function never fails.
  527. int Find(PyContainer* self, PyObject* item) {
  528. // The item can only be in one position: item.index.
  529. // Check that self[item.index] == item, it's faster than a linear search.
  530. //
  531. // This assumes that sequences are only defined by syntax of the .proto file:
  532. // a specific item belongs to only one sequence, depending on its position in
  533. // the .proto file definition.
  534. const void* descriptor_ptr = PyDescriptor_AsVoidPtr(item);
  535. if (descriptor_ptr == NULL) {
  536. // Not a descriptor, it cannot be in the list.
  537. return -1;
  538. }
  539. if (self->container_def->get_item_index_fn) {
  540. int index = self->container_def->get_item_index_fn(descriptor_ptr);
  541. if (index < 0 || index >= Length(self)) {
  542. // This index is not from this collection.
  543. return -1;
  544. }
  545. if (self->container_def->get_by_index_fn(self, index) != descriptor_ptr) {
  546. // The descriptor at this index is not the same.
  547. return -1;
  548. }
  549. // self[item.index] == item, so return the index.
  550. return index;
  551. } else {
  552. // Fall back to linear search.
  553. int length = Length(self);
  554. for (int index=0; index < length; index++) {
  555. if (self->container_def->get_by_index_fn(self, index) == descriptor_ptr) {
  556. return index;
  557. }
  558. }
  559. // Not found
  560. return -1;
  561. }
  562. }
  563. // Implements list.index(): the position of the item is in the sequence.
  564. static PyObject* Index(PyContainer* self, PyObject* item) {
  565. int position = Find(self, item);
  566. if (position < 0) {
  567. // Not found
  568. PyErr_SetNone(PyExc_ValueError);
  569. return NULL;
  570. } else {
  571. return PyInt_FromLong(position);
  572. }
  573. }
  574. // Implements "list.__contains__()": is the object in the sequence.
  575. static int SeqContains(PyContainer* self, PyObject* item) {
  576. int position = Find(self, item);
  577. if (position < 0) {
  578. return 0;
  579. } else {
  580. return 1;
  581. }
  582. }
  583. // Implements list.count(): number of occurrences of the item in the sequence.
  584. // An item can only appear once in a sequence. If it exists, return 1.
  585. static PyObject* Count(PyContainer* self, PyObject* item) {
  586. int position = Find(self, item);
  587. if (position < 0) {
  588. return PyInt_FromLong(0);
  589. } else {
  590. return PyInt_FromLong(1);
  591. }
  592. }
  593. static PyObject* Append(PyContainer* self, PyObject* args) {
  594. if (_CalledFromGeneratedFile(0)) {
  595. Py_RETURN_NONE;
  596. }
  597. PyErr_Format(PyExc_TypeError,
  598. "'%.200s' object is not a mutable sequence",
  599. Py_TYPE(self)->tp_name);
  600. return NULL;
  601. }
  602. static PyObject* Reversed(PyContainer* self, PyObject* args) {
  603. return NewContainerIterator(self,
  604. PyContainerIterator::KIND_ITERVALUE_REVERSED);
  605. }
  606. static PyMethodDef SeqMethods[] = {
  607. { "index", (PyCFunction)Index, METH_O, },
  608. { "count", (PyCFunction)Count, METH_O, },
  609. { "append", (PyCFunction)Append, METH_O, },
  610. { "__reversed__", (PyCFunction)Reversed, METH_NOARGS, },
  611. {NULL}
  612. };
  613. static PySequenceMethods SeqSequenceMethods = {
  614. (lenfunc)Length, // sq_length
  615. 0, // sq_concat
  616. 0, // sq_repeat
  617. (ssizeargfunc)GetItem, // sq_item
  618. 0, // sq_slice
  619. 0, // sq_ass_item
  620. 0, // sq_ass_slice
  621. (objobjproc)SeqContains, // sq_contains
  622. };
  623. PyTypeObject DescriptorSequence_Type = {
  624. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  625. "DescriptorSequence", // tp_name
  626. sizeof(PyContainer), // tp_basicsize
  627. 0, // tp_itemsize
  628. 0, // tp_dealloc
  629. 0, // tp_print
  630. 0, // tp_getattr
  631. 0, // tp_setattr
  632. 0, // tp_compare
  633. (reprfunc)ContainerRepr, // tp_repr
  634. 0, // tp_as_number
  635. &SeqSequenceMethods, // tp_as_sequence
  636. 0, // tp_as_mapping
  637. 0, // tp_hash
  638. 0, // tp_call
  639. 0, // tp_str
  640. 0, // tp_getattro
  641. 0, // tp_setattro
  642. 0, // tp_as_buffer
  643. Py_TPFLAGS_DEFAULT, // tp_flags
  644. 0, // tp_doc
  645. 0, // tp_traverse
  646. 0, // tp_clear
  647. (richcmpfunc)RichCompare, // tp_richcompare
  648. 0, // tp_weaklistoffset
  649. 0, // tp_iter
  650. 0, // tp_iternext
  651. SeqMethods, // tp_methods
  652. 0, // tp_members
  653. 0, // tp_getset
  654. 0, // tp_base
  655. 0, // tp_dict
  656. 0, // tp_descr_get
  657. 0, // tp_descr_set
  658. 0, // tp_dictoffset
  659. 0, // tp_init
  660. 0, // tp_alloc
  661. 0, // tp_new
  662. 0, // tp_free
  663. };
  664. static PyObject* NewMappingByName(
  665. DescriptorContainerDef* container_def, const void* descriptor) {
  666. PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
  667. if (self == NULL) {
  668. return NULL;
  669. }
  670. self->descriptor = descriptor;
  671. self->container_def = container_def;
  672. self->kind = PyContainer::KIND_BYNAME;
  673. return reinterpret_cast<PyObject*>(self);
  674. }
  675. static PyObject* NewMappingByNumber(
  676. DescriptorContainerDef* container_def, const void* descriptor) {
  677. if (container_def->get_by_number_fn == NULL ||
  678. container_def->get_item_number_fn == NULL) {
  679. PyErr_SetNone(PyExc_NotImplementedError);
  680. return NULL;
  681. }
  682. PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
  683. if (self == NULL) {
  684. return NULL;
  685. }
  686. self->descriptor = descriptor;
  687. self->container_def = container_def;
  688. self->kind = PyContainer::KIND_BYNUMBER;
  689. return reinterpret_cast<PyObject*>(self);
  690. }
  691. static PyObject* NewSequence(
  692. DescriptorContainerDef* container_def, const void* descriptor) {
  693. PyContainer* self = PyObject_New(PyContainer, &DescriptorSequence_Type);
  694. if (self == NULL) {
  695. return NULL;
  696. }
  697. self->descriptor = descriptor;
  698. self->container_def = container_def;
  699. self->kind = PyContainer::KIND_SEQUENCE;
  700. return reinterpret_cast<PyObject*>(self);
  701. }
  702. // Implement iterators over PyContainers.
  703. static void Iterator_Dealloc(PyContainerIterator* self) {
  704. Py_CLEAR(self->container);
  705. Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
  706. }
  707. static PyObject* Iterator_Next(PyContainerIterator* self) {
  708. int count = self->container->container_def->count_fn(self->container);
  709. if (self->index >= count) {
  710. // Return NULL with no exception to indicate the end.
  711. return NULL;
  712. }
  713. int index = self->index;
  714. self->index += 1;
  715. switch (self->kind) {
  716. case PyContainerIterator::KIND_ITERKEY:
  717. return _NewKey_ByIndex(self->container, index);
  718. case PyContainerIterator::KIND_ITERVALUE:
  719. return _NewObj_ByIndex(self->container, index);
  720. case PyContainerIterator::KIND_ITERVALUE_REVERSED:
  721. return _NewObj_ByIndex(self->container, count - index - 1);
  722. case PyContainerIterator::KIND_ITERITEM:
  723. {
  724. PyObject* obj = PyTuple_New(2);
  725. if (obj == NULL) {
  726. return NULL;
  727. }
  728. PyObject* key = _NewKey_ByIndex(self->container, index);
  729. if (key == NULL) {
  730. Py_DECREF(obj);
  731. return NULL;
  732. }
  733. PyTuple_SET_ITEM(obj, 0, key);
  734. PyObject* value = _NewObj_ByIndex(self->container, index);
  735. if (value == NULL) {
  736. Py_DECREF(obj);
  737. return NULL;
  738. }
  739. PyTuple_SET_ITEM(obj, 1, value);
  740. return obj;
  741. }
  742. default:
  743. PyErr_SetNone(PyExc_NotImplementedError);
  744. return NULL;
  745. }
  746. }
  747. static PyTypeObject ContainerIterator_Type = {
  748. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  749. "DescriptorContainerIterator", // tp_name
  750. sizeof(PyContainerIterator), // tp_basicsize
  751. 0, // tp_itemsize
  752. (destructor)Iterator_Dealloc, // tp_dealloc
  753. 0, // tp_print
  754. 0, // tp_getattr
  755. 0, // tp_setattr
  756. 0, // tp_compare
  757. 0, // tp_repr
  758. 0, // tp_as_number
  759. 0, // tp_as_sequence
  760. 0, // tp_as_mapping
  761. 0, // tp_hash
  762. 0, // tp_call
  763. 0, // tp_str
  764. 0, // tp_getattro
  765. 0, // tp_setattro
  766. 0, // tp_as_buffer
  767. Py_TPFLAGS_DEFAULT, // tp_flags
  768. 0, // tp_doc
  769. 0, // tp_traverse
  770. 0, // tp_clear
  771. 0, // tp_richcompare
  772. 0, // tp_weaklistoffset
  773. PyObject_SelfIter, // tp_iter
  774. (iternextfunc)Iterator_Next, // tp_iternext
  775. 0, // tp_methods
  776. 0, // tp_members
  777. 0, // tp_getset
  778. 0, // tp_base
  779. 0, // tp_dict
  780. 0, // tp_descr_get
  781. 0, // tp_descr_set
  782. 0, // tp_dictoffset
  783. 0, // tp_init
  784. 0, // tp_alloc
  785. 0, // tp_new
  786. 0, // tp_free
  787. };
  788. static PyObject* NewContainerIterator(PyContainer* container,
  789. PyContainerIterator::IterKind kind) {
  790. PyContainerIterator* self = PyObject_New(PyContainerIterator,
  791. &ContainerIterator_Type);
  792. if (self == NULL) {
  793. return NULL;
  794. }
  795. Py_INCREF(container);
  796. self->container = container;
  797. self->kind = kind;
  798. self->index = 0;
  799. return reinterpret_cast<PyObject*>(self);
  800. }
  801. } // namespace descriptor
  802. // Now define the real collections!
  803. namespace message_descriptor {
  804. typedef const Descriptor* ParentDescriptor;
  805. static ParentDescriptor GetDescriptor(PyContainer* self) {
  806. return reinterpret_cast<ParentDescriptor>(self->descriptor);
  807. }
  808. namespace fields {
  809. typedef const FieldDescriptor* ItemDescriptor;
  810. static int Count(PyContainer* self) {
  811. return GetDescriptor(self)->field_count();
  812. }
  813. static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  814. return GetDescriptor(self)->FindFieldByName(name);
  815. }
  816. static ItemDescriptor GetByNumber(PyContainer* self, int number) {
  817. return GetDescriptor(self)->FindFieldByNumber(number);
  818. }
  819. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  820. return GetDescriptor(self)->field(index);
  821. }
  822. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  823. return PyFieldDescriptor_New(item);
  824. }
  825. static const string& GetItemName(ItemDescriptor item) {
  826. return item->name();
  827. }
  828. static int GetItemNumber(ItemDescriptor item) {
  829. return item->number();
  830. }
  831. static int GetItemIndex(ItemDescriptor item) {
  832. return item->index();
  833. }
  834. static DescriptorContainerDef ContainerDef = {
  835. "MessageFields",
  836. (CountMethod)Count,
  837. (GetByIndexMethod)GetByIndex,
  838. (GetByNameMethod)GetByName,
  839. (GetByNumberMethod)GetByNumber,
  840. (NewObjectFromItemMethod)NewObjectFromItem,
  841. (GetItemNameMethod)GetItemName,
  842. (GetItemNumberMethod)GetItemNumber,
  843. (GetItemIndexMethod)GetItemIndex,
  844. };
  845. } // namespace fields
  846. PyObject* NewMessageFieldsByName(ParentDescriptor descriptor) {
  847. return descriptor::NewMappingByName(&fields::ContainerDef, descriptor);
  848. }
  849. PyObject* NewMessageFieldsByNumber(ParentDescriptor descriptor) {
  850. return descriptor::NewMappingByNumber(&fields::ContainerDef, descriptor);
  851. }
  852. PyObject* NewMessageFieldsSeq(ParentDescriptor descriptor) {
  853. return descriptor::NewSequence(&fields::ContainerDef, descriptor);
  854. }
  855. namespace nested_types {
  856. typedef const Descriptor* ItemDescriptor;
  857. static int Count(PyContainer* self) {
  858. return GetDescriptor(self)->nested_type_count();
  859. }
  860. static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  861. return GetDescriptor(self)->FindNestedTypeByName(name);
  862. }
  863. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  864. return GetDescriptor(self)->nested_type(index);
  865. }
  866. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  867. return PyMessageDescriptor_New(item);
  868. }
  869. static const string& GetItemName(ItemDescriptor item) {
  870. return item->name();
  871. }
  872. static int GetItemIndex(ItemDescriptor item) {
  873. return item->index();
  874. }
  875. static DescriptorContainerDef ContainerDef = {
  876. "MessageNestedTypes",
  877. (CountMethod)Count,
  878. (GetByIndexMethod)GetByIndex,
  879. (GetByNameMethod)GetByName,
  880. (GetByNumberMethod)NULL,
  881. (NewObjectFromItemMethod)NewObjectFromItem,
  882. (GetItemNameMethod)GetItemName,
  883. (GetItemNumberMethod)NULL,
  884. (GetItemIndexMethod)GetItemIndex,
  885. };
  886. } // namespace nested_types
  887. PyObject* NewMessageNestedTypesSeq(ParentDescriptor descriptor) {
  888. return descriptor::NewSequence(&nested_types::ContainerDef, descriptor);
  889. }
  890. PyObject* NewMessageNestedTypesByName(ParentDescriptor descriptor) {
  891. return descriptor::NewMappingByName(&nested_types::ContainerDef, descriptor);
  892. }
  893. namespace enums {
  894. typedef const EnumDescriptor* ItemDescriptor;
  895. static int Count(PyContainer* self) {
  896. return GetDescriptor(self)->enum_type_count();
  897. }
  898. static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  899. return GetDescriptor(self)->FindEnumTypeByName(name);
  900. }
  901. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  902. return GetDescriptor(self)->enum_type(index);
  903. }
  904. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  905. return PyEnumDescriptor_New(item);
  906. }
  907. static const string& GetItemName(ItemDescriptor item) {
  908. return item->name();
  909. }
  910. static int GetItemIndex(ItemDescriptor item) {
  911. return item->index();
  912. }
  913. static DescriptorContainerDef ContainerDef = {
  914. "MessageNestedEnums",
  915. (CountMethod)Count,
  916. (GetByIndexMethod)GetByIndex,
  917. (GetByNameMethod)GetByName,
  918. (GetByNumberMethod)NULL,
  919. (NewObjectFromItemMethod)NewObjectFromItem,
  920. (GetItemNameMethod)GetItemName,
  921. (GetItemNumberMethod)NULL,
  922. (GetItemIndexMethod)GetItemIndex,
  923. };
  924. } // namespace enums
  925. PyObject* NewMessageEnumsByName(ParentDescriptor descriptor) {
  926. return descriptor::NewMappingByName(&enums::ContainerDef, descriptor);
  927. }
  928. PyObject* NewMessageEnumsSeq(ParentDescriptor descriptor) {
  929. return descriptor::NewSequence(&enums::ContainerDef, descriptor);
  930. }
  931. namespace enumvalues {
  932. // This is the "enum_values_by_name" mapping, which collects values from all
  933. // enum types in a message.
  934. //
  935. // Note that the behavior of the C++ descriptor is different: it will search and
  936. // return the first value that matches the name, whereas the Python
  937. // implementation retrieves the last one.
  938. typedef const EnumValueDescriptor* ItemDescriptor;
  939. static int Count(PyContainer* self) {
  940. int count = 0;
  941. for (int i = 0; i < GetDescriptor(self)->enum_type_count(); ++i) {
  942. count += GetDescriptor(self)->enum_type(i)->value_count();
  943. }
  944. return count;
  945. }
  946. static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  947. return GetDescriptor(self)->FindEnumValueByName(name);
  948. }
  949. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  950. // This is not optimal, but the number of enums *types* in a given message
  951. // is small. This function is only used when iterating over the mapping.
  952. const EnumDescriptor* enum_type = NULL;
  953. int enum_type_count = GetDescriptor(self)->enum_type_count();
  954. for (int i = 0; i < enum_type_count; ++i) {
  955. enum_type = GetDescriptor(self)->enum_type(i);
  956. int enum_value_count = enum_type->value_count();
  957. if (index < enum_value_count) {
  958. // Found it!
  959. break;
  960. }
  961. index -= enum_value_count;
  962. }
  963. // The next statement cannot overflow, because this function is only called by
  964. // internal iterators which ensure that 0 <= index < Count().
  965. return enum_type->value(index);
  966. }
  967. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  968. return PyEnumValueDescriptor_New(item);
  969. }
  970. static const string& GetItemName(ItemDescriptor item) {
  971. return item->name();
  972. }
  973. static DescriptorContainerDef ContainerDef = {
  974. "MessageEnumValues",
  975. (CountMethod)Count,
  976. (GetByIndexMethod)GetByIndex,
  977. (GetByNameMethod)GetByName,
  978. (GetByNumberMethod)NULL,
  979. (NewObjectFromItemMethod)NewObjectFromItem,
  980. (GetItemNameMethod)GetItemName,
  981. (GetItemNumberMethod)NULL,
  982. (GetItemIndexMethod)NULL,
  983. };
  984. } // namespace enumvalues
  985. PyObject* NewMessageEnumValuesByName(ParentDescriptor descriptor) {
  986. return descriptor::NewMappingByName(&enumvalues::ContainerDef, descriptor);
  987. }
  988. namespace extensions {
  989. typedef const FieldDescriptor* ItemDescriptor;
  990. static int Count(PyContainer* self) {
  991. return GetDescriptor(self)->extension_count();
  992. }
  993. static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  994. return GetDescriptor(self)->FindExtensionByName(name);
  995. }
  996. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  997. return GetDescriptor(self)->extension(index);
  998. }
  999. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  1000. return PyFieldDescriptor_New(item);
  1001. }
  1002. static const string& GetItemName(ItemDescriptor item) {
  1003. return item->name();
  1004. }
  1005. static int GetItemIndex(ItemDescriptor item) {
  1006. return item->index();
  1007. }
  1008. static DescriptorContainerDef ContainerDef = {
  1009. "MessageExtensions",
  1010. (CountMethod)Count,
  1011. (GetByIndexMethod)GetByIndex,
  1012. (GetByNameMethod)GetByName,
  1013. (GetByNumberMethod)NULL,
  1014. (NewObjectFromItemMethod)NewObjectFromItem,
  1015. (GetItemNameMethod)GetItemName,
  1016. (GetItemNumberMethod)NULL,
  1017. (GetItemIndexMethod)GetItemIndex,
  1018. };
  1019. } // namespace extensions
  1020. PyObject* NewMessageExtensionsByName(ParentDescriptor descriptor) {
  1021. return descriptor::NewMappingByName(&extensions::ContainerDef, descriptor);
  1022. }
  1023. PyObject* NewMessageExtensionsSeq(ParentDescriptor descriptor) {
  1024. return descriptor::NewSequence(&extensions::ContainerDef, descriptor);
  1025. }
  1026. namespace oneofs {
  1027. typedef const OneofDescriptor* ItemDescriptor;
  1028. static int Count(PyContainer* self) {
  1029. return GetDescriptor(self)->oneof_decl_count();
  1030. }
  1031. static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  1032. return GetDescriptor(self)->FindOneofByName(name);
  1033. }
  1034. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  1035. return GetDescriptor(self)->oneof_decl(index);
  1036. }
  1037. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  1038. return PyOneofDescriptor_New(item);
  1039. }
  1040. static const string& GetItemName(ItemDescriptor item) {
  1041. return item->name();
  1042. }
  1043. static int GetItemIndex(ItemDescriptor item) {
  1044. return item->index();
  1045. }
  1046. static DescriptorContainerDef ContainerDef = {
  1047. "MessageOneofs",
  1048. (CountMethod)Count,
  1049. (GetByIndexMethod)GetByIndex,
  1050. (GetByNameMethod)GetByName,
  1051. (GetByNumberMethod)NULL,
  1052. (NewObjectFromItemMethod)NewObjectFromItem,
  1053. (GetItemNameMethod)GetItemName,
  1054. (GetItemNumberMethod)NULL,
  1055. (GetItemIndexMethod)GetItemIndex,
  1056. };
  1057. } // namespace oneofs
  1058. PyObject* NewMessageOneofsByName(ParentDescriptor descriptor) {
  1059. return descriptor::NewMappingByName(&oneofs::ContainerDef, descriptor);
  1060. }
  1061. PyObject* NewMessageOneofsSeq(ParentDescriptor descriptor) {
  1062. return descriptor::NewSequence(&oneofs::ContainerDef, descriptor);
  1063. }
  1064. } // namespace message_descriptor
  1065. namespace enum_descriptor {
  1066. typedef const EnumDescriptor* ParentDescriptor;
  1067. static ParentDescriptor GetDescriptor(PyContainer* self) {
  1068. return reinterpret_cast<ParentDescriptor>(self->descriptor);
  1069. }
  1070. namespace enumvalues {
  1071. typedef const EnumValueDescriptor* ItemDescriptor;
  1072. static int Count(PyContainer* self) {
  1073. return GetDescriptor(self)->value_count();
  1074. }
  1075. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  1076. return GetDescriptor(self)->value(index);
  1077. }
  1078. static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  1079. return GetDescriptor(self)->FindValueByName(name);
  1080. }
  1081. static ItemDescriptor GetByNumber(PyContainer* self, int number) {
  1082. return GetDescriptor(self)->FindValueByNumber(number);
  1083. }
  1084. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  1085. return PyEnumValueDescriptor_New(item);
  1086. }
  1087. static const string& GetItemName(ItemDescriptor item) {
  1088. return item->name();
  1089. }
  1090. static int GetItemNumber(ItemDescriptor item) {
  1091. return item->number();
  1092. }
  1093. static int GetItemIndex(ItemDescriptor item) {
  1094. return item->index();
  1095. }
  1096. static DescriptorContainerDef ContainerDef = {
  1097. "EnumValues",
  1098. (CountMethod)Count,
  1099. (GetByIndexMethod)GetByIndex,
  1100. (GetByNameMethod)GetByName,
  1101. (GetByNumberMethod)GetByNumber,
  1102. (NewObjectFromItemMethod)NewObjectFromItem,
  1103. (GetItemNameMethod)GetItemName,
  1104. (GetItemNumberMethod)GetItemNumber,
  1105. (GetItemIndexMethod)GetItemIndex,
  1106. };
  1107. } // namespace enumvalues
  1108. PyObject* NewEnumValuesByName(ParentDescriptor descriptor) {
  1109. return descriptor::NewMappingByName(&enumvalues::ContainerDef, descriptor);
  1110. }
  1111. PyObject* NewEnumValuesByNumber(ParentDescriptor descriptor) {
  1112. return descriptor::NewMappingByNumber(&enumvalues::ContainerDef, descriptor);
  1113. }
  1114. PyObject* NewEnumValuesSeq(ParentDescriptor descriptor) {
  1115. return descriptor::NewSequence(&enumvalues::ContainerDef, descriptor);
  1116. }
  1117. } // namespace enum_descriptor
  1118. namespace oneof_descriptor {
  1119. typedef const OneofDescriptor* ParentDescriptor;
  1120. static ParentDescriptor GetDescriptor(PyContainer* self) {
  1121. return reinterpret_cast<ParentDescriptor>(self->descriptor);
  1122. }
  1123. namespace fields {
  1124. typedef const FieldDescriptor* ItemDescriptor;
  1125. static int Count(PyContainer* self) {
  1126. return GetDescriptor(self)->field_count();
  1127. }
  1128. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  1129. return GetDescriptor(self)->field(index);
  1130. }
  1131. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  1132. return PyFieldDescriptor_New(item);
  1133. }
  1134. static int GetItemIndex(ItemDescriptor item) {
  1135. return item->index_in_oneof();
  1136. }
  1137. static DescriptorContainerDef ContainerDef = {
  1138. "OneofFields",
  1139. (CountMethod)Count,
  1140. (GetByIndexMethod)GetByIndex,
  1141. (GetByNameMethod)NULL,
  1142. (GetByNumberMethod)NULL,
  1143. (NewObjectFromItemMethod)NewObjectFromItem,
  1144. (GetItemNameMethod)NULL,
  1145. (GetItemNumberMethod)NULL,
  1146. (GetItemIndexMethod)GetItemIndex,
  1147. };
  1148. } // namespace fields
  1149. PyObject* NewOneofFieldsSeq(ParentDescriptor descriptor) {
  1150. return descriptor::NewSequence(&fields::ContainerDef, descriptor);
  1151. }
  1152. } // namespace oneof_descriptor
  1153. namespace file_descriptor {
  1154. typedef const FileDescriptor* ParentDescriptor;
  1155. static ParentDescriptor GetDescriptor(PyContainer* self) {
  1156. return reinterpret_cast<ParentDescriptor>(self->descriptor);
  1157. }
  1158. namespace messages {
  1159. typedef const Descriptor* ItemDescriptor;
  1160. static int Count(PyContainer* self) {
  1161. return GetDescriptor(self)->message_type_count();
  1162. }
  1163. static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  1164. return GetDescriptor(self)->FindMessageTypeByName(name);
  1165. }
  1166. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  1167. return GetDescriptor(self)->message_type(index);
  1168. }
  1169. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  1170. return PyMessageDescriptor_New(item);
  1171. }
  1172. static const string& GetItemName(ItemDescriptor item) {
  1173. return item->name();
  1174. }
  1175. static int GetItemIndex(ItemDescriptor item) {
  1176. return item->index();
  1177. }
  1178. static DescriptorContainerDef ContainerDef = {
  1179. "FileMessages",
  1180. (CountMethod)Count,
  1181. (GetByIndexMethod)GetByIndex,
  1182. (GetByNameMethod)GetByName,
  1183. (GetByNumberMethod)NULL,
  1184. (NewObjectFromItemMethod)NewObjectFromItem,
  1185. (GetItemNameMethod)GetItemName,
  1186. (GetItemNumberMethod)NULL,
  1187. (GetItemIndexMethod)GetItemIndex,
  1188. };
  1189. } // namespace messages
  1190. PyObject* NewFileMessageTypesByName(const FileDescriptor* descriptor) {
  1191. return descriptor::NewMappingByName(&messages::ContainerDef, descriptor);
  1192. }
  1193. namespace enums {
  1194. typedef const EnumDescriptor* ItemDescriptor;
  1195. static int Count(PyContainer* self) {
  1196. return GetDescriptor(self)->enum_type_count();
  1197. }
  1198. static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  1199. return GetDescriptor(self)->FindEnumTypeByName(name);
  1200. }
  1201. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  1202. return GetDescriptor(self)->enum_type(index);
  1203. }
  1204. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  1205. return PyEnumDescriptor_New(item);
  1206. }
  1207. static const string& GetItemName(ItemDescriptor item) {
  1208. return item->name();
  1209. }
  1210. static int GetItemIndex(ItemDescriptor item) {
  1211. return item->index();
  1212. }
  1213. static DescriptorContainerDef ContainerDef = {
  1214. "FileEnums",
  1215. (CountMethod)Count,
  1216. (GetByIndexMethod)GetByIndex,
  1217. (GetByNameMethod)GetByName,
  1218. (GetByNumberMethod)NULL,
  1219. (NewObjectFromItemMethod)NewObjectFromItem,
  1220. (GetItemNameMethod)GetItemName,
  1221. (GetItemNumberMethod)NULL,
  1222. (GetItemIndexMethod)GetItemIndex,
  1223. };
  1224. } // namespace enums
  1225. PyObject* NewFileEnumTypesByName(const FileDescriptor* descriptor) {
  1226. return descriptor::NewMappingByName(&enums::ContainerDef, descriptor);
  1227. }
  1228. namespace extensions {
  1229. typedef const FieldDescriptor* ItemDescriptor;
  1230. static int Count(PyContainer* self) {
  1231. return GetDescriptor(self)->extension_count();
  1232. }
  1233. static ItemDescriptor GetByName(PyContainer* self, const string& name) {
  1234. return GetDescriptor(self)->FindExtensionByName(name);
  1235. }
  1236. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  1237. return GetDescriptor(self)->extension(index);
  1238. }
  1239. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  1240. return PyFieldDescriptor_New(item);
  1241. }
  1242. static const string& GetItemName(ItemDescriptor item) {
  1243. return item->name();
  1244. }
  1245. static int GetItemIndex(ItemDescriptor item) {
  1246. return item->index();
  1247. }
  1248. static DescriptorContainerDef ContainerDef = {
  1249. "FileExtensions",
  1250. (CountMethod)Count,
  1251. (GetByIndexMethod)GetByIndex,
  1252. (GetByNameMethod)GetByName,
  1253. (GetByNumberMethod)NULL,
  1254. (NewObjectFromItemMethod)NewObjectFromItem,
  1255. (GetItemNameMethod)GetItemName,
  1256. (GetItemNumberMethod)NULL,
  1257. (GetItemIndexMethod)GetItemIndex,
  1258. };
  1259. } // namespace extensions
  1260. PyObject* NewFileExtensionsByName(const FileDescriptor* descriptor) {
  1261. return descriptor::NewMappingByName(&extensions::ContainerDef, descriptor);
  1262. }
  1263. namespace dependencies {
  1264. typedef const FileDescriptor* ItemDescriptor;
  1265. static int Count(PyContainer* self) {
  1266. return GetDescriptor(self)->dependency_count();
  1267. }
  1268. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  1269. return GetDescriptor(self)->dependency(index);
  1270. }
  1271. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  1272. return PyFileDescriptor_New(item);
  1273. }
  1274. static DescriptorContainerDef ContainerDef = {
  1275. "FileDependencies",
  1276. (CountMethod)Count,
  1277. (GetByIndexMethod)GetByIndex,
  1278. (GetByNameMethod)NULL,
  1279. (GetByNumberMethod)NULL,
  1280. (NewObjectFromItemMethod)NewObjectFromItem,
  1281. (GetItemNameMethod)NULL,
  1282. (GetItemNumberMethod)NULL,
  1283. (GetItemIndexMethod)NULL,
  1284. };
  1285. } // namespace dependencies
  1286. PyObject* NewFileDependencies(const FileDescriptor* descriptor) {
  1287. return descriptor::NewSequence(&dependencies::ContainerDef, descriptor);
  1288. }
  1289. namespace public_dependencies {
  1290. typedef const FileDescriptor* ItemDescriptor;
  1291. static int Count(PyContainer* self) {
  1292. return GetDescriptor(self)->public_dependency_count();
  1293. }
  1294. static ItemDescriptor GetByIndex(PyContainer* self, int index) {
  1295. return GetDescriptor(self)->public_dependency(index);
  1296. }
  1297. static PyObject* NewObjectFromItem(ItemDescriptor item) {
  1298. return PyFileDescriptor_New(item);
  1299. }
  1300. static DescriptorContainerDef ContainerDef = {
  1301. "FilePublicDependencies",
  1302. (CountMethod)Count,
  1303. (GetByIndexMethod)GetByIndex,
  1304. (GetByNameMethod)NULL,
  1305. (GetByNumberMethod)NULL,
  1306. (NewObjectFromItemMethod)NewObjectFromItem,
  1307. (GetItemNameMethod)NULL,
  1308. (GetItemNumberMethod)NULL,
  1309. (GetItemIndexMethod)NULL,
  1310. };
  1311. } // namespace public_dependencies
  1312. PyObject* NewFilePublicDependencies(const FileDescriptor* descriptor) {
  1313. return descriptor::NewSequence(&public_dependencies::ContainerDef,
  1314. descriptor);
  1315. }
  1316. } // namespace file_descriptor
  1317. // Register all implementations
  1318. bool InitDescriptorMappingTypes() {
  1319. if (PyType_Ready(&descriptor::DescriptorMapping_Type) < 0)
  1320. return false;
  1321. if (PyType_Ready(&descriptor::DescriptorSequence_Type) < 0)
  1322. return false;
  1323. if (PyType_Ready(&descriptor::ContainerIterator_Type) < 0)
  1324. return false;
  1325. return true;
  1326. }
  1327. } // namespace python
  1328. } // namespace protobuf
  1329. } // namespace google