Make SetField/GetField public and operate on MessageValue instead of void*.

PiperOrigin-RevId: 584309590
diff --git a/upb/message/BUILD b/upb/message/BUILD
index 2640868..05fa825 100644
--- a/upb/message/BUILD
+++ b/upb/message/BUILD
@@ -35,6 +35,7 @@
         "//upb:base",
         "//upb:eps_copy_input_stream",
         "//upb:mem",
+        "//upb:message_types",
         "//upb:mini_table",
         "//upb:mini_table_internal",
         "//upb:port",
diff --git a/upb/message/accessors.c b/upb/message/accessors.c
index 25c0f9e..70a60a0 100644
--- a/upb/message/accessors.c
+++ b/upb/message/accessors.c
@@ -7,15 +7,15 @@
 
 #include "upb/message/accessors.h"
 
+#include <string.h>
+
+#include "upb/mem/arena.h"
 #include "upb/message/array.h"
-#include "upb/message/internal/array.h"
 #include "upb/message/map.h"
 #include "upb/message/message.h"
 #include "upb/mini_table/field.h"
-#include "upb/wire/decode.h"
+#include "upb/mini_table/message.h"
 #include "upb/wire/encode.h"
-#include "upb/wire/eps_copy_input_stream.h"
-#include "upb/wire/reader.h"
 
 // Must be last.
 #include "upb/port/def.inc"
@@ -37,12 +37,10 @@
   // hence assuming a zero default is valid.
   upb_MessageValue default_val;
   memset(&default_val, 0, sizeof(upb_MessageValue));
-  upb_MessageValue map_entry_key;
-  upb_MessageValue map_entry_value;
-  _upb_Message_GetField(map_entry_message, map_entry_key_field, &default_val,
-                        &map_entry_key);
-  _upb_Message_GetField(map_entry_message, map_entry_value_field, &default_val,
-                        &map_entry_value);
+  upb_MessageValue map_entry_key =
+      upb_Message_GetField(map_entry_message, map_entry_key_field, default_val);
+  upb_MessageValue map_entry_value = upb_Message_GetField(
+      map_entry_message, map_entry_value_field, default_val);
   return upb_Map_Insert(map, map_entry_key, map_entry_value, arena);
 }
 
diff --git a/upb/message/accessors.h b/upb/message/accessors.h
index 3a23f2f..3a4d6dc 100644
--- a/upb/message/accessors.h
+++ b/upb/message/accessors.h
@@ -8,17 +8,29 @@
 #ifndef UPB_MESSAGE_ACCESSORS_H_
 #define UPB_MESSAGE_ACCESSORS_H_
 
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
 #include "upb/base/descriptor_constants.h"
+#include "upb/base/string_view.h"
+#include "upb/mem/arena.h"
 #include "upb/message/array.h"
 #include "upb/message/internal/accessors.h"
 #include "upb/message/internal/array.h"
 #include "upb/message/internal/map.h"
 #include "upb/message/internal/message.h"
+#include "upb/message/internal/types.h"
 #include "upb/message/map.h"
+#include "upb/message/tagged_ptr.h"
+#include "upb/message/types.h"
 #include "upb/mini_table/enum.h"
+#include "upb/mini_table/extension.h"
 #include "upb/mini_table/field.h"
 
 // Must be last.
+#include "upb/mini_table/internal/field.h"
+#include "upb/mini_table/message.h"
 #include "upb/port/def.inc"
 
 #ifdef __cplusplus
@@ -58,15 +70,45 @@
   return _upb_Message_GetOneofCase(message, oneof_field);
 }
 
+// NOTE: The default_val is only used for fields that support presence.
+// For repeated/map fields, the resulting upb_Array*/upb_Map* can be NULL if a
+// upb_Array/upb_Map has not been allocated yet. Array/map fields do not have
+// presence, so this is semantically identical to a pointer to an empty
+// array/map, and must be treated the same for all semantic purposes.
+UPB_INLINE upb_MessageValue
+upb_Message_GetField(const upb_Message* msg, const upb_MiniTableField* field,
+                     upb_MessageValue default_val) {
+  upb_MessageValue ret;
+  if (upb_MiniTableField_IsExtension(field)) {
+    _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field,
+                                   &default_val, &ret);
+  } else {
+    _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret);
+  }
+  return ret;
+}
+
+UPB_INLINE bool upb_Message_SetField(upb_Message* msg,
+                                     const upb_MiniTableField* field,
+                                     upb_MessageValue val, upb_Arena* a) {
+  if (upb_MiniTableField_IsExtension(field)) {
+    const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)field;
+    return _upb_Message_SetExtensionField(msg, ext, &val, a);
+  } else {
+    _upb_Message_SetNonExtensionField(msg, field, &val);
+    return true;
+  }
+}
+
 UPB_API_INLINE bool upb_Message_GetBool(const upb_Message* msg,
                                         const upb_MiniTableField* field,
                                         bool default_val) {
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Bool);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  bool ret;
-  _upb_Message_GetField(msg, field, &default_val, &ret);
-  return ret;
+  upb_MessageValue def;
+  def.bool_val = default_val;
+  return upb_Message_GetField(msg, field, def).bool_val;
 }
 
 UPB_API_INLINE bool upb_Message_SetBool(upb_Message* msg,
@@ -75,7 +117,9 @@
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Bool);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  return _upb_Message_SetField(msg, field, &value, a);
+  upb_MessageValue val;
+  val.bool_val = value;
+  return upb_Message_SetField(msg, field, val, a);
 }
 
 UPB_API_INLINE int32_t upb_Message_GetInt32(const upb_Message* msg,
@@ -85,9 +129,10 @@
              upb_MiniTableField_CType(field) == kUpb_CType_Enum);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  int32_t ret;
-  _upb_Message_GetField(msg, field, &default_val, &ret);
-  return ret;
+
+  upb_MessageValue def;
+  def.int32_val = default_val;
+  return upb_Message_GetField(msg, field, def).int32_val;
 }
 
 UPB_API_INLINE bool upb_Message_SetInt32(upb_Message* msg,
@@ -97,7 +142,9 @@
              upb_MiniTableField_CType(field) == kUpb_CType_Enum);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  return _upb_Message_SetField(msg, field, &value, a);
+  upb_MessageValue val;
+  val.int32_val = value;
+  return upb_Message_SetField(msg, field, val, a);
 }
 
 UPB_API_INLINE uint32_t upb_Message_GetUInt32(const upb_Message* msg,
@@ -106,9 +153,10 @@
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt32);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  uint32_t ret;
-  _upb_Message_GetField(msg, field, &default_val, &ret);
-  return ret;
+
+  upb_MessageValue def;
+  def.uint32_val = default_val;
+  return upb_Message_GetField(msg, field, def).uint32_val;
 }
 
 UPB_API_INLINE bool upb_Message_SetUInt32(upb_Message* msg,
@@ -117,7 +165,9 @@
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt32);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  return _upb_Message_SetField(msg, field, &value, a);
+  upb_MessageValue val;
+  val.uint32_val = value;
+  return upb_Message_SetField(msg, field, val, a);
 }
 
 UPB_API_INLINE void upb_Message_SetClosedEnum(
@@ -133,13 +183,14 @@
 
 UPB_API_INLINE int64_t upb_Message_GetInt64(const upb_Message* msg,
                                             const upb_MiniTableField* field,
-                                            uint64_t default_val) {
+                                            int64_t default_val) {
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int64);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  int64_t ret;
-  _upb_Message_GetField(msg, field, &default_val, &ret);
-  return ret;
+
+  upb_MessageValue def;
+  def.int64_val = default_val;
+  return upb_Message_GetField(msg, field, def).int64_val;
 }
 
 UPB_API_INLINE bool upb_Message_SetInt64(upb_Message* msg,
@@ -148,7 +199,9 @@
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int64);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  return _upb_Message_SetField(msg, field, &value, a);
+  upb_MessageValue val;
+  val.int64_val = value;
+  return upb_Message_SetField(msg, field, val, a);
 }
 
 UPB_API_INLINE uint64_t upb_Message_GetUInt64(const upb_Message* msg,
@@ -157,9 +210,10 @@
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt64);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  uint64_t ret;
-  _upb_Message_GetField(msg, field, &default_val, &ret);
-  return ret;
+
+  upb_MessageValue def;
+  def.uint64_val = default_val;
+  return upb_Message_GetField(msg, field, def).uint64_val;
 }
 
 UPB_API_INLINE bool upb_Message_SetUInt64(upb_Message* msg,
@@ -168,7 +222,9 @@
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt64);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  return _upb_Message_SetField(msg, field, &value, a);
+  upb_MessageValue val;
+  val.uint64_val = value;
+  return upb_Message_SetField(msg, field, val, a);
 }
 
 UPB_API_INLINE float upb_Message_GetFloat(const upb_Message* msg,
@@ -177,9 +233,10 @@
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Float);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  float ret;
-  _upb_Message_GetField(msg, field, &default_val, &ret);
-  return ret;
+
+  upb_MessageValue def;
+  def.float_val = default_val;
+  return upb_Message_GetField(msg, field, def).float_val;
 }
 
 UPB_API_INLINE bool upb_Message_SetFloat(upb_Message* msg,
@@ -188,7 +245,9 @@
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Float);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  return _upb_Message_SetField(msg, field, &value, a);
+  upb_MessageValue val;
+  val.float_val = value;
+  return upb_Message_SetField(msg, field, val, a);
 }
 
 UPB_API_INLINE double upb_Message_GetDouble(const upb_Message* msg,
@@ -197,9 +256,10 @@
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Double);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  double ret;
-  _upb_Message_GetField(msg, field, &default_val, &ret);
-  return ret;
+
+  upb_MessageValue def;
+  def.double_val = default_val;
+  return upb_Message_GetField(msg, field, def).double_val;
 }
 
 UPB_API_INLINE bool upb_Message_SetDouble(upb_Message* msg,
@@ -208,19 +268,22 @@
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Double);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  return _upb_Message_SetField(msg, field, &value, a);
+  upb_MessageValue val;
+  val.double_val = value;
+  return upb_Message_SetField(msg, field, val, a);
 }
 
 UPB_API_INLINE upb_StringView
 upb_Message_GetString(const upb_Message* msg, const upb_MiniTableField* field,
-                      upb_StringView def_val) {
+                      upb_StringView default_val) {
   UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_String ||
              upb_MiniTableField_CType(field) == kUpb_CType_Bytes);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_StringView);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  upb_StringView ret;
-  _upb_Message_GetField(msg, field, &def_val, &ret);
-  return ret;
+
+  upb_MessageValue def;
+  def.str_val = default_val;
+  return upb_Message_GetField(msg, field, def).str_val;
 }
 
 UPB_API_INLINE bool upb_Message_SetString(upb_Message* msg,
@@ -230,7 +293,9 @@
              upb_MiniTableField_CType(field) == kUpb_CType_Bytes);
   UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_StringView);
   UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
-  return _upb_Message_SetField(msg, field, &value, a);
+  upb_MessageValue val;
+  val.str_val = value;
+  return upb_Message_SetField(msg, field, val, a);
 }
 
 UPB_API_INLINE upb_TaggedMessagePtr upb_Message_GetTaggedMessagePtr(
@@ -316,7 +381,9 @@
     array = _upb_Array_New(arena, 4, _upb_MiniTable_ElementSizeLg2(field));
     // Check again due to: https://godbolt.org/z/7WfaoKG1r
     _upb_MiniTableField_CheckIsArray(field);
-    _upb_Message_SetField(msg, field, &array, arena);
+    upb_MessageValue val;
+    val.array_val = array;
+    upb_Message_SetField(msg, field, val, arena);
   }
   return array;
 }
diff --git a/upb/message/internal/accessors.h b/upb/message/internal/accessors.h
index aa39009..fcf4f90 100644
--- a/upb/message/internal/accessors.h
+++ b/upb/message/internal/accessors.h
@@ -15,6 +15,7 @@
 #include "upb/base/descriptor_constants.h"
 #include "upb/base/string_view.h"
 #include "upb/mem/arena.h"
+#include "upb/message/array.h"
 #include "upb/message/internal/extension.h"
 #include "upb/message/internal/map.h"
 #include "upb/message/internal/message.h"
@@ -214,7 +215,7 @@
 //     UPB_ASSUME(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bool);
 //     UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field));
 //     UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte);
-//     _upb_Message_SetField(msg, field, &value, a);
+//     upb_Message_SetField(msg, field, &value, a);
 //   }
 //
 // As a result, we can use these universal getters/setters for *all* message
@@ -269,15 +270,31 @@
   }
 }
 
-UPB_INLINE void _upb_Message_GetField(const upb_Message* msg,
-                                      const upb_MiniTableField* field,
-                                      const void* default_val, void* val) {
+// Gets a mutable Array, Map or Message field.
+// NOTE: For repeated/map fields, the resulting upb_Array*/upb_Map* can
+// be NULL if a upb_Array/upb_Map has not been allocated yet. Array/map
+// fields do not have presence, so this is semantically identical to a
+// pointer to an empty array/map, and must be treated the same for all
+// semantic purposes.
+//
+// For message fields, the pointer is guaranteed to be NULL iff the field
+// is unset (as message fields do have presence).
+UPB_INLINE upb_MutableMessageValue _upb_Message_GetMutableField(
+    const upb_Message* msg, const upb_MiniTableField* field) {
+  UPB_ASSUME(upb_MiniTableField_IsRepeatedOrMap(field) ||
+             upb_MiniTableField_IsSubMessage(field));
+
+  upb_MutableMessageValue default_val;
+  default_val.msg = NULL;
+
+  upb_MutableMessageValue ret;
   if (upb_MiniTableField_IsExtension(field)) {
     _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field,
-                                   default_val, val);
+                                   &default_val, &ret);
   } else {
-    _upb_Message_GetNonExtensionField(msg, field, default_val, val);
+    _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret);
   }
+  return ret;
 }
 
 UPB_INLINE void _upb_Message_SetNonExtensionField(
@@ -299,18 +316,6 @@
   return true;
 }
 
-UPB_INLINE bool _upb_Message_SetField(upb_Message* msg,
-                                      const upb_MiniTableField* field,
-                                      const void* val, upb_Arena* a) {
-  if (upb_MiniTableField_IsExtension(field)) {
-    const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)field;
-    return _upb_Message_SetExtensionField(msg, ext, val, a);
-  } else {
-    _upb_Message_SetNonExtensionField(msg, field, val);
-    return true;
-  }
-}
-
 UPB_INLINE void _upb_Message_ClearExtensionField(
     upb_Message* msg, const upb_MiniTableExtension* ext_l) {
   upb_Message_Internal* in = upb_Message_Getinternal(msg);
diff --git a/upb/reflection/message.c b/upb/reflection/message.c
index dc014ae..2d41a95 100644
--- a/upb/reflection/message.c
+++ b/upb/reflection/message.c
@@ -47,9 +47,7 @@
 upb_MessageValue upb_Message_GetFieldByDef(const upb_Message* msg,
                                            const upb_FieldDef* f) {
   upb_MessageValue default_val = upb_FieldDef_Default(f);
-  upb_MessageValue ret;
-  _upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), &default_val, &ret);
-  return ret;
+  return upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), default_val);
 }
 
 upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg,
@@ -93,7 +91,7 @@
 
 bool upb_Message_SetFieldByDef(upb_Message* msg, const upb_FieldDef* f,
                                upb_MessageValue val, upb_Arena* a) {
-  return _upb_Message_SetField(msg, upb_FieldDef_MiniTable(f), &val, a);
+  return upb_Message_SetField(msg, upb_FieldDef_MiniTable(f), val, a);
 }
 
 void upb_Message_ClearFieldByDef(upb_Message* msg, const upb_FieldDef* f) {