Auto-generate files after cl/593870914
diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c
index 89a20f3..07f17c3 100644
--- a/ruby/ext/google/protobuf_c/ruby-upb.c
+++ b/ruby/ext/google/protobuf_c/ruby-upb.c
@@ -7936,23 +7936,6 @@
 }
 
 
-#include <stddef.h>
-
-// Must be last.
-
-// A MiniTable for an empty message, used for unlinked sub-messages.
-const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty) = {
-    .UPB_PRIVATE(subs) = NULL,
-    .UPB_PRIVATE(fields) = NULL,
-    .UPB_PRIVATE(size) = 0,
-    .UPB_PRIVATE(field_count) = 0,
-    .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable,
-    .UPB_PRIVATE(dense_below) = 0,
-    .UPB_PRIVATE(table_mask) = -1,
-    .UPB_PRIVATE(required_count) = 0,
-};
-
-
 #include <inttypes.h>
 #include <stddef.h>
 #include <stdint.h>
@@ -8020,6 +8003,106 @@
 }
 
 
+#include <stddef.h>
+#include <stdint.h>
+
+
+// Must be last.
+
+// Checks if source and target mini table fields are identical.
+//
+// If the field is a sub message and sub messages are identical we record
+// the association in table.
+//
+// Hashing the source sub message mini table and it's equivalent in the table
+// stops recursing when a cycle is detected and instead just checks if the
+// destination table is equal.
+static upb_MiniTableEquals_Status upb_deep_check(const upb_MiniTable* src,
+                                                 const upb_MiniTable* dst,
+                                                 upb_inttable* table,
+                                                 upb_Arena** arena) {
+  if (src->UPB_PRIVATE(field_count) != dst->UPB_PRIVATE(field_count))
+    return kUpb_MiniTableEquals_NotEqual;
+  bool marked_src = false;
+  for (int i = 0; i < upb_MiniTable_FieldCount(src); i++) {
+    const upb_MiniTableField* src_field = upb_MiniTable_GetFieldByIndex(src, i);
+    const upb_MiniTableField* dst_field = upb_MiniTable_FindFieldByNumber(
+        dst, upb_MiniTableField_Number(src_field));
+
+    if (upb_MiniTableField_CType(src_field) !=
+        upb_MiniTableField_CType(dst_field))
+      return false;
+    if (src_field->UPB_PRIVATE(mode) != dst_field->UPB_PRIVATE(mode))
+      return false;
+    if (src_field->UPB_PRIVATE(offset) != dst_field->UPB_PRIVATE(offset))
+      return false;
+    if (src_field->presence != dst_field->presence) return false;
+    if (src_field->UPB_PRIVATE(submsg_index) !=
+        dst_field->UPB_PRIVATE(submsg_index))
+      return kUpb_MiniTableEquals_NotEqual;
+
+    // Go no further if we are only checking for compatibility.
+    if (!table) continue;
+
+    if (upb_MiniTableField_CType(src_field) == kUpb_CType_Message) {
+      if (!*arena) {
+        *arena = upb_Arena_New();
+        if (!upb_inttable_init(table, *arena)) {
+          return kUpb_MiniTableEquals_OutOfMemory;
+        }
+      }
+      if (!marked_src) {
+        marked_src = true;
+        upb_value val;
+        val.val = (uint64_t)dst;
+        if (!upb_inttable_insert(table, (uintptr_t)src, val, *arena)) {
+          return kUpb_MiniTableEquals_OutOfMemory;
+        }
+      }
+      const upb_MiniTable* sub_src =
+          upb_MiniTable_GetSubMessageTable(src, src_field);
+      const upb_MiniTable* sub_dst =
+          upb_MiniTable_GetSubMessageTable(dst, dst_field);
+      if (sub_src != NULL) {
+        upb_value cmp;
+        if (upb_inttable_lookup(table, (uintptr_t)sub_src, &cmp)) {
+          // We already compared this src before. Check if same dst.
+          if (cmp.val != (uint64_t)sub_dst) {
+            return kUpb_MiniTableEquals_NotEqual;
+          }
+        } else {
+          // Recurse if not already visited.
+          upb_MiniTableEquals_Status s =
+              upb_deep_check(sub_src, sub_dst, table, arena);
+          if (s != kUpb_MiniTableEquals_Equal) {
+            return s;
+          }
+        }
+      }
+    }
+  }
+  return kUpb_MiniTableEquals_Equal;
+}
+
+bool upb_MiniTable_Compatible(const upb_MiniTable* src,
+                              const upb_MiniTable* dst) {
+  return upb_deep_check(src, dst, NULL, NULL);
+}
+
+upb_MiniTableEquals_Status upb_MiniTable_Equals(const upb_MiniTable* src,
+                                                const upb_MiniTable* dst) {
+  // Arena allocated on demand for hash table.
+  upb_Arena* arena = NULL;
+  // Table to keep track of visited mini tables to guard against cycles.
+  upb_inttable table;
+  upb_MiniTableEquals_Status status = upb_deep_check(src, dst, &table, &arena);
+  if (arena) {
+    upb_Arena_Free(arena);
+  }
+  return status;
+}
+
+
 
 // Must be last.
 
@@ -15308,6 +15391,23 @@
   return ptr;
 }
 
+
+#include <stddef.h>
+
+// Must be last.
+
+// A MiniTable for an empty message, used for unlinked sub-messages.
+const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty) = {
+    .UPB_PRIVATE(subs) = NULL,
+    .UPB_PRIVATE(fields) = NULL,
+    .UPB_PRIVATE(size) = 0,
+    .UPB_PRIVATE(field_count) = 0,
+    .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable,
+    .UPB_PRIVATE(dense_below) = 0,
+    .UPB_PRIVATE(table_mask) = -1,
+    .UPB_PRIVATE(required_count) = 0,
+};
+
 // This should #undef all macros #defined in def.inc
 
 #undef UPB_SIZE
diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h
index 46a568f..244da19 100755
--- a/ruby/ext/google/protobuf_c/ruby-upb.h
+++ b/ruby/ext/google/protobuf_c/ruby-upb.h
@@ -12758,6 +12758,42 @@
 
 #endif /* UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_ */
 
+#ifndef UPB_MINI_TABLE_COMPAT_H_
+#define UPB_MINI_TABLE_COMPAT_H_
+
+
+// Must be last.
+
+// upb does not support mixing minitables from different sources but these
+// functions are still used by some existing users so for now we make them
+// available here. This may or may not change in the future so do not add
+// them to new code.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Checks if memory layout of src is compatible with dst.
+bool upb_MiniTable_Compatible(const upb_MiniTable* src,
+                              const upb_MiniTable* dst);
+
+typedef enum {
+  kUpb_MiniTableEquals_NotEqual,
+  kUpb_MiniTableEquals_Equal,
+  kUpb_MiniTableEquals_OutOfMemory,
+} upb_MiniTableEquals_Status;
+
+// Checks equality of mini tables originating from different language runtimes.
+upb_MiniTableEquals_Status upb_MiniTable_Equals(const upb_MiniTable* src,
+                                                const upb_MiniTable* dst);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+
+#endif /* UPB_MINI_TABLE_COMPAT_H_ */
+
 #ifndef UPB_REFLECTION_DEF_POOL_INTERNAL_H_
 #define UPB_REFLECTION_DEF_POOL_INTERNAL_H_