Implemented msg.<NAME>_FIELD_NUMBER attributes.
diff --git a/python/message.c b/python/message.c
index cf88bae..45c70e9 100644
--- a/python/message.c
+++ b/python/message.c
@@ -1626,11 +1626,29 @@
ret = PyUpb_FieldDescriptor_Get(ext);
}
- // TODO(haberman): *_FIELD_NUMBER attributes? Haven't seen any failing
- // tests for these yet.
-
Py_DECREF(py_key);
+ const char* suffix = "_FIELD_NUMBER";
+ size_t n = strlen(name_buf);
+ size_t suffix_n = strlen(suffix);
+ if (n > strlen(suffix) &&
+ memcmp(suffix, name_buf + n - suffix_n, suffix_n) == 0) {
+ // We can't look up field names dynamically, because the <NAME>_FIELD_NUMBER
+ // naming scheme upper-cases the field name and is therefore non-reversible.
+ // So we just add all field numbers.
+ int n = upb_msgdef_fieldcount(msgdef);
+ for (int i = 0; i < n; i++) {
+ const upb_fielddef* f = upb_msgdef_field(msgdef, i);
+ PyObject* name = PyUnicode_FromFormat(
+ "%s_FIELD_NUMBER", upb_fielddef_name(f));
+ PyObject* upper = PyObject_CallMethod(name, "upper", "");
+ PyObject_SetAttr(self, upper, PyLong_FromLong(upb_fielddef_number(f)));
+ Py_DECREF(name);
+ Py_DECREF(upper);
+ }
+ ret = PyObject_GenericGetAttr(self, name);
+ }
+
return ret;
}