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