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
31 #include <google/protobuf/pyext/field.h>
32
33 #include <google/protobuf/descriptor.h>
34 #include <google/protobuf/pyext/descriptor.h>
35 #include <google/protobuf/pyext/message.h>
36
37 #if PY_MAJOR_VERSION >= 3
38 #define PyString_FromFormat PyUnicode_FromFormat
39 #endif
40
41 namespace google {
42 namespace protobuf {
43 namespace python {
44
45 namespace field {
46
Repr(PyMessageFieldProperty * self)47 static PyObject* Repr(PyMessageFieldProperty* self) {
48 return PyString_FromFormat("<field property '%s'>",
49 self->field_descriptor->full_name().c_str());
50 }
51
DescrGet(PyMessageFieldProperty * self,PyObject * obj,PyObject * type)52 static PyObject* DescrGet(PyMessageFieldProperty* self, PyObject* obj,
53 PyObject* type) {
54 if (obj == NULL) {
55 Py_INCREF(self);
56 return reinterpret_cast<PyObject*>(self);
57 }
58 return cmessage::GetFieldValue(reinterpret_cast<CMessage*>(obj),
59 self->field_descriptor);
60 }
61
DescrSet(PyMessageFieldProperty * self,PyObject * obj,PyObject * value)62 static int DescrSet(PyMessageFieldProperty* self, PyObject* obj,
63 PyObject* value) {
64 if (value == NULL) {
65 PyErr_SetString(PyExc_AttributeError, "Cannot delete field attribute");
66 return -1;
67 }
68 return cmessage::SetFieldValue(reinterpret_cast<CMessage*>(obj),
69 self->field_descriptor, value);
70 }
71
GetDescriptor(PyMessageFieldProperty * self,void * closure)72 static PyObject* GetDescriptor(PyMessageFieldProperty* self, void* closure) {
73 return PyFieldDescriptor_FromDescriptor(self->field_descriptor);
74 }
75
GetDoc(PyMessageFieldProperty * self,void * closure)76 static PyObject* GetDoc(PyMessageFieldProperty* self, void* closure) {
77 return PyString_FromFormat("Field %s",
78 self->field_descriptor->full_name().c_str());
79 }
80
81 static PyGetSetDef Getters[] = {
82 {"DESCRIPTOR", (getter)GetDescriptor, NULL, "Field descriptor"},
83 {"__doc__", (getter)GetDoc, NULL, NULL},
84 {NULL}};
85 } // namespace field
86
87 static PyTypeObject _CFieldProperty_Type = {
88 PyVarObject_HEAD_INIT(&PyType_Type, 0) // head
89 FULL_MODULE_NAME ".FieldProperty", // tp_name
90 sizeof(PyMessageFieldProperty), // tp_basicsize
91 0, // tp_itemsize
92 0, // tp_dealloc
93 0, // tp_print
94 0, // tp_getattr
95 0, // tp_setattr
96 0, // tp_compare
97 (reprfunc)field::Repr, // tp_repr
98 0, // tp_as_number
99 0, // tp_as_sequence
100 0, // tp_as_mapping
101 0, // tp_hash
102 0, // tp_call
103 0, // tp_str
104 0, // tp_getattro
105 0, // tp_setattro
106 0, // tp_as_buffer
107 Py_TPFLAGS_DEFAULT, // tp_flags
108 "Field property of a Message", // tp_doc
109 0, // tp_traverse
110 0, // tp_clear
111 0, // tp_richcompare
112 0, // tp_weaklistoffset
113 0, // tp_iter
114 0, // tp_iternext
115 0, // tp_methods
116 0, // tp_members
117 field::Getters, // tp_getset
118 0, // tp_base
119 0, // tp_dict
120 (descrgetfunc)field::DescrGet, // tp_descr_get
121 (descrsetfunc)field::DescrSet, // tp_descr_set
122 0, // tp_dictoffset
123 0, // tp_init
124 0, // tp_alloc
125 0, // tp_new
126 };
127 PyTypeObject* CFieldProperty_Type = &_CFieldProperty_Type;
128
NewFieldProperty(const FieldDescriptor * field_descriptor)129 PyObject* NewFieldProperty(const FieldDescriptor* field_descriptor) {
130 // Create a new descriptor object
131 PyMessageFieldProperty* property =
132 PyObject_New(PyMessageFieldProperty, CFieldProperty_Type);
133 if (property == NULL) {
134 return NULL;
135 }
136 property->field_descriptor = field_descriptor;
137 return reinterpret_cast<PyObject*>(property);
138 }
139
140 } // namespace python
141 } // namespace protobuf
142 } // namespace google
143