Auto-generate files after cl/565789618
diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index de81125..1c13c8d 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h
@@ -371,6 +371,8 @@ #ifndef UPB_COLLECTIONS_ARRAY_H_ #define UPB_COLLECTIONS_ARRAY_H_ +#include <stddef.h> + #ifndef UPB_BASE_DESCRIPTOR_CONSTANTS_H_ #define UPB_BASE_DESCRIPTOR_CONSTANTS_H_ @@ -448,591 +450,6 @@ #endif /* UPB_BASE_DESCRIPTOR_CONSTANTS_H_ */ -// Users should include array.h or map.h instead. -// IWYU pragma: private, include "upb/upb/collections/array.h" - -#ifndef UPB_MESSAGE_VALUE_H_ -#define UPB_MESSAGE_VALUE_H_ - -#ifndef UPB_BASE_STRING_VIEW_H_ -#define UPB_BASE_STRING_VIEW_H_ - -#include <string.h> - -// Must be last. - -#define UPB_STRINGVIEW_INIT(ptr, len) \ - { ptr, len } - -#define UPB_STRINGVIEW_FORMAT "%.*s" -#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data - -// LINT.IfChange(struct_definition) -typedef struct { - const char* data; - size_t size; -} upb_StringView; -// LINT.ThenChange( -// GoogleInternalName0, -// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string -// ) - -#ifdef __cplusplus -extern "C" { -#endif - -UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, - size_t size) { - upb_StringView ret; - ret.data = data; - ret.size = size; - return ret; -} - -UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { - return upb_StringView_FromDataAndSize(data, strlen(data)); -} - -UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { - return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_BASE_STRING_VIEW_H_ */ - -#ifndef UPB_MINI_TABLE_TYPES_H_ -#define UPB_MINI_TABLE_TYPES_H_ - -#include <stdint.h> - - -#ifndef UPB_MESSAGE_TYPES_H_ -#define UPB_MESSAGE_TYPES_H_ - -// This typedef is in a leaf header to resolve a circular dependency between -// messages and mini tables. -typedef void upb_Message; - -#endif /* UPB_MESSAGE_TYPES_H_ */ - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -// When a upb_Message* is stored in a message, array, or map, it is stored in a -// tagged form. If the tag bit is set, the referenced upb_Message is of type -// _kUpb_MiniTable_Empty (a sentinel message type with no fields) instead of -// that field's true message type. This forms the basis of what we call -// "dynamic tree shaking." -// -// See the documentation for kUpb_DecodeOption_ExperimentalAllowUnlinked for -// more information. -typedef uintptr_t upb_TaggedMessagePtr; - -// Internal-only because empty messages cannot be created by the user. -UPB_INLINE upb_TaggedMessagePtr _upb_TaggedMessagePtr_Pack(upb_Message* ptr, - bool empty) { - UPB_ASSERT(((uintptr_t)ptr & 1) == 0); - return (uintptr_t)ptr | (empty ? 1 : 0); -} - -// Users who enable unlinked sub-messages must use this to test whether a -// message is empty before accessing it. If a message is empty, it must be -// first promoted using the interfaces in message/promote.h. -UPB_INLINE bool upb_TaggedMessagePtr_IsEmpty(upb_TaggedMessagePtr ptr) { - return ptr & 1; -} - -UPB_INLINE upb_Message* _upb_TaggedMessagePtr_GetMessage( - upb_TaggedMessagePtr ptr) { - return (upb_Message*)(ptr & ~(uintptr_t)1); -} - -UPB_INLINE upb_Message* upb_TaggedMessagePtr_GetNonEmptyMessage( - upb_TaggedMessagePtr ptr) { - UPB_ASSERT(!upb_TaggedMessagePtr_IsEmpty(ptr)); - return _upb_TaggedMessagePtr_GetMessage(ptr); -} - -UPB_INLINE upb_Message* _upb_TaggedMessagePtr_GetEmptyMessage( - upb_TaggedMessagePtr ptr) { - UPB_ASSERT(upb_TaggedMessagePtr_IsEmpty(ptr)); - return _upb_TaggedMessagePtr_GetMessage(ptr); -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_MINI_TABLE_TYPES_H_ */ - -#ifndef UPB_MINI_TABLE_MESSAGE_H_ -#define UPB_MINI_TABLE_MESSAGE_H_ - - -#ifndef UPB_MINI_TABLE_ENUM_H_ -#define UPB_MINI_TABLE_ENUM_H_ - - -#ifndef UPB_MINI_TABLE_INTERNAL_ENUM_H_ -#define UPB_MINI_TABLE_INTERNAL_ENUM_H_ - -#include <stdint.h> - -// Must be last. - -struct upb_MiniTableEnum { - uint32_t mask_limit; // Limit enum value that can be tested with mask. - uint32_t value_count; // Number of values after the bitfield. - uint32_t data[]; // Bitmask + enumerated values follow. -}; - -typedef enum { - _kUpb_FastEnumCheck_ValueIsInEnum = 0, - _kUpb_FastEnumCheck_ValueIsNotInEnum = 1, - _kUpb_FastEnumCheck_CannotCheckFast = 2, -} _kUpb_FastEnumCheck_Status; - -#ifdef __cplusplus -extern "C" { -#endif - -UPB_INLINE _kUpb_FastEnumCheck_Status _upb_MiniTable_CheckEnumValueFast( - const struct upb_MiniTableEnum* e, uint32_t val) { - if (UPB_UNLIKELY(val >= 64)) return _kUpb_FastEnumCheck_CannotCheckFast; - uint64_t mask = e->data[0] | ((uint64_t)e->data[1] << 32); - return (mask & (1ULL << val)) ? _kUpb_FastEnumCheck_ValueIsInEnum - : _kUpb_FastEnumCheck_ValueIsNotInEnum; -} - -UPB_INLINE bool _upb_MiniTable_CheckEnumValueSlow( - const struct upb_MiniTableEnum* e, uint32_t val) { - if (val < e->mask_limit) return e->data[val / 32] & (1ULL << (val % 32)); - // OPT: binary search long lists? - const uint32_t* start = &e->data[e->mask_limit / 32]; - const uint32_t* limit = &e->data[(e->mask_limit / 32) + e->value_count]; - for (const uint32_t* p = start; p < limit; p++) { - if (*p == val) return true; - } - return false; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_MINI_TABLE_INTERNAL_ENUM_H_ */ - -// Must be last - -typedef struct upb_MiniTableEnum upb_MiniTableEnum; - -// Validates enum value against range defined by enum mini table. -UPB_INLINE bool upb_MiniTableEnum_CheckValue(const struct upb_MiniTableEnum* e, - uint32_t val) { - _kUpb_FastEnumCheck_Status status = _upb_MiniTable_CheckEnumValueFast(e, val); - if (UPB_UNLIKELY(status == _kUpb_FastEnumCheck_CannotCheckFast)) { - return _upb_MiniTable_CheckEnumValueSlow(e, val); - } - return status == _kUpb_FastEnumCheck_ValueIsInEnum ? true : false; -} - - -#endif /* UPB_MINI_TABLE_ENUM_H_ */ - -#ifndef UPB_MINI_TABLE_FIELD_H_ -#define UPB_MINI_TABLE_FIELD_H_ - - -#ifndef UPB_MINI_TABLE_INTERNAL_FIELD_H_ -#define UPB_MINI_TABLE_INTERNAL_FIELD_H_ - -#include <stdint.h> - - -// Must be last. - -struct upb_MiniTableField { - uint32_t number; - uint16_t offset; - int16_t presence; // If >0, hasbit_index. If <0, ~oneof_index - - // Indexes into `upb_MiniTable.subs` - // Will be set to `kUpb_NoSub` if `descriptortype` != MESSAGE/GROUP/ENUM - uint16_t UPB_PRIVATE(submsg_index); - - uint8_t UPB_PRIVATE(descriptortype); - - // upb_FieldMode | upb_LabelFlags | (upb_FieldRep << kUpb_FieldRep_Shift) - uint8_t mode; -}; - -#define kUpb_NoSub ((uint16_t)-1) - -typedef enum { - kUpb_FieldMode_Map = 0, - kUpb_FieldMode_Array = 1, - kUpb_FieldMode_Scalar = 2, -} upb_FieldMode; - -// Mask to isolate the upb_FieldMode from field.mode. -#define kUpb_FieldMode_Mask 3 - -// Extra flags on the mode field. -typedef enum { - kUpb_LabelFlags_IsPacked = 4, - kUpb_LabelFlags_IsExtension = 8, - // Indicates that this descriptor type is an "alternate type": - // - for Int32, this indicates that the actual type is Enum (but was - // rewritten to Int32 because it is an open enum that requires no check). - // - for Bytes, this indicates that the actual type is String (but does - // not require any UTF-8 check). - kUpb_LabelFlags_IsAlternate = 16, -} upb_LabelFlags; - -// Note: we sort by this number when calculating layout order. -typedef enum { - kUpb_FieldRep_1Byte = 0, - kUpb_FieldRep_4Byte = 1, - kUpb_FieldRep_StringView = 2, - kUpb_FieldRep_8Byte = 3, - - kUpb_FieldRep_NativePointer = - UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte), - kUpb_FieldRep_Max = kUpb_FieldRep_8Byte, -} upb_FieldRep; - -#define kUpb_FieldRep_Shift 6 - -UPB_INLINE upb_FieldRep -_upb_MiniTableField_GetRep(const struct upb_MiniTableField* field) { - return (upb_FieldRep)(field->mode >> kUpb_FieldRep_Shift); -} - -#ifdef __cplusplus -extern "C" { -#endif - -UPB_INLINE upb_FieldMode -upb_FieldMode_Get(const struct upb_MiniTableField* field) { - return (upb_FieldMode)(field->mode & 3); -} - -UPB_INLINE void _upb_MiniTableField_CheckIsArray( - const struct upb_MiniTableField* field) { - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_NativePointer); - UPB_ASSUME(upb_FieldMode_Get(field) == kUpb_FieldMode_Array); - UPB_ASSUME(field->presence == 0); -} - -UPB_INLINE void _upb_MiniTableField_CheckIsMap( - const struct upb_MiniTableField* field) { - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_NativePointer); - UPB_ASSUME(upb_FieldMode_Get(field) == kUpb_FieldMode_Map); - UPB_ASSUME(field->presence == 0); -} - -UPB_INLINE bool upb_IsRepeatedOrMap(const struct upb_MiniTableField* field) { - // This works because upb_FieldMode has no value 3. - return !(field->mode & kUpb_FieldMode_Scalar); -} - -UPB_INLINE bool upb_IsSubMessage(const struct upb_MiniTableField* field) { - return field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || - field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_MINI_TABLE_INTERNAL_FIELD_H_ */ - -#ifndef UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ -#define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ - - -// Must be last. - -struct upb_Decoder; -typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, - upb_Message* msg, intptr_t table, - uint64_t hasbits, uint64_t data); -typedef struct { - uint64_t field_data; - _upb_FieldParser* field_parser; -} _upb_FastTable_Entry; - -typedef enum { - kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. - kUpb_ExtMode_Extendable = 1, // Normal extendable message. - kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. - kUpb_ExtMode_IsMessageSet_ITEM = - 3, // MessageSet item (temporary only, see decode.c) - - // During table building we steal a bit to indicate that the message is a map - // entry. *Only* used during table building! - kUpb_ExtMode_IsMapEntry = 4, -} upb_ExtMode; - -union upb_MiniTableSub; - -// upb_MiniTable represents the memory layout of a given upb_MessageDef. -// The members are public so generated code can initialize them, -// but users MUST NOT directly read or write any of its members. -struct upb_MiniTable { - const union upb_MiniTableSub* subs; - const struct upb_MiniTableField* fields; - - // Must be aligned to sizeof(void*). Doesn't include internal members like - // unknown fields, extension dict, pointer to msglayout, etc. - uint16_t size; - - uint16_t field_count; - uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1 - uint8_t dense_below; - uint8_t table_mask; - uint8_t required_count; // Required fields have the lowest hasbits. - - // To statically initialize the tables of variable length, we need a flexible - // array member, and we need to compile in gnu99 mode (constant initialization - // of flexible array members is a GNU extension, not in C99 unfortunately. - _upb_FastTable_Entry fasttable[]; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -// A MiniTable for an empty message, used for unlinked sub-messages. -extern const struct upb_MiniTable _kUpb_MiniTable_Empty; - -// Computes a bitmask in which the |l->required_count| lowest bits are set, -// except that we skip the lowest bit (because upb never uses hasbit 0). -// -// Sample output: -// requiredmask(1) => 0b10 (0x2) -// requiredmask(5) => 0b111110 (0x3e) -UPB_INLINE uint64_t upb_MiniTable_requiredmask(const struct upb_MiniTable* l) { - int n = l->required_count; - assert(0 < n && n <= 63); - return ((1ULL << n) - 1) << 1; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ - -#ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ -#define UPB_MINI_TABLE_INTERNAL_SUB_H_ - - -union upb_MiniTableSub { - const struct upb_MiniTable* submsg; - const struct upb_MiniTableEnum* subenum; -}; - -#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct upb_MiniTableField upb_MiniTableField; - -UPB_API_INLINE upb_FieldType -upb_MiniTableField_Type(const upb_MiniTableField* field) { - if (field->mode & kUpb_LabelFlags_IsAlternate) { - if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Int32) { - return kUpb_FieldType_Enum; - } else if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bytes) { - return kUpb_FieldType_String; - } else { - UPB_ASSERT(false); - } - } - return (upb_FieldType)field->UPB_PRIVATE(descriptortype); -} - -UPB_API_INLINE upb_CType upb_MiniTableField_CType(const upb_MiniTableField* f) { - switch (upb_MiniTableField_Type(f)) { - case kUpb_FieldType_Double: - return kUpb_CType_Double; - case kUpb_FieldType_Float: - return kUpb_CType_Float; - case kUpb_FieldType_Int64: - case kUpb_FieldType_SInt64: - case kUpb_FieldType_SFixed64: - return kUpb_CType_Int64; - case kUpb_FieldType_Int32: - case kUpb_FieldType_SFixed32: - case kUpb_FieldType_SInt32: - return kUpb_CType_Int32; - case kUpb_FieldType_UInt64: - case kUpb_FieldType_Fixed64: - return kUpb_CType_UInt64; - case kUpb_FieldType_UInt32: - case kUpb_FieldType_Fixed32: - return kUpb_CType_UInt32; - case kUpb_FieldType_Enum: - return kUpb_CType_Enum; - case kUpb_FieldType_Bool: - return kUpb_CType_Bool; - case kUpb_FieldType_String: - return kUpb_CType_String; - case kUpb_FieldType_Bytes: - return kUpb_CType_Bytes; - case kUpb_FieldType_Group: - case kUpb_FieldType_Message: - return kUpb_CType_Message; - } - UPB_UNREACHABLE(); -} - -UPB_API_INLINE bool upb_MiniTableField_IsExtension( - const upb_MiniTableField* field) { - return field->mode & kUpb_LabelFlags_IsExtension; -} - -UPB_API_INLINE bool upb_MiniTableField_IsClosedEnum( - const upb_MiniTableField* field) { - return field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum; -} - -UPB_API_INLINE bool upb_MiniTableField_HasPresence( - const upb_MiniTableField* field) { - if (upb_MiniTableField_IsExtension(field)) { - return !upb_IsRepeatedOrMap(field); - } else { - return field->presence != 0; - } -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_MINI_TABLE_FIELD_H_ */ - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct upb_MiniTable upb_MiniTable; - -UPB_API const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( - const upb_MiniTable* table, uint32_t number); - -UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex( - const upb_MiniTable* t, uint32_t index) { - return &t->fields[index]; -} - -// Returns the MiniTable for this message field. If the field is unlinked, -// returns NULL. -UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Message); - const upb_MiniTable* ret = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; - UPB_ASSUME(ret); - return ret == &_kUpb_MiniTable_Empty ? NULL : ret; -} - -// Returns the MiniTableEnum for this enum field. If the field is unlinked, -// returns NULL. -UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Enum); - return mini_table->subs[field->UPB_PRIVATE(submsg_index)].subenum; -} - -// Returns true if this MiniTable field is linked to a MiniTable for the -// sub-message. -UPB_API_INLINE bool upb_MiniTable_MessageFieldIsLinked( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - return upb_MiniTable_GetSubMessageTable(mini_table, field) != NULL; -} - -// If this field is in a oneof, returns the first field in the oneof. -// -// Otherwise returns NULL. -// -// Usage: -// const upb_MiniTableField* field = upb_MiniTable_GetOneof(m, f); -// do { -// .. -// } while (upb_MiniTable_NextOneofField(m, &field); -// -const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, - const upb_MiniTableField* f); - -// Iterates to the next field in the oneof. If this is the last field in the -// oneof, returns false. The ordering of fields in the oneof is not -// guaranteed. -// REQUIRES: |f| is the field initialized by upb_MiniTable_GetOneof and updated -// by prior upb_MiniTable_NextOneofField calls. -bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, - const upb_MiniTableField** f); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_MINI_TABLE_MESSAGE_H_ */ - -// Must be last. - -typedef struct upb_Array upb_Array; -typedef struct upb_Map upb_Map; - -typedef union { - bool bool_val; - float float_val; - double double_val; - int32_t int32_val; - int64_t int64_val; - uint32_t uint32_val; - uint64_t uint64_val; - const upb_Array* array_val; - const upb_Map* map_val; - const upb_Message* msg_val; - upb_StringView str_val; - - // EXPERIMENTAL: A tagged upb_Message*. Users must use this instead of - // msg_val if unlinked sub-messages may possibly be in use. See the - // documentation in kUpb_DecodeOption_ExperimentalAllowUnlinked for more - // information. - upb_TaggedMessagePtr tagged_msg_val; -} upb_MessageValue; - -typedef union { - upb_Array* array; - upb_Map* map; - upb_Message* msg; -} upb_MutableMessageValue; - - -#endif /* UPB_MESSAGE_VALUE_H_ */ - /* upb_Arena is a specific allocator implementation that uses arena allocation. * The user provides an allocator that will be used to allocate the underlying * arena blocks. Arenas by nature do not require the individual allocations @@ -1223,8 +640,165 @@ #endif /* UPB_MEM_ARENA_H_ */ +// Users should include array.h or map.h instead. +// IWYU pragma: private, include "upb/upb/collections/array.h" + +#ifndef UPB_MESSAGE_VALUE_H_ +#define UPB_MESSAGE_VALUE_H_ + +#include <stdint.h> + +#ifndef UPB_BASE_STRING_VIEW_H_ +#define UPB_BASE_STRING_VIEW_H_ + +#include <string.h> + // Must be last. +#define UPB_STRINGVIEW_INIT(ptr, len) \ + { ptr, len } + +#define UPB_STRINGVIEW_FORMAT "%.*s" +#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data + +// LINT.IfChange(struct_definition) +typedef struct { + const char* data; + size_t size; +} upb_StringView; +// LINT.ThenChange( +// GoogleInternalName0, +// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string +// ) + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, + size_t size) { + upb_StringView ret; + ret.data = data; + ret.size = size; + return ret; +} + +UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { + return upb_StringView_FromDataAndSize(data, strlen(data)); +} + +UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { + return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_BASE_STRING_VIEW_H_ */ + +#ifndef UPB_MINI_TABLE_TYPES_H_ +#define UPB_MINI_TABLE_TYPES_H_ + +#include <stdint.h> + + +#ifndef UPB_MESSAGE_TYPES_H_ +#define UPB_MESSAGE_TYPES_H_ + +// This typedef is in a leaf header to resolve a circular dependency between +// messages and mini tables. +typedef void upb_Message; + +#endif /* UPB_MESSAGE_TYPES_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// When a upb_Message* is stored in a message, array, or map, it is stored in a +// tagged form. If the tag bit is set, the referenced upb_Message is of type +// _kUpb_MiniTable_Empty (a sentinel message type with no fields) instead of +// that field's true message type. This forms the basis of what we call +// "dynamic tree shaking." +// +// See the documentation for kUpb_DecodeOption_ExperimentalAllowUnlinked for +// more information. +typedef uintptr_t upb_TaggedMessagePtr; + +// Internal-only because empty messages cannot be created by the user. +UPB_INLINE upb_TaggedMessagePtr _upb_TaggedMessagePtr_Pack(upb_Message* ptr, + bool empty) { + UPB_ASSERT(((uintptr_t)ptr & 1) == 0); + return (uintptr_t)ptr | (empty ? 1 : 0); +} + +// Users who enable unlinked sub-messages must use this to test whether a +// message is empty before accessing it. If a message is empty, it must be +// first promoted using the interfaces in message/promote.h. +UPB_INLINE bool upb_TaggedMessagePtr_IsEmpty(upb_TaggedMessagePtr ptr) { + return ptr & 1; +} + +UPB_INLINE upb_Message* _upb_TaggedMessagePtr_GetMessage( + upb_TaggedMessagePtr ptr) { + return (upb_Message*)(ptr & ~(uintptr_t)1); +} + +UPB_INLINE upb_Message* upb_TaggedMessagePtr_GetNonEmptyMessage( + upb_TaggedMessagePtr ptr) { + UPB_ASSERT(!upb_TaggedMessagePtr_IsEmpty(ptr)); + return _upb_TaggedMessagePtr_GetMessage(ptr); +} + +UPB_INLINE upb_Message* _upb_TaggedMessagePtr_GetEmptyMessage( + upb_TaggedMessagePtr ptr) { + UPB_ASSERT(upb_TaggedMessagePtr_IsEmpty(ptr)); + return _upb_TaggedMessagePtr_GetMessage(ptr); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_TYPES_H_ */ + +typedef union { + bool bool_val; + float float_val; + double double_val; + int32_t int32_val; + int64_t int64_val; + uint32_t uint32_val; + uint64_t uint64_val; + const struct upb_Array* array_val; + const struct upb_Map* map_val; + const upb_Message* msg_val; + upb_StringView str_val; + + // EXPERIMENTAL: A tagged upb_Message*. Users must use this instead of + // msg_val if unlinked sub-messages may possibly be in use. See the + // documentation in kUpb_DecodeOption_ExperimentalAllowUnlinked for more + // information. + upb_TaggedMessagePtr tagged_msg_val; +} upb_MessageValue; + +typedef union { + struct upb_Array* array; + struct upb_Map* map; + upb_Message* msg; +} upb_MutableMessageValue; + +#endif /* UPB_MESSAGE_VALUE_H_ */ + +// Must be last. + +typedef struct upb_Array upb_Array; + #ifdef __cplusplus extern "C" { #endif @@ -1382,9 +956,13 @@ #ifndef UPB_COLLECTIONS_MAP_H_ #define UPB_COLLECTIONS_MAP_H_ +#include <stddef.h> + // Must be last. +typedef struct upb_Map upb_Map; + #ifdef __cplusplus extern "C" { #endif @@ -1996,6 +1574,432 @@ #include <stddef.h> +#ifndef UPB_MINI_TABLE_MESSAGE_H_ +#define UPB_MINI_TABLE_MESSAGE_H_ + + +#ifndef UPB_MINI_TABLE_ENUM_H_ +#define UPB_MINI_TABLE_ENUM_H_ + + +#ifndef UPB_MINI_TABLE_INTERNAL_ENUM_H_ +#define UPB_MINI_TABLE_INTERNAL_ENUM_H_ + +#include <stdint.h> + +// Must be last. + +struct upb_MiniTableEnum { + uint32_t mask_limit; // Limit enum value that can be tested with mask. + uint32_t value_count; // Number of values after the bitfield. + uint32_t data[]; // Bitmask + enumerated values follow. +}; + +typedef enum { + _kUpb_FastEnumCheck_ValueIsInEnum = 0, + _kUpb_FastEnumCheck_ValueIsNotInEnum = 1, + _kUpb_FastEnumCheck_CannotCheckFast = 2, +} _kUpb_FastEnumCheck_Status; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE _kUpb_FastEnumCheck_Status _upb_MiniTable_CheckEnumValueFast( + const struct upb_MiniTableEnum* e, uint32_t val) { + if (UPB_UNLIKELY(val >= 64)) return _kUpb_FastEnumCheck_CannotCheckFast; + uint64_t mask = e->data[0] | ((uint64_t)e->data[1] << 32); + return (mask & (1ULL << val)) ? _kUpb_FastEnumCheck_ValueIsInEnum + : _kUpb_FastEnumCheck_ValueIsNotInEnum; +} + +UPB_INLINE bool _upb_MiniTable_CheckEnumValueSlow( + const struct upb_MiniTableEnum* e, uint32_t val) { + if (val < e->mask_limit) return e->data[val / 32] & (1ULL << (val % 32)); + // OPT: binary search long lists? + const uint32_t* start = &e->data[e->mask_limit / 32]; + const uint32_t* limit = &e->data[(e->mask_limit / 32) + e->value_count]; + for (const uint32_t* p = start; p < limit; p++) { + if (*p == val) return true; + } + return false; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_ENUM_H_ */ + +// Must be last + +typedef struct upb_MiniTableEnum upb_MiniTableEnum; + +// Validates enum value against range defined by enum mini table. +UPB_INLINE bool upb_MiniTableEnum_CheckValue(const struct upb_MiniTableEnum* e, + uint32_t val) { + _kUpb_FastEnumCheck_Status status = _upb_MiniTable_CheckEnumValueFast(e, val); + if (UPB_UNLIKELY(status == _kUpb_FastEnumCheck_CannotCheckFast)) { + return _upb_MiniTable_CheckEnumValueSlow(e, val); + } + return status == _kUpb_FastEnumCheck_ValueIsInEnum ? true : false; +} + + +#endif /* UPB_MINI_TABLE_ENUM_H_ */ + +#ifndef UPB_MINI_TABLE_FIELD_H_ +#define UPB_MINI_TABLE_FIELD_H_ + + +#ifndef UPB_MINI_TABLE_INTERNAL_FIELD_H_ +#define UPB_MINI_TABLE_INTERNAL_FIELD_H_ + +#include <stdint.h> + + +// Must be last. + +struct upb_MiniTableField { + uint32_t number; + uint16_t offset; + int16_t presence; // If >0, hasbit_index. If <0, ~oneof_index + + // Indexes into `upb_MiniTable.subs` + // Will be set to `kUpb_NoSub` if `descriptortype` != MESSAGE/GROUP/ENUM + uint16_t UPB_PRIVATE(submsg_index); + + uint8_t UPB_PRIVATE(descriptortype); + + // upb_FieldMode | upb_LabelFlags | (upb_FieldRep << kUpb_FieldRep_Shift) + uint8_t mode; +}; + +#define kUpb_NoSub ((uint16_t)-1) + +typedef enum { + kUpb_FieldMode_Map = 0, + kUpb_FieldMode_Array = 1, + kUpb_FieldMode_Scalar = 2, +} upb_FieldMode; + +// Mask to isolate the upb_FieldMode from field.mode. +#define kUpb_FieldMode_Mask 3 + +// Extra flags on the mode field. +typedef enum { + kUpb_LabelFlags_IsPacked = 4, + kUpb_LabelFlags_IsExtension = 8, + // Indicates that this descriptor type is an "alternate type": + // - for Int32, this indicates that the actual type is Enum (but was + // rewritten to Int32 because it is an open enum that requires no check). + // - for Bytes, this indicates that the actual type is String (but does + // not require any UTF-8 check). + kUpb_LabelFlags_IsAlternate = 16, +} upb_LabelFlags; + +// Note: we sort by this number when calculating layout order. +typedef enum { + kUpb_FieldRep_1Byte = 0, + kUpb_FieldRep_4Byte = 1, + kUpb_FieldRep_StringView = 2, + kUpb_FieldRep_8Byte = 3, + + kUpb_FieldRep_NativePointer = + UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte), + kUpb_FieldRep_Max = kUpb_FieldRep_8Byte, +} upb_FieldRep; + +#define kUpb_FieldRep_Shift 6 + +UPB_INLINE upb_FieldRep +_upb_MiniTableField_GetRep(const struct upb_MiniTableField* field) { + return (upb_FieldRep)(field->mode >> kUpb_FieldRep_Shift); +} + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE upb_FieldMode +upb_FieldMode_Get(const struct upb_MiniTableField* field) { + return (upb_FieldMode)(field->mode & 3); +} + +UPB_INLINE void _upb_MiniTableField_CheckIsArray( + const struct upb_MiniTableField* field) { + UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_NativePointer); + UPB_ASSUME(upb_FieldMode_Get(field) == kUpb_FieldMode_Array); + UPB_ASSUME(field->presence == 0); +} + +UPB_INLINE void _upb_MiniTableField_CheckIsMap( + const struct upb_MiniTableField* field) { + UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_NativePointer); + UPB_ASSUME(upb_FieldMode_Get(field) == kUpb_FieldMode_Map); + UPB_ASSUME(field->presence == 0); +} + +UPB_INLINE bool upb_IsRepeatedOrMap(const struct upb_MiniTableField* field) { + // This works because upb_FieldMode has no value 3. + return !(field->mode & kUpb_FieldMode_Scalar); +} + +UPB_INLINE bool upb_IsSubMessage(const struct upb_MiniTableField* field) { + return field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || + field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_FIELD_H_ */ + +#ifndef UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ +#define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ + + +// Must be last. + +struct upb_Decoder; +typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data); +typedef struct { + uint64_t field_data; + _upb_FieldParser* field_parser; +} _upb_FastTable_Entry; + +typedef enum { + kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. + kUpb_ExtMode_Extendable = 1, // Normal extendable message. + kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. + kUpb_ExtMode_IsMessageSet_ITEM = + 3, // MessageSet item (temporary only, see decode.c) + + // During table building we steal a bit to indicate that the message is a map + // entry. *Only* used during table building! + kUpb_ExtMode_IsMapEntry = 4, +} upb_ExtMode; + +union upb_MiniTableSub; + +// upb_MiniTable represents the memory layout of a given upb_MessageDef. +// The members are public so generated code can initialize them, +// but users MUST NOT directly read or write any of its members. +struct upb_MiniTable { + const union upb_MiniTableSub* subs; + const struct upb_MiniTableField* fields; + + // Must be aligned to sizeof(void*). Doesn't include internal members like + // unknown fields, extension dict, pointer to msglayout, etc. + uint16_t size; + + uint16_t field_count; + uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1 + uint8_t dense_below; + uint8_t table_mask; + uint8_t required_count; // Required fields have the lowest hasbits. + + // To statically initialize the tables of variable length, we need a flexible + // array member, and we need to compile in gnu99 mode (constant initialization + // of flexible array members is a GNU extension, not in C99 unfortunately. + _upb_FastTable_Entry fasttable[]; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +// A MiniTable for an empty message, used for unlinked sub-messages. +extern const struct upb_MiniTable _kUpb_MiniTable_Empty; + +// Computes a bitmask in which the |l->required_count| lowest bits are set, +// except that we skip the lowest bit (because upb never uses hasbit 0). +// +// Sample output: +// requiredmask(1) => 0b10 (0x2) +// requiredmask(5) => 0b111110 (0x3e) +UPB_INLINE uint64_t upb_MiniTable_requiredmask(const struct upb_MiniTable* l) { + int n = l->required_count; + assert(0 < n && n <= 63); + return ((1ULL << n) - 1) << 1; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ + +#ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ +#define UPB_MINI_TABLE_INTERNAL_SUB_H_ + + +union upb_MiniTableSub { + const struct upb_MiniTable* submsg; + const struct upb_MiniTableEnum* subenum; +}; + +#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct upb_MiniTableField upb_MiniTableField; + +UPB_API_INLINE upb_FieldType +upb_MiniTableField_Type(const upb_MiniTableField* field) { + if (field->mode & kUpb_LabelFlags_IsAlternate) { + if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Int32) { + return kUpb_FieldType_Enum; + } else if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bytes) { + return kUpb_FieldType_String; + } else { + UPB_ASSERT(false); + } + } + return (upb_FieldType)field->UPB_PRIVATE(descriptortype); +} + +UPB_API_INLINE upb_CType upb_MiniTableField_CType(const upb_MiniTableField* f) { + switch (upb_MiniTableField_Type(f)) { + case kUpb_FieldType_Double: + return kUpb_CType_Double; + case kUpb_FieldType_Float: + return kUpb_CType_Float; + case kUpb_FieldType_Int64: + case kUpb_FieldType_SInt64: + case kUpb_FieldType_SFixed64: + return kUpb_CType_Int64; + case kUpb_FieldType_Int32: + case kUpb_FieldType_SFixed32: + case kUpb_FieldType_SInt32: + return kUpb_CType_Int32; + case kUpb_FieldType_UInt64: + case kUpb_FieldType_Fixed64: + return kUpb_CType_UInt64; + case kUpb_FieldType_UInt32: + case kUpb_FieldType_Fixed32: + return kUpb_CType_UInt32; + case kUpb_FieldType_Enum: + return kUpb_CType_Enum; + case kUpb_FieldType_Bool: + return kUpb_CType_Bool; + case kUpb_FieldType_String: + return kUpb_CType_String; + case kUpb_FieldType_Bytes: + return kUpb_CType_Bytes; + case kUpb_FieldType_Group: + case kUpb_FieldType_Message: + return kUpb_CType_Message; + } + UPB_UNREACHABLE(); +} + +UPB_API_INLINE bool upb_MiniTableField_IsExtension( + const upb_MiniTableField* field) { + return field->mode & kUpb_LabelFlags_IsExtension; +} + +UPB_API_INLINE bool upb_MiniTableField_IsClosedEnum( + const upb_MiniTableField* field) { + return field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum; +} + +UPB_API_INLINE bool upb_MiniTableField_HasPresence( + const upb_MiniTableField* field) { + if (upb_MiniTableField_IsExtension(field)) { + return !upb_IsRepeatedOrMap(field); + } else { + return field->presence != 0; + } +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_FIELD_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct upb_MiniTable upb_MiniTable; + +UPB_API const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( + const upb_MiniTable* table, uint32_t number); + +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex( + const upb_MiniTable* t, uint32_t index) { + return &t->fields[index]; +} + +// Returns the MiniTable for this message field. If the field is unlinked, +// returns NULL. +UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable( + const upb_MiniTable* mini_table, const upb_MiniTableField* field) { + UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Message); + const upb_MiniTable* ret = + mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; + UPB_ASSUME(ret); + return ret == &_kUpb_MiniTable_Empty ? NULL : ret; +} + +// Returns the MiniTableEnum for this enum field. If the field is unlinked, +// returns NULL. +UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( + const upb_MiniTable* mini_table, const upb_MiniTableField* field) { + UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Enum); + return mini_table->subs[field->UPB_PRIVATE(submsg_index)].subenum; +} + +// Returns true if this MiniTable field is linked to a MiniTable for the +// sub-message. +UPB_API_INLINE bool upb_MiniTable_MessageFieldIsLinked( + const upb_MiniTable* mini_table, const upb_MiniTableField* field) { + return upb_MiniTable_GetSubMessageTable(mini_table, field) != NULL; +} + +// If this field is in a oneof, returns the first field in the oneof. +// +// Otherwise returns NULL. +// +// Usage: +// const upb_MiniTableField* field = upb_MiniTable_GetOneof(m, f); +// do { +// .. +// } while (upb_MiniTable_NextOneofField(m, &field); +// +const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, + const upb_MiniTableField* f); + +// Iterates to the next field in the oneof. If this is the last field in the +// oneof, returns false. The ordering of fields in the oneof is not +// guaranteed. +// REQUIRES: |f| is the field initialized by upb_MiniTable_GetOneof and updated +// by prior upb_MiniTable_NextOneofField calls. +bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, + const upb_MiniTableField** f); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_MESSAGE_H_ */ + // Must be last. #ifdef __cplusplus @@ -11454,6 +11458,8 @@ #ifndef UPB_REFLECTION_MESSAGE_H_ #define UPB_REFLECTION_MESSAGE_H_ +#include <stddef.h> + // Must be last.