1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 #include "python/descriptor.h"
9
10 #include "python/convert.h"
11 #include "python/descriptor_containers.h"
12 #include "python/descriptor_pool.h"
13 #include "python/message.h"
14 #include "python/protobuf.h"
15 #include "upb/base/upcast.h"
16 #include "upb/reflection/def.h"
17 #include "upb/util/def_to_proto.h"
18
19 // -----------------------------------------------------------------------------
20 // DescriptorBase
21 // -----------------------------------------------------------------------------
22
23 // This representation is used by all concrete descriptors.
24
25 typedef struct {
26 PyObject_HEAD;
27 PyObject* pool; // We own a ref.
28 const void* def; // Type depends on the class. Kept alive by "pool".
29 PyObject* options; // NULL if not present or not cached.
30 PyObject* features; // NULL if not present or not cached.
31 PyObject* message_meta; // We own a ref.
32 } PyUpb_DescriptorBase;
33
PyUpb_AnyDescriptor_GetPool(PyObject * desc)34 PyObject* PyUpb_AnyDescriptor_GetPool(PyObject* desc) {
35 PyUpb_DescriptorBase* base = (void*)desc;
36 return base->pool;
37 }
38
PyUpb_AnyDescriptor_GetDef(PyObject * desc)39 const void* PyUpb_AnyDescriptor_GetDef(PyObject* desc) {
40 PyUpb_DescriptorBase* base = (void*)desc;
41 return base->def;
42 }
43
PyUpb_DescriptorBase_DoCreate(PyUpb_DescriptorType type,const void * def,const upb_FileDef * file)44 static PyUpb_DescriptorBase* PyUpb_DescriptorBase_DoCreate(
45 PyUpb_DescriptorType type, const void* def, const upb_FileDef* file) {
46 PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
47 PyTypeObject* type_obj = state->descriptor_types[type];
48 assert(def);
49
50 PyUpb_DescriptorBase* base = (void*)PyType_GenericAlloc(type_obj, 0);
51 base->pool = PyUpb_DescriptorPool_Get(upb_FileDef_Pool(file));
52 base->def = def;
53 base->options = NULL;
54 base->features = NULL;
55 base->message_meta = NULL;
56
57 PyUpb_ObjCache_Add(def, &base->ob_base);
58 return base;
59 }
60
61 // Returns a Python object wrapping |def|, of descriptor type |type|. If a
62 // wrapper was previously created for this def, returns it, otherwise creates a
63 // new wrapper.
PyUpb_DescriptorBase_Get(PyUpb_DescriptorType type,const void * def,const upb_FileDef * file)64 static PyObject* PyUpb_DescriptorBase_Get(PyUpb_DescriptorType type,
65 const void* def,
66 const upb_FileDef* file) {
67 PyUpb_DescriptorBase* base = (PyUpb_DescriptorBase*)PyUpb_ObjCache_Get(def);
68
69 if (!base) {
70 base = PyUpb_DescriptorBase_DoCreate(type, def, file);
71 }
72
73 return &base->ob_base;
74 }
75
PyUpb_DescriptorBase_Check(PyObject * obj,PyUpb_DescriptorType type)76 static PyUpb_DescriptorBase* PyUpb_DescriptorBase_Check(
77 PyObject* obj, PyUpb_DescriptorType type) {
78 PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
79 PyTypeObject* type_obj = state->descriptor_types[type];
80 if (!PyObject_TypeCheck(obj, type_obj)) {
81 PyErr_Format(PyExc_TypeError, "Expected object of type %S, but got %R",
82 type_obj, obj);
83 return NULL;
84 }
85 return (PyUpb_DescriptorBase*)obj;
86 }
87
PyUpb_DescriptorBase_GetCached(PyObject ** cached,const upb_Message * opts,const upb_MiniTable * layout,const char * msg_name,const char * strip_field)88 static PyObject* PyUpb_DescriptorBase_GetCached(PyObject** cached,
89 const upb_Message* opts,
90 const upb_MiniTable* layout,
91 const char* msg_name,
92 const char* strip_field) {
93 if (!*cached) {
94 // Load descriptors protos if they are not loaded already. We have to do
95 // this lazily, otherwise, it would lead to circular imports.
96 PyObject* mod = PyImport_ImportModuleLevel(PYUPB_DESCRIPTOR_MODULE, NULL,
97 NULL, NULL, 0);
98 if (mod == NULL) return NULL;
99 Py_DECREF(mod);
100
101 // Find the correct options message.
102 PyObject* default_pool = PyUpb_DescriptorPool_GetDefaultPool();
103 const upb_DefPool* symtab = PyUpb_DescriptorPool_GetSymtab(default_pool);
104 const upb_MessageDef* m = upb_DefPool_FindMessageByName(symtab, msg_name);
105 assert(m);
106
107 // Copy the options message from C to Python using serialize+parse.
108 // We don't wrap the C object directly because there is no guarantee that
109 // the descriptor_pb2 that was loaded at runtime has the same members or
110 // layout as the C types that were compiled in.
111 size_t size;
112 PyObject* py_arena = PyUpb_Arena_New();
113 upb_Arena* arena = PyUpb_Arena_Get(py_arena);
114 char* pb;
115 // TODO: Need to correctly handle failed return codes.
116 (void)upb_Encode(opts, layout, 0, arena, &pb, &size);
117 const upb_MiniTable* opts2_layout = upb_MessageDef_MiniTable(m);
118 upb_Message* opts2 = upb_Message_New(opts2_layout, arena);
119 assert(opts2);
120 upb_DecodeStatus ds =
121 upb_Decode(pb, size, opts2, opts2_layout,
122 upb_DefPool_ExtensionRegistry(symtab), 0, arena);
123 (void)ds;
124 assert(ds == kUpb_DecodeStatus_Ok);
125
126 if (strip_field) {
127 const upb_FieldDef* field =
128 upb_MessageDef_FindFieldByName(m, strip_field);
129 assert(field);
130 upb_Message_ClearFieldByDef(opts2, field);
131 }
132
133 *cached = PyUpb_Message_Get(opts2, m, py_arena);
134 Py_DECREF(py_arena);
135 }
136
137 Py_INCREF(*cached);
138 return *cached;
139 }
140
PyUpb_DescriptorBase_GetOptions(PyObject ** cached,const upb_Message * opts,const upb_MiniTable * layout,const char * msg_name)141 static PyObject* PyUpb_DescriptorBase_GetOptions(PyObject** cached,
142 const upb_Message* opts,
143 const upb_MiniTable* layout,
144 const char* msg_name) {
145 return PyUpb_DescriptorBase_GetCached(cached, opts, layout, msg_name,
146 "features");
147 }
148
PyUpb_DescriptorBase_GetFeatures(PyObject ** cached,const upb_Message * opts)149 static PyObject* PyUpb_DescriptorBase_GetFeatures(PyObject** cached,
150 const upb_Message* opts) {
151 return PyUpb_DescriptorBase_GetCached(
152 cached, opts, &google__protobuf__FeatureSet_msg_init,
153 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".FeatureSet", NULL);
154 }
155
156 typedef void* PyUpb_ToProto_Func(const void* def, upb_Arena* arena);
157
PyUpb_DescriptorBase_GetSerializedProto(PyObject * _self,PyUpb_ToProto_Func * func,const upb_MiniTable * layout)158 static PyObject* PyUpb_DescriptorBase_GetSerializedProto(
159 PyObject* _self, PyUpb_ToProto_Func* func, const upb_MiniTable* layout) {
160 PyUpb_DescriptorBase* self = (void*)_self;
161 upb_Arena* arena = upb_Arena_New();
162 if (!arena) PYUPB_RETURN_OOM;
163 upb_Message* proto = func(self->def, arena);
164 if (!proto) goto oom;
165 size_t size;
166 char* pb;
167 upb_EncodeStatus status = upb_Encode(proto, layout, 0, arena, &pb, &size);
168 if (status) goto oom; // TODO non-oom errors are possible here
169 PyObject* str = PyBytes_FromStringAndSize(pb, size);
170 upb_Arena_Free(arena);
171 return str;
172
173 oom:
174 upb_Arena_Free(arena);
175 PyErr_SetNone(PyExc_MemoryError);
176 return NULL;
177 }
178
PyUpb_DescriptorBase_CopyToProto(PyObject * _self,PyUpb_ToProto_Func * func,const upb_MiniTable * layout,const char * expected_type,PyObject * py_proto)179 static PyObject* PyUpb_DescriptorBase_CopyToProto(PyObject* _self,
180 PyUpb_ToProto_Func* func,
181 const upb_MiniTable* layout,
182 const char* expected_type,
183 PyObject* py_proto) {
184 if (!PyUpb_Message_Verify(py_proto)) return NULL;
185 const upb_MessageDef* m = PyUpb_Message_GetMsgdef(py_proto);
186 const char* type = upb_MessageDef_FullName(m);
187 if (strcmp(type, expected_type) != 0) {
188 PyErr_Format(
189 PyExc_TypeError,
190 "CopyToProto: message is of incorrect type '%s' (expected '%s'", type,
191 expected_type);
192 return NULL;
193 }
194 PyObject* serialized =
195 PyUpb_DescriptorBase_GetSerializedProto(_self, func, layout);
196 if (!serialized) return NULL;
197 PyObject* ret = PyUpb_Message_MergeFromString(py_proto, serialized);
198 Py_DECREF(serialized);
199 return ret;
200 }
201
PyUpb_DescriptorBase_Dealloc(PyUpb_DescriptorBase * base)202 static void PyUpb_DescriptorBase_Dealloc(PyUpb_DescriptorBase* base) {
203 // This deallocator can be called on different types (which, despite
204 // 'Base' in the name of one of them, do not inherit from each other).
205 // Some of these types are GC types (they have Py_TPFLAGS_HAVE_GC set),
206 // which means Python's GC can visit them (via tp_visit and/or tp_clear
207 // methods) at any time. This also means we *must* stop GC from tracking
208 // instances of them before we start destructing the object. In Python
209 // 3.11, failing to do so would raise a runtime warning.
210 if (PyType_HasFeature(Py_TYPE(base), Py_TPFLAGS_HAVE_GC)) {
211 PyObject_GC_UnTrack(base);
212 }
213 PyUpb_ObjCache_Delete(base->def);
214 // In addition to being visited by GC, instances can also (potentially) be
215 // accessed whenever arbitrary code is executed. Destructors can execute
216 // arbitrary code, so any struct members we DECREF should be set to NULL
217 // or a new value *before* calling Py_DECREF on them. The Py_CLEAR macro
218 // (and Py_SETREF in Python 3.8+) takes care to do this safely.
219 Py_CLEAR(base->message_meta);
220 Py_CLEAR(base->pool);
221 Py_CLEAR(base->options);
222 Py_CLEAR(base->features);
223 PyUpb_Dealloc(base);
224 }
225
PyUpb_Descriptor_Traverse(PyUpb_DescriptorBase * base,visitproc visit,void * arg)226 static int PyUpb_Descriptor_Traverse(PyUpb_DescriptorBase* base,
227 visitproc visit, void* arg) {
228 Py_VISIT(base->message_meta);
229 return 0;
230 }
231
PyUpb_Descriptor_Clear(PyUpb_DescriptorBase * base)232 static int PyUpb_Descriptor_Clear(PyUpb_DescriptorBase* base) {
233 Py_CLEAR(base->message_meta);
234 return 0;
235 }
236
237 #define DESCRIPTOR_BASE_SLOTS \
238 {Py_tp_new, (void*)&PyUpb_Forbidden_New}, { \
239 Py_tp_dealloc, (void*)&PyUpb_DescriptorBase_Dealloc \
240 }
241
242 // -----------------------------------------------------------------------------
243 // Descriptor
244 // -----------------------------------------------------------------------------
245
PyUpb_Descriptor_Get(const upb_MessageDef * m)246 PyObject* PyUpb_Descriptor_Get(const upb_MessageDef* m) {
247 assert(m);
248 const upb_FileDef* file = upb_MessageDef_File(m);
249 return PyUpb_DescriptorBase_Get(kPyUpb_Descriptor, m, file);
250 }
251
PyUpb_Descriptor_GetClass(const upb_MessageDef * m)252 PyObject* PyUpb_Descriptor_GetClass(const upb_MessageDef* m) {
253 PyObject* ret = PyUpb_ObjCache_Get(upb_MessageDef_MiniTable(m));
254 if (ret) return ret;
255
256 // On demand create the clss if not exist. However, if users repeatedly
257 // create and destroy a class, it could trigger a loop. This is not an
258 // issue now, but if we see CPU waste for repeatedly create and destroy
259 // in the future, we could make PyUpb_Descriptor_Get() append the descriptor
260 // to an internal list in DescriptorPool, let the pool keep descriptors alive.
261 PyObject* py_descriptor = PyUpb_Descriptor_Get(m);
262 if (py_descriptor == NULL) return NULL;
263 const char* name = upb_MessageDef_Name(m);
264 PyObject* dict = PyDict_New();
265 if (dict == NULL) goto err;
266 int status = PyDict_SetItemString(dict, "DESCRIPTOR", py_descriptor);
267 if (status < 0) goto err;
268 ret = PyUpb_MessageMeta_DoCreateClass(py_descriptor, name, dict);
269
270 err:
271 Py_XDECREF(py_descriptor);
272 Py_XDECREF(dict);
273 return ret;
274 }
275
PyUpb_Descriptor_SetClass(PyObject * py_descriptor,PyObject * meta)276 void PyUpb_Descriptor_SetClass(PyObject* py_descriptor, PyObject* meta) {
277 PyUpb_DescriptorBase* base = (PyUpb_DescriptorBase*)py_descriptor;
278 Py_INCREF(meta);
279 // Py_SETREF replaces strong references without an intermediate invalid
280 // object state, which code executed by base->message_meta's destructor
281 // might see, but it's Python 3.8+.
282 PyObject* tmp = base->message_meta;
283 base->message_meta = meta;
284 Py_XDECREF(tmp);
285 }
286
287 // The LookupNested*() functions provide name lookup for entities nested inside
288 // a message. This uses the symtab's table, which requires that the symtab is
289 // not being mutated concurrently. We can guarantee this for Python-owned
290 // symtabs, but upb cannot guarantee it in general for an arbitrary
291 // `const upb_MessageDef*`.
292
PyUpb_Descriptor_LookupNestedMessage(const upb_MessageDef * m,const char * name)293 static const void* PyUpb_Descriptor_LookupNestedMessage(const upb_MessageDef* m,
294 const char* name) {
295 const upb_FileDef* filedef = upb_MessageDef_File(m);
296 const upb_DefPool* symtab = upb_FileDef_Pool(filedef);
297 PyObject* qname =
298 PyUnicode_FromFormat("%s.%s", upb_MessageDef_FullName(m), name);
299 const upb_MessageDef* ret = upb_DefPool_FindMessageByName(
300 symtab, PyUnicode_AsUTF8AndSize(qname, NULL));
301 Py_DECREF(qname);
302 return ret;
303 }
304
PyUpb_Descriptor_LookupNestedEnum(const upb_MessageDef * m,const char * name)305 static const void* PyUpb_Descriptor_LookupNestedEnum(const upb_MessageDef* m,
306 const char* name) {
307 const upb_FileDef* filedef = upb_MessageDef_File(m);
308 const upb_DefPool* symtab = upb_FileDef_Pool(filedef);
309 PyObject* qname =
310 PyUnicode_FromFormat("%s.%s", upb_MessageDef_FullName(m), name);
311 const upb_EnumDef* ret =
312 upb_DefPool_FindEnumByName(symtab, PyUnicode_AsUTF8AndSize(qname, NULL));
313 Py_DECREF(qname);
314 return ret;
315 }
316
PyUpb_Descriptor_LookupNestedExtension(const upb_MessageDef * m,const char * name)317 static const void* PyUpb_Descriptor_LookupNestedExtension(
318 const upb_MessageDef* m, const char* name) {
319 const upb_FileDef* filedef = upb_MessageDef_File(m);
320 const upb_DefPool* symtab = upb_FileDef_Pool(filedef);
321 PyObject* qname =
322 PyUnicode_FromFormat("%s.%s", upb_MessageDef_FullName(m), name);
323 const upb_FieldDef* ret = upb_DefPool_FindExtensionByName(
324 symtab, PyUnicode_AsUTF8AndSize(qname, NULL));
325 Py_DECREF(qname);
326 return ret;
327 }
328
PyUpb_Descriptor_GetExtensionRanges(PyObject * _self,void * closure)329 static PyObject* PyUpb_Descriptor_GetExtensionRanges(PyObject* _self,
330 void* closure) {
331 PyUpb_DescriptorBase* self = (PyUpb_DescriptorBase*)_self;
332 int n = upb_MessageDef_ExtensionRangeCount(self->def);
333 PyObject* range_list = PyList_New(n);
334
335 for (int i = 0; i < n; i++) {
336 const upb_ExtensionRange* range =
337 upb_MessageDef_ExtensionRange(self->def, i);
338 PyObject* start = PyLong_FromLong(upb_ExtensionRange_Start(range));
339 PyObject* end = PyLong_FromLong(upb_ExtensionRange_End(range));
340 PyList_SetItem(range_list, i, PyTuple_Pack(2, start, end));
341 }
342
343 return range_list;
344 }
345
PyUpb_Descriptor_GetExtensions(PyObject * _self,void * closure)346 static PyObject* PyUpb_Descriptor_GetExtensions(PyObject* _self,
347 void* closure) {
348 PyUpb_DescriptorBase* self = (void*)_self;
349 static PyUpb_GenericSequence_Funcs funcs = {
350 (void*)&upb_MessageDef_NestedExtensionCount,
351 (void*)&upb_MessageDef_NestedExtension,
352 (void*)&PyUpb_FieldDescriptor_Get,
353 };
354 return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
355 }
356
PyUpb_Descriptor_GetExtensionsByName(PyObject * _self,void * closure)357 static PyObject* PyUpb_Descriptor_GetExtensionsByName(PyObject* _self,
358 void* closure) {
359 PyUpb_DescriptorBase* self = (void*)_self;
360 static PyUpb_ByNameMap_Funcs funcs = {
361 {
362 (void*)&upb_MessageDef_NestedExtensionCount,
363 (void*)&upb_MessageDef_NestedExtension,
364 (void*)&PyUpb_FieldDescriptor_Get,
365 },
366 (void*)&PyUpb_Descriptor_LookupNestedExtension,
367 (void*)&upb_FieldDef_Name,
368 };
369 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
370 }
371
PyUpb_Descriptor_GetEnumTypes(PyObject * _self,void * closure)372 static PyObject* PyUpb_Descriptor_GetEnumTypes(PyObject* _self, void* closure) {
373 PyUpb_DescriptorBase* self = (void*)_self;
374 static PyUpb_GenericSequence_Funcs funcs = {
375 (void*)&upb_MessageDef_NestedEnumCount,
376 (void*)&upb_MessageDef_NestedEnum,
377 (void*)&PyUpb_EnumDescriptor_Get,
378 };
379 return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
380 }
381
PyUpb_Descriptor_GetOneofs(PyObject * _self,void * closure)382 static PyObject* PyUpb_Descriptor_GetOneofs(PyObject* _self, void* closure) {
383 PyUpb_DescriptorBase* self = (void*)_self;
384 static PyUpb_GenericSequence_Funcs funcs = {
385 (void*)&upb_MessageDef_OneofCount,
386 (void*)&upb_MessageDef_Oneof,
387 (void*)&PyUpb_OneofDescriptor_Get,
388 };
389 return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
390 }
391
PyUpb_Descriptor_GetOptions(PyObject * _self,PyObject * args)392 static PyObject* PyUpb_Descriptor_GetOptions(PyObject* _self, PyObject* args) {
393 PyUpb_DescriptorBase* self = (void*)_self;
394 return PyUpb_DescriptorBase_GetOptions(
395 &self->options, UPB_UPCAST(upb_MessageDef_Options(self->def)),
396 &google__protobuf__MessageOptions_msg_init,
397 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".MessageOptions");
398 }
399
PyUpb_Descriptor_GetFeatures(PyObject * _self,PyObject * args)400 static PyObject* PyUpb_Descriptor_GetFeatures(PyObject* _self, PyObject* args) {
401 PyUpb_DescriptorBase* self = (void*)_self;
402 return PyUpb_DescriptorBase_GetFeatures(
403 &self->features, UPB_UPCAST(upb_MessageDef_ResolvedFeatures(self->def)));
404 }
405
PyUpb_Descriptor_CopyToProto(PyObject * _self,PyObject * py_proto)406 static PyObject* PyUpb_Descriptor_CopyToProto(PyObject* _self,
407 PyObject* py_proto) {
408 return PyUpb_DescriptorBase_CopyToProto(
409 _self, (PyUpb_ToProto_Func*)&upb_MessageDef_ToProto,
410 &google__protobuf__DescriptorProto_msg_init,
411 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".DescriptorProto", py_proto);
412 }
413
PyUpb_Descriptor_EnumValueName(PyObject * _self,PyObject * args)414 static PyObject* PyUpb_Descriptor_EnumValueName(PyObject* _self,
415 PyObject* args) {
416 PyUpb_DescriptorBase* self = (void*)_self;
417 const char* enum_name;
418 int number;
419 if (!PyArg_ParseTuple(args, "si", &enum_name, &number)) return NULL;
420 const upb_EnumDef* e =
421 PyUpb_Descriptor_LookupNestedEnum(self->def, enum_name);
422 if (!e) {
423 PyErr_SetString(PyExc_KeyError, enum_name);
424 return NULL;
425 }
426 const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(e, number);
427 if (!ev) {
428 PyErr_Format(PyExc_KeyError, "%d", number);
429 return NULL;
430 }
431 return PyUnicode_FromString(upb_EnumValueDef_Name(ev));
432 }
433
PyUpb_Descriptor_GetFieldsByName(PyObject * _self,void * closure)434 static PyObject* PyUpb_Descriptor_GetFieldsByName(PyObject* _self,
435 void* closure) {
436 PyUpb_DescriptorBase* self = (void*)_self;
437 static PyUpb_ByNameMap_Funcs funcs = {
438 {
439 (void*)&upb_MessageDef_FieldCount,
440 (void*)&upb_MessageDef_Field,
441 (void*)&PyUpb_FieldDescriptor_Get,
442 },
443 (void*)&upb_MessageDef_FindFieldByName,
444 (void*)&upb_FieldDef_Name,
445 };
446 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
447 }
448
PyUpb_Descriptor_GetFieldsByCamelCaseName(PyObject * _self,void * closure)449 static PyObject* PyUpb_Descriptor_GetFieldsByCamelCaseName(PyObject* _self,
450 void* closure) {
451 PyUpb_DescriptorBase* self = (void*)_self;
452 static PyUpb_ByNameMap_Funcs funcs = {
453 {
454 (void*)&upb_MessageDef_FieldCount,
455 (void*)&upb_MessageDef_Field,
456 (void*)&PyUpb_FieldDescriptor_Get,
457 },
458 (void*)&upb_MessageDef_FindByJsonName,
459 (void*)&upb_FieldDef_JsonName,
460 };
461 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
462 }
463
PyUpb_Descriptor_GetFieldsByNumber(PyObject * _self,void * closure)464 static PyObject* PyUpb_Descriptor_GetFieldsByNumber(PyObject* _self,
465 void* closure) {
466 static PyUpb_ByNumberMap_Funcs funcs = {
467 {
468 (void*)&upb_MessageDef_FieldCount,
469 (void*)&upb_MessageDef_Field,
470 (void*)&PyUpb_FieldDescriptor_Get,
471 },
472 (void*)&upb_MessageDef_FindFieldByNumber,
473 (void*)&upb_FieldDef_Number,
474 };
475 PyUpb_DescriptorBase* self = (void*)_self;
476 return PyUpb_ByNumberMap_New(&funcs, self->def, self->pool);
477 }
478
PyUpb_Descriptor_GetNestedTypes(PyObject * _self,void * closure)479 static PyObject* PyUpb_Descriptor_GetNestedTypes(PyObject* _self,
480 void* closure) {
481 PyUpb_DescriptorBase* self = (void*)_self;
482 static PyUpb_GenericSequence_Funcs funcs = {
483 (void*)&upb_MessageDef_NestedMessageCount,
484 (void*)&upb_MessageDef_NestedMessage,
485 (void*)&PyUpb_Descriptor_Get,
486 };
487 return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
488 }
489
PyUpb_Descriptor_GetNestedTypesByName(PyObject * _self,void * closure)490 static PyObject* PyUpb_Descriptor_GetNestedTypesByName(PyObject* _self,
491 void* closure) {
492 PyUpb_DescriptorBase* self = (void*)_self;
493 static PyUpb_ByNameMap_Funcs funcs = {
494 {
495 (void*)&upb_MessageDef_NestedMessageCount,
496 (void*)&upb_MessageDef_NestedMessage,
497 (void*)&PyUpb_Descriptor_Get,
498 },
499 (void*)&PyUpb_Descriptor_LookupNestedMessage,
500 (void*)&upb_MessageDef_Name,
501 };
502 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
503 }
504
PyUpb_Descriptor_GetContainingType(PyObject * _self,void * closure)505 static PyObject* PyUpb_Descriptor_GetContainingType(PyObject* _self,
506 void* closure) {
507 // upb does not natively store the lexical parent of a message type, but we
508 // can derive it with some string manipulation and a lookup.
509 PyUpb_DescriptorBase* self = (void*)_self;
510 const upb_MessageDef* m = self->def;
511 const upb_FileDef* file = upb_MessageDef_File(m);
512 const upb_DefPool* symtab = upb_FileDef_Pool(file);
513 const char* full_name = upb_MessageDef_FullName(m);
514 const char* last_dot = strrchr(full_name, '.');
515 if (!last_dot) Py_RETURN_NONE;
516 const upb_MessageDef* parent = upb_DefPool_FindMessageByNameWithSize(
517 symtab, full_name, last_dot - full_name);
518 if (!parent) Py_RETURN_NONE;
519 return PyUpb_Descriptor_Get(parent);
520 }
521
PyUpb_Descriptor_GetEnumTypesByName(PyObject * _self,void * closure)522 static PyObject* PyUpb_Descriptor_GetEnumTypesByName(PyObject* _self,
523 void* closure) {
524 PyUpb_DescriptorBase* self = (void*)_self;
525 static PyUpb_ByNameMap_Funcs funcs = {
526 {
527 (void*)&upb_MessageDef_NestedEnumCount,
528 (void*)&upb_MessageDef_NestedEnum,
529 (void*)&PyUpb_EnumDescriptor_Get,
530 },
531 (void*)&PyUpb_Descriptor_LookupNestedEnum,
532 (void*)&upb_EnumDef_Name,
533 };
534 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
535 }
536
PyUpb_Descriptor_GetIsExtendable(PyObject * _self,void * closure)537 static PyObject* PyUpb_Descriptor_GetIsExtendable(PyObject* _self,
538 void* closure) {
539 PyUpb_DescriptorBase* self = (void*)_self;
540 if (upb_MessageDef_ExtensionRangeCount(self->def) > 0) {
541 Py_RETURN_TRUE;
542 } else {
543 Py_RETURN_FALSE;
544 }
545 }
546
PyUpb_Descriptor_GetFullName(PyObject * self,void * closure)547 static PyObject* PyUpb_Descriptor_GetFullName(PyObject* self, void* closure) {
548 const upb_MessageDef* msgdef = PyUpb_Descriptor_GetDef(self);
549 return PyUnicode_FromString(upb_MessageDef_FullName(msgdef));
550 }
551
PyUpb_Descriptor_GetConcreteClass(PyObject * self,void * closure)552 static PyObject* PyUpb_Descriptor_GetConcreteClass(PyObject* self,
553 void* closure) {
554 const upb_MessageDef* msgdef = PyUpb_Descriptor_GetDef(self);
555 return PyUpb_ObjCache_Get(upb_MessageDef_MiniTable(msgdef));
556 }
557
PyUpb_Descriptor_GetFile(PyObject * self,void * closure)558 static PyObject* PyUpb_Descriptor_GetFile(PyObject* self, void* closure) {
559 const upb_MessageDef* msgdef = PyUpb_Descriptor_GetDef(self);
560 return PyUpb_FileDescriptor_Get(upb_MessageDef_File(msgdef));
561 }
562
PyUpb_Descriptor_GetFields(PyObject * _self,void * closure)563 static PyObject* PyUpb_Descriptor_GetFields(PyObject* _self, void* closure) {
564 PyUpb_DescriptorBase* self = (void*)_self;
565 static PyUpb_GenericSequence_Funcs funcs = {
566 (void*)&upb_MessageDef_FieldCount,
567 (void*)&upb_MessageDef_Field,
568 (void*)&PyUpb_FieldDescriptor_Get,
569 };
570 return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
571 }
572
PyUpb_Descriptor_GetHasOptions(PyObject * _self,void * closure)573 static PyObject* PyUpb_Descriptor_GetHasOptions(PyObject* _self,
574 void* closure) {
575 PyUpb_DescriptorBase* self = (void*)_self;
576 return PyBool_FromLong(upb_MessageDef_HasOptions(self->def));
577 }
578
PyUpb_Descriptor_GetName(PyObject * self,void * closure)579 static PyObject* PyUpb_Descriptor_GetName(PyObject* self, void* closure) {
580 const upb_MessageDef* msgdef = PyUpb_Descriptor_GetDef(self);
581 return PyUnicode_FromString(upb_MessageDef_Name(msgdef));
582 }
583
PyUpb_Descriptor_GetEnumValuesByName(PyObject * _self,void * closure)584 static PyObject* PyUpb_Descriptor_GetEnumValuesByName(PyObject* _self,
585 void* closure) {
586 // upb does not natively store any table containing all nested values.
587 // Consider:
588 // message M {
589 // enum E1 {
590 // A = 0;
591 // B = 1;
592 // }
593 // enum E2 {
594 // C = 0;
595 // D = 1;
596 // }
597 // }
598 //
599 // In this case, upb stores tables for E1 and E2, but it does not store a
600 // table for M that combines them (it is rarely needed and costs precious
601 // space and time to build).
602 //
603 // To work around this, we build an actual Python dict whenever a user
604 // actually asks for this.
605 PyUpb_DescriptorBase* self = (void*)_self;
606 PyObject* ret = PyDict_New();
607 if (!ret) return NULL;
608 int enum_count = upb_MessageDef_NestedEnumCount(self->def);
609 for (int i = 0; i < enum_count; i++) {
610 const upb_EnumDef* e = upb_MessageDef_NestedEnum(self->def, i);
611 int value_count = upb_EnumDef_ValueCount(e);
612 for (int j = 0; j < value_count; j++) {
613 // Collisions should be impossible here, as uniqueness is checked by
614 // protoc (this is an invariant of the protobuf language). However this
615 // uniqueness constraint is not currently checked by upb/def.c at load
616 // time, so if the user supplies a manually-constructed descriptor that
617 // does not respect this constraint, a collision could be possible and the
618 // last-defined enumerator would win. This could be seen as an argument
619 // for having upb actually build the table at load time, thus checking the
620 // constraint proactively, but upb is always checking a subset of the full
621 // validation performed by C++, and we have to pick and choose the biggest
622 // bang for the buck.
623 const upb_EnumValueDef* ev = upb_EnumDef_Value(e, j);
624 const char* name = upb_EnumValueDef_Name(ev);
625 PyObject* val = PyUpb_EnumValueDescriptor_Get(ev);
626 if (!val || PyDict_SetItemString(ret, name, val) < 0) {
627 Py_XDECREF(val);
628 Py_DECREF(ret);
629 return NULL;
630 }
631 Py_DECREF(val);
632 }
633 }
634 return ret;
635 }
636
PyUpb_Descriptor_GetOneofsByName(PyObject * _self,void * closure)637 static PyObject* PyUpb_Descriptor_GetOneofsByName(PyObject* _self,
638 void* closure) {
639 PyUpb_DescriptorBase* self = (void*)_self;
640 static PyUpb_ByNameMap_Funcs funcs = {
641 {
642 (void*)&upb_MessageDef_OneofCount,
643 (void*)&upb_MessageDef_Oneof,
644 (void*)&PyUpb_OneofDescriptor_Get,
645 },
646 (void*)&upb_MessageDef_FindOneofByName,
647 (void*)&upb_OneofDef_Name,
648 };
649 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
650 }
651
652 static PyGetSetDef PyUpb_Descriptor_Getters[] = {
653 {"name", PyUpb_Descriptor_GetName, NULL, "Last name"},
654 {"full_name", PyUpb_Descriptor_GetFullName, NULL, "Full name"},
655 {"_concrete_class", PyUpb_Descriptor_GetConcreteClass, NULL,
656 "concrete class"},
657 {"file", PyUpb_Descriptor_GetFile, NULL, "File descriptor"},
658 {"fields", PyUpb_Descriptor_GetFields, NULL, "Fields sequence"},
659 {"fields_by_name", PyUpb_Descriptor_GetFieldsByName, NULL,
660 "Fields by name"},
661 {"fields_by_camelcase_name", PyUpb_Descriptor_GetFieldsByCamelCaseName,
662 NULL, "Fields by camelCase name"},
663 {"fields_by_number", PyUpb_Descriptor_GetFieldsByNumber, NULL,
664 "Fields by number"},
665 {"nested_types", PyUpb_Descriptor_GetNestedTypes, NULL,
666 "Nested types sequence"},
667 {"nested_types_by_name", PyUpb_Descriptor_GetNestedTypesByName, NULL,
668 "Nested types by name"},
669 {"extensions", PyUpb_Descriptor_GetExtensions, NULL, "Extensions Sequence"},
670 {"extensions_by_name", PyUpb_Descriptor_GetExtensionsByName, NULL,
671 "Extensions by name"},
672 {"extension_ranges", PyUpb_Descriptor_GetExtensionRanges, NULL,
673 "Extension ranges"},
674 {"enum_types", PyUpb_Descriptor_GetEnumTypes, NULL, "Enum sequence"},
675 {"enum_types_by_name", PyUpb_Descriptor_GetEnumTypesByName, NULL,
676 "Enum types by name"},
677 {"enum_values_by_name", PyUpb_Descriptor_GetEnumValuesByName, NULL,
678 "Enum values by name"},
679 {"oneofs_by_name", PyUpb_Descriptor_GetOneofsByName, NULL,
680 "Oneofs by name"},
681 {"oneofs", PyUpb_Descriptor_GetOneofs, NULL, "Oneofs Sequence"},
682 {"containing_type", PyUpb_Descriptor_GetContainingType, NULL,
683 "Containing type"},
684 {"is_extendable", PyUpb_Descriptor_GetIsExtendable, NULL},
685 {"has_options", PyUpb_Descriptor_GetHasOptions, NULL, "Has Options"},
686 {NULL}};
687
688 static PyMethodDef PyUpb_Descriptor_Methods[] = {
689 {"GetOptions", PyUpb_Descriptor_GetOptions, METH_NOARGS},
690 {"_GetFeatures", PyUpb_Descriptor_GetFeatures, METH_NOARGS},
691 {"CopyToProto", PyUpb_Descriptor_CopyToProto, METH_O},
692 {"EnumValueName", PyUpb_Descriptor_EnumValueName, METH_VARARGS},
693 {NULL}};
694
695 static PyType_Slot PyUpb_Descriptor_Slots[] = {
696 DESCRIPTOR_BASE_SLOTS,
697 {Py_tp_methods, PyUpb_Descriptor_Methods},
698 {Py_tp_getset, PyUpb_Descriptor_Getters},
699 {Py_tp_traverse, PyUpb_Descriptor_Traverse},
700 {Py_tp_clear, PyUpb_Descriptor_Clear},
701 {0, NULL}};
702
703 static PyType_Spec PyUpb_Descriptor_Spec = {
704 PYUPB_MODULE_NAME ".Descriptor", // tp_name
705 sizeof(PyUpb_DescriptorBase), // tp_basicsize
706 0, // tp_itemsize
707 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
708 PyUpb_Descriptor_Slots,
709 };
710
PyUpb_Descriptor_GetDef(PyObject * _self)711 const upb_MessageDef* PyUpb_Descriptor_GetDef(PyObject* _self) {
712 PyUpb_DescriptorBase* self =
713 PyUpb_DescriptorBase_Check(_self, kPyUpb_Descriptor);
714 return self ? self->def : NULL;
715 }
716
717 // -----------------------------------------------------------------------------
718 // EnumDescriptor
719 // -----------------------------------------------------------------------------
720
PyUpb_EnumDescriptor_Get(const upb_EnumDef * enumdef)721 PyObject* PyUpb_EnumDescriptor_Get(const upb_EnumDef* enumdef) {
722 const upb_FileDef* file = upb_EnumDef_File(enumdef);
723 return PyUpb_DescriptorBase_Get(kPyUpb_EnumDescriptor, enumdef, file);
724 }
725
PyUpb_EnumDescriptor_GetDef(PyObject * _self)726 const upb_EnumDef* PyUpb_EnumDescriptor_GetDef(PyObject* _self) {
727 PyUpb_DescriptorBase* self =
728 PyUpb_DescriptorBase_Check(_self, kPyUpb_EnumDescriptor);
729 return self ? self->def : NULL;
730 }
731
PyUpb_EnumDescriptor_GetFullName(PyObject * self,void * closure)732 static PyObject* PyUpb_EnumDescriptor_GetFullName(PyObject* self,
733 void* closure) {
734 const upb_EnumDef* enumdef = PyUpb_EnumDescriptor_GetDef(self);
735 return PyUnicode_FromString(upb_EnumDef_FullName(enumdef));
736 }
737
PyUpb_EnumDescriptor_GetName(PyObject * self,void * closure)738 static PyObject* PyUpb_EnumDescriptor_GetName(PyObject* self, void* closure) {
739 const upb_EnumDef* enumdef = PyUpb_EnumDescriptor_GetDef(self);
740 return PyUnicode_FromString(upb_EnumDef_Name(enumdef));
741 }
742
PyUpb_EnumDescriptor_GetFile(PyObject * self,void * closure)743 static PyObject* PyUpb_EnumDescriptor_GetFile(PyObject* self, void* closure) {
744 const upb_EnumDef* enumdef = PyUpb_EnumDescriptor_GetDef(self);
745 return PyUpb_FileDescriptor_Get(upb_EnumDef_File(enumdef));
746 }
747
PyUpb_EnumDescriptor_GetValues(PyObject * _self,void * closure)748 static PyObject* PyUpb_EnumDescriptor_GetValues(PyObject* _self,
749 void* closure) {
750 PyUpb_DescriptorBase* self = (void*)_self;
751 static PyUpb_GenericSequence_Funcs funcs = {
752 (void*)&upb_EnumDef_ValueCount,
753 (void*)&upb_EnumDef_Value,
754 (void*)&PyUpb_EnumValueDescriptor_Get,
755 };
756 return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
757 }
758
PyUpb_EnumDescriptor_GetValuesByName(PyObject * _self,void * closure)759 static PyObject* PyUpb_EnumDescriptor_GetValuesByName(PyObject* _self,
760 void* closure) {
761 static PyUpb_ByNameMap_Funcs funcs = {
762 {
763 (void*)&upb_EnumDef_ValueCount,
764 (void*)&upb_EnumDef_Value,
765 (void*)&PyUpb_EnumValueDescriptor_Get,
766 },
767 (void*)&upb_EnumDef_FindValueByName,
768 (void*)&upb_EnumValueDef_Name,
769 };
770 PyUpb_DescriptorBase* self = (void*)_self;
771 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
772 }
773
PyUpb_EnumDescriptor_GetValuesByNumber(PyObject * _self,void * closure)774 static PyObject* PyUpb_EnumDescriptor_GetValuesByNumber(PyObject* _self,
775 void* closure) {
776 static PyUpb_ByNumberMap_Funcs funcs = {
777 {
778 (void*)&upb_EnumDef_ValueCount,
779 (void*)&upb_EnumDef_Value,
780 (void*)&PyUpb_EnumValueDescriptor_Get,
781 },
782 (void*)&upb_EnumDef_FindValueByNumber,
783 (void*)&upb_EnumValueDef_Number,
784 };
785 PyUpb_DescriptorBase* self = (void*)_self;
786 return PyUpb_ByNumberMap_New(&funcs, self->def, self->pool);
787 }
788
PyUpb_EnumDescriptor_GetContainingType(PyObject * _self,void * closure)789 static PyObject* PyUpb_EnumDescriptor_GetContainingType(PyObject* _self,
790 void* closure) {
791 PyUpb_DescriptorBase* self = (void*)_self;
792 const upb_MessageDef* m = upb_EnumDef_ContainingType(self->def);
793 if (!m) Py_RETURN_NONE;
794 return PyUpb_Descriptor_Get(m);
795 }
796
PyUpb_EnumDescriptor_GetHasOptions(PyObject * _self,void * closure)797 static PyObject* PyUpb_EnumDescriptor_GetHasOptions(PyObject* _self,
798 void* closure) {
799 PyUpb_DescriptorBase* self = (void*)_self;
800 return PyBool_FromLong(upb_EnumDef_HasOptions(self->def));
801 }
802
PyUpb_EnumDescriptor_GetIsClosed(PyObject * _self,void * closure)803 static PyObject* PyUpb_EnumDescriptor_GetIsClosed(PyObject* _self,
804 void* closure) {
805 const upb_EnumDef* enumdef = PyUpb_EnumDescriptor_GetDef(_self);
806 return PyBool_FromLong(upb_EnumDef_IsClosed(enumdef));
807 }
808
PyUpb_EnumDescriptor_GetOptions(PyObject * _self,PyObject * args)809 static PyObject* PyUpb_EnumDescriptor_GetOptions(PyObject* _self,
810 PyObject* args) {
811 PyUpb_DescriptorBase* self = (void*)_self;
812 return PyUpb_DescriptorBase_GetOptions(
813 &self->options, UPB_UPCAST(upb_EnumDef_Options(self->def)),
814 &google__protobuf__EnumOptions_msg_init,
815 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".EnumOptions");
816 }
817
PyUpb_EnumDescriptor_GetFeatures(PyObject * _self,PyObject * args)818 static PyObject* PyUpb_EnumDescriptor_GetFeatures(PyObject* _self,
819 PyObject* args) {
820 PyUpb_DescriptorBase* self = (void*)_self;
821 return PyUpb_DescriptorBase_GetFeatures(
822 &self->features, UPB_UPCAST(upb_EnumDef_ResolvedFeatures(self->def)));
823 }
824
PyUpb_EnumDescriptor_CopyToProto(PyObject * _self,PyObject * py_proto)825 static PyObject* PyUpb_EnumDescriptor_CopyToProto(PyObject* _self,
826 PyObject* py_proto) {
827 return PyUpb_DescriptorBase_CopyToProto(
828 _self, (PyUpb_ToProto_Func*)&upb_EnumDef_ToProto,
829 &google__protobuf__EnumDescriptorProto_msg_init,
830 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".EnumDescriptorProto", py_proto);
831 }
832
833 static PyGetSetDef PyUpb_EnumDescriptor_Getters[] = {
834 {"full_name", PyUpb_EnumDescriptor_GetFullName, NULL, "Full name"},
835 {"name", PyUpb_EnumDescriptor_GetName, NULL, "last name"},
836 {"file", PyUpb_EnumDescriptor_GetFile, NULL, "File descriptor"},
837 {"values", PyUpb_EnumDescriptor_GetValues, NULL, "values"},
838 {"values_by_name", PyUpb_EnumDescriptor_GetValuesByName, NULL,
839 "Enum values by name"},
840 {"values_by_number", PyUpb_EnumDescriptor_GetValuesByNumber, NULL,
841 "Enum values by number"},
842 {"containing_type", PyUpb_EnumDescriptor_GetContainingType, NULL,
843 "Containing type"},
844 {"has_options", PyUpb_EnumDescriptor_GetHasOptions, NULL, "Has Options"},
845 {"is_closed", PyUpb_EnumDescriptor_GetIsClosed, NULL,
846 "Checks if the enum is closed"},
847 {NULL}};
848
849 static PyMethodDef PyUpb_EnumDescriptor_Methods[] = {
850 {"GetOptions", PyUpb_EnumDescriptor_GetOptions, METH_NOARGS},
851 {"_GetFeatures", PyUpb_EnumDescriptor_GetFeatures, METH_NOARGS},
852 {"CopyToProto", PyUpb_EnumDescriptor_CopyToProto, METH_O},
853 {NULL}};
854
855 static PyType_Slot PyUpb_EnumDescriptor_Slots[] = {
856 DESCRIPTOR_BASE_SLOTS,
857 {Py_tp_methods, PyUpb_EnumDescriptor_Methods},
858 {Py_tp_getset, PyUpb_EnumDescriptor_Getters},
859 {0, NULL}};
860
861 static PyType_Spec PyUpb_EnumDescriptor_Spec = {
862 PYUPB_MODULE_NAME ".EnumDescriptor", // tp_name
863 sizeof(PyUpb_DescriptorBase), // tp_basicsize
864 0, // tp_itemsize
865 Py_TPFLAGS_DEFAULT, // tp_flags
866 PyUpb_EnumDescriptor_Slots,
867 };
868
869 // -----------------------------------------------------------------------------
870 // EnumValueDescriptor
871 // -----------------------------------------------------------------------------
872
PyUpb_EnumValueDescriptor_Get(const upb_EnumValueDef * ev)873 PyObject* PyUpb_EnumValueDescriptor_Get(const upb_EnumValueDef* ev) {
874 const upb_FileDef* file = upb_EnumDef_File(upb_EnumValueDef_Enum(ev));
875 return PyUpb_DescriptorBase_Get(kPyUpb_EnumValueDescriptor, ev, file);
876 }
877
PyUpb_EnumValueDescriptor_GetName(PyObject * self,void * closure)878 static PyObject* PyUpb_EnumValueDescriptor_GetName(PyObject* self,
879 void* closure) {
880 PyUpb_DescriptorBase* base = (PyUpb_DescriptorBase*)self;
881 return PyUnicode_FromString(upb_EnumValueDef_Name(base->def));
882 }
883
PyUpb_EnumValueDescriptor_GetNumber(PyObject * self,void * closure)884 static PyObject* PyUpb_EnumValueDescriptor_GetNumber(PyObject* self,
885 void* closure) {
886 PyUpb_DescriptorBase* base = (PyUpb_DescriptorBase*)self;
887 return PyLong_FromLong(upb_EnumValueDef_Number(base->def));
888 }
889
PyUpb_EnumValueDescriptor_GetIndex(PyObject * self,void * closure)890 static PyObject* PyUpb_EnumValueDescriptor_GetIndex(PyObject* self,
891 void* closure) {
892 PyUpb_DescriptorBase* base = (PyUpb_DescriptorBase*)self;
893 return PyLong_FromLong(upb_EnumValueDef_Index(base->def));
894 }
895
PyUpb_EnumValueDescriptor_GetType(PyObject * self,void * closure)896 static PyObject* PyUpb_EnumValueDescriptor_GetType(PyObject* self,
897 void* closure) {
898 PyUpb_DescriptorBase* base = (PyUpb_DescriptorBase*)self;
899 return PyUpb_EnumDescriptor_Get(upb_EnumValueDef_Enum(base->def));
900 }
901
PyUpb_EnumValueDescriptor_GetHasOptions(PyObject * _self,void * closure)902 static PyObject* PyUpb_EnumValueDescriptor_GetHasOptions(PyObject* _self,
903 void* closure) {
904 PyUpb_DescriptorBase* self = (void*)_self;
905 return PyBool_FromLong(upb_EnumValueDef_HasOptions(self->def));
906 }
907
PyUpb_EnumValueDescriptor_GetOptions(PyObject * _self,PyObject * args)908 static PyObject* PyUpb_EnumValueDescriptor_GetOptions(PyObject* _self,
909 PyObject* args) {
910 PyUpb_DescriptorBase* self = (void*)_self;
911 return PyUpb_DescriptorBase_GetOptions(
912 &self->options, UPB_UPCAST(upb_EnumValueDef_Options(self->def)),
913 &google__protobuf__EnumValueOptions_msg_init,
914 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".EnumValueOptions");
915 }
916
PyUpb_EnumValueDescriptor_GetFeatures(PyObject * _self,PyObject * args)917 static PyObject* PyUpb_EnumValueDescriptor_GetFeatures(PyObject* _self,
918 PyObject* args) {
919 PyUpb_DescriptorBase* self = (void*)_self;
920 return PyUpb_DescriptorBase_GetFeatures(
921 &self->features,
922 UPB_UPCAST(upb_EnumValueDef_ResolvedFeatures(self->def)));
923 }
924
925 static PyGetSetDef PyUpb_EnumValueDescriptor_Getters[] = {
926 {"name", PyUpb_EnumValueDescriptor_GetName, NULL, "name"},
927 {"number", PyUpb_EnumValueDescriptor_GetNumber, NULL, "number"},
928 {"index", PyUpb_EnumValueDescriptor_GetIndex, NULL, "index"},
929 {"type", PyUpb_EnumValueDescriptor_GetType, NULL, "index"},
930 {"has_options", PyUpb_EnumValueDescriptor_GetHasOptions, NULL,
931 "Has Options"},
932 {NULL}};
933
934 static PyMethodDef PyUpb_EnumValueDescriptor_Methods[] = {
935 {
936 "GetOptions",
937 PyUpb_EnumValueDescriptor_GetOptions,
938 METH_NOARGS,
939 },
940 {
941 "_GetFeatures",
942 PyUpb_EnumValueDescriptor_GetFeatures,
943 METH_NOARGS,
944 },
945 {NULL}};
946
947 static PyType_Slot PyUpb_EnumValueDescriptor_Slots[] = {
948 DESCRIPTOR_BASE_SLOTS,
949 {Py_tp_methods, PyUpb_EnumValueDescriptor_Methods},
950 {Py_tp_getset, PyUpb_EnumValueDescriptor_Getters},
951 {0, NULL}};
952
953 static PyType_Spec PyUpb_EnumValueDescriptor_Spec = {
954 PYUPB_MODULE_NAME ".EnumValueDescriptor", // tp_name
955 sizeof(PyUpb_DescriptorBase), // tp_basicsize
956 0, // tp_itemsize
957 Py_TPFLAGS_DEFAULT, // tp_flags
958 PyUpb_EnumValueDescriptor_Slots,
959 };
960
961 // -----------------------------------------------------------------------------
962 // FieldDescriptor
963 // -----------------------------------------------------------------------------
964
PyUpb_FieldDescriptor_GetDef(PyObject * _self)965 const upb_FieldDef* PyUpb_FieldDescriptor_GetDef(PyObject* _self) {
966 PyUpb_DescriptorBase* self =
967 PyUpb_DescriptorBase_Check(_self, kPyUpb_FieldDescriptor);
968 return self ? self->def : NULL;
969 }
970
PyUpb_FieldDescriptor_Get(const upb_FieldDef * field)971 PyObject* PyUpb_FieldDescriptor_Get(const upb_FieldDef* field) {
972 const upb_FileDef* file = upb_FieldDef_File(field);
973 return PyUpb_DescriptorBase_Get(kPyUpb_FieldDescriptor, field, file);
974 }
975
PyUpb_FieldDescriptor_GetFullName(PyUpb_DescriptorBase * self,void * closure)976 static PyObject* PyUpb_FieldDescriptor_GetFullName(PyUpb_DescriptorBase* self,
977 void* closure) {
978 return PyUnicode_FromString(upb_FieldDef_FullName(self->def));
979 }
980
PyUpb_FieldDescriptor_GetName(PyUpb_DescriptorBase * self,void * closure)981 static PyObject* PyUpb_FieldDescriptor_GetName(PyUpb_DescriptorBase* self,
982 void* closure) {
983 return PyUnicode_FromString(upb_FieldDef_Name(self->def));
984 }
985
PyUpb_AsciiIsUpper(char ch)986 static char PyUpb_AsciiIsUpper(char ch) { return ch >= 'A' && ch <= 'Z'; }
987
PyUpb_AsciiToLower(char ch)988 static char PyUpb_AsciiToLower(char ch) {
989 assert(PyUpb_AsciiIsUpper(ch));
990 return ch + ('a' - 'A');
991 }
992
PyUpb_FieldDescriptor_GetCamelCaseName(PyUpb_DescriptorBase * self,void * closure)993 static PyObject* PyUpb_FieldDescriptor_GetCamelCaseName(
994 PyUpb_DescriptorBase* self, void* closure) {
995 // Camelcase is equivalent to JSON name except for potentially the first
996 // character.
997 const char* name = upb_FieldDef_JsonName(self->def);
998 size_t size = strlen(name);
999 return size > 0 && PyUpb_AsciiIsUpper(name[0])
1000 ? PyUnicode_FromFormat("%c%s", PyUpb_AsciiToLower(name[0]),
1001 name + 1)
1002 : PyUnicode_FromStringAndSize(name, size);
1003 }
1004
PyUpb_FieldDescriptor_GetJsonName(PyUpb_DescriptorBase * self,void * closure)1005 static PyObject* PyUpb_FieldDescriptor_GetJsonName(PyUpb_DescriptorBase* self,
1006 void* closure) {
1007 return PyUnicode_FromString(upb_FieldDef_JsonName(self->def));
1008 }
1009
PyUpb_FieldDescriptor_GetFile(PyUpb_DescriptorBase * self,void * closure)1010 static PyObject* PyUpb_FieldDescriptor_GetFile(PyUpb_DescriptorBase* self,
1011 void* closure) {
1012 const upb_FileDef* file = upb_FieldDef_File(self->def);
1013 if (!file) Py_RETURN_NONE;
1014 return PyUpb_FileDescriptor_Get(file);
1015 }
1016
PyUpb_FieldDescriptor_GetType(PyUpb_DescriptorBase * self,void * closure)1017 static PyObject* PyUpb_FieldDescriptor_GetType(PyUpb_DescriptorBase* self,
1018 void* closure) {
1019 return PyLong_FromLong(upb_FieldDef_Type(self->def));
1020 }
1021
1022 // Enum values copied from descriptor.h in C++.
1023 enum CppType {
1024 CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32
1025 CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64
1026 CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32
1027 CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64
1028 CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE
1029 CPPTYPE_FLOAT = 6, // TYPE_FLOAT
1030 CPPTYPE_BOOL = 7, // TYPE_BOOL
1031 CPPTYPE_ENUM = 8, // TYPE_ENUM
1032 CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES
1033 CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP
1034 };
1035
PyUpb_FieldDescriptor_GetCppType(PyUpb_DescriptorBase * self,void * closure)1036 static PyObject* PyUpb_FieldDescriptor_GetCppType(PyUpb_DescriptorBase* self,
1037 void* closure) {
1038 static const uint8_t cpp_types[] = {
1039 -1,
1040 [kUpb_CType_Int32] = CPPTYPE_INT32,
1041 [kUpb_CType_Int64] = CPPTYPE_INT64,
1042 [kUpb_CType_UInt32] = CPPTYPE_UINT32,
1043 [kUpb_CType_UInt64] = CPPTYPE_UINT64,
1044 [kUpb_CType_Double] = CPPTYPE_DOUBLE,
1045 [kUpb_CType_Float] = CPPTYPE_FLOAT,
1046 [kUpb_CType_Bool] = CPPTYPE_BOOL,
1047 [kUpb_CType_Enum] = CPPTYPE_ENUM,
1048 [kUpb_CType_String] = CPPTYPE_STRING,
1049 [kUpb_CType_Bytes] = CPPTYPE_STRING,
1050 [kUpb_CType_Message] = CPPTYPE_MESSAGE,
1051 };
1052 return PyLong_FromLong(cpp_types[upb_FieldDef_CType(self->def)]);
1053 }
1054
PyUpb_FieldDescriptor_GetLabel(PyUpb_DescriptorBase * self,void * closure)1055 static PyObject* PyUpb_FieldDescriptor_GetLabel(PyUpb_DescriptorBase* self,
1056 void* closure) {
1057 return PyLong_FromLong(upb_FieldDef_Label(self->def));
1058 }
1059
PyUpb_FieldDescriptor_GetIsExtension(PyUpb_DescriptorBase * self,void * closure)1060 static PyObject* PyUpb_FieldDescriptor_GetIsExtension(
1061 PyUpb_DescriptorBase* self, void* closure) {
1062 return PyBool_FromLong(upb_FieldDef_IsExtension(self->def));
1063 }
1064
PyUpb_FieldDescriptor_GetIsPacked(PyUpb_DescriptorBase * self,void * closure)1065 static PyObject* PyUpb_FieldDescriptor_GetIsPacked(PyUpb_DescriptorBase* self,
1066 void* closure) {
1067 return PyBool_FromLong(upb_FieldDef_IsPacked(self->def));
1068 }
1069
PyUpb_FieldDescriptor_GetNumber(PyUpb_DescriptorBase * self,void * closure)1070 static PyObject* PyUpb_FieldDescriptor_GetNumber(PyUpb_DescriptorBase* self,
1071 void* closure) {
1072 return PyLong_FromLong(upb_FieldDef_Number(self->def));
1073 }
1074
PyUpb_FieldDescriptor_GetIndex(PyUpb_DescriptorBase * self,void * closure)1075 static PyObject* PyUpb_FieldDescriptor_GetIndex(PyUpb_DescriptorBase* self,
1076 void* closure) {
1077 return PyLong_FromLong(upb_FieldDef_Index(self->def));
1078 }
1079
PyUpb_FieldDescriptor_GetMessageType(PyUpb_DescriptorBase * self,void * closure)1080 static PyObject* PyUpb_FieldDescriptor_GetMessageType(
1081 PyUpb_DescriptorBase* self, void* closure) {
1082 const upb_MessageDef* subdef = upb_FieldDef_MessageSubDef(self->def);
1083 if (!subdef) Py_RETURN_NONE;
1084 return PyUpb_Descriptor_Get(subdef);
1085 }
1086
PyUpb_FieldDescriptor_GetEnumType(PyUpb_DescriptorBase * self,void * closure)1087 static PyObject* PyUpb_FieldDescriptor_GetEnumType(PyUpb_DescriptorBase* self,
1088 void* closure) {
1089 const upb_EnumDef* enumdef = upb_FieldDef_EnumSubDef(self->def);
1090 if (!enumdef) Py_RETURN_NONE;
1091 return PyUpb_EnumDescriptor_Get(enumdef);
1092 }
1093
PyUpb_FieldDescriptor_GetContainingType(PyUpb_DescriptorBase * self,void * closure)1094 static PyObject* PyUpb_FieldDescriptor_GetContainingType(
1095 PyUpb_DescriptorBase* self, void* closure) {
1096 const upb_MessageDef* m = upb_FieldDef_ContainingType(self->def);
1097 if (!m) Py_RETURN_NONE;
1098 return PyUpb_Descriptor_Get(m);
1099 }
1100
PyUpb_FieldDescriptor_GetExtensionScope(PyUpb_DescriptorBase * self,void * closure)1101 static PyObject* PyUpb_FieldDescriptor_GetExtensionScope(
1102 PyUpb_DescriptorBase* self, void* closure) {
1103 const upb_MessageDef* m = upb_FieldDef_ExtensionScope(self->def);
1104 if (!m) Py_RETURN_NONE;
1105 return PyUpb_Descriptor_Get(m);
1106 }
1107
PyUpb_FieldDescriptor_HasDefaultValue(PyUpb_DescriptorBase * self,void * closure)1108 static PyObject* PyUpb_FieldDescriptor_HasDefaultValue(
1109 PyUpb_DescriptorBase* self, void* closure) {
1110 return PyBool_FromLong(upb_FieldDef_HasDefault(self->def));
1111 }
1112
PyUpb_FieldDescriptor_GetDefaultValue(PyUpb_DescriptorBase * self,void * closure)1113 static PyObject* PyUpb_FieldDescriptor_GetDefaultValue(
1114 PyUpb_DescriptorBase* self, void* closure) {
1115 const upb_FieldDef* f = self->def;
1116 if (upb_FieldDef_IsRepeated(f)) return PyList_New(0);
1117 if (upb_FieldDef_IsSubMessage(f)) Py_RETURN_NONE;
1118 return PyUpb_UpbToPy(upb_FieldDef_Default(self->def), self->def, NULL);
1119 }
1120
PyUpb_FieldDescriptor_GetContainingOneof(PyUpb_DescriptorBase * self,void * closure)1121 static PyObject* PyUpb_FieldDescriptor_GetContainingOneof(
1122 PyUpb_DescriptorBase* self, void* closure) {
1123 const upb_OneofDef* oneof = upb_FieldDef_ContainingOneof(self->def);
1124 if (!oneof) Py_RETURN_NONE;
1125 return PyUpb_OneofDescriptor_Get(oneof);
1126 }
1127
PyUpb_FieldDescriptor_GetHasOptions(PyUpb_DescriptorBase * _self,void * closure)1128 static PyObject* PyUpb_FieldDescriptor_GetHasOptions(
1129 PyUpb_DescriptorBase* _self, void* closure) {
1130 PyUpb_DescriptorBase* self = (void*)_self;
1131 return PyBool_FromLong(upb_FieldDef_HasOptions(self->def));
1132 }
1133
PyUpb_FieldDescriptor_GetHasPresence(PyUpb_DescriptorBase * _self,void * closure)1134 static PyObject* PyUpb_FieldDescriptor_GetHasPresence(
1135 PyUpb_DescriptorBase* _self, void* closure) {
1136 PyUpb_DescriptorBase* self = (void*)_self;
1137 return PyBool_FromLong(upb_FieldDef_HasPresence(self->def));
1138 }
1139
PyUpb_FieldDescriptor_GetOptions(PyObject * _self,PyObject * args)1140 static PyObject* PyUpb_FieldDescriptor_GetOptions(PyObject* _self,
1141 PyObject* args) {
1142 PyUpb_DescriptorBase* self = (void*)_self;
1143 return PyUpb_DescriptorBase_GetOptions(
1144 &self->options, UPB_UPCAST(upb_FieldDef_Options(self->def)),
1145 &google__protobuf__FieldOptions_msg_init,
1146 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".FieldOptions");
1147 }
1148
PyUpb_FieldDescriptor_GetFeatures(PyObject * _self,PyObject * args)1149 static PyObject* PyUpb_FieldDescriptor_GetFeatures(PyObject* _self,
1150 PyObject* args) {
1151 PyUpb_DescriptorBase* self = (void*)_self;
1152 return PyUpb_DescriptorBase_GetFeatures(
1153 &self->features, UPB_UPCAST(upb_FieldDef_ResolvedFeatures(self->def)));
1154 }
1155
1156 static PyGetSetDef PyUpb_FieldDescriptor_Getters[] = {
1157 {"full_name", (getter)PyUpb_FieldDescriptor_GetFullName, NULL, "Full name"},
1158 {"name", (getter)PyUpb_FieldDescriptor_GetName, NULL, "Unqualified name"},
1159 {"camelcase_name", (getter)PyUpb_FieldDescriptor_GetCamelCaseName, NULL,
1160 "CamelCase name"},
1161 {"json_name", (getter)PyUpb_FieldDescriptor_GetJsonName, NULL, "Json name"},
1162 {"file", (getter)PyUpb_FieldDescriptor_GetFile, NULL, "File Descriptor"},
1163 {"type", (getter)PyUpb_FieldDescriptor_GetType, NULL, "Type"},
1164 {"cpp_type", (getter)PyUpb_FieldDescriptor_GetCppType, NULL, "C++ Type"},
1165 {"label", (getter)PyUpb_FieldDescriptor_GetLabel, NULL, "Label"},
1166 {"number", (getter)PyUpb_FieldDescriptor_GetNumber, NULL, "Number"},
1167 {"index", (getter)PyUpb_FieldDescriptor_GetIndex, NULL, "Index"},
1168 {"default_value", (getter)PyUpb_FieldDescriptor_GetDefaultValue, NULL,
1169 "Default Value"},
1170 {"has_default_value", (getter)PyUpb_FieldDescriptor_HasDefaultValue},
1171 {"is_extension", (getter)PyUpb_FieldDescriptor_GetIsExtension, NULL, "ID"},
1172 {"is_packed", (getter)PyUpb_FieldDescriptor_GetIsPacked, NULL, "Is Packed"},
1173 // TODO
1174 //{ "id", (getter)GetID, NULL, "ID"},
1175 {"message_type", (getter)PyUpb_FieldDescriptor_GetMessageType, NULL,
1176 "Message type"},
1177 {"enum_type", (getter)PyUpb_FieldDescriptor_GetEnumType, NULL, "Enum type"},
1178 {"containing_type", (getter)PyUpb_FieldDescriptor_GetContainingType, NULL,
1179 "Containing type"},
1180 {"extension_scope", (getter)PyUpb_FieldDescriptor_GetExtensionScope, NULL,
1181 "Extension scope"},
1182 {"containing_oneof", (getter)PyUpb_FieldDescriptor_GetContainingOneof, NULL,
1183 "Containing oneof"},
1184 {"has_options", (getter)PyUpb_FieldDescriptor_GetHasOptions, NULL,
1185 "Has Options"},
1186 {"has_presence", (getter)PyUpb_FieldDescriptor_GetHasPresence, NULL,
1187 "Has Presence"},
1188 // TODO
1189 //{ "_options",
1190 //(getter)NULL, (setter)SetOptions, "Options"}, { "_serialized_options",
1191 //(getter)NULL, (setter)SetSerializedOptions, "Serialized Options"},
1192 {NULL}};
1193
1194 static PyMethodDef PyUpb_FieldDescriptor_Methods[] = {
1195 {
1196 "GetOptions",
1197 PyUpb_FieldDescriptor_GetOptions,
1198 METH_NOARGS,
1199 },
1200 {
1201 "_GetFeatures",
1202 PyUpb_FieldDescriptor_GetFeatures,
1203 METH_NOARGS,
1204 },
1205 {NULL}};
1206
1207 static PyType_Slot PyUpb_FieldDescriptor_Slots[] = {
1208 DESCRIPTOR_BASE_SLOTS,
1209 {Py_tp_methods, PyUpb_FieldDescriptor_Methods},
1210 {Py_tp_getset, PyUpb_FieldDescriptor_Getters},
1211 {0, NULL}};
1212
1213 static PyType_Spec PyUpb_FieldDescriptor_Spec = {
1214 PYUPB_MODULE_NAME ".FieldDescriptor",
1215 sizeof(PyUpb_DescriptorBase),
1216 0, // tp_itemsize
1217 Py_TPFLAGS_DEFAULT,
1218 PyUpb_FieldDescriptor_Slots,
1219 };
1220
1221 // -----------------------------------------------------------------------------
1222 // FileDescriptor
1223 // -----------------------------------------------------------------------------
1224
PyUpb_FileDescriptor_Get(const upb_FileDef * file)1225 PyObject* PyUpb_FileDescriptor_Get(const upb_FileDef* file) {
1226 return PyUpb_DescriptorBase_Get(kPyUpb_FileDescriptor, file, file);
1227 }
1228
1229 // These are not provided on upb_FileDef because they use the underlying
1230 // symtab's hash table. This works for Python because everything happens under
1231 // the GIL, but in general the caller has to guarantee that the symtab is not
1232 // being mutated concurrently.
1233 typedef const void* PyUpb_FileDescriptor_LookupFunc(const upb_DefPool*,
1234 const char*);
1235
PyUpb_FileDescriptor_NestedLookup(const upb_FileDef * filedef,const char * name,PyUpb_FileDescriptor_LookupFunc * func)1236 static const void* PyUpb_FileDescriptor_NestedLookup(
1237 const upb_FileDef* filedef, const char* name,
1238 PyUpb_FileDescriptor_LookupFunc* func) {
1239 const upb_DefPool* symtab = upb_FileDef_Pool(filedef);
1240 const char* package = upb_FileDef_Package(filedef);
1241 if (strlen(package)) {
1242 PyObject* qname = PyUnicode_FromFormat("%s.%s", package, name);
1243 const void* ret = func(symtab, PyUnicode_AsUTF8AndSize(qname, NULL));
1244 Py_DECREF(qname);
1245 return ret;
1246 } else {
1247 return func(symtab, name);
1248 }
1249 }
1250
PyUpb_FileDescriptor_LookupMessage(const upb_FileDef * filedef,const char * name)1251 static const void* PyUpb_FileDescriptor_LookupMessage(
1252 const upb_FileDef* filedef, const char* name) {
1253 const upb_MessageDef* m = PyUpb_FileDescriptor_NestedLookup(
1254 filedef, name, (void*)&upb_DefPool_FindMessageByName);
1255 if (!m) return NULL;
1256 return upb_MessageDef_File(m) == filedef ? m : NULL;
1257 }
1258
PyUpb_FileDescriptor_LookupEnum(const upb_FileDef * filedef,const char * name)1259 static const void* PyUpb_FileDescriptor_LookupEnum(const upb_FileDef* filedef,
1260 const char* name) {
1261 const upb_EnumDef* e = PyUpb_FileDescriptor_NestedLookup(
1262 filedef, name, (void*)&upb_DefPool_FindEnumByName);
1263 if (!e) return NULL;
1264 return upb_EnumDef_File(e) == filedef ? e : NULL;
1265 }
1266
PyUpb_FileDescriptor_LookupExtension(const upb_FileDef * filedef,const char * name)1267 static const void* PyUpb_FileDescriptor_LookupExtension(
1268 const upb_FileDef* filedef, const char* name) {
1269 const upb_FieldDef* f = PyUpb_FileDescriptor_NestedLookup(
1270 filedef, name, (void*)&upb_DefPool_FindExtensionByName);
1271 if (!f) return NULL;
1272 return upb_FieldDef_File(f) == filedef ? f : NULL;
1273 }
1274
PyUpb_FileDescriptor_LookupService(const upb_FileDef * filedef,const char * name)1275 static const void* PyUpb_FileDescriptor_LookupService(
1276 const upb_FileDef* filedef, const char* name) {
1277 const upb_ServiceDef* s = PyUpb_FileDescriptor_NestedLookup(
1278 filedef, name, (void*)&upb_DefPool_FindServiceByName);
1279 if (!s) return NULL;
1280 return upb_ServiceDef_File(s) == filedef ? s : NULL;
1281 }
1282
PyUpb_FileDescriptor_GetName(PyUpb_DescriptorBase * self,void * closure)1283 static PyObject* PyUpb_FileDescriptor_GetName(PyUpb_DescriptorBase* self,
1284 void* closure) {
1285 return PyUnicode_FromString(upb_FileDef_Name(self->def));
1286 }
1287
PyUpb_FileDescriptor_GetPool(PyObject * _self,void * closure)1288 static PyObject* PyUpb_FileDescriptor_GetPool(PyObject* _self, void* closure) {
1289 PyUpb_DescriptorBase* self = (PyUpb_DescriptorBase*)_self;
1290 Py_INCREF(self->pool);
1291 return self->pool;
1292 }
1293
PyUpb_FileDescriptor_GetPackage(PyObject * _self,void * closure)1294 static PyObject* PyUpb_FileDescriptor_GetPackage(PyObject* _self,
1295 void* closure) {
1296 PyUpb_DescriptorBase* self = (PyUpb_DescriptorBase*)_self;
1297 return PyUnicode_FromString(upb_FileDef_Package(self->def));
1298 }
1299
PyUpb_FileDescriptor_GetSerializedPb(PyObject * self,void * closure)1300 static PyObject* PyUpb_FileDescriptor_GetSerializedPb(PyObject* self,
1301 void* closure) {
1302 return PyUpb_DescriptorBase_GetSerializedProto(
1303 self, (PyUpb_ToProto_Func*)&upb_FileDef_ToProto,
1304 &google__protobuf__FileDescriptorProto_msg_init);
1305 }
1306
PyUpb_FileDescriptor_GetMessageTypesByName(PyObject * _self,void * closure)1307 static PyObject* PyUpb_FileDescriptor_GetMessageTypesByName(PyObject* _self,
1308 void* closure) {
1309 static PyUpb_ByNameMap_Funcs funcs = {
1310 {
1311 (void*)&upb_FileDef_TopLevelMessageCount,
1312 (void*)&upb_FileDef_TopLevelMessage,
1313 (void*)&PyUpb_Descriptor_Get,
1314 },
1315 (void*)&PyUpb_FileDescriptor_LookupMessage,
1316 (void*)&upb_MessageDef_Name,
1317 };
1318 PyUpb_DescriptorBase* self = (void*)_self;
1319 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
1320 }
1321
PyUpb_FileDescriptor_GetEnumTypesByName(PyObject * _self,void * closure)1322 static PyObject* PyUpb_FileDescriptor_GetEnumTypesByName(PyObject* _self,
1323 void* closure) {
1324 static PyUpb_ByNameMap_Funcs funcs = {
1325 {
1326 (void*)&upb_FileDef_TopLevelEnumCount,
1327 (void*)&upb_FileDef_TopLevelEnum,
1328 (void*)&PyUpb_EnumDescriptor_Get,
1329 },
1330 (void*)&PyUpb_FileDescriptor_LookupEnum,
1331 (void*)&upb_EnumDef_Name,
1332 };
1333 PyUpb_DescriptorBase* self = (void*)_self;
1334 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
1335 }
1336
PyUpb_FileDescriptor_GetExtensionsByName(PyObject * _self,void * closure)1337 static PyObject* PyUpb_FileDescriptor_GetExtensionsByName(PyObject* _self,
1338 void* closure) {
1339 static PyUpb_ByNameMap_Funcs funcs = {
1340 {
1341 (void*)&upb_FileDef_TopLevelExtensionCount,
1342 (void*)&upb_FileDef_TopLevelExtension,
1343 (void*)&PyUpb_FieldDescriptor_Get,
1344 },
1345 (void*)&PyUpb_FileDescriptor_LookupExtension,
1346 (void*)&upb_FieldDef_Name,
1347 };
1348 PyUpb_DescriptorBase* self = (void*)_self;
1349 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
1350 }
1351
PyUpb_FileDescriptor_GetServicesByName(PyObject * _self,void * closure)1352 static PyObject* PyUpb_FileDescriptor_GetServicesByName(PyObject* _self,
1353 void* closure) {
1354 static PyUpb_ByNameMap_Funcs funcs = {
1355 {
1356 (void*)&upb_FileDef_ServiceCount,
1357 (void*)&upb_FileDef_Service,
1358 (void*)&PyUpb_ServiceDescriptor_Get,
1359 },
1360 (void*)&PyUpb_FileDescriptor_LookupService,
1361 (void*)&upb_ServiceDef_Name,
1362 };
1363 PyUpb_DescriptorBase* self = (void*)_self;
1364 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
1365 }
1366
PyUpb_FileDescriptor_GetDependencies(PyObject * _self,void * closure)1367 static PyObject* PyUpb_FileDescriptor_GetDependencies(PyObject* _self,
1368 void* closure) {
1369 PyUpb_DescriptorBase* self = (void*)_self;
1370 static PyUpb_GenericSequence_Funcs funcs = {
1371 (void*)&upb_FileDef_DependencyCount,
1372 (void*)&upb_FileDef_Dependency,
1373 (void*)&PyUpb_FileDescriptor_Get,
1374 };
1375 return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
1376 }
1377
PyUpb_FileDescriptor_GetPublicDependencies(PyObject * _self,void * closure)1378 static PyObject* PyUpb_FileDescriptor_GetPublicDependencies(PyObject* _self,
1379 void* closure) {
1380 PyUpb_DescriptorBase* self = (void*)_self;
1381 static PyUpb_GenericSequence_Funcs funcs = {
1382 (void*)&upb_FileDef_PublicDependencyCount,
1383 (void*)&upb_FileDef_PublicDependency,
1384 (void*)&PyUpb_FileDescriptor_Get,
1385 };
1386 return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
1387 }
1388
PyUpb_FileDescriptor_GetHasOptions(PyObject * _self,void * closure)1389 static PyObject* PyUpb_FileDescriptor_GetHasOptions(PyObject* _self,
1390 void* closure) {
1391 PyUpb_DescriptorBase* self = (void*)_self;
1392 return PyBool_FromLong(upb_FileDef_HasOptions(self->def));
1393 }
1394
PyUpb_FileDescriptor_GetOptions(PyObject * _self,PyObject * args)1395 static PyObject* PyUpb_FileDescriptor_GetOptions(PyObject* _self,
1396 PyObject* args) {
1397 PyUpb_DescriptorBase* self = (void*)_self;
1398 return PyUpb_DescriptorBase_GetOptions(
1399 &self->options, UPB_UPCAST(upb_FileDef_Options(self->def)),
1400 &google__protobuf__FileOptions_msg_init,
1401 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".FileOptions");
1402 }
1403
PyUpb_FileDescriptor_GetFeatures(PyObject * _self,PyObject * args)1404 static PyObject* PyUpb_FileDescriptor_GetFeatures(PyObject* _self,
1405 PyObject* args) {
1406 PyUpb_DescriptorBase* self = (void*)_self;
1407 return PyUpb_DescriptorBase_GetFeatures(
1408 &self->features, UPB_UPCAST(upb_FileDef_ResolvedFeatures(self->def)));
1409 }
1410
PyUpb_FileDescriptor_CopyToProto(PyObject * _self,PyObject * py_proto)1411 static PyObject* PyUpb_FileDescriptor_CopyToProto(PyObject* _self,
1412 PyObject* py_proto) {
1413 return PyUpb_DescriptorBase_CopyToProto(
1414 _self, (PyUpb_ToProto_Func*)&upb_FileDef_ToProto,
1415 &google__protobuf__FileDescriptorProto_msg_init,
1416 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".FileDescriptorProto", py_proto);
1417 }
1418
1419 static PyGetSetDef PyUpb_FileDescriptor_Getters[] = {
1420 {"pool", PyUpb_FileDescriptor_GetPool, NULL, "pool"},
1421 {"name", (getter)PyUpb_FileDescriptor_GetName, NULL, "name"},
1422 {"package", PyUpb_FileDescriptor_GetPackage, NULL, "package"},
1423 {"serialized_pb", PyUpb_FileDescriptor_GetSerializedPb},
1424 {"message_types_by_name", PyUpb_FileDescriptor_GetMessageTypesByName, NULL,
1425 "Messages by name"},
1426 {"enum_types_by_name", PyUpb_FileDescriptor_GetEnumTypesByName, NULL,
1427 "Enums by name"},
1428 {"extensions_by_name", PyUpb_FileDescriptor_GetExtensionsByName, NULL,
1429 "Extensions by name"},
1430 {"services_by_name", PyUpb_FileDescriptor_GetServicesByName, NULL,
1431 "Services by name"},
1432 {"dependencies", PyUpb_FileDescriptor_GetDependencies, NULL,
1433 "Dependencies"},
1434 {"public_dependencies", PyUpb_FileDescriptor_GetPublicDependencies, NULL,
1435 "Dependencies"},
1436 {"has_options", PyUpb_FileDescriptor_GetHasOptions, NULL, "Has Options"},
1437 {NULL},
1438 };
1439
1440 static PyMethodDef PyUpb_FileDescriptor_Methods[] = {
1441 {"GetOptions", PyUpb_FileDescriptor_GetOptions, METH_NOARGS},
1442 {"_GetFeatures", PyUpb_FileDescriptor_GetFeatures, METH_NOARGS},
1443 {"CopyToProto", PyUpb_FileDescriptor_CopyToProto, METH_O},
1444 {NULL}};
1445
1446 static PyType_Slot PyUpb_FileDescriptor_Slots[] = {
1447 DESCRIPTOR_BASE_SLOTS,
1448 {Py_tp_methods, PyUpb_FileDescriptor_Methods},
1449 {Py_tp_getset, PyUpb_FileDescriptor_Getters},
1450 {0, NULL}};
1451
1452 static PyType_Spec PyUpb_FileDescriptor_Spec = {
1453 PYUPB_MODULE_NAME ".FileDescriptor", // tp_name
1454 sizeof(PyUpb_DescriptorBase), // tp_basicsize
1455 0, // tp_itemsize
1456 Py_TPFLAGS_DEFAULT, // tp_flags
1457 PyUpb_FileDescriptor_Slots,
1458 };
1459
PyUpb_FileDescriptor_GetDef(PyObject * _self)1460 const upb_FileDef* PyUpb_FileDescriptor_GetDef(PyObject* _self) {
1461 PyUpb_DescriptorBase* self =
1462 PyUpb_DescriptorBase_Check(_self, kPyUpb_FileDescriptor);
1463 return self ? self->def : NULL;
1464 }
1465
1466 // -----------------------------------------------------------------------------
1467 // MethodDescriptor
1468 // -----------------------------------------------------------------------------
1469
PyUpb_MethodDescriptor_GetDef(PyObject * _self)1470 const upb_MethodDef* PyUpb_MethodDescriptor_GetDef(PyObject* _self) {
1471 PyUpb_DescriptorBase* self =
1472 PyUpb_DescriptorBase_Check(_self, kPyUpb_MethodDescriptor);
1473 return self ? self->def : NULL;
1474 }
1475
PyUpb_MethodDescriptor_Get(const upb_MethodDef * m)1476 PyObject* PyUpb_MethodDescriptor_Get(const upb_MethodDef* m) {
1477 const upb_FileDef* file = upb_ServiceDef_File(upb_MethodDef_Service(m));
1478 return PyUpb_DescriptorBase_Get(kPyUpb_MethodDescriptor, m, file);
1479 }
1480
PyUpb_MethodDescriptor_GetName(PyObject * self,void * closure)1481 static PyObject* PyUpb_MethodDescriptor_GetName(PyObject* self, void* closure) {
1482 const upb_MethodDef* m = PyUpb_MethodDescriptor_GetDef(self);
1483 return PyUnicode_FromString(upb_MethodDef_Name(m));
1484 }
1485
PyUpb_MethodDescriptor_GetFullName(PyObject * self,void * closure)1486 static PyObject* PyUpb_MethodDescriptor_GetFullName(PyObject* self,
1487 void* closure) {
1488 const upb_MethodDef* m = PyUpb_MethodDescriptor_GetDef(self);
1489 return PyUnicode_FromString(upb_MethodDef_FullName(m));
1490 }
1491
PyUpb_MethodDescriptor_GetIndex(PyObject * self,void * closure)1492 static PyObject* PyUpb_MethodDescriptor_GetIndex(PyObject* self,
1493 void* closure) {
1494 const upb_MethodDef* oneof = PyUpb_MethodDescriptor_GetDef(self);
1495 return PyLong_FromLong(upb_MethodDef_Index(oneof));
1496 }
1497
PyUpb_MethodDescriptor_GetContainingService(PyObject * self,void * closure)1498 static PyObject* PyUpb_MethodDescriptor_GetContainingService(PyObject* self,
1499 void* closure) {
1500 const upb_MethodDef* m = PyUpb_MethodDescriptor_GetDef(self);
1501 return PyUpb_ServiceDescriptor_Get(upb_MethodDef_Service(m));
1502 }
1503
PyUpb_MethodDescriptor_GetInputType(PyObject * self,void * closure)1504 static PyObject* PyUpb_MethodDescriptor_GetInputType(PyObject* self,
1505 void* closure) {
1506 const upb_MethodDef* m = PyUpb_MethodDescriptor_GetDef(self);
1507 return PyUpb_Descriptor_Get(upb_MethodDef_InputType(m));
1508 }
1509
PyUpb_MethodDescriptor_GetOutputType(PyObject * self,void * closure)1510 static PyObject* PyUpb_MethodDescriptor_GetOutputType(PyObject* self,
1511 void* closure) {
1512 const upb_MethodDef* m = PyUpb_MethodDescriptor_GetDef(self);
1513 return PyUpb_Descriptor_Get(upb_MethodDef_OutputType(m));
1514 }
1515
PyUpb_MethodDescriptor_GetClientStreaming(PyObject * self,void * closure)1516 static PyObject* PyUpb_MethodDescriptor_GetClientStreaming(PyObject* self,
1517 void* closure) {
1518 const upb_MethodDef* m = PyUpb_MethodDescriptor_GetDef(self);
1519 return PyBool_FromLong(upb_MethodDef_ClientStreaming(m) ? 1 : 0);
1520 }
1521
PyUpb_MethodDescriptor_GetServerStreaming(PyObject * self,void * closure)1522 static PyObject* PyUpb_MethodDescriptor_GetServerStreaming(PyObject* self,
1523 void* closure) {
1524 const upb_MethodDef* m = PyUpb_MethodDescriptor_GetDef(self);
1525 return PyBool_FromLong(upb_MethodDef_ServerStreaming(m) ? 1 : 0);
1526 }
1527
PyUpb_MethodDescriptor_GetOptions(PyObject * _self,PyObject * args)1528 static PyObject* PyUpb_MethodDescriptor_GetOptions(PyObject* _self,
1529 PyObject* args) {
1530 PyUpb_DescriptorBase* self = (void*)_self;
1531 return PyUpb_DescriptorBase_GetOptions(
1532 &self->options, UPB_UPCAST(upb_MethodDef_Options(self->def)),
1533 &google__protobuf__MethodOptions_msg_init,
1534 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".MethodOptions");
1535 }
1536
PyUpb_MethodDescriptor_GetFeatures(PyObject * _self,PyObject * args)1537 static PyObject* PyUpb_MethodDescriptor_GetFeatures(PyObject* _self,
1538 PyObject* args) {
1539 PyUpb_DescriptorBase* self = (void*)_self;
1540 return PyUpb_DescriptorBase_GetFeatures(
1541 &self->features, UPB_UPCAST(upb_MethodDef_ResolvedFeatures(self->def)));
1542 }
1543
PyUpb_MethodDescriptor_CopyToProto(PyObject * _self,PyObject * py_proto)1544 static PyObject* PyUpb_MethodDescriptor_CopyToProto(PyObject* _self,
1545 PyObject* py_proto) {
1546 return PyUpb_DescriptorBase_CopyToProto(
1547 _self, (PyUpb_ToProto_Func*)&upb_MethodDef_ToProto,
1548 &google__protobuf__MethodDescriptorProto_msg_init,
1549 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".MethodDescriptorProto", py_proto);
1550 }
1551
1552 static PyGetSetDef PyUpb_MethodDescriptor_Getters[] = {
1553 {"name", PyUpb_MethodDescriptor_GetName, NULL, "Name", NULL},
1554 {"full_name", PyUpb_MethodDescriptor_GetFullName, NULL, "Full name", NULL},
1555 {"index", PyUpb_MethodDescriptor_GetIndex, NULL, "Index", NULL},
1556 {"containing_service", PyUpb_MethodDescriptor_GetContainingService, NULL,
1557 "Containing service", NULL},
1558 {"input_type", PyUpb_MethodDescriptor_GetInputType, NULL, "Input type",
1559 NULL},
1560 {"output_type", PyUpb_MethodDescriptor_GetOutputType, NULL, "Output type",
1561 NULL},
1562 {"client_streaming", PyUpb_MethodDescriptor_GetClientStreaming, NULL,
1563 "Client streaming", NULL},
1564 {"server_streaming", PyUpb_MethodDescriptor_GetServerStreaming, NULL,
1565 "Server streaming", NULL},
1566 {NULL}};
1567
1568 static PyMethodDef PyUpb_MethodDescriptor_Methods[] = {
1569 {"GetOptions", PyUpb_MethodDescriptor_GetOptions, METH_NOARGS},
1570 {"_GetFeatures", PyUpb_MethodDescriptor_GetFeatures, METH_NOARGS},
1571 {"CopyToProto", PyUpb_MethodDescriptor_CopyToProto, METH_O},
1572 {NULL}};
1573
1574 static PyType_Slot PyUpb_MethodDescriptor_Slots[] = {
1575 DESCRIPTOR_BASE_SLOTS,
1576 {Py_tp_methods, PyUpb_MethodDescriptor_Methods},
1577 {Py_tp_getset, PyUpb_MethodDescriptor_Getters},
1578 {0, NULL}};
1579
1580 static PyType_Spec PyUpb_MethodDescriptor_Spec = {
1581 PYUPB_MODULE_NAME ".MethodDescriptor", // tp_name
1582 sizeof(PyUpb_DescriptorBase), // tp_basicsize
1583 0, // tp_itemsize
1584 Py_TPFLAGS_DEFAULT, // tp_flags
1585 PyUpb_MethodDescriptor_Slots,
1586 };
1587
1588 // -----------------------------------------------------------------------------
1589 // OneofDescriptor
1590 // -----------------------------------------------------------------------------
1591
PyUpb_OneofDescriptor_GetDef(PyObject * _self)1592 const upb_OneofDef* PyUpb_OneofDescriptor_GetDef(PyObject* _self) {
1593 PyUpb_DescriptorBase* self =
1594 PyUpb_DescriptorBase_Check(_self, kPyUpb_OneofDescriptor);
1595 return self ? self->def : NULL;
1596 }
1597
PyUpb_OneofDescriptor_Get(const upb_OneofDef * oneof)1598 PyObject* PyUpb_OneofDescriptor_Get(const upb_OneofDef* oneof) {
1599 const upb_FileDef* file =
1600 upb_MessageDef_File(upb_OneofDef_ContainingType(oneof));
1601 return PyUpb_DescriptorBase_Get(kPyUpb_OneofDescriptor, oneof, file);
1602 }
1603
PyUpb_OneofDescriptor_GetName(PyObject * self,void * closure)1604 static PyObject* PyUpb_OneofDescriptor_GetName(PyObject* self, void* closure) {
1605 const upb_OneofDef* oneof = PyUpb_OneofDescriptor_GetDef(self);
1606 return PyUnicode_FromString(upb_OneofDef_Name(oneof));
1607 }
1608
PyUpb_OneofDescriptor_GetFullName(PyObject * self,void * closure)1609 static PyObject* PyUpb_OneofDescriptor_GetFullName(PyObject* self,
1610 void* closure) {
1611 const upb_OneofDef* oneof = PyUpb_OneofDescriptor_GetDef(self);
1612 return PyUnicode_FromFormat(
1613 "%s.%s", upb_MessageDef_FullName(upb_OneofDef_ContainingType(oneof)),
1614 upb_OneofDef_Name(oneof));
1615 }
1616
PyUpb_OneofDescriptor_GetIndex(PyObject * self,void * closure)1617 static PyObject* PyUpb_OneofDescriptor_GetIndex(PyObject* self, void* closure) {
1618 const upb_OneofDef* oneof = PyUpb_OneofDescriptor_GetDef(self);
1619 return PyLong_FromLong(upb_OneofDef_Index(oneof));
1620 }
1621
PyUpb_OneofDescriptor_GetContainingType(PyObject * self,void * closure)1622 static PyObject* PyUpb_OneofDescriptor_GetContainingType(PyObject* self,
1623 void* closure) {
1624 const upb_OneofDef* oneof = PyUpb_OneofDescriptor_GetDef(self);
1625 return PyUpb_Descriptor_Get(upb_OneofDef_ContainingType(oneof));
1626 }
1627
PyUpb_OneofDescriptor_GetHasOptions(PyObject * _self,void * closure)1628 static PyObject* PyUpb_OneofDescriptor_GetHasOptions(PyObject* _self,
1629 void* closure) {
1630 PyUpb_DescriptorBase* self = (void*)_self;
1631 return PyBool_FromLong(upb_OneofDef_HasOptions(self->def));
1632 }
1633
PyUpb_OneofDescriptor_GetFields(PyObject * _self,void * closure)1634 static PyObject* PyUpb_OneofDescriptor_GetFields(PyObject* _self,
1635 void* closure) {
1636 PyUpb_DescriptorBase* self = (void*)_self;
1637 static PyUpb_GenericSequence_Funcs funcs = {
1638 (void*)&upb_OneofDef_FieldCount,
1639 (void*)&upb_OneofDef_Field,
1640 (void*)&PyUpb_FieldDescriptor_Get,
1641 };
1642 return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
1643 }
1644
PyUpb_OneofDescriptor_GetOptions(PyObject * _self,PyObject * args)1645 static PyObject* PyUpb_OneofDescriptor_GetOptions(PyObject* _self,
1646 PyObject* args) {
1647 PyUpb_DescriptorBase* self = (void*)_self;
1648 return PyUpb_DescriptorBase_GetOptions(
1649 &self->options, UPB_UPCAST(upb_OneofDef_Options(self->def)),
1650 &google__protobuf__OneofOptions_msg_init,
1651 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".OneofOptions");
1652 }
1653
PyUpb_OneofDescriptor_GetFeatures(PyObject * _self,PyObject * args)1654 static PyObject* PyUpb_OneofDescriptor_GetFeatures(PyObject* _self,
1655 PyObject* args) {
1656 PyUpb_DescriptorBase* self = (void*)_self;
1657 return PyUpb_DescriptorBase_GetFeatures(
1658 &self->features, UPB_UPCAST(upb_OneofDef_ResolvedFeatures(self->def)));
1659 }
1660
1661 static PyGetSetDef PyUpb_OneofDescriptor_Getters[] = {
1662 {"name", PyUpb_OneofDescriptor_GetName, NULL, "Name"},
1663 {"full_name", PyUpb_OneofDescriptor_GetFullName, NULL, "Full name"},
1664 {"index", PyUpb_OneofDescriptor_GetIndex, NULL, "Index"},
1665 {"containing_type", PyUpb_OneofDescriptor_GetContainingType, NULL,
1666 "Containing type"},
1667 {"has_options", PyUpb_OneofDescriptor_GetHasOptions, NULL, "Has Options"},
1668 {"fields", PyUpb_OneofDescriptor_GetFields, NULL, "Fields"},
1669 {NULL}};
1670
1671 static PyMethodDef PyUpb_OneofDescriptor_Methods[] = {
1672 {"GetOptions", PyUpb_OneofDescriptor_GetOptions, METH_NOARGS},
1673 {"_GetFeatures", PyUpb_OneofDescriptor_GetFeatures, METH_NOARGS},
1674 {NULL}};
1675
1676 static PyType_Slot PyUpb_OneofDescriptor_Slots[] = {
1677 DESCRIPTOR_BASE_SLOTS,
1678 {Py_tp_methods, PyUpb_OneofDescriptor_Methods},
1679 {Py_tp_getset, PyUpb_OneofDescriptor_Getters},
1680 {0, NULL}};
1681
1682 static PyType_Spec PyUpb_OneofDescriptor_Spec = {
1683 PYUPB_MODULE_NAME ".OneofDescriptor", // tp_name
1684 sizeof(PyUpb_DescriptorBase), // tp_basicsize
1685 0, // tp_itemsize
1686 Py_TPFLAGS_DEFAULT, // tp_flags
1687 PyUpb_OneofDescriptor_Slots,
1688 };
1689
1690 // -----------------------------------------------------------------------------
1691 // ServiceDescriptor
1692 // -----------------------------------------------------------------------------
1693
PyUpb_ServiceDescriptor_GetDef(PyObject * _self)1694 const upb_ServiceDef* PyUpb_ServiceDescriptor_GetDef(PyObject* _self) {
1695 PyUpb_DescriptorBase* self =
1696 PyUpb_DescriptorBase_Check(_self, kPyUpb_ServiceDescriptor);
1697 return self ? self->def : NULL;
1698 }
1699
PyUpb_ServiceDescriptor_Get(const upb_ServiceDef * s)1700 PyObject* PyUpb_ServiceDescriptor_Get(const upb_ServiceDef* s) {
1701 const upb_FileDef* file = upb_ServiceDef_File(s);
1702 return PyUpb_DescriptorBase_Get(kPyUpb_ServiceDescriptor, s, file);
1703 }
1704
PyUpb_ServiceDescriptor_GetFullName(PyObject * self,void * closure)1705 static PyObject* PyUpb_ServiceDescriptor_GetFullName(PyObject* self,
1706 void* closure) {
1707 const upb_ServiceDef* s = PyUpb_ServiceDescriptor_GetDef(self);
1708 return PyUnicode_FromString(upb_ServiceDef_FullName(s));
1709 }
1710
PyUpb_ServiceDescriptor_GetName(PyObject * self,void * closure)1711 static PyObject* PyUpb_ServiceDescriptor_GetName(PyObject* self,
1712 void* closure) {
1713 const upb_ServiceDef* s = PyUpb_ServiceDescriptor_GetDef(self);
1714 return PyUnicode_FromString(upb_ServiceDef_Name(s));
1715 }
1716
PyUpb_ServiceDescriptor_GetFile(PyObject * self,void * closure)1717 static PyObject* PyUpb_ServiceDescriptor_GetFile(PyObject* self,
1718 void* closure) {
1719 const upb_ServiceDef* s = PyUpb_ServiceDescriptor_GetDef(self);
1720 return PyUpb_FileDescriptor_Get(upb_ServiceDef_File(s));
1721 }
1722
PyUpb_ServiceDescriptor_GetIndex(PyObject * self,void * closure)1723 static PyObject* PyUpb_ServiceDescriptor_GetIndex(PyObject* self,
1724 void* closure) {
1725 const upb_ServiceDef* s = PyUpb_ServiceDescriptor_GetDef(self);
1726 return PyLong_FromLong(upb_ServiceDef_Index(s));
1727 }
1728
PyUpb_ServiceDescriptor_GetMethods(PyObject * _self,void * closure)1729 static PyObject* PyUpb_ServiceDescriptor_GetMethods(PyObject* _self,
1730 void* closure) {
1731 PyUpb_DescriptorBase* self = (void*)_self;
1732 static PyUpb_GenericSequence_Funcs funcs = {
1733 (void*)&upb_ServiceDef_MethodCount,
1734 (void*)&upb_ServiceDef_Method,
1735 (void*)&PyUpb_MethodDescriptor_Get,
1736 };
1737 return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
1738 }
1739
PyUpb_ServiceDescriptor_GetMethodsByName(PyObject * _self,void * closure)1740 static PyObject* PyUpb_ServiceDescriptor_GetMethodsByName(PyObject* _self,
1741 void* closure) {
1742 static PyUpb_ByNameMap_Funcs funcs = {
1743 {
1744 (void*)&upb_ServiceDef_MethodCount,
1745 (void*)&upb_ServiceDef_Method,
1746 (void*)&PyUpb_MethodDescriptor_Get,
1747 },
1748 (void*)&upb_ServiceDef_FindMethodByName,
1749 (void*)&upb_MethodDef_Name,
1750 };
1751 PyUpb_DescriptorBase* self = (void*)_self;
1752 return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
1753 }
1754
PyUpb_ServiceDescriptor_GetOptions(PyObject * _self,PyObject * args)1755 static PyObject* PyUpb_ServiceDescriptor_GetOptions(PyObject* _self,
1756 PyObject* args) {
1757 PyUpb_DescriptorBase* self = (void*)_self;
1758 return PyUpb_DescriptorBase_GetOptions(
1759 &self->options, UPB_UPCAST(upb_ServiceDef_Options(self->def)),
1760 &google__protobuf__ServiceOptions_msg_init,
1761 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".ServiceOptions");
1762 }
1763
PyUpb_ServiceDescriptor_GetFeatures(PyObject * _self,PyObject * args)1764 static PyObject* PyUpb_ServiceDescriptor_GetFeatures(PyObject* _self,
1765 PyObject* args) {
1766 PyUpb_DescriptorBase* self = (void*)_self;
1767 return PyUpb_DescriptorBase_GetFeatures(
1768 &self->features, UPB_UPCAST(upb_ServiceDef_ResolvedFeatures(self->def)));
1769 }
1770
PyUpb_ServiceDescriptor_CopyToProto(PyObject * _self,PyObject * py_proto)1771 static PyObject* PyUpb_ServiceDescriptor_CopyToProto(PyObject* _self,
1772 PyObject* py_proto) {
1773 return PyUpb_DescriptorBase_CopyToProto(
1774 _self, (PyUpb_ToProto_Func*)&upb_ServiceDef_ToProto,
1775 &google__protobuf__ServiceDescriptorProto_msg_init,
1776 PYUPB_DESCRIPTOR_PROTO_PACKAGE ".ServiceDescriptorProto", py_proto);
1777 }
1778
PyUpb_ServiceDescriptor_FindMethodByName(PyObject * _self,PyObject * py_name)1779 static PyObject* PyUpb_ServiceDescriptor_FindMethodByName(PyObject* _self,
1780 PyObject* py_name) {
1781 PyUpb_DescriptorBase* self = (void*)_self;
1782 const char* name = PyUnicode_AsUTF8AndSize(py_name, NULL);
1783 if (!name) return NULL;
1784 const upb_MethodDef* method =
1785 upb_ServiceDef_FindMethodByName(self->def, name);
1786 if (method == NULL) {
1787 return PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
1788 }
1789 return PyUpb_MethodDescriptor_Get(method);
1790 }
1791
1792 static PyGetSetDef PyUpb_ServiceDescriptor_Getters[] = {
1793 {"name", PyUpb_ServiceDescriptor_GetName, NULL, "Name", NULL},
1794 {"full_name", PyUpb_ServiceDescriptor_GetFullName, NULL, "Full name", NULL},
1795 {"file", PyUpb_ServiceDescriptor_GetFile, NULL, "File descriptor"},
1796 {"index", PyUpb_ServiceDescriptor_GetIndex, NULL, "Index", NULL},
1797 {"methods", PyUpb_ServiceDescriptor_GetMethods, NULL, "Methods", NULL},
1798 {"methods_by_name", PyUpb_ServiceDescriptor_GetMethodsByName, NULL,
1799 "Methods by name", NULL},
1800 {NULL}};
1801
1802 static PyMethodDef PyUpb_ServiceDescriptor_Methods[] = {
1803 {"GetOptions", PyUpb_ServiceDescriptor_GetOptions, METH_NOARGS},
1804 {"_GetFeatures", PyUpb_ServiceDescriptor_GetFeatures, METH_NOARGS},
1805 {"CopyToProto", PyUpb_ServiceDescriptor_CopyToProto, METH_O},
1806 {"FindMethodByName", PyUpb_ServiceDescriptor_FindMethodByName, METH_O},
1807 {NULL}};
1808
1809 static PyType_Slot PyUpb_ServiceDescriptor_Slots[] = {
1810 DESCRIPTOR_BASE_SLOTS,
1811 {Py_tp_methods, PyUpb_ServiceDescriptor_Methods},
1812 {Py_tp_getset, PyUpb_ServiceDescriptor_Getters},
1813 {0, NULL}};
1814
1815 static PyType_Spec PyUpb_ServiceDescriptor_Spec = {
1816 PYUPB_MODULE_NAME ".ServiceDescriptor", // tp_name
1817 sizeof(PyUpb_DescriptorBase), // tp_basicsize
1818 0, // tp_itemsize
1819 Py_TPFLAGS_DEFAULT, // tp_flags
1820 PyUpb_ServiceDescriptor_Slots,
1821 };
1822
1823 // -----------------------------------------------------------------------------
1824 // Top Level
1825 // -----------------------------------------------------------------------------
1826
PyUpb_SetIntAttr(PyObject * obj,const char * name,int val)1827 static bool PyUpb_SetIntAttr(PyObject* obj, const char* name, int val) {
1828 PyObject* num = PyLong_FromLong(val);
1829 if (!num) return false;
1830 int status = PyObject_SetAttrString(obj, name, num);
1831 Py_DECREF(num);
1832 return status >= 0;
1833 }
1834
1835 // These must be in the same order as PyUpb_DescriptorType in the header.
1836 static PyType_Spec* desc_specs[] = {
1837 &PyUpb_Descriptor_Spec, &PyUpb_EnumDescriptor_Spec,
1838 &PyUpb_EnumValueDescriptor_Spec, &PyUpb_FieldDescriptor_Spec,
1839 &PyUpb_FileDescriptor_Spec, &PyUpb_MethodDescriptor_Spec,
1840 &PyUpb_OneofDescriptor_Spec, &PyUpb_ServiceDescriptor_Spec,
1841 };
1842
PyUpb_InitDescriptor(PyObject * m)1843 bool PyUpb_InitDescriptor(PyObject* m) {
1844 PyUpb_ModuleState* s = PyUpb_ModuleState_GetFromModule(m);
1845
1846 for (size_t i = 0; i < kPyUpb_Descriptor_Count; i++) {
1847 s->descriptor_types[i] = PyUpb_AddClass(m, desc_specs[i]);
1848 if (!s->descriptor_types[i]) {
1849 return false;
1850 }
1851 }
1852
1853 PyObject* fd = (PyObject*)s->descriptor_types[kPyUpb_FieldDescriptor];
1854 return PyUpb_SetIntAttr(fd, "LABEL_OPTIONAL", kUpb_Label_Optional) &&
1855 PyUpb_SetIntAttr(fd, "LABEL_REPEATED", kUpb_Label_Repeated) &&
1856 PyUpb_SetIntAttr(fd, "LABEL_REQUIRED", kUpb_Label_Required) &&
1857 PyUpb_SetIntAttr(fd, "TYPE_BOOL", kUpb_FieldType_Bool) &&
1858 PyUpb_SetIntAttr(fd, "TYPE_BYTES", kUpb_FieldType_Bytes) &&
1859 PyUpb_SetIntAttr(fd, "TYPE_DOUBLE", kUpb_FieldType_Double) &&
1860 PyUpb_SetIntAttr(fd, "TYPE_ENUM", kUpb_FieldType_Enum) &&
1861 PyUpb_SetIntAttr(fd, "TYPE_FIXED32", kUpb_FieldType_Fixed32) &&
1862 PyUpb_SetIntAttr(fd, "TYPE_FIXED64", kUpb_FieldType_Fixed64) &&
1863 PyUpb_SetIntAttr(fd, "TYPE_FLOAT", kUpb_FieldType_Float) &&
1864 PyUpb_SetIntAttr(fd, "TYPE_GROUP", kUpb_FieldType_Group) &&
1865 PyUpb_SetIntAttr(fd, "TYPE_INT32", kUpb_FieldType_Int32) &&
1866 PyUpb_SetIntAttr(fd, "TYPE_INT64", kUpb_FieldType_Int64) &&
1867 PyUpb_SetIntAttr(fd, "TYPE_MESSAGE", kUpb_FieldType_Message) &&
1868 PyUpb_SetIntAttr(fd, "TYPE_SFIXED32", kUpb_FieldType_SFixed32) &&
1869 PyUpb_SetIntAttr(fd, "TYPE_SFIXED64", kUpb_FieldType_SFixed64) &&
1870 PyUpb_SetIntAttr(fd, "TYPE_SINT32", kUpb_FieldType_SInt32) &&
1871 PyUpb_SetIntAttr(fd, "TYPE_SINT64", kUpb_FieldType_SInt64) &&
1872 PyUpb_SetIntAttr(fd, "TYPE_STRING", kUpb_FieldType_String) &&
1873 PyUpb_SetIntAttr(fd, "TYPE_UINT32", kUpb_FieldType_UInt32) &&
1874 PyUpb_SetIntAttr(fd, "TYPE_UINT64", kUpb_FieldType_UInt64) &&
1875 PyUpb_SetIntAttr(fd, "CPPTYPE_INT32", CPPTYPE_INT32) &&
1876 PyUpb_SetIntAttr(fd, "CPPTYPE_INT64", CPPTYPE_INT64) &&
1877 PyUpb_SetIntAttr(fd, "CPPTYPE_UINT32", CPPTYPE_UINT32) &&
1878 PyUpb_SetIntAttr(fd, "CPPTYPE_UINT64", CPPTYPE_UINT64) &&
1879 PyUpb_SetIntAttr(fd, "CPPTYPE_DOUBLE", CPPTYPE_DOUBLE) &&
1880 PyUpb_SetIntAttr(fd, "CPPTYPE_FLOAT", CPPTYPE_FLOAT) &&
1881 PyUpb_SetIntAttr(fd, "CPPTYPE_BOOL", CPPTYPE_BOOL) &&
1882 PyUpb_SetIntAttr(fd, "CPPTYPE_ENUM", CPPTYPE_ENUM) &&
1883 PyUpb_SetIntAttr(fd, "CPPTYPE_STRING", CPPTYPE_STRING) &&
1884 PyUpb_SetIntAttr(fd, "CPPTYPE_BYTES", CPPTYPE_STRING) &&
1885 PyUpb_SetIntAttr(fd, "CPPTYPE_MESSAGE", CPPTYPE_MESSAGE);
1886 }
1887