diff --git a/upb/message/accessors.c b/upb/message/accessors.c index a3184a5a21..de142d90d4 100644 --- a/upb/message/accessors.c +++ b/upb/message/accessors.c @@ -24,10 +24,8 @@ bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTable* m, const upb_MiniTableField* f, upb_Message* map_entry_message, upb_Arena* arena) { UPB_ASSERT(!upb_Message_IsFrozen(map_entry_message)); - - // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. - const upb_MiniTable* map_entry_mini_table = upb_MiniTableSub_Message( - m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); + const upb_MiniTable* map_entry_mini_table = + upb_MiniTable_MapEntrySubMessage(m, f); UPB_ASSERT(map_entry_mini_table); const upb_MiniTableField* map_entry_key_field = upb_MiniTable_MapKey(map_entry_mini_table); diff --git a/upb/message/accessors.h b/upb/message/accessors.h index 59ec925d79..09ea66ae5b 100644 --- a/upb/message/accessors.h +++ b/upb/message/accessors.h @@ -22,9 +22,15 @@ #include "upb/message/internal/message.h" #include "upb/message/internal/tagged_ptr.h" #include "upb/message/map.h" +#include "upb/message/message.h" #include "upb/message/tagged_ptr.h" #include "upb/message/value.h" #include "upb/mini_table/enum.h" +#include "upb/mini_table/extension.h" +#include "upb/mini_table/field.h" +#include "upb/mini_table/internal/field.h" +#include "upb/mini_table/internal/message.h" +#include "upb/mini_table/message.h" #include "upb/mini_table/sub.h" // Must be last. @@ -354,8 +360,6 @@ UPB_API_INLINE void _upb_Message_SetTaggedMessagePtr( UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); UPB_ASSUME(upb_MiniTableField_IsScalar(field)); - UPB_ASSERT(upb_MiniTableSub_Message( - mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)])); upb_Message_SetBaseField(msg, field, &sub_message); } @@ -379,8 +383,8 @@ UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage( upb_Message* sub_message = *UPB_PTR_AT(msg, field->UPB_ONLYBITS(offset), upb_Message*); if (!sub_message) { - const upb_MiniTable* sub_mini_table = upb_MiniTableSub_Message( - mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]); + const upb_MiniTable* sub_mini_table = + upb_MiniTable_SubMessage(mini_table, field); UPB_ASSERT(sub_mini_table); sub_message = _upb_Message_New(sub_mini_table, arena); *UPB_PTR_AT(msg, field->UPB_ONLYBITS(offset), upb_Message*) = sub_message; diff --git a/upb/message/copy.c b/upb/message/copy.c index 114b92e018..38cb8494bc 100644 --- a/upb/message/copy.c +++ b/upb/message/copy.c @@ -117,9 +117,8 @@ static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map, const upb_MiniTableField* f, upb_Message* clone, upb_Arena* arena) { - // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. - const upb_MiniTable* map_entry_table = upb_MiniTableSub_Message( - mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); + const upb_MiniTable* map_entry_table = + upb_MiniTable_MapEntrySubMessage(mini_table, f); UPB_ASSERT(map_entry_table); const upb_MiniTableField* key_field = upb_MiniTable_MapKey(map_entry_table); diff --git a/upb/message/promote.c b/upb/message/promote.c index 51412e1781..d4b1ad1dee 100644 --- a/upb/message/promote.c +++ b/upb/message/promote.c @@ -327,12 +327,9 @@ upb_UnknownToMessage_Status upb_MiniTable_PromoteUnknownToMessageArray( upb_UnknownToMessage_Status upb_MiniTable_PromoteUnknownToMap( upb_Message* msg, const upb_MiniTable* mini_table, const upb_MiniTableField* field, int decode_options, upb_Arena* arena) { - // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. - const upb_MiniTable* map_entry_mini_table = upb_MiniTableSub_Message( - mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]); - UPB_ASSERT(map_entry_mini_table); + const upb_MiniTable* map_entry_mini_table = + upb_MiniTable_MapEntrySubMessage(mini_table, field); UPB_ASSERT(upb_MiniTable_FieldCount(map_entry_mini_table) == 2); - UPB_ASSERT(upb_MiniTableField_IsMap(field)); // Find all unknowns with given field number and parse. upb_FindUnknownRet unknown; while (1) { diff --git a/upb/mini_descriptor/internal/encode_test.cc b/upb/mini_descriptor/internal/encode_test.cc index 3ae2f6f56c..a84c739bbc 100644 --- a/upb/mini_descriptor/internal/encode_test.cc +++ b/upb/mini_descriptor/internal/encode_test.cc @@ -45,7 +45,7 @@ TEST_P(MiniTableTest, Empty) { upb_MiniTable* table = _upb_MiniTable_Build(nullptr, 0, GetParam(), arena.ptr(), status.ptr()); ASSERT_NE(nullptr, table); - EXPECT_EQ(0, table->UPB_PRIVATE(field_count)); + EXPECT_EQ(0, upb_MiniTable_FieldCount(table)); EXPECT_EQ(0, table->UPB_PRIVATE(required_count)); } @@ -242,11 +242,11 @@ TEST_P(MiniTableTest, SubsInitializedToEmpty) { upb_MiniTable* table = _upb_MiniTable_Build( e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr()); ASSERT_NE(nullptr, table); - EXPECT_EQ(table->UPB_PRIVATE(field_count), 2); - EXPECT_TRUE(UPB_PRIVATE(_upb_MiniTable_IsEmpty)( - upb_MiniTableSub_Message(table->UPB_PRIVATE(subs)[0]))); - EXPECT_TRUE(UPB_PRIVATE(_upb_MiniTable_IsEmpty)( - upb_MiniTableSub_Message(table->UPB_PRIVATE(subs)[1]))); + EXPECT_EQ(upb_MiniTable_FieldCount(table), 2); + EXPECT_FALSE(upb_MiniTable_FieldIsLinked( + table, upb_MiniTable_GetFieldByIndex(table, 0))); + EXPECT_FALSE(upb_MiniTable_FieldIsLinked( + table, upb_MiniTable_GetFieldByIndex(table, 1))); } TEST(MiniTableEnumTest, PositiveAndNegative) { diff --git a/upb/mini_table/internal/message.h b/upb/mini_table/internal/message.h index e044c0e48c..d5b1ae4e0b 100644 --- a/upb/mini_table/internal/message.h +++ b/upb/mini_table/internal/message.h @@ -8,8 +8,10 @@ #ifndef UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ #define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ +#include #include +#include "upb/base/descriptor_constants.h" #include "upb/mini_table/internal/field.h" #include "upb/mini_table/internal/sub.h" @@ -97,34 +99,44 @@ UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTable_GetFieldByIndex( return &m->UPB_ONLYBITS(fields)[i]; } -UPB_INLINE const union upb_MiniTableSub* UPB_PRIVATE( +UPB_INLINE const union upb_MiniTableSub UPB_PRIVATE( _upb_MiniTable_GetSubByIndex)(const struct upb_MiniTable* m, uint32_t i) { - return &m->UPB_PRIVATE(subs)[i]; + return m->UPB_PRIVATE(subs)[i]; +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_SubMessage( + const struct upb_MiniTable* m, const struct upb_MiniTableField* f) { + if (upb_MiniTableField_CType(f) != kUpb_CType_Message) { + return NULL; + } + return m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)].UPB_PRIVATE(submsg); } UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_GetSubMessageTable( const struct upb_MiniTable* m, const struct upb_MiniTableField* f) { - UPB_ASSERT(upb_MiniTableField_CType(f) == kUpb_CType_Message); - const struct upb_MiniTable* ret = upb_MiniTableSub_Message( - m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message); + const struct upb_MiniTable* ret = upb_MiniTable_SubMessage(m, f); UPB_ASSUME(ret); return UPB_PRIVATE(_upb_MiniTable_IsEmpty)(ret) ? NULL : ret; } -UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_SubMessage( +UPB_API_INLINE bool upb_MiniTable_FieldIsLinked( const struct upb_MiniTable* m, const struct upb_MiniTableField* f) { - if (upb_MiniTableField_CType(f) != kUpb_CType_Message) { - return NULL; - } - return upb_MiniTableSub_Message( - m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); + return upb_MiniTable_GetSubMessageTable(m, f) != NULL; +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_MapEntrySubMessage( + const struct upb_MiniTable* m, const struct upb_MiniTableField* f) { + UPB_ASSERT(upb_MiniTable_FieldIsLinked(m, f)); // Map entries must be linked. + UPB_ASSERT(upb_MiniTableField_IsMap(f)); // Function precondition. + return upb_MiniTable_SubMessage(m, f); } UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( const struct upb_MiniTable* m, const struct upb_MiniTableField* f) { UPB_ASSERT(upb_MiniTableField_CType(f) == kUpb_CType_Enum); - return upb_MiniTableSub_Enum( - m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); + return m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)].UPB_PRIVATE( + subenum); } UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTable_MapKey( @@ -143,11 +155,6 @@ UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTable_MapValue( return f; } -UPB_API_INLINE bool upb_MiniTable_FieldIsLinked( - const struct upb_MiniTable* m, const struct upb_MiniTableField* f) { - return upb_MiniTable_GetSubMessageTable(m, f) != NULL; -} - // Computes a bitmask in which the |m->required_count| lowest bits are set. // // Sample output: diff --git a/upb/mini_table/message.h b/upb/mini_table/message.h index 1ce9087b0a..6589762f4e 100644 --- a/upb/mini_table/message.h +++ b/upb/mini_table/message.h @@ -34,10 +34,20 @@ UPB_API_INLINE int upb_MiniTable_FieldCount(const upb_MiniTable* m); UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable( const upb_MiniTable* m, const upb_MiniTableField* f); -// Returns the MiniTable for a message field if it is a submessage. +// Returns the MiniTable for a message field if it is a submessage, otherwise +// returns NULL. +// +// WARNING: if dynamic tree shaking is in use, the return value may be the +// "empty", zero-field placeholder message instead of the real message type. +// If the message is later linked, this function will begin returning the real +// message type. UPB_API_INLINE const upb_MiniTable* upb_MiniTable_SubMessage( const upb_MiniTable* m, const upb_MiniTableField* f); +// Returns the MiniTable for a map field. The given field must refer to a map. +UPB_API_INLINE const upb_MiniTable* upb_MiniTable_MapEntrySubMessage( + const upb_MiniTable* m, const upb_MiniTableField* f); + // Returns the MiniTableEnum for a message field, NULL if the field is unlinked. UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( const upb_MiniTable* m, const upb_MiniTableField* f);