/proc/self/cwd/upb/reflection/message_def.c
Line | Count | Source (jump to first uncovered line) |
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/hash/int_table.h" |
29 | | #include "upb/hash/str_table.h" |
30 | | #include "upb/mini_table/decode.h" |
31 | | #include "upb/reflection/def.h" |
32 | | #include "upb/reflection/def_builder_internal.h" |
33 | | #include "upb/reflection/def_type.h" |
34 | | #include "upb/reflection/desc_state_internal.h" |
35 | | #include "upb/reflection/enum_def_internal.h" |
36 | | #include "upb/reflection/extension_range_internal.h" |
37 | | #include "upb/reflection/field_def_internal.h" |
38 | | #include "upb/reflection/file_def_internal.h" |
39 | | #include "upb/reflection/message_def_internal.h" |
40 | | #include "upb/reflection/message_reserved_range_internal.h" |
41 | | #include "upb/reflection/oneof_def_internal.h" |
42 | | |
43 | | // Must be last. |
44 | | #include "upb/port/def.inc" |
45 | | |
46 | | struct upb_MessageDef { |
47 | | const UPB_DESC(MessageOptions) * opts; |
48 | | const upb_MiniTable* layout; |
49 | | const upb_FileDef* file; |
50 | | const upb_MessageDef* containing_type; |
51 | | const char* full_name; |
52 | | |
53 | | // Tables for looking up fields by number and name. |
54 | | upb_inttable itof; |
55 | | upb_strtable ntof; |
56 | | |
57 | | /* All nested defs. |
58 | | * MEM: We could save some space here by putting nested defs in a contiguous |
59 | | * region and calculating counts from offsets or vice-versa. */ |
60 | | const upb_FieldDef* fields; |
61 | | const upb_OneofDef* oneofs; |
62 | | const upb_ExtensionRange* ext_ranges; |
63 | | const upb_StringView* res_names; |
64 | | const upb_MessageDef* nested_msgs; |
65 | | const upb_MessageReservedRange* res_ranges; |
66 | | const upb_EnumDef* nested_enums; |
67 | | const upb_FieldDef* nested_exts; |
68 | | |
69 | | // TODO(salo): These counters don't need anywhere near 32 bits. |
70 | | int field_count; |
71 | | int real_oneof_count; |
72 | | int oneof_count; |
73 | | int ext_range_count; |
74 | | int res_range_count; |
75 | | int res_name_count; |
76 | | int nested_msg_count; |
77 | | int nested_enum_count; |
78 | | int nested_ext_count; |
79 | | bool in_message_set; |
80 | | bool is_sorted; |
81 | | upb_WellKnown well_known_type; |
82 | | #if UINTPTR_MAX == 0xffffffff |
83 | | uint32_t padding; // Increase size to a multiple of 8. |
84 | | #endif |
85 | | }; |
86 | | |
87 | 23.3k | static void assign_msg_wellknowntype(upb_MessageDef* m) { |
88 | 23.3k | const char* name = m->full_name; |
89 | 23.3k | if (name == NULL) { |
90 | 0 | m->well_known_type = kUpb_WellKnown_Unspecified; |
91 | 0 | return; |
92 | 0 | } |
93 | 23.3k | if (!strcmp(name, "google.protobuf.Any")) { |
94 | 0 | m->well_known_type = kUpb_WellKnown_Any; |
95 | 23.3k | } else if (!strcmp(name, "google.protobuf.FieldMask")) { |
96 | 0 | m->well_known_type = kUpb_WellKnown_FieldMask; |
97 | 23.3k | } else if (!strcmp(name, "google.protobuf.Duration")) { |
98 | 0 | m->well_known_type = kUpb_WellKnown_Duration; |
99 | 23.3k | } else if (!strcmp(name, "google.protobuf.Timestamp")) { |
100 | 0 | m->well_known_type = kUpb_WellKnown_Timestamp; |
101 | 23.3k | } else if (!strcmp(name, "google.protobuf.DoubleValue")) { |
102 | 0 | m->well_known_type = kUpb_WellKnown_DoubleValue; |
103 | 23.3k | } else if (!strcmp(name, "google.protobuf.FloatValue")) { |
104 | 0 | m->well_known_type = kUpb_WellKnown_FloatValue; |
105 | 23.3k | } else if (!strcmp(name, "google.protobuf.Int64Value")) { |
106 | 0 | m->well_known_type = kUpb_WellKnown_Int64Value; |
107 | 23.3k | } else if (!strcmp(name, "google.protobuf.UInt64Value")) { |
108 | 0 | m->well_known_type = kUpb_WellKnown_UInt64Value; |
109 | 23.3k | } else if (!strcmp(name, "google.protobuf.Int32Value")) { |
110 | 0 | m->well_known_type = kUpb_WellKnown_Int32Value; |
111 | 23.3k | } else if (!strcmp(name, "google.protobuf.UInt32Value")) { |
112 | 0 | m->well_known_type = kUpb_WellKnown_UInt32Value; |
113 | 23.3k | } else if (!strcmp(name, "google.protobuf.BoolValue")) { |
114 | 0 | m->well_known_type = kUpb_WellKnown_BoolValue; |
115 | 23.3k | } else if (!strcmp(name, "google.protobuf.StringValue")) { |
116 | 0 | m->well_known_type = kUpb_WellKnown_StringValue; |
117 | 23.3k | } else if (!strcmp(name, "google.protobuf.BytesValue")) { |
118 | 0 | m->well_known_type = kUpb_WellKnown_BytesValue; |
119 | 23.3k | } else if (!strcmp(name, "google.protobuf.Value")) { |
120 | 0 | m->well_known_type = kUpb_WellKnown_Value; |
121 | 23.3k | } else if (!strcmp(name, "google.protobuf.ListValue")) { |
122 | 0 | m->well_known_type = kUpb_WellKnown_ListValue; |
123 | 23.3k | } else if (!strcmp(name, "google.protobuf.Struct")) { |
124 | 0 | m->well_known_type = kUpb_WellKnown_Struct; |
125 | 23.3k | } else { |
126 | 23.3k | m->well_known_type = kUpb_WellKnown_Unspecified; |
127 | 23.3k | } |
128 | 23.3k | } |
129 | | |
130 | 27.8k | upb_MessageDef* _upb_MessageDef_At(const upb_MessageDef* m, int i) { |
131 | 27.8k | return (upb_MessageDef*)&m[i]; |
132 | 27.8k | } |
133 | | |
134 | 4.10k | bool _upb_MessageDef_IsValidExtensionNumber(const upb_MessageDef* m, int n) { |
135 | 4.96k | for (int i = 0; i < m->ext_range_count; i++) { |
136 | 4.88k | const upb_ExtensionRange* r = upb_MessageDef_ExtensionRange(m, i); |
137 | 4.88k | if (upb_ExtensionRange_Start(r) <= n && n < upb_ExtensionRange_End(r)) { |
138 | 4.02k | return true; |
139 | 4.02k | } |
140 | 4.88k | } |
141 | 81 | return false; |
142 | 4.10k | } |
143 | | |
144 | | const UPB_DESC(MessageOptions) * |
145 | 2.30k | upb_MessageDef_Options(const upb_MessageDef* m) { |
146 | 2.30k | return m->opts; |
147 | 2.30k | } |
148 | | |
149 | 0 | bool upb_MessageDef_HasOptions(const upb_MessageDef* m) { |
150 | 0 | return m->opts != (void*)kUpbDefOptDefault; |
151 | 0 | } |
152 | | |
153 | 25.6k | const char* upb_MessageDef_FullName(const upb_MessageDef* m) { |
154 | 25.6k | return m->full_name; |
155 | 25.6k | } |
156 | | |
157 | 12.9k | const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m) { |
158 | 12.9k | return m->file; |
159 | 12.9k | } |
160 | | |
161 | 0 | const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m) { |
162 | 0 | return m->containing_type; |
163 | 0 | } |
164 | | |
165 | 0 | const char* upb_MessageDef_Name(const upb_MessageDef* m) { |
166 | 0 | return _upb_DefBuilder_FullToShort(m->full_name); |
167 | 0 | } |
168 | | |
169 | 0 | upb_Syntax upb_MessageDef_Syntax(const upb_MessageDef* m) { |
170 | 0 | return upb_FileDef_Syntax(m->file); |
171 | 0 | } |
172 | | |
173 | | const upb_FieldDef* upb_MessageDef_FindFieldByNumber(const upb_MessageDef* m, |
174 | 0 | uint32_t i) { |
175 | 0 | upb_value val; |
176 | 0 | return upb_inttable_lookup(&m->itof, i, &val) ? upb_value_getconstptr(val) |
177 | 0 | : NULL; |
178 | 0 | } |
179 | | |
180 | | const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize( |
181 | 0 | const upb_MessageDef* m, const char* name, size_t size) { |
182 | 0 | upb_value val; |
183 | |
|
184 | 0 | if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { |
185 | 0 | return NULL; |
186 | 0 | } |
187 | | |
188 | 0 | return _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); |
189 | 0 | } |
190 | | |
191 | | const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize( |
192 | 0 | const upb_MessageDef* m, const char* name, size_t size) { |
193 | 0 | upb_value val; |
194 | |
|
195 | 0 | if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { |
196 | 0 | return NULL; |
197 | 0 | } |
198 | | |
199 | 0 | return _upb_DefType_Unpack(val, UPB_DEFTYPE_ONEOF); |
200 | 0 | } |
201 | | |
202 | | bool _upb_MessageDef_Insert(upb_MessageDef* m, const char* name, size_t len, |
203 | 51.6k | upb_value v, upb_Arena* a) { |
204 | 51.6k | return upb_strtable_insert(&m->ntof, name, len, v, a); |
205 | 51.6k | } |
206 | | |
207 | | bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m, |
208 | | const char* name, size_t len, |
209 | | const upb_FieldDef** out_f, |
210 | 1.80k | const upb_OneofDef** out_o) { |
211 | 1.80k | upb_value val; |
212 | | |
213 | 1.80k | if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { |
214 | 1.80k | return false; |
215 | 1.80k | } |
216 | | |
217 | 5 | const upb_FieldDef* f = _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); |
218 | 5 | const upb_OneofDef* o = _upb_DefType_Unpack(val, UPB_DEFTYPE_ONEOF); |
219 | 5 | if (out_f) *out_f = f; |
220 | 5 | if (out_o) *out_o = o; |
221 | 5 | return f || o; /* False if this was a JSON name. */ |
222 | 1.80k | } |
223 | | |
224 | | const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize( |
225 | 0 | const upb_MessageDef* m, const char* name, size_t size) { |
226 | 0 | upb_value val; |
227 | 0 | const upb_FieldDef* f; |
228 | |
|
229 | 0 | if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { |
230 | 0 | return NULL; |
231 | 0 | } |
232 | | |
233 | 0 | f = _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); |
234 | 0 | if (!f) f = _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD_JSONNAME); |
235 | |
|
236 | 0 | return f; |
237 | 0 | } |
238 | | |
239 | 0 | int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m) { |
240 | 0 | return m->ext_range_count; |
241 | 0 | } |
242 | | |
243 | 0 | int upb_MessageDef_ReservedRangeCount(const upb_MessageDef* m) { |
244 | 0 | return m->res_range_count; |
245 | 0 | } |
246 | | |
247 | 0 | int upb_MessageDef_ReservedNameCount(const upb_MessageDef* m) { |
248 | 0 | return m->res_name_count; |
249 | 0 | } |
250 | | |
251 | 64.4k | int upb_MessageDef_FieldCount(const upb_MessageDef* m) { |
252 | 64.4k | return m->field_count; |
253 | 64.4k | } |
254 | | |
255 | 28.6k | int upb_MessageDef_OneofCount(const upb_MessageDef* m) { |
256 | 28.6k | return m->oneof_count; |
257 | 28.6k | } |
258 | | |
259 | 0 | int upb_MessageDef_RealOneofCount(const upb_MessageDef* m) { |
260 | 0 | return m->real_oneof_count; |
261 | 0 | } |
262 | | |
263 | 23.2k | int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m) { |
264 | 23.2k | return m->nested_msg_count; |
265 | 23.2k | } |
266 | | |
267 | 0 | int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m) { |
268 | 0 | return m->nested_enum_count; |
269 | 0 | } |
270 | | |
271 | 36.2k | int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m) { |
272 | 36.2k | return m->nested_ext_count; |
273 | 36.2k | } |
274 | | |
275 | 31.2k | const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m) { |
276 | 31.2k | return m->layout; |
277 | 31.2k | } |
278 | | |
279 | | const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m, |
280 | 4.88k | int i) { |
281 | 4.88k | UPB_ASSERT(0 <= i && i < m->ext_range_count); |
282 | 4.88k | return _upb_ExtensionRange_At(m->ext_ranges, i); |
283 | 4.88k | } |
284 | | |
285 | | const upb_MessageReservedRange* upb_MessageDef_ReservedRange( |
286 | 0 | const upb_MessageDef* m, int i) { |
287 | 0 | UPB_ASSERT(0 <= i && i < m->res_range_count); |
288 | 0 | return _upb_MessageReservedRange_At(m->res_ranges, i); |
289 | 0 | } |
290 | | |
291 | 0 | upb_StringView upb_MessageDef_ReservedName(const upb_MessageDef* m, int i) { |
292 | 0 | UPB_ASSERT(0 <= i && i < m->res_name_count); |
293 | 0 | return m->res_names[i]; |
294 | 0 | } |
295 | | |
296 | 103k | const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, int i) { |
297 | 103k | UPB_ASSERT(0 <= i && i < m->field_count); |
298 | 103k | return _upb_FieldDef_At(m->fields, i); |
299 | 103k | } |
300 | | |
301 | 6.24k | const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, int i) { |
302 | 6.24k | UPB_ASSERT(0 <= i && i < m->oneof_count); |
303 | 6.24k | return _upb_OneofDef_At(m->oneofs, i); |
304 | 6.24k | } |
305 | | |
306 | | const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m, |
307 | 15.4k | int i) { |
308 | 15.4k | UPB_ASSERT(0 <= i && i < m->nested_msg_count); |
309 | 15.4k | return &m->nested_msgs[i]; |
310 | 15.4k | } |
311 | | |
312 | 0 | const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i) { |
313 | 0 | UPB_ASSERT(0 <= i && i < m->nested_enum_count); |
314 | 0 | return _upb_EnumDef_At(m->nested_enums, i); |
315 | 0 | } |
316 | | |
317 | | const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m, |
318 | 6.51k | int i) { |
319 | 6.51k | UPB_ASSERT(0 <= i && i < m->nested_ext_count); |
320 | 6.51k | return _upb_FieldDef_At(m->nested_exts, i); |
321 | 6.51k | } |
322 | | |
323 | 0 | upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m) { |
324 | 0 | return m->well_known_type; |
325 | 0 | } |
326 | | |
327 | 0 | bool _upb_MessageDef_InMessageSet(const upb_MessageDef* m) { |
328 | 0 | return m->in_message_set; |
329 | 0 | } |
330 | | |
331 | | const upb_FieldDef* upb_MessageDef_FindFieldByName(const upb_MessageDef* m, |
332 | 0 | const char* name) { |
333 | 0 | return upb_MessageDef_FindFieldByNameWithSize(m, name, strlen(name)); |
334 | 0 | } |
335 | | |
336 | | const upb_OneofDef* upb_MessageDef_FindOneofByName(const upb_MessageDef* m, |
337 | 0 | const char* name) { |
338 | 0 | return upb_MessageDef_FindOneofByNameWithSize(m, name, strlen(name)); |
339 | 0 | } |
340 | | |
341 | 13.3k | bool upb_MessageDef_IsMapEntry(const upb_MessageDef* m) { |
342 | 13.3k | return UPB_DESC(MessageOptions_map_entry)(m->opts); |
343 | 13.3k | } |
344 | | |
345 | 0 | bool upb_MessageDef_IsMessageSet(const upb_MessageDef* m) { |
346 | 0 | return UPB_DESC(MessageOptions_message_set_wire_format)(m->opts); |
347 | 0 | } |
348 | | |
349 | | static upb_MiniTable* _upb_MessageDef_MakeMiniTable(upb_DefBuilder* ctx, |
350 | 13.3k | const upb_MessageDef* m) { |
351 | 13.3k | upb_StringView desc; |
352 | | // Note: this will assign layout_index for fields, so upb_FieldDef_MiniTable() |
353 | | // is safe to call only after this call. |
354 | 13.3k | bool ok = upb_MessageDef_MiniDescriptorEncode(m, ctx->tmp_arena, &desc); |
355 | 13.3k | if (!ok) _upb_DefBuilder_OomErr(ctx); |
356 | | |
357 | 13.3k | void** scratch_data = _upb_DefPool_ScratchData(ctx->symtab); |
358 | 13.3k | size_t* scratch_size = _upb_DefPool_ScratchSize(ctx->symtab); |
359 | 13.3k | upb_MiniTable* ret = upb_MiniTable_BuildWithBuf( |
360 | 13.3k | desc.data, desc.size, ctx->platform, ctx->arena, scratch_data, |
361 | 13.3k | scratch_size, ctx->status); |
362 | 13.3k | if (!ret) _upb_DefBuilder_FailJmp(ctx); |
363 | | |
364 | 13.2k | return ret; |
365 | 13.3k | } |
366 | | |
367 | 17.0k | void _upb_MessageDef_Resolve(upb_DefBuilder* ctx, upb_MessageDef* m) { |
368 | 49.8k | for (int i = 0; i < m->field_count; i++) { |
369 | 32.8k | upb_FieldDef* f = (upb_FieldDef*)upb_MessageDef_Field(m, i); |
370 | 32.8k | _upb_FieldDef_Resolve(ctx, m->full_name, f); |
371 | 32.8k | } |
372 | | |
373 | 17.0k | m->in_message_set = false; |
374 | 20.5k | for (int i = 0; i < upb_MessageDef_NestedExtensionCount(m); i++) { |
375 | 3.48k | upb_FieldDef* ext = (upb_FieldDef*)upb_MessageDef_NestedExtension(m, i); |
376 | 3.48k | _upb_FieldDef_Resolve(ctx, m->full_name, ext); |
377 | 3.48k | if (upb_FieldDef_Type(ext) == kUpb_FieldType_Message && |
378 | 3.48k | upb_FieldDef_Label(ext) == kUpb_Label_Optional && |
379 | 3.48k | upb_FieldDef_MessageSubDef(ext) == m && |
380 | 3.48k | UPB_DESC(MessageOptions_message_set_wire_format)( |
381 | 74 | upb_MessageDef_Options(upb_FieldDef_ContainingType(ext)))) { |
382 | 41 | m->in_message_set = true; |
383 | 41 | } |
384 | 3.48k | } |
385 | | |
386 | 23.3k | for (int i = 0; i < upb_MessageDef_NestedMessageCount(m); i++) { |
387 | 6.32k | upb_MessageDef* n = (upb_MessageDef*)upb_MessageDef_NestedMessage(m, i); |
388 | 6.32k | _upb_MessageDef_Resolve(ctx, n); |
389 | 6.32k | } |
390 | 17.0k | } |
391 | | |
392 | | void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m, |
393 | 41.4k | const upb_FieldDef* f) { |
394 | 41.4k | const int32_t field_number = upb_FieldDef_Number(f); |
395 | | |
396 | 41.4k | if (field_number <= 0 || field_number > kUpb_MaxFieldNumber) { |
397 | 53 | _upb_DefBuilder_Errf(ctx, "invalid field number (%u)", field_number); |
398 | 53 | } |
399 | | |
400 | 41.3k | const char* json_name = upb_FieldDef_JsonName(f); |
401 | 41.3k | const char* shortname = upb_FieldDef_Name(f); |
402 | 41.3k | const size_t shortnamelen = strlen(shortname); |
403 | | |
404 | 41.3k | upb_value v = upb_value_constptr(f); |
405 | | |
406 | 41.3k | upb_value existing_v; |
407 | 41.3k | if (upb_strtable_lookup(&m->ntof, shortname, &existing_v)) { |
408 | 5 | _upb_DefBuilder_Errf(ctx, "duplicate field name (%s)", shortname); |
409 | 5 | } |
410 | | |
411 | 41.3k | const upb_value field_v = _upb_DefType_Pack(f, UPB_DEFTYPE_FIELD); |
412 | 41.3k | bool ok = |
413 | 41.3k | _upb_MessageDef_Insert(m, shortname, shortnamelen, field_v, ctx->arena); |
414 | 41.3k | if (!ok) _upb_DefBuilder_OomErr(ctx); |
415 | | |
416 | 41.3k | if (strcmp(shortname, json_name) != 0) { |
417 | 8.52k | if (upb_strtable_lookup(&m->ntof, json_name, &v)) { |
418 | 1 | _upb_DefBuilder_Errf(ctx, "duplicate json_name (%s)", json_name); |
419 | 1 | } |
420 | | |
421 | 8.52k | const size_t json_size = strlen(json_name); |
422 | 8.52k | const upb_value json_v = _upb_DefType_Pack(f, UPB_DEFTYPE_FIELD_JSONNAME); |
423 | 8.52k | ok = _upb_MessageDef_Insert(m, json_name, json_size, json_v, ctx->arena); |
424 | 8.52k | if (!ok) _upb_DefBuilder_OomErr(ctx); |
425 | 8.52k | } |
426 | | |
427 | 41.3k | if (upb_inttable_lookup(&m->itof, field_number, NULL)) { |
428 | 3 | _upb_DefBuilder_Errf(ctx, "duplicate field number (%u)", field_number); |
429 | 3 | } |
430 | | |
431 | 41.3k | ok = upb_inttable_insert(&m->itof, field_number, v, ctx->arena); |
432 | 41.3k | if (!ok) _upb_DefBuilder_OomErr(ctx); |
433 | 41.3k | } |
434 | | |
435 | 13.3k | void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m) { |
436 | 13.3k | if (ctx->layout == NULL) { |
437 | 13.3k | m->layout = _upb_MessageDef_MakeMiniTable(ctx, m); |
438 | 13.3k | } else { |
439 | 0 | UPB_ASSERT(ctx->msg_count < ctx->layout->msg_count); |
440 | 0 | m->layout = ctx->layout->msgs[ctx->msg_count++]; |
441 | 0 | UPB_ASSERT(m->field_count == m->layout->field_count); |
442 | | |
443 | | // We don't need the result of this call, but it will assign layout_index |
444 | | // for all the fields in O(n lg n) time. |
445 | 0 | _upb_FieldDefs_Sorted(m->fields, m->field_count, ctx->tmp_arena); |
446 | 0 | } |
447 | | |
448 | 18.0k | for (int i = 0; i < m->nested_msg_count; i++) { |
449 | 4.61k | upb_MessageDef* nested = |
450 | 4.61k | (upb_MessageDef*)upb_MessageDef_NestedMessage(m, i); |
451 | 4.61k | _upb_MessageDef_CreateMiniTable(ctx, nested); |
452 | 4.61k | } |
453 | 13.3k | } |
454 | | |
455 | | void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, |
456 | 12.7k | const upb_MessageDef* m) { |
457 | 15.8k | for (int i = 0; i < upb_MessageDef_NestedExtensionCount(m); i++) { |
458 | 3.03k | const upb_FieldDef* ext = upb_MessageDef_NestedExtension(m, i); |
459 | 3.03k | _upb_FieldDef_BuildMiniTableExtension(ctx, ext); |
460 | 3.03k | } |
461 | | |
462 | 17.2k | for (int i = 0; i < m->nested_msg_count; i++) { |
463 | 4.46k | _upb_MessageDef_LinkMiniTable(ctx, upb_MessageDef_NestedMessage(m, i)); |
464 | 4.46k | } |
465 | | |
466 | 12.7k | if (ctx->layout) return; |
467 | | |
468 | 39.8k | for (int i = 0; i < m->field_count; i++) { |
469 | 27.0k | const upb_FieldDef* f = upb_MessageDef_Field(m, i); |
470 | 27.0k | const upb_MessageDef* sub_m = upb_FieldDef_MessageSubDef(f); |
471 | 27.0k | const upb_EnumDef* sub_e = upb_FieldDef_EnumSubDef(f); |
472 | 27.0k | const int layout_index = _upb_FieldDef_LayoutIndex(f); |
473 | 27.0k | upb_MiniTable* mt = (upb_MiniTable*)upb_MessageDef_MiniTable(m); |
474 | | |
475 | 27.0k | UPB_ASSERT(layout_index < m->field_count); |
476 | 27.0k | upb_MiniTableField* mt_f = |
477 | 27.0k | (upb_MiniTableField*)&m->layout->fields[layout_index]; |
478 | 27.0k | if (sub_m) { |
479 | 208 | if (!mt->subs) { |
480 | 0 | _upb_DefBuilder_Errf(ctx, "unexpected submsg for (%s)", m->full_name); |
481 | 0 | } |
482 | 208 | UPB_ASSERT(mt_f); |
483 | 208 | UPB_ASSERT(sub_m->layout); |
484 | 208 | if (UPB_UNLIKELY(!upb_MiniTable_SetSubMessage(mt, mt_f, sub_m->layout))) { |
485 | 3 | _upb_DefBuilder_Errf(ctx, "invalid submsg for (%s)", m->full_name); |
486 | 3 | } |
487 | 26.8k | } else if (_upb_FieldDef_IsClosedEnum(f)) { |
488 | 28 | const upb_MiniTableEnum* mt_e = _upb_EnumDef_MiniTable(sub_e); |
489 | 28 | if (UPB_UNLIKELY(!upb_MiniTable_SetSubEnum(mt, mt_f, mt_e))) { |
490 | 0 | _upb_DefBuilder_Errf(ctx, "invalid subenum for (%s)", m->full_name); |
491 | 0 | } |
492 | 28 | } |
493 | 27.0k | } |
494 | | |
495 | | #ifndef NDEBUG |
496 | | for (int i = 0; i < m->field_count; i++) { |
497 | | const upb_FieldDef* f = upb_MessageDef_Field(m, i); |
498 | | const int layout_index = _upb_FieldDef_LayoutIndex(f); |
499 | | UPB_ASSERT(layout_index < m->layout->field_count); |
500 | | const upb_MiniTableField* mt_f = &m->layout->fields[layout_index]; |
501 | | UPB_ASSERT(upb_FieldDef_Type(f) == upb_MiniTableField_Type(mt_f)); |
502 | | UPB_ASSERT(upb_FieldDef_HasPresence(f) == |
503 | | upb_MiniTableField_HasPresence(mt_f)); |
504 | | } |
505 | | #endif |
506 | 12.7k | } |
507 | | |
508 | 12.9k | static uint64_t _upb_MessageDef_Modifiers(const upb_MessageDef* m) { |
509 | 12.9k | uint64_t out = 0; |
510 | 12.9k | if (upb_FileDef_Syntax(m->file) == kUpb_Syntax_Proto3) { |
511 | 595 | out |= kUpb_MessageModifier_ValidateUtf8; |
512 | 595 | out |= kUpb_MessageModifier_DefaultIsPacked; |
513 | 595 | } |
514 | 12.9k | if (m->ext_range_count) { |
515 | 710 | out |= kUpb_MessageModifier_IsExtendable; |
516 | 710 | } |
517 | 12.9k | return out; |
518 | 12.9k | } |
519 | | |
520 | | static bool _upb_MessageDef_EncodeMap(upb_DescState* s, const upb_MessageDef* m, |
521 | 295 | upb_Arena* a) { |
522 | 295 | if (m->field_count != 2) return false; |
523 | | |
524 | 280 | const upb_FieldDef* key_field = upb_MessageDef_Field(m, 0); |
525 | 280 | const upb_FieldDef* val_field = upb_MessageDef_Field(m, 1); |
526 | 280 | if (key_field == NULL || val_field == NULL) return false; |
527 | | |
528 | 280 | UPB_ASSERT(_upb_FieldDef_LayoutIndex(key_field) == 0); |
529 | 280 | UPB_ASSERT(_upb_FieldDef_LayoutIndex(val_field) == 1); |
530 | | |
531 | 280 | s->ptr = upb_MtDataEncoder_EncodeMap( |
532 | 280 | &s->e, s->ptr, upb_FieldDef_Type(key_field), upb_FieldDef_Type(val_field), |
533 | 280 | _upb_FieldDef_Modifiers(key_field), _upb_FieldDef_Modifiers(val_field)); |
534 | 280 | return true; |
535 | 280 | } |
536 | | |
537 | | static bool _upb_MessageDef_EncodeMessage(upb_DescState* s, |
538 | | const upb_MessageDef* m, |
539 | 12.9k | upb_Arena* a) { |
540 | 12.9k | const upb_FieldDef** sorted = NULL; |
541 | 12.9k | if (!m->is_sorted) { |
542 | 3.22k | sorted = _upb_FieldDefs_Sorted(m->fields, m->field_count, a); |
543 | 3.22k | if (!sorted) return false; |
544 | 3.22k | } |
545 | | |
546 | 12.9k | s->ptr = upb_MtDataEncoder_StartMessage(&s->e, s->ptr, |
547 | 12.9k | _upb_MessageDef_Modifiers(m)); |
548 | | |
549 | 41.3k | for (int i = 0; i < m->field_count; i++) { |
550 | 28.4k | const upb_FieldDef* f = sorted ? sorted[i] : upb_MessageDef_Field(m, i); |
551 | 28.4k | const upb_FieldType type = upb_FieldDef_Type(f); |
552 | 28.4k | const int number = upb_FieldDef_Number(f); |
553 | 28.4k | const uint64_t modifiers = _upb_FieldDef_Modifiers(f); |
554 | | |
555 | 28.4k | if (!_upb_DescState_Grow(s, a)) return false; |
556 | 28.4k | s->ptr = upb_MtDataEncoder_PutField(&s->e, s->ptr, type, number, modifiers); |
557 | 28.4k | } |
558 | | |
559 | 13.8k | for (int i = 0; i < m->real_oneof_count; i++) { |
560 | 970 | if (!_upb_DescState_Grow(s, a)) return false; |
561 | 970 | s->ptr = upb_MtDataEncoder_StartOneof(&s->e, s->ptr); |
562 | | |
563 | 970 | const upb_OneofDef* o = upb_MessageDef_Oneof(m, i); |
564 | 970 | const int field_count = upb_OneofDef_FieldCount(o); |
565 | 3.57k | for (int j = 0; j < field_count; j++) { |
566 | 2.60k | const int number = upb_FieldDef_Number(upb_OneofDef_Field(o, j)); |
567 | | |
568 | 2.60k | if (!_upb_DescState_Grow(s, a)) return false; |
569 | 2.60k | s->ptr = upb_MtDataEncoder_PutOneofField(&s->e, s->ptr, number); |
570 | 2.60k | } |
571 | 970 | } |
572 | | |
573 | 12.9k | return true; |
574 | 12.9k | } |
575 | | |
576 | | static bool _upb_MessageDef_EncodeMessageSet(upb_DescState* s, |
577 | | const upb_MessageDef* m, |
578 | 176 | upb_Arena* a) { |
579 | 176 | s->ptr = upb_MtDataEncoder_EncodeMessageSet(&s->e, s->ptr); |
580 | | |
581 | 176 | return true; |
582 | 176 | } |
583 | | |
584 | | bool upb_MessageDef_MiniDescriptorEncode(const upb_MessageDef* m, upb_Arena* a, |
585 | 13.3k | upb_StringView* out) { |
586 | 13.3k | upb_DescState s; |
587 | 13.3k | _upb_DescState_Init(&s); |
588 | | |
589 | 13.3k | if (!_upb_DescState_Grow(&s, a)) return false; |
590 | | |
591 | 13.3k | if (upb_MessageDef_IsMapEntry(m)) { |
592 | 295 | if (!_upb_MessageDef_EncodeMap(&s, m, a)) return false; |
593 | 13.0k | } else if (UPB_DESC(MessageOptions_message_set_wire_format)(m->opts)) { |
594 | 176 | if (!_upb_MessageDef_EncodeMessageSet(&s, m, a)) return false; |
595 | 12.9k | } else { |
596 | 12.9k | if (!_upb_MessageDef_EncodeMessage(&s, m, a)) return false; |
597 | 12.9k | } |
598 | | |
599 | 13.3k | if (!_upb_DescState_Grow(&s, a)) return false; |
600 | 13.3k | *s.ptr = '\0'; |
601 | | |
602 | 13.3k | out->data = s.buf; |
603 | 13.3k | out->size = s.ptr - s.buf; |
604 | 13.3k | return true; |
605 | 13.3k | } |
606 | | |
607 | | static upb_StringView* _upb_ReservedNames_New(upb_DefBuilder* ctx, int n, |
608 | 23.3k | const upb_StringView* protos) { |
609 | 23.3k | upb_StringView* sv = _upb_DefBuilder_Alloc(ctx, sizeof(upb_StringView) * n); |
610 | 26.8k | for (size_t i = 0; i < n; i++) { |
611 | 3.44k | sv[i].data = |
612 | 3.44k | upb_strdup2(protos[i].data, protos[i].size, _upb_DefBuilder_Arena(ctx)); |
613 | 3.44k | sv[i].size = protos[i].size; |
614 | 3.44k | } |
615 | 23.3k | return sv; |
616 | 23.3k | } |
617 | | |
618 | | static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, |
619 | | const UPB_DESC(DescriptorProto) * msg_proto, |
620 | | const upb_MessageDef* containing_type, |
621 | 24.4k | upb_MessageDef* m) { |
622 | 24.4k | const UPB_DESC(OneofDescriptorProto)* const* oneofs; |
623 | 24.4k | const UPB_DESC(FieldDescriptorProto)* const* fields; |
624 | 24.4k | const UPB_DESC(DescriptorProto_ExtensionRange)* const* ext_ranges; |
625 | 24.4k | const UPB_DESC(DescriptorProto_ReservedRange)* const* res_ranges; |
626 | 24.4k | const upb_StringView* res_names; |
627 | 24.4k | size_t n_oneof, n_field, n_enum, n_ext, n_msg; |
628 | 24.4k | size_t n_ext_range, n_res_range, n_res_name; |
629 | 24.4k | upb_StringView name; |
630 | | |
631 | | // Must happen before _upb_DefBuilder_Add() |
632 | 24.4k | m->file = _upb_DefBuilder_File(ctx); |
633 | | |
634 | 24.4k | m->containing_type = containing_type; |
635 | 24.4k | m->is_sorted = true; |
636 | | |
637 | 24.4k | name = UPB_DESC(DescriptorProto_name)(msg_proto); |
638 | | |
639 | 24.4k | m->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); |
640 | 24.4k | _upb_DefBuilder_Add(ctx, m->full_name, _upb_DefType_Pack(m, UPB_DEFTYPE_MSG)); |
641 | | |
642 | 24.4k | oneofs = UPB_DESC(DescriptorProto_oneof_decl)(msg_proto, &n_oneof); |
643 | 24.4k | fields = UPB_DESC(DescriptorProto_field)(msg_proto, &n_field); |
644 | 24.4k | ext_ranges = |
645 | 24.4k | UPB_DESC(DescriptorProto_extension_range)(msg_proto, &n_ext_range); |
646 | 24.4k | res_ranges = |
647 | 24.4k | UPB_DESC(DescriptorProto_reserved_range)(msg_proto, &n_res_range); |
648 | 24.4k | res_names = UPB_DESC(DescriptorProto_reserved_name)(msg_proto, &n_res_name); |
649 | | |
650 | 24.4k | bool ok = upb_inttable_init(&m->itof, ctx->arena); |
651 | 24.4k | if (!ok) _upb_DefBuilder_OomErr(ctx); |
652 | | |
653 | 24.4k | ok = upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena); |
654 | 24.4k | if (!ok) _upb_DefBuilder_OomErr(ctx); |
655 | | |
656 | 24.4k | UPB_DEF_SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto); |
657 | | |
658 | 24.4k | m->oneof_count = n_oneof; |
659 | 24.4k | m->oneofs = _upb_OneofDefs_New(ctx, n_oneof, oneofs, m); |
660 | | |
661 | 24.4k | m->field_count = n_field; |
662 | 24.4k | m->fields = |
663 | 24.4k | _upb_FieldDefs_New(ctx, n_field, fields, m->full_name, m, &m->is_sorted); |
664 | | |
665 | | // Message Sets may not contain fields. |
666 | 24.4k | if (UPB_UNLIKELY(UPB_DESC(MessageOptions_message_set_wire_format)(m->opts))) { |
667 | 290 | if (UPB_UNLIKELY(n_field > 0)) { |
668 | 6 | _upb_DefBuilder_Errf(ctx, "invalid message set (%s)", m->full_name); |
669 | 6 | } |
670 | 290 | } |
671 | | |
672 | 24.4k | m->ext_range_count = n_ext_range; |
673 | 24.4k | m->ext_ranges = _upb_ExtensionRanges_New(ctx, n_ext_range, ext_ranges, m); |
674 | | |
675 | 24.4k | m->res_range_count = n_res_range; |
676 | 24.4k | m->res_ranges = |
677 | 24.4k | _upb_MessageReservedRanges_New(ctx, n_res_range, res_ranges, m); |
678 | | |
679 | 24.4k | m->res_name_count = n_res_name; |
680 | 24.4k | m->res_names = _upb_ReservedNames_New(ctx, n_res_name, res_names); |
681 | | |
682 | 24.4k | const size_t synthetic_count = _upb_OneofDefs_Finalize(ctx, m); |
683 | 24.4k | m->real_oneof_count = m->oneof_count - synthetic_count; |
684 | | |
685 | 24.4k | assign_msg_wellknowntype(m); |
686 | 24.4k | upb_inttable_compact(&m->itof, ctx->arena); |
687 | | |
688 | 24.4k | const UPB_DESC(EnumDescriptorProto)* const* enums = |
689 | 24.4k | UPB_DESC(DescriptorProto_enum_type)(msg_proto, &n_enum); |
690 | 24.4k | m->nested_enum_count = n_enum; |
691 | 24.4k | m->nested_enums = _upb_EnumDefs_New(ctx, n_enum, enums, m); |
692 | | |
693 | 24.4k | const UPB_DESC(FieldDescriptorProto)* const* exts = |
694 | 24.4k | UPB_DESC(DescriptorProto_extension)(msg_proto, &n_ext); |
695 | 24.4k | m->nested_ext_count = n_ext; |
696 | 24.4k | m->nested_exts = _upb_Extensions_New(ctx, n_ext, exts, m->full_name, m); |
697 | | |
698 | 24.4k | const UPB_DESC(DescriptorProto)* const* msgs = |
699 | 24.4k | UPB_DESC(DescriptorProto_nested_type)(msg_proto, &n_msg); |
700 | 24.4k | m->nested_msg_count = n_msg; |
701 | 24.4k | m->nested_msgs = _upb_MessageDefs_New(ctx, n_msg, msgs, m); |
702 | 24.4k | } |
703 | | |
704 | | // Allocate and initialize an array of |n| message defs. |
705 | | upb_MessageDef* _upb_MessageDefs_New( |
706 | | upb_DefBuilder* ctx, int n, const UPB_DESC(DescriptorProto) * const* protos, |
707 | 29.4k | const upb_MessageDef* containing_type) { |
708 | 29.4k | _upb_DefType_CheckPadding(sizeof(upb_MessageDef)); |
709 | | |
710 | 29.4k | const char* name = containing_type ? containing_type->full_name |
711 | 29.4k | : _upb_FileDef_RawPackage(ctx->file); |
712 | | |
713 | 29.4k | upb_MessageDef* m = _upb_DefBuilder_Alloc(ctx, sizeof(upb_MessageDef) * n); |
714 | 53.8k | for (int i = 0; i < n; i++) { |
715 | 24.4k | create_msgdef(ctx, name, protos[i], containing_type, &m[i]); |
716 | 24.4k | } |
717 | 29.4k | return m; |
718 | 29.4k | } |