• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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