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