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 // Author: petar@google.com (Petar Petrov)
32
33 #include <Python.h>
34 #include <frameobject.h>
35 #include <string>
36
37 #include <google/protobuf/io/coded_stream.h>
38 #include <google/protobuf/descriptor.pb.h>
39 #include <google/protobuf/dynamic_message.h>
40 #include <google/protobuf/pyext/descriptor.h>
41 #include <google/protobuf/pyext/descriptor_containers.h>
42 #include <google/protobuf/pyext/descriptor_pool.h>
43 #include <google/protobuf/pyext/message.h>
44 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
45
46 #if PY_MAJOR_VERSION >= 3
47 #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
48 #define PyString_Check PyUnicode_Check
49 #define PyString_InternFromString PyUnicode_InternFromString
50 #define PyInt_FromLong PyLong_FromLong
51 #define PyInt_FromSize_t PyLong_FromSize_t
52 #if PY_VERSION_HEX < 0x03030000
53 #error "Python 3.0 - 3.2 are not supported."
54 #endif
55 #define PyString_AsStringAndSize(ob, charpp, sizep) \
56 (PyUnicode_Check(ob)? \
57 ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
58 PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
59 #endif
60
61 namespace google {
62 namespace protobuf {
63 namespace python {
64
65 // Store interned descriptors, so that the same C++ descriptor yields the same
66 // Python object. Objects are not immortal: this map does not own the
67 // references, and items are deleted when the last reference to the object is
68 // released.
69 // This is enough to support the "is" operator on live objects.
70 // All descriptors are stored here.
71 hash_map<const void*, PyObject*> interned_descriptors;
72
PyString_FromCppString(const string & str)73 PyObject* PyString_FromCppString(const string& str) {
74 return PyString_FromStringAndSize(str.c_str(), str.size());
75 }
76
77 // Check that the calling Python code is the global scope of a _pb2.py module.
78 // This function is used to support the current code generated by the proto
79 // compiler, which creates descriptors, then update some properties.
80 // For example:
81 // message_descriptor = Descriptor(
82 // name='Message',
83 // fields = [FieldDescriptor(name='field')]
84 // message_descriptor.fields[0].containing_type = message_descriptor
85 //
86 // This code is still executed, but the descriptors now have no other storage
87 // than the (const) C++ pointer, and are immutable.
88 // So we let this code pass, by simply ignoring the new value.
89 //
90 // From user code, descriptors still look immutable.
91 //
92 // TODO(amauryfa): Change the proto2 compiler to remove the assignments, and
93 // remove this hack.
_CalledFromGeneratedFile(int stacklevel)94 bool _CalledFromGeneratedFile(int stacklevel) {
95 #ifndef PYPY_VERSION
96 // This check is not critical and is somewhat difficult to implement correctly
97 // in PyPy.
98 PyFrameObject* frame = PyEval_GetFrame();
99 if (frame == NULL) {
100 return false;
101 }
102 while (stacklevel-- > 0) {
103 frame = frame->f_back;
104 if (frame == NULL) {
105 return false;
106 }
107 }
108 if (frame->f_globals != frame->f_locals) {
109 // Not at global module scope
110 return false;
111 }
112
113 if (frame->f_code->co_filename == NULL) {
114 return false;
115 }
116 char* filename;
117 Py_ssize_t filename_size;
118 if (PyString_AsStringAndSize(frame->f_code->co_filename,
119 &filename, &filename_size) < 0) {
120 // filename is not a string.
121 PyErr_Clear();
122 return false;
123 }
124 if (filename_size < 7) {
125 // filename is too short.
126 return false;
127 }
128 if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) {
129 // Filename is not ending with _pb2.
130 return false;
131 }
132 #endif
133 return true;
134 }
135
136 // If the calling code is not a _pb2.py file, raise AttributeError.
137 // To be used in attribute setters.
CheckCalledFromGeneratedFile(const char * attr_name)138 static int CheckCalledFromGeneratedFile(const char* attr_name) {
139 if (_CalledFromGeneratedFile(0)) {
140 return 0;
141 }
142 PyErr_Format(PyExc_AttributeError,
143 "attribute is not writable: %s", attr_name);
144 return -1;
145 }
146
147
148 #ifndef PyVarObject_HEAD_INIT
149 #define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
150 #endif
151 #ifndef Py_TYPE
152 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
153 #endif
154
155
156 // Helper functions for descriptor objects.
157
158 // A set of templates to retrieve the C++ FileDescriptor of any descriptor.
159 template<class DescriptorClass>
GetFileDescriptor(const DescriptorClass * descriptor)160 const FileDescriptor* GetFileDescriptor(const DescriptorClass* descriptor) {
161 return descriptor->file();
162 }
163 template<>
GetFileDescriptor(const FileDescriptor * descriptor)164 const FileDescriptor* GetFileDescriptor(const FileDescriptor* descriptor) {
165 return descriptor;
166 }
167 template<>
GetFileDescriptor(const EnumValueDescriptor * descriptor)168 const FileDescriptor* GetFileDescriptor(const EnumValueDescriptor* descriptor) {
169 return descriptor->type()->file();
170 }
171 template<>
GetFileDescriptor(const OneofDescriptor * descriptor)172 const FileDescriptor* GetFileDescriptor(const OneofDescriptor* descriptor) {
173 return descriptor->containing_type()->file();
174 }
175 template<>
GetFileDescriptor(const MethodDescriptor * descriptor)176 const FileDescriptor* GetFileDescriptor(const MethodDescriptor* descriptor) {
177 return descriptor->service()->file();
178 }
179
180 // Converts options into a Python protobuf, and cache the result.
181 //
182 // This is a bit tricky because options can contain extension fields defined in
183 // the same proto file. In this case the options parsed from the serialized_pb
184 // have unknown fields, and we need to parse them again.
185 //
186 // Always returns a new reference.
187 template<class DescriptorClass>
GetOrBuildOptions(const DescriptorClass * descriptor)188 static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
189 // Options (and their extensions) are completely resolved in the proto file
190 // containing the descriptor.
191 PyDescriptorPool* pool = GetDescriptorPool_FromPool(
192 GetFileDescriptor(descriptor)->pool());
193
194 hash_map<const void*, PyObject*>* descriptor_options =
195 pool->descriptor_options;
196 // First search in the cache.
197 if (descriptor_options->find(descriptor) != descriptor_options->end()) {
198 PyObject *value = (*descriptor_options)[descriptor];
199 Py_INCREF(value);
200 return value;
201 }
202
203 // Build the Options object: get its Python class, and make a copy of the C++
204 // read-only instance.
205 const Message& options(descriptor->options());
206 const Descriptor *message_type = options.GetDescriptor();
207 CMessageClass* message_class(
208 cdescriptor_pool::GetMessageClass(pool, message_type));
209 if (message_class == NULL) {
210 // The Options message was not found in the current DescriptorPool.
211 // This means that the pool cannot contain any extensions to the Options
212 // message either, so falling back to the basic pool we can only increase
213 // the chances of successfully parsing the options.
214 PyErr_Clear();
215 pool = GetDefaultDescriptorPool();
216 message_class = cdescriptor_pool::GetMessageClass(pool, message_type);
217 }
218 if (message_class == NULL) {
219 PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s",
220 message_type->full_name().c_str());
221 return NULL;
222 }
223 ScopedPyObjectPtr value(
224 PyEval_CallObject(message_class->AsPyObject(), NULL));
225 if (value == NULL) {
226 return NULL;
227 }
228 if (!PyObject_TypeCheck(value.get(), &CMessage_Type)) {
229 PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s",
230 message_type->full_name().c_str(),
231 Py_TYPE(value.get())->tp_name);
232 return NULL;
233 }
234 CMessage* cmsg = reinterpret_cast<CMessage*>(value.get());
235
236 const Reflection* reflection = options.GetReflection();
237 const UnknownFieldSet& unknown_fields(reflection->GetUnknownFields(options));
238 if (unknown_fields.empty()) {
239 cmsg->message->CopyFrom(options);
240 } else {
241 // Reparse options string! XXX call cmessage::MergeFromString
242 string serialized;
243 options.SerializeToString(&serialized);
244 io::CodedInputStream input(
245 reinterpret_cast<const uint8*>(serialized.c_str()), serialized.size());
246 input.SetExtensionRegistry(pool->pool, pool->message_factory);
247 bool success = cmsg->message->MergePartialFromCodedStream(&input);
248 if (!success) {
249 PyErr_Format(PyExc_ValueError, "Error parsing Options message");
250 return NULL;
251 }
252 }
253
254 // Cache the result.
255 Py_INCREF(value.get());
256 (*descriptor_options)[descriptor] = value.get();
257
258 return value.release();
259 }
260
261 // Copy the C++ descriptor to a Python message.
262 // The Python message is an instance of descriptor_pb2.DescriptorProto
263 // or similar.
264 template<class DescriptorProtoClass, class DescriptorClass>
CopyToPythonProto(const DescriptorClass * descriptor,PyObject * target)265 static PyObject* CopyToPythonProto(const DescriptorClass *descriptor,
266 PyObject *target) {
267 const Descriptor* self_descriptor =
268 DescriptorProtoClass::default_instance().GetDescriptor();
269 CMessage* message = reinterpret_cast<CMessage*>(target);
270 if (!PyObject_TypeCheck(target, &CMessage_Type) ||
271 message->message->GetDescriptor() != self_descriptor) {
272 PyErr_Format(PyExc_TypeError, "Not a %s message",
273 self_descriptor->full_name().c_str());
274 return NULL;
275 }
276 cmessage::AssureWritable(message);
277 DescriptorProtoClass* descriptor_message =
278 static_cast<DescriptorProtoClass*>(message->message);
279 descriptor->CopyTo(descriptor_message);
280 Py_RETURN_NONE;
281 }
282
283 // All Descriptors classes share the same memory layout.
284 typedef struct PyBaseDescriptor {
285 PyObject_HEAD
286
287 // Pointer to the C++ proto2 descriptor.
288 // Like all descriptors, it is owned by the global DescriptorPool.
289 const void* descriptor;
290
291 // Owned reference to the DescriptorPool, to ensure it is kept alive.
292 PyDescriptorPool* pool;
293 } PyBaseDescriptor;
294
295
296 // FileDescriptor structure "inherits" from the base descriptor.
297 typedef struct PyFileDescriptor {
298 PyBaseDescriptor base;
299
300 // The cached version of serialized pb. Either NULL, or a Bytes string.
301 // We own the reference.
302 PyObject *serialized_pb;
303 } PyFileDescriptor;
304
305
306 namespace descriptor {
307
308 // Creates or retrieve a Python descriptor of the specified type.
309 // Objects are interned: the same descriptor will return the same object if it
310 // was kept alive.
311 // 'was_created' is an optional pointer to a bool, and is set to true if a new
312 // object was allocated.
313 // Always return a new reference.
314 template<class DescriptorClass>
NewInternedDescriptor(PyTypeObject * type,const DescriptorClass * descriptor,bool * was_created)315 PyObject* NewInternedDescriptor(PyTypeObject* type,
316 const DescriptorClass* descriptor,
317 bool* was_created) {
318 if (was_created) {
319 *was_created = false;
320 }
321 if (descriptor == NULL) {
322 PyErr_BadInternalCall();
323 return NULL;
324 }
325
326 // See if the object is in the map of interned descriptors
327 hash_map<const void*, PyObject*>::iterator it =
328 interned_descriptors.find(descriptor);
329 if (it != interned_descriptors.end()) {
330 GOOGLE_DCHECK(Py_TYPE(it->second) == type);
331 Py_INCREF(it->second);
332 return it->second;
333 }
334 // Create a new descriptor object
335 PyBaseDescriptor* py_descriptor = PyObject_New(
336 PyBaseDescriptor, type);
337 if (py_descriptor == NULL) {
338 return NULL;
339 }
340 py_descriptor->descriptor = descriptor;
341
342 // and cache it.
343 interned_descriptors.insert(
344 std::make_pair(descriptor, reinterpret_cast<PyObject*>(py_descriptor)));
345
346 // Ensures that the DescriptorPool stays alive.
347 PyDescriptorPool* pool = GetDescriptorPool_FromPool(
348 GetFileDescriptor(descriptor)->pool());
349 if (pool == NULL) {
350 // Don't DECREF, the object is not fully initialized.
351 PyObject_Del(py_descriptor);
352 return NULL;
353 }
354 Py_INCREF(pool);
355 py_descriptor->pool = pool;
356
357 if (was_created) {
358 *was_created = true;
359 }
360 return reinterpret_cast<PyObject*>(py_descriptor);
361 }
362
Dealloc(PyBaseDescriptor * self)363 static void Dealloc(PyBaseDescriptor* self) {
364 // Remove from interned dictionary
365 interned_descriptors.erase(self->descriptor);
366 Py_CLEAR(self->pool);
367 Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
368 }
369
370 static PyGetSetDef Getters[] = {
371 {NULL}
372 };
373
374 PyTypeObject PyBaseDescriptor_Type = {
375 PyVarObject_HEAD_INIT(&PyType_Type, 0)
376 FULL_MODULE_NAME ".DescriptorBase", // tp_name
377 sizeof(PyBaseDescriptor), // tp_basicsize
378 0, // tp_itemsize
379 (destructor)Dealloc, // tp_dealloc
380 0, // tp_print
381 0, // tp_getattr
382 0, // tp_setattr
383 0, // tp_compare
384 0, // tp_repr
385 0, // tp_as_number
386 0, // tp_as_sequence
387 0, // tp_as_mapping
388 0, // tp_hash
389 0, // tp_call
390 0, // tp_str
391 0, // tp_getattro
392 0, // tp_setattro
393 0, // tp_as_buffer
394 Py_TPFLAGS_DEFAULT, // tp_flags
395 "Descriptors base class", // tp_doc
396 0, // tp_traverse
397 0, // tp_clear
398 0, // tp_richcompare
399 0, // tp_weaklistoffset
400 0, // tp_iter
401 0, // tp_iternext
402 0, // tp_methods
403 0, // tp_members
404 Getters, // tp_getset
405 };
406
407 } // namespace descriptor
408
PyDescriptor_AsVoidPtr(PyObject * obj)409 const void* PyDescriptor_AsVoidPtr(PyObject* obj) {
410 if (!PyObject_TypeCheck(obj, &descriptor::PyBaseDescriptor_Type)) {
411 PyErr_SetString(PyExc_TypeError, "Not a BaseDescriptor");
412 return NULL;
413 }
414 return reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor;
415 }
416
417 namespace message_descriptor {
418
419 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)420 static const Descriptor* _GetDescriptor(PyBaseDescriptor* self) {
421 return reinterpret_cast<const Descriptor*>(self->descriptor);
422 }
423
GetName(PyBaseDescriptor * self,void * closure)424 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
425 return PyString_FromCppString(_GetDescriptor(self)->name());
426 }
427
GetFullName(PyBaseDescriptor * self,void * closure)428 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
429 return PyString_FromCppString(_GetDescriptor(self)->full_name());
430 }
431
GetFile(PyBaseDescriptor * self,void * closure)432 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
433 return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
434 }
435
GetConcreteClass(PyBaseDescriptor * self,void * closure)436 static PyObject* GetConcreteClass(PyBaseDescriptor* self, void *closure) {
437 // Retuns the canonical class for the given descriptor.
438 // This is the class that was registered with the primary descriptor pool
439 // which contains this descriptor.
440 // This might not be the one you expect! For example the returned object does
441 // not know about extensions defined in a custom pool.
442 CMessageClass* concrete_class(cdescriptor_pool::GetMessageClass(
443 GetDescriptorPool_FromPool(_GetDescriptor(self)->file()->pool()),
444 _GetDescriptor(self)));
445 Py_XINCREF(concrete_class);
446 return concrete_class->AsPyObject();
447 }
448
GetFieldsByName(PyBaseDescriptor * self,void * closure)449 static PyObject* GetFieldsByName(PyBaseDescriptor* self, void *closure) {
450 return NewMessageFieldsByName(_GetDescriptor(self));
451 }
452
GetFieldsByCamelcaseName(PyBaseDescriptor * self,void * closure)453 static PyObject* GetFieldsByCamelcaseName(PyBaseDescriptor* self,
454 void *closure) {
455 return NewMessageFieldsByCamelcaseName(_GetDescriptor(self));
456 }
457
GetFieldsByNumber(PyBaseDescriptor * self,void * closure)458 static PyObject* GetFieldsByNumber(PyBaseDescriptor* self, void *closure) {
459 return NewMessageFieldsByNumber(_GetDescriptor(self));
460 }
461
GetFieldsSeq(PyBaseDescriptor * self,void * closure)462 static PyObject* GetFieldsSeq(PyBaseDescriptor* self, void *closure) {
463 return NewMessageFieldsSeq(_GetDescriptor(self));
464 }
465
GetNestedTypesByName(PyBaseDescriptor * self,void * closure)466 static PyObject* GetNestedTypesByName(PyBaseDescriptor* self, void *closure) {
467 return NewMessageNestedTypesByName(_GetDescriptor(self));
468 }
469
GetNestedTypesSeq(PyBaseDescriptor * self,void * closure)470 static PyObject* GetNestedTypesSeq(PyBaseDescriptor* self, void *closure) {
471 return NewMessageNestedTypesSeq(_GetDescriptor(self));
472 }
473
GetExtensionsByName(PyBaseDescriptor * self,void * closure)474 static PyObject* GetExtensionsByName(PyBaseDescriptor* self, void *closure) {
475 return NewMessageExtensionsByName(_GetDescriptor(self));
476 }
477
GetExtensions(PyBaseDescriptor * self,void * closure)478 static PyObject* GetExtensions(PyBaseDescriptor* self, void *closure) {
479 return NewMessageExtensionsSeq(_GetDescriptor(self));
480 }
481
GetEnumsSeq(PyBaseDescriptor * self,void * closure)482 static PyObject* GetEnumsSeq(PyBaseDescriptor* self, void *closure) {
483 return NewMessageEnumsSeq(_GetDescriptor(self));
484 }
485
GetEnumTypesByName(PyBaseDescriptor * self,void * closure)486 static PyObject* GetEnumTypesByName(PyBaseDescriptor* self, void *closure) {
487 return NewMessageEnumsByName(_GetDescriptor(self));
488 }
489
GetEnumValuesByName(PyBaseDescriptor * self,void * closure)490 static PyObject* GetEnumValuesByName(PyBaseDescriptor* self, void *closure) {
491 return NewMessageEnumValuesByName(_GetDescriptor(self));
492 }
493
GetOneofsByName(PyBaseDescriptor * self,void * closure)494 static PyObject* GetOneofsByName(PyBaseDescriptor* self, void *closure) {
495 return NewMessageOneofsByName(_GetDescriptor(self));
496 }
497
GetOneofsSeq(PyBaseDescriptor * self,void * closure)498 static PyObject* GetOneofsSeq(PyBaseDescriptor* self, void *closure) {
499 return NewMessageOneofsSeq(_GetDescriptor(self));
500 }
501
IsExtendable(PyBaseDescriptor * self,void * closure)502 static PyObject* IsExtendable(PyBaseDescriptor *self, void *closure) {
503 if (_GetDescriptor(self)->extension_range_count() > 0) {
504 Py_RETURN_TRUE;
505 } else {
506 Py_RETURN_FALSE;
507 }
508 }
509
GetExtensionRanges(PyBaseDescriptor * self,void * closure)510 static PyObject* GetExtensionRanges(PyBaseDescriptor *self, void *closure) {
511 const Descriptor* descriptor = _GetDescriptor(self);
512 PyObject* range_list = PyList_New(descriptor->extension_range_count());
513
514 for (int i = 0; i < descriptor->extension_range_count(); i++) {
515 const Descriptor::ExtensionRange* range = descriptor->extension_range(i);
516 PyObject* start = PyInt_FromLong(range->start);
517 PyObject* end = PyInt_FromLong(range->end);
518 PyList_SetItem(range_list, i, PyTuple_Pack(2, start, end));
519 }
520
521 return range_list;
522 }
523
GetContainingType(PyBaseDescriptor * self,void * closure)524 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
525 const Descriptor* containing_type =
526 _GetDescriptor(self)->containing_type();
527 if (containing_type) {
528 return PyMessageDescriptor_FromDescriptor(containing_type);
529 } else {
530 Py_RETURN_NONE;
531 }
532 }
533
SetContainingType(PyBaseDescriptor * self,PyObject * value,void * closure)534 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
535 void *closure) {
536 return CheckCalledFromGeneratedFile("containing_type");
537 }
538
GetHasOptions(PyBaseDescriptor * self,void * closure)539 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
540 const MessageOptions& options(_GetDescriptor(self)->options());
541 if (&options != &MessageOptions::default_instance()) {
542 Py_RETURN_TRUE;
543 } else {
544 Py_RETURN_FALSE;
545 }
546 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)547 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
548 void *closure) {
549 return CheckCalledFromGeneratedFile("has_options");
550 }
551
GetOptions(PyBaseDescriptor * self)552 static PyObject* GetOptions(PyBaseDescriptor *self) {
553 return GetOrBuildOptions(_GetDescriptor(self));
554 }
555
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)556 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
557 void *closure) {
558 return CheckCalledFromGeneratedFile("_options");
559 }
560
CopyToProto(PyBaseDescriptor * self,PyObject * target)561 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
562 return CopyToPythonProto<DescriptorProto>(_GetDescriptor(self), target);
563 }
564
EnumValueName(PyBaseDescriptor * self,PyObject * args)565 static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) {
566 const char *enum_name;
567 int number;
568 if (!PyArg_ParseTuple(args, "si", &enum_name, &number))
569 return NULL;
570 const EnumDescriptor *enum_type =
571 _GetDescriptor(self)->FindEnumTypeByName(enum_name);
572 if (enum_type == NULL) {
573 PyErr_SetString(PyExc_KeyError, enum_name);
574 return NULL;
575 }
576 const EnumValueDescriptor *enum_value =
577 enum_type->FindValueByNumber(number);
578 if (enum_value == NULL) {
579 PyErr_Format(PyExc_KeyError, "%d", number);
580 return NULL;
581 }
582 return PyString_FromCppString(enum_value->name());
583 }
584
GetSyntax(PyBaseDescriptor * self,void * closure)585 static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) {
586 return PyString_InternFromString(
587 FileDescriptor::SyntaxName(_GetDescriptor(self)->file()->syntax()));
588 }
589
590 static PyGetSetDef Getters[] = {
591 { "name", (getter)GetName, NULL, "Last name"},
592 { "full_name", (getter)GetFullName, NULL, "Full name"},
593 { "_concrete_class", (getter)GetConcreteClass, NULL, "concrete class"},
594 { "file", (getter)GetFile, NULL, "File descriptor"},
595
596 { "fields", (getter)GetFieldsSeq, NULL, "Fields sequence"},
597 { "fields_by_name", (getter)GetFieldsByName, NULL, "Fields by name"},
598 { "fields_by_camelcase_name", (getter)GetFieldsByCamelcaseName, NULL,
599 "Fields by camelCase name"},
600 { "fields_by_number", (getter)GetFieldsByNumber, NULL, "Fields by number"},
601 { "nested_types", (getter)GetNestedTypesSeq, NULL, "Nested types sequence"},
602 { "nested_types_by_name", (getter)GetNestedTypesByName, NULL,
603 "Nested types by name"},
604 { "extensions", (getter)GetExtensions, NULL, "Extensions Sequence"},
605 { "extensions_by_name", (getter)GetExtensionsByName, NULL,
606 "Extensions by name"},
607 { "extension_ranges", (getter)GetExtensionRanges, NULL, "Extension ranges"},
608 { "enum_types", (getter)GetEnumsSeq, NULL, "Enum sequence"},
609 { "enum_types_by_name", (getter)GetEnumTypesByName, NULL,
610 "Enum types by name"},
611 { "enum_values_by_name", (getter)GetEnumValuesByName, NULL,
612 "Enum values by name"},
613 { "oneofs_by_name", (getter)GetOneofsByName, NULL, "Oneofs by name"},
614 { "oneofs", (getter)GetOneofsSeq, NULL, "Oneofs by name"},
615 { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
616 "Containing type"},
617 { "is_extendable", (getter)IsExtendable, (setter)NULL},
618 { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
619 { "_options", (getter)NULL, (setter)SetOptions, "Options"},
620 { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
621 {NULL}
622 };
623
624 static PyMethodDef Methods[] = {
625 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
626 { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
627 { "EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS, },
628 {NULL}
629 };
630
631 } // namespace message_descriptor
632
633 PyTypeObject PyMessageDescriptor_Type = {
634 PyVarObject_HEAD_INIT(&PyType_Type, 0)
635 FULL_MODULE_NAME ".MessageDescriptor", // tp_name
636 sizeof(PyBaseDescriptor), // tp_basicsize
637 0, // tp_itemsize
638 0, // tp_dealloc
639 0, // tp_print
640 0, // tp_getattr
641 0, // tp_setattr
642 0, // tp_compare
643 0, // tp_repr
644 0, // tp_as_number
645 0, // tp_as_sequence
646 0, // tp_as_mapping
647 0, // tp_hash
648 0, // tp_call
649 0, // tp_str
650 0, // tp_getattro
651 0, // tp_setattro
652 0, // tp_as_buffer
653 Py_TPFLAGS_DEFAULT, // tp_flags
654 "A Message Descriptor", // tp_doc
655 0, // tp_traverse
656 0, // tp_clear
657 0, // tp_richcompare
658 0, // tp_weaklistoffset
659 0, // tp_iter
660 0, // tp_iternext
661 message_descriptor::Methods, // tp_methods
662 0, // tp_members
663 message_descriptor::Getters, // tp_getset
664 &descriptor::PyBaseDescriptor_Type, // tp_base
665 };
666
PyMessageDescriptor_FromDescriptor(const Descriptor * message_descriptor)667 PyObject* PyMessageDescriptor_FromDescriptor(
668 const Descriptor* message_descriptor) {
669 return descriptor::NewInternedDescriptor(
670 &PyMessageDescriptor_Type, message_descriptor, NULL);
671 }
672
PyMessageDescriptor_AsDescriptor(PyObject * obj)673 const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj) {
674 if (!PyObject_TypeCheck(obj, &PyMessageDescriptor_Type)) {
675 PyErr_SetString(PyExc_TypeError, "Not a MessageDescriptor");
676 return NULL;
677 }
678 return reinterpret_cast<const Descriptor*>(
679 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
680 }
681
682 namespace field_descriptor {
683
684 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)685 static const FieldDescriptor* _GetDescriptor(
686 PyBaseDescriptor *self) {
687 return reinterpret_cast<const FieldDescriptor*>(self->descriptor);
688 }
689
GetFullName(PyBaseDescriptor * self,void * closure)690 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
691 return PyString_FromCppString(_GetDescriptor(self)->full_name());
692 }
693
GetName(PyBaseDescriptor * self,void * closure)694 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
695 return PyString_FromCppString(_GetDescriptor(self)->name());
696 }
697
GetCamelcaseName(PyBaseDescriptor * self,void * closure)698 static PyObject* GetCamelcaseName(PyBaseDescriptor* self, void *closure) {
699 return PyString_FromCppString(_GetDescriptor(self)->camelcase_name());
700 }
701
GetType(PyBaseDescriptor * self,void * closure)702 static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
703 return PyInt_FromLong(_GetDescriptor(self)->type());
704 }
705
GetCppType(PyBaseDescriptor * self,void * closure)706 static PyObject* GetCppType(PyBaseDescriptor *self, void *closure) {
707 return PyInt_FromLong(_GetDescriptor(self)->cpp_type());
708 }
709
GetLabel(PyBaseDescriptor * self,void * closure)710 static PyObject* GetLabel(PyBaseDescriptor *self, void *closure) {
711 return PyInt_FromLong(_GetDescriptor(self)->label());
712 }
713
GetNumber(PyBaseDescriptor * self,void * closure)714 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
715 return PyInt_FromLong(_GetDescriptor(self)->number());
716 }
717
GetIndex(PyBaseDescriptor * self,void * closure)718 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
719 return PyInt_FromLong(_GetDescriptor(self)->index());
720 }
721
GetID(PyBaseDescriptor * self,void * closure)722 static PyObject* GetID(PyBaseDescriptor *self, void *closure) {
723 return PyLong_FromVoidPtr(self);
724 }
725
IsExtension(PyBaseDescriptor * self,void * closure)726 static PyObject* IsExtension(PyBaseDescriptor *self, void *closure) {
727 return PyBool_FromLong(_GetDescriptor(self)->is_extension());
728 }
729
HasDefaultValue(PyBaseDescriptor * self,void * closure)730 static PyObject* HasDefaultValue(PyBaseDescriptor *self, void *closure) {
731 return PyBool_FromLong(_GetDescriptor(self)->has_default_value());
732 }
733
GetDefaultValue(PyBaseDescriptor * self,void * closure)734 static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) {
735 PyObject *result;
736
737 switch (_GetDescriptor(self)->cpp_type()) {
738 case FieldDescriptor::CPPTYPE_INT32: {
739 int32 value = _GetDescriptor(self)->default_value_int32();
740 result = PyInt_FromLong(value);
741 break;
742 }
743 case FieldDescriptor::CPPTYPE_INT64: {
744 int64 value = _GetDescriptor(self)->default_value_int64();
745 result = PyLong_FromLongLong(value);
746 break;
747 }
748 case FieldDescriptor::CPPTYPE_UINT32: {
749 uint32 value = _GetDescriptor(self)->default_value_uint32();
750 result = PyInt_FromSize_t(value);
751 break;
752 }
753 case FieldDescriptor::CPPTYPE_UINT64: {
754 uint64 value = _GetDescriptor(self)->default_value_uint64();
755 result = PyLong_FromUnsignedLongLong(value);
756 break;
757 }
758 case FieldDescriptor::CPPTYPE_FLOAT: {
759 float value = _GetDescriptor(self)->default_value_float();
760 result = PyFloat_FromDouble(value);
761 break;
762 }
763 case FieldDescriptor::CPPTYPE_DOUBLE: {
764 double value = _GetDescriptor(self)->default_value_double();
765 result = PyFloat_FromDouble(value);
766 break;
767 }
768 case FieldDescriptor::CPPTYPE_BOOL: {
769 bool value = _GetDescriptor(self)->default_value_bool();
770 result = PyBool_FromLong(value);
771 break;
772 }
773 case FieldDescriptor::CPPTYPE_STRING: {
774 string value = _GetDescriptor(self)->default_value_string();
775 result = ToStringObject(_GetDescriptor(self), value);
776 break;
777 }
778 case FieldDescriptor::CPPTYPE_ENUM: {
779 const EnumValueDescriptor* value =
780 _GetDescriptor(self)->default_value_enum();
781 result = PyInt_FromLong(value->number());
782 break;
783 }
784 default:
785 PyErr_Format(PyExc_NotImplementedError, "default value for %s",
786 _GetDescriptor(self)->full_name().c_str());
787 return NULL;
788 }
789 return result;
790 }
791
GetCDescriptor(PyObject * self,void * closure)792 static PyObject* GetCDescriptor(PyObject *self, void *closure) {
793 Py_INCREF(self);
794 return self;
795 }
796
GetEnumType(PyBaseDescriptor * self,void * closure)797 static PyObject *GetEnumType(PyBaseDescriptor *self, void *closure) {
798 const EnumDescriptor* enum_type = _GetDescriptor(self)->enum_type();
799 if (enum_type) {
800 return PyEnumDescriptor_FromDescriptor(enum_type);
801 } else {
802 Py_RETURN_NONE;
803 }
804 }
805
SetEnumType(PyBaseDescriptor * self,PyObject * value,void * closure)806 static int SetEnumType(PyBaseDescriptor *self, PyObject *value, void *closure) {
807 return CheckCalledFromGeneratedFile("enum_type");
808 }
809
GetMessageType(PyBaseDescriptor * self,void * closure)810 static PyObject *GetMessageType(PyBaseDescriptor *self, void *closure) {
811 const Descriptor* message_type = _GetDescriptor(self)->message_type();
812 if (message_type) {
813 return PyMessageDescriptor_FromDescriptor(message_type);
814 } else {
815 Py_RETURN_NONE;
816 }
817 }
818
SetMessageType(PyBaseDescriptor * self,PyObject * value,void * closure)819 static int SetMessageType(PyBaseDescriptor *self, PyObject *value,
820 void *closure) {
821 return CheckCalledFromGeneratedFile("message_type");
822 }
823
GetContainingType(PyBaseDescriptor * self,void * closure)824 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
825 const Descriptor* containing_type =
826 _GetDescriptor(self)->containing_type();
827 if (containing_type) {
828 return PyMessageDescriptor_FromDescriptor(containing_type);
829 } else {
830 Py_RETURN_NONE;
831 }
832 }
833
SetContainingType(PyBaseDescriptor * self,PyObject * value,void * closure)834 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
835 void *closure) {
836 return CheckCalledFromGeneratedFile("containing_type");
837 }
838
GetExtensionScope(PyBaseDescriptor * self,void * closure)839 static PyObject* GetExtensionScope(PyBaseDescriptor *self, void *closure) {
840 const Descriptor* extension_scope =
841 _GetDescriptor(self)->extension_scope();
842 if (extension_scope) {
843 return PyMessageDescriptor_FromDescriptor(extension_scope);
844 } else {
845 Py_RETURN_NONE;
846 }
847 }
848
GetContainingOneof(PyBaseDescriptor * self,void * closure)849 static PyObject* GetContainingOneof(PyBaseDescriptor *self, void *closure) {
850 const OneofDescriptor* containing_oneof =
851 _GetDescriptor(self)->containing_oneof();
852 if (containing_oneof) {
853 return PyOneofDescriptor_FromDescriptor(containing_oneof);
854 } else {
855 Py_RETURN_NONE;
856 }
857 }
858
SetContainingOneof(PyBaseDescriptor * self,PyObject * value,void * closure)859 static int SetContainingOneof(PyBaseDescriptor *self, PyObject *value,
860 void *closure) {
861 return CheckCalledFromGeneratedFile("containing_oneof");
862 }
863
GetHasOptions(PyBaseDescriptor * self,void * closure)864 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
865 const FieldOptions& options(_GetDescriptor(self)->options());
866 if (&options != &FieldOptions::default_instance()) {
867 Py_RETURN_TRUE;
868 } else {
869 Py_RETURN_FALSE;
870 }
871 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)872 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
873 void *closure) {
874 return CheckCalledFromGeneratedFile("has_options");
875 }
876
GetOptions(PyBaseDescriptor * self)877 static PyObject* GetOptions(PyBaseDescriptor *self) {
878 return GetOrBuildOptions(_GetDescriptor(self));
879 }
880
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)881 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
882 void *closure) {
883 return CheckCalledFromGeneratedFile("_options");
884 }
885
886
887 static PyGetSetDef Getters[] = {
888 { "full_name", (getter)GetFullName, NULL, "Full name"},
889 { "name", (getter)GetName, NULL, "Unqualified name"},
890 { "camelcase_name", (getter)GetCamelcaseName, NULL, "Camelcase name"},
891 { "type", (getter)GetType, NULL, "C++ Type"},
892 { "cpp_type", (getter)GetCppType, NULL, "C++ Type"},
893 { "label", (getter)GetLabel, NULL, "Label"},
894 { "number", (getter)GetNumber, NULL, "Number"},
895 { "index", (getter)GetIndex, NULL, "Index"},
896 { "default_value", (getter)GetDefaultValue, NULL, "Default Value"},
897 { "has_default_value", (getter)HasDefaultValue},
898 { "is_extension", (getter)IsExtension, NULL, "ID"},
899 { "id", (getter)GetID, NULL, "ID"},
900 { "_cdescriptor", (getter)GetCDescriptor, NULL, "HAACK REMOVE ME"},
901
902 { "message_type", (getter)GetMessageType, (setter)SetMessageType,
903 "Message type"},
904 { "enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"},
905 { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
906 "Containing type"},
907 { "extension_scope", (getter)GetExtensionScope, (setter)NULL,
908 "Extension scope"},
909 { "containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof,
910 "Containing oneof"},
911 { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
912 { "_options", (getter)NULL, (setter)SetOptions, "Options"},
913 {NULL}
914 };
915
916 static PyMethodDef Methods[] = {
917 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
918 {NULL}
919 };
920
921 } // namespace field_descriptor
922
923 PyTypeObject PyFieldDescriptor_Type = {
924 PyVarObject_HEAD_INIT(&PyType_Type, 0)
925 FULL_MODULE_NAME ".FieldDescriptor", // tp_name
926 sizeof(PyBaseDescriptor), // tp_basicsize
927 0, // tp_itemsize
928 0, // tp_dealloc
929 0, // tp_print
930 0, // tp_getattr
931 0, // tp_setattr
932 0, // tp_compare
933 0, // tp_repr
934 0, // tp_as_number
935 0, // tp_as_sequence
936 0, // tp_as_mapping
937 0, // tp_hash
938 0, // tp_call
939 0, // tp_str
940 0, // tp_getattro
941 0, // tp_setattro
942 0, // tp_as_buffer
943 Py_TPFLAGS_DEFAULT, // tp_flags
944 "A Field Descriptor", // tp_doc
945 0, // tp_traverse
946 0, // tp_clear
947 0, // tp_richcompare
948 0, // tp_weaklistoffset
949 0, // tp_iter
950 0, // tp_iternext
951 field_descriptor::Methods, // tp_methods
952 0, // tp_members
953 field_descriptor::Getters, // tp_getset
954 &descriptor::PyBaseDescriptor_Type, // tp_base
955 };
956
PyFieldDescriptor_FromDescriptor(const FieldDescriptor * field_descriptor)957 PyObject* PyFieldDescriptor_FromDescriptor(
958 const FieldDescriptor* field_descriptor) {
959 return descriptor::NewInternedDescriptor(
960 &PyFieldDescriptor_Type, field_descriptor, NULL);
961 }
962
PyFieldDescriptor_AsDescriptor(PyObject * obj)963 const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj) {
964 if (!PyObject_TypeCheck(obj, &PyFieldDescriptor_Type)) {
965 PyErr_SetString(PyExc_TypeError, "Not a FieldDescriptor");
966 return NULL;
967 }
968 return reinterpret_cast<const FieldDescriptor*>(
969 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
970 }
971
972 namespace enum_descriptor {
973
974 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)975 static const EnumDescriptor* _GetDescriptor(
976 PyBaseDescriptor *self) {
977 return reinterpret_cast<const EnumDescriptor*>(self->descriptor);
978 }
979
GetFullName(PyBaseDescriptor * self,void * closure)980 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
981 return PyString_FromCppString(_GetDescriptor(self)->full_name());
982 }
983
GetName(PyBaseDescriptor * self,void * closure)984 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
985 return PyString_FromCppString(_GetDescriptor(self)->name());
986 }
987
GetFile(PyBaseDescriptor * self,void * closure)988 static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
989 return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
990 }
991
GetEnumvaluesByName(PyBaseDescriptor * self,void * closure)992 static PyObject* GetEnumvaluesByName(PyBaseDescriptor* self, void *closure) {
993 return NewEnumValuesByName(_GetDescriptor(self));
994 }
995
GetEnumvaluesByNumber(PyBaseDescriptor * self,void * closure)996 static PyObject* GetEnumvaluesByNumber(PyBaseDescriptor* self, void *closure) {
997 return NewEnumValuesByNumber(_GetDescriptor(self));
998 }
999
GetEnumvaluesSeq(PyBaseDescriptor * self,void * closure)1000 static PyObject* GetEnumvaluesSeq(PyBaseDescriptor* self, void *closure) {
1001 return NewEnumValuesSeq(_GetDescriptor(self));
1002 }
1003
GetContainingType(PyBaseDescriptor * self,void * closure)1004 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
1005 const Descriptor* containing_type =
1006 _GetDescriptor(self)->containing_type();
1007 if (containing_type) {
1008 return PyMessageDescriptor_FromDescriptor(containing_type);
1009 } else {
1010 Py_RETURN_NONE;
1011 }
1012 }
1013
SetContainingType(PyBaseDescriptor * self,PyObject * value,void * closure)1014 static int SetContainingType(PyBaseDescriptor *self, PyObject *value,
1015 void *closure) {
1016 return CheckCalledFromGeneratedFile("containing_type");
1017 }
1018
1019
GetHasOptions(PyBaseDescriptor * self,void * closure)1020 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
1021 const EnumOptions& options(_GetDescriptor(self)->options());
1022 if (&options != &EnumOptions::default_instance()) {
1023 Py_RETURN_TRUE;
1024 } else {
1025 Py_RETURN_FALSE;
1026 }
1027 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1028 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
1029 void *closure) {
1030 return CheckCalledFromGeneratedFile("has_options");
1031 }
1032
GetOptions(PyBaseDescriptor * self)1033 static PyObject* GetOptions(PyBaseDescriptor *self) {
1034 return GetOrBuildOptions(_GetDescriptor(self));
1035 }
1036
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1037 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
1038 void *closure) {
1039 return CheckCalledFromGeneratedFile("_options");
1040 }
1041
CopyToProto(PyBaseDescriptor * self,PyObject * target)1042 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
1043 return CopyToPythonProto<EnumDescriptorProto>(_GetDescriptor(self), target);
1044 }
1045
1046 static PyMethodDef Methods[] = {
1047 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
1048 { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
1049 {NULL}
1050 };
1051
1052 static PyGetSetDef Getters[] = {
1053 { "full_name", (getter)GetFullName, NULL, "Full name"},
1054 { "name", (getter)GetName, NULL, "last name"},
1055 { "file", (getter)GetFile, NULL, "File descriptor"},
1056 { "values", (getter)GetEnumvaluesSeq, NULL, "values"},
1057 { "values_by_name", (getter)GetEnumvaluesByName, NULL,
1058 "Enum values by name"},
1059 { "values_by_number", (getter)GetEnumvaluesByNumber, NULL,
1060 "Enum values by number"},
1061
1062 { "containing_type", (getter)GetContainingType, (setter)SetContainingType,
1063 "Containing type"},
1064 { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
1065 { "_options", (getter)NULL, (setter)SetOptions, "Options"},
1066 {NULL}
1067 };
1068
1069 } // namespace enum_descriptor
1070
1071 PyTypeObject PyEnumDescriptor_Type = {
1072 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1073 FULL_MODULE_NAME ".EnumDescriptor", // tp_name
1074 sizeof(PyBaseDescriptor), // tp_basicsize
1075 0, // tp_itemsize
1076 0, // tp_dealloc
1077 0, // tp_print
1078 0, // tp_getattr
1079 0, // tp_setattr
1080 0, // tp_compare
1081 0, // tp_repr
1082 0, // tp_as_number
1083 0, // tp_as_sequence
1084 0, // tp_as_mapping
1085 0, // tp_hash
1086 0, // tp_call
1087 0, // tp_str
1088 0, // tp_getattro
1089 0, // tp_setattro
1090 0, // tp_as_buffer
1091 Py_TPFLAGS_DEFAULT, // tp_flags
1092 "A Enum Descriptor", // tp_doc
1093 0, // tp_traverse
1094 0, // tp_clear
1095 0, // tp_richcompare
1096 0, // tp_weaklistoffset
1097 0, // tp_iter
1098 0, // tp_iternext
1099 enum_descriptor::Methods, // tp_methods
1100 0, // tp_members
1101 enum_descriptor::Getters, // tp_getset
1102 &descriptor::PyBaseDescriptor_Type, // tp_base
1103 };
1104
PyEnumDescriptor_FromDescriptor(const EnumDescriptor * enum_descriptor)1105 PyObject* PyEnumDescriptor_FromDescriptor(
1106 const EnumDescriptor* enum_descriptor) {
1107 return descriptor::NewInternedDescriptor(
1108 &PyEnumDescriptor_Type, enum_descriptor, NULL);
1109 }
1110
PyEnumDescriptor_AsDescriptor(PyObject * obj)1111 const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj) {
1112 if (!PyObject_TypeCheck(obj, &PyEnumDescriptor_Type)) {
1113 PyErr_SetString(PyExc_TypeError, "Not an EnumDescriptor");
1114 return NULL;
1115 }
1116 return reinterpret_cast<const EnumDescriptor*>(
1117 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
1118 }
1119
1120 namespace enumvalue_descriptor {
1121
1122 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)1123 static const EnumValueDescriptor* _GetDescriptor(
1124 PyBaseDescriptor *self) {
1125 return reinterpret_cast<const EnumValueDescriptor*>(self->descriptor);
1126 }
1127
GetName(PyBaseDescriptor * self,void * closure)1128 static PyObject* GetName(PyBaseDescriptor *self, void *closure) {
1129 return PyString_FromCppString(_GetDescriptor(self)->name());
1130 }
1131
GetNumber(PyBaseDescriptor * self,void * closure)1132 static PyObject* GetNumber(PyBaseDescriptor *self, void *closure) {
1133 return PyInt_FromLong(_GetDescriptor(self)->number());
1134 }
1135
GetIndex(PyBaseDescriptor * self,void * closure)1136 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
1137 return PyInt_FromLong(_GetDescriptor(self)->index());
1138 }
1139
GetType(PyBaseDescriptor * self,void * closure)1140 static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
1141 return PyEnumDescriptor_FromDescriptor(_GetDescriptor(self)->type());
1142 }
1143
GetHasOptions(PyBaseDescriptor * self,void * closure)1144 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
1145 const EnumValueOptions& options(_GetDescriptor(self)->options());
1146 if (&options != &EnumValueOptions::default_instance()) {
1147 Py_RETURN_TRUE;
1148 } else {
1149 Py_RETURN_FALSE;
1150 }
1151 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1152 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
1153 void *closure) {
1154 return CheckCalledFromGeneratedFile("has_options");
1155 }
1156
GetOptions(PyBaseDescriptor * self)1157 static PyObject* GetOptions(PyBaseDescriptor *self) {
1158 return GetOrBuildOptions(_GetDescriptor(self));
1159 }
1160
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1161 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
1162 void *closure) {
1163 return CheckCalledFromGeneratedFile("_options");
1164 }
1165
1166
1167 static PyGetSetDef Getters[] = {
1168 { "name", (getter)GetName, NULL, "name"},
1169 { "number", (getter)GetNumber, NULL, "number"},
1170 { "index", (getter)GetIndex, NULL, "index"},
1171 { "type", (getter)GetType, NULL, "index"},
1172
1173 { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
1174 { "_options", (getter)NULL, (setter)SetOptions, "Options"},
1175 {NULL}
1176 };
1177
1178 static PyMethodDef Methods[] = {
1179 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
1180 {NULL}
1181 };
1182
1183 } // namespace enumvalue_descriptor
1184
1185 PyTypeObject PyEnumValueDescriptor_Type = {
1186 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1187 FULL_MODULE_NAME ".EnumValueDescriptor", // tp_name
1188 sizeof(PyBaseDescriptor), // tp_basicsize
1189 0, // tp_itemsize
1190 0, // tp_dealloc
1191 0, // tp_print
1192 0, // tp_getattr
1193 0, // tp_setattr
1194 0, // tp_compare
1195 0, // tp_repr
1196 0, // tp_as_number
1197 0, // tp_as_sequence
1198 0, // tp_as_mapping
1199 0, // tp_hash
1200 0, // tp_call
1201 0, // tp_str
1202 0, // tp_getattro
1203 0, // tp_setattro
1204 0, // tp_as_buffer
1205 Py_TPFLAGS_DEFAULT, // tp_flags
1206 "A EnumValue Descriptor", // tp_doc
1207 0, // tp_traverse
1208 0, // tp_clear
1209 0, // tp_richcompare
1210 0, // tp_weaklistoffset
1211 0, // tp_iter
1212 0, // tp_iternext
1213 enumvalue_descriptor::Methods, // tp_methods
1214 0, // tp_members
1215 enumvalue_descriptor::Getters, // tp_getset
1216 &descriptor::PyBaseDescriptor_Type, // tp_base
1217 };
1218
PyEnumValueDescriptor_FromDescriptor(const EnumValueDescriptor * enumvalue_descriptor)1219 PyObject* PyEnumValueDescriptor_FromDescriptor(
1220 const EnumValueDescriptor* enumvalue_descriptor) {
1221 return descriptor::NewInternedDescriptor(
1222 &PyEnumValueDescriptor_Type, enumvalue_descriptor, NULL);
1223 }
1224
1225 namespace file_descriptor {
1226
1227 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyFileDescriptor * self)1228 static const FileDescriptor* _GetDescriptor(PyFileDescriptor *self) {
1229 return reinterpret_cast<const FileDescriptor*>(self->base.descriptor);
1230 }
1231
Dealloc(PyFileDescriptor * self)1232 static void Dealloc(PyFileDescriptor* self) {
1233 Py_XDECREF(self->serialized_pb);
1234 descriptor::Dealloc(&self->base);
1235 }
1236
GetPool(PyFileDescriptor * self,void * closure)1237 static PyObject* GetPool(PyFileDescriptor *self, void *closure) {
1238 PyObject* pool = reinterpret_cast<PyObject*>(
1239 GetDescriptorPool_FromPool(_GetDescriptor(self)->pool()));
1240 Py_XINCREF(pool);
1241 return pool;
1242 }
1243
GetName(PyFileDescriptor * self,void * closure)1244 static PyObject* GetName(PyFileDescriptor *self, void *closure) {
1245 return PyString_FromCppString(_GetDescriptor(self)->name());
1246 }
1247
GetPackage(PyFileDescriptor * self,void * closure)1248 static PyObject* GetPackage(PyFileDescriptor *self, void *closure) {
1249 return PyString_FromCppString(_GetDescriptor(self)->package());
1250 }
1251
GetSerializedPb(PyFileDescriptor * self,void * closure)1252 static PyObject* GetSerializedPb(PyFileDescriptor *self, void *closure) {
1253 PyObject *serialized_pb = self->serialized_pb;
1254 if (serialized_pb != NULL) {
1255 Py_INCREF(serialized_pb);
1256 return serialized_pb;
1257 }
1258 FileDescriptorProto file_proto;
1259 _GetDescriptor(self)->CopyTo(&file_proto);
1260 string contents;
1261 file_proto.SerializePartialToString(&contents);
1262 self->serialized_pb = PyBytes_FromStringAndSize(
1263 contents.c_str(), contents.size());
1264 if (self->serialized_pb == NULL) {
1265 return NULL;
1266 }
1267 Py_INCREF(self->serialized_pb);
1268 return self->serialized_pb;
1269 }
1270
GetMessageTypesByName(PyFileDescriptor * self,void * closure)1271 static PyObject* GetMessageTypesByName(PyFileDescriptor* self, void *closure) {
1272 return NewFileMessageTypesByName(_GetDescriptor(self));
1273 }
1274
GetEnumTypesByName(PyFileDescriptor * self,void * closure)1275 static PyObject* GetEnumTypesByName(PyFileDescriptor* self, void *closure) {
1276 return NewFileEnumTypesByName(_GetDescriptor(self));
1277 }
1278
GetExtensionsByName(PyFileDescriptor * self,void * closure)1279 static PyObject* GetExtensionsByName(PyFileDescriptor* self, void *closure) {
1280 return NewFileExtensionsByName(_GetDescriptor(self));
1281 }
1282
GetServicesByName(PyFileDescriptor * self,void * closure)1283 static PyObject* GetServicesByName(PyFileDescriptor* self, void *closure) {
1284 return NewFileServicesByName(_GetDescriptor(self));
1285 }
1286
GetDependencies(PyFileDescriptor * self,void * closure)1287 static PyObject* GetDependencies(PyFileDescriptor* self, void *closure) {
1288 return NewFileDependencies(_GetDescriptor(self));
1289 }
1290
GetPublicDependencies(PyFileDescriptor * self,void * closure)1291 static PyObject* GetPublicDependencies(PyFileDescriptor* self, void *closure) {
1292 return NewFilePublicDependencies(_GetDescriptor(self));
1293 }
1294
GetHasOptions(PyFileDescriptor * self,void * closure)1295 static PyObject* GetHasOptions(PyFileDescriptor *self, void *closure) {
1296 const FileOptions& options(_GetDescriptor(self)->options());
1297 if (&options != &FileOptions::default_instance()) {
1298 Py_RETURN_TRUE;
1299 } else {
1300 Py_RETURN_FALSE;
1301 }
1302 }
SetHasOptions(PyFileDescriptor * self,PyObject * value,void * closure)1303 static int SetHasOptions(PyFileDescriptor *self, PyObject *value,
1304 void *closure) {
1305 return CheckCalledFromGeneratedFile("has_options");
1306 }
1307
GetOptions(PyFileDescriptor * self)1308 static PyObject* GetOptions(PyFileDescriptor *self) {
1309 return GetOrBuildOptions(_GetDescriptor(self));
1310 }
1311
SetOptions(PyFileDescriptor * self,PyObject * value,void * closure)1312 static int SetOptions(PyFileDescriptor *self, PyObject *value,
1313 void *closure) {
1314 return CheckCalledFromGeneratedFile("_options");
1315 }
1316
GetSyntax(PyFileDescriptor * self,void * closure)1317 static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) {
1318 return PyString_InternFromString(
1319 FileDescriptor::SyntaxName(_GetDescriptor(self)->syntax()));
1320 }
1321
CopyToProto(PyFileDescriptor * self,PyObject * target)1322 static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) {
1323 return CopyToPythonProto<FileDescriptorProto>(_GetDescriptor(self), target);
1324 }
1325
1326 static PyGetSetDef Getters[] = {
1327 { "pool", (getter)GetPool, NULL, "pool"},
1328 { "name", (getter)GetName, NULL, "name"},
1329 { "package", (getter)GetPackage, NULL, "package"},
1330 { "serialized_pb", (getter)GetSerializedPb},
1331 { "message_types_by_name", (getter)GetMessageTypesByName, NULL,
1332 "Messages by name"},
1333 { "enum_types_by_name", (getter)GetEnumTypesByName, NULL, "Enums by name"},
1334 { "extensions_by_name", (getter)GetExtensionsByName, NULL,
1335 "Extensions by name"},
1336 { "services_by_name", (getter)GetServicesByName, NULL, "Services by name"},
1337 { "dependencies", (getter)GetDependencies, NULL, "Dependencies"},
1338 { "public_dependencies", (getter)GetPublicDependencies, NULL, "Dependencies"},
1339
1340 { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
1341 { "_options", (getter)NULL, (setter)SetOptions, "Options"},
1342 { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"},
1343 {NULL}
1344 };
1345
1346 static PyMethodDef Methods[] = {
1347 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
1348 { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
1349 {NULL}
1350 };
1351
1352 } // namespace file_descriptor
1353
1354 PyTypeObject PyFileDescriptor_Type = {
1355 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1356 FULL_MODULE_NAME ".FileDescriptor", // tp_name
1357 sizeof(PyFileDescriptor), // tp_basicsize
1358 0, // tp_itemsize
1359 (destructor)file_descriptor::Dealloc, // tp_dealloc
1360 0, // tp_print
1361 0, // tp_getattr
1362 0, // tp_setattr
1363 0, // tp_compare
1364 0, // tp_repr
1365 0, // tp_as_number
1366 0, // tp_as_sequence
1367 0, // tp_as_mapping
1368 0, // tp_hash
1369 0, // tp_call
1370 0, // tp_str
1371 0, // tp_getattro
1372 0, // tp_setattro
1373 0, // tp_as_buffer
1374 Py_TPFLAGS_DEFAULT, // tp_flags
1375 "A File Descriptor", // tp_doc
1376 0, // tp_traverse
1377 0, // tp_clear
1378 0, // tp_richcompare
1379 0, // tp_weaklistoffset
1380 0, // tp_iter
1381 0, // tp_iternext
1382 file_descriptor::Methods, // tp_methods
1383 0, // tp_members
1384 file_descriptor::Getters, // tp_getset
1385 &descriptor::PyBaseDescriptor_Type, // tp_base
1386 0, // tp_dict
1387 0, // tp_descr_get
1388 0, // tp_descr_set
1389 0, // tp_dictoffset
1390 0, // tp_init
1391 0, // tp_alloc
1392 0, // tp_new
1393 PyObject_Del, // tp_free
1394 };
1395
PyFileDescriptor_FromDescriptor(const FileDescriptor * file_descriptor)1396 PyObject* PyFileDescriptor_FromDescriptor(
1397 const FileDescriptor* file_descriptor) {
1398 return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor,
1399 NULL);
1400 }
1401
PyFileDescriptor_FromDescriptorWithSerializedPb(const FileDescriptor * file_descriptor,PyObject * serialized_pb)1402 PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb(
1403 const FileDescriptor* file_descriptor, PyObject *serialized_pb) {
1404 bool was_created;
1405 PyObject* py_descriptor = descriptor::NewInternedDescriptor(
1406 &PyFileDescriptor_Type, file_descriptor, &was_created);
1407 if (py_descriptor == NULL) {
1408 return NULL;
1409 }
1410 if (was_created) {
1411 PyFileDescriptor* cfile_descriptor =
1412 reinterpret_cast<PyFileDescriptor*>(py_descriptor);
1413 Py_XINCREF(serialized_pb);
1414 cfile_descriptor->serialized_pb = serialized_pb;
1415 }
1416 // TODO(amauryfa): In the case of a cached object, check that serialized_pb
1417 // is the same as before.
1418
1419 return py_descriptor;
1420 }
1421
PyFileDescriptor_AsDescriptor(PyObject * obj)1422 const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj) {
1423 if (!PyObject_TypeCheck(obj, &PyFileDescriptor_Type)) {
1424 PyErr_SetString(PyExc_TypeError, "Not a FileDescriptor");
1425 return NULL;
1426 }
1427 return reinterpret_cast<const FileDescriptor*>(
1428 reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
1429 }
1430
1431 namespace oneof_descriptor {
1432
1433 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)1434 static const OneofDescriptor* _GetDescriptor(
1435 PyBaseDescriptor *self) {
1436 return reinterpret_cast<const OneofDescriptor*>(self->descriptor);
1437 }
1438
GetName(PyBaseDescriptor * self,void * closure)1439 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
1440 return PyString_FromCppString(_GetDescriptor(self)->name());
1441 }
1442
GetFullName(PyBaseDescriptor * self,void * closure)1443 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
1444 return PyString_FromCppString(_GetDescriptor(self)->full_name());
1445 }
1446
GetIndex(PyBaseDescriptor * self,void * closure)1447 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
1448 return PyInt_FromLong(_GetDescriptor(self)->index());
1449 }
1450
GetFields(PyBaseDescriptor * self,void * closure)1451 static PyObject* GetFields(PyBaseDescriptor* self, void *closure) {
1452 return NewOneofFieldsSeq(_GetDescriptor(self));
1453 }
1454
GetContainingType(PyBaseDescriptor * self,void * closure)1455 static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
1456 const Descriptor* containing_type =
1457 _GetDescriptor(self)->containing_type();
1458 if (containing_type) {
1459 return PyMessageDescriptor_FromDescriptor(containing_type);
1460 } else {
1461 Py_RETURN_NONE;
1462 }
1463 }
1464
GetHasOptions(PyBaseDescriptor * self,void * closure)1465 static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
1466 const OneofOptions& options(_GetDescriptor(self)->options());
1467 if (&options != &OneofOptions::default_instance()) {
1468 Py_RETURN_TRUE;
1469 } else {
1470 Py_RETURN_FALSE;
1471 }
1472 }
SetHasOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1473 static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
1474 void *closure) {
1475 return CheckCalledFromGeneratedFile("has_options");
1476 }
1477
GetOptions(PyBaseDescriptor * self)1478 static PyObject* GetOptions(PyBaseDescriptor *self) {
1479 return GetOrBuildOptions(_GetDescriptor(self));
1480 }
1481
SetOptions(PyBaseDescriptor * self,PyObject * value,void * closure)1482 static int SetOptions(PyBaseDescriptor *self, PyObject *value,
1483 void *closure) {
1484 return CheckCalledFromGeneratedFile("_options");
1485 }
1486
1487 static PyGetSetDef Getters[] = {
1488 { "name", (getter)GetName, NULL, "Name"},
1489 { "full_name", (getter)GetFullName, NULL, "Full name"},
1490 { "index", (getter)GetIndex, NULL, "Index"},
1491
1492 { "containing_type", (getter)GetContainingType, NULL, "Containing type"},
1493 { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
1494 { "_options", (getter)NULL, (setter)SetOptions, "Options"},
1495 { "fields", (getter)GetFields, NULL, "Fields"},
1496 {NULL}
1497 };
1498
1499 static PyMethodDef Methods[] = {
1500 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS },
1501 {NULL}
1502 };
1503
1504 } // namespace oneof_descriptor
1505
1506 PyTypeObject PyOneofDescriptor_Type = {
1507 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1508 FULL_MODULE_NAME ".OneofDescriptor", // tp_name
1509 sizeof(PyBaseDescriptor), // tp_basicsize
1510 0, // tp_itemsize
1511 0, // tp_dealloc
1512 0, // tp_print
1513 0, // tp_getattr
1514 0, // tp_setattr
1515 0, // tp_compare
1516 0, // tp_repr
1517 0, // tp_as_number
1518 0, // tp_as_sequence
1519 0, // tp_as_mapping
1520 0, // tp_hash
1521 0, // tp_call
1522 0, // tp_str
1523 0, // tp_getattro
1524 0, // tp_setattro
1525 0, // tp_as_buffer
1526 Py_TPFLAGS_DEFAULT, // tp_flags
1527 "A Oneof Descriptor", // tp_doc
1528 0, // tp_traverse
1529 0, // tp_clear
1530 0, // tp_richcompare
1531 0, // tp_weaklistoffset
1532 0, // tp_iter
1533 0, // tp_iternext
1534 oneof_descriptor::Methods, // tp_methods
1535 0, // tp_members
1536 oneof_descriptor::Getters, // tp_getset
1537 &descriptor::PyBaseDescriptor_Type, // tp_base
1538 };
1539
PyOneofDescriptor_FromDescriptor(const OneofDescriptor * oneof_descriptor)1540 PyObject* PyOneofDescriptor_FromDescriptor(
1541 const OneofDescriptor* oneof_descriptor) {
1542 return descriptor::NewInternedDescriptor(
1543 &PyOneofDescriptor_Type, oneof_descriptor, NULL);
1544 }
1545
1546 namespace service_descriptor {
1547
1548 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)1549 static const ServiceDescriptor* _GetDescriptor(
1550 PyBaseDescriptor *self) {
1551 return reinterpret_cast<const ServiceDescriptor*>(self->descriptor);
1552 }
1553
GetName(PyBaseDescriptor * self,void * closure)1554 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
1555 return PyString_FromCppString(_GetDescriptor(self)->name());
1556 }
1557
GetFullName(PyBaseDescriptor * self,void * closure)1558 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
1559 return PyString_FromCppString(_GetDescriptor(self)->full_name());
1560 }
1561
GetIndex(PyBaseDescriptor * self,void * closure)1562 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
1563 return PyInt_FromLong(_GetDescriptor(self)->index());
1564 }
1565
GetMethods(PyBaseDescriptor * self,void * closure)1566 static PyObject* GetMethods(PyBaseDescriptor* self, void *closure) {
1567 return NewServiceMethodsSeq(_GetDescriptor(self));
1568 }
1569
GetMethodsByName(PyBaseDescriptor * self,void * closure)1570 static PyObject* GetMethodsByName(PyBaseDescriptor* self, void *closure) {
1571 return NewServiceMethodsByName(_GetDescriptor(self));
1572 }
1573
FindMethodByName(PyBaseDescriptor * self,PyObject * arg)1574 static PyObject* FindMethodByName(PyBaseDescriptor *self, PyObject* arg) {
1575 Py_ssize_t name_size;
1576 char* name;
1577 if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
1578 return NULL;
1579 }
1580
1581 const MethodDescriptor* method_descriptor =
1582 _GetDescriptor(self)->FindMethodByName(string(name, name_size));
1583 if (method_descriptor == NULL) {
1584 PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
1585 return NULL;
1586 }
1587
1588 return PyMethodDescriptor_FromDescriptor(method_descriptor);
1589 }
1590
GetOptions(PyBaseDescriptor * self)1591 static PyObject* GetOptions(PyBaseDescriptor *self) {
1592 return GetOrBuildOptions(_GetDescriptor(self));
1593 }
1594
CopyToProto(PyBaseDescriptor * self,PyObject * target)1595 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
1596 return CopyToPythonProto<ServiceDescriptorProto>(_GetDescriptor(self),
1597 target);
1598 }
1599
1600 static PyGetSetDef Getters[] = {
1601 { "name", (getter)GetName, NULL, "Name", NULL},
1602 { "full_name", (getter)GetFullName, NULL, "Full name", NULL},
1603 { "index", (getter)GetIndex, NULL, "Index", NULL},
1604
1605 { "methods", (getter)GetMethods, NULL, "Methods", NULL},
1606 { "methods_by_name", (getter)GetMethodsByName, NULL, "Methods by name", NULL},
1607 {NULL}
1608 };
1609
1610 static PyMethodDef Methods[] = {
1611 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS },
1612 { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
1613 { "FindMethodByName", (PyCFunction)FindMethodByName, METH_O },
1614 {NULL}
1615 };
1616
1617 } // namespace service_descriptor
1618
1619 PyTypeObject PyServiceDescriptor_Type = {
1620 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1621 FULL_MODULE_NAME ".ServiceDescriptor", // tp_name
1622 sizeof(PyBaseDescriptor), // tp_basicsize
1623 0, // tp_itemsize
1624 0, // tp_dealloc
1625 0, // tp_print
1626 0, // tp_getattr
1627 0, // tp_setattr
1628 0, // tp_compare
1629 0, // tp_repr
1630 0, // tp_as_number
1631 0, // tp_as_sequence
1632 0, // tp_as_mapping
1633 0, // tp_hash
1634 0, // tp_call
1635 0, // tp_str
1636 0, // tp_getattro
1637 0, // tp_setattro
1638 0, // tp_as_buffer
1639 Py_TPFLAGS_DEFAULT, // tp_flags
1640 "A Service Descriptor", // tp_doc
1641 0, // tp_traverse
1642 0, // tp_clear
1643 0, // tp_richcompare
1644 0, // tp_weaklistoffset
1645 0, // tp_iter
1646 0, // tp_iternext
1647 service_descriptor::Methods, // tp_methods
1648 0, // tp_members
1649 service_descriptor::Getters, // tp_getset
1650 &descriptor::PyBaseDescriptor_Type, // tp_base
1651 };
1652
PyServiceDescriptor_FromDescriptor(const ServiceDescriptor * service_descriptor)1653 PyObject* PyServiceDescriptor_FromDescriptor(
1654 const ServiceDescriptor* service_descriptor) {
1655 return descriptor::NewInternedDescriptor(
1656 &PyServiceDescriptor_Type, service_descriptor, NULL);
1657 }
1658
1659 namespace method_descriptor {
1660
1661 // Unchecked accessor to the C++ pointer.
_GetDescriptor(PyBaseDescriptor * self)1662 static const MethodDescriptor* _GetDescriptor(
1663 PyBaseDescriptor *self) {
1664 return reinterpret_cast<const MethodDescriptor*>(self->descriptor);
1665 }
1666
GetName(PyBaseDescriptor * self,void * closure)1667 static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
1668 return PyString_FromCppString(_GetDescriptor(self)->name());
1669 }
1670
GetFullName(PyBaseDescriptor * self,void * closure)1671 static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
1672 return PyString_FromCppString(_GetDescriptor(self)->full_name());
1673 }
1674
GetIndex(PyBaseDescriptor * self,void * closure)1675 static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
1676 return PyInt_FromLong(_GetDescriptor(self)->index());
1677 }
1678
GetContainingService(PyBaseDescriptor * self,void * closure)1679 static PyObject* GetContainingService(PyBaseDescriptor *self, void *closure) {
1680 const ServiceDescriptor* containing_service =
1681 _GetDescriptor(self)->service();
1682 return PyServiceDescriptor_FromDescriptor(containing_service);
1683 }
1684
GetInputType(PyBaseDescriptor * self,void * closure)1685 static PyObject* GetInputType(PyBaseDescriptor *self, void *closure) {
1686 const Descriptor* input_type = _GetDescriptor(self)->input_type();
1687 return PyMessageDescriptor_FromDescriptor(input_type);
1688 }
1689
GetOutputType(PyBaseDescriptor * self,void * closure)1690 static PyObject* GetOutputType(PyBaseDescriptor *self, void *closure) {
1691 const Descriptor* output_type = _GetDescriptor(self)->output_type();
1692 return PyMessageDescriptor_FromDescriptor(output_type);
1693 }
1694
GetOptions(PyBaseDescriptor * self)1695 static PyObject* GetOptions(PyBaseDescriptor *self) {
1696 return GetOrBuildOptions(_GetDescriptor(self));
1697 }
1698
CopyToProto(PyBaseDescriptor * self,PyObject * target)1699 static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
1700 return CopyToPythonProto<MethodDescriptorProto>(_GetDescriptor(self), target);
1701 }
1702
1703 static PyGetSetDef Getters[] = {
1704 { "name", (getter)GetName, NULL, "Name", NULL},
1705 { "full_name", (getter)GetFullName, NULL, "Full name", NULL},
1706 { "index", (getter)GetIndex, NULL, "Index", NULL},
1707 { "containing_service", (getter)GetContainingService, NULL,
1708 "Containing service", NULL},
1709 { "input_type", (getter)GetInputType, NULL, "Input type", NULL},
1710 { "output_type", (getter)GetOutputType, NULL, "Output type", NULL},
1711 {NULL}
1712 };
1713
1714 static PyMethodDef Methods[] = {
1715 { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
1716 { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
1717 {NULL}
1718 };
1719
1720 } // namespace method_descriptor
1721
1722 PyTypeObject PyMethodDescriptor_Type = {
1723 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1724 FULL_MODULE_NAME ".MethodDescriptor", // tp_name
1725 sizeof(PyBaseDescriptor), // tp_basicsize
1726 0, // tp_itemsize
1727 0, // tp_dealloc
1728 0, // tp_print
1729 0, // tp_getattr
1730 0, // tp_setattr
1731 0, // tp_compare
1732 0, // tp_repr
1733 0, // tp_as_number
1734 0, // tp_as_sequence
1735 0, // tp_as_mapping
1736 0, // tp_hash
1737 0, // tp_call
1738 0, // tp_str
1739 0, // tp_getattro
1740 0, // tp_setattro
1741 0, // tp_as_buffer
1742 Py_TPFLAGS_DEFAULT, // tp_flags
1743 "A Method Descriptor", // tp_doc
1744 0, // tp_traverse
1745 0, // tp_clear
1746 0, // tp_richcompare
1747 0, // tp_weaklistoffset
1748 0, // tp_iter
1749 0, // tp_iternext
1750 method_descriptor::Methods, // tp_methods
1751 0, // tp_members
1752 method_descriptor::Getters, // tp_getset
1753 &descriptor::PyBaseDescriptor_Type, // tp_base
1754 };
1755
PyMethodDescriptor_FromDescriptor(const MethodDescriptor * method_descriptor)1756 PyObject* PyMethodDescriptor_FromDescriptor(
1757 const MethodDescriptor* method_descriptor) {
1758 return descriptor::NewInternedDescriptor(
1759 &PyMethodDescriptor_Type, method_descriptor, NULL);
1760 }
1761
1762 // Add a enum values to a type dictionary.
AddEnumValues(PyTypeObject * type,const EnumDescriptor * enum_descriptor)1763 static bool AddEnumValues(PyTypeObject *type,
1764 const EnumDescriptor* enum_descriptor) {
1765 for (int i = 0; i < enum_descriptor->value_count(); ++i) {
1766 const EnumValueDescriptor* value = enum_descriptor->value(i);
1767 ScopedPyObjectPtr obj(PyInt_FromLong(value->number()));
1768 if (obj == NULL) {
1769 return false;
1770 }
1771 if (PyDict_SetItemString(type->tp_dict, value->name().c_str(), obj.get()) <
1772 0) {
1773 return false;
1774 }
1775 }
1776 return true;
1777 }
1778
AddIntConstant(PyTypeObject * type,const char * name,int value)1779 static bool AddIntConstant(PyTypeObject *type, const char* name, int value) {
1780 ScopedPyObjectPtr obj(PyInt_FromLong(value));
1781 if (PyDict_SetItemString(type->tp_dict, name, obj.get()) < 0) {
1782 return false;
1783 }
1784 return true;
1785 }
1786
1787
InitDescriptor()1788 bool InitDescriptor() {
1789 if (PyType_Ready(&PyMessageDescriptor_Type) < 0)
1790 return false;
1791
1792 if (PyType_Ready(&PyFieldDescriptor_Type) < 0)
1793 return false;
1794
1795 if (!AddEnumValues(&PyFieldDescriptor_Type,
1796 FieldDescriptorProto::Label_descriptor())) {
1797 return false;
1798 }
1799 if (!AddEnumValues(&PyFieldDescriptor_Type,
1800 FieldDescriptorProto::Type_descriptor())) {
1801 return false;
1802 }
1803 #define ADD_FIELDDESC_CONSTANT(NAME) AddIntConstant( \
1804 &PyFieldDescriptor_Type, #NAME, FieldDescriptor::NAME)
1805 if (!ADD_FIELDDESC_CONSTANT(CPPTYPE_INT32) ||
1806 !ADD_FIELDDESC_CONSTANT(CPPTYPE_INT64) ||
1807 !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT32) ||
1808 !ADD_FIELDDESC_CONSTANT(CPPTYPE_UINT64) ||
1809 !ADD_FIELDDESC_CONSTANT(CPPTYPE_DOUBLE) ||
1810 !ADD_FIELDDESC_CONSTANT(CPPTYPE_FLOAT) ||
1811 !ADD_FIELDDESC_CONSTANT(CPPTYPE_BOOL) ||
1812 !ADD_FIELDDESC_CONSTANT(CPPTYPE_ENUM) ||
1813 !ADD_FIELDDESC_CONSTANT(CPPTYPE_STRING) ||
1814 !ADD_FIELDDESC_CONSTANT(CPPTYPE_MESSAGE)) {
1815 return false;
1816 }
1817 #undef ADD_FIELDDESC_CONSTANT
1818
1819 if (PyType_Ready(&PyEnumDescriptor_Type) < 0)
1820 return false;
1821
1822 if (PyType_Ready(&PyEnumValueDescriptor_Type) < 0)
1823 return false;
1824
1825 if (PyType_Ready(&PyFileDescriptor_Type) < 0)
1826 return false;
1827
1828 if (PyType_Ready(&PyOneofDescriptor_Type) < 0)
1829 return false;
1830
1831 if (PyType_Ready(&PyServiceDescriptor_Type) < 0)
1832 return false;
1833
1834 if (PyType_Ready(&PyMethodDescriptor_Type) < 0)
1835 return false;
1836
1837 if (!InitDescriptorMappingTypes())
1838 return false;
1839
1840 return true;
1841 }
1842
1843 } // namespace python
1844 } // namespace protobuf
1845 } // namespace google
1846