WPILibC++ 2027.0.0-alpha-3
Loading...
Searching...
No Matches
message.h
Go to the documentation of this file.
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 <stddef.h>
12#include <stdint.h>
13
17
18// Must be last.
19#include "upb/port/def.inc"
20
21struct upb_Decoder;
22struct upb_Message;
23
25 struct upb_Decoder* d, const char* ptr, struct upb_Message* msg,
26 intptr_t table, uint64_t hasbits, uint64_t data);
27
32
33typedef enum {
34 kUpb_ExtMode_NonExtendable = 0, // Non-extendable message.
35 kUpb_ExtMode_Extendable = 1, // Normal extendable message.
36 kUpb_ExtMode_IsMessageSet = 2, // MessageSet message.
38 3, // MessageSet item (temporary only, see decode.c)
39
40 // During table building we steal a bit to indicate that the message is a map
41 // entry. *Only* used during table building!
44
45enum {
47};
48
49// upb_MiniTable represents the memory layout of a given upb_MessageDef.
50// The members are public so generated code can initialize them,
51// but users MUST NOT directly read or write any of its members.
52
53// LINT.IfChange(minitable_struct_definition)
56 const struct upb_MiniTableField* UPB_ONLYBITS(fields);
57
58 // Must be aligned to kUpb_Message_Align. Doesn't include internal members
59 // like unknown fields, extension dict, pointer to msglayout, etc.
60 uint16_t UPB_PRIVATE(size);
61
62 uint16_t UPB_ONLYBITS(field_count);
63
64 uint8_t UPB_PRIVATE(ext); // upb_ExtMode, uint8_t here so sizeof(ext) == 1
65 uint8_t UPB_PRIVATE(dense_below);
66 uint8_t UPB_PRIVATE(table_mask);
67 uint8_t UPB_PRIVATE(required_count); // Required fields have the low hasbits.
68
69#ifdef UPB_TRACING_ENABLED
70 const char* UPB_PRIVATE(full_name);
71#endif
72
73#if UPB_FASTTABLE || !defined(__cplusplus)
74 // Flexible array member is not supported in C++, but it is an extension in
75 // every compiler that supports UPB_FASTTABLE.
77#endif
78};
79// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/mini_table.ts)
80
81#ifdef __cplusplus
82extern "C" {
83#endif
84
86 const struct upb_MiniTable* mt) {
88 UPB_STATIC_ASSERT(kUpb_Message_Align >= UPB_ALIGN_OF(void*), "Under aligned");
89 UPB_ASSERT(mt->UPB_PRIVATE(size) % kUpb_Message_Align == 0);
90}
91
94#if defined(__GNUC__)
95 __asm__("" : : "r"(mt));
96#else
97 const struct upb_MiniTable* volatile unused = mt;
98 (void)&unused; // Use address to avoid an extra load of "unused".
99#endif
100 return mt;
101}
102
104 extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
105
106 return &UPB_PRIVATE(_kUpb_MiniTable_Empty);
107}
108
110 return m->UPB_ONLYBITS(field_count);
111}
112
116
119 const struct upb_MiniTable* m, uint32_t number) {
120 const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX
121
122 // Ideal case: index into dense fields
123 if (i < m->UPB_PRIVATE(dense_below)) {
124 UPB_ASSERT(m->UPB_ONLYBITS(fields)[i].UPB_ONLYBITS(number) == number);
125 return &m->UPB_ONLYBITS(fields)[i];
126 }
127
128 // Early exit if the field number is out of range.
129 int32_t hi = m->UPB_ONLYBITS(field_count) - 1;
130 if (hi < 0 || number > m->UPB_ONLYBITS(fields)[hi].UPB_ONLYBITS(number)) {
131 return NULL;
132 }
133
134 // Slow case: binary search
135 uint32_t lo = m->UPB_PRIVATE(dense_below);
136 const struct upb_MiniTableField* base = m->UPB_ONLYBITS(fields);
137 while (hi >= (int32_t)lo) {
138 uint32_t mid = (hi + lo) / 2;
139 uint32_t num = base[mid].UPB_ONLYBITS(number);
140 // These comparison operations allow, on ARM machines, to fuse all these
141 // branches into one comparison followed by two CSELs to set the lo/hi
142 // values, followed by a BNE to continue or terminate the loop. Since binary
143 // search branches are generally unpredictable (50/50 in each direction),
144 // this is a good deal. We use signed for the high, as this decrement may
145 // underflow if mid is 0.
146 int32_t hi_mid = mid - 1;
147 uint32_t lo_mid = mid + 1;
148 if (num == number) {
149 return &base[mid];
150 }
151 if (UPB_UNPREDICTABLE(num < number)) {
152 lo = lo_mid;
153 } else {
154 hi = hi_mid;
155 }
156 }
157
158 return NULL;
159}
160
162 const struct upb_MiniTable* m) {
163 extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
164
165 return m == &UPB_PRIVATE(_kUpb_MiniTable_Empty);
166}
167
169 const struct upb_MiniTable* m, uint32_t i) {
170 return &m->UPB_ONLYBITS(fields)[i];
171}
172
175 uint32_t i) {
176 return *m->UPB_PRIVATE(subs)[i].UPB_PRIVATE(submsg);
177}
178
180 const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
182 return NULL;
183 }
185 m, f->UPB_PRIVATE(submsg_index));
186}
187
189 const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
191 const struct upb_MiniTable* ret = upb_MiniTable_SubMessage(m, f);
192 UPB_ASSUME(ret);
193 return UPB_PRIVATE(_upb_MiniTable_IsEmpty)(ret) ? NULL : ret;
194}
195
197 const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
198 return upb_MiniTable_GetSubMessageTable(m, f) != NULL;
199}
200
202 const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
203 UPB_ASSERT(upb_MiniTable_FieldIsLinked(m, f)); // Map entries must be linked.
204 UPB_ASSERT(upb_MiniTableField_IsMap(f)); // Function precondition.
205 return upb_MiniTable_SubMessage(m, f);
206}
207
209 const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
211 return m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)].UPB_PRIVATE(
212 subenum);
213}
214
216 const struct upb_MiniTable* m) {
220 return f;
221}
222
230
231// Computes a bitmask in which the |m->required_count| lowest bits are set.
232//
233// Sample output:
234// RequiredMask(1) => 0b1 (0x1)
235// RequiredMask(5) => 0b11111 (0x1f)
236UPB_INLINE uint64_t
238 int n = m->UPB_PRIVATE(required_count);
239 UPB_ASSERT(0 < n && n <= 64);
240 return (1ULL << n) - 1;
241}
242
243#ifdef UPB_TRACING_ENABLED
244UPB_INLINE const char* upb_MiniTable_FullName(
245 const struct upb_MiniTable* mini_table) {
246 return mini_table->UPB_PRIVATE(full_name);
247}
248// Initializes tracing proto name from language runtimes that construct
249// mini tables dynamically at runtime. The runtime is responsible for passing
250// controlling lifetime of name such as storing in same arena as mini_table.
251UPB_INLINE void upb_MiniTable_SetFullName(struct upb_MiniTable* mini_table,
252 const char* full_name) {
253 mini_table->UPB_PRIVATE(full_name) = full_name;
254}
255#endif
256
257#ifdef __cplusplus
258} /* extern "C" */
259#endif
260
261#include "upb/port/undef.inc"
262
263#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */
#define UPB_API_INLINE
Definition def.inc:163
#define UPB_ALIGN_OF(type)
Definition def.inc:211
#define UPB_ASSUME(expr)
Definition def.inc:319
#define UPB_ASSERT(expr)
Definition def.inc:329
#define UPB_PRIVATE(x)
Definition def.inc:393
#define UPB_STATIC_ASSERT(val, msg)
Definition def.inc:239
#define UPB_MALLOC_ALIGN
Definition def.inc:184
#define UPB_INLINE
Definition def.inc:144
#define UPB_UNPREDICTABLE(x)
Definition def.inc:272
#define UPB_PRESERVE_NONE
Definition def.inc:412
@ kUpb_CType_Enum
Definition descriptor_constants.h:23
@ kUpb_CType_Message
Definition descriptor_constants.h:24
UPB_API_INLINE uint32_t upb_MiniTableField_Number(const upb_MiniTableField *f)
UPB_API_INLINE upb_CType upb_MiniTableField_CType(const upb_MiniTableField *f)
UPB_API_INLINE bool upb_MiniTableField_IsMap(const upb_MiniTableField *f)
auto ptr(T p) -> const void *
Converts p to const void* for pointer formatting.
Definition format.h:3963
UPB_INLINE uint64_t UPB_PRIVATE _upb_MiniTable_RequiredMask(const struct upb_MiniTable *m)
Definition message.h:237
UPB_API_INLINE const struct upb_MiniTable * upb_MiniTable_SubMessage(const struct upb_MiniTable *m, const struct upb_MiniTableField *f)
Definition message.h:179
UPB_INLINE const struct upb_MiniTable *UPB_PRIVATE _upb_MiniTable_GetSubTableByIndex(const struct upb_MiniTable *m, uint32_t i)
Definition message.h:174
UPB_INLINE const struct upb_MiniTable *UPB_PRIVATE _upb_MiniTable_Empty(void)
Definition message.h:103
@ kUpb_Message_Align
Definition message.h:46
UPB_INLINE const struct upb_MiniTable *UPB_PRIVATE _upb_MiniTable_StrongReference(const struct upb_MiniTable *mt)
Definition message.h:93
UPB_API_INLINE bool upb_MiniTable_IsMessageSet(const struct upb_MiniTable *m)
Definition message.h:113
UPB_API_INLINE const struct upb_MiniTableEnum * upb_MiniTable_GetSubEnumTable(const struct upb_MiniTable *m, const struct upb_MiniTableField *f)
Definition message.h:208
UPB_INLINE bool UPB_PRIVATE _upb_MiniTable_IsEmpty(const struct upb_MiniTable *m)
Definition message.h:161
upb_ExtMode
Definition message.h:33
@ kUpb_ExtMode_IsMessageSet_ITEM
Definition message.h:37
@ kUpb_ExtMode_IsMapEntry
Definition message.h:42
@ kUpb_ExtMode_IsMessageSet
Definition message.h:36
@ kUpb_ExtMode_Extendable
Definition message.h:35
@ kUpb_ExtMode_NonExtendable
Definition message.h:34
UPB_API_INLINE int upb_MiniTable_FieldCount(const struct upb_MiniTable *m)
Definition message.h:109
UPB_API_INLINE const struct upb_MiniTableField * upb_MiniTable_MapKey(const struct upb_MiniTable *m)
Definition message.h:215
UPB_API_INLINE const struct upb_MiniTable * upb_MiniTable_MapEntrySubMessage(const struct upb_MiniTable *m, const struct upb_MiniTableField *f)
Definition message.h:201
UPB_API_INLINE const struct upb_MiniTableField * upb_MiniTable_MapValue(const struct upb_MiniTable *m)
Definition message.h:223
UPB_API_INLINE const struct upb_MiniTableField * upb_MiniTable_GetFieldByIndex(const struct upb_MiniTable *m, uint32_t i)
Definition message.h:168
UPB_API_INLINE bool upb_MiniTable_FieldIsLinked(const struct upb_MiniTable *m, const struct upb_MiniTableField *f)
Definition message.h:196
UPB_API_INLINE const struct upb_MiniTableField * upb_MiniTable_FindFieldByNumber(const struct upb_MiniTable *m, uint32_t number)
Definition message.h:118
UPB_INLINE void UPB_PRIVATE upb_MiniTable_CheckInvariants(const struct upb_MiniTable *mt)
Definition message.h:85
UPB_PRESERVE_NONE const char * _upb_FieldParser(struct upb_Decoder *d, const char *ptr, struct upb_Message *msg, intptr_t table, uint64_t hasbits, uint64_t data)
Definition message.h:24
UPB_API_INLINE const struct upb_MiniTable * upb_MiniTable_GetSubMessageTable(const struct upb_MiniTable *m, const struct upb_MiniTableField *f)
Definition message.h:188
Definition message.h:28
uint64_t field_data
Definition message.h:29
_upb_FieldParser * field_parser
Definition message.h:30
Definition reader.h:17
Definition decoder.h:35
Definition types.h:18
double d
Definition types.h:21
Definition enum.h:16
Definition field.h:21
uint32_t UPB_ONLYBITS(number)
uint16_t UPB_PRIVATE(submsg_index)
Definition message.h:54
uint16_t UPB_PRIVATE(size)
const struct upb_MiniTableField * UPB_ONLYBITS(fields)
uint8_t UPB_PRIVATE(required_count)
uint16_t UPB_ONLYBITS(field_count)
uint8_t UPB_PRIVATE(dense_below)
uint8_t UPB_PRIVATE(table_mask)
uint8_t UPB_PRIVATE(ext)
const upb_MiniTableSubInternal * UPB_PRIVATE(subs)
Definition sub.h:14
const struct upb_MiniTable *const * UPB_PRIVATE(submsg)