xref: /aosp_15_r20/external/grpc-grpc/third_party/upb/upb/mini_table/internal/field.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_FIELD_H_
9 #define UPB_MINI_TABLE_INTERNAL_FIELD_H_
10 
11 #include <stddef.h>
12 #include <stdint.h>
13 
14 #include "upb/base/descriptor_constants.h"
15 #include "upb/mini_table/internal/size_log2.h"
16 
17 // Must be last.
18 #include "upb/port/def.inc"
19 
20 // LINT.IfChange(struct_definition)
21 struct upb_MiniTableField {
22   uint32_t UPB_ONLYBITS(number);
23   uint16_t UPB_ONLYBITS(offset);
24   int16_t presence;  // If >0, hasbit_index.  If <0, ~oneof_index
25 
26   // Indexes into `upb_MiniTable.subs`
27   // Will be set to `kUpb_NoSub` if `descriptortype` != MESSAGE/GROUP/ENUM
28   uint16_t UPB_PRIVATE(submsg_index);
29 
30   uint8_t UPB_PRIVATE(descriptortype);
31 
32   // upb_FieldMode | upb_LabelFlags | (upb_FieldRep << kUpb_FieldRep_Shift)
33   uint8_t UPB_ONLYBITS(mode);
34 };
35 
36 #define kUpb_NoSub ((uint16_t)-1)
37 
38 typedef enum {
39   kUpb_FieldMode_Map = 0,
40   kUpb_FieldMode_Array = 1,
41   kUpb_FieldMode_Scalar = 2,
42 } upb_FieldMode;
43 
44 // Mask to isolate the upb_FieldMode from field.mode.
45 #define kUpb_FieldMode_Mask 3
46 
47 // Extra flags on the mode field.
48 typedef enum {
49   kUpb_LabelFlags_IsPacked = 4,
50   kUpb_LabelFlags_IsExtension = 8,
51   // Indicates that this descriptor type is an "alternate type":
52   //   - for Int32, this indicates that the actual type is Enum (but was
53   //     rewritten to Int32 because it is an open enum that requires no check).
54   //   - for Bytes, this indicates that the actual type is String (but does
55   //     not require any UTF-8 check).
56   kUpb_LabelFlags_IsAlternate = 16,
57 } upb_LabelFlags;
58 
59 // Note: we sort by this number when calculating layout order.
60 typedef enum {
61   kUpb_FieldRep_1Byte = 0,
62   kUpb_FieldRep_4Byte = 1,
63   kUpb_FieldRep_StringView = 2,
64   kUpb_FieldRep_8Byte = 3,
65 
66   kUpb_FieldRep_NativePointer =
67       UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte),
68   kUpb_FieldRep_Max = kUpb_FieldRep_8Byte,
69 } upb_FieldRep;
70 
71 #define kUpb_FieldRep_Shift 6
72 
73 #ifdef __cplusplus
74 extern "C" {
75 #endif
76 
77 UPB_INLINE upb_FieldMode
UPB_PRIVATE(_upb_MiniTableField_Mode)78 UPB_PRIVATE(_upb_MiniTableField_Mode)(const struct upb_MiniTableField* f) {
79   return (upb_FieldMode)(f->UPB_ONLYBITS(mode) & kUpb_FieldMode_Mask);
80 }
81 
82 UPB_INLINE upb_FieldRep
UPB_PRIVATE(_upb_MiniTableField_GetRep)83 UPB_PRIVATE(_upb_MiniTableField_GetRep)(const struct upb_MiniTableField* f) {
84   return (upb_FieldRep)(f->UPB_ONLYBITS(mode) >> kUpb_FieldRep_Shift);
85 }
86 
UPB_PRIVATE(_upb_MiniTableField_IsArray)87 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsArray)(
88     const struct upb_MiniTableField* f) {
89   return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Array;
90 }
91 
UPB_PRIVATE(_upb_MiniTableField_IsMap)92 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsMap)(
93     const struct upb_MiniTableField* f) {
94   return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Map;
95 }
96 
UPB_PRIVATE(_upb_MiniTableField_IsScalar)97 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsScalar)(
98     const struct upb_MiniTableField* f) {
99   return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Scalar;
100 }
101 
UPB_PRIVATE(_upb_MiniTableField_IsAlternate)102 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsAlternate)(
103     const struct upb_MiniTableField* f) {
104   return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsAlternate) != 0;
105 }
106 
UPB_PRIVATE(_upb_MiniTableField_IsExtension)107 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsExtension)(
108     const struct upb_MiniTableField* f) {
109   return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsExtension) != 0;
110 }
111 
UPB_PRIVATE(_upb_MiniTableField_IsPacked)112 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsPacked)(
113     const struct upb_MiniTableField* f) {
114   return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsPacked) != 0;
115 }
116 
117 UPB_INLINE upb_FieldType
UPB_PRIVATE(_upb_MiniTableField_Type)118 UPB_PRIVATE(_upb_MiniTableField_Type)(const struct upb_MiniTableField* f) {
119   const upb_FieldType type = (upb_FieldType)f->UPB_PRIVATE(descriptortype);
120   if (UPB_PRIVATE(_upb_MiniTableField_IsAlternate)(f)) {
121     if (type == kUpb_FieldType_Int32) return kUpb_FieldType_Enum;
122     if (type == kUpb_FieldType_Bytes) return kUpb_FieldType_String;
123     UPB_ASSERT(false);
124   }
125   return type;
126 }
127 
128 UPB_INLINE upb_CType
UPB_PRIVATE(_upb_MiniTableField_CType)129 UPB_PRIVATE(_upb_MiniTableField_CType)(const struct upb_MiniTableField* f) {
130   return upb_FieldType_CType(UPB_PRIVATE(_upb_MiniTableField_Type)(f));
131 }
132 
UPB_PRIVATE(_upb_MiniTableField_HasHasbit)133 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(
134     const struct upb_MiniTableField* f) {
135   return f->presence > 0;
136 }
137 
UPB_PRIVATE(_upb_MiniTableField_HasbitMask)138 UPB_INLINE char UPB_PRIVATE(_upb_MiniTableField_HasbitMask)(
139     const struct upb_MiniTableField* f) {
140   UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f));
141   const size_t index = f->presence;
142   return 1 << (index % 8);
143 }
144 
UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)145 UPB_INLINE size_t UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)(
146     const struct upb_MiniTableField* f) {
147   UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f));
148   const size_t index = f->presence;
149   return index / 8;
150 }
151 
UPB_PRIVATE(_upb_MiniTableField_IsClosedEnum)152 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsClosedEnum)(
153     const struct upb_MiniTableField* f) {
154   return f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum;
155 }
156 
UPB_PRIVATE(_upb_MiniTableField_IsInOneof)157 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsInOneof)(
158     const struct upb_MiniTableField* f) {
159   return f->presence < 0;
160 }
161 
UPB_PRIVATE(_upb_MiniTableField_IsSubMessage)162 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsSubMessage)(
163     const struct upb_MiniTableField* f) {
164   return f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message ||
165          f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group;
166 }
167 
UPB_PRIVATE(_upb_MiniTableField_HasPresence)168 UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_HasPresence)(
169     const struct upb_MiniTableField* f) {
170   if (UPB_PRIVATE(_upb_MiniTableField_IsExtension)(f)) {
171     return UPB_PRIVATE(_upb_MiniTableField_IsScalar)(f);
172   } else {
173     return f->presence != 0;
174   }
175 }
176 
177 UPB_INLINE uint32_t
UPB_PRIVATE(_upb_MiniTableField_Number)178 UPB_PRIVATE(_upb_MiniTableField_Number)(const struct upb_MiniTableField* f) {
179   return f->UPB_ONLYBITS(number);
180 }
181 
182 UPB_INLINE uint16_t
UPB_PRIVATE(_upb_MiniTableField_Offset)183 UPB_PRIVATE(_upb_MiniTableField_Offset)(const struct upb_MiniTableField* f) {
184   return f->UPB_ONLYBITS(offset);
185 }
186 
UPB_PRIVATE(_upb_MiniTableField_OneofOffset)187 UPB_INLINE size_t UPB_PRIVATE(_upb_MiniTableField_OneofOffset)(
188     const struct upb_MiniTableField* f) {
189   UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_IsInOneof)(f));
190   return ~(ptrdiff_t)f->presence;
191 }
192 
UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)193 UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(
194     const struct upb_MiniTableField* f) {
195   UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) ==
196              kUpb_FieldRep_NativePointer);
197   UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_IsArray)(f));
198   UPB_ASSUME(f->presence == 0);
199 }
200 
UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)201 UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(
202     const struct upb_MiniTableField* f) {
203   UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) ==
204              kUpb_FieldRep_NativePointer);
205   UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_IsMap)(f));
206   UPB_ASSUME(f->presence == 0);
207 }
208 
UPB_PRIVATE(_upb_MiniTableField_ElemSizeLg2)209 UPB_INLINE size_t UPB_PRIVATE(_upb_MiniTableField_ElemSizeLg2)(
210     const struct upb_MiniTableField* f) {
211   const upb_FieldType field_type = UPB_PRIVATE(_upb_MiniTableField_Type)(f);
212   return UPB_PRIVATE(_upb_FieldType_SizeLg2)(field_type);
213 }
214 
215 // LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/mini_table_field.ts)
216 
217 #ifdef __cplusplus
218 } /* extern "C" */
219 #endif
220 
221 #include "upb/port/undef.inc"
222 
223 #endif /* UPB_MINI_TABLE_INTERNAL_FIELD_H_ */
224