| /* |
| * 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; |
| } |