Fasttable: Fix overly strict assert.

PiperOrigin-RevId: 969873676
diff --git a/upb/wire/decode_fast/field_extension.c b/upb/wire/decode_fast/field_extension.c
index 0f10ef6..aaef874 100644
--- a/upb/wire/decode_fast/field_extension.c
+++ b/upb/wire/decode_fast/field_extension.c
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include "upb/base/descriptor_constants.h"
 #include "upb/message/message.h"
 #include "upb/mini_table/extension_registry.h"
 #include "upb/mini_table/field.h"
@@ -35,12 +36,19 @@
   }
 
   // Assert that the field is either truly unknown, has a mismatched wire
-  // type, or is an overlong tag.
+  // type, is a long tag (field_num >= 2048), is an overlong tag, or is an
+  // unlinked submessage field.
 #ifndef NDEBUG
   const upb_MiniTableField* field =
       upb_MiniTable_FindFieldByNumber(table, field_num);
-  UPB_ASSERT((tag & 0xFF80) == 0x80 || field == NULL ||
-             _upb_MiniTableField_GetWireType(field) != (tag & 0x07));
+  bool long_tag = (tag & 0xFF80) == 0x80 || (tag & 0x8080) == 0x8080;
+  bool mismatched_wire_type =
+      field != NULL && _upb_MiniTableField_GetWireType(field) != (tag & 0x07);
+  bool unlinked_submessage =
+      field != NULL && upb_MiniTableField_CType(field) == kUpb_CType_Message &&
+      upb_MiniTable_GetSubMessageTable(field) == NULL;
+  UPB_ASSERT(long_tag || field == NULL || mismatched_wire_type ||
+             unlinked_submessage);
 #endif
 
   if (d->extreg && upb_ExtensionRegistry_Lookup(d->extreg, table, field_num)) {