123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794 |
- // Protocol Buffers - Google's data interchange format
- // Copyright 2008 Google Inc. All rights reserved.
- // https://developers.google.com/protocol-buffers/
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- // Mappings and Sequences of descriptors.
- // Used by Descriptor.fields_by_name, EnumDescriptor.values...
- //
- // They avoid the allocation of a full dictionary or a full list: they simply
- // store a pointer to the parent descriptor, use the C++ Descriptor methods (see
- // net/proto2/public/descriptor.h) to retrieve other descriptors, and create
- // Python objects on the fly.
- //
- // The containers fully conform to abc.Mapping and abc.Sequence, and behave just
- // like read-only dictionaries and lists.
- //
- // Because the interface of C++ Descriptors is quite regular, this file actually
- // defines only three types, the exact behavior of a container is controlled by
- // a DescriptorContainerDef structure, which contains functions that uses the
- // public Descriptor API.
- //
- // Note: This DescriptorContainerDef is similar to the "virtual methods table"
- // that a C++ compiler generates for a class. We have to make it explicit
- // because the Python API is based on C, and does not play well with C++
- // inheritance.
- #include <Python.h>
- #include <google/protobuf/descriptor.h>
- #include <google/protobuf/pyext/descriptor_containers.h>
- #include <google/protobuf/pyext/descriptor_pool.h>
- #include <google/protobuf/pyext/descriptor.h>
- #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
- #if PY_MAJOR_VERSION >= 3
- #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
- #define PyString_FromFormat PyUnicode_FromFormat
- #define PyInt_FromLong PyLong_FromLong
- #if PY_VERSION_HEX < 0x03030000
- #error "Python 3.0 - 3.2 are not supported."
- #endif
- #define PyString_AsStringAndSize(ob, charpp, sizep) \
- (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \
- PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
- ? -1 \
- : 0) \
- : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
- #endif
- namespace google {
- namespace protobuf {
- namespace python {
- struct PyContainer;
- typedef int (*CountMethod)(PyContainer* self);
- typedef const void* (*GetByIndexMethod)(PyContainer* self, int index);
- typedef const void* (*GetByNameMethod)(PyContainer* self,
- ConstStringParam name);
- typedef const void* (*GetByCamelcaseNameMethod)(PyContainer* self,
- ConstStringParam name);
- typedef const void* (*GetByNumberMethod)(PyContainer* self, int index);
- typedef PyObject* (*NewObjectFromItemMethod)(const void* descriptor);
- typedef const std::string& (*GetItemNameMethod)(const void* descriptor);
- typedef const std::string& (*GetItemCamelcaseNameMethod)(
- const void* descriptor);
- typedef int (*GetItemNumberMethod)(const void* descriptor);
- typedef int (*GetItemIndexMethod)(const void* descriptor);
- struct DescriptorContainerDef {
- const char* mapping_name;
- // Returns the number of items in the container.
- CountMethod count_fn;
- // Retrieve item by index (usually the order of declaration in the proto file)
- // Used by sequences, but also iterators. 0 <= index < Count().
- GetByIndexMethod get_by_index_fn;
- // Retrieve item by name (usually a call to some 'FindByName' method).
- // Used by "by_name" mappings.
- GetByNameMethod get_by_name_fn;
- // Retrieve item by camelcase name (usually a call to some
- // 'FindByCamelcaseName' method). Used by "by_camelcase_name" mappings.
- GetByCamelcaseNameMethod get_by_camelcase_name_fn;
- // Retrieve item by declared number (field tag, or enum value).
- // Used by "by_number" mappings.
- GetByNumberMethod get_by_number_fn;
- // Converts a item C++ descriptor to a Python object. Returns a new reference.
- NewObjectFromItemMethod new_object_from_item_fn;
- // Retrieve the name of an item. Used by iterators on "by_name" mappings.
- GetItemNameMethod get_item_name_fn;
- // Retrieve the camelcase name of an item. Used by iterators on
- // "by_camelcase_name" mappings.
- GetItemCamelcaseNameMethod get_item_camelcase_name_fn;
- // Retrieve the number of an item. Used by iterators on "by_number" mappings.
- GetItemNumberMethod get_item_number_fn;
- // Retrieve the index of an item for the container type.
- // Used by "__contains__".
- // If not set, "x in sequence" will do a linear search.
- GetItemIndexMethod get_item_index_fn;
- };
- struct PyContainer {
- PyObject_HEAD
- // The proto2 descriptor this container belongs to the global DescriptorPool.
- const void* descriptor;
- // A pointer to a static structure with function pointers that control the
- // behavior of the container. Very similar to the table of virtual functions
- // of a C++ class.
- const DescriptorContainerDef* container_def;
- // The kind of container: list, or dict by name or value.
- enum ContainerKind {
- KIND_SEQUENCE,
- KIND_BYNAME,
- KIND_BYCAMELCASENAME,
- KIND_BYNUMBER,
- } kind;
- };
- struct PyContainerIterator {
- PyObject_HEAD
- // The container we are iterating over. Own a reference.
- PyContainer* container;
- // The current index in the iterator.
- int index;
- // The kind of container: list, or dict by name or value.
- enum IterKind {
- KIND_ITERKEY,
- KIND_ITERVALUE,
- KIND_ITERITEM,
- KIND_ITERVALUE_REVERSED, // For sequences
- } kind;
- };
- namespace descriptor {
- // Returns the C++ item descriptor for a given Python key.
- // When the descriptor is found, return true and set *item.
- // When the descriptor is not found, return true, but set *item to NULL.
- // On error, returns false with an exception set.
- static bool _GetItemByKey(PyContainer* self, PyObject* key, const void** item) {
- switch (self->kind) {
- case PyContainer::KIND_BYNAME:
- {
- char* name;
- Py_ssize_t name_size;
- if (PyString_AsStringAndSize(key, &name, &name_size) < 0) {
- if (PyErr_ExceptionMatches(PyExc_TypeError)) {
- // Not a string, cannot be in the container.
- PyErr_Clear();
- *item = NULL;
- return true;
- }
- return false;
- }
- *item = self->container_def->get_by_name_fn(
- self, StringParam(name, name_size));
- return true;
- }
- case PyContainer::KIND_BYCAMELCASENAME:
- {
- char* camelcase_name;
- Py_ssize_t name_size;
- if (PyString_AsStringAndSize(key, &camelcase_name, &name_size) < 0) {
- if (PyErr_ExceptionMatches(PyExc_TypeError)) {
- // Not a string, cannot be in the container.
- PyErr_Clear();
- *item = NULL;
- return true;
- }
- return false;
- }
- *item = self->container_def->get_by_camelcase_name_fn(
- self, StringParam(camelcase_name, name_size));
- return true;
- }
- case PyContainer::KIND_BYNUMBER:
- {
- Py_ssize_t number = PyNumber_AsSsize_t(key, NULL);
- if (number == -1 && PyErr_Occurred()) {
- if (PyErr_ExceptionMatches(PyExc_TypeError)) {
- // Not a number, cannot be in the container.
- PyErr_Clear();
- *item = NULL;
- return true;
- }
- return false;
- }
- *item = self->container_def->get_by_number_fn(self, number);
- return true;
- }
- default:
- PyErr_SetNone(PyExc_NotImplementedError);
- return false;
- }
- }
- // Returns the key of the object at the given index.
- // Used when iterating over mappings.
- static PyObject* _NewKey_ByIndex(PyContainer* self, Py_ssize_t index) {
- const void* item = self->container_def->get_by_index_fn(self, index);
- switch (self->kind) {
- case PyContainer::KIND_BYNAME:
- {
- const std::string& name(self->container_def->get_item_name_fn(item));
- return PyString_FromStringAndSize(name.c_str(), name.size());
- }
- case PyContainer::KIND_BYCAMELCASENAME:
- {
- const std::string& name(
- self->container_def->get_item_camelcase_name_fn(item));
- return PyString_FromStringAndSize(name.c_str(), name.size());
- }
- case PyContainer::KIND_BYNUMBER:
- {
- int value = self->container_def->get_item_number_fn(item);
- return PyInt_FromLong(value);
- }
- default:
- PyErr_SetNone(PyExc_NotImplementedError);
- return NULL;
- }
- }
- // Returns the object at the given index.
- // Also used when iterating over mappings.
- static PyObject* _NewObj_ByIndex(PyContainer* self, Py_ssize_t index) {
- return self->container_def->new_object_from_item_fn(
- self->container_def->get_by_index_fn(self, index));
- }
- static Py_ssize_t Length(PyContainer* self) {
- return self->container_def->count_fn(self);
- }
- // The DescriptorMapping type.
- static PyObject* Subscript(PyContainer* self, PyObject* key) {
- const void* item = NULL;
- if (!_GetItemByKey(self, key, &item)) {
- return NULL;
- }
- if (!item) {
- PyErr_SetObject(PyExc_KeyError, key);
- return NULL;
- }
- return self->container_def->new_object_from_item_fn(item);
- }
- static int AssSubscript(PyContainer* self, PyObject* key, PyObject* value) {
- if (_CalledFromGeneratedFile(0)) {
- return 0;
- }
- PyErr_Format(PyExc_TypeError,
- "'%.200s' object does not support item assignment",
- Py_TYPE(self)->tp_name);
- return -1;
- }
- static PyMappingMethods MappingMappingMethods = {
- (lenfunc)Length, // mp_length
- (binaryfunc)Subscript, // mp_subscript
- (objobjargproc)AssSubscript, // mp_ass_subscript
- };
- static int Contains(PyContainer* self, PyObject* key) {
- const void* item = NULL;
- if (!_GetItemByKey(self, key, &item)) {
- return -1;
- }
- if (item) {
- return 1;
- } else {
- return 0;
- }
- }
- static PyObject* ContainerRepr(PyContainer* self) {
- const char* kind = "";
- switch (self->kind) {
- case PyContainer::KIND_SEQUENCE:
- kind = "sequence";
- break;
- case PyContainer::KIND_BYNAME:
- kind = "mapping by name";
- break;
- case PyContainer::KIND_BYCAMELCASENAME:
- kind = "mapping by camelCase name";
- break;
- case PyContainer::KIND_BYNUMBER:
- kind = "mapping by number";
- break;
- }
- return PyString_FromFormat(
- "<%s %s>", self->container_def->mapping_name, kind);
- }
- extern PyTypeObject DescriptorMapping_Type;
- extern PyTypeObject DescriptorSequence_Type;
- // A sequence container can only be equal to another sequence container, or (for
- // backward compatibility) to a list containing the same items.
- // Returns 1 if equal, 0 if unequal, -1 on error.
- static int DescriptorSequence_Equal(PyContainer* self, PyObject* other) {
- // Check the identity of C++ pointers.
- if (PyObject_TypeCheck(other, &DescriptorSequence_Type)) {
- PyContainer* other_container = reinterpret_cast<PyContainer*>(other);
- if (self->descriptor == other_container->descriptor &&
- self->container_def == other_container->container_def &&
- self->kind == other_container->kind) {
- return 1;
- } else {
- return 0;
- }
- }
- // If other is a list
- if (PyList_Check(other)) {
- // return list(self) == other
- int size = Length(self);
- if (size != PyList_Size(other)) {
- return false;
- }
- for (int index = 0; index < size; index++) {
- ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index));
- if (value1 == NULL) {
- return -1;
- }
- PyObject* value2 = PyList_GetItem(other, index);
- if (value2 == NULL) {
- return -1;
- }
- int cmp = PyObject_RichCompareBool(value1.get(), value2, Py_EQ);
- if (cmp != 1) // error or not equal
- return cmp;
- }
- // All items were found and equal
- return 1;
- }
- // Any other object is different.
- return 0;
- }
- // A mapping container can only be equal to another mapping container, or (for
- // backward compatibility) to a dict containing the same items.
- // Returns 1 if equal, 0 if unequal, -1 on error.
- static int DescriptorMapping_Equal(PyContainer* self, PyObject* other) {
- // Check the identity of C++ pointers.
- if (PyObject_TypeCheck(other, &DescriptorMapping_Type)) {
- PyContainer* other_container = reinterpret_cast<PyContainer*>(other);
- if (self->descriptor == other_container->descriptor &&
- self->container_def == other_container->container_def &&
- self->kind == other_container->kind) {
- return 1;
- } else {
- return 0;
- }
- }
- // If other is a dict
- if (PyDict_Check(other)) {
- // equivalent to dict(self.items()) == other
- int size = Length(self);
- if (size != PyDict_Size(other)) {
- return false;
- }
- for (int index = 0; index < size; index++) {
- ScopedPyObjectPtr key(_NewKey_ByIndex(self, index));
- if (key == NULL) {
- return -1;
- }
- ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index));
- if (value1 == NULL) {
- return -1;
- }
- PyObject* value2 = PyDict_GetItem(other, key.get());
- if (value2 == NULL) {
- // Not found in the other dictionary
- return 0;
- }
- int cmp = PyObject_RichCompareBool(value1.get(), value2, Py_EQ);
- if (cmp != 1) // error or not equal
- return cmp;
- }
- // All items were found and equal
- return 1;
- }
- // Any other object is different.
- return 0;
- }
- static PyObject* RichCompare(PyContainer* self, PyObject* other, int opid) {
- if (opid != Py_EQ && opid != Py_NE) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- int result;
- if (self->kind == PyContainer::KIND_SEQUENCE) {
- result = DescriptorSequence_Equal(self, other);
- } else {
- result = DescriptorMapping_Equal(self, other);
- }
- if (result < 0) {
- return NULL;
- }
- if (result ^ (opid == Py_NE)) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
- }
- static PySequenceMethods MappingSequenceMethods = {
- 0, // sq_length
- 0, // sq_concat
- 0, // sq_repeat
- 0, // sq_item
- 0, // sq_slice
- 0, // sq_ass_item
- 0, // sq_ass_slice
- (objobjproc)Contains, // sq_contains
- };
- static PyObject* Get(PyContainer* self, PyObject* args) {
- PyObject* key;
- PyObject* default_value = Py_None;
- if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
- return NULL;
- }
- const void* item;
- if (!_GetItemByKey(self, key, &item)) {
- return NULL;
- }
- if (item == NULL) {
- Py_INCREF(default_value);
- return default_value;
- }
- return self->container_def->new_object_from_item_fn(item);
- }
- static PyObject* Keys(PyContainer* self, PyObject* args) {
- Py_ssize_t count = Length(self);
- ScopedPyObjectPtr list(PyList_New(count));
- if (list == NULL) {
- return NULL;
- }
- for (Py_ssize_t index = 0; index < count; ++index) {
- PyObject* key = _NewKey_ByIndex(self, index);
- if (key == NULL) {
- return NULL;
- }
- PyList_SET_ITEM(list.get(), index, key);
- }
- return list.release();
- }
- static PyObject* Values(PyContainer* self, PyObject* args) {
- Py_ssize_t count = Length(self);
- ScopedPyObjectPtr list(PyList_New(count));
- if (list == NULL) {
- return NULL;
- }
- for (Py_ssize_t index = 0; index < count; ++index) {
- PyObject* value = _NewObj_ByIndex(self, index);
- if (value == NULL) {
- return NULL;
- }
- PyList_SET_ITEM(list.get(), index, value);
- }
- return list.release();
- }
- static PyObject* Items(PyContainer* self, PyObject* args) {
- Py_ssize_t count = Length(self);
- ScopedPyObjectPtr list(PyList_New(count));
- if (list == NULL) {
- return NULL;
- }
- for (Py_ssize_t index = 0; index < count; ++index) {
- ScopedPyObjectPtr obj(PyTuple_New(2));
- if (obj == NULL) {
- return NULL;
- }
- PyObject* key = _NewKey_ByIndex(self, index);
- if (key == NULL) {
- return NULL;
- }
- PyTuple_SET_ITEM(obj.get(), 0, key);
- PyObject* value = _NewObj_ByIndex(self, index);
- if (value == NULL) {
- return NULL;
- }
- PyTuple_SET_ITEM(obj.get(), 1, value);
- PyList_SET_ITEM(list.get(), index, obj.release());
- }
- return list.release();
- }
- static PyObject* NewContainerIterator(PyContainer* mapping,
- PyContainerIterator::IterKind kind);
- static PyObject* Iter(PyContainer* self) {
- return NewContainerIterator(self, PyContainerIterator::KIND_ITERKEY);
- }
- static PyObject* IterKeys(PyContainer* self, PyObject* args) {
- return NewContainerIterator(self, PyContainerIterator::KIND_ITERKEY);
- }
- static PyObject* IterValues(PyContainer* self, PyObject* args) {
- return NewContainerIterator(self, PyContainerIterator::KIND_ITERVALUE);
- }
- static PyObject* IterItems(PyContainer* self, PyObject* args) {
- return NewContainerIterator(self, PyContainerIterator::KIND_ITERITEM);
- }
- static PyMethodDef MappingMethods[] = {
- { "get", (PyCFunction)Get, METH_VARARGS, },
- { "keys", (PyCFunction)Keys, METH_NOARGS, },
- { "values", (PyCFunction)Values, METH_NOARGS, },
- { "items", (PyCFunction)Items, METH_NOARGS, },
- { "iterkeys", (PyCFunction)IterKeys, METH_NOARGS, },
- { "itervalues", (PyCFunction)IterValues, METH_NOARGS, },
- { "iteritems", (PyCFunction)IterItems, METH_NOARGS, },
- {NULL}
- };
- PyTypeObject DescriptorMapping_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "DescriptorMapping", // tp_name
- sizeof(PyContainer), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- (reprfunc)ContainerRepr, // tp_repr
- 0, // tp_as_number
- &MappingSequenceMethods, // tp_as_sequence
- &MappingMappingMethods, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- 0, // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- (richcmpfunc)RichCompare, // tp_richcompare
- 0, // tp_weaklistoffset
- (getiterfunc)Iter, // tp_iter
- 0, // tp_iternext
- MappingMethods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- 0, // tp_alloc
- 0, // tp_new
- 0, // tp_free
- };
- // The DescriptorSequence type.
- static PyObject* GetItem(PyContainer* self, Py_ssize_t index) {
- if (index < 0) {
- index += Length(self);
- }
- if (index < 0 || index >= Length(self)) {
- PyErr_SetString(PyExc_IndexError, "index out of range");
- return NULL;
- }
- return _NewObj_ByIndex(self, index);
- }
- static PyObject *
- SeqSubscript(PyContainer* self, PyObject* item) {
- if (PyIndex_Check(item)) {
- Py_ssize_t index;
- index = PyNumber_AsSsize_t(item, PyExc_IndexError);
- if (index == -1 && PyErr_Occurred())
- return NULL;
- return GetItem(self, index);
- }
- // Materialize the list and delegate the operation to it.
- ScopedPyObjectPtr list(PyObject_CallFunctionObjArgs(
- reinterpret_cast<PyObject*>(&PyList_Type), self, NULL));
- if (list == NULL) {
- return NULL;
- }
- return Py_TYPE(list.get())->tp_as_mapping->mp_subscript(list.get(), item);
- }
- // Returns the position of the item in the sequence, of -1 if not found.
- // This function never fails.
- int Find(PyContainer* self, PyObject* item) {
- // The item can only be in one position: item.index.
- // Check that self[item.index] == item, it's faster than a linear search.
- //
- // This assumes that sequences are only defined by syntax of the .proto file:
- // a specific item belongs to only one sequence, depending on its position in
- // the .proto file definition.
- const void* descriptor_ptr = PyDescriptor_AsVoidPtr(item);
- if (descriptor_ptr == NULL) {
- PyErr_Clear();
- // Not a descriptor, it cannot be in the list.
- return -1;
- }
- if (self->container_def->get_item_index_fn) {
- int index = self->container_def->get_item_index_fn(descriptor_ptr);
- if (index < 0 || index >= Length(self)) {
- // This index is not from this collection.
- return -1;
- }
- if (self->container_def->get_by_index_fn(self, index) != descriptor_ptr) {
- // The descriptor at this index is not the same.
- return -1;
- }
- // self[item.index] == item, so return the index.
- return index;
- } else {
- // Fall back to linear search.
- int length = Length(self);
- for (int index=0; index < length; index++) {
- if (self->container_def->get_by_index_fn(self, index) == descriptor_ptr) {
- return index;
- }
- }
- // Not found
- return -1;
- }
- }
- // Implements list.index(): the position of the item is in the sequence.
- static PyObject* Index(PyContainer* self, PyObject* item) {
- int position = Find(self, item);
- if (position < 0) {
- // Not found
- PyErr_SetNone(PyExc_ValueError);
- return NULL;
- } else {
- return PyInt_FromLong(position);
- }
- }
- // Implements "list.__contains__()": is the object in the sequence.
- static int SeqContains(PyContainer* self, PyObject* item) {
- int position = Find(self, item);
- if (position < 0) {
- return 0;
- } else {
- return 1;
- }
- }
- // Implements list.count(): number of occurrences of the item in the sequence.
- // An item can only appear once in a sequence. If it exists, return 1.
- static PyObject* Count(PyContainer* self, PyObject* item) {
- int position = Find(self, item);
- if (position < 0) {
- return PyInt_FromLong(0);
- } else {
- return PyInt_FromLong(1);
- }
- }
- static PyObject* Append(PyContainer* self, PyObject* args) {
- if (_CalledFromGeneratedFile(0)) {
- Py_RETURN_NONE;
- }
- PyErr_Format(PyExc_TypeError,
- "'%.200s' object is not a mutable sequence",
- Py_TYPE(self)->tp_name);
- return NULL;
- }
- static PyObject* Reversed(PyContainer* self, PyObject* args) {
- return NewContainerIterator(self,
- PyContainerIterator::KIND_ITERVALUE_REVERSED);
- }
- static PyMethodDef SeqMethods[] = {
- { "index", (PyCFunction)Index, METH_O, },
- { "count", (PyCFunction)Count, METH_O, },
- { "append", (PyCFunction)Append, METH_O, },
- { "__reversed__", (PyCFunction)Reversed, METH_NOARGS, },
- {NULL}
- };
- static PySequenceMethods SeqSequenceMethods = {
- (lenfunc)Length, // sq_length
- 0, // sq_concat
- 0, // sq_repeat
- (ssizeargfunc)GetItem, // sq_item
- 0, // sq_slice
- 0, // sq_ass_item
- 0, // sq_ass_slice
- (objobjproc)SeqContains, // sq_contains
- };
- static PyMappingMethods SeqMappingMethods = {
- (lenfunc)Length, // mp_length
- (binaryfunc)SeqSubscript, // mp_subscript
- 0, // mp_ass_subscript
- };
- PyTypeObject DescriptorSequence_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "DescriptorSequence", // tp_name
- sizeof(PyContainer), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- (reprfunc)ContainerRepr, // tp_repr
- 0, // tp_as_number
- &SeqSequenceMethods, // tp_as_sequence
- &SeqMappingMethods, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- 0, // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- (richcmpfunc)RichCompare, // tp_richcompare
- 0, // tp_weaklistoffset
- 0, // tp_iter
- 0, // tp_iternext
- SeqMethods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- 0, // tp_alloc
- 0, // tp_new
- 0, // tp_free
- };
- static PyObject* NewMappingByName(
- DescriptorContainerDef* container_def, const void* descriptor) {
- PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
- if (self == NULL) {
- return NULL;
- }
- self->descriptor = descriptor;
- self->container_def = container_def;
- self->kind = PyContainer::KIND_BYNAME;
- return reinterpret_cast<PyObject*>(self);
- }
- static PyObject* NewMappingByCamelcaseName(
- DescriptorContainerDef* container_def, const void* descriptor) {
- PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
- if (self == NULL) {
- return NULL;
- }
- self->descriptor = descriptor;
- self->container_def = container_def;
- self->kind = PyContainer::KIND_BYCAMELCASENAME;
- return reinterpret_cast<PyObject*>(self);
- }
- static PyObject* NewMappingByNumber(
- DescriptorContainerDef* container_def, const void* descriptor) {
- if (container_def->get_by_number_fn == NULL ||
- container_def->get_item_number_fn == NULL) {
- PyErr_SetNone(PyExc_NotImplementedError);
- return NULL;
- }
- PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type);
- if (self == NULL) {
- return NULL;
- }
- self->descriptor = descriptor;
- self->container_def = container_def;
- self->kind = PyContainer::KIND_BYNUMBER;
- return reinterpret_cast<PyObject*>(self);
- }
- static PyObject* NewSequence(
- DescriptorContainerDef* container_def, const void* descriptor) {
- PyContainer* self = PyObject_New(PyContainer, &DescriptorSequence_Type);
- if (self == NULL) {
- return NULL;
- }
- self->descriptor = descriptor;
- self->container_def = container_def;
- self->kind = PyContainer::KIND_SEQUENCE;
- return reinterpret_cast<PyObject*>(self);
- }
- // Implement iterators over PyContainers.
- static void Iterator_Dealloc(PyContainerIterator* self) {
- Py_CLEAR(self->container);
- Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
- }
- static PyObject* Iterator_Next(PyContainerIterator* self) {
- int count = self->container->container_def->count_fn(self->container);
- if (self->index >= count) {
- // Return NULL with no exception to indicate the end.
- return NULL;
- }
- int index = self->index;
- self->index += 1;
- switch (self->kind) {
- case PyContainerIterator::KIND_ITERKEY:
- return _NewKey_ByIndex(self->container, index);
- case PyContainerIterator::KIND_ITERVALUE:
- return _NewObj_ByIndex(self->container, index);
- case PyContainerIterator::KIND_ITERVALUE_REVERSED:
- return _NewObj_ByIndex(self->container, count - index - 1);
- case PyContainerIterator::KIND_ITERITEM:
- {
- PyObject* obj = PyTuple_New(2);
- if (obj == NULL) {
- return NULL;
- }
- PyObject* key = _NewKey_ByIndex(self->container, index);
- if (key == NULL) {
- Py_DECREF(obj);
- return NULL;
- }
- PyTuple_SET_ITEM(obj, 0, key);
- PyObject* value = _NewObj_ByIndex(self->container, index);
- if (value == NULL) {
- Py_DECREF(obj);
- return NULL;
- }
- PyTuple_SET_ITEM(obj, 1, value);
- return obj;
- }
- default:
- PyErr_SetNone(PyExc_NotImplementedError);
- return NULL;
- }
- }
- static PyTypeObject ContainerIterator_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "DescriptorContainerIterator", // tp_name
- sizeof(PyContainerIterator), // tp_basicsize
- 0, // tp_itemsize
- (destructor)Iterator_Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- 0, // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- PyObject_SelfIter, // tp_iter
- (iternextfunc)Iterator_Next, // tp_iternext
- 0, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- 0, // tp_alloc
- 0, // tp_new
- 0, // tp_free
- };
- static PyObject* NewContainerIterator(PyContainer* container,
- PyContainerIterator::IterKind kind) {
- PyContainerIterator* self = PyObject_New(PyContainerIterator,
- &ContainerIterator_Type);
- if (self == NULL) {
- return NULL;
- }
- Py_INCREF(container);
- self->container = container;
- self->kind = kind;
- self->index = 0;
- return reinterpret_cast<PyObject*>(self);
- }
- } // namespace descriptor
- // Now define the real collections!
- namespace message_descriptor {
- typedef const Descriptor* ParentDescriptor;
- static ParentDescriptor GetDescriptor(PyContainer* self) {
- return reinterpret_cast<ParentDescriptor>(self->descriptor);
- }
- namespace fields {
- typedef const FieldDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->field_count();
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindFieldByName(name);
- }
- static const void* GetByCamelcaseName(PyContainer* self,
- ConstStringParam name) {
- return GetDescriptor(self)->FindFieldByCamelcaseName(name);
- }
- static const void* GetByNumber(PyContainer* self, int number) {
- return GetDescriptor(self)->FindFieldByNumber(number);
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->field(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyFieldDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static const std::string& GetItemCamelcaseName(const void* item) {
- return static_cast<ItemDescriptor>(item)->camelcase_name();
- }
- static int GetItemNumber(const void* item) {
- return static_cast<ItemDescriptor>(item)->number();
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index();
- }
- static DescriptorContainerDef ContainerDef = {
- "MessageFields",
- Count,
- GetByIndex,
- GetByName,
- GetByCamelcaseName,
- GetByNumber,
- NewObjectFromItem,
- GetItemName,
- GetItemCamelcaseName,
- GetItemNumber,
- GetItemIndex,
- };
- } // namespace fields
- PyObject* NewMessageFieldsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&fields::ContainerDef, descriptor);
- }
- PyObject* NewMessageFieldsByCamelcaseName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByCamelcaseName(&fields::ContainerDef,
- descriptor);
- }
- PyObject* NewMessageFieldsByNumber(ParentDescriptor descriptor) {
- return descriptor::NewMappingByNumber(&fields::ContainerDef, descriptor);
- }
- PyObject* NewMessageFieldsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&fields::ContainerDef, descriptor);
- }
- namespace nested_types {
- typedef const Descriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->nested_type_count();
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindNestedTypeByName(name);
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->nested_type(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyMessageDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index();
- }
- static DescriptorContainerDef ContainerDef = {
- "MessageNestedTypes",
- Count,
- GetByIndex,
- GetByName,
- NULL,
- NULL,
- NewObjectFromItem,
- GetItemName,
- NULL,
- NULL,
- GetItemIndex,
- };
- } // namespace nested_types
- PyObject* NewMessageNestedTypesSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&nested_types::ContainerDef, descriptor);
- }
- PyObject* NewMessageNestedTypesByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&nested_types::ContainerDef, descriptor);
- }
- namespace enums {
- typedef const EnumDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->enum_type_count();
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindEnumTypeByName(name);
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->enum_type(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyEnumDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index();
- }
- static DescriptorContainerDef ContainerDef = {
- "MessageNestedEnums",
- Count,
- GetByIndex,
- GetByName,
- NULL,
- NULL,
- NewObjectFromItem,
- GetItemName,
- NULL,
- NULL,
- GetItemIndex,
- };
- } // namespace enums
- PyObject* NewMessageEnumsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&enums::ContainerDef, descriptor);
- }
- PyObject* NewMessageEnumsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&enums::ContainerDef, descriptor);
- }
- namespace enumvalues {
- // This is the "enum_values_by_name" mapping, which collects values from all
- // enum types in a message.
- //
- // Note that the behavior of the C++ descriptor is different: it will search and
- // return the first value that matches the name, whereas the Python
- // implementation retrieves the last one.
- typedef const EnumValueDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- int count = 0;
- for (int i = 0; i < GetDescriptor(self)->enum_type_count(); ++i) {
- count += GetDescriptor(self)->enum_type(i)->value_count();
- }
- return count;
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindEnumValueByName(name);
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- // This is not optimal, but the number of enums *types* in a given message
- // is small. This function is only used when iterating over the mapping.
- const EnumDescriptor* enum_type = NULL;
- int enum_type_count = GetDescriptor(self)->enum_type_count();
- for (int i = 0; i < enum_type_count; ++i) {
- enum_type = GetDescriptor(self)->enum_type(i);
- int enum_value_count = enum_type->value_count();
- if (index < enum_value_count) {
- // Found it!
- break;
- }
- index -= enum_value_count;
- }
- // The next statement cannot overflow, because this function is only called by
- // internal iterators which ensure that 0 <= index < Count().
- return enum_type->value(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyEnumValueDescriptor_FromDescriptor(
- static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static DescriptorContainerDef ContainerDef = {
- "MessageEnumValues",
- Count,
- GetByIndex,
- GetByName,
- NULL,
- NULL,
- NewObjectFromItem,
- GetItemName,
- NULL,
- NULL,
- NULL,
- };
- } // namespace enumvalues
- PyObject* NewMessageEnumValuesByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&enumvalues::ContainerDef, descriptor);
- }
- namespace extensions {
- typedef const FieldDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->extension_count();
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindExtensionByName(name);
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->extension(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyFieldDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index();
- }
- static DescriptorContainerDef ContainerDef = {
- "MessageExtensions",
- Count,
- GetByIndex,
- GetByName,
- NULL,
- NULL,
- NewObjectFromItem,
- GetItemName,
- NULL,
- NULL,
- GetItemIndex,
- };
- } // namespace extensions
- PyObject* NewMessageExtensionsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&extensions::ContainerDef, descriptor);
- }
- PyObject* NewMessageExtensionsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&extensions::ContainerDef, descriptor);
- }
- namespace oneofs {
- typedef const OneofDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->oneof_decl_count();
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindOneofByName(name);
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->oneof_decl(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyOneofDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index();
- }
- static DescriptorContainerDef ContainerDef = {
- "MessageOneofs",
- Count,
- GetByIndex,
- GetByName,
- NULL,
- NULL,
- NewObjectFromItem,
- GetItemName,
- NULL,
- NULL,
- GetItemIndex,
- };
- } // namespace oneofs
- PyObject* NewMessageOneofsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&oneofs::ContainerDef, descriptor);
- }
- PyObject* NewMessageOneofsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&oneofs::ContainerDef, descriptor);
- }
- } // namespace message_descriptor
- namespace enum_descriptor {
- typedef const EnumDescriptor* ParentDescriptor;
- static ParentDescriptor GetDescriptor(PyContainer* self) {
- return reinterpret_cast<ParentDescriptor>(self->descriptor);
- }
- namespace enumvalues {
- typedef const EnumValueDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->value_count();
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->value(index);
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindValueByName(name);
- }
- static const void* GetByNumber(PyContainer* self, int number) {
- return GetDescriptor(self)->FindValueByNumber(number);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyEnumValueDescriptor_FromDescriptor(
- static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static int GetItemNumber(const void* item) {
- return static_cast<ItemDescriptor>(item)->number();
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index();
- }
- static DescriptorContainerDef ContainerDef = {
- "EnumValues",
- Count,
- GetByIndex,
- GetByName,
- NULL,
- GetByNumber,
- NewObjectFromItem,
- GetItemName,
- NULL,
- GetItemNumber,
- GetItemIndex,
- };
- } // namespace enumvalues
- PyObject* NewEnumValuesByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&enumvalues::ContainerDef, descriptor);
- }
- PyObject* NewEnumValuesByNumber(ParentDescriptor descriptor) {
- return descriptor::NewMappingByNumber(&enumvalues::ContainerDef, descriptor);
- }
- PyObject* NewEnumValuesSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&enumvalues::ContainerDef, descriptor);
- }
- } // namespace enum_descriptor
- namespace oneof_descriptor {
- typedef const OneofDescriptor* ParentDescriptor;
- static ParentDescriptor GetDescriptor(PyContainer* self) {
- return reinterpret_cast<ParentDescriptor>(self->descriptor);
- }
- namespace fields {
- typedef const FieldDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->field_count();
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->field(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyFieldDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index_in_oneof();
- }
- static DescriptorContainerDef ContainerDef = {
- "OneofFields",
- Count,
- GetByIndex,
- NULL,
- NULL,
- NULL,
- NewObjectFromItem,
- NULL,
- NULL,
- NULL,
- GetItemIndex,
- };
- } // namespace fields
- PyObject* NewOneofFieldsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&fields::ContainerDef, descriptor);
- }
- } // namespace oneof_descriptor
- namespace service_descriptor {
- typedef const ServiceDescriptor* ParentDescriptor;
- static ParentDescriptor GetDescriptor(PyContainer* self) {
- return reinterpret_cast<ParentDescriptor>(self->descriptor);
- }
- namespace methods {
- typedef const MethodDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->method_count();
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindMethodByName(name);
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->method(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyMethodDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index();
- }
- static DescriptorContainerDef ContainerDef = {
- "ServiceMethods",
- Count,
- GetByIndex,
- GetByName,
- NULL,
- NULL,
- NewObjectFromItem,
- GetItemName,
- NULL,
- NULL,
- GetItemIndex,
- };
- } // namespace methods
- PyObject* NewServiceMethodsSeq(ParentDescriptor descriptor) {
- return descriptor::NewSequence(&methods::ContainerDef, descriptor);
- }
- PyObject* NewServiceMethodsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&methods::ContainerDef, descriptor);
- }
- } // namespace service_descriptor
- namespace file_descriptor {
- typedef const FileDescriptor* ParentDescriptor;
- static ParentDescriptor GetDescriptor(PyContainer* self) {
- return reinterpret_cast<ParentDescriptor>(self->descriptor);
- }
- namespace messages {
- typedef const Descriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->message_type_count();
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindMessageTypeByName(name);
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->message_type(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyMessageDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index();
- }
- static DescriptorContainerDef ContainerDef = {
- "FileMessages",
- Count,
- GetByIndex,
- GetByName,
- NULL,
- NULL,
- NewObjectFromItem,
- GetItemName,
- NULL,
- NULL,
- GetItemIndex,
- };
- } // namespace messages
- PyObject* NewFileMessageTypesByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&messages::ContainerDef, descriptor);
- }
- namespace enums {
- typedef const EnumDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->enum_type_count();
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindEnumTypeByName(name);
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->enum_type(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyEnumDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index();
- }
- static DescriptorContainerDef ContainerDef = {
- "FileEnums",
- Count,
- GetByIndex,
- GetByName,
- NULL,
- NULL,
- NewObjectFromItem,
- GetItemName,
- NULL,
- NULL,
- GetItemIndex,
- };
- } // namespace enums
- PyObject* NewFileEnumTypesByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&enums::ContainerDef, descriptor);
- }
- namespace extensions {
- typedef const FieldDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->extension_count();
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindExtensionByName(name);
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->extension(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyFieldDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index();
- }
- static DescriptorContainerDef ContainerDef = {
- "FileExtensions",
- Count,
- GetByIndex,
- GetByName,
- NULL,
- NULL,
- NewObjectFromItem,
- GetItemName,
- NULL,
- NULL,
- GetItemIndex,
- };
- } // namespace extensions
- PyObject* NewFileExtensionsByName(ParentDescriptor descriptor) {
- return descriptor::NewMappingByName(&extensions::ContainerDef, descriptor);
- }
- namespace services {
- typedef const ServiceDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->service_count();
- }
- static const void* GetByName(PyContainer* self, ConstStringParam name) {
- return GetDescriptor(self)->FindServiceByName(name);
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->service(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyServiceDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static const std::string& GetItemName(const void* item) {
- return static_cast<ItemDescriptor>(item)->name();
- }
- static int GetItemIndex(const void* item) {
- return static_cast<ItemDescriptor>(item)->index();
- }
- static DescriptorContainerDef ContainerDef = {
- "FileServices",
- Count,
- GetByIndex,
- GetByName,
- NULL,
- NULL,
- NewObjectFromItem,
- GetItemName,
- NULL,
- NULL,
- GetItemIndex,
- };
- } // namespace services
- PyObject* NewFileServicesByName(const FileDescriptor* descriptor) {
- return descriptor::NewMappingByName(&services::ContainerDef, descriptor);
- }
- namespace dependencies {
- typedef const FileDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->dependency_count();
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->dependency(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyFileDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static DescriptorContainerDef ContainerDef = {
- "FileDependencies",
- Count,
- GetByIndex,
- NULL,
- NULL,
- NULL,
- NewObjectFromItem,
- NULL,
- NULL,
- NULL,
- NULL,
- };
- } // namespace dependencies
- PyObject* NewFileDependencies(const FileDescriptor* descriptor) {
- return descriptor::NewSequence(&dependencies::ContainerDef, descriptor);
- }
- namespace public_dependencies {
- typedef const FileDescriptor* ItemDescriptor;
- static int Count(PyContainer* self) {
- return GetDescriptor(self)->public_dependency_count();
- }
- static const void* GetByIndex(PyContainer* self, int index) {
- return GetDescriptor(self)->public_dependency(index);
- }
- static PyObject* NewObjectFromItem(const void* item) {
- return PyFileDescriptor_FromDescriptor(static_cast<ItemDescriptor>(item));
- }
- static DescriptorContainerDef ContainerDef = {
- "FilePublicDependencies",
- Count,
- GetByIndex,
- NULL,
- NULL,
- NULL,
- NewObjectFromItem,
- NULL,
- NULL,
- NULL,
- NULL,
- };
- } // namespace public_dependencies
- PyObject* NewFilePublicDependencies(const FileDescriptor* descriptor) {
- return descriptor::NewSequence(&public_dependencies::ContainerDef,
- descriptor);
- }
- } // namespace file_descriptor
- // Register all implementations
- bool InitDescriptorMappingTypes() {
- if (PyType_Ready(&descriptor::DescriptorMapping_Type) < 0)
- return false;
- if (PyType_Ready(&descriptor::DescriptorSequence_Type) < 0)
- return false;
- if (PyType_Ready(&descriptor::ContainerIterator_Type) < 0)
- return false;
- return true;
- }
- } // namespace python
- } // namespace protobuf
- } // namespace google
|