1 /*
2 * Copyright (c) 2009-2022, Google LLC
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Google LLC nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #ifndef UPB_MINI_TABLE_COMMON_H_
29 #define UPB_MINI_TABLE_COMMON_H_
30
31 #include "upb/mini_table/field_internal.h"
32 #include "upb/mini_table/message_internal.h"
33 #include "upb/mini_table/sub_internal.h"
34
35 // Must be last.
36 #include "upb/port/def.inc"
37
38 typedef enum {
39 kUpb_FieldModifier_IsRepeated = 1 << 0,
40 kUpb_FieldModifier_IsPacked = 1 << 1,
41 kUpb_FieldModifier_IsClosedEnum = 1 << 2,
42 kUpb_FieldModifier_IsProto3Singular = 1 << 3,
43 kUpb_FieldModifier_IsRequired = 1 << 4,
44 } kUpb_FieldModifier;
45
46 typedef enum {
47 kUpb_MessageModifier_ValidateUtf8 = 1 << 0,
48 kUpb_MessageModifier_DefaultIsPacked = 1 << 1,
49 kUpb_MessageModifier_IsExtendable = 1 << 2,
50 } kUpb_MessageModifier;
51
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55
56 UPB_API const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
57 const upb_MiniTable* table, uint32_t number);
58
upb_MiniTable_GetFieldByIndex(const upb_MiniTable * t,uint32_t index)59 UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex(
60 const upb_MiniTable* t, uint32_t index) {
61 return &t->fields[index];
62 }
63
64 UPB_API upb_FieldType upb_MiniTableField_Type(const upb_MiniTableField* field);
65
upb_MiniTableField_CType(const upb_MiniTableField * f)66 UPB_API_INLINE upb_CType upb_MiniTableField_CType(const upb_MiniTableField* f) {
67 switch (f->UPB_PRIVATE(descriptortype)) {
68 case kUpb_FieldType_Double:
69 return kUpb_CType_Double;
70 case kUpb_FieldType_Float:
71 return kUpb_CType_Float;
72 case kUpb_FieldType_Int64:
73 case kUpb_FieldType_SInt64:
74 case kUpb_FieldType_SFixed64:
75 return kUpb_CType_Int64;
76 case kUpb_FieldType_Int32:
77 case kUpb_FieldType_SFixed32:
78 case kUpb_FieldType_SInt32:
79 return kUpb_CType_Int32;
80 case kUpb_FieldType_UInt64:
81 case kUpb_FieldType_Fixed64:
82 return kUpb_CType_UInt64;
83 case kUpb_FieldType_UInt32:
84 case kUpb_FieldType_Fixed32:
85 return kUpb_CType_UInt32;
86 case kUpb_FieldType_Enum:
87 return kUpb_CType_Enum;
88 case kUpb_FieldType_Bool:
89 return kUpb_CType_Bool;
90 case kUpb_FieldType_String:
91 return kUpb_CType_String;
92 case kUpb_FieldType_Bytes:
93 return kUpb_CType_Bytes;
94 case kUpb_FieldType_Group:
95 case kUpb_FieldType_Message:
96 return kUpb_CType_Message;
97 }
98 UPB_UNREACHABLE();
99 }
100
upb_MiniTableField_IsExtension(const upb_MiniTableField * field)101 UPB_API_INLINE bool upb_MiniTableField_IsExtension(
102 const upb_MiniTableField* field) {
103 return field->mode & kUpb_LabelFlags_IsExtension;
104 }
105
upb_MiniTableField_IsClosedEnum(const upb_MiniTableField * field)106 UPB_API_INLINE bool upb_MiniTableField_IsClosedEnum(
107 const upb_MiniTableField* field) {
108 return field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum;
109 }
110
upb_MiniTableField_HasPresence(const upb_MiniTableField * field)111 UPB_API_INLINE bool upb_MiniTableField_HasPresence(
112 const upb_MiniTableField* field) {
113 if (upb_MiniTableField_IsExtension(field)) {
114 return !upb_IsRepeatedOrMap(field);
115 } else {
116 return field->presence != 0;
117 }
118 }
119
120 // Returns the MiniTable for this message field. If the field is unlinked,
121 // returns NULL.
upb_MiniTable_GetSubMessageTable(const upb_MiniTable * mini_table,const upb_MiniTableField * field)122 UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable(
123 const upb_MiniTable* mini_table, const upb_MiniTableField* field) {
124 UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Message);
125 return mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg;
126 }
127
128 // Returns the MiniTableEnum for this enum field. If the field is unlinked,
129 // returns NULL.
upb_MiniTable_GetSubEnumTable(const upb_MiniTable * mini_table,const upb_MiniTableField * field)130 UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable(
131 const upb_MiniTable* mini_table, const upb_MiniTableField* field) {
132 UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Enum);
133 return mini_table->subs[field->UPB_PRIVATE(submsg_index)].subenum;
134 }
135
136 // Returns true if this MiniTable field is linked to a MiniTable for the
137 // sub-message.
upb_MiniTable_MessageFieldIsLinked(const upb_MiniTable * mini_table,const upb_MiniTableField * field)138 UPB_API_INLINE bool upb_MiniTable_MessageFieldIsLinked(
139 const upb_MiniTable* mini_table, const upb_MiniTableField* field) {
140 return upb_MiniTable_GetSubMessageTable(mini_table, field) != NULL;
141 }
142
143 // If this field is in a oneof, returns the first field in the oneof.
144 //
145 // Otherwise returns NULL.
146 //
147 // Usage:
148 // const upb_MiniTableField* field = upb_MiniTable_GetOneof(m, f);
149 // do {
150 // ..
151 // } while (upb_MiniTable_NextOneofField(m, &field);
152 //
153 const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
154 const upb_MiniTableField* f);
155
156 // Iterates to the next field in the oneof. If this is the last field in the
157 // oneof, returns false. The ordering of fields in the oneof is not
158 // guaranteed.
159 // REQUIRES: |f| is the field initialized by upb_MiniTable_GetOneof and updated
160 // by prior upb_MiniTable_NextOneofField calls.
161 bool upb_MiniTable_NextOneofField(const upb_MiniTable* m,
162 const upb_MiniTableField** f);
163
164 #ifdef __cplusplus
165 } /* extern "C" */
166 #endif
167
168 #include "upb/port/undef.inc"
169
170 #endif /* UPB_MINI_TABLE_COMMON_H_ */
171