xref: /aosp_15_r20/external/grpc-grpc/third_party/upb/upb/mini_table/internal/message.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #ifndef UPB_MINI_TABLE_INTERNAL_MESSAGE_H_
9 #define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_
10 
11 #include <stdint.h>
12 
13 #include "upb/mini_table/internal/field.h"
14 #include "upb/mini_table/internal/sub.h"
15 
16 // Must be last.
17 #include "upb/port/def.inc"
18 
19 struct upb_Decoder;
20 struct upb_Message;
21 typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr,
22                                      struct upb_Message* msg, intptr_t table,
23                                      uint64_t hasbits, uint64_t data);
24 typedef struct {
25   uint64_t field_data;
26   _upb_FieldParser* field_parser;
27 } _upb_FastTable_Entry;
28 
29 typedef enum {
30   kUpb_ExtMode_NonExtendable = 0,  // Non-extendable message.
31   kUpb_ExtMode_Extendable = 1,     // Normal extendable message.
32   kUpb_ExtMode_IsMessageSet = 2,   // MessageSet message.
33   kUpb_ExtMode_IsMessageSet_ITEM =
34       3,  // MessageSet item (temporary only, see decode.c)
35 
36   // During table building we steal a bit to indicate that the message is a map
37   // entry.  *Only* used during table building!
38   kUpb_ExtMode_IsMapEntry = 4,
39 } upb_ExtMode;
40 
41 // upb_MiniTable represents the memory layout of a given upb_MessageDef.
42 // The members are public so generated code can initialize them,
43 // but users MUST NOT directly read or write any of its members.
44 
45 // LINT.IfChange(minitable_struct_definition)
46 struct upb_MiniTable {
47   const union upb_MiniTableSub* UPB_PRIVATE(subs);
48   const struct upb_MiniTableField* UPB_ONLYBITS(fields);
49 
50   // Must be aligned to sizeof(void*). Doesn't include internal members like
51   // unknown fields, extension dict, pointer to msglayout, etc.
52   uint16_t UPB_PRIVATE(size);
53 
54   uint16_t UPB_ONLYBITS(field_count);
55 
56   uint8_t UPB_PRIVATE(ext);  // upb_ExtMode, uint8_t here so sizeof(ext) == 1
57   uint8_t UPB_PRIVATE(dense_below);
58   uint8_t UPB_PRIVATE(table_mask);
59   uint8_t UPB_PRIVATE(required_count);  // Required fields have the low hasbits.
60 
61   // To statically initialize the tables of variable length, we need a flexible
62   // array member, and we need to compile in gnu99 mode (constant initialization
63   // of flexible array members is a GNU extension, not in C99 unfortunately.
64   _upb_FastTable_Entry UPB_PRIVATE(fasttable)[];
65 };
66 // LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/mini_table.ts)
67 
68 #ifdef __cplusplus
69 extern "C" {
70 #endif
71 
UPB_PRIVATE(_upb_MiniTable_Empty)72 UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTable_Empty)(void) {
73   extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
74 
75   return &UPB_PRIVATE(_kUpb_MiniTable_Empty);
76 }
77 
UPB_PRIVATE(_upb_MiniTable_FieldCount)78 UPB_INLINE int UPB_PRIVATE(_upb_MiniTable_FieldCount)(
79     const struct upb_MiniTable* m) {
80   return m->UPB_ONLYBITS(field_count);
81 }
82 
UPB_PRIVATE(_upb_MiniTable_IsEmpty)83 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_IsEmpty)(
84     const struct upb_MiniTable* m) {
85   extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
86 
87   return m == &UPB_PRIVATE(_kUpb_MiniTable_Empty);
88 }
89 
UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)90 UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE(
91     _upb_MiniTable_GetFieldByIndex)(const struct upb_MiniTable* m, uint32_t i) {
92   return &m->UPB_ONLYBITS(fields)[i];
93 }
94 
UPB_PRIVATE(_upb_MiniTable_GetSubByIndex)95 UPB_INLINE const union upb_MiniTableSub* UPB_PRIVATE(
96     _upb_MiniTable_GetSubByIndex)(const struct upb_MiniTable* m, uint32_t i) {
97   return &m->UPB_PRIVATE(subs)[i];
98 }
99 
UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)100 UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(
101     _upb_MiniTable_GetSubMessageTable)(const struct upb_MiniTable* m,
102                                        const struct upb_MiniTableField* f) {
103   UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Message);
104   const struct upb_MiniTable* ret = UPB_PRIVATE(_upb_MiniTableSub_Message)(
105       m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]);
106   UPB_ASSUME(ret);
107   return UPB_PRIVATE(_upb_MiniTable_IsEmpty)(ret) ? NULL : ret;
108 }
109 
UPB_PRIVATE(_upb_MiniTable_GetSubEnumTable)110 UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE(
111     _upb_MiniTable_GetSubEnumTable)(const struct upb_MiniTable* m,
112                                     const struct upb_MiniTableField* f) {
113   UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Enum);
114   return UPB_PRIVATE(_upb_MiniTableSub_Enum)(
115       m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]);
116 }
117 
UPB_PRIVATE(_upb_MiniTable_MapKey)118 UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE(_upb_MiniTable_MapKey)(
119     const struct upb_MiniTable* m) {
120   UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_FieldCount)(m) == 2);
121   const struct upb_MiniTableField* f =
122       UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, 0);
123   UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_Number)(f) == 1);
124   return f;
125 }
126 
UPB_PRIVATE(_upb_MiniTable_MapValue)127 UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE(
128     _upb_MiniTable_MapValue)(const struct upb_MiniTable* m) {
129   UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_FieldCount)(m) == 2);
130   const struct upb_MiniTableField* f =
131       UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, 1);
132   UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_Number)(f) == 2);
133   return f;
134 }
135 
UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)136 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)(
137     const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
138   return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f) != NULL;
139 }
140 
141 // Computes a bitmask in which the |m->required_count| lowest bits are set.
142 //
143 // Sample output:
144 //    RequiredMask(1) => 0b1 (0x1)
145 //    RequiredMask(5) => 0b11111 (0x1f)
146 UPB_INLINE uint64_t
UPB_PRIVATE(_upb_MiniTable_RequiredMask)147 UPB_PRIVATE(_upb_MiniTable_RequiredMask)(const struct upb_MiniTable* m) {
148   int n = m->UPB_PRIVATE(required_count);
149   UPB_ASSERT(0 < n && n <= 64);
150   return (1ULL << n) - 1;
151 }
152 
153 #ifdef __cplusplus
154 } /* extern "C" */
155 #endif
156 
157 #include "upb/port/undef.inc"
158 
159 #endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */
160