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