Add new unknown fields API to support noncontiguous storage. Currently shares the same implementation as the existing unknown fields API.

PiperOrigin-RevId: 694241076
diff --git a/upb/message/message.c b/upb/message/message.c
index 5bb14e7..daeeef1 100644
--- a/upb/message/message.c
+++ b/upb/message/message.c
@@ -11,6 +11,7 @@
 #include <stdint.h>
 #include <string.h>
 
+#include "upb/base/string_view.h"
 #include "upb/mem/arena.h"
 #include "upb/message/accessors.h"
 #include "upb/message/array.h"
@@ -52,6 +53,21 @@
   }
 }
 
+bool upb_Message_NextUnknown(const upb_Message* msg, upb_StringView* data,
+                             uintptr_t* iter) {
+  upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
+  if (in && *iter == kUpb_Message_UnknownBegin) {
+    data->size = in->unknown_end - message_overhead;
+    data->data = (char*)(in + 1);
+    (*iter)++;
+    return true;
+  } else {
+    data->size = 0;
+    data->data = NULL;
+    return false;
+  }
+}
+
 const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len) {
   upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
   if (in) {
diff --git a/upb/message/message.h b/upb/message/message.h
index 50388fc..46f7d73 100644
--- a/upb/message/message.h
+++ b/upb/message/message.h
@@ -13,7 +13,9 @@
 #define UPB_MESSAGE_MESSAGE_H_
 
 #include <stddef.h>
+#include <stdint.h>
 
+#include "upb/base/string_view.h"
 #include "upb/mem/arena.h"
 #include "upb/message/internal/message.h"
 #include "upb/message/internal/types.h"
@@ -31,6 +33,21 @@
 // Creates a new message with the given mini_table on the given arena.
 UPB_API upb_Message* upb_Message_New(const upb_MiniTable* m, upb_Arena* arena);
 
+//
+// Unknown data may be stored non-contiguously. Each segment stores a block of
+// unknown fields. To iterate over segments:
+//
+//   uintptr_t iter = kUpb_Message_UnknownBegin;
+//   upb_StringView data;
+//   while (upb_Message_NextUnknown(msg, &data, &iter)) {
+//     // Use data
+//   }
+
+#define kUpb_Message_UnknownBegin 0
+
+bool upb_Message_NextUnknown(const upb_Message* msg, upb_StringView* data,
+                             uintptr_t* iter);
+
 // Returns a reference to the message's unknown data.
 const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len);