~verterok/ubuntu/lucid/protobuf/2.4.0a-backport

« back to all changes in this revision

Viewing changes to python/google/protobuf/pyext/python_descriptor.cc

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2011-05-31 14:41:47 UTC
  • mfrom: (2.2.8 sid)
  • Revision ID: james.westby@ubuntu.com-20110531144147-s41g5fozgvyo462l
Tags: 2.4.0a-2ubuntu1
* Merge with Debian; remaining changes:
  - Fix linking with -lpthread.

Show diffs side-by-side

added added

removed removed

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