/* * Copyright (c) 2009-2021, Google LLC * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Google LLC nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "python/descriptor.h" #include "python/protobuf.h" #include "upb/def.h" // ----------------------------------------------------------------------------- // DescriptorBase // ----------------------------------------------------------------------------- // This representation is used by all concrete descriptors. typedef struct { PyObject_HEAD PyObject *pool; // We own a ref. const void *def; // Type depends on the class. Kept alive by "pool". } PyUpb_DescriptorBase; PyObject *PyUpb_AnyDescriptor_GetPool(PyObject *desc) { PyUpb_DescriptorBase *base = (void *)desc; return base->pool; } static PyObject *PyUpb_DescriptorBase_New(PyTypeObject *subtype, PyObject *args, PyObject *kwds) { return PyErr_Format(PyExc_RuntimeError, "Creating descriptors directly is not allowed."); } static PyObject *PyUpb_DescriptorBase_NewInternal(PyTypeObject *type, const void *def, PyObject *pool) { PyUpb_DescriptorBase *base = (PyUpb_DescriptorBase *)PyUpb_ObjCache_Get(def); if (!base) { base = PyObject_New(PyUpb_DescriptorBase, type); base->pool = pool; base->def = def; Py_INCREF(pool); PyUpb_ObjCache_Add(def, &base->ob_base); } return &base->ob_base; } static void PyUpb_DescriptorBase_Dealloc(PyUpb_DescriptorBase *self) { PyUpb_DescriptorBase *base = (PyUpb_DescriptorBase *)self; PyUpb_ObjCache_Delete(base->def); Py_CLEAR(base->pool); PyObject_Del(self); } #define DESCRIPTOR_BASE_SLOTS \ {Py_tp_new, (void *)&PyUpb_DescriptorBase_New}, \ {Py_tp_dealloc, (void *)&PyUpb_DescriptorBase_Dealloc} // ----------------------------------------------------------------------------- // FieldDescriptor // ----------------------------------------------------------------------------- static PyObject *PyUpb_FieldDescriptor_GetType(PyUpb_DescriptorBase *self, void *closure) { return PyLong_FromLong(upb_fielddef_descriptortype(self->def)); } static PyObject *PyUpb_FieldDescriptor_GetLabel(PyUpb_DescriptorBase *self, void *closure) { return PyLong_FromLong(upb_fielddef_label(self->def)); } static PyObject *PyUpb_FieldDescriptor_GetNumber(PyUpb_DescriptorBase *self, void *closure) { return PyLong_FromLong(upb_fielddef_number(self->def)); } static PyGetSetDef PyUpb_FieldDescriptor_Getters[] = { /* { "full_name", (getter)GetFullName, NULL, "Full name"}, { "name", (getter)GetName, NULL, "Unqualified name"}, { "camelcase_name", (getter)GetCamelcaseName, NULL, "Camelcase name"}, { "json_name", (getter)GetJsonName, NULL, "Json name"}, { "file", (getter)GetFile, NULL, "File Descriptor"}, */ {"type", (getter)PyUpb_FieldDescriptor_GetType, NULL, "Type"}, /* { "cpp_type", (getter)PyUpb_FieldDescriptor_GetCppType, NULL, "C++ Type"}, */ {"label", (getter)PyUpb_FieldDescriptor_GetLabel, NULL, "Label"}, {"number", (getter)PyUpb_FieldDescriptor_GetNumber, NULL, "Number"}, /* { "index", (getter)GetIndex, NULL, "Index"}, { "default_value", (getter)GetDefaultValue, NULL, "Default Value"}, { "has_default_value", (getter)HasDefaultValue}, { "is_extension", (getter)IsExtension, NULL, "ID"}, { "id", (getter)GetID, NULL, "ID"}, { "_cdescriptor", (getter)GetCDescriptor, NULL, "HAACK REMOVE ME"}, { "message_type", (getter)GetMessageType, (setter)SetMessageType, "Message type"}, { "enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"}, { "containing_type", (getter)GetContainingType, (setter)SetContainingType, "Containing type"}, { "extension_scope", (getter)GetExtensionScope, (setter)NULL, "Extension scope"}, { "containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof, "Containing oneof"}, { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, { "_options", (getter)NULL, (setter)SetOptions, "Options"}, { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, "Serialized Options"}, */ {NULL}}; static PyMethodDef PyUpb_FieldDescriptor_Methods[] = { /* { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, */ {NULL}}; static PyType_Slot PyUpb_FieldDescriptor_Slots[] = { DESCRIPTOR_BASE_SLOTS, {Py_tp_methods, PyUpb_FieldDescriptor_Methods}, {Py_tp_getset, PyUpb_FieldDescriptor_Getters}, {0, NULL}}; static PyType_Spec PyUpb_FieldDescriptor_Spec = { PYUPB_MODULE_NAME ".FieldDescriptor", sizeof(PyUpb_DescriptorBase), 0, // tp_itemsize Py_TPFLAGS_DEFAULT, PyUpb_FieldDescriptor_Slots, }; PyObject *PyUpb_FieldDescriptor_GetOrCreateWrapper(const upb_fielddef *field, PyObject *pool) { PyUpb_ModuleState *state = PyUpb_ModuleState_Get(); return PyUpb_DescriptorBase_NewInternal(state->field_descriptor_type, field, pool); } // ----------------------------------------------------------------------------- // FileDescriptor // ----------------------------------------------------------------------------- // static PyObject *PyUpb_FileDescriptor_GetName(PyUpb_DescriptorBase *self, void *closure) { return PyUnicode_FromString(upb_filedef_name(self->def)); } static PyGetSetDef PyUpb_FileDescriptor_Getters[] = { /* { "pool", (getter)GetPool, NULL, "pool"}, */ {"name", (getter)PyUpb_FileDescriptor_GetName, NULL, "name"}, /* { "package", (getter)GetPackage, NULL, "package"}, { "serialized_pb", (getter)GetSerializedPb}, { "message_types_by_name", PyUpb_FileDescriptor_GetMessageTypesByName, NULL, "Messages by name"}, { "enum_types_by_name", PyUpb_FileDescriptor_GetEnumTypesByName, NULL, "Enums by name"}, { "extensions_by_name", (getter)GetExtensionsByName, NULL, "Extensions by name"}, { "services_by_name", (getter)GetServicesByName, NULL, "Services by name"}, { "dependencies", (getter)GetDependencies, NULL, "Dependencies"}, { "public_dependencies", (getter)GetPublicDependencies, NULL, "Dependencies"}, { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, { "_options", (getter)NULL, (setter)SetOptions, "Options"}, { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, "Serialized Options"}, { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"}, */ {NULL}}; static PyMethodDef PyUpb_FileDescriptor_Methods[] = { /* { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, */ {NULL}}; static PyType_Slot PyUpb_FileDescriptor_Slots[] = { DESCRIPTOR_BASE_SLOTS, {Py_tp_methods, PyUpb_FileDescriptor_Methods}, {Py_tp_getset, PyUpb_FileDescriptor_Getters}, {0, NULL}}; static PyType_Spec PyUpb_FileDescriptor_Spec = { PYUPB_MODULE_NAME ".FileDescriptor", // tp_name sizeof(PyUpb_DescriptorBase), // tp_basicsize 0, // tp_itemsize Py_TPFLAGS_DEFAULT, // tp_flags PyUpb_FileDescriptor_Slots, }; PyObject *PyUpb_FileDescriptor_GetOrCreateWrapper(const upb_filedef *file, PyObject *pool) { PyUpb_ModuleState *state = PyUpb_ModuleState_Get(); return PyUpb_DescriptorBase_NewInternal(state->file_descriptor_type, file, pool); } const upb_filedef *PyUpb_FileDescriptor_GetDef(PyObject *_self) { PyUpb_DescriptorBase *self = (void *)_self; return self->def; } // ----------------------------------------------------------------------------- // Top Level // ----------------------------------------------------------------------------- bool PyUpb_InitDescriptor(PyObject *m) { PyUpb_ModuleState *s = PyUpb_ModuleState_Get(); s->field_descriptor_type = AddObject(m, "FieldDescriptor", &PyUpb_FieldDescriptor_Spec); s->file_descriptor_type = AddObject(m, "FileDescriptor", &PyUpb_FileDescriptor_Spec); return s->field_descriptor_type && s->file_descriptor_type; }