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