@@ -213,6 +213,25 @@ PyObject* PyUpb_Descriptor_Get(const upb_MessageDef* m) {
213
213
214
214
PyObject * PyUpb_Descriptor_GetClass (const upb_MessageDef * m ) {
215
215
PyObject * ret = PyUpb_ObjCache_Get (upb_MessageDef_MiniTable (m ));
216
+ if (ret ) return ret ;
217
+
218
+ // On demand create the clss if not exist. However, if users repeatedly
219
+ // create and destroy a class, it could trigger a loop. This is not an
220
+ // issue now, but if we see CPU waste for repeatedly create and destroy
221
+ // in the future, we could make PyUpb_Descriptor_Get() append the descriptor
222
+ // to an internal list in DescriptorPool, let the pool keep descriptors alive.
223
+ PyObject * py_descriptor = PyUpb_Descriptor_Get (m );
224
+ if (py_descriptor == NULL ) return NULL ;
225
+ const char * name = upb_MessageDef_Name (m );
226
+ PyObject * dict = PyDict_New ();
227
+ if (dict == NULL ) goto err ;
228
+ int status = PyDict_SetItemString (dict , "DESCRIPTOR" , py_descriptor );
229
+ if (status < 0 ) goto err ;
230
+ ret = PyUpb_MessageMeta_DoCreateClass (py_descriptor , name , dict );
231
+
232
+ err :
233
+ Py_XDECREF (py_descriptor );
234
+ Py_XDECREF (dict );
216
235
return ret ;
217
236
}
218
237
@@ -477,7 +496,7 @@ static PyObject* PyUpb_Descriptor_GetFullName(PyObject* self, void* closure) {
477
496
static PyObject * PyUpb_Descriptor_GetConcreteClass (PyObject * self ,
478
497
void * closure ) {
479
498
const upb_MessageDef * msgdef = PyUpb_Descriptor_GetDef (self );
480
- return PyUpb_Descriptor_GetClass ( msgdef );
499
+ return PyUpb_ObjCache_Get ( upb_MessageDef_MiniTable ( msgdef ) );
481
500
}
482
501
483
502
static PyObject * PyUpb_Descriptor_GetFile (PyObject * self , void * closure ) {
0 commit comments