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) {