- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / protobuf / python / google / protobuf / pyext / python_descriptor.cc
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // http://code.google.com/p/protobuf/
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 // Author: petar@google.com (Petar Petrov)
32
33 #include <Python.h>
34 #include <string>
35
36 #include <google/protobuf/pyext/python_descriptor.h>
37 #include <google/protobuf/descriptor.pb.h>
38
39 #define C(str) const_cast<char*>(str)
40
41 namespace google {
42 namespace protobuf {
43 namespace python {
44
45
46 static void CFieldDescriptorDealloc(CFieldDescriptor* self);
47
48 static google::protobuf::DescriptorPool* g_descriptor_pool = NULL;
49
50 static PyObject* CFieldDescriptor_GetFullName(
51     CFieldDescriptor* self, void *closure) {
52   Py_XINCREF(self->full_name);
53   return self->full_name;
54 }
55
56 static PyObject* CFieldDescriptor_GetName(
57     CFieldDescriptor *self, void *closure) {
58   Py_XINCREF(self->name);
59   return self->name;
60 }
61
62 static PyObject* CFieldDescriptor_GetCppType(
63     CFieldDescriptor *self, void *closure) {
64   Py_XINCREF(self->cpp_type);
65   return self->cpp_type;
66 }
67
68 static PyObject* CFieldDescriptor_GetLabel(
69     CFieldDescriptor *self, void *closure) {
70   Py_XINCREF(self->label);
71   return self->label;
72 }
73
74 static PyObject* CFieldDescriptor_GetID(
75     CFieldDescriptor *self, void *closure) {
76   Py_XINCREF(self->id);
77   return self->id;
78 }
79
80
81 static PyGetSetDef CFieldDescriptorGetters[] = {
82   { C("full_name"),
83     (getter)CFieldDescriptor_GetFullName, NULL, "Full name", NULL},
84   { C("name"),
85     (getter)CFieldDescriptor_GetName, NULL, "last name", NULL},
86   { C("cpp_type"),
87     (getter)CFieldDescriptor_GetCppType, NULL, "C++ Type", NULL},
88   { C("label"),
89     (getter)CFieldDescriptor_GetLabel, NULL, "Label", NULL},
90   { C("id"),
91     (getter)CFieldDescriptor_GetID, NULL, "ID", NULL},
92   {NULL}
93 };
94
95 PyTypeObject CFieldDescriptor_Type = {
96   PyObject_HEAD_INIT(&PyType_Type)
97   0,
98   C("google.protobuf.internal."
99     "_net_proto2___python."
100     "CFieldDescriptor"),                // tp_name
101   sizeof(CFieldDescriptor),             // tp_basicsize
102   0,                                    // tp_itemsize
103   (destructor)CFieldDescriptorDealloc,  // tp_dealloc
104   0,                                    // tp_print
105   0,                                    // tp_getattr
106   0,                                    // tp_setattr
107   0,                                    // tp_compare
108   0,                                    // tp_repr
109   0,                                    // tp_as_number
110   0,                                    // tp_as_sequence
111   0,                                    // tp_as_mapping
112   0,                                    // tp_hash
113   0,                                    // tp_call
114   0,                                    // tp_str
115   0,                                    // tp_getattro
116   0,                                    // tp_setattro
117   0,                                    // tp_as_buffer
118   Py_TPFLAGS_DEFAULT,                   // tp_flags
119   C("A Field Descriptor"),              // tp_doc
120   0,                                    // tp_traverse
121   0,                                    // tp_clear
122   0,                                    // tp_richcompare
123   0,                                    // tp_weaklistoffset
124   0,                                    // tp_iter
125   0,                                    // tp_iternext
126   0,                                    // tp_methods
127   0,                                    // tp_members
128   CFieldDescriptorGetters,              // tp_getset
129   0,                                    // tp_base
130   0,                                    // tp_dict
131   0,                                    // tp_descr_get
132   0,                                    // tp_descr_set
133   0,                                    // tp_dictoffset
134   0,                                    // tp_init
135   PyType_GenericAlloc,                  // tp_alloc
136   PyType_GenericNew,                    // tp_new
137   PyObject_Del,                         // tp_free
138 };
139
140 static void CFieldDescriptorDealloc(CFieldDescriptor* self) {
141   Py_DECREF(self->full_name);
142   Py_DECREF(self->name);
143   Py_DECREF(self->cpp_type);
144   Py_DECREF(self->label);
145   Py_DECREF(self->id);
146   self->ob_type->tp_free(reinterpret_cast<PyObject*>(self));
147 }
148
149 typedef struct {
150   PyObject_HEAD
151
152   const google::protobuf::DescriptorPool* pool;
153 } CDescriptorPool;
154
155 static void CDescriptorPoolDealloc(CDescriptorPool* self);
156
157 static PyObject* CDescriptorPool_NewCDescriptor(
158     const google::protobuf::FieldDescriptor* field_descriptor) {
159   CFieldDescriptor* cfield_descriptor = PyObject_New(
160       CFieldDescriptor, &CFieldDescriptor_Type);
161   if (cfield_descriptor == NULL) {
162     return NULL;
163   }
164   cfield_descriptor->descriptor = field_descriptor;
165
166   cfield_descriptor->full_name = PyString_FromString(
167       field_descriptor->full_name().c_str());
168   cfield_descriptor->name = PyString_FromString(
169       field_descriptor->name().c_str());
170   cfield_descriptor->cpp_type = PyLong_FromLong(field_descriptor->cpp_type());
171   cfield_descriptor->label = PyLong_FromLong(field_descriptor->label());
172   cfield_descriptor->id = PyLong_FromVoidPtr(cfield_descriptor);
173   return reinterpret_cast<PyObject*>(cfield_descriptor);
174 }
175
176 static PyObject* CDescriptorPool_FindFieldByName(
177     CDescriptorPool* self, PyObject* arg) {
178   const char* full_field_name = PyString_AsString(arg);
179   if (full_field_name == NULL) {
180     return NULL;
181   }
182
183   const google::protobuf::FieldDescriptor* field_descriptor = NULL;
184
185   field_descriptor = self->pool->FindFieldByName(full_field_name);
186
187
188   if (field_descriptor == NULL) {
189     PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s",
190                  full_field_name);
191     return NULL;
192   }
193
194   return CDescriptorPool_NewCDescriptor(field_descriptor);
195 }
196
197 static PyObject* CDescriptorPool_FindExtensionByName(
198     CDescriptorPool* self, PyObject* arg) {
199   const char* full_field_name = PyString_AsString(arg);
200   if (full_field_name == NULL) {
201     return NULL;
202   }
203
204   const google::protobuf::FieldDescriptor* field_descriptor =
205       self->pool->FindExtensionByName(full_field_name);
206   if (field_descriptor == NULL) {
207     PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s",
208                  full_field_name);
209     return NULL;
210   }
211
212   return CDescriptorPool_NewCDescriptor(field_descriptor);
213 }
214
215 static PyMethodDef CDescriptorPoolMethods[] = {
216   { C("FindFieldByName"),
217     (PyCFunction)CDescriptorPool_FindFieldByName,
218     METH_O,
219     C("Searches for a field descriptor by full name.") },
220   { C("FindExtensionByName"),
221     (PyCFunction)CDescriptorPool_FindExtensionByName,
222     METH_O,
223     C("Searches for extension descriptor by full name.") },
224   {NULL}
225 };
226
227 PyTypeObject CDescriptorPool_Type = {
228   PyObject_HEAD_INIT(&PyType_Type)
229   0,
230   C("google.protobuf.internal."
231     "_net_proto2___python."
232     "CFieldDescriptor"),               // tp_name
233   sizeof(CDescriptorPool),             // tp_basicsize
234   0,                                   // tp_itemsize
235   (destructor)CDescriptorPoolDealloc,  // tp_dealloc
236   0,                                   // tp_print
237   0,                                   // tp_getattr
238   0,                                   // tp_setattr
239   0,                                   // tp_compare
240   0,                                   // tp_repr
241   0,                                   // tp_as_number
242   0,                                   // tp_as_sequence
243   0,                                   // tp_as_mapping
244   0,                                   // tp_hash
245   0,                                   // tp_call
246   0,                                   // tp_str
247   0,                                   // tp_getattro
248   0,                                   // tp_setattro
249   0,                                   // tp_as_buffer
250   Py_TPFLAGS_DEFAULT,                  // tp_flags
251   C("A Descriptor Pool"),              // tp_doc
252   0,                                   // tp_traverse
253   0,                                   // tp_clear
254   0,                                   // tp_richcompare
255   0,                                   // tp_weaklistoffset
256   0,                                   // tp_iter
257   0,                                   // tp_iternext
258   CDescriptorPoolMethods,              // tp_methods
259   0,                                   // tp_members
260   0,                                   // tp_getset
261   0,                                   // tp_base
262   0,                                   // tp_dict
263   0,                                   // tp_descr_get
264   0,                                   // tp_descr_set
265   0,                                   // tp_dictoffset
266   0,                                   // tp_init
267   PyType_GenericAlloc,                 // tp_alloc
268   PyType_GenericNew,                   // tp_new
269   PyObject_Del,                        // tp_free
270 };
271
272 static void CDescriptorPoolDealloc(CDescriptorPool* self) {
273   self->ob_type->tp_free(reinterpret_cast<PyObject*>(self));
274 }
275
276 google::protobuf::DescriptorPool* GetDescriptorPool() {
277   if (g_descriptor_pool == NULL) {
278     g_descriptor_pool = new google::protobuf::DescriptorPool(
279         google::protobuf::DescriptorPool::generated_pool());
280   }
281   return g_descriptor_pool;
282 }
283
284 PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args) {
285   CDescriptorPool* cdescriptor_pool = PyObject_New(
286       CDescriptorPool, &CDescriptorPool_Type);
287   if (cdescriptor_pool == NULL) {
288     return NULL;
289   }
290   cdescriptor_pool->pool = GetDescriptorPool();
291   return reinterpret_cast<PyObject*>(cdescriptor_pool);
292 }
293
294 PyObject* Python_BuildFile(PyObject* ignored, PyObject* arg) {
295   char* message_type;
296   Py_ssize_t message_len;
297
298   if (PyString_AsStringAndSize(arg, &message_type, &message_len) < 0) {
299     return NULL;
300   }
301
302   google::protobuf::FileDescriptorProto file_proto;
303   if (!file_proto.ParseFromArray(message_type, message_len)) {
304     PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!");
305     return NULL;
306   }
307
308   if (google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
309       file_proto.name()) != NULL) {
310     Py_RETURN_NONE;
311   }
312
313   const google::protobuf::FileDescriptor* descriptor = GetDescriptorPool()->BuildFile(
314       file_proto);
315   if (descriptor == NULL) {
316     PyErr_SetString(PyExc_TypeError,
317                     "Couldn't build proto file into descriptor pool!");
318     return NULL;
319   }
320
321   Py_RETURN_NONE;
322 }
323
324 bool InitDescriptor() {
325   CFieldDescriptor_Type.tp_new = PyType_GenericNew;
326   if (PyType_Ready(&CFieldDescriptor_Type) < 0)
327     return false;
328
329   CDescriptorPool_Type.tp_new = PyType_GenericNew;
330   if (PyType_Ready(&CDescriptorPool_Type) < 0)
331     return false;
332   return true;
333 }
334
335 }  // namespace python
336 }  // namespace protobuf
337 }  // namespace google