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 #include "upb/reflection/message.h"
9
10 #include <stdint.h>
11 #include <string.h>
12
13 #include "upb/mem/arena.h"
14 #include "upb/message/accessors.h"
15 #include "upb/message/array.h"
16 #include "upb/message/internal/extension.h"
17 #include "upb/message/internal/message.h"
18 #include "upb/message/map.h"
19 #include "upb/message/message.h"
20 #include "upb/mini_table/extension.h"
21 #include "upb/mini_table/field.h"
22 #include "upb/mini_table/internal/field.h"
23 #include "upb/mini_table/internal/message.h"
24 #include "upb/mini_table/message.h"
25 #include "upb/reflection/def.h"
26 #include "upb/reflection/def_pool.h"
27 #include "upb/reflection/message_def.h"
28 #include "upb/reflection/oneof_def.h"
29
30 // Must be last.
31 #include "upb/port/def.inc"
32
upb_Message_HasFieldByDef(const upb_Message * msg,const upb_FieldDef * f)33 bool upb_Message_HasFieldByDef(const upb_Message* msg, const upb_FieldDef* f) {
34 const upb_MiniTableField* m_f = upb_FieldDef_MiniTable(f);
35 UPB_ASSERT(upb_FieldDef_HasPresence(f));
36
37 if (upb_MiniTableField_IsExtension(m_f)) {
38 return upb_Message_HasExtension(msg, (const upb_MiniTableExtension*)m_f);
39 } else {
40 return upb_Message_HasBaseField(msg, m_f);
41 }
42 }
43
upb_Message_WhichOneofByDef(const upb_Message * msg,const upb_OneofDef * o)44 const upb_FieldDef* upb_Message_WhichOneofByDef(const upb_Message* msg,
45 const upb_OneofDef* o) {
46 const upb_FieldDef* f = upb_OneofDef_Field(o, 0);
47 if (upb_OneofDef_IsSynthetic(o)) {
48 UPB_ASSERT(upb_OneofDef_FieldCount(o) == 1);
49 return upb_Message_HasFieldByDef(msg, f) ? f : NULL;
50 } else {
51 const upb_MiniTableField* field = upb_FieldDef_MiniTable(f);
52 uint32_t oneof_case = upb_Message_WhichOneofFieldNumber(msg, field);
53 f = oneof_case ? upb_OneofDef_LookupNumber(o, oneof_case) : NULL;
54 UPB_ASSERT((f != NULL) == (oneof_case != 0));
55 return f;
56 }
57 }
58
upb_Message_GetFieldByDef(const upb_Message * msg,const upb_FieldDef * f)59 upb_MessageValue upb_Message_GetFieldByDef(const upb_Message* msg,
60 const upb_FieldDef* f) {
61 upb_MessageValue default_val = upb_FieldDef_Default(f);
62 return upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), default_val);
63 }
64
upb_Message_Mutable(upb_Message * msg,const upb_FieldDef * f,upb_Arena * a)65 upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg,
66 const upb_FieldDef* f,
67 upb_Arena* a) {
68 UPB_ASSERT(!upb_Message_IsFrozen(msg));
69 UPB_ASSERT(upb_FieldDef_IsSubMessage(f) || upb_FieldDef_IsRepeated(f));
70 if (upb_FieldDef_HasPresence(f) && !upb_Message_HasFieldByDef(msg, f)) {
71 // We need to skip the upb_Message_GetFieldByDef() call in this case.
72 goto make;
73 }
74
75 upb_MessageValue val = upb_Message_GetFieldByDef(msg, f);
76 if (val.array_val) {
77 return (upb_MutableMessageValue){.array = (upb_Array*)val.array_val};
78 }
79
80 upb_MutableMessageValue ret;
81 make:
82 if (!a) return (upb_MutableMessageValue){.array = NULL};
83 if (upb_FieldDef_IsMap(f)) {
84 const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f);
85 const upb_FieldDef* key =
86 upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_KeyFieldNumber);
87 const upb_FieldDef* value =
88 upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_ValueFieldNumber);
89 ret.map =
90 upb_Map_New(a, upb_FieldDef_CType(key), upb_FieldDef_CType(value));
91 } else if (upb_FieldDef_IsRepeated(f)) {
92 ret.array = upb_Array_New(a, upb_FieldDef_CType(f));
93 } else {
94 UPB_ASSERT(upb_FieldDef_IsSubMessage(f));
95 const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
96 ret.msg = upb_Message_New(upb_MessageDef_MiniTable(m), a);
97 }
98
99 val.array_val = ret.array;
100 upb_Message_SetFieldByDef(msg, f, val, a);
101
102 return ret;
103 }
104
upb_Message_SetFieldByDef(upb_Message * msg,const upb_FieldDef * f,upb_MessageValue val,upb_Arena * a)105 bool upb_Message_SetFieldByDef(upb_Message* msg, const upb_FieldDef* f,
106 upb_MessageValue val, upb_Arena* a) {
107 UPB_ASSERT(!upb_Message_IsFrozen(msg));
108 const upb_MiniTableField* m_f = upb_FieldDef_MiniTable(f);
109
110 if (upb_MiniTableField_IsExtension(m_f)) {
111 return upb_Message_SetExtension(msg, (const upb_MiniTableExtension*)m_f,
112 &val, a);
113 } else {
114 upb_Message_SetBaseField(msg, m_f, &val);
115 return true;
116 }
117 }
118
upb_Message_ClearFieldByDef(upb_Message * msg,const upb_FieldDef * f)119 void upb_Message_ClearFieldByDef(upb_Message* msg, const upb_FieldDef* f) {
120 UPB_ASSERT(!upb_Message_IsFrozen(msg));
121 const upb_MiniTableField* m_f = upb_FieldDef_MiniTable(f);
122
123 if (upb_MiniTableField_IsExtension(m_f)) {
124 upb_Message_ClearExtension(msg, (const upb_MiniTableExtension*)m_f);
125 } else {
126 upb_Message_ClearBaseField(msg, m_f);
127 }
128 }
129
upb_Message_ClearByDef(upb_Message * msg,const upb_MessageDef * m)130 void upb_Message_ClearByDef(upb_Message* msg, const upb_MessageDef* m) {
131 UPB_ASSERT(!upb_Message_IsFrozen(msg));
132 upb_Message_Clear(msg, upb_MessageDef_MiniTable(m));
133 }
134
upb_Message_Next(const upb_Message * msg,const upb_MessageDef * m,const upb_DefPool * ext_pool,const upb_FieldDef ** out_f,upb_MessageValue * out_val,size_t * iter)135 bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m,
136 const upb_DefPool* ext_pool, const upb_FieldDef** out_f,
137 upb_MessageValue* out_val, size_t* iter) {
138 const upb_MiniTable* mt = upb_MessageDef_MiniTable(m);
139 size_t i = *iter;
140 size_t n = upb_MiniTable_FieldCount(mt);
141 upb_MessageValue zero = upb_MessageValue_Zero();
142 UPB_UNUSED(ext_pool);
143
144 // Iterate over normal fields, returning the first one that is set.
145 while (++i < n) {
146 const upb_MiniTableField* field = upb_MiniTable_GetFieldByIndex(mt, i);
147 upb_MessageValue val = upb_Message_GetField(msg, field, zero);
148
149 // Skip field if unset or empty.
150 if (upb_MiniTableField_HasPresence(field)) {
151 if (!upb_Message_HasBaseField(msg, field)) continue;
152 } else {
153 switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(field)) {
154 case kUpb_FieldMode_Map:
155 if (!val.map_val || upb_Map_Size(val.map_val) == 0) continue;
156 break;
157 case kUpb_FieldMode_Array:
158 if (!val.array_val || upb_Array_Size(val.array_val) == 0) continue;
159 break;
160 case kUpb_FieldMode_Scalar:
161 if (UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(field, &val))
162 continue;
163 break;
164 }
165 }
166
167 *out_val = val;
168 *out_f =
169 upb_MessageDef_FindFieldByNumber(m, upb_MiniTableField_Number(field));
170 *iter = i;
171 return true;
172 }
173
174 if (ext_pool) {
175 // Return any extensions that are set.
176 size_t count;
177 const upb_Extension* ext = UPB_PRIVATE(_upb_Message_Getexts)(msg, &count);
178 if (i - n < count) {
179 ext += count - 1 - (i - n);
180 memcpy(out_val, &ext->data, sizeof(*out_val));
181 *out_f = upb_DefPool_FindExtensionByMiniTable(ext_pool, ext->ext);
182 *iter = i;
183 return true;
184 }
185 }
186
187 *iter = i;
188 return false;
189 }
190
_upb_Message_DiscardUnknown(upb_Message * msg,const upb_MessageDef * m,int depth)191 bool _upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m,
192 int depth) {
193 UPB_ASSERT(!upb_Message_IsFrozen(msg));
194 size_t iter = kUpb_Message_Begin;
195 const upb_FieldDef* f;
196 upb_MessageValue val;
197 bool ret = true;
198
199 if (--depth == 0) return false;
200
201 _upb_Message_DiscardUnknown_shallow(msg);
202
203 while (upb_Message_Next(msg, m, NULL /*ext_pool*/, &f, &val, &iter)) {
204 const upb_MessageDef* subm = upb_FieldDef_MessageSubDef(f);
205 if (!subm) continue;
206 if (upb_FieldDef_IsMap(f)) {
207 const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(subm, 2);
208 const upb_MessageDef* val_m = upb_FieldDef_MessageSubDef(val_f);
209 upb_Map* map = (upb_Map*)val.map_val;
210 size_t iter = kUpb_Map_Begin;
211
212 if (!val_m) continue;
213
214 upb_MessageValue map_key, map_val;
215 while (upb_Map_Next(map, &map_key, &map_val, &iter)) {
216 if (!_upb_Message_DiscardUnknown((upb_Message*)map_val.msg_val, val_m,
217 depth)) {
218 ret = false;
219 }
220 }
221 } else if (upb_FieldDef_IsRepeated(f)) {
222 const upb_Array* arr = val.array_val;
223 size_t i, n = upb_Array_Size(arr);
224 for (i = 0; i < n; i++) {
225 upb_MessageValue elem = upb_Array_Get(arr, i);
226 if (!_upb_Message_DiscardUnknown((upb_Message*)elem.msg_val, subm,
227 depth)) {
228 ret = false;
229 }
230 }
231 } else {
232 if (!_upb_Message_DiscardUnknown((upb_Message*)val.msg_val, subm,
233 depth)) {
234 ret = false;
235 }
236 }
237 }
238
239 return ret;
240 }
241
upb_Message_DiscardUnknown(upb_Message * msg,const upb_MessageDef * m,int maxdepth)242 bool upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m,
243 int maxdepth) {
244 return _upb_Message_DiscardUnknown(msg, m, maxdepth);
245 }
246