// Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd #ifndef UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ #define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ #include "upb/message/types.h" #include "upb/mini_table/internal/field.h" // Must be last. #include "upb/port/def.inc" 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 #include "upb/port/undef.inc" #endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */