1 /* Amalgamated source file */
2 #include "php-upb.h"
3 /*
4 * Copyright (c) 2009-2021, Google LLC
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of Google LLC nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 * This is where we define macros used across upb.
32 *
33 * All of these macros are undef'd in port_undef.inc to avoid leaking them to
34 * users.
35 *
36 * The correct usage is:
37 *
38 * #include "upb/foobar.h"
39 * #include "upb/baz.h"
40 *
41 * // MUST be last included header.
42 * #include "upb/port_def.inc"
43 *
44 * // Code for this file.
45 * // <...>
46 *
47 * // Can be omitted for .c files, required for .h.
48 * #include "upb/port_undef.inc"
49 *
50 * This file is private and must not be included by users!
51 */
52
53 #if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
54 (defined(__cplusplus) && __cplusplus >= 201103L) || \
55 (defined(_MSC_VER) && _MSC_VER >= 1900))
56 #error upb requires C99 or C++11 or MSVC >= 2015.
57 #endif
58
59 #include <stdint.h>
60 #include <stddef.h>
61
62 #if UINTPTR_MAX == 0xffffffff
63 #define UPB_SIZE(size32, size64) size32
64 #else
65 #define UPB_SIZE(size32, size64) size64
66 #endif
67
68 /* If we always read/write as a consistent type to each address, this shouldn't
69 * violate aliasing.
70 */
71 #define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs)))
72
73 #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
74 *UPB_PTR_AT(msg, case_offset, int) == case_val \
75 ? *UPB_PTR_AT(msg, offset, fieldtype) \
76 : default
77
78 #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
79 *UPB_PTR_AT(msg, case_offset, int) = case_val; \
80 *UPB_PTR_AT(msg, offset, fieldtype) = value;
81
82 #define UPB_MAPTYPE_STRING 0
83
84 /* UPB_INLINE: inline if possible, emit standalone code if required. */
85 #ifdef __cplusplus
86 #define UPB_INLINE inline
87 #elif defined (__GNUC__) || defined(__clang__)
88 #define UPB_INLINE static __inline__
89 #else
90 #define UPB_INLINE static
91 #endif
92
93 #define UPB_MALLOC_ALIGN 8
94 #define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align))
95 #define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align))
96 #define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, UPB_MALLOC_ALIGN)
97 #define UPB_ALIGN_OF(type) offsetof (struct { char c; type member; }, member)
98
99 // Hints to the compiler about likely/unlikely branches.
100 #if defined (__GNUC__) || defined(__clang__)
101 #define UPB_LIKELY(x) __builtin_expect((bool)(x), 1)
102 #define UPB_UNLIKELY(x) __builtin_expect((bool)(x), 0)
103 #else
104 #define UPB_LIKELY(x) (x)
105 #define UPB_UNLIKELY(x) (x)
106 #endif
107
108 // Macros for function attributes on compilers that support them.
109 #ifdef __GNUC__
110 #define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
111 #define UPB_NOINLINE __attribute__((noinline))
112 #define UPB_NORETURN __attribute__((__noreturn__))
113 #define UPB_PRINTF(str, first_vararg) __attribute__((format (printf, str, first_vararg)))
114 #elif defined(_MSC_VER)
115 #define UPB_NOINLINE
116 #define UPB_FORCEINLINE
117 #define UPB_NORETURN __declspec(noreturn)
118 #define UPB_PRINTF(str, first_vararg)
119 #else /* !defined(__GNUC__) */
120 #define UPB_FORCEINLINE
121 #define UPB_NOINLINE
122 #define UPB_NORETURN
123 #define UPB_PRINTF(str, first_vararg)
124 #endif
125
126 #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
127 #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
128
129 #define UPB_UNUSED(var) (void)var
130
131 // UPB_ASSUME(): in release mode, we tell the compiler to assume this is true.
132 #ifdef NDEBUG
133 #ifdef __GNUC__
134 #define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable()
135 #elif defined _MSC_VER
136 #define UPB_ASSUME(expr) if (!(expr)) __assume(0)
137 #else
138 #define UPB_ASSUME(expr) do {} while (false && (expr))
139 #endif
140 #else
141 #define UPB_ASSUME(expr) assert(expr)
142 #endif
143
144 /* UPB_ASSERT(): in release mode, we use the expression without letting it be
145 * evaluated. This prevents "unused variable" warnings. */
146 #ifdef NDEBUG
147 #define UPB_ASSERT(expr) do {} while (false && (expr))
148 #else
149 #define UPB_ASSERT(expr) assert(expr)
150 #endif
151
152 #if defined(__GNUC__) || defined(__clang__)
153 #define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0)
154 #else
155 #define UPB_UNREACHABLE() do { assert(0); } while(0)
156 #endif
157
158 /* UPB_SETJMP() / UPB_LONGJMP(): avoid setting/restoring signal mask. */
159 #ifdef __APPLE__
160 #define UPB_SETJMP(buf) _setjmp(buf)
161 #define UPB_LONGJMP(buf, val) _longjmp(buf, val)
162 #else
163 #define UPB_SETJMP(buf) setjmp(buf)
164 #define UPB_LONGJMP(buf, val) longjmp(buf, val)
165 #endif
166
167 /* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */
168 #define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr))
169
170 /* Configure whether fasttable is switched on or not. *************************/
171
172 #ifdef __has_attribute
173 #define UPB_HAS_ATTRIBUTE(x) __has_attribute(x)
174 #else
175 #define UPB_HAS_ATTRIBUTE(x) 0
176 #endif
177
178 #if UPB_HAS_ATTRIBUTE(musttail)
179 #define UPB_MUSTTAIL __attribute__((musttail))
180 #else
181 #define UPB_MUSTTAIL
182 #endif
183
184 #undef UPB_HAS_ATTRIBUTE
185
186 /* This check is not fully robust: it does not require that we have "musttail"
187 * support available. We need tail calls to avoid consuming arbitrary amounts
188 * of stack space.
189 *
190 * GCC/Clang can mostly be trusted to generate tail calls as long as
191 * optimization is enabled, but, debug builds will not generate tail calls
192 * unless "musttail" is available.
193 *
194 * We should probably either:
195 * 1. require that the compiler supports musttail.
196 * 2. add some fallback code for when musttail isn't available (ie. return
197 * instead of tail calling). This is safe and portable, but this comes at
198 * a CPU cost.
199 */
200 #if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__)
201 #define UPB_FASTTABLE_SUPPORTED 1
202 #else
203 #define UPB_FASTTABLE_SUPPORTED 0
204 #endif
205
206 /* define UPB_ENABLE_FASTTABLE to force fast table support.
207 * This is useful when we want to ensure we are really getting fasttable,
208 * for example for testing or benchmarking. */
209 #if defined(UPB_ENABLE_FASTTABLE)
210 #if !UPB_FASTTABLE_SUPPORTED
211 #error fasttable is x86-64/ARM64 only and requires GCC or Clang.
212 #endif
213 #define UPB_FASTTABLE 1
214 /* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible.
215 * This is useful for releasing code that might be used on multiple platforms,
216 * for example the PHP or Ruby C extensions. */
217 #elif defined(UPB_TRY_ENABLE_FASTTABLE)
218 #define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED
219 #else
220 #define UPB_FASTTABLE 0
221 #endif
222
223 /* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully
224 * degrade to non-fasttable if we are using UPB_TRY_ENABLE_FASTTABLE. */
225 #if !UPB_FASTTABLE && defined(UPB_TRY_ENABLE_FASTTABLE)
226 #define UPB_FASTTABLE_INIT(...)
227 #else
228 #define UPB_FASTTABLE_INIT(...) __VA_ARGS__
229 #endif
230
231 #undef UPB_FASTTABLE_SUPPORTED
232
233 /* ASAN poisoning (for arena) *************************************************/
234
235 #if defined(__SANITIZE_ADDRESS__)
236 #define UPB_ASAN 1
237 #ifdef __cplusplus
238 extern "C" {
239 #endif
240 void __asan_poison_memory_region(void const volatile *addr, size_t size);
241 void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
242 #ifdef __cplusplus
243 } /* extern "C" */
244 #endif
245 #define UPB_POISON_MEMORY_REGION(addr, size) \
246 __asan_poison_memory_region((addr), (size))
247 #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
248 __asan_unpoison_memory_region((addr), (size))
249 #else
250 #define UPB_ASAN 0
251 #define UPB_POISON_MEMORY_REGION(addr, size) \
252 ((void)(addr), (void)(size))
253 #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
254 ((void)(addr), (void)(size))
255 #endif
256
257 /* Disable proto2 arena behavior (TEMPORARY) **********************************/
258
259 #ifdef UPB_DISABLE_PROTO2_ENUM_CHECKING
260 #define UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 1
261 #else
262 #define UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 0
263 #endif
264
265 /** upb/collections.c ************************************************************/
266
267 #include <string.h>
268
269
270 /* Strings/bytes are special-cased in maps. */
271 static char _upb_CTypeo_mapsize[12] = {
272 0,
273 1, /* kUpb_CType_Bool */
274 4, /* kUpb_CType_Float */
275 4, /* kUpb_CType_Int32 */
276 4, /* kUpb_CType_UInt32 */
277 4, /* kUpb_CType_Enum */
278 sizeof(void*), /* kUpb_CType_Message */
279 8, /* kUpb_CType_Double */
280 8, /* kUpb_CType_Int64 */
281 8, /* kUpb_CType_UInt64 */
282 0, /* kUpb_CType_String */
283 0, /* kUpb_CType_Bytes */
284 };
285
286 static const char _upb_CTypeo_sizelg2[12] = {
287 0,
288 0, /* kUpb_CType_Bool */
289 2, /* kUpb_CType_Float */
290 2, /* kUpb_CType_Int32 */
291 2, /* kUpb_CType_UInt32 */
292 2, /* kUpb_CType_Enum */
293 UPB_SIZE(2, 3), /* kUpb_CType_Message */
294 3, /* kUpb_CType_Double */
295 3, /* kUpb_CType_Int64 */
296 3, /* kUpb_CType_UInt64 */
297 UPB_SIZE(3, 4), /* kUpb_CType_String */
298 UPB_SIZE(3, 4), /* kUpb_CType_Bytes */
299 };
300
301 /** upb_Array *****************************************************************/
302
upb_Array_New(upb_Arena * a,upb_CType type)303 upb_Array* upb_Array_New(upb_Arena* a, upb_CType type) {
304 return _upb_Array_New(a, 4, _upb_CTypeo_sizelg2[type]);
305 }
306
upb_Array_Size(const upb_Array * arr)307 size_t upb_Array_Size(const upb_Array* arr) { return arr->len; }
308
upb_Array_Get(const upb_Array * arr,size_t i)309 upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i) {
310 upb_MessageValue ret;
311 const char* data = _upb_array_constptr(arr);
312 int lg2 = arr->data & 7;
313 UPB_ASSERT(i < arr->len);
314 memcpy(&ret, data + (i << lg2), 1 << lg2);
315 return ret;
316 }
317
upb_Array_Set(upb_Array * arr,size_t i,upb_MessageValue val)318 void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue val) {
319 char* data = _upb_array_ptr(arr);
320 int lg2 = arr->data & 7;
321 UPB_ASSERT(i < arr->len);
322 memcpy(data + (i << lg2), &val, 1 << lg2);
323 }
324
upb_Array_Append(upb_Array * arr,upb_MessageValue val,upb_Arena * arena)325 bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) {
326 if (!upb_Array_Resize(arr, arr->len + 1, arena)) {
327 return false;
328 }
329 upb_Array_Set(arr, arr->len - 1, val);
330 return true;
331 }
332
upb_Array_Move(upb_Array * arr,size_t dst_idx,size_t src_idx,size_t count)333 void upb_Array_Move(upb_Array* arr, size_t dst_idx, size_t src_idx,
334 size_t count) {
335 char* data = _upb_array_ptr(arr);
336 int lg2 = arr->data & 7;
337 memmove(&data[dst_idx << lg2], &data[src_idx << lg2], count << lg2);
338 }
339
upb_Array_Insert(upb_Array * arr,size_t i,size_t count,upb_Arena * arena)340 bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count,
341 upb_Arena* arena) {
342 UPB_ASSERT(i <= arr->len);
343 UPB_ASSERT(count + arr->len >= count);
344 size_t oldsize = arr->len;
345 if (!upb_Array_Resize(arr, arr->len + count, arena)) {
346 return false;
347 }
348 upb_Array_Move(arr, i + count, i, oldsize - i);
349 return true;
350 }
351
352 /*
353 * i end arr->len
354 * |------------|XXXXXXXX|--------|
355 */
upb_Array_Delete(upb_Array * arr,size_t i,size_t count)356 void upb_Array_Delete(upb_Array* arr, size_t i, size_t count) {
357 size_t end = i + count;
358 UPB_ASSERT(i <= end);
359 UPB_ASSERT(end <= arr->len);
360 upb_Array_Move(arr, i, end, arr->len - end);
361 arr->len -= count;
362 }
363
upb_Array_Resize(upb_Array * arr,size_t size,upb_Arena * arena)364 bool upb_Array_Resize(upb_Array* arr, size_t size, upb_Arena* arena) {
365 return _upb_Array_Resize(arr, size, arena);
366 }
367
368 /** upb_Map *******************************************************************/
369
upb_Map_New(upb_Arena * a,upb_CType key_type,upb_CType value_type)370 upb_Map* upb_Map_New(upb_Arena* a, upb_CType key_type, upb_CType value_type) {
371 return _upb_Map_New(a, _upb_CTypeo_mapsize[key_type],
372 _upb_CTypeo_mapsize[value_type]);
373 }
374
upb_Map_Size(const upb_Map * map)375 size_t upb_Map_Size(const upb_Map* map) { return _upb_Map_Size(map); }
376
upb_Map_Get(const upb_Map * map,upb_MessageValue key,upb_MessageValue * val)377 bool upb_Map_Get(const upb_Map* map, upb_MessageValue key,
378 upb_MessageValue* val) {
379 return _upb_Map_Get(map, &key, map->key_size, val, map->val_size);
380 }
381
upb_Map_Clear(upb_Map * map)382 void upb_Map_Clear(upb_Map* map) { _upb_Map_Clear(map); }
383
upb_Map_Insert(upb_Map * map,upb_MessageValue key,upb_MessageValue val,upb_Arena * arena)384 upb_MapInsertStatus upb_Map_Insert(upb_Map* map, upb_MessageValue key,
385 upb_MessageValue val, upb_Arena* arena) {
386 return (upb_MapInsertStatus)_upb_Map_Insert(map, &key, map->key_size, &val,
387 map->val_size, arena);
388 }
389
upb_Map_Delete(upb_Map * map,upb_MessageValue key)390 bool upb_Map_Delete(upb_Map* map, upb_MessageValue key) {
391 return _upb_Map_Delete(map, &key, map->key_size);
392 }
393
upb_MapIterator_Next(const upb_Map * map,size_t * iter)394 bool upb_MapIterator_Next(const upb_Map* map, size_t* iter) {
395 return _upb_map_next(map, iter);
396 }
397
upb_MapIterator_Done(const upb_Map * map,size_t iter)398 bool upb_MapIterator_Done(const upb_Map* map, size_t iter) {
399 upb_strtable_iter i;
400 UPB_ASSERT(iter != kUpb_Map_Begin);
401 i.t = &map->table;
402 i.index = iter;
403 return upb_strtable_done(&i);
404 }
405
406 /* Returns the key and value for this entry of the map. */
upb_MapIterator_Key(const upb_Map * map,size_t iter)407 upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter) {
408 upb_strtable_iter i;
409 upb_MessageValue ret;
410 i.t = &map->table;
411 i.index = iter;
412 _upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size);
413 return ret;
414 }
415
upb_MapIterator_Value(const upb_Map * map,size_t iter)416 upb_MessageValue upb_MapIterator_Value(const upb_Map* map, size_t iter) {
417 upb_strtable_iter i;
418 upb_MessageValue ret;
419 i.t = &map->table;
420 i.index = iter;
421 _upb_map_fromvalue(upb_strtable_iter_value(&i), &ret, map->val_size);
422 return ret;
423 }
424
425 /* void upb_MapIterator_SetValue(upb_Map *map, size_t iter, upb_MessageValue
426 * value); */
427
428 /** bazel-out/k8-fastbuild/bin/external/com_google_protobuf/google/protobuf/descriptor.upb.c ************************************************************//* This file was generated by upbc (the upb compiler) from the input
429 * file:
430 *
431 * google/protobuf/descriptor.proto
432 *
433 * Do not edit -- your changes will be discarded when the file is
434 * regenerated. */
435
436 #include <stddef.h>
437
438
439 static const upb_MiniTable_Sub google_protobuf_FileDescriptorSet_submsgs[1] = {
440 {.submsg = &google_protobuf_FileDescriptorProto_msginit},
441 };
442
443 static const upb_MiniTable_Field google_protobuf_FileDescriptorSet__fields[1] = {
444 {1, UPB_SIZE(0, 0), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
445 };
446
447 const upb_MiniTable google_protobuf_FileDescriptorSet_msginit = {
448 &google_protobuf_FileDescriptorSet_submsgs[0],
449 &google_protobuf_FileDescriptorSet__fields[0],
450 UPB_SIZE(8, 8), 1, kUpb_ExtMode_NonExtendable, 1, 255, 0,
451 };
452
453 static const upb_MiniTable_Sub google_protobuf_FileDescriptorProto_submsgs[6] = {
454 {.submsg = &google_protobuf_DescriptorProto_msginit},
455 {.submsg = &google_protobuf_EnumDescriptorProto_msginit},
456 {.submsg = &google_protobuf_ServiceDescriptorProto_msginit},
457 {.submsg = &google_protobuf_FieldDescriptorProto_msginit},
458 {.submsg = &google_protobuf_FileOptions_msginit},
459 {.submsg = &google_protobuf_SourceCodeInfo_msginit},
460 };
461
462 static const upb_MiniTable_Field google_protobuf_FileDescriptorProto__fields[12] = {
463 {1, UPB_SIZE(4, 8), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
464 {2, UPB_SIZE(12, 24), UPB_SIZE(2, 2), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
465 {3, UPB_SIZE(20, 40), UPB_SIZE(0, 0), kUpb_NoSub, 12, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
466 {4, UPB_SIZE(24, 48), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
467 {5, UPB_SIZE(28, 56), UPB_SIZE(0, 0), 1, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
468 {6, UPB_SIZE(32, 64), UPB_SIZE(0, 0), 2, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
469 {7, UPB_SIZE(36, 72), UPB_SIZE(0, 0), 3, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
470 {8, UPB_SIZE(40, 80), UPB_SIZE(3, 3), 4, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
471 {9, UPB_SIZE(44, 88), UPB_SIZE(4, 4), 5, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
472 {10, UPB_SIZE(48, 96), UPB_SIZE(0, 0), kUpb_NoSub, 5, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
473 {11, UPB_SIZE(52, 104), UPB_SIZE(0, 0), kUpb_NoSub, 5, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
474 {12, UPB_SIZE(56, 112), UPB_SIZE(5, 5), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
475 };
476
477 const upb_MiniTable google_protobuf_FileDescriptorProto_msginit = {
478 &google_protobuf_FileDescriptorProto_submsgs[0],
479 &google_protobuf_FileDescriptorProto__fields[0],
480 UPB_SIZE(64, 128), 12, kUpb_ExtMode_NonExtendable, 12, 255, 0,
481 };
482
483 static const upb_MiniTable_Sub google_protobuf_DescriptorProto_submsgs[8] = {
484 {.submsg = &google_protobuf_FieldDescriptorProto_msginit},
485 {.submsg = &google_protobuf_DescriptorProto_msginit},
486 {.submsg = &google_protobuf_EnumDescriptorProto_msginit},
487 {.submsg = &google_protobuf_DescriptorProto_ExtensionRange_msginit},
488 {.submsg = &google_protobuf_FieldDescriptorProto_msginit},
489 {.submsg = &google_protobuf_MessageOptions_msginit},
490 {.submsg = &google_protobuf_OneofDescriptorProto_msginit},
491 {.submsg = &google_protobuf_DescriptorProto_ReservedRange_msginit},
492 };
493
494 static const upb_MiniTable_Field google_protobuf_DescriptorProto__fields[10] = {
495 {1, UPB_SIZE(4, 8), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
496 {2, UPB_SIZE(12, 24), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
497 {3, UPB_SIZE(16, 32), UPB_SIZE(0, 0), 1, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
498 {4, UPB_SIZE(20, 40), UPB_SIZE(0, 0), 2, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
499 {5, UPB_SIZE(24, 48), UPB_SIZE(0, 0), 3, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
500 {6, UPB_SIZE(28, 56), UPB_SIZE(0, 0), 4, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
501 {7, UPB_SIZE(32, 64), UPB_SIZE(2, 2), 5, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
502 {8, UPB_SIZE(36, 72), UPB_SIZE(0, 0), 6, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
503 {9, UPB_SIZE(40, 80), UPB_SIZE(0, 0), 7, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
504 {10, UPB_SIZE(44, 88), UPB_SIZE(0, 0), kUpb_NoSub, 12, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
505 };
506
507 const upb_MiniTable google_protobuf_DescriptorProto_msginit = {
508 &google_protobuf_DescriptorProto_submsgs[0],
509 &google_protobuf_DescriptorProto__fields[0],
510 UPB_SIZE(48, 96), 10, kUpb_ExtMode_NonExtendable, 10, 255, 0,
511 };
512
513 static const upb_MiniTable_Sub google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
514 {.submsg = &google_protobuf_ExtensionRangeOptions_msginit},
515 };
516
517 static const upb_MiniTable_Field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = {
518 {1, UPB_SIZE(4, 4), UPB_SIZE(1, 1), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
519 {2, UPB_SIZE(8, 8), UPB_SIZE(2, 2), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
520 {3, UPB_SIZE(12, 16), UPB_SIZE(3, 3), 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
521 };
522
523 const upb_MiniTable google_protobuf_DescriptorProto_ExtensionRange_msginit = {
524 &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
525 &google_protobuf_DescriptorProto_ExtensionRange__fields[0],
526 UPB_SIZE(16, 24), 3, kUpb_ExtMode_NonExtendable, 3, 255, 0,
527 };
528
529 static const upb_MiniTable_Field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
530 {1, UPB_SIZE(4, 4), UPB_SIZE(1, 1), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
531 {2, UPB_SIZE(8, 8), UPB_SIZE(2, 2), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
532 };
533
534 const upb_MiniTable google_protobuf_DescriptorProto_ReservedRange_msginit = {
535 NULL,
536 &google_protobuf_DescriptorProto_ReservedRange__fields[0],
537 UPB_SIZE(16, 16), 2, kUpb_ExtMode_NonExtendable, 2, 255, 0,
538 };
539
540 static const upb_MiniTable_Sub google_protobuf_ExtensionRangeOptions_submsgs[1] = {
541 {.submsg = &google_protobuf_UninterpretedOption_msginit},
542 };
543
544 static const upb_MiniTable_Field google_protobuf_ExtensionRangeOptions__fields[1] = {
545 {999, UPB_SIZE(0, 0), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
546 };
547
548 const upb_MiniTable google_protobuf_ExtensionRangeOptions_msginit = {
549 &google_protobuf_ExtensionRangeOptions_submsgs[0],
550 &google_protobuf_ExtensionRangeOptions__fields[0],
551 UPB_SIZE(8, 8), 1, kUpb_ExtMode_Extendable, 0, 255, 0,
552 };
553
554 static const upb_MiniTable_Sub google_protobuf_FieldDescriptorProto_submsgs[3] = {
555 {.subenum = &google_protobuf_FieldDescriptorProto_Label_enuminit},
556 {.subenum = &google_protobuf_FieldDescriptorProto_Type_enuminit},
557 {.submsg = &google_protobuf_FieldOptions_msginit},
558 };
559
560 static const upb_MiniTable_Field google_protobuf_FieldDescriptorProto__fields[11] = {
561 {1, UPB_SIZE(24, 24), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
562 {2, UPB_SIZE(32, 40), UPB_SIZE(2, 2), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
563 {3, UPB_SIZE(4, 4), UPB_SIZE(3, 3), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
564 {4, UPB_SIZE(8, 8), UPB_SIZE(4, 4), 0, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
565 {5, UPB_SIZE(12, 12), UPB_SIZE(5, 5), 1, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
566 {6, UPB_SIZE(40, 56), UPB_SIZE(6, 6), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
567 {7, UPB_SIZE(48, 72), UPB_SIZE(7, 7), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
568 {8, UPB_SIZE(56, 88), UPB_SIZE(8, 8), 2, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
569 {9, UPB_SIZE(16, 16), UPB_SIZE(9, 9), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
570 {10, UPB_SIZE(60, 96), UPB_SIZE(10, 10), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
571 {17, UPB_SIZE(20, 20), UPB_SIZE(11, 11), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
572 };
573
574 const upb_MiniTable google_protobuf_FieldDescriptorProto_msginit = {
575 &google_protobuf_FieldDescriptorProto_submsgs[0],
576 &google_protobuf_FieldDescriptorProto__fields[0],
577 UPB_SIZE(72, 112), 11, kUpb_ExtMode_NonExtendable, 10, 255, 0,
578 };
579
580 static const upb_MiniTable_Sub google_protobuf_OneofDescriptorProto_submsgs[1] = {
581 {.submsg = &google_protobuf_OneofOptions_msginit},
582 };
583
584 static const upb_MiniTable_Field google_protobuf_OneofDescriptorProto__fields[2] = {
585 {1, UPB_SIZE(4, 8), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
586 {2, UPB_SIZE(12, 24), UPB_SIZE(2, 2), 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
587 };
588
589 const upb_MiniTable google_protobuf_OneofDescriptorProto_msginit = {
590 &google_protobuf_OneofDescriptorProto_submsgs[0],
591 &google_protobuf_OneofDescriptorProto__fields[0],
592 UPB_SIZE(16, 32), 2, kUpb_ExtMode_NonExtendable, 2, 255, 0,
593 };
594
595 static const upb_MiniTable_Sub google_protobuf_EnumDescriptorProto_submsgs[3] = {
596 {.submsg = &google_protobuf_EnumValueDescriptorProto_msginit},
597 {.submsg = &google_protobuf_EnumOptions_msginit},
598 {.submsg = &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit},
599 };
600
601 static const upb_MiniTable_Field google_protobuf_EnumDescriptorProto__fields[5] = {
602 {1, UPB_SIZE(4, 8), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
603 {2, UPB_SIZE(12, 24), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
604 {3, UPB_SIZE(16, 32), UPB_SIZE(2, 2), 1, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
605 {4, UPB_SIZE(20, 40), UPB_SIZE(0, 0), 2, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
606 {5, UPB_SIZE(24, 48), UPB_SIZE(0, 0), kUpb_NoSub, 12, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
607 };
608
609 const upb_MiniTable google_protobuf_EnumDescriptorProto_msginit = {
610 &google_protobuf_EnumDescriptorProto_submsgs[0],
611 &google_protobuf_EnumDescriptorProto__fields[0],
612 UPB_SIZE(32, 56), 5, kUpb_ExtMode_NonExtendable, 5, 255, 0,
613 };
614
615 static const upb_MiniTable_Field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
616 {1, UPB_SIZE(4, 4), UPB_SIZE(1, 1), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
617 {2, UPB_SIZE(8, 8), UPB_SIZE(2, 2), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
618 };
619
620 const upb_MiniTable google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
621 NULL,
622 &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
623 UPB_SIZE(16, 16), 2, kUpb_ExtMode_NonExtendable, 2, 255, 0,
624 };
625
626 static const upb_MiniTable_Sub google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
627 {.submsg = &google_protobuf_EnumValueOptions_msginit},
628 };
629
630 static const upb_MiniTable_Field google_protobuf_EnumValueDescriptorProto__fields[3] = {
631 {1, UPB_SIZE(8, 8), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
632 {2, UPB_SIZE(4, 4), UPB_SIZE(2, 2), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
633 {3, UPB_SIZE(16, 24), UPB_SIZE(3, 3), 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
634 };
635
636 const upb_MiniTable google_protobuf_EnumValueDescriptorProto_msginit = {
637 &google_protobuf_EnumValueDescriptorProto_submsgs[0],
638 &google_protobuf_EnumValueDescriptorProto__fields[0],
639 UPB_SIZE(24, 32), 3, kUpb_ExtMode_NonExtendable, 3, 255, 0,
640 };
641
642 static const upb_MiniTable_Sub google_protobuf_ServiceDescriptorProto_submsgs[2] = {
643 {.submsg = &google_protobuf_MethodDescriptorProto_msginit},
644 {.submsg = &google_protobuf_ServiceOptions_msginit},
645 };
646
647 static const upb_MiniTable_Field google_protobuf_ServiceDescriptorProto__fields[3] = {
648 {1, UPB_SIZE(4, 8), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
649 {2, UPB_SIZE(12, 24), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
650 {3, UPB_SIZE(16, 32), UPB_SIZE(2, 2), 1, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
651 };
652
653 const upb_MiniTable google_protobuf_ServiceDescriptorProto_msginit = {
654 &google_protobuf_ServiceDescriptorProto_submsgs[0],
655 &google_protobuf_ServiceDescriptorProto__fields[0],
656 UPB_SIZE(24, 40), 3, kUpb_ExtMode_NonExtendable, 3, 255, 0,
657 };
658
659 static const upb_MiniTable_Sub google_protobuf_MethodDescriptorProto_submsgs[1] = {
660 {.submsg = &google_protobuf_MethodOptions_msginit},
661 };
662
663 static const upb_MiniTable_Field google_protobuf_MethodDescriptorProto__fields[6] = {
664 {1, UPB_SIZE(4, 8), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
665 {2, UPB_SIZE(12, 24), UPB_SIZE(2, 2), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
666 {3, UPB_SIZE(20, 40), UPB_SIZE(3, 3), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
667 {4, UPB_SIZE(28, 56), UPB_SIZE(4, 4), 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
668 {5, UPB_SIZE(1, 1), UPB_SIZE(5, 5), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
669 {6, UPB_SIZE(2, 2), UPB_SIZE(6, 6), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
670 };
671
672 const upb_MiniTable google_protobuf_MethodDescriptorProto_msginit = {
673 &google_protobuf_MethodDescriptorProto_submsgs[0],
674 &google_protobuf_MethodDescriptorProto__fields[0],
675 UPB_SIZE(32, 64), 6, kUpb_ExtMode_NonExtendable, 6, 255, 0,
676 };
677
678 static const upb_MiniTable_Sub google_protobuf_FileOptions_submsgs[2] = {
679 {.subenum = &google_protobuf_FileOptions_OptimizeMode_enuminit},
680 {.submsg = &google_protobuf_UninterpretedOption_msginit},
681 };
682
683 static const upb_MiniTable_Field google_protobuf_FileOptions__fields[21] = {
684 {1, UPB_SIZE(20, 24), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
685 {8, UPB_SIZE(28, 40), UPB_SIZE(2, 2), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
686 {9, UPB_SIZE(4, 4), UPB_SIZE(3, 3), 0, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
687 {10, UPB_SIZE(8, 8), UPB_SIZE(4, 4), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
688 {11, UPB_SIZE(36, 56), UPB_SIZE(5, 5), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
689 {16, UPB_SIZE(9, 9), UPB_SIZE(6, 6), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
690 {17, UPB_SIZE(10, 10), UPB_SIZE(7, 7), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
691 {18, UPB_SIZE(11, 11), UPB_SIZE(8, 8), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
692 {20, UPB_SIZE(12, 12), UPB_SIZE(9, 9), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
693 {23, UPB_SIZE(13, 13), UPB_SIZE(10, 10), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
694 {27, UPB_SIZE(14, 14), UPB_SIZE(11, 11), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
695 {31, UPB_SIZE(15, 15), UPB_SIZE(12, 12), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
696 {36, UPB_SIZE(44, 72), UPB_SIZE(13, 13), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
697 {37, UPB_SIZE(52, 88), UPB_SIZE(14, 14), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
698 {39, UPB_SIZE(60, 104), UPB_SIZE(15, 15), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
699 {40, UPB_SIZE(68, 120), UPB_SIZE(16, 16), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
700 {41, UPB_SIZE(76, 136), UPB_SIZE(17, 17), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
701 {42, UPB_SIZE(16, 16), UPB_SIZE(18, 18), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
702 {44, UPB_SIZE(84, 152), UPB_SIZE(19, 19), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
703 {45, UPB_SIZE(92, 168), UPB_SIZE(20, 20), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
704 {999, UPB_SIZE(100, 184), UPB_SIZE(0, 0), 1, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
705 };
706
707 const upb_MiniTable google_protobuf_FileOptions_msginit = {
708 &google_protobuf_FileOptions_submsgs[0],
709 &google_protobuf_FileOptions__fields[0],
710 UPB_SIZE(104, 192), 21, kUpb_ExtMode_Extendable, 1, 255, 0,
711 };
712
713 static const upb_MiniTable_Sub google_protobuf_MessageOptions_submsgs[1] = {
714 {.submsg = &google_protobuf_UninterpretedOption_msginit},
715 };
716
717 static const upb_MiniTable_Field google_protobuf_MessageOptions__fields[5] = {
718 {1, UPB_SIZE(1, 1), UPB_SIZE(1, 1), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
719 {2, UPB_SIZE(2, 2), UPB_SIZE(2, 2), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
720 {3, UPB_SIZE(3, 3), UPB_SIZE(3, 3), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
721 {7, UPB_SIZE(4, 4), UPB_SIZE(4, 4), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
722 {999, UPB_SIZE(8, 8), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
723 };
724
725 const upb_MiniTable google_protobuf_MessageOptions_msginit = {
726 &google_protobuf_MessageOptions_submsgs[0],
727 &google_protobuf_MessageOptions__fields[0],
728 UPB_SIZE(16, 16), 5, kUpb_ExtMode_Extendable, 3, 255, 0,
729 };
730
731 static const upb_MiniTable_Sub google_protobuf_FieldOptions_submsgs[3] = {
732 {.subenum = &google_protobuf_FieldOptions_CType_enuminit},
733 {.subenum = &google_protobuf_FieldOptions_JSType_enuminit},
734 {.submsg = &google_protobuf_UninterpretedOption_msginit},
735 };
736
737 static const upb_MiniTable_Field google_protobuf_FieldOptions__fields[8] = {
738 {1, UPB_SIZE(4, 4), UPB_SIZE(1, 1), 0, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
739 {2, UPB_SIZE(8, 8), UPB_SIZE(2, 2), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
740 {3, UPB_SIZE(9, 9), UPB_SIZE(3, 3), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
741 {5, UPB_SIZE(10, 10), UPB_SIZE(4, 4), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
742 {6, UPB_SIZE(12, 12), UPB_SIZE(5, 5), 1, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
743 {10, UPB_SIZE(16, 16), UPB_SIZE(6, 6), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
744 {15, UPB_SIZE(17, 17), UPB_SIZE(7, 7), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
745 {999, UPB_SIZE(20, 24), UPB_SIZE(0, 0), 2, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
746 };
747
748 const upb_MiniTable google_protobuf_FieldOptions_msginit = {
749 &google_protobuf_FieldOptions_submsgs[0],
750 &google_protobuf_FieldOptions__fields[0],
751 UPB_SIZE(24, 32), 8, kUpb_ExtMode_Extendable, 3, 255, 0,
752 };
753
754 static const upb_MiniTable_Sub google_protobuf_OneofOptions_submsgs[1] = {
755 {.submsg = &google_protobuf_UninterpretedOption_msginit},
756 };
757
758 static const upb_MiniTable_Field google_protobuf_OneofOptions__fields[1] = {
759 {999, UPB_SIZE(0, 0), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
760 };
761
762 const upb_MiniTable google_protobuf_OneofOptions_msginit = {
763 &google_protobuf_OneofOptions_submsgs[0],
764 &google_protobuf_OneofOptions__fields[0],
765 UPB_SIZE(8, 8), 1, kUpb_ExtMode_Extendable, 0, 255, 0,
766 };
767
768 static const upb_MiniTable_Sub google_protobuf_EnumOptions_submsgs[1] = {
769 {.submsg = &google_protobuf_UninterpretedOption_msginit},
770 };
771
772 static const upb_MiniTable_Field google_protobuf_EnumOptions__fields[3] = {
773 {2, UPB_SIZE(1, 1), UPB_SIZE(1, 1), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
774 {3, UPB_SIZE(2, 2), UPB_SIZE(2, 2), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
775 {999, UPB_SIZE(4, 8), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
776 };
777
778 const upb_MiniTable google_protobuf_EnumOptions_msginit = {
779 &google_protobuf_EnumOptions_submsgs[0],
780 &google_protobuf_EnumOptions__fields[0],
781 UPB_SIZE(8, 16), 3, kUpb_ExtMode_Extendable, 0, 255, 0,
782 };
783
784 static const upb_MiniTable_Sub google_protobuf_EnumValueOptions_submsgs[1] = {
785 {.submsg = &google_protobuf_UninterpretedOption_msginit},
786 };
787
788 static const upb_MiniTable_Field google_protobuf_EnumValueOptions__fields[2] = {
789 {1, UPB_SIZE(1, 1), UPB_SIZE(1, 1), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
790 {999, UPB_SIZE(4, 8), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
791 };
792
793 const upb_MiniTable google_protobuf_EnumValueOptions_msginit = {
794 &google_protobuf_EnumValueOptions_submsgs[0],
795 &google_protobuf_EnumValueOptions__fields[0],
796 UPB_SIZE(8, 16), 2, kUpb_ExtMode_Extendable, 1, 255, 0,
797 };
798
799 static const upb_MiniTable_Sub google_protobuf_ServiceOptions_submsgs[1] = {
800 {.submsg = &google_protobuf_UninterpretedOption_msginit},
801 };
802
803 static const upb_MiniTable_Field google_protobuf_ServiceOptions__fields[2] = {
804 {33, UPB_SIZE(1, 1), UPB_SIZE(1, 1), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
805 {999, UPB_SIZE(4, 8), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
806 };
807
808 const upb_MiniTable google_protobuf_ServiceOptions_msginit = {
809 &google_protobuf_ServiceOptions_submsgs[0],
810 &google_protobuf_ServiceOptions__fields[0],
811 UPB_SIZE(8, 16), 2, kUpb_ExtMode_Extendable, 0, 255, 0,
812 };
813
814 static const upb_MiniTable_Sub google_protobuf_MethodOptions_submsgs[2] = {
815 {.subenum = &google_protobuf_MethodOptions_IdempotencyLevel_enuminit},
816 {.submsg = &google_protobuf_UninterpretedOption_msginit},
817 };
818
819 static const upb_MiniTable_Field google_protobuf_MethodOptions__fields[3] = {
820 {33, UPB_SIZE(1, 1), UPB_SIZE(1, 1), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
821 {34, UPB_SIZE(4, 4), UPB_SIZE(2, 2), 0, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
822 {999, UPB_SIZE(8, 8), UPB_SIZE(0, 0), 1, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
823 };
824
825 const upb_MiniTable google_protobuf_MethodOptions_msginit = {
826 &google_protobuf_MethodOptions_submsgs[0],
827 &google_protobuf_MethodOptions__fields[0],
828 UPB_SIZE(16, 16), 3, kUpb_ExtMode_Extendable, 0, 255, 0,
829 };
830
831 static const upb_MiniTable_Sub google_protobuf_UninterpretedOption_submsgs[1] = {
832 {.submsg = &google_protobuf_UninterpretedOption_NamePart_msginit},
833 };
834
835 static const upb_MiniTable_Field google_protobuf_UninterpretedOption__fields[7] = {
836 {2, UPB_SIZE(4, 8), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
837 {3, UPB_SIZE(8, 16), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
838 {4, UPB_SIZE(32, 64), UPB_SIZE(2, 2), kUpb_NoSub, 4, kUpb_FieldMode_Scalar | (kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)},
839 {5, UPB_SIZE(40, 72), UPB_SIZE(3, 3), kUpb_NoSub, 3, kUpb_FieldMode_Scalar | (kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)},
840 {6, UPB_SIZE(48, 80), UPB_SIZE(4, 4), kUpb_NoSub, 1, kUpb_FieldMode_Scalar | (kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)},
841 {7, UPB_SIZE(16, 32), UPB_SIZE(5, 5), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
842 {8, UPB_SIZE(24, 48), UPB_SIZE(6, 6), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
843 };
844
845 const upb_MiniTable google_protobuf_UninterpretedOption_msginit = {
846 &google_protobuf_UninterpretedOption_submsgs[0],
847 &google_protobuf_UninterpretedOption__fields[0],
848 UPB_SIZE(56, 88), 7, kUpb_ExtMode_NonExtendable, 0, 255, 0,
849 };
850
851 static const upb_MiniTable_Field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
852 {1, UPB_SIZE(4, 8), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
853 {2, UPB_SIZE(1, 1), UPB_SIZE(2, 2), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
854 };
855
856 const upb_MiniTable google_protobuf_UninterpretedOption_NamePart_msginit = {
857 NULL,
858 &google_protobuf_UninterpretedOption_NamePart__fields[0],
859 UPB_SIZE(16, 24), 2, kUpb_ExtMode_NonExtendable, 2, 255, 2,
860 };
861
862 static const upb_MiniTable_Sub google_protobuf_SourceCodeInfo_submsgs[1] = {
863 {.submsg = &google_protobuf_SourceCodeInfo_Location_msginit},
864 };
865
866 static const upb_MiniTable_Field google_protobuf_SourceCodeInfo__fields[1] = {
867 {1, UPB_SIZE(0, 0), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
868 };
869
870 const upb_MiniTable google_protobuf_SourceCodeInfo_msginit = {
871 &google_protobuf_SourceCodeInfo_submsgs[0],
872 &google_protobuf_SourceCodeInfo__fields[0],
873 UPB_SIZE(8, 8), 1, kUpb_ExtMode_NonExtendable, 1, 255, 0,
874 };
875
876 static const upb_MiniTable_Field google_protobuf_SourceCodeInfo_Location__fields[5] = {
877 {1, UPB_SIZE(4, 8), UPB_SIZE(0, 0), kUpb_NoSub, 5, kUpb_FieldMode_Array | kUpb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
878 {2, UPB_SIZE(8, 16), UPB_SIZE(0, 0), kUpb_NoSub, 5, kUpb_FieldMode_Array | kUpb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
879 {3, UPB_SIZE(12, 24), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
880 {4, UPB_SIZE(20, 40), UPB_SIZE(2, 2), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
881 {6, UPB_SIZE(28, 56), UPB_SIZE(0, 0), kUpb_NoSub, 12, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
882 };
883
884 const upb_MiniTable google_protobuf_SourceCodeInfo_Location_msginit = {
885 NULL,
886 &google_protobuf_SourceCodeInfo_Location__fields[0],
887 UPB_SIZE(32, 64), 5, kUpb_ExtMode_NonExtendable, 4, 255, 0,
888 };
889
890 static const upb_MiniTable_Sub google_protobuf_GeneratedCodeInfo_submsgs[1] = {
891 {.submsg = &google_protobuf_GeneratedCodeInfo_Annotation_msginit},
892 };
893
894 static const upb_MiniTable_Field google_protobuf_GeneratedCodeInfo__fields[1] = {
895 {1, UPB_SIZE(0, 0), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
896 };
897
898 const upb_MiniTable google_protobuf_GeneratedCodeInfo_msginit = {
899 &google_protobuf_GeneratedCodeInfo_submsgs[0],
900 &google_protobuf_GeneratedCodeInfo__fields[0],
901 UPB_SIZE(8, 8), 1, kUpb_ExtMode_NonExtendable, 1, 255, 0,
902 };
903
904 static const upb_MiniTable_Field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
905 {1, UPB_SIZE(12, 16), UPB_SIZE(0, 0), kUpb_NoSub, 5, kUpb_FieldMode_Array | kUpb_LabelFlags_IsPacked | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
906 {2, UPB_SIZE(16, 24), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
907 {3, UPB_SIZE(4, 4), UPB_SIZE(2, 2), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
908 {4, UPB_SIZE(8, 8), UPB_SIZE(3, 3), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
909 };
910
911 const upb_MiniTable google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
912 NULL,
913 &google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
914 UPB_SIZE(24, 40), 4, kUpb_ExtMode_NonExtendable, 4, 255, 0,
915 };
916
917 static const upb_MiniTable *messages_layout[27] = {
918 &google_protobuf_FileDescriptorSet_msginit,
919 &google_protobuf_FileDescriptorProto_msginit,
920 &google_protobuf_DescriptorProto_msginit,
921 &google_protobuf_DescriptorProto_ExtensionRange_msginit,
922 &google_protobuf_DescriptorProto_ReservedRange_msginit,
923 &google_protobuf_ExtensionRangeOptions_msginit,
924 &google_protobuf_FieldDescriptorProto_msginit,
925 &google_protobuf_OneofDescriptorProto_msginit,
926 &google_protobuf_EnumDescriptorProto_msginit,
927 &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit,
928 &google_protobuf_EnumValueDescriptorProto_msginit,
929 &google_protobuf_ServiceDescriptorProto_msginit,
930 &google_protobuf_MethodDescriptorProto_msginit,
931 &google_protobuf_FileOptions_msginit,
932 &google_protobuf_MessageOptions_msginit,
933 &google_protobuf_FieldOptions_msginit,
934 &google_protobuf_OneofOptions_msginit,
935 &google_protobuf_EnumOptions_msginit,
936 &google_protobuf_EnumValueOptions_msginit,
937 &google_protobuf_ServiceOptions_msginit,
938 &google_protobuf_MethodOptions_msginit,
939 &google_protobuf_UninterpretedOption_msginit,
940 &google_protobuf_UninterpretedOption_NamePart_msginit,
941 &google_protobuf_SourceCodeInfo_msginit,
942 &google_protobuf_SourceCodeInfo_Location_msginit,
943 &google_protobuf_GeneratedCodeInfo_msginit,
944 &google_protobuf_GeneratedCodeInfo_Annotation_msginit,
945 };
946
947 const upb_MiniTable_Enum google_protobuf_FieldDescriptorProto_Type_enuminit = {
948 NULL,
949 0x7fffeULL,
950 0,
951 };
952
953 const upb_MiniTable_Enum google_protobuf_FieldDescriptorProto_Label_enuminit = {
954 NULL,
955 0xeULL,
956 0,
957 };
958
959 const upb_MiniTable_Enum google_protobuf_FileOptions_OptimizeMode_enuminit = {
960 NULL,
961 0xeULL,
962 0,
963 };
964
965 const upb_MiniTable_Enum google_protobuf_FieldOptions_CType_enuminit = {
966 NULL,
967 0x7ULL,
968 0,
969 };
970
971 const upb_MiniTable_Enum google_protobuf_FieldOptions_JSType_enuminit = {
972 NULL,
973 0x7ULL,
974 0,
975 };
976
977 const upb_MiniTable_Enum google_protobuf_MethodOptions_IdempotencyLevel_enuminit = {
978 NULL,
979 0x7ULL,
980 0,
981 };
982
983 static const upb_MiniTable_Enum *enums_layout[6] = {
984 &google_protobuf_FieldDescriptorProto_Type_enuminit,
985 &google_protobuf_FieldDescriptorProto_Label_enuminit,
986 &google_protobuf_FileOptions_OptimizeMode_enuminit,
987 &google_protobuf_FieldOptions_CType_enuminit,
988 &google_protobuf_FieldOptions_JSType_enuminit,
989 &google_protobuf_MethodOptions_IdempotencyLevel_enuminit,
990 };
991
992 const upb_MiniTable_File google_protobuf_descriptor_proto_upb_file_layout = {
993 messages_layout,
994 enums_layout,
995 NULL,
996 27,
997 6,
998 0,
999 };
1000
1001
1002
1003 /** bazel-out/k8-fastbuild/bin/external/com_google_protobuf/google/protobuf/descriptor.upbdefs.c ************************************************************//* This file was generated by upbc (the upb compiler) from the input
1004 * file:
1005 *
1006 * google/protobuf/descriptor.proto
1007 *
1008 * Do not edit -- your changes will be discarded when the file is
1009 * regenerated. */
1010
1011
1012 static const char descriptor[7667] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p',
1013 't', 'o', 'r', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u',
1014 'f', '\"', 'M', '\n', '\021', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'S', 'e', 't', '\022', '8', '\n',
1015 '\004', 'f', 'i', 'l', 'e', '\030', '\001', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't',
1016 'o', 'b', 'u', 'f', '.', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R',
1017 '\004', 'f', 'i', 'l', 'e', '\"', '\344', '\004', '\n', '\023', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P',
1018 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022',
1019 '\030', '\n', '\007', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\007', 'p', 'a', 'c', 'k', 'a', 'g', 'e',
1020 '\022', '\036', '\n', '\n', 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\030', '\003', ' ', '\003', '(', '\t', 'R', '\n', 'd', 'e', 'p',
1021 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\022', '+', '\n', '\021', 'p', 'u', 'b', 'l', 'i', 'c', '_', 'd', 'e', 'p', 'e', 'n', 'd', 'e',
1022 'n', 'c', 'y', '\030', '\n', ' ', '\003', '(', '\005', 'R', '\020', 'p', 'u', 'b', 'l', 'i', 'c', 'D', 'e', 'p', 'e', 'n', 'd', 'e', 'n',
1023 'c', 'y', '\022', '\'', '\n', '\017', 'w', 'e', 'a', 'k', '_', 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\030', '\013', ' ', '\003',
1024 '(', '\005', 'R', '\016', 'w', 'e', 'a', 'k', 'D', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\022', 'C', '\n', '\014', 'm', 'e', 's',
1025 's', 'a', 'g', 'e', '_', 't', 'y', 'p', 'e', '\030', '\004', ' ', '\003', '(', '\013', '2', ' ', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.',
1026 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R',
1027 '\013', 'm', 'e', 's', 's', 'a', 'g', 'e', 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\t', 'e', 'n', 'u', 'm', '_', 't', 'y', 'p', 'e',
1028 '\030', '\005', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.',
1029 'E', 'n', 'u', 'm', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\010', 'e', 'n', 'u', 'm',
1030 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\007', 's', 'e', 'r', 'v', 'i', 'c', 'e', '\030', '\006', ' ', '\003', '(', '\013', '2', '\'', '.', 'g',
1031 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'D', 'e', 's',
1032 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\007', 's', 'e', 'r', 'v', 'i', 'c', 'e', '\022', 'C', '\n', '\t',
1033 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\007', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.',
1034 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P',
1035 'r', 'o', 't', 'o', 'R', '\t', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\022', '6', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n',
1036 's', '\030', '\010', ' ', '\001', '(', '\013', '2', '\034', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f',
1037 '.', 'F', 'i', 'l', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', 'I', '\n', '\020',
1038 's', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'd', 'e', '_', 'i', 'n', 'f', 'o', '\030', '\t', ' ', '\001', '(', '\013', '2', '\037', '.',
1039 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd',
1040 'e', 'I', 'n', 'f', 'o', 'R', '\016', 's', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', '\026', '\n', '\006',
1041 's', 'y', 'n', 't', 'a', 'x', '\030', '\014', ' ', '\001', '(', '\t', 'R', '\006', 's', 'y', 'n', 't', 'a', 'x', '\"', '\271', '\006', '\n', '\017',
1042 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001',
1043 ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ';', '\n', '\005', 'f', 'i', 'e', 'l', 'd', '\030', '\002', ' ', '\003', '(', '\013',
1044 '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D',
1045 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\005', 'f', 'i', 'e', 'l', 'd', '\022', 'C', '\n', '\t',
1046 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\006', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.',
1047 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P',
1048 'r', 'o', 't', 'o', 'R', '\t', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\022', 'A', '\n', '\013', 'n', 'e', 's', 't', 'e', 'd',
1049 '_', 't', 'y', 'p', 'e', '\030', '\003', ' ', '\003', '(', '\013', '2', ' ', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't',
1050 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\n', 'n', 'e', 's',
1051 't', 'e', 'd', 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\t', 'e', 'n', 'u', 'm', '_', 't', 'y', 'p', 'e', '\030', '\004', ' ', '\003', '(',
1052 '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'D',
1053 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\010', 'e', 'n', 'u', 'm', 'T', 'y', 'p', 'e', '\022',
1054 'X', '\n', '\017', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\005', ' ', '\003', '(', '\013', '2',
1055 '/', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p',
1056 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', 'R', '\016',
1057 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', '\022', 'D', '\n', '\n', 'o', 'n', 'e', 'o', 'f', '_', 'd',
1058 'e', 'c', 'l', '\030', '\010', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b',
1059 'u', 'f', '.', 'O', 'n', 'e', 'o', 'f', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\t',
1060 'o', 'n', 'e', 'o', 'f', 'D', 'e', 'c', 'l', '\022', '9', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\007', ' ', '\001', '(',
1061 '\013', '2', '\037', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 's', 's', 'a',
1062 'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', 'U', '\n', '\016', 'r', 'e', 's',
1063 'e', 'r', 'v', 'e', 'd', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\t', ' ', '\003', '(', '\013', '2', '.', '.', 'g', 'o', 'o', 'g', 'l',
1064 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't',
1065 'o', '.', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', 'R', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd',
1066 'R', 'a', 'n', 'g', 'e', '\022', '#', '\n', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'n', 'a', 'm', 'e', '\030', '\n', ' ',
1067 '\003', '(', '\t', 'R', '\014', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'N', 'a', 'm', 'e', '\032', 'z', '\n', '\016', 'E', 'x', 't', 'e',
1068 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005',
1069 'R', '\005', 's', 't', 'a', 'r', 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd',
1070 '\022', '@', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '&', '.', 'g', 'o', 'o', 'g', 'l',
1071 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e',
1072 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\032', '7', '\n', '\r', 'R', 'e', 's', 'e', 'r',
1073 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005', 'R', '\005',
1074 's', 't', 'a', 'r', 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', '\"', '|',
1075 '\n', '\025', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'X',
1076 '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007',
1077 ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n',
1078 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e',
1079 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"',
1080 '\301', '\006', '\n', '\024', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022',
1081 '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u',
1082 'm', 'b', 'e', 'r', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', 'A', '\n', '\005', 'l', 'a', 'b',
1083 'e', 'l', '\030', '\004', ' ', '\001', '(', '\016', '2', '+', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u',
1084 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'L', 'a',
1085 'b', 'e', 'l', 'R', '\005', 'l', 'a', 'b', 'e', 'l', '\022', '>', '\n', '\004', 't', 'y', 'p', 'e', '\030', '\005', ' ', '\001', '(', '\016', '2',
1086 '*', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e',
1087 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'T', 'y', 'p', 'e', 'R', '\004', 't', 'y', 'p', 'e', '\022',
1088 '\033', '\n', '\t', 't', 'y', 'p', 'e', '_', 'n', 'a', 'm', 'e', '\030', '\006', ' ', '\001', '(', '\t', 'R', '\010', 't', 'y', 'p', 'e', 'N',
1089 'a', 'm', 'e', '\022', '\032', '\n', '\010', 'e', 'x', 't', 'e', 'n', 'd', 'e', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\010', 'e', 'x',
1090 't', 'e', 'n', 'd', 'e', 'e', '\022', '#', '\n', '\r', 'd', 'e', 'f', 'a', 'u', 'l', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\007',
1091 ' ', '\001', '(', '\t', 'R', '\014', 'd', 'e', 'f', 'a', 'u', 'l', 't', 'V', 'a', 'l', 'u', 'e', '\022', '\037', '\n', '\013', 'o', 'n', 'e',
1092 'o', 'f', '_', 'i', 'n', 'd', 'e', 'x', '\030', '\t', ' ', '\001', '(', '\005', 'R', '\n', 'o', 'n', 'e', 'o', 'f', 'I', 'n', 'd', 'e',
1093 'x', '\022', '\033', '\n', '\t', 'j', 's', 'o', 'n', '_', 'n', 'a', 'm', 'e', '\030', '\n', ' ', '\001', '(', '\t', 'R', '\010', 'j', 's', 'o',
1094 'n', 'N', 'a', 'm', 'e', '\022', '7', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\010', ' ', '\001', '(', '\013', '2', '\035', '.',
1095 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i',
1096 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', '\'', '\n', '\017', 'p', 'r', 'o', 't', 'o', '3', '_', 'o', 'p',
1097 't', 'i', 'o', 'n', 'a', 'l', '\030', '\021', ' ', '\001', '(', '\010', 'R', '\016', 'p', 'r', 'o', 't', 'o', '3', 'O', 'p', 't', 'i', 'o',
1098 'n', 'a', 'l', '\"', '\266', '\002', '\n', '\004', 'T', 'y', 'p', 'e', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'D', 'O', 'U', 'B',
1099 'L', 'E', '\020', '\001', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'F', 'L', 'O', 'A', 'T', '\020', '\002', '\022', '\016', '\n', '\n', 'T',
1100 'Y', 'P', 'E', '_', 'I', 'N', 'T', '6', '4', '\020', '\003', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '6',
1101 '4', '\020', '\004', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'I', 'N', 'T', '3', '2', '\020', '\005', '\022', '\020', '\n', '\014', 'T', 'Y',
1102 'P', 'E', '_', 'F', 'I', 'X', 'E', 'D', '6', '4', '\020', '\006', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'X', 'E',
1103 'D', '3', '2', '\020', '\007', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'B', 'O', 'O', 'L', '\020', '\010', '\022', '\017', '\n', '\013', 'T',
1104 'Y', 'P', 'E', '_', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\t', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'G', 'R', 'O', 'U',
1105 'P', '\020', '\n', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '\020', '\013', '\022', '\016', '\n', '\n',
1106 'T', 'Y', 'P', 'E', '_', 'B', 'Y', 'T', 'E', 'S', '\020', '\014', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T',
1107 '3', '2', '\020', '\r', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'E', 'N', 'U', 'M', '\020', '\016', '\022', '\021', '\n', '\r', 'T', 'Y',
1108 'P', 'E', '_', 'S', 'F', 'I', 'X', 'E', 'D', '3', '2', '\020', '\017', '\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', 'S', 'F', 'I',
1109 'X', 'E', 'D', '6', '4', '\020', '\020', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '3', '2', '\020', '\021', '\022',
1110 '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '6', '4', '\020', '\022', '\"', 'C', '\n', '\005', 'L', 'a', 'b', 'e', 'l',
1111 '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_', 'O', 'P', 'T', 'I', 'O', 'N', 'A', 'L', '\020', '\001', '\022', '\022', '\n', '\016', 'L',
1112 'A', 'B', 'E', 'L', '_', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D', '\020', '\002', '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_',
1113 'R', 'E', 'P', 'E', 'A', 'T', 'E', 'D', '\020', '\003', '\"', 'c', '\n', '\024', 'O', 'n', 'e', 'o', 'f', 'D', 'e', 's', 'c', 'r', 'i',
1114 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004',
1115 'n', 'a', 'm', 'e', '\022', '7', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\002', ' ', '\001', '(', '\013', '2', '\035', '.', 'g',
1116 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't', 'i', 'o',
1117 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\343', '\002', '\n', '\023', 'E', 'n', 'u', 'm', 'D', 'e', 's', 'c', 'r',
1118 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R',
1119 '\004', 'n', 'a', 'm', 'e', '\022', '?', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', ')', '.', 'g', 'o',
1120 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'D', 'e',
1121 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\005', 'v', 'a', 'l', 'u', 'e', '\022', '6', '\n', '\007', 'o',
1122 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '\034', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o',
1123 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n',
1124 's', '\022', ']', '\n', '\016', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\004', ' ', '\003', '(', '\013',
1125 '2', '6', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'D', 'e',
1126 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'E', 'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e',
1127 'd', 'R', 'a', 'n', 'g', 'e', 'R', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '#', '\n', '\r',
1128 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'n', 'a', 'm', 'e', '\030', '\005', ' ', '\003', '(', '\t', 'R', '\014', 'r', 'e', 's', 'e',
1129 'r', 'v', 'e', 'd', 'N', 'a', 'm', 'e', '\032', ';', '\n', '\021', 'E', 'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R',
1130 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005', 'R', '\005', 's', 't', 'a', 'r',
1131 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', '\"', '\203', '\001', '\n', '\030', 'E',
1132 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022',
1133 '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u', 'm',
1134 'b', 'e', 'r', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', ';', '\n', '\007', 'o', 'p', 't', 'i',
1135 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '!', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b',
1136 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i',
1137 'o', 'n', 's', '\"', '\247', '\001', '\n', '\026', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r',
1138 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e',
1139 '\022', '>', '\n', '\006', 'm', 'e', 't', 'h', 'o', 'd', '\030', '\002', ' ', '\003', '(', '\013', '2', '&', '.', 'g', 'o', 'o', 'g', 'l', 'e',
1140 '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o',
1141 'r', 'P', 'r', 'o', 't', 'o', 'R', '\006', 'm', 'e', 't', 'h', 'o', 'd', '\022', '9', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's',
1142 '\030', '\003', ' ', '\001', '(', '\013', '2', '\037', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.',
1143 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\211',
1144 '\002', '\n', '\025', 'M', 'e', 't', 'h', 'o', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022',
1145 '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\035', '\n', '\n', 'i', 'n',
1146 'p', 'u', 't', '_', 't', 'y', 'p', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\t', 'i', 'n', 'p', 'u', 't', 'T', 'y', 'p', 'e',
1147 '\022', '\037', '\n', '\013', 'o', 'u', 't', 'p', 'u', 't', '_', 't', 'y', 'p', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\n', 'o', 'u',
1148 't', 'p', 'u', 't', 'T', 'y', 'p', 'e', '\022', '8', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\004', ' ', '\001', '(', '\013',
1149 '2', '\036', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd',
1150 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', '0', '\n', '\020', 'c', 'l', 'i', 'e', 'n',
1151 't', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
1152 '\017', 'c', 'l', 'i', 'e', 'n', 't', 'S', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\022', '0', '\n', '\020', 's', 'e', 'r', 'v', 'e',
1153 'r', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\006', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
1154 '\017', 's', 'e', 'r', 'v', 'e', 'r', 'S', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\"', '\221', '\t', '\n', '\013', 'F', 'i', 'l', 'e',
1155 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '!', '\n', '\014', 'j', 'a', 'v', 'a', '_', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\001',
1156 ' ', '\001', '(', '\t', 'R', '\013', 'j', 'a', 'v', 'a', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '0', '\n', '\024', 'j', 'a', 'v', 'a',
1157 '_', 'o', 'u', 't', 'e', 'r', '_', 'c', 'l', 'a', 's', 's', 'n', 'a', 'm', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\022', 'j',
1158 'a', 'v', 'a', 'O', 'u', 't', 'e', 'r', 'C', 'l', 'a', 's', 's', 'n', 'a', 'm', 'e', '\022', '5', '\n', '\023', 'j', 'a', 'v', 'a',
1159 '_', 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', '_', 'f', 'i', 'l', 'e', 's', '\030', '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a',
1160 'l', 's', 'e', 'R', '\021', 'j', 'a', 'v', 'a', 'M', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'F', 'i', 'l', 'e', 's', '\022', 'D', '\n',
1161 '\035', 'j', 'a', 'v', 'a', '_', 'g', 'e', 'n', 'e', 'r', 'a', 't', 'e', '_', 'e', 'q', 'u', 'a', 'l', 's', '_', 'a', 'n', 'd',
1162 '_', 'h', 'a', 's', 'h', '\030', '\024', ' ', '\001', '(', '\010', 'B', '\002', '\030', '\001', 'R', '\031', 'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e',
1163 'r', 'a', 't', 'e', 'E', 'q', 'u', 'a', 'l', 's', 'A', 'n', 'd', 'H', 'a', 's', 'h', '\022', ':', '\n', '\026', 'j', 'a', 'v', 'a',
1164 '_', 's', 't', 'r', 'i', 'n', 'g', '_', 'c', 'h', 'e', 'c', 'k', '_', 'u', 't', 'f', '8', '\030', '\033', ' ', '\001', '(', '\010', ':',
1165 '\005', 'f', 'a', 'l', 's', 'e', 'R', '\023', 'j', 'a', 'v', 'a', 'S', 't', 'r', 'i', 'n', 'g', 'C', 'h', 'e', 'c', 'k', 'U', 't',
1166 'f', '8', '\022', 'S', '\n', '\014', 'o', 'p', 't', 'i', 'm', 'i', 'z', 'e', '_', 'f', 'o', 'r', '\030', '\t', ' ', '\001', '(', '\016', '2',
1167 ')', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'l', 'e', 'O', 'p', 't',
1168 'i', 'o', 'n', 's', '.', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'M', 'o', 'd', 'e', ':', '\005', 'S', 'P', 'E', 'E', 'D', 'R',
1169 '\013', 'o', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'F', 'o', 'r', '\022', '\035', '\n', '\n', 'g', 'o', '_', 'p', 'a', 'c', 'k', 'a', 'g',
1170 'e', '\030', '\013', ' ', '\001', '(', '\t', 'R', '\t', 'g', 'o', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '5', '\n', '\023', 'c', 'c', '_',
1171 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\020', ' ', '\001', '(', '\010', ':', '\005', 'f',
1172 'a', 'l', 's', 'e', 'R', '\021', 'c', 'c', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '9',
1173 '\n', '\025', 'j', 'a', 'v', 'a', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\021',
1174 ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\023', 'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S',
1175 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '5', '\n', '\023', 'p', 'y', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r',
1176 'v', 'i', 'c', 'e', 's', '\030', '\022', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\021', 'p', 'y', 'G', 'e', 'n',
1177 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '7', '\n', '\024', 'p', 'h', 'p', '_', 'g', 'e', 'n', 'e', 'r',
1178 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '*', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
1179 '\022', 'p', 'h', 'p', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '%', '\n', '\n', 'd', 'e',
1180 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\027', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e',
1181 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '.', '\n', '\020', 'c', 'c', '_', 'e', 'n', 'a', 'b', 'l', 'e', '_', 'a', 'r', 'e',
1182 'n', 'a', 's', '\030', '\037', ' ', '\001', '(', '\010', ':', '\004', 't', 'r', 'u', 'e', 'R', '\016', 'c', 'c', 'E', 'n', 'a', 'b', 'l', 'e',
1183 'A', 'r', 'e', 'n', 'a', 's', '\022', '*', '\n', '\021', 'o', 'b', 'j', 'c', '_', 'c', 'l', 'a', 's', 's', '_', 'p', 'r', 'e', 'f',
1184 'i', 'x', '\030', '$', ' ', '\001', '(', '\t', 'R', '\017', 'o', 'b', 'j', 'c', 'C', 'l', 'a', 's', 's', 'P', 'r', 'e', 'f', 'i', 'x',
1185 '\022', ')', '\n', '\020', 'c', 's', 'h', 'a', 'r', 'p', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', '%', ' ', '\001', '(',
1186 '\t', 'R', '\017', 'c', 's', 'h', 'a', 'r', 'p', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '!', '\n', '\014', 's', 'w', 'i',
1187 'f', 't', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '\'', ' ', '\001', '(', '\t', 'R', '\013', 's', 'w', 'i', 'f', 't', 'P', 'r', 'e',
1188 'f', 'i', 'x', '\022', '(', '\n', '\020', 'p', 'h', 'p', '_', 'c', 'l', 'a', 's', 's', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '(',
1189 ' ', '\001', '(', '\t', 'R', '\016', 'p', 'h', 'p', 'C', 'l', 'a', 's', 's', 'P', 'r', 'e', 'f', 'i', 'x', '\022', '#', '\n', '\r', 'p',
1190 'h', 'p', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', ')', ' ', '\001', '(', '\t', 'R', '\014', 'p', 'h', 'p', 'N', 'a',
1191 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '4', '\n', '\026', 'p', 'h', 'p', '_', 'm', 'e', 't', 'a', 'd', 'a', 't', 'a', '_', 'n',
1192 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', ',', ' ', '\001', '(', '\t', 'R', '\024', 'p', 'h', 'p', 'M', 'e', 't', 'a', 'd', 'a',
1193 't', 'a', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '!', '\n', '\014', 'r', 'u', 'b', 'y', '_', 'p', 'a', 'c', 'k', 'a',
1194 'g', 'e', '\030', '-', ' ', '\001', '(', '\t', 'R', '\013', 'r', 'u', 'b', 'y', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', 'X', '\n', '\024',
1195 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003',
1196 '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n',
1197 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p',
1198 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', ':', '\n', '\014', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'M', 'o',
1199 'd', 'e', '\022', '\t', '\n', '\005', 'S', 'P', 'E', 'E', 'D', '\020', '\001', '\022', '\r', '\n', '\t', 'C', 'O', 'D', 'E', '_', 'S', 'I', 'Z',
1200 'E', '\020', '\002', '\022', '\020', '\n', '\014', 'L', 'I', 'T', 'E', '_', 'R', 'U', 'N', 'T', 'I', 'M', 'E', '\020', '\003', '*', '\t', '\010', '\350',
1201 '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '&', '\020', '\'', '\"', '\343', '\002', '\n', '\016', 'M', 'e', 's', 's', 'a', 'g', 'e',
1202 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '<', '\n', '\027', 'm', 'e', 's', 's', 'a', 'g', 'e', '_', 's', 'e', 't', '_', 'w', 'i',
1203 'r', 'e', '_', 'f', 'o', 'r', 'm', 'a', 't', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\024', 'm',
1204 'e', 's', 's', 'a', 'g', 'e', 'S', 'e', 't', 'W', 'i', 'r', 'e', 'F', 'o', 'r', 'm', 'a', 't', '\022', 'L', '\n', '\037', 'n', 'o',
1205 '_', 's', 't', 'a', 'n', 'd', 'a', 'r', 'd', '_', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', '_', 'a', 'c', 'c', 'e',
1206 's', 's', 'o', 'r', '\030', '\002', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\034', 'n', 'o', 'S', 't', 'a', 'n',
1207 'd', 'a', 'r', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'A', 'c', 'c', 'e', 's', 's', 'o', 'r', '\022', '%', '\n',
1208 '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R',
1209 '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '\033', '\n', '\t', 'm', 'a', 'p', '_', 'e', 'n', 't', 'r', 'y', '\030',
1210 '\007', ' ', '\001', '(', '\010', 'R', '\010', 'm', 'a', 'p', 'E', 'n', 't', 'r', 'y', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e',
1211 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g',
1212 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e',
1213 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O',
1214 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\004', '\020', '\005', 'J', '\004', '\010',
1215 '\005', '\020', '\006', 'J', '\004', '\010', '\006', '\020', '\007', 'J', '\004', '\010', '\010', '\020', '\t', 'J', '\004', '\010', '\t', '\020', '\n', '\"', '\222', '\004', '\n',
1216 '\014', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'A', '\n', '\005', 'c', 't', 'y', 'p', 'e', '\030', '\001', ' ',
1217 '\001', '(', '\016', '2', '#', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e',
1218 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'C', 'T', 'y', 'p', 'e', ':', '\006', 'S', 'T', 'R', 'I', 'N', 'G', 'R', '\005',
1219 'c', 't', 'y', 'p', 'e', '\022', '\026', '\n', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\030', '\002', ' ', '\001', '(', '\010', 'R', '\006', 'p', 'a',
1220 'c', 'k', 'e', 'd', '\022', 'G', '\n', '\006', 'j', 's', 't', 'y', 'p', 'e', '\030', '\006', ' ', '\001', '(', '\016', '2', '$', '.', 'g', 'o',
1221 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n',
1222 's', '.', 'J', 'S', 'T', 'y', 'p', 'e', ':', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A', 'L', 'R', '\006', 'j', 's', 't', 'y',
1223 'p', 'e', '\022', '\031', '\n', '\004', 'l', 'a', 'z', 'y', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\004',
1224 'l', 'a', 'z', 'y', '\022', '.', '\n', '\017', 'u', 'n', 'v', 'e', 'r', 'i', 'f', 'i', 'e', 'd', '_', 'l', 'a', 'z', 'y', '\030', '\017',
1225 ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\016', 'u', 'n', 'v', 'e', 'r', 'i', 'f', 'i', 'e', 'd', 'L', 'a',
1226 'z', 'y', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f',
1227 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '\031', '\n', '\004', 'w', 'e', 'a', 'k', '\030',
1228 '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\004', 'w', 'e', 'a', 'k', '\022', 'X', '\n', '\024', 'u', 'n', 'i',
1229 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2',
1230 '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r',
1231 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't',
1232 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', '/', '\n', '\005', 'C', 'T', 'y', 'p', 'e', '\022', '\n', '\n', '\006', 'S', 'T', 'R', 'I',
1233 'N', 'G', '\020', '\000', '\022', '\010', '\n', '\004', 'C', 'O', 'R', 'D', '\020', '\001', '\022', '\020', '\n', '\014', 'S', 'T', 'R', 'I', 'N', 'G', '_',
1234 'P', 'I', 'E', 'C', 'E', '\020', '\002', '\"', '5', '\n', '\006', 'J', 'S', 'T', 'y', 'p', 'e', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N',
1235 'O', 'R', 'M', 'A', 'L', '\020', '\000', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\001', '\022', '\r', '\n',
1236 '\t', 'J', 'S', '_', 'N', 'U', 'M', 'B', 'E', 'R', '\020', '\002', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004',
1237 '\010', '\004', '\020', '\005', '\"', 's', '\n', '\014', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'X', '\n', '\024', 'u',
1238 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(',
1239 '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't',
1240 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r',
1241 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\300', '\001', '\n',
1242 '\013', 'E', 'n', 'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '\037', '\n', '\013', 'a', 'l', 'l', 'o', 'w', '_', 'a', 'l', 'i',
1243 'a', 's', '\030', '\002', ' ', '\001', '(', '\010', 'R', '\n', 'a', 'l', 'l', 'o', 'w', 'A', 'l', 'i', 'a', 's', '\022', '%', '\n', '\n', 'd',
1244 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd',
1245 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e',
1246 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.',
1247 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't',
1248 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*',
1249 '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\005', '\020', '\006', '\"', '\236', '\001', '\n', '\020', 'E', 'n', 'u', 'm',
1250 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e',
1251 'd', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e',
1252 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n',
1253 '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f',
1254 '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i',
1255 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200',
1256 '\200', '\002', '\"', '\234', '\001', '\n', '\016', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n',
1257 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n',
1258 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't',
1259 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e',
1260 '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p',
1261 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n',
1262 '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\340', '\002', '\n', '\r', 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't',
1263 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':',
1264 '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'q', '\n', '\021', 'i', 'd', 'e',
1265 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', '_', 'l', 'e', 'v', 'e', 'l', '\030', '\"', ' ', '\001', '(', '\016', '2', '/', '.', 'g', 'o',
1266 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o',
1267 'n', 's', '.', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', ':', '\023', 'I', 'D', 'E', 'M',
1268 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', 'R', '\020', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e',
1269 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd',
1270 '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p',
1271 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i',
1272 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', 'P',
1273 '\n', '\020', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', '\022', '\027', '\n', '\023', 'I', 'D', 'E',
1274 'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\023', '\n', '\017', 'N', 'O', '_',
1275 'S', 'I', 'D', 'E', '_', 'E', 'F', 'F', 'E', 'C', 'T', 'S', '\020', '\001', '\022', '\016', '\n', '\n', 'I', 'D', 'E', 'M', 'P', 'O', 'T',
1276 'E', 'N', 'T', '\020', '\002', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\232', '\003', '\n', '\023', 'U', 'n', 'i', 'n',
1277 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\022', 'A', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\002',
1278 ' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n',
1279 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '.', 'N', 'a', 'm', 'e', 'P', 'a', 'r',
1280 't', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ')', '\n', '\020', 'i', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', '_', 'v', 'a', 'l',
1281 'u', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'i', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', 'V', 'a', 'l', 'u', 'e',
1282 '\022', ',', '\n', '\022', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\004', ' ',
1283 '\001', '(', '\004', 'R', '\020', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022',
1284 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\005', ' ', '\001', '(', '\003', 'R',
1285 '\020', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u', 'e', '\022', '!', '\n', '\014', 'd', 'o', 'u', 'b',
1286 'l', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\006', ' ', '\001', '(', '\001', 'R', '\013', 'd', 'o', 'u', 'b', 'l', 'e', 'V', 'a', 'l',
1287 'u', 'e', '\022', '!', '\n', '\014', 's', 't', 'r', 'i', 'n', 'g', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\007', ' ', '\001', '(', '\014', 'R',
1288 '\013', 's', 't', 'r', 'i', 'n', 'g', 'V', 'a', 'l', 'u', 'e', '\022', '\'', '\n', '\017', 'a', 'g', 'g', 'r', 'e', 'g', 'a', 't', 'e',
1289 '_', 'v', 'a', 'l', 'u', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\016', 'a', 'g', 'g', 'r', 'e', 'g', 'a', 't', 'e', 'V', 'a',
1290 'l', 'u', 'e', '\032', 'J', '\n', '\010', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', '\033', '\n', '\t', 'n', 'a', 'm', 'e', '_', 'p',
1291 'a', 'r', 't', '\030', '\001', ' ', '\002', '(', '\t', 'R', '\010', 'n', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', '!', '\n', '\014', 'i', 's',
1292 '_', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\002', ' ', '\002', '(', '\010', 'R', '\013', 'i', 's', 'E', 'x', 't', 'e', 'n',
1293 's', 'i', 'o', 'n', '\"', '\247', '\002', '\n', '\016', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'D',
1294 '\n', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', '\013', '2', '(', '.', 'g', 'o', 'o', 'g', 'l', 'e',
1295 '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.',
1296 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', 'R', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\032', '\316', '\001', '\n', '\010', 'L', 'o',
1297 'c', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R',
1298 '\004', 'p', 'a', 't', 'h', '\022', '\026', '\n', '\004', 's', 'p', 'a', 'n', '\030', '\002', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004',
1299 's', 'p', 'a', 'n', '\022', ')', '\n', '\020', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030',
1300 '\003', ' ', '\001', '(', '\t', 'R', '\017', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\022', '+', '\n',
1301 '\021', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\004', ' ', '\001', '(', '\t', 'R',
1302 '\020', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\022', ':', '\n', '\031', 'l', 'e', 'a', 'd',
1303 'i', 'n', 'g', '_', 'd', 'e', 't', 'a', 'c', 'h', 'e', 'd', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\006', ' ', '\003',
1304 '(', '\t', 'R', '\027', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'D', 'e', 't', 'a', 'c', 'h', 'e', 'd', 'C', 'o', 'm', 'm', 'e', 'n',
1305 't', 's', '\"', '\321', '\001', '\n', '\021', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022',
1306 'M', '\n', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o',
1307 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd',
1308 'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', 'R', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't',
1309 'i', 'o', 'n', '\032', 'm', '\n', '\n', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h',
1310 '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', '\037', '\n', '\013', 's', 'o', 'u', 'r', 'c',
1311 'e', '_', 'f', 'i', 'l', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\n', 's', 'o', 'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e', '\022',
1312 '\024', '\n', '\005', 'b', 'e', 'g', 'i', 'n', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\005', 'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003',
1313 'e', 'n', 'd', '\030', '\004', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', 'B', '~', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o',
1314 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\020', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P',
1315 'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', '-', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r',
1316 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't',
1317 'o', 'r', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\032', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r',
1318 'o', 't', 'o', 'b', 'u', 'f', '.', 'R', 'e', 'f', 'l', 'e', 'c', 't', 'i', 'o', 'n',
1319 };
1320
1321 static _upb_DefPool_Init *deps[1] = {
1322 NULL
1323 };
1324
1325 _upb_DefPool_Init google_protobuf_descriptor_proto_upbdefinit = {
1326 deps,
1327 &google_protobuf_descriptor_proto_upb_file_layout,
1328 "google/protobuf/descriptor.proto",
1329 UPB_STRINGVIEW_INIT(descriptor, 7667)
1330 };
1331
1332 /** upb/decode_fast.c ************************************************************/
1333 // Fast decoder: ~3x the speed of decode.c, but requires x86-64/ARM64.
1334 // Also the table size grows by 2x.
1335 //
1336 // Could potentially be ported to other 64-bit archs that pass at least six
1337 // arguments in registers and have 8 unused high bits in pointers.
1338 //
1339 // The overall design is to create specialized functions for every possible
1340 // field type (eg. oneof boolean field with a 1 byte tag) and then dispatch
1341 // to the specialized function as quickly as possible.
1342
1343
1344
1345 /* Must be last. */
1346
1347 #if UPB_FASTTABLE
1348
1349 // The standard set of arguments passed to each parsing function.
1350 // Thanks to x86-64 calling conventions, these will stay in registers.
1351 #define UPB_PARSE_PARAMS \
1352 upb_Decoder *d, const char *ptr, upb_Message *msg, intptr_t table, \
1353 uint64_t hasbits, uint64_t data
1354
1355 #define UPB_PARSE_ARGS d, ptr, msg, table, hasbits, data
1356
1357 #define RETURN_GENERIC(m) \
1358 /* Uncomment either of these for debugging purposes. */ \
1359 /* fprintf(stderr, m); */ \
1360 /*__builtin_trap(); */ \
1361 return fastdecode_generic(d, ptr, msg, table, hasbits, 0);
1362
1363 typedef enum {
1364 CARD_s = 0, /* Singular (optional, non-repeated) */
1365 CARD_o = 1, /* Oneof */
1366 CARD_r = 2, /* Repeated */
1367 CARD_p = 3 /* Packed Repeated */
1368 } upb_card;
1369
1370 UPB_NOINLINE
fastdecode_isdonefallback(UPB_PARSE_PARAMS)1371 static const char* fastdecode_isdonefallback(UPB_PARSE_PARAMS) {
1372 int overrun = data;
1373 int status;
1374 ptr = decode_isdonefallback_inl(d, ptr, overrun, &status);
1375 if (ptr == NULL) {
1376 return fastdecode_err(d, status);
1377 }
1378 data = fastdecode_loadtag(ptr);
1379 UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
1380 }
1381
1382 UPB_FORCEINLINE
fastdecode_dispatch(UPB_PARSE_PARAMS)1383 static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) {
1384 if (UPB_UNLIKELY(ptr >= d->limit_ptr)) {
1385 int overrun = ptr - d->end;
1386 if (UPB_LIKELY(overrun == d->limit)) {
1387 // Parse is finished.
1388 *(uint32_t*)msg |= hasbits; // Sync hasbits.
1389 const upb_MiniTable* l = decode_totablep(table);
1390 return UPB_UNLIKELY(l->required_count)
1391 ? decode_checkrequired(d, ptr, msg, l)
1392 : ptr;
1393 } else {
1394 data = overrun;
1395 UPB_MUSTTAIL return fastdecode_isdonefallback(UPB_PARSE_ARGS);
1396 }
1397 }
1398
1399 // Read two bytes of tag data (for a one-byte tag, the high byte is junk).
1400 data = fastdecode_loadtag(ptr);
1401 UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
1402 }
1403
1404 UPB_FORCEINLINE
fastdecode_checktag(uint16_t data,int tagbytes)1405 static bool fastdecode_checktag(uint16_t data, int tagbytes) {
1406 if (tagbytes == 1) {
1407 return (data & 0xff) == 0;
1408 } else {
1409 return data == 0;
1410 }
1411 }
1412
1413 UPB_FORCEINLINE
fastdecode_longsize(const char * ptr,int * size)1414 static const char* fastdecode_longsize(const char* ptr, int* size) {
1415 int i;
1416 UPB_ASSERT(*size & 0x80);
1417 *size &= 0xff;
1418 for (i = 0; i < 3; i++) {
1419 ptr++;
1420 size_t byte = (uint8_t)ptr[-1];
1421 *size += (byte - 1) << (7 + 7 * i);
1422 if (UPB_LIKELY((byte & 0x80) == 0)) return ptr;
1423 }
1424 ptr++;
1425 size_t byte = (uint8_t)ptr[-1];
1426 // len is limited by 2gb not 4gb, hence 8 and not 16 as normally expected
1427 // for a 32 bit varint.
1428 if (UPB_UNLIKELY(byte >= 8)) return NULL;
1429 *size += (byte - 1) << 28;
1430 return ptr;
1431 }
1432
1433 UPB_FORCEINLINE
fastdecode_boundscheck(const char * ptr,size_t len,const char * end)1434 static bool fastdecode_boundscheck(const char* ptr, size_t len,
1435 const char* end) {
1436 uintptr_t uptr = (uintptr_t)ptr;
1437 uintptr_t uend = (uintptr_t)end + 16;
1438 uintptr_t res = uptr + len;
1439 return res < uptr || res > uend;
1440 }
1441
1442 UPB_FORCEINLINE
fastdecode_boundscheck2(const char * ptr,size_t len,const char * end)1443 static bool fastdecode_boundscheck2(const char* ptr, size_t len,
1444 const char* end) {
1445 // This is one extra branch compared to the more normal:
1446 // return (size_t)(end - ptr) < size;
1447 // However it is one less computation if we are just about to use "ptr + len":
1448 // https://godbolt.org/z/35YGPz
1449 // In microbenchmarks this shows an overall 4% improvement.
1450 uintptr_t uptr = (uintptr_t)ptr;
1451 uintptr_t uend = (uintptr_t)end;
1452 uintptr_t res = uptr + len;
1453 return res < uptr || res > uend;
1454 }
1455
1456 typedef const char* fastdecode_delimfunc(upb_Decoder* d, const char* ptr,
1457 void* ctx);
1458
1459 UPB_FORCEINLINE
fastdecode_delimited(upb_Decoder * d,const char * ptr,fastdecode_delimfunc * func,void * ctx)1460 static const char* fastdecode_delimited(upb_Decoder* d, const char* ptr,
1461 fastdecode_delimfunc* func, void* ctx) {
1462 ptr++;
1463 int len = (int8_t)ptr[-1];
1464 if (fastdecode_boundscheck2(ptr, len, d->limit_ptr)) {
1465 // Slow case: Sub-message is >=128 bytes and/or exceeds the current buffer.
1466 // If it exceeds the buffer limit, limit/limit_ptr will change during
1467 // sub-message parsing, so we need to preserve delta, not limit.
1468 if (UPB_UNLIKELY(len & 0x80)) {
1469 // Size varint >1 byte (length >= 128).
1470 ptr = fastdecode_longsize(ptr, &len);
1471 if (!ptr) {
1472 // Corrupt wire format: size exceeded INT_MAX.
1473 return NULL;
1474 }
1475 }
1476 if (ptr - d->end + (int)len > d->limit) {
1477 // Corrupt wire format: invalid limit.
1478 return NULL;
1479 }
1480 int delta = decode_pushlimit(d, ptr, len);
1481 ptr = func(d, ptr, ctx);
1482 decode_poplimit(d, ptr, delta);
1483 } else {
1484 // Fast case: Sub-message is <128 bytes and fits in the current buffer.
1485 // This means we can preserve limit/limit_ptr verbatim.
1486 const char* saved_limit_ptr = d->limit_ptr;
1487 int saved_limit = d->limit;
1488 d->limit_ptr = ptr + len;
1489 d->limit = d->limit_ptr - d->end;
1490 UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
1491 ptr = func(d, ptr, ctx);
1492 d->limit_ptr = saved_limit_ptr;
1493 d->limit = saved_limit;
1494 UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
1495 }
1496 return ptr;
1497 }
1498
1499 /* singular, oneof, repeated field handling ***********************************/
1500
1501 typedef struct {
1502 upb_Array* arr;
1503 void* end;
1504 } fastdecode_arr;
1505
1506 typedef enum {
1507 FD_NEXT_ATLIMIT,
1508 FD_NEXT_SAMEFIELD,
1509 FD_NEXT_OTHERFIELD
1510 } fastdecode_next;
1511
1512 typedef struct {
1513 void* dst;
1514 fastdecode_next next;
1515 uint32_t tag;
1516 } fastdecode_nextret;
1517
1518 UPB_FORCEINLINE
fastdecode_resizearr(upb_Decoder * d,void * dst,fastdecode_arr * farr,int valbytes)1519 static void* fastdecode_resizearr(upb_Decoder* d, void* dst,
1520 fastdecode_arr* farr, int valbytes) {
1521 if (UPB_UNLIKELY(dst == farr->end)) {
1522 size_t old_size = farr->arr->size;
1523 size_t old_bytes = old_size * valbytes;
1524 size_t new_size = old_size * 2;
1525 size_t new_bytes = new_size * valbytes;
1526 char* old_ptr = _upb_array_ptr(farr->arr);
1527 char* new_ptr = upb_Arena_Realloc(&d->arena, old_ptr, old_bytes, new_bytes);
1528 uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
1529 farr->arr->size = new_size;
1530 farr->arr->data = _upb_array_tagptr(new_ptr, elem_size_lg2);
1531 dst = (void*)(new_ptr + (old_size * valbytes));
1532 farr->end = (void*)(new_ptr + (new_size * valbytes));
1533 }
1534 return dst;
1535 }
1536
1537 UPB_FORCEINLINE
fastdecode_tagmatch(uint32_t tag,uint64_t data,int tagbytes)1538 static bool fastdecode_tagmatch(uint32_t tag, uint64_t data, int tagbytes) {
1539 if (tagbytes == 1) {
1540 return (uint8_t)tag == (uint8_t)data;
1541 } else {
1542 return (uint16_t)tag == (uint16_t)data;
1543 }
1544 }
1545
1546 UPB_FORCEINLINE
fastdecode_commitarr(void * dst,fastdecode_arr * farr,int valbytes)1547 static void fastdecode_commitarr(void* dst, fastdecode_arr* farr,
1548 int valbytes) {
1549 farr->arr->len =
1550 (size_t)((char*)dst - (char*)_upb_array_ptr(farr->arr)) / valbytes;
1551 }
1552
1553 UPB_FORCEINLINE
fastdecode_nextrepeated(upb_Decoder * d,void * dst,const char ** ptr,fastdecode_arr * farr,uint64_t data,int tagbytes,int valbytes)1554 static fastdecode_nextret fastdecode_nextrepeated(upb_Decoder* d, void* dst,
1555 const char** ptr,
1556 fastdecode_arr* farr,
1557 uint64_t data, int tagbytes,
1558 int valbytes) {
1559 fastdecode_nextret ret;
1560 dst = (char*)dst + valbytes;
1561
1562 if (UPB_LIKELY(!decode_isdone(d, ptr))) {
1563 ret.tag = fastdecode_loadtag(*ptr);
1564 if (fastdecode_tagmatch(ret.tag, data, tagbytes)) {
1565 ret.next = FD_NEXT_SAMEFIELD;
1566 } else {
1567 fastdecode_commitarr(dst, farr, valbytes);
1568 ret.next = FD_NEXT_OTHERFIELD;
1569 }
1570 } else {
1571 fastdecode_commitarr(dst, farr, valbytes);
1572 ret.next = FD_NEXT_ATLIMIT;
1573 }
1574
1575 ret.dst = dst;
1576 return ret;
1577 }
1578
1579 UPB_FORCEINLINE
fastdecode_fieldmem(upb_Message * msg,uint64_t data)1580 static void* fastdecode_fieldmem(upb_Message* msg, uint64_t data) {
1581 size_t ofs = data >> 48;
1582 return (char*)msg + ofs;
1583 }
1584
1585 UPB_FORCEINLINE
fastdecode_getfield(upb_Decoder * d,const char * ptr,upb_Message * msg,uint64_t * data,uint64_t * hasbits,fastdecode_arr * farr,int valbytes,upb_card card)1586 static void* fastdecode_getfield(upb_Decoder* d, const char* ptr,
1587 upb_Message* msg, uint64_t* data,
1588 uint64_t* hasbits, fastdecode_arr* farr,
1589 int valbytes, upb_card card) {
1590 switch (card) {
1591 case CARD_s: {
1592 uint8_t hasbit_index = *data >> 24;
1593 // Set hasbit and return pointer to scalar field.
1594 *hasbits |= 1ull << hasbit_index;
1595 return fastdecode_fieldmem(msg, *data);
1596 }
1597 case CARD_o: {
1598 uint16_t case_ofs = *data >> 32;
1599 uint32_t* oneof_case = UPB_PTR_AT(msg, case_ofs, uint32_t);
1600 uint8_t field_number = *data >> 24;
1601 *oneof_case = field_number;
1602 return fastdecode_fieldmem(msg, *data);
1603 }
1604 case CARD_r: {
1605 // Get pointer to upb_Array and allocate/expand if necessary.
1606 uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
1607 upb_Array** arr_p = fastdecode_fieldmem(msg, *data);
1608 char* begin;
1609 *(uint32_t*)msg |= *hasbits;
1610 *hasbits = 0;
1611 if (UPB_LIKELY(!*arr_p)) {
1612 farr->arr = _upb_Array_New(&d->arena, 8, elem_size_lg2);
1613 *arr_p = farr->arr;
1614 } else {
1615 farr->arr = *arr_p;
1616 }
1617 begin = _upb_array_ptr(farr->arr);
1618 farr->end = begin + (farr->arr->size * valbytes);
1619 *data = fastdecode_loadtag(ptr);
1620 return begin + (farr->arr->len * valbytes);
1621 }
1622 default:
1623 UPB_UNREACHABLE();
1624 }
1625 }
1626
1627 UPB_FORCEINLINE
fastdecode_flippacked(uint64_t * data,int tagbytes)1628 static bool fastdecode_flippacked(uint64_t* data, int tagbytes) {
1629 *data ^= (0x2 ^ 0x0); // Patch data to match packed wiretype.
1630 return fastdecode_checktag(*data, tagbytes);
1631 }
1632
1633 #define FASTDECODE_CHECKPACKED(tagbytes, card, func) \
1634 if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
1635 if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) { \
1636 UPB_MUSTTAIL return func(UPB_PARSE_ARGS); \
1637 } \
1638 RETURN_GENERIC("packed check tag mismatch\n"); \
1639 }
1640
1641 /* varint fields **************************************************************/
1642
1643 UPB_FORCEINLINE
fastdecode_munge(uint64_t val,int valbytes,bool zigzag)1644 static uint64_t fastdecode_munge(uint64_t val, int valbytes, bool zigzag) {
1645 if (valbytes == 1) {
1646 return val != 0;
1647 } else if (zigzag) {
1648 if (valbytes == 4) {
1649 uint32_t n = val;
1650 return (n >> 1) ^ -(int32_t)(n & 1);
1651 } else if (valbytes == 8) {
1652 return (val >> 1) ^ -(int64_t)(val & 1);
1653 }
1654 UPB_UNREACHABLE();
1655 }
1656 return val;
1657 }
1658
1659 UPB_FORCEINLINE
fastdecode_varint64(const char * ptr,uint64_t * val)1660 static const char* fastdecode_varint64(const char* ptr, uint64_t* val) {
1661 ptr++;
1662 *val = (uint8_t)ptr[-1];
1663 if (UPB_UNLIKELY(*val & 0x80)) {
1664 int i;
1665 for (i = 0; i < 8; i++) {
1666 ptr++;
1667 uint64_t byte = (uint8_t)ptr[-1];
1668 *val += (byte - 1) << (7 + 7 * i);
1669 if (UPB_LIKELY((byte & 0x80) == 0)) goto done;
1670 }
1671 ptr++;
1672 uint64_t byte = (uint8_t)ptr[-1];
1673 if (byte > 1) {
1674 return NULL;
1675 }
1676 *val += (byte - 1) << 63;
1677 }
1678 done:
1679 UPB_ASSUME(ptr != NULL);
1680 return ptr;
1681 }
1682
1683 #define FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
1684 valbytes, card, zigzag, packed) \
1685 uint64_t val; \
1686 void* dst; \
1687 fastdecode_arr farr; \
1688 \
1689 FASTDECODE_CHECKPACKED(tagbytes, card, packed); \
1690 \
1691 dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \
1692 card); \
1693 if (card == CARD_r) { \
1694 if (UPB_UNLIKELY(!dst)) { \
1695 RETURN_GENERIC("need array resize\n"); \
1696 } \
1697 } \
1698 \
1699 again: \
1700 if (card == CARD_r) { \
1701 dst = fastdecode_resizearr(d, dst, &farr, valbytes); \
1702 } \
1703 \
1704 ptr += tagbytes; \
1705 ptr = fastdecode_varint64(ptr, &val); \
1706 if (ptr == NULL) return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
1707 val = fastdecode_munge(val, valbytes, zigzag); \
1708 memcpy(dst, &val, valbytes); \
1709 \
1710 if (card == CARD_r) { \
1711 fastdecode_nextret ret = fastdecode_nextrepeated( \
1712 d, dst, &ptr, &farr, data, tagbytes, valbytes); \
1713 switch (ret.next) { \
1714 case FD_NEXT_SAMEFIELD: \
1715 dst = ret.dst; \
1716 goto again; \
1717 case FD_NEXT_OTHERFIELD: \
1718 data = ret.tag; \
1719 UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
1720 case FD_NEXT_ATLIMIT: \
1721 return ptr; \
1722 } \
1723 } \
1724 \
1725 UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
1726
1727 typedef struct {
1728 uint8_t valbytes;
1729 bool zigzag;
1730 void* dst;
1731 fastdecode_arr farr;
1732 } fastdecode_varintdata;
1733
1734 UPB_FORCEINLINE
fastdecode_topackedvarint(upb_Decoder * d,const char * ptr,void * ctx)1735 static const char* fastdecode_topackedvarint(upb_Decoder* d, const char* ptr,
1736 void* ctx) {
1737 fastdecode_varintdata* data = ctx;
1738 void* dst = data->dst;
1739 uint64_t val;
1740
1741 while (!decode_isdone(d, &ptr)) {
1742 dst = fastdecode_resizearr(d, dst, &data->farr, data->valbytes);
1743 ptr = fastdecode_varint64(ptr, &val);
1744 if (ptr == NULL) return NULL;
1745 val = fastdecode_munge(val, data->valbytes, data->zigzag);
1746 memcpy(dst, &val, data->valbytes);
1747 dst = (char*)dst + data->valbytes;
1748 }
1749
1750 fastdecode_commitarr(dst, &data->farr, data->valbytes);
1751 return ptr;
1752 }
1753
1754 #define FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
1755 valbytes, zigzag, unpacked) \
1756 fastdecode_varintdata ctx = {valbytes, zigzag}; \
1757 \
1758 FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked); \
1759 \
1760 ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr, \
1761 valbytes, CARD_r); \
1762 if (UPB_UNLIKELY(!ctx.dst)) { \
1763 RETURN_GENERIC("need array resize\n"); \
1764 } \
1765 \
1766 ptr += tagbytes; \
1767 ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx); \
1768 \
1769 if (UPB_UNLIKELY(ptr == NULL)) { \
1770 return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
1771 } \
1772 \
1773 UPB_MUSTTAIL return fastdecode_dispatch(d, ptr, msg, table, hasbits, 0);
1774
1775 #define FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
1776 valbytes, card, zigzag, unpacked, packed) \
1777 if (card == CARD_p) { \
1778 FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
1779 valbytes, zigzag, unpacked); \
1780 } else { \
1781 FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
1782 valbytes, card, zigzag, packed); \
1783 }
1784
1785 #define z_ZZ true
1786 #define b_ZZ false
1787 #define v_ZZ false
1788
1789 /* Generate all combinations:
1790 * {s,o,r,p} x {b1,v4,z4,v8,z8} x {1bt,2bt} */
1791
1792 #define F(card, type, valbytes, tagbytes) \
1793 UPB_NOINLINE \
1794 const char* upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
1795 FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \
1796 CARD_##card, type##_ZZ, \
1797 upb_pr##type##valbytes##_##tagbytes##bt, \
1798 upb_pp##type##valbytes##_##tagbytes##bt); \
1799 }
1800
1801 #define TYPES(card, tagbytes) \
1802 F(card, b, 1, tagbytes) \
1803 F(card, v, 4, tagbytes) \
1804 F(card, v, 8, tagbytes) \
1805 F(card, z, 4, tagbytes) \
1806 F(card, z, 8, tagbytes)
1807
1808 #define TAGBYTES(card) \
1809 TYPES(card, 1) \
1810 TYPES(card, 2)
1811
1812 TAGBYTES(s)
1813 TAGBYTES(o)
1814 TAGBYTES(r)
1815 TAGBYTES(p)
1816
1817 #undef z_ZZ
1818 #undef b_ZZ
1819 #undef v_ZZ
1820 #undef o_ONEOF
1821 #undef s_ONEOF
1822 #undef r_ONEOF
1823 #undef F
1824 #undef TYPES
1825 #undef TAGBYTES
1826 #undef FASTDECODE_UNPACKEDVARINT
1827 #undef FASTDECODE_PACKEDVARINT
1828 #undef FASTDECODE_VARINT
1829
1830 /* fixed fields ***************************************************************/
1831
1832 #define FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
1833 valbytes, card, packed) \
1834 void* dst; \
1835 fastdecode_arr farr; \
1836 \
1837 FASTDECODE_CHECKPACKED(tagbytes, card, packed) \
1838 \
1839 dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \
1840 card); \
1841 if (card == CARD_r) { \
1842 if (UPB_UNLIKELY(!dst)) { \
1843 RETURN_GENERIC("couldn't allocate array in arena\n"); \
1844 } \
1845 } \
1846 \
1847 again: \
1848 if (card == CARD_r) { \
1849 dst = fastdecode_resizearr(d, dst, &farr, valbytes); \
1850 } \
1851 \
1852 ptr += tagbytes; \
1853 memcpy(dst, ptr, valbytes); \
1854 ptr += valbytes; \
1855 \
1856 if (card == CARD_r) { \
1857 fastdecode_nextret ret = fastdecode_nextrepeated( \
1858 d, dst, &ptr, &farr, data, tagbytes, valbytes); \
1859 switch (ret.next) { \
1860 case FD_NEXT_SAMEFIELD: \
1861 dst = ret.dst; \
1862 goto again; \
1863 case FD_NEXT_OTHERFIELD: \
1864 data = ret.tag; \
1865 UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
1866 case FD_NEXT_ATLIMIT: \
1867 return ptr; \
1868 } \
1869 } \
1870 \
1871 UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
1872
1873 #define FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
1874 valbytes, unpacked) \
1875 FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked) \
1876 \
1877 ptr += tagbytes; \
1878 int size = (uint8_t)ptr[0]; \
1879 ptr++; \
1880 if (size & 0x80) { \
1881 ptr = fastdecode_longsize(ptr, &size); \
1882 } \
1883 \
1884 if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr) || \
1885 (size % valbytes) != 0)) { \
1886 return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
1887 } \
1888 \
1889 upb_Array** arr_p = fastdecode_fieldmem(msg, data); \
1890 upb_Array* arr = *arr_p; \
1891 uint8_t elem_size_lg2 = __builtin_ctz(valbytes); \
1892 int elems = size / valbytes; \
1893 \
1894 if (UPB_LIKELY(!arr)) { \
1895 *arr_p = arr = _upb_Array_New(&d->arena, elems, elem_size_lg2); \
1896 if (!arr) { \
1897 return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
1898 } \
1899 } else { \
1900 _upb_Array_Resize(arr, elems, &d->arena); \
1901 } \
1902 \
1903 char* dst = _upb_array_ptr(arr); \
1904 memcpy(dst, ptr, size); \
1905 arr->len = elems; \
1906 \
1907 ptr += size; \
1908 UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
1909
1910 #define FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
1911 valbytes, card, unpacked, packed) \
1912 if (card == CARD_p) { \
1913 FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
1914 valbytes, unpacked); \
1915 } else { \
1916 FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
1917 valbytes, card, packed); \
1918 }
1919
1920 /* Generate all combinations:
1921 * {s,o,r,p} x {f4,f8} x {1bt,2bt} */
1922
1923 #define F(card, valbytes, tagbytes) \
1924 UPB_NOINLINE \
1925 const char* upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
1926 FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \
1927 CARD_##card, upb_ppf##valbytes##_##tagbytes##bt, \
1928 upb_prf##valbytes##_##tagbytes##bt); \
1929 }
1930
1931 #define TYPES(card, tagbytes) \
1932 F(card, 4, tagbytes) \
1933 F(card, 8, tagbytes)
1934
1935 #define TAGBYTES(card) \
1936 TYPES(card, 1) \
1937 TYPES(card, 2)
1938
1939 TAGBYTES(s)
1940 TAGBYTES(o)
1941 TAGBYTES(r)
1942 TAGBYTES(p)
1943
1944 #undef F
1945 #undef TYPES
1946 #undef TAGBYTES
1947 #undef FASTDECODE_UNPACKEDFIXED
1948 #undef FASTDECODE_PACKEDFIXED
1949
1950 /* string fields **************************************************************/
1951
1952 typedef const char* fastdecode_copystr_func(struct upb_Decoder* d,
1953 const char* ptr, upb_Message* msg,
1954 const upb_MiniTable* table,
1955 uint64_t hasbits,
1956 upb_StringView* dst);
1957
1958 UPB_NOINLINE
fastdecode_verifyutf8(upb_Decoder * d,const char * ptr,upb_Message * msg,intptr_t table,uint64_t hasbits,uint64_t data)1959 static const char* fastdecode_verifyutf8(upb_Decoder* d, const char* ptr,
1960 upb_Message* msg, intptr_t table,
1961 uint64_t hasbits, uint64_t data) {
1962 upb_StringView* dst = (upb_StringView*)data;
1963 if (!decode_verifyutf8_inl(dst->data, dst->size)) {
1964 return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8);
1965 }
1966 UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
1967 }
1968
1969 #define FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, validate_utf8) \
1970 int size = (uint8_t)ptr[0]; /* Could plumb through hasbits. */ \
1971 ptr++; \
1972 if (size & 0x80) { \
1973 ptr = fastdecode_longsize(ptr, &size); \
1974 } \
1975 \
1976 if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) { \
1977 dst->size = 0; \
1978 return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
1979 } \
1980 \
1981 if (d->options & kUpb_DecodeOption_AliasString) { \
1982 dst->data = ptr; \
1983 dst->size = size; \
1984 } else { \
1985 char* data = upb_Arena_Malloc(&d->arena, size); \
1986 if (!data) { \
1987 return fastdecode_err(d, kUpb_DecodeStatus_OutOfMemory); \
1988 } \
1989 memcpy(data, ptr, size); \
1990 dst->data = data; \
1991 dst->size = size; \
1992 } \
1993 \
1994 ptr += size; \
1995 if (validate_utf8) { \
1996 data = (uint64_t)dst; \
1997 UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
1998 } else { \
1999 UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \
2000 }
2001
2002 UPB_NOINLINE
fastdecode_longstring_utf8(struct upb_Decoder * d,const char * ptr,upb_Message * msg,intptr_t table,uint64_t hasbits,uint64_t data)2003 static const char* fastdecode_longstring_utf8(struct upb_Decoder* d,
2004 const char* ptr, upb_Message* msg,
2005 intptr_t table, uint64_t hasbits,
2006 uint64_t data) {
2007 upb_StringView* dst = (upb_StringView*)data;
2008 FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, true);
2009 }
2010
2011 UPB_NOINLINE
fastdecode_longstring_noutf8(struct upb_Decoder * d,const char * ptr,upb_Message * msg,intptr_t table,uint64_t hasbits,uint64_t data)2012 static const char* fastdecode_longstring_noutf8(
2013 struct upb_Decoder* d, const char* ptr, upb_Message* msg, intptr_t table,
2014 uint64_t hasbits, uint64_t data) {
2015 upb_StringView* dst = (upb_StringView*)data;
2016 FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, false);
2017 }
2018
2019 UPB_FORCEINLINE
fastdecode_docopy(upb_Decoder * d,const char * ptr,uint32_t size,int copy,char * data,upb_StringView * dst)2020 static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size,
2021 int copy, char* data, upb_StringView* dst) {
2022 d->arena.head.ptr += copy;
2023 dst->data = data;
2024 UPB_UNPOISON_MEMORY_REGION(data, copy);
2025 memcpy(data, ptr, copy);
2026 UPB_POISON_MEMORY_REGION(data + size, copy - size);
2027 }
2028
2029 #define FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \
2030 card, validate_utf8) \
2031 upb_StringView* dst; \
2032 fastdecode_arr farr; \
2033 int64_t size; \
2034 size_t arena_has; \
2035 size_t common_has; \
2036 char* buf; \
2037 \
2038 UPB_ASSERT((d->options & kUpb_DecodeOption_AliasString) == 0); \
2039 UPB_ASSERT(fastdecode_checktag(data, tagbytes)); \
2040 \
2041 dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
2042 sizeof(upb_StringView), card); \
2043 \
2044 again: \
2045 if (card == CARD_r) { \
2046 dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_StringView)); \
2047 } \
2048 \
2049 size = (uint8_t)ptr[tagbytes]; \
2050 ptr += tagbytes + 1; \
2051 dst->size = size; \
2052 \
2053 buf = d->arena.head.ptr; \
2054 arena_has = _upb_ArenaHas(&d->arena); \
2055 common_has = UPB_MIN(arena_has, (d->end - ptr) + 16); \
2056 \
2057 if (UPB_LIKELY(size <= 15 - tagbytes)) { \
2058 if (arena_has < 16) goto longstr; \
2059 d->arena.head.ptr += 16; \
2060 memcpy(buf, ptr - tagbytes - 1, 16); \
2061 dst->data = buf + tagbytes + 1; \
2062 } else if (UPB_LIKELY(size <= 32)) { \
2063 if (UPB_UNLIKELY(common_has < 32)) goto longstr; \
2064 fastdecode_docopy(d, ptr, size, 32, buf, dst); \
2065 } else if (UPB_LIKELY(size <= 64)) { \
2066 if (UPB_UNLIKELY(common_has < 64)) goto longstr; \
2067 fastdecode_docopy(d, ptr, size, 64, buf, dst); \
2068 } else if (UPB_LIKELY(size < 128)) { \
2069 if (UPB_UNLIKELY(common_has < 128)) goto longstr; \
2070 fastdecode_docopy(d, ptr, size, 128, buf, dst); \
2071 } else { \
2072 goto longstr; \
2073 } \
2074 \
2075 ptr += size; \
2076 \
2077 if (card == CARD_r) { \
2078 if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
2079 return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); \
2080 } \
2081 fastdecode_nextret ret = fastdecode_nextrepeated( \
2082 d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_StringView)); \
2083 switch (ret.next) { \
2084 case FD_NEXT_SAMEFIELD: \
2085 dst = ret.dst; \
2086 goto again; \
2087 case FD_NEXT_OTHERFIELD: \
2088 data = ret.tag; \
2089 UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
2090 case FD_NEXT_ATLIMIT: \
2091 return ptr; \
2092 } \
2093 } \
2094 \
2095 if (card != CARD_r && validate_utf8) { \
2096 data = (uint64_t)dst; \
2097 UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
2098 } \
2099 \
2100 UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \
2101 \
2102 longstr: \
2103 if (card == CARD_r) { \
2104 fastdecode_commitarr(dst + 1, &farr, sizeof(upb_StringView)); \
2105 } \
2106 ptr--; \
2107 if (validate_utf8) { \
2108 UPB_MUSTTAIL return fastdecode_longstring_utf8(d, ptr, msg, table, \
2109 hasbits, (uint64_t)dst); \
2110 } else { \
2111 UPB_MUSTTAIL return fastdecode_longstring_noutf8(d, ptr, msg, table, \
2112 hasbits, (uint64_t)dst); \
2113 }
2114
2115 #define FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, card, \
2116 copyfunc, validate_utf8) \
2117 upb_StringView* dst; \
2118 fastdecode_arr farr; \
2119 int64_t size; \
2120 \
2121 if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
2122 RETURN_GENERIC("string field tag mismatch\n"); \
2123 } \
2124 \
2125 if (UPB_UNLIKELY((d->options & kUpb_DecodeOption_AliasString) == 0)) { \
2126 UPB_MUSTTAIL return copyfunc(UPB_PARSE_ARGS); \
2127 } \
2128 \
2129 dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
2130 sizeof(upb_StringView), card); \
2131 \
2132 again: \
2133 if (card == CARD_r) { \
2134 dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_StringView)); \
2135 } \
2136 \
2137 size = (int8_t)ptr[tagbytes]; \
2138 ptr += tagbytes + 1; \
2139 dst->data = ptr; \
2140 dst->size = size; \
2141 \
2142 if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->end))) { \
2143 ptr--; \
2144 if (validate_utf8) { \
2145 return fastdecode_longstring_utf8(d, ptr, msg, table, hasbits, \
2146 (uint64_t)dst); \
2147 } else { \
2148 return fastdecode_longstring_noutf8(d, ptr, msg, table, hasbits, \
2149 (uint64_t)dst); \
2150 } \
2151 } \
2152 \
2153 ptr += size; \
2154 \
2155 if (card == CARD_r) { \
2156 if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
2157 return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); \
2158 } \
2159 fastdecode_nextret ret = fastdecode_nextrepeated( \
2160 d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_StringView)); \
2161 switch (ret.next) { \
2162 case FD_NEXT_SAMEFIELD: \
2163 dst = ret.dst; \
2164 if (UPB_UNLIKELY((d->options & kUpb_DecodeOption_AliasString) == 0)) { \
2165 /* Buffer flipped and we can't alias any more. Bounce to */ \
2166 /* copyfunc(), but via dispatch since we need to reload table */ \
2167 /* data also. */ \
2168 fastdecode_commitarr(dst, &farr, sizeof(upb_StringView)); \
2169 data = ret.tag; \
2170 UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
2171 } \
2172 goto again; \
2173 case FD_NEXT_OTHERFIELD: \
2174 data = ret.tag; \
2175 UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
2176 case FD_NEXT_ATLIMIT: \
2177 return ptr; \
2178 } \
2179 } \
2180 \
2181 if (card != CARD_r && validate_utf8) { \
2182 data = (uint64_t)dst; \
2183 UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
2184 } \
2185 \
2186 UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
2187
2188 /* Generate all combinations:
2189 * {p,c} x {s,o,r} x {s, b} x {1bt,2bt} */
2190
2191 #define s_VALIDATE true
2192 #define b_VALIDATE false
2193
2194 #define F(card, tagbytes, type) \
2195 UPB_NOINLINE \
2196 const char* upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
2197 FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \
2198 CARD_##card, type##_VALIDATE); \
2199 } \
2200 const char* upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
2201 FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, \
2202 CARD_##card, upb_c##card##type##_##tagbytes##bt, \
2203 type##_VALIDATE); \
2204 }
2205
2206 #define UTF8(card, tagbytes) \
2207 F(card, tagbytes, s) \
2208 F(card, tagbytes, b)
2209
2210 #define TAGBYTES(card) \
2211 UTF8(card, 1) \
2212 UTF8(card, 2)
2213
2214 TAGBYTES(s)
TAGBYTES(o)2215 TAGBYTES(o)
2216 TAGBYTES(r)
2217
2218 #undef s_VALIDATE
2219 #undef b_VALIDATE
2220 #undef F
2221 #undef TAGBYTES
2222 #undef FASTDECODE_LONGSTRING
2223 #undef FASTDECODE_COPYSTRING
2224 #undef FASTDECODE_STRING
2225
2226 /* message fields *************************************************************/
2227
2228 UPB_INLINE
2229 upb_Message* decode_newmsg_ceil(upb_Decoder* d, const upb_MiniTable* l,
2230 int msg_ceil_bytes) {
2231 size_t size = l->size + sizeof(upb_Message_Internal);
2232 char* msg_data;
2233 if (UPB_LIKELY(msg_ceil_bytes > 0 &&
2234 _upb_ArenaHas(&d->arena) >= msg_ceil_bytes)) {
2235 UPB_ASSERT(size <= (size_t)msg_ceil_bytes);
2236 msg_data = d->arena.head.ptr;
2237 d->arena.head.ptr += size;
2238 UPB_UNPOISON_MEMORY_REGION(msg_data, msg_ceil_bytes);
2239 memset(msg_data, 0, msg_ceil_bytes);
2240 UPB_POISON_MEMORY_REGION(msg_data + size, msg_ceil_bytes - size);
2241 } else {
2242 msg_data = (char*)upb_Arena_Malloc(&d->arena, size);
2243 memset(msg_data, 0, size);
2244 }
2245 return msg_data + sizeof(upb_Message_Internal);
2246 }
2247
2248 typedef struct {
2249 intptr_t table;
2250 upb_Message* msg;
2251 } fastdecode_submsgdata;
2252
2253 UPB_FORCEINLINE
fastdecode_tosubmsg(upb_Decoder * d,const char * ptr,void * ctx)2254 static const char* fastdecode_tosubmsg(upb_Decoder* d, const char* ptr,
2255 void* ctx) {
2256 fastdecode_submsgdata* submsg = ctx;
2257 ptr = fastdecode_dispatch(d, ptr, submsg->msg, submsg->table, 0, 0);
2258 UPB_ASSUME(ptr != NULL);
2259 return ptr;
2260 }
2261
2262 #define FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, \
2263 msg_ceil_bytes, card) \
2264 \
2265 if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
2266 RETURN_GENERIC("submessage field tag mismatch\n"); \
2267 } \
2268 \
2269 if (--d->depth == 0) { \
2270 return fastdecode_err(d, kUpb_DecodeStatus_MaxDepthExceeded); \
2271 } \
2272 \
2273 upb_Message** dst; \
2274 uint32_t submsg_idx = (data >> 16) & 0xff; \
2275 const upb_MiniTable* tablep = decode_totablep(table); \
2276 const upb_MiniTable* subtablep = tablep->subs[submsg_idx].submsg; \
2277 fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \
2278 fastdecode_arr farr; \
2279 \
2280 if (subtablep->table_mask == (uint8_t)-1) { \
2281 RETURN_GENERIC("submessage doesn't have fast tables."); \
2282 } \
2283 \
2284 dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
2285 sizeof(upb_Message*), card); \
2286 \
2287 if (card == CARD_s) { \
2288 *(uint32_t*)msg |= hasbits; \
2289 hasbits = 0; \
2290 } \
2291 \
2292 again: \
2293 if (card == CARD_r) { \
2294 dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_Message*)); \
2295 } \
2296 \
2297 submsg.msg = *dst; \
2298 \
2299 if (card == CARD_r || UPB_LIKELY(!submsg.msg)) { \
2300 *dst = submsg.msg = decode_newmsg_ceil(d, subtablep, msg_ceil_bytes); \
2301 } \
2302 \
2303 ptr += tagbytes; \
2304 ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg); \
2305 \
2306 if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) { \
2307 return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
2308 } \
2309 \
2310 if (card == CARD_r) { \
2311 fastdecode_nextret ret = fastdecode_nextrepeated( \
2312 d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_Message*)); \
2313 switch (ret.next) { \
2314 case FD_NEXT_SAMEFIELD: \
2315 dst = ret.dst; \
2316 goto again; \
2317 case FD_NEXT_OTHERFIELD: \
2318 d->depth++; \
2319 data = ret.tag; \
2320 UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
2321 case FD_NEXT_ATLIMIT: \
2322 d->depth++; \
2323 return ptr; \
2324 } \
2325 } \
2326 \
2327 d->depth++; \
2328 UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
2329
2330 #define F(card, tagbytes, size_ceil, ceil_arg) \
2331 const char* upb_p##card##m_##tagbytes##bt_max##size_ceil##b( \
2332 UPB_PARSE_PARAMS) { \
2333 FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, ceil_arg, \
2334 CARD_##card); \
2335 }
2336
2337 #define SIZES(card, tagbytes) \
2338 F(card, tagbytes, 64, 64) \
2339 F(card, tagbytes, 128, 128) \
2340 F(card, tagbytes, 192, 192) \
2341 F(card, tagbytes, 256, 256) \
2342 F(card, tagbytes, max, -1)
2343
2344 #define TAGBYTES(card) \
2345 SIZES(card, 1) \
2346 SIZES(card, 2)
2347
2348 TAGBYTES(s)
2349 TAGBYTES(o)
2350 TAGBYTES(r)
2351
2352 #undef TAGBYTES
2353 #undef SIZES
2354 #undef F
2355 #undef FASTDECODE_SUBMSG
2356
2357 #endif /* UPB_FASTTABLE */
2358
2359 /** upb/json_decode.c ************************************************************/
2360
2361 #include <errno.h>
2362 #include <float.h>
2363 #include <inttypes.h>
2364 #include <limits.h>
2365 #include <math.h>
2366 #include <setjmp.h>
2367 #include <stdlib.h>
2368 #include <string.h>
2369
2370
2371 /* Special header, must be included last. */
2372
2373 typedef struct {
2374 const char *ptr, *end;
2375 upb_Arena* arena; /* TODO: should we have a tmp arena for tmp data? */
2376 const upb_DefPool* symtab;
2377 int depth;
2378 upb_Status* status;
2379 jmp_buf err;
2380 int line;
2381 const char* line_begin;
2382 bool is_first;
2383 int options;
2384 const upb_FieldDef* debug_field;
2385 } jsondec;
2386
2387 enum { JD_OBJECT, JD_ARRAY, JD_STRING, JD_NUMBER, JD_TRUE, JD_FALSE, JD_NULL };
2388
2389 /* Forward declarations of mutually-recursive functions. */
2390 static void jsondec_wellknown(jsondec* d, upb_Message* msg,
2391 const upb_MessageDef* m);
2392 static upb_MessageValue jsondec_value(jsondec* d, const upb_FieldDef* f);
2393 static void jsondec_wellknownvalue(jsondec* d, upb_Message* msg,
2394 const upb_MessageDef* m);
2395 static void jsondec_object(jsondec* d, upb_Message* msg,
2396 const upb_MessageDef* m);
2397
jsondec_streql(upb_StringView str,const char * lit)2398 static bool jsondec_streql(upb_StringView str, const char* lit) {
2399 return str.size == strlen(lit) && memcmp(str.data, lit, str.size) == 0;
2400 }
2401
jsondec_isnullvalue(const upb_FieldDef * f)2402 static bool jsondec_isnullvalue(const upb_FieldDef* f) {
2403 return upb_FieldDef_CType(f) == kUpb_CType_Enum &&
2404 strcmp(upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(f)),
2405 "google.protobuf.NullValue") == 0;
2406 }
2407
jsondec_isvalue(const upb_FieldDef * f)2408 static bool jsondec_isvalue(const upb_FieldDef* f) {
2409 return (upb_FieldDef_CType(f) == kUpb_CType_Message &&
2410 upb_MessageDef_WellKnownType(upb_FieldDef_MessageSubDef(f)) ==
2411 kUpb_WellKnown_Value) ||
2412 jsondec_isnullvalue(f);
2413 }
2414
jsondec_err(jsondec * d,const char * msg)2415 UPB_NORETURN static void jsondec_err(jsondec* d, const char* msg) {
2416 upb_Status_SetErrorFormat(d->status, "Error parsing JSON @%d:%d: %s", d->line,
2417 (int)(d->ptr - d->line_begin), msg);
2418 UPB_LONGJMP(d->err, 1);
2419 }
2420
2421 UPB_PRINTF(2, 3)
jsondec_errf(jsondec * d,const char * fmt,...)2422 UPB_NORETURN static void jsondec_errf(jsondec* d, const char* fmt, ...) {
2423 va_list argp;
2424 upb_Status_SetErrorFormat(d->status, "Error parsing JSON @%d:%d: ", d->line,
2425 (int)(d->ptr - d->line_begin));
2426 va_start(argp, fmt);
2427 upb_Status_VAppendErrorFormat(d->status, fmt, argp);
2428 va_end(argp);
2429 UPB_LONGJMP(d->err, 1);
2430 }
2431
jsondec_skipws(jsondec * d)2432 static void jsondec_skipws(jsondec* d) {
2433 while (d->ptr != d->end) {
2434 switch (*d->ptr) {
2435 case '\n':
2436 d->line++;
2437 d->line_begin = d->ptr;
2438 /* Fallthrough. */
2439 case '\r':
2440 case '\t':
2441 case ' ':
2442 d->ptr++;
2443 break;
2444 default:
2445 return;
2446 }
2447 }
2448 jsondec_err(d, "Unexpected EOF");
2449 }
2450
jsondec_tryparsech(jsondec * d,char ch)2451 static bool jsondec_tryparsech(jsondec* d, char ch) {
2452 if (d->ptr == d->end || *d->ptr != ch) return false;
2453 d->ptr++;
2454 return true;
2455 }
2456
jsondec_parselit(jsondec * d,const char * lit)2457 static void jsondec_parselit(jsondec* d, const char* lit) {
2458 size_t avail = d->end - d->ptr;
2459 size_t len = strlen(lit);
2460 if (avail < len || memcmp(d->ptr, lit, len) != 0) {
2461 jsondec_errf(d, "Expected: '%s'", lit);
2462 }
2463 d->ptr += len;
2464 }
2465
jsondec_wsch(jsondec * d,char ch)2466 static void jsondec_wsch(jsondec* d, char ch) {
2467 jsondec_skipws(d);
2468 if (!jsondec_tryparsech(d, ch)) {
2469 jsondec_errf(d, "Expected: '%c'", ch);
2470 }
2471 }
2472
jsondec_true(jsondec * d)2473 static void jsondec_true(jsondec* d) { jsondec_parselit(d, "true"); }
jsondec_false(jsondec * d)2474 static void jsondec_false(jsondec* d) { jsondec_parselit(d, "false"); }
jsondec_null(jsondec * d)2475 static void jsondec_null(jsondec* d) { jsondec_parselit(d, "null"); }
2476
jsondec_entrysep(jsondec * d)2477 static void jsondec_entrysep(jsondec* d) {
2478 jsondec_skipws(d);
2479 jsondec_parselit(d, ":");
2480 }
2481
jsondec_rawpeek(jsondec * d)2482 static int jsondec_rawpeek(jsondec* d) {
2483 switch (*d->ptr) {
2484 case '{':
2485 return JD_OBJECT;
2486 case '[':
2487 return JD_ARRAY;
2488 case '"':
2489 return JD_STRING;
2490 case '-':
2491 case '0':
2492 case '1':
2493 case '2':
2494 case '3':
2495 case '4':
2496 case '5':
2497 case '6':
2498 case '7':
2499 case '8':
2500 case '9':
2501 return JD_NUMBER;
2502 case 't':
2503 return JD_TRUE;
2504 case 'f':
2505 return JD_FALSE;
2506 case 'n':
2507 return JD_NULL;
2508 default:
2509 jsondec_errf(d, "Unexpected character: '%c'", *d->ptr);
2510 }
2511 }
2512
2513 /* JSON object/array **********************************************************/
2514
2515 /* These are used like so:
2516 *
2517 * jsondec_objstart(d);
2518 * while (jsondec_objnext(d)) {
2519 * ...
2520 * }
2521 * jsondec_objend(d) */
2522
jsondec_peek(jsondec * d)2523 static int jsondec_peek(jsondec* d) {
2524 jsondec_skipws(d);
2525 return jsondec_rawpeek(d);
2526 }
2527
jsondec_push(jsondec * d)2528 static void jsondec_push(jsondec* d) {
2529 if (--d->depth < 0) {
2530 jsondec_err(d, "Recursion limit exceeded");
2531 }
2532 d->is_first = true;
2533 }
2534
jsondec_seqnext(jsondec * d,char end_ch)2535 static bool jsondec_seqnext(jsondec* d, char end_ch) {
2536 bool is_first = d->is_first;
2537 d->is_first = false;
2538 jsondec_skipws(d);
2539 if (*d->ptr == end_ch) return false;
2540 if (!is_first) jsondec_parselit(d, ",");
2541 return true;
2542 }
2543
jsondec_arrstart(jsondec * d)2544 static void jsondec_arrstart(jsondec* d) {
2545 jsondec_push(d);
2546 jsondec_wsch(d, '[');
2547 }
2548
jsondec_arrend(jsondec * d)2549 static void jsondec_arrend(jsondec* d) {
2550 d->depth++;
2551 jsondec_wsch(d, ']');
2552 }
2553
jsondec_arrnext(jsondec * d)2554 static bool jsondec_arrnext(jsondec* d) { return jsondec_seqnext(d, ']'); }
2555
jsondec_objstart(jsondec * d)2556 static void jsondec_objstart(jsondec* d) {
2557 jsondec_push(d);
2558 jsondec_wsch(d, '{');
2559 }
2560
jsondec_objend(jsondec * d)2561 static void jsondec_objend(jsondec* d) {
2562 d->depth++;
2563 jsondec_wsch(d, '}');
2564 }
2565
jsondec_objnext(jsondec * d)2566 static bool jsondec_objnext(jsondec* d) {
2567 if (!jsondec_seqnext(d, '}')) return false;
2568 if (jsondec_peek(d) != JD_STRING) {
2569 jsondec_err(d, "Object must start with string");
2570 }
2571 return true;
2572 }
2573
2574 /* JSON number ****************************************************************/
2575
jsondec_tryskipdigits(jsondec * d)2576 static bool jsondec_tryskipdigits(jsondec* d) {
2577 const char* start = d->ptr;
2578
2579 while (d->ptr < d->end) {
2580 if (*d->ptr < '0' || *d->ptr > '9') {
2581 break;
2582 }
2583 d->ptr++;
2584 }
2585
2586 return d->ptr != start;
2587 }
2588
jsondec_skipdigits(jsondec * d)2589 static void jsondec_skipdigits(jsondec* d) {
2590 if (!jsondec_tryskipdigits(d)) {
2591 jsondec_err(d, "Expected one or more digits");
2592 }
2593 }
2594
jsondec_number(jsondec * d)2595 static double jsondec_number(jsondec* d) {
2596 const char* start = d->ptr;
2597
2598 assert(jsondec_rawpeek(d) == JD_NUMBER);
2599
2600 /* Skip over the syntax of a number, as specified by JSON. */
2601 if (*d->ptr == '-') d->ptr++;
2602
2603 if (jsondec_tryparsech(d, '0')) {
2604 if (jsondec_tryskipdigits(d)) {
2605 jsondec_err(d, "number cannot have leading zero");
2606 }
2607 } else {
2608 jsondec_skipdigits(d);
2609 }
2610
2611 if (d->ptr == d->end) goto parse;
2612 if (jsondec_tryparsech(d, '.')) {
2613 jsondec_skipdigits(d);
2614 }
2615 if (d->ptr == d->end) goto parse;
2616
2617 if (*d->ptr == 'e' || *d->ptr == 'E') {
2618 d->ptr++;
2619 if (d->ptr == d->end) {
2620 jsondec_err(d, "Unexpected EOF in number");
2621 }
2622 if (*d->ptr == '+' || *d->ptr == '-') {
2623 d->ptr++;
2624 }
2625 jsondec_skipdigits(d);
2626 }
2627
2628 parse:
2629 /* Having verified the syntax of a JSON number, use strtod() to parse
2630 * (strtod() accepts a superset of JSON syntax). */
2631 errno = 0;
2632 {
2633 char* end;
2634 double val = strtod(start, &end);
2635 assert(end == d->ptr);
2636
2637 /* Currently the min/max-val conformance tests fail if we check this. Does
2638 * this mean the conformance tests are wrong or strtod() is wrong, or
2639 * something else? Investigate further. */
2640 /*
2641 if (errno == ERANGE) {
2642 jsondec_err(d, "Number out of range");
2643 }
2644 */
2645
2646 if (val > DBL_MAX || val < -DBL_MAX) {
2647 jsondec_err(d, "Number out of range");
2648 }
2649
2650 return val;
2651 }
2652 }
2653
2654 /* JSON string ****************************************************************/
2655
jsondec_escape(jsondec * d)2656 static char jsondec_escape(jsondec* d) {
2657 switch (*d->ptr++) {
2658 case '"':
2659 return '\"';
2660 case '\\':
2661 return '\\';
2662 case '/':
2663 return '/';
2664 case 'b':
2665 return '\b';
2666 case 'f':
2667 return '\f';
2668 case 'n':
2669 return '\n';
2670 case 'r':
2671 return '\r';
2672 case 't':
2673 return '\t';
2674 default:
2675 jsondec_err(d, "Invalid escape char");
2676 }
2677 }
2678
jsondec_codepoint(jsondec * d)2679 static uint32_t jsondec_codepoint(jsondec* d) {
2680 uint32_t cp = 0;
2681 const char* end;
2682
2683 if (d->end - d->ptr < 4) {
2684 jsondec_err(d, "EOF inside string");
2685 }
2686
2687 end = d->ptr + 4;
2688 while (d->ptr < end) {
2689 char ch = *d->ptr++;
2690 if (ch >= '0' && ch <= '9') {
2691 ch -= '0';
2692 } else if (ch >= 'a' && ch <= 'f') {
2693 ch = ch - 'a' + 10;
2694 } else if (ch >= 'A' && ch <= 'F') {
2695 ch = ch - 'A' + 10;
2696 } else {
2697 jsondec_err(d, "Invalid hex digit");
2698 }
2699 cp = (cp << 4) | ch;
2700 }
2701
2702 return cp;
2703 }
2704
2705 /* Parses a \uXXXX unicode escape (possibly a surrogate pair). */
jsondec_unicode(jsondec * d,char * out)2706 static size_t jsondec_unicode(jsondec* d, char* out) {
2707 uint32_t cp = jsondec_codepoint(d);
2708 if (cp >= 0xd800 && cp <= 0xdbff) {
2709 /* Surrogate pair: two 16-bit codepoints become a 32-bit codepoint. */
2710 uint32_t high = cp;
2711 uint32_t low;
2712 jsondec_parselit(d, "\\u");
2713 low = jsondec_codepoint(d);
2714 if (low < 0xdc00 || low > 0xdfff) {
2715 jsondec_err(d, "Invalid low surrogate");
2716 }
2717 cp = (high & 0x3ff) << 10;
2718 cp |= (low & 0x3ff);
2719 cp += 0x10000;
2720 } else if (cp >= 0xdc00 && cp <= 0xdfff) {
2721 jsondec_err(d, "Unpaired low surrogate");
2722 }
2723
2724 /* Write to UTF-8 */
2725 if (cp <= 0x7f) {
2726 out[0] = cp;
2727 return 1;
2728 } else if (cp <= 0x07FF) {
2729 out[0] = ((cp >> 6) & 0x1F) | 0xC0;
2730 out[1] = ((cp >> 0) & 0x3F) | 0x80;
2731 return 2;
2732 } else if (cp <= 0xFFFF) {
2733 out[0] = ((cp >> 12) & 0x0F) | 0xE0;
2734 out[1] = ((cp >> 6) & 0x3F) | 0x80;
2735 out[2] = ((cp >> 0) & 0x3F) | 0x80;
2736 return 3;
2737 } else if (cp < 0x10FFFF) {
2738 out[0] = ((cp >> 18) & 0x07) | 0xF0;
2739 out[1] = ((cp >> 12) & 0x3f) | 0x80;
2740 out[2] = ((cp >> 6) & 0x3f) | 0x80;
2741 out[3] = ((cp >> 0) & 0x3f) | 0x80;
2742 return 4;
2743 } else {
2744 jsondec_err(d, "Invalid codepoint");
2745 }
2746 }
2747
jsondec_resize(jsondec * d,char ** buf,char ** end,char ** buf_end)2748 static void jsondec_resize(jsondec* d, char** buf, char** end, char** buf_end) {
2749 size_t oldsize = *buf_end - *buf;
2750 size_t len = *end - *buf;
2751 size_t size = UPB_MAX(8, 2 * oldsize);
2752
2753 *buf = upb_Arena_Realloc(d->arena, *buf, len, size);
2754 if (!*buf) jsondec_err(d, "Out of memory");
2755
2756 *end = *buf + len;
2757 *buf_end = *buf + size;
2758 }
2759
jsondec_string(jsondec * d)2760 static upb_StringView jsondec_string(jsondec* d) {
2761 char* buf = NULL;
2762 char* end = NULL;
2763 char* buf_end = NULL;
2764
2765 jsondec_skipws(d);
2766
2767 if (*d->ptr++ != '"') {
2768 jsondec_err(d, "Expected string");
2769 }
2770
2771 while (d->ptr < d->end) {
2772 char ch = *d->ptr++;
2773
2774 if (end == buf_end) {
2775 jsondec_resize(d, &buf, &end, &buf_end);
2776 }
2777
2778 switch (ch) {
2779 case '"': {
2780 upb_StringView ret;
2781 ret.data = buf;
2782 ret.size = end - buf;
2783 *end = '\0'; /* Needed for possible strtod(). */
2784 return ret;
2785 }
2786 case '\\':
2787 if (d->ptr == d->end) goto eof;
2788 if (*d->ptr == 'u') {
2789 d->ptr++;
2790 if (buf_end - end < 4) {
2791 /* Allow space for maximum-sized code point (4 bytes). */
2792 jsondec_resize(d, &buf, &end, &buf_end);
2793 }
2794 end += jsondec_unicode(d, end);
2795 } else {
2796 *end++ = jsondec_escape(d);
2797 }
2798 break;
2799 default:
2800 if ((unsigned char)*d->ptr < 0x20) {
2801 jsondec_err(d, "Invalid char in JSON string");
2802 }
2803 *end++ = ch;
2804 break;
2805 }
2806 }
2807
2808 eof:
2809 jsondec_err(d, "EOF inside string");
2810 }
2811
jsondec_skipval(jsondec * d)2812 static void jsondec_skipval(jsondec* d) {
2813 switch (jsondec_peek(d)) {
2814 case JD_OBJECT:
2815 jsondec_objstart(d);
2816 while (jsondec_objnext(d)) {
2817 jsondec_string(d);
2818 jsondec_entrysep(d);
2819 jsondec_skipval(d);
2820 }
2821 jsondec_objend(d);
2822 break;
2823 case JD_ARRAY:
2824 jsondec_arrstart(d);
2825 while (jsondec_arrnext(d)) {
2826 jsondec_skipval(d);
2827 }
2828 jsondec_arrend(d);
2829 break;
2830 case JD_TRUE:
2831 jsondec_true(d);
2832 break;
2833 case JD_FALSE:
2834 jsondec_false(d);
2835 break;
2836 case JD_NULL:
2837 jsondec_null(d);
2838 break;
2839 case JD_STRING:
2840 jsondec_string(d);
2841 break;
2842 case JD_NUMBER:
2843 jsondec_number(d);
2844 break;
2845 }
2846 }
2847
2848 /* Base64 decoding for bytes fields. ******************************************/
2849
jsondec_base64_tablelookup(const char ch)2850 static unsigned int jsondec_base64_tablelookup(const char ch) {
2851 /* Table includes the normal base64 chars plus the URL-safe variant. */
2852 const signed char table[256] = {
2853 -1, -1, -1, -1, -1, -1, -1,
2854 -1, -1, -1, -1, -1, -1, -1,
2855 -1, -1, -1, -1, -1, -1, -1,
2856 -1, -1, -1, -1, -1, -1, -1,
2857 -1, -1, -1, -1, -1, -1, -1,
2858 -1, -1, -1, -1, -1, -1, -1,
2859 -1, 62 /*+*/, -1, 62 /*-*/, -1, 63 /*/ */, 52 /*0*/,
2860 53 /*1*/, 54 /*2*/, 55 /*3*/, 56 /*4*/, 57 /*5*/, 58 /*6*/, 59 /*7*/,
2861 60 /*8*/, 61 /*9*/, -1, -1, -1, -1, -1,
2862 -1, -1, 0 /*A*/, 1 /*B*/, 2 /*C*/, 3 /*D*/, 4 /*E*/,
2863 5 /*F*/, 6 /*G*/, 07 /*H*/, 8 /*I*/, 9 /*J*/, 10 /*K*/, 11 /*L*/,
2864 12 /*M*/, 13 /*N*/, 14 /*O*/, 15 /*P*/, 16 /*Q*/, 17 /*R*/, 18 /*S*/,
2865 19 /*T*/, 20 /*U*/, 21 /*V*/, 22 /*W*/, 23 /*X*/, 24 /*Y*/, 25 /*Z*/,
2866 -1, -1, -1, -1, 63 /*_*/, -1, 26 /*a*/,
2867 27 /*b*/, 28 /*c*/, 29 /*d*/, 30 /*e*/, 31 /*f*/, 32 /*g*/, 33 /*h*/,
2868 34 /*i*/, 35 /*j*/, 36 /*k*/, 37 /*l*/, 38 /*m*/, 39 /*n*/, 40 /*o*/,
2869 41 /*p*/, 42 /*q*/, 43 /*r*/, 44 /*s*/, 45 /*t*/, 46 /*u*/, 47 /*v*/,
2870 48 /*w*/, 49 /*x*/, 50 /*y*/, 51 /*z*/, -1, -1, -1,
2871 -1, -1, -1, -1, -1, -1, -1,
2872 -1, -1, -1, -1, -1, -1, -1,
2873 -1, -1, -1, -1, -1, -1, -1,
2874 -1, -1, -1, -1, -1, -1, -1,
2875 -1, -1, -1, -1, -1, -1, -1,
2876 -1, -1, -1, -1, -1, -1, -1,
2877 -1, -1, -1, -1, -1, -1, -1,
2878 -1, -1, -1, -1, -1, -1, -1,
2879 -1, -1, -1, -1, -1, -1, -1,
2880 -1, -1, -1, -1, -1, -1, -1,
2881 -1, -1, -1, -1, -1, -1, -1,
2882 -1, -1, -1, -1, -1, -1, -1,
2883 -1, -1, -1, -1, -1, -1, -1,
2884 -1, -1, -1, -1, -1, -1, -1,
2885 -1, -1, -1, -1, -1, -1, -1,
2886 -1, -1, -1, -1, -1, -1, -1,
2887 -1, -1, -1, -1, -1, -1, -1,
2888 -1, -1, -1, -1, -1, -1, -1,
2889 -1, -1, -1, -1};
2890
2891 /* Sign-extend return value so high bit will be set on any unexpected char. */
2892 return table[(unsigned)ch];
2893 }
2894
jsondec_partialbase64(jsondec * d,const char * ptr,const char * end,char * out)2895 static char* jsondec_partialbase64(jsondec* d, const char* ptr, const char* end,
2896 char* out) {
2897 int32_t val = -1;
2898
2899 switch (end - ptr) {
2900 case 2:
2901 val = jsondec_base64_tablelookup(ptr[0]) << 18 |
2902 jsondec_base64_tablelookup(ptr[1]) << 12;
2903 out[0] = val >> 16;
2904 out += 1;
2905 break;
2906 case 3:
2907 val = jsondec_base64_tablelookup(ptr[0]) << 18 |
2908 jsondec_base64_tablelookup(ptr[1]) << 12 |
2909 jsondec_base64_tablelookup(ptr[2]) << 6;
2910 out[0] = val >> 16;
2911 out[1] = (val >> 8) & 0xff;
2912 out += 2;
2913 break;
2914 }
2915
2916 if (val < 0) {
2917 jsondec_err(d, "Corrupt base64");
2918 }
2919
2920 return out;
2921 }
2922
jsondec_base64(jsondec * d,upb_StringView str)2923 static size_t jsondec_base64(jsondec* d, upb_StringView str) {
2924 /* We decode in place. This is safe because this is a new buffer (not
2925 * aliasing the input) and because base64 decoding shrinks 4 bytes into 3. */
2926 char* out = (char*)str.data;
2927 const char* ptr = str.data;
2928 const char* end = ptr + str.size;
2929 const char* end4 = ptr + (str.size & -4); /* Round down to multiple of 4. */
2930
2931 for (; ptr < end4; ptr += 4, out += 3) {
2932 int val = jsondec_base64_tablelookup(ptr[0]) << 18 |
2933 jsondec_base64_tablelookup(ptr[1]) << 12 |
2934 jsondec_base64_tablelookup(ptr[2]) << 6 |
2935 jsondec_base64_tablelookup(ptr[3]) << 0;
2936
2937 if (val < 0) {
2938 /* Junk chars or padding. Remove trailing padding, if any. */
2939 if (end - ptr == 4 && ptr[3] == '=') {
2940 if (ptr[2] == '=') {
2941 end -= 2;
2942 } else {
2943 end -= 1;
2944 }
2945 }
2946 break;
2947 }
2948
2949 out[0] = val >> 16;
2950 out[1] = (val >> 8) & 0xff;
2951 out[2] = val & 0xff;
2952 }
2953
2954 if (ptr < end) {
2955 /* Process remaining chars. We do not require padding. */
2956 out = jsondec_partialbase64(d, ptr, end, out);
2957 }
2958
2959 return out - str.data;
2960 }
2961
2962 /* Low-level integer parsing **************************************************/
2963
2964 /* We use these hand-written routines instead of strto[u]l() because the "long
2965 * long" variants aren't in c89. Also our version allows setting a ptr limit. */
2966
jsondec_buftouint64(jsondec * d,const char * ptr,const char * end,uint64_t * val)2967 static const char* jsondec_buftouint64(jsondec* d, const char* ptr,
2968 const char* end, uint64_t* val) {
2969 uint64_t u64 = 0;
2970 while (ptr < end) {
2971 unsigned ch = *ptr - '0';
2972 if (ch >= 10) break;
2973 if (u64 > UINT64_MAX / 10 || u64 * 10 > UINT64_MAX - ch) {
2974 jsondec_err(d, "Integer overflow");
2975 }
2976 u64 *= 10;
2977 u64 += ch;
2978 ptr++;
2979 }
2980
2981 *val = u64;
2982 return ptr;
2983 }
2984
jsondec_buftoint64(jsondec * d,const char * ptr,const char * end,int64_t * val)2985 static const char* jsondec_buftoint64(jsondec* d, const char* ptr,
2986 const char* end, int64_t* val) {
2987 bool neg = false;
2988 uint64_t u64;
2989
2990 if (ptr != end && *ptr == '-') {
2991 ptr++;
2992 neg = true;
2993 }
2994
2995 ptr = jsondec_buftouint64(d, ptr, end, &u64);
2996 if (u64 > (uint64_t)INT64_MAX + neg) {
2997 jsondec_err(d, "Integer overflow");
2998 }
2999
3000 *val = neg ? -u64 : u64;
3001 return ptr;
3002 }
3003
jsondec_strtouint64(jsondec * d,upb_StringView str)3004 static uint64_t jsondec_strtouint64(jsondec* d, upb_StringView str) {
3005 const char* end = str.data + str.size;
3006 uint64_t ret;
3007 if (jsondec_buftouint64(d, str.data, end, &ret) != end) {
3008 jsondec_err(d, "Non-number characters in quoted integer");
3009 }
3010 return ret;
3011 }
3012
jsondec_strtoint64(jsondec * d,upb_StringView str)3013 static int64_t jsondec_strtoint64(jsondec* d, upb_StringView str) {
3014 const char* end = str.data + str.size;
3015 int64_t ret;
3016 if (jsondec_buftoint64(d, str.data, end, &ret) != end) {
3017 jsondec_err(d, "Non-number characters in quoted integer");
3018 }
3019 return ret;
3020 }
3021
3022 /* Primitive value types ******************************************************/
3023
3024 /* Parse INT32 or INT64 value. */
jsondec_int(jsondec * d,const upb_FieldDef * f)3025 static upb_MessageValue jsondec_int(jsondec* d, const upb_FieldDef* f) {
3026 upb_MessageValue val;
3027
3028 switch (jsondec_peek(d)) {
3029 case JD_NUMBER: {
3030 double dbl = jsondec_number(d);
3031 if (dbl > 9223372036854774784.0 || dbl < -9223372036854775808.0) {
3032 jsondec_err(d, "JSON number is out of range.");
3033 }
3034 val.int64_val = dbl; /* must be guarded, overflow here is UB */
3035 if (val.int64_val != dbl) {
3036 jsondec_errf(d, "JSON number was not integral (%f != %" PRId64 ")", dbl,
3037 val.int64_val);
3038 }
3039 break;
3040 }
3041 case JD_STRING: {
3042 upb_StringView str = jsondec_string(d);
3043 val.int64_val = jsondec_strtoint64(d, str);
3044 break;
3045 }
3046 default:
3047 jsondec_err(d, "Expected number or string");
3048 }
3049
3050 if (upb_FieldDef_CType(f) == kUpb_CType_Int32 ||
3051 upb_FieldDef_CType(f) == kUpb_CType_Enum) {
3052 if (val.int64_val > INT32_MAX || val.int64_val < INT32_MIN) {
3053 jsondec_err(d, "Integer out of range.");
3054 }
3055 val.int32_val = (int32_t)val.int64_val;
3056 }
3057
3058 return val;
3059 }
3060
3061 /* Parse UINT32 or UINT64 value. */
jsondec_uint(jsondec * d,const upb_FieldDef * f)3062 static upb_MessageValue jsondec_uint(jsondec* d, const upb_FieldDef* f) {
3063 upb_MessageValue val = {0};
3064
3065 switch (jsondec_peek(d)) {
3066 case JD_NUMBER: {
3067 double dbl = jsondec_number(d);
3068 if (dbl > 18446744073709549568.0 || dbl < 0) {
3069 jsondec_err(d, "JSON number is out of range.");
3070 }
3071 val.uint64_val = dbl; /* must be guarded, overflow here is UB */
3072 if (val.uint64_val != dbl) {
3073 jsondec_errf(d, "JSON number was not integral (%f != %" PRIu64 ")", dbl,
3074 val.uint64_val);
3075 }
3076 break;
3077 }
3078 case JD_STRING: {
3079 upb_StringView str = jsondec_string(d);
3080 val.uint64_val = jsondec_strtouint64(d, str);
3081 break;
3082 }
3083 default:
3084 jsondec_err(d, "Expected number or string");
3085 }
3086
3087 if (upb_FieldDef_CType(f) == kUpb_CType_UInt32) {
3088 if (val.uint64_val > UINT32_MAX) {
3089 jsondec_err(d, "Integer out of range.");
3090 }
3091 val.uint32_val = (uint32_t)val.uint64_val;
3092 }
3093
3094 return val;
3095 }
3096
3097 /* Parse DOUBLE or FLOAT value. */
jsondec_double(jsondec * d,const upb_FieldDef * f)3098 static upb_MessageValue jsondec_double(jsondec* d, const upb_FieldDef* f) {
3099 upb_StringView str;
3100 upb_MessageValue val = {0};
3101
3102 switch (jsondec_peek(d)) {
3103 case JD_NUMBER:
3104 val.double_val = jsondec_number(d);
3105 break;
3106 case JD_STRING:
3107 str = jsondec_string(d);
3108 if (jsondec_streql(str, "NaN")) {
3109 val.double_val = NAN;
3110 } else if (jsondec_streql(str, "Infinity")) {
3111 val.double_val = INFINITY;
3112 } else if (jsondec_streql(str, "-Infinity")) {
3113 val.double_val = -INFINITY;
3114 } else {
3115 val.double_val = strtod(str.data, NULL);
3116 }
3117 break;
3118 default:
3119 jsondec_err(d, "Expected number or string");
3120 }
3121
3122 if (upb_FieldDef_CType(f) == kUpb_CType_Float) {
3123 if (val.double_val != INFINITY && val.double_val != -INFINITY &&
3124 (val.double_val > FLT_MAX || val.double_val < -FLT_MAX)) {
3125 jsondec_err(d, "Float out of range");
3126 }
3127 val.float_val = val.double_val;
3128 }
3129
3130 return val;
3131 }
3132
3133 /* Parse STRING or BYTES value. */
jsondec_strfield(jsondec * d,const upb_FieldDef * f)3134 static upb_MessageValue jsondec_strfield(jsondec* d, const upb_FieldDef* f) {
3135 upb_MessageValue val;
3136 val.str_val = jsondec_string(d);
3137 if (upb_FieldDef_CType(f) == kUpb_CType_Bytes) {
3138 val.str_val.size = jsondec_base64(d, val.str_val);
3139 }
3140 return val;
3141 }
3142
jsondec_enum(jsondec * d,const upb_FieldDef * f)3143 static upb_MessageValue jsondec_enum(jsondec* d, const upb_FieldDef* f) {
3144 switch (jsondec_peek(d)) {
3145 case JD_STRING: {
3146 upb_StringView str = jsondec_string(d);
3147 const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f);
3148 const upb_EnumValueDef* ev =
3149 upb_EnumDef_FindValueByNameWithSize(e, str.data, str.size);
3150 upb_MessageValue val;
3151 if (ev) {
3152 val.int32_val = upb_EnumValueDef_Number(ev);
3153 } else {
3154 if (d->options & upb_JsonDecode_IgnoreUnknown) {
3155 val.int32_val = 0;
3156 } else {
3157 jsondec_errf(d, "Unknown enumerator: '" UPB_STRINGVIEW_FORMAT "'",
3158 UPB_STRINGVIEW_ARGS(str));
3159 }
3160 }
3161 return val;
3162 }
3163 case JD_NULL: {
3164 if (jsondec_isnullvalue(f)) {
3165 upb_MessageValue val;
3166 jsondec_null(d);
3167 val.int32_val = 0;
3168 return val;
3169 }
3170 }
3171 /* Fallthrough. */
3172 default:
3173 return jsondec_int(d, f);
3174 }
3175 }
3176
jsondec_bool(jsondec * d,const upb_FieldDef * f)3177 static upb_MessageValue jsondec_bool(jsondec* d, const upb_FieldDef* f) {
3178 bool is_map_key = upb_FieldDef_Number(f) == 1 &&
3179 upb_MessageDef_IsMapEntry(upb_FieldDef_ContainingType(f));
3180 upb_MessageValue val;
3181
3182 if (is_map_key) {
3183 upb_StringView str = jsondec_string(d);
3184 if (jsondec_streql(str, "true")) {
3185 val.bool_val = true;
3186 } else if (jsondec_streql(str, "false")) {
3187 val.bool_val = false;
3188 } else {
3189 jsondec_err(d, "Invalid boolean map key");
3190 }
3191 } else {
3192 switch (jsondec_peek(d)) {
3193 case JD_TRUE:
3194 val.bool_val = true;
3195 jsondec_true(d);
3196 break;
3197 case JD_FALSE:
3198 val.bool_val = false;
3199 jsondec_false(d);
3200 break;
3201 default:
3202 jsondec_err(d, "Expected true or false");
3203 }
3204 }
3205
3206 return val;
3207 }
3208
3209 /* Composite types (array/message/map) ****************************************/
3210
jsondec_array(jsondec * d,upb_Message * msg,const upb_FieldDef * f)3211 static void jsondec_array(jsondec* d, upb_Message* msg, const upb_FieldDef* f) {
3212 upb_Array* arr = upb_Message_Mutable(msg, f, d->arena).array;
3213
3214 jsondec_arrstart(d);
3215 while (jsondec_arrnext(d)) {
3216 upb_MessageValue elem = jsondec_value(d, f);
3217 upb_Array_Append(arr, elem, d->arena);
3218 }
3219 jsondec_arrend(d);
3220 }
3221
jsondec_map(jsondec * d,upb_Message * msg,const upb_FieldDef * f)3222 static void jsondec_map(jsondec* d, upb_Message* msg, const upb_FieldDef* f) {
3223 upb_Map* map = upb_Message_Mutable(msg, f, d->arena).map;
3224 const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f);
3225 const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry, 1);
3226 const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry, 2);
3227
3228 jsondec_objstart(d);
3229 while (jsondec_objnext(d)) {
3230 upb_MessageValue key, val;
3231 key = jsondec_value(d, key_f);
3232 jsondec_entrysep(d);
3233 val = jsondec_value(d, val_f);
3234 upb_Map_Set(map, key, val, d->arena);
3235 }
3236 jsondec_objend(d);
3237 }
3238
jsondec_tomsg(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3239 static void jsondec_tomsg(jsondec* d, upb_Message* msg,
3240 const upb_MessageDef* m) {
3241 if (upb_MessageDef_WellKnownType(m) == kUpb_WellKnown_Unspecified) {
3242 jsondec_object(d, msg, m);
3243 } else {
3244 jsondec_wellknown(d, msg, m);
3245 }
3246 }
3247
jsondec_msg(jsondec * d,const upb_FieldDef * f)3248 static upb_MessageValue jsondec_msg(jsondec* d, const upb_FieldDef* f) {
3249 const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
3250 upb_Message* msg = upb_Message_New(m, d->arena);
3251 upb_MessageValue val;
3252
3253 jsondec_tomsg(d, msg, m);
3254 val.msg_val = msg;
3255 return val;
3256 }
3257
jsondec_field(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3258 static void jsondec_field(jsondec* d, upb_Message* msg,
3259 const upb_MessageDef* m) {
3260 upb_StringView name;
3261 const upb_FieldDef* f;
3262 const upb_FieldDef* preserved;
3263
3264 name = jsondec_string(d);
3265 jsondec_entrysep(d);
3266
3267 if (name.size >= 2 && name.data[0] == '[' &&
3268 name.data[name.size - 1] == ']') {
3269 f = upb_DefPool_FindExtensionByNameWithSize(d->symtab, name.data + 1,
3270 name.size - 2);
3271 if (f && upb_FieldDef_ContainingType(f) != m) {
3272 jsondec_errf(
3273 d, "Extension %s extends message %s, but was seen in message %s",
3274 upb_FieldDef_FullName(f),
3275 upb_MessageDef_FullName(upb_FieldDef_ContainingType(f)),
3276 upb_MessageDef_FullName(m));
3277 }
3278 } else {
3279 f = upb_MessageDef_FindByJsonNameWithSize(m, name.data, name.size);
3280 }
3281
3282 if (!f) {
3283 if ((d->options & upb_JsonDecode_IgnoreUnknown) == 0) {
3284 jsondec_errf(d, "No such field: " UPB_STRINGVIEW_FORMAT,
3285 UPB_STRINGVIEW_ARGS(name));
3286 }
3287 jsondec_skipval(d);
3288 return;
3289 }
3290
3291 if (jsondec_peek(d) == JD_NULL && !jsondec_isvalue(f)) {
3292 /* JSON "null" indicates a default value, so no need to set anything. */
3293 jsondec_null(d);
3294 return;
3295 }
3296
3297 if (upb_FieldDef_RealContainingOneof(f) &&
3298 upb_Message_WhichOneof(msg, upb_FieldDef_ContainingOneof(f))) {
3299 jsondec_err(d, "More than one field for this oneof.");
3300 }
3301
3302 preserved = d->debug_field;
3303 d->debug_field = f;
3304
3305 if (upb_FieldDef_IsMap(f)) {
3306 jsondec_map(d, msg, f);
3307 } else if (upb_FieldDef_IsRepeated(f)) {
3308 jsondec_array(d, msg, f);
3309 } else if (upb_FieldDef_IsSubMessage(f)) {
3310 upb_Message* submsg = upb_Message_Mutable(msg, f, d->arena).msg;
3311 const upb_MessageDef* subm = upb_FieldDef_MessageSubDef(f);
3312 jsondec_tomsg(d, submsg, subm);
3313 } else {
3314 upb_MessageValue val = jsondec_value(d, f);
3315 upb_Message_Set(msg, f, val, d->arena);
3316 }
3317
3318 d->debug_field = preserved;
3319 }
3320
jsondec_object(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3321 static void jsondec_object(jsondec* d, upb_Message* msg,
3322 const upb_MessageDef* m) {
3323 jsondec_objstart(d);
3324 while (jsondec_objnext(d)) {
3325 jsondec_field(d, msg, m);
3326 }
3327 jsondec_objend(d);
3328 }
3329
jsondec_value(jsondec * d,const upb_FieldDef * f)3330 static upb_MessageValue jsondec_value(jsondec* d, const upb_FieldDef* f) {
3331 switch (upb_FieldDef_CType(f)) {
3332 case kUpb_CType_Bool:
3333 return jsondec_bool(d, f);
3334 case kUpb_CType_Float:
3335 case kUpb_CType_Double:
3336 return jsondec_double(d, f);
3337 case kUpb_CType_UInt32:
3338 case kUpb_CType_UInt64:
3339 return jsondec_uint(d, f);
3340 case kUpb_CType_Int32:
3341 case kUpb_CType_Int64:
3342 return jsondec_int(d, f);
3343 case kUpb_CType_String:
3344 case kUpb_CType_Bytes:
3345 return jsondec_strfield(d, f);
3346 case kUpb_CType_Enum:
3347 return jsondec_enum(d, f);
3348 case kUpb_CType_Message:
3349 return jsondec_msg(d, f);
3350 default:
3351 UPB_UNREACHABLE();
3352 }
3353 }
3354
3355 /* Well-known types ***********************************************************/
3356
jsondec_tsdigits(jsondec * d,const char ** ptr,size_t digits,const char * after)3357 static int jsondec_tsdigits(jsondec* d, const char** ptr, size_t digits,
3358 const char* after) {
3359 uint64_t val;
3360 const char* p = *ptr;
3361 const char* end = p + digits;
3362 size_t after_len = after ? strlen(after) : 0;
3363
3364 UPB_ASSERT(digits <= 9); /* int can't overflow. */
3365
3366 if (jsondec_buftouint64(d, p, end, &val) != end ||
3367 (after_len && memcmp(end, after, after_len) != 0)) {
3368 jsondec_err(d, "Malformed timestamp");
3369 }
3370
3371 UPB_ASSERT(val < INT_MAX);
3372
3373 *ptr = end + after_len;
3374 return (int)val;
3375 }
3376
jsondec_nanos(jsondec * d,const char ** ptr,const char * end)3377 static int jsondec_nanos(jsondec* d, const char** ptr, const char* end) {
3378 uint64_t nanos = 0;
3379 const char* p = *ptr;
3380
3381 if (p != end && *p == '.') {
3382 const char* nano_end = jsondec_buftouint64(d, p + 1, end, &nanos);
3383 int digits = (int)(nano_end - p - 1);
3384 int exp_lg10 = 9 - digits;
3385 if (digits > 9) {
3386 jsondec_err(d, "Too many digits for partial seconds");
3387 }
3388 while (exp_lg10--) nanos *= 10;
3389 *ptr = nano_end;
3390 }
3391
3392 UPB_ASSERT(nanos < INT_MAX);
3393
3394 return (int)nanos;
3395 }
3396
3397 /* jsondec_epochdays(1970, 1, 1) == 1970-01-01 == 0. */
jsondec_epochdays(int y,int m,int d)3398 int jsondec_epochdays(int y, int m, int d) {
3399 const uint32_t year_base = 4800; /* Before min year, multiple of 400. */
3400 const uint32_t m_adj = m - 3; /* March-based month. */
3401 const uint32_t carry = m_adj > (uint32_t)m ? 1 : 0;
3402 const uint32_t adjust = carry ? 12 : 0;
3403 const uint32_t y_adj = y + year_base - carry;
3404 const uint32_t month_days = ((m_adj + adjust) * 62719 + 769) / 2048;
3405 const uint32_t leap_days = y_adj / 4 - y_adj / 100 + y_adj / 400;
3406 return y_adj * 365 + leap_days + month_days + (d - 1) - 2472632;
3407 }
3408
jsondec_unixtime(int y,int m,int d,int h,int min,int s)3409 static int64_t jsondec_unixtime(int y, int m, int d, int h, int min, int s) {
3410 return (int64_t)jsondec_epochdays(y, m, d) * 86400 + h * 3600 + min * 60 + s;
3411 }
3412
jsondec_timestamp(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3413 static void jsondec_timestamp(jsondec* d, upb_Message* msg,
3414 const upb_MessageDef* m) {
3415 upb_MessageValue seconds;
3416 upb_MessageValue nanos;
3417 upb_StringView str = jsondec_string(d);
3418 const char* ptr = str.data;
3419 const char* end = ptr + str.size;
3420
3421 if (str.size < 20) goto malformed;
3422
3423 {
3424 /* 1972-01-01T01:00:00 */
3425 int year = jsondec_tsdigits(d, &ptr, 4, "-");
3426 int mon = jsondec_tsdigits(d, &ptr, 2, "-");
3427 int day = jsondec_tsdigits(d, &ptr, 2, "T");
3428 int hour = jsondec_tsdigits(d, &ptr, 2, ":");
3429 int min = jsondec_tsdigits(d, &ptr, 2, ":");
3430 int sec = jsondec_tsdigits(d, &ptr, 2, NULL);
3431
3432 seconds.int64_val = jsondec_unixtime(year, mon, day, hour, min, sec);
3433 }
3434
3435 nanos.int32_val = jsondec_nanos(d, &ptr, end);
3436
3437 {
3438 /* [+-]08:00 or Z */
3439 int ofs_hour = 0;
3440 int ofs_min = 0;
3441 bool neg = false;
3442
3443 if (ptr == end) goto malformed;
3444
3445 switch (*ptr++) {
3446 case '-':
3447 neg = true;
3448 /* fallthrough */
3449 case '+':
3450 if ((end - ptr) != 5) goto malformed;
3451 ofs_hour = jsondec_tsdigits(d, &ptr, 2, ":");
3452 ofs_min = jsondec_tsdigits(d, &ptr, 2, NULL);
3453 ofs_min = ((ofs_hour * 60) + ofs_min) * 60;
3454 seconds.int64_val += (neg ? ofs_min : -ofs_min);
3455 break;
3456 case 'Z':
3457 if (ptr != end) goto malformed;
3458 break;
3459 default:
3460 goto malformed;
3461 }
3462 }
3463
3464 if (seconds.int64_val < -62135596800) {
3465 jsondec_err(d, "Timestamp out of range");
3466 }
3467
3468 upb_Message_Set(msg, upb_MessageDef_FindFieldByNumber(m, 1), seconds,
3469 d->arena);
3470 upb_Message_Set(msg, upb_MessageDef_FindFieldByNumber(m, 2), nanos, d->arena);
3471 return;
3472
3473 malformed:
3474 jsondec_err(d, "Malformed timestamp");
3475 }
3476
jsondec_duration(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3477 static void jsondec_duration(jsondec* d, upb_Message* msg,
3478 const upb_MessageDef* m) {
3479 upb_MessageValue seconds;
3480 upb_MessageValue nanos;
3481 upb_StringView str = jsondec_string(d);
3482 const char* ptr = str.data;
3483 const char* end = ptr + str.size;
3484 const int64_t max = (uint64_t)3652500 * 86400;
3485
3486 /* "3.000000001s", "3s", etc. */
3487 ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val);
3488 nanos.int32_val = jsondec_nanos(d, &ptr, end);
3489
3490 if (end - ptr != 1 || *ptr != 's') {
3491 jsondec_err(d, "Malformed duration");
3492 }
3493
3494 if (seconds.int64_val < -max || seconds.int64_val > max) {
3495 jsondec_err(d, "Duration out of range");
3496 }
3497
3498 if (seconds.int64_val < 0) {
3499 nanos.int32_val = -nanos.int32_val;
3500 }
3501
3502 upb_Message_Set(msg, upb_MessageDef_FindFieldByNumber(m, 1), seconds,
3503 d->arena);
3504 upb_Message_Set(msg, upb_MessageDef_FindFieldByNumber(m, 2), nanos, d->arena);
3505 }
3506
jsondec_listvalue(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3507 static void jsondec_listvalue(jsondec* d, upb_Message* msg,
3508 const upb_MessageDef* m) {
3509 const upb_FieldDef* values_f = upb_MessageDef_FindFieldByNumber(m, 1);
3510 const upb_MessageDef* value_m = upb_FieldDef_MessageSubDef(values_f);
3511 upb_Array* values = upb_Message_Mutable(msg, values_f, d->arena).array;
3512
3513 jsondec_arrstart(d);
3514 while (jsondec_arrnext(d)) {
3515 upb_Message* value_msg = upb_Message_New(value_m, d->arena);
3516 upb_MessageValue value;
3517 value.msg_val = value_msg;
3518 upb_Array_Append(values, value, d->arena);
3519 jsondec_wellknownvalue(d, value_msg, value_m);
3520 }
3521 jsondec_arrend(d);
3522 }
3523
jsondec_struct(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3524 static void jsondec_struct(jsondec* d, upb_Message* msg,
3525 const upb_MessageDef* m) {
3526 const upb_FieldDef* fields_f = upb_MessageDef_FindFieldByNumber(m, 1);
3527 const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(fields_f);
3528 const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(entry_m, 2);
3529 const upb_MessageDef* value_m = upb_FieldDef_MessageSubDef(value_f);
3530 upb_Map* fields = upb_Message_Mutable(msg, fields_f, d->arena).map;
3531
3532 jsondec_objstart(d);
3533 while (jsondec_objnext(d)) {
3534 upb_MessageValue key, value;
3535 upb_Message* value_msg = upb_Message_New(value_m, d->arena);
3536 key.str_val = jsondec_string(d);
3537 value.msg_val = value_msg;
3538 upb_Map_Set(fields, key, value, d->arena);
3539 jsondec_entrysep(d);
3540 jsondec_wellknownvalue(d, value_msg, value_m);
3541 }
3542 jsondec_objend(d);
3543 }
3544
jsondec_wellknownvalue(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3545 static void jsondec_wellknownvalue(jsondec* d, upb_Message* msg,
3546 const upb_MessageDef* m) {
3547 upb_MessageValue val;
3548 const upb_FieldDef* f;
3549 upb_Message* submsg;
3550
3551 switch (jsondec_peek(d)) {
3552 case JD_NUMBER:
3553 /* double number_value = 2; */
3554 f = upb_MessageDef_FindFieldByNumber(m, 2);
3555 val.double_val = jsondec_number(d);
3556 break;
3557 case JD_STRING:
3558 /* string string_value = 3; */
3559 f = upb_MessageDef_FindFieldByNumber(m, 3);
3560 val.str_val = jsondec_string(d);
3561 break;
3562 case JD_FALSE:
3563 /* bool bool_value = 4; */
3564 f = upb_MessageDef_FindFieldByNumber(m, 4);
3565 val.bool_val = false;
3566 jsondec_false(d);
3567 break;
3568 case JD_TRUE:
3569 /* bool bool_value = 4; */
3570 f = upb_MessageDef_FindFieldByNumber(m, 4);
3571 val.bool_val = true;
3572 jsondec_true(d);
3573 break;
3574 case JD_NULL:
3575 /* NullValue null_value = 1; */
3576 f = upb_MessageDef_FindFieldByNumber(m, 1);
3577 val.int32_val = 0;
3578 jsondec_null(d);
3579 break;
3580 /* Note: these cases return, because upb_Message_Mutable() is enough. */
3581 case JD_OBJECT:
3582 /* Struct struct_value = 5; */
3583 f = upb_MessageDef_FindFieldByNumber(m, 5);
3584 submsg = upb_Message_Mutable(msg, f, d->arena).msg;
3585 jsondec_struct(d, submsg, upb_FieldDef_MessageSubDef(f));
3586 return;
3587 case JD_ARRAY:
3588 /* ListValue list_value = 6; */
3589 f = upb_MessageDef_FindFieldByNumber(m, 6);
3590 submsg = upb_Message_Mutable(msg, f, d->arena).msg;
3591 jsondec_listvalue(d, submsg, upb_FieldDef_MessageSubDef(f));
3592 return;
3593 default:
3594 UPB_UNREACHABLE();
3595 }
3596
3597 upb_Message_Set(msg, f, val, d->arena);
3598 }
3599
jsondec_mask(jsondec * d,const char * buf,const char * end)3600 static upb_StringView jsondec_mask(jsondec* d, const char* buf,
3601 const char* end) {
3602 /* FieldMask fields grow due to inserted '_' characters, so we can't do the
3603 * transform in place. */
3604 const char* ptr = buf;
3605 upb_StringView ret;
3606 char* out;
3607
3608 ret.size = end - ptr;
3609 while (ptr < end) {
3610 ret.size += (*ptr >= 'A' && *ptr <= 'Z');
3611 ptr++;
3612 }
3613
3614 out = upb_Arena_Malloc(d->arena, ret.size);
3615 ptr = buf;
3616 ret.data = out;
3617
3618 while (ptr < end) {
3619 char ch = *ptr++;
3620 if (ch >= 'A' && ch <= 'Z') {
3621 *out++ = '_';
3622 *out++ = ch + 32;
3623 } else if (ch == '_') {
3624 jsondec_err(d, "field mask may not contain '_'");
3625 } else {
3626 *out++ = ch;
3627 }
3628 }
3629
3630 return ret;
3631 }
3632
jsondec_fieldmask(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3633 static void jsondec_fieldmask(jsondec* d, upb_Message* msg,
3634 const upb_MessageDef* m) {
3635 /* repeated string paths = 1; */
3636 const upb_FieldDef* paths_f = upb_MessageDef_FindFieldByNumber(m, 1);
3637 upb_Array* arr = upb_Message_Mutable(msg, paths_f, d->arena).array;
3638 upb_StringView str = jsondec_string(d);
3639 const char* ptr = str.data;
3640 const char* end = ptr + str.size;
3641 upb_MessageValue val;
3642
3643 while (ptr < end) {
3644 const char* elem_end = memchr(ptr, ',', end - ptr);
3645 if (elem_end) {
3646 val.str_val = jsondec_mask(d, ptr, elem_end);
3647 ptr = elem_end + 1;
3648 } else {
3649 val.str_val = jsondec_mask(d, ptr, end);
3650 ptr = end;
3651 }
3652 upb_Array_Append(arr, val, d->arena);
3653 }
3654 }
3655
jsondec_anyfield(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3656 static void jsondec_anyfield(jsondec* d, upb_Message* msg,
3657 const upb_MessageDef* m) {
3658 if (upb_MessageDef_WellKnownType(m) == kUpb_WellKnown_Unspecified) {
3659 /* For regular types: {"@type": "[user type]", "f1": <V1>, "f2": <V2>}
3660 * where f1, f2, etc. are the normal fields of this type. */
3661 jsondec_field(d, msg, m);
3662 } else {
3663 /* For well-known types: {"@type": "[well-known type]", "value": <X>}
3664 * where <X> is whatever encoding the WKT normally uses. */
3665 upb_StringView str = jsondec_string(d);
3666 jsondec_entrysep(d);
3667 if (!jsondec_streql(str, "value")) {
3668 jsondec_err(d, "Key for well-known type must be 'value'");
3669 }
3670 jsondec_wellknown(d, msg, m);
3671 }
3672 }
3673
jsondec_typeurl(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3674 static const upb_MessageDef* jsondec_typeurl(jsondec* d, upb_Message* msg,
3675 const upb_MessageDef* m) {
3676 const upb_FieldDef* type_url_f = upb_MessageDef_FindFieldByNumber(m, 1);
3677 const upb_MessageDef* type_m;
3678 upb_StringView type_url = jsondec_string(d);
3679 const char* end = type_url.data + type_url.size;
3680 const char* ptr = end;
3681 upb_MessageValue val;
3682
3683 val.str_val = type_url;
3684 upb_Message_Set(msg, type_url_f, val, d->arena);
3685
3686 /* Find message name after the last '/' */
3687 while (ptr > type_url.data && *--ptr != '/') {
3688 }
3689
3690 if (ptr == type_url.data || ptr == end) {
3691 jsondec_err(d, "Type url must have at least one '/' and non-empty host");
3692 }
3693
3694 ptr++;
3695 type_m = upb_DefPool_FindMessageByNameWithSize(d->symtab, ptr, end - ptr);
3696
3697 if (!type_m) {
3698 jsondec_err(d, "Type was not found");
3699 }
3700
3701 return type_m;
3702 }
3703
jsondec_any(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3704 static void jsondec_any(jsondec* d, upb_Message* msg, const upb_MessageDef* m) {
3705 /* string type_url = 1;
3706 * bytes value = 2; */
3707 const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(m, 2);
3708 upb_Message* any_msg;
3709 const upb_MessageDef* any_m = NULL;
3710 const char* pre_type_data = NULL;
3711 const char* pre_type_end = NULL;
3712 upb_MessageValue encoded;
3713
3714 jsondec_objstart(d);
3715
3716 /* Scan looking for "@type", which is not necessarily first. */
3717 while (!any_m && jsondec_objnext(d)) {
3718 const char* start = d->ptr;
3719 upb_StringView name = jsondec_string(d);
3720 jsondec_entrysep(d);
3721 if (jsondec_streql(name, "@type")) {
3722 any_m = jsondec_typeurl(d, msg, m);
3723 if (pre_type_data) {
3724 pre_type_end = start;
3725 while (*pre_type_end != ',') pre_type_end--;
3726 }
3727 } else {
3728 if (!pre_type_data) pre_type_data = start;
3729 jsondec_skipval(d);
3730 }
3731 }
3732
3733 if (!any_m) {
3734 jsondec_err(d, "Any object didn't contain a '@type' field");
3735 }
3736
3737 any_msg = upb_Message_New(any_m, d->arena);
3738
3739 if (pre_type_data) {
3740 size_t len = pre_type_end - pre_type_data + 1;
3741 char* tmp = upb_Arena_Malloc(d->arena, len);
3742 const char* saved_ptr = d->ptr;
3743 const char* saved_end = d->end;
3744 memcpy(tmp, pre_type_data, len - 1);
3745 tmp[len - 1] = '}';
3746 d->ptr = tmp;
3747 d->end = tmp + len;
3748 d->is_first = true;
3749 while (jsondec_objnext(d)) {
3750 jsondec_anyfield(d, any_msg, any_m);
3751 }
3752 d->ptr = saved_ptr;
3753 d->end = saved_end;
3754 }
3755
3756 while (jsondec_objnext(d)) {
3757 jsondec_anyfield(d, any_msg, any_m);
3758 }
3759
3760 jsondec_objend(d);
3761
3762 encoded.str_val.data = upb_Encode(any_msg, upb_MessageDef_MiniTable(any_m), 0,
3763 d->arena, &encoded.str_val.size);
3764 upb_Message_Set(msg, value_f, encoded, d->arena);
3765 }
3766
jsondec_wrapper(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3767 static void jsondec_wrapper(jsondec* d, upb_Message* msg,
3768 const upb_MessageDef* m) {
3769 const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(m, 1);
3770 upb_MessageValue val = jsondec_value(d, value_f);
3771 upb_Message_Set(msg, value_f, val, d->arena);
3772 }
3773
jsondec_wellknown(jsondec * d,upb_Message * msg,const upb_MessageDef * m)3774 static void jsondec_wellknown(jsondec* d, upb_Message* msg,
3775 const upb_MessageDef* m) {
3776 switch (upb_MessageDef_WellKnownType(m)) {
3777 case kUpb_WellKnown_Any:
3778 jsondec_any(d, msg, m);
3779 break;
3780 case kUpb_WellKnown_FieldMask:
3781 jsondec_fieldmask(d, msg, m);
3782 break;
3783 case kUpb_WellKnown_Duration:
3784 jsondec_duration(d, msg, m);
3785 break;
3786 case kUpb_WellKnown_Timestamp:
3787 jsondec_timestamp(d, msg, m);
3788 break;
3789 case kUpb_WellKnown_Value:
3790 jsondec_wellknownvalue(d, msg, m);
3791 break;
3792 case kUpb_WellKnown_ListValue:
3793 jsondec_listvalue(d, msg, m);
3794 break;
3795 case kUpb_WellKnown_Struct:
3796 jsondec_struct(d, msg, m);
3797 break;
3798 case kUpb_WellKnown_DoubleValue:
3799 case kUpb_WellKnown_FloatValue:
3800 case kUpb_WellKnown_Int64Value:
3801 case kUpb_WellKnown_UInt64Value:
3802 case kUpb_WellKnown_Int32Value:
3803 case kUpb_WellKnown_UInt32Value:
3804 case kUpb_WellKnown_StringValue:
3805 case kUpb_WellKnown_BytesValue:
3806 case kUpb_WellKnown_BoolValue:
3807 jsondec_wrapper(d, msg, m);
3808 break;
3809 default:
3810 UPB_UNREACHABLE();
3811 }
3812 }
3813
upb_JsonDecode(const char * buf,size_t size,upb_Message * msg,const upb_MessageDef * m,const upb_DefPool * symtab,int options,upb_Arena * arena,upb_Status * status)3814 bool upb_JsonDecode(const char* buf, size_t size, upb_Message* msg,
3815 const upb_MessageDef* m, const upb_DefPool* symtab,
3816 int options, upb_Arena* arena, upb_Status* status) {
3817 jsondec d;
3818
3819 if (size == 0) return true;
3820
3821 d.ptr = buf;
3822 d.end = buf + size;
3823 d.arena = arena;
3824 d.symtab = symtab;
3825 d.status = status;
3826 d.options = options;
3827 d.depth = 64;
3828 d.line = 1;
3829 d.line_begin = d.ptr;
3830 d.debug_field = NULL;
3831 d.is_first = false;
3832
3833 if (UPB_SETJMP(d.err)) return false;
3834
3835 jsondec_tomsg(&d, msg, m);
3836 return true;
3837 }
3838
3839 /** upb/json_encode.c ************************************************************/
3840
3841 #include <ctype.h>
3842 #include <float.h>
3843 #include <inttypes.h>
3844 #include <math.h>
3845 #include <setjmp.h>
3846 #include <stdarg.h>
3847 #include <stdio.h>
3848 #include <string.h>
3849
3850
3851 /* Must be last. */
3852
3853 typedef struct {
3854 char *buf, *ptr, *end;
3855 size_t overflow;
3856 int indent_depth;
3857 int options;
3858 const upb_DefPool* ext_pool;
3859 jmp_buf err;
3860 upb_Status* status;
3861 upb_Arena* arena;
3862 } jsonenc;
3863
3864 static void jsonenc_msg(jsonenc* e, const upb_Message* msg,
3865 const upb_MessageDef* m);
3866 static void jsonenc_scalar(jsonenc* e, upb_MessageValue val,
3867 const upb_FieldDef* f);
3868 static void jsonenc_msgfield(jsonenc* e, const upb_Message* msg,
3869 const upb_MessageDef* m);
3870 static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg,
3871 const upb_MessageDef* m, bool first);
3872 static void jsonenc_value(jsonenc* e, const upb_Message* msg,
3873 const upb_MessageDef* m);
3874
jsonenc_err(jsonenc * e,const char * msg)3875 UPB_NORETURN static void jsonenc_err(jsonenc* e, const char* msg) {
3876 upb_Status_SetErrorMessage(e->status, msg);
3877 longjmp(e->err, 1);
3878 }
3879
3880 UPB_PRINTF(2, 3)
jsonenc_errf(jsonenc * e,const char * fmt,...)3881 UPB_NORETURN static void jsonenc_errf(jsonenc* e, const char* fmt, ...) {
3882 va_list argp;
3883 va_start(argp, fmt);
3884 upb_Status_VSetErrorFormat(e->status, fmt, argp);
3885 va_end(argp);
3886 longjmp(e->err, 1);
3887 }
3888
jsonenc_arena(jsonenc * e)3889 static upb_Arena* jsonenc_arena(jsonenc* e) {
3890 /* Create lazily, since it's only needed for Any */
3891 if (!e->arena) {
3892 e->arena = upb_Arena_New();
3893 }
3894 return e->arena;
3895 }
3896
jsonenc_putbytes(jsonenc * e,const void * data,size_t len)3897 static void jsonenc_putbytes(jsonenc* e, const void* data, size_t len) {
3898 size_t have = e->end - e->ptr;
3899 if (UPB_LIKELY(have >= len)) {
3900 memcpy(e->ptr, data, len);
3901 e->ptr += len;
3902 } else {
3903 if (have) {
3904 memcpy(e->ptr, data, have);
3905 e->ptr += have;
3906 }
3907 e->overflow += (len - have);
3908 }
3909 }
3910
jsonenc_putstr(jsonenc * e,const char * str)3911 static void jsonenc_putstr(jsonenc* e, const char* str) {
3912 jsonenc_putbytes(e, str, strlen(str));
3913 }
3914
3915 UPB_PRINTF(2, 3)
jsonenc_printf(jsonenc * e,const char * fmt,...)3916 static void jsonenc_printf(jsonenc* e, const char* fmt, ...) {
3917 size_t n;
3918 size_t have = e->end - e->ptr;
3919 va_list args;
3920
3921 va_start(args, fmt);
3922 n = _upb_vsnprintf(e->ptr, have, fmt, args);
3923 va_end(args);
3924
3925 if (UPB_LIKELY(have > n)) {
3926 e->ptr += n;
3927 } else {
3928 e->ptr = UPB_PTRADD(e->ptr, have);
3929 e->overflow += (n - have);
3930 }
3931 }
3932
jsonenc_nanos(jsonenc * e,int32_t nanos)3933 static void jsonenc_nanos(jsonenc* e, int32_t nanos) {
3934 int digits = 9;
3935
3936 if (nanos == 0) return;
3937 if (nanos < 0 || nanos >= 1000000000) {
3938 jsonenc_err(e, "error formatting timestamp as JSON: invalid nanos");
3939 }
3940
3941 while (nanos % 1000 == 0) {
3942 nanos /= 1000;
3943 digits -= 3;
3944 }
3945
3946 jsonenc_printf(e, ".%.*" PRId32, digits, nanos);
3947 }
3948
jsonenc_timestamp(jsonenc * e,const upb_Message * msg,const upb_MessageDef * m)3949 static void jsonenc_timestamp(jsonenc* e, const upb_Message* msg,
3950 const upb_MessageDef* m) {
3951 const upb_FieldDef* seconds_f = upb_MessageDef_FindFieldByNumber(m, 1);
3952 const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(m, 2);
3953 int64_t seconds = upb_Message_Get(msg, seconds_f).int64_val;
3954 int32_t nanos = upb_Message_Get(msg, nanos_f).int32_val;
3955 int L, N, I, J, K, hour, min, sec;
3956
3957 if (seconds < -62135596800) {
3958 jsonenc_err(e,
3959 "error formatting timestamp as JSON: minimum acceptable value "
3960 "is 0001-01-01T00:00:00Z");
3961 } else if (seconds > 253402300799) {
3962 jsonenc_err(e,
3963 "error formatting timestamp as JSON: maximum acceptable value "
3964 "is 9999-12-31T23:59:59Z");
3965 }
3966
3967 /* Julian Day -> Y/M/D, Algorithm from:
3968 * Fliegel, H. F., and Van Flandern, T. C., "A Machine Algorithm for
3969 * Processing Calendar Dates," Communications of the Association of
3970 * Computing Machines, vol. 11 (1968), p. 657. */
3971 seconds += 62135596800; // Ensure seconds is positive.
3972 L = (int)(seconds / 86400) - 719162 + 68569 + 2440588;
3973 N = 4 * L / 146097;
3974 L = L - (146097 * N + 3) / 4;
3975 I = 4000 * (L + 1) / 1461001;
3976 L = L - 1461 * I / 4 + 31;
3977 J = 80 * L / 2447;
3978 K = L - 2447 * J / 80;
3979 L = J / 11;
3980 J = J + 2 - 12 * L;
3981 I = 100 * (N - 49) + I + L;
3982
3983 sec = seconds % 60;
3984 min = (seconds / 60) % 60;
3985 hour = (seconds / 3600) % 24;
3986
3987 jsonenc_printf(e, "\"%04d-%02d-%02dT%02d:%02d:%02d", I, J, K, hour, min, sec);
3988 jsonenc_nanos(e, nanos);
3989 jsonenc_putstr(e, "Z\"");
3990 }
3991
jsonenc_duration(jsonenc * e,const upb_Message * msg,const upb_MessageDef * m)3992 static void jsonenc_duration(jsonenc* e, const upb_Message* msg,
3993 const upb_MessageDef* m) {
3994 const upb_FieldDef* seconds_f = upb_MessageDef_FindFieldByNumber(m, 1);
3995 const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(m, 2);
3996 int64_t seconds = upb_Message_Get(msg, seconds_f).int64_val;
3997 int32_t nanos = upb_Message_Get(msg, nanos_f).int32_val;
3998
3999 if (seconds > 315576000000 || seconds < -315576000000 ||
4000 (seconds < 0) != (nanos < 0)) {
4001 jsonenc_err(e, "bad duration");
4002 }
4003
4004 if (nanos < 0) {
4005 nanos = -nanos;
4006 }
4007
4008 jsonenc_printf(e, "\"%" PRId64, seconds);
4009 jsonenc_nanos(e, nanos);
4010 jsonenc_putstr(e, "s\"");
4011 }
4012
jsonenc_enum(int32_t val,const upb_FieldDef * f,jsonenc * e)4013 static void jsonenc_enum(int32_t val, const upb_FieldDef* f, jsonenc* e) {
4014 const upb_EnumDef* e_def = upb_FieldDef_EnumSubDef(f);
4015
4016 if (strcmp(upb_EnumDef_FullName(e_def), "google.protobuf.NullValue") == 0) {
4017 jsonenc_putstr(e, "null");
4018 } else {
4019 const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(e_def, val);
4020
4021 if (ev) {
4022 jsonenc_printf(e, "\"%s\"", upb_EnumValueDef_Name(ev));
4023 } else {
4024 jsonenc_printf(e, "%" PRId32, val);
4025 }
4026 }
4027 }
4028
jsonenc_bytes(jsonenc * e,upb_StringView str)4029 static void jsonenc_bytes(jsonenc* e, upb_StringView str) {
4030 /* This is the regular base64, not the "web-safe" version. */
4031 static const char base64[] =
4032 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
4033 const unsigned char* ptr = (unsigned char*)str.data;
4034 const unsigned char* end = UPB_PTRADD(ptr, str.size);
4035 char buf[4];
4036
4037 jsonenc_putstr(e, "\"");
4038
4039 while (end - ptr >= 3) {
4040 buf[0] = base64[ptr[0] >> 2];
4041 buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)];
4042 buf[2] = base64[((ptr[1] & 0xf) << 2) | (ptr[2] >> 6)];
4043 buf[3] = base64[ptr[2] & 0x3f];
4044 jsonenc_putbytes(e, buf, 4);
4045 ptr += 3;
4046 }
4047
4048 switch (end - ptr) {
4049 case 2:
4050 buf[0] = base64[ptr[0] >> 2];
4051 buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)];
4052 buf[2] = base64[(ptr[1] & 0xf) << 2];
4053 buf[3] = '=';
4054 jsonenc_putbytes(e, buf, 4);
4055 break;
4056 case 1:
4057 buf[0] = base64[ptr[0] >> 2];
4058 buf[1] = base64[((ptr[0] & 0x3) << 4)];
4059 buf[2] = '=';
4060 buf[3] = '=';
4061 jsonenc_putbytes(e, buf, 4);
4062 break;
4063 }
4064
4065 jsonenc_putstr(e, "\"");
4066 }
4067
jsonenc_stringbody(jsonenc * e,upb_StringView str)4068 static void jsonenc_stringbody(jsonenc* e, upb_StringView str) {
4069 const char* ptr = str.data;
4070 const char* end = UPB_PTRADD(ptr, str.size);
4071
4072 while (ptr < end) {
4073 switch (*ptr) {
4074 case '\n':
4075 jsonenc_putstr(e, "\\n");
4076 break;
4077 case '\r':
4078 jsonenc_putstr(e, "\\r");
4079 break;
4080 case '\t':
4081 jsonenc_putstr(e, "\\t");
4082 break;
4083 case '\"':
4084 jsonenc_putstr(e, "\\\"");
4085 break;
4086 case '\f':
4087 jsonenc_putstr(e, "\\f");
4088 break;
4089 case '\b':
4090 jsonenc_putstr(e, "\\b");
4091 break;
4092 case '\\':
4093 jsonenc_putstr(e, "\\\\");
4094 break;
4095 default:
4096 if ((uint8_t)*ptr < 0x20) {
4097 jsonenc_printf(e, "\\u%04x", (int)(uint8_t)*ptr);
4098 } else {
4099 /* This could be a non-ASCII byte. We rely on the string being valid
4100 * UTF-8. */
4101 jsonenc_putbytes(e, ptr, 1);
4102 }
4103 break;
4104 }
4105 ptr++;
4106 }
4107 }
4108
jsonenc_string(jsonenc * e,upb_StringView str)4109 static void jsonenc_string(jsonenc* e, upb_StringView str) {
4110 jsonenc_putstr(e, "\"");
4111 jsonenc_stringbody(e, str);
4112 jsonenc_putstr(e, "\"");
4113 }
4114
upb_JsonEncode_HandleSpecialDoubles(jsonenc * e,double val)4115 static bool upb_JsonEncode_HandleSpecialDoubles(jsonenc* e, double val) {
4116 if (val == INFINITY) {
4117 jsonenc_putstr(e, "\"Infinity\"");
4118 } else if (val == -INFINITY) {
4119 jsonenc_putstr(e, "\"-Infinity\"");
4120 } else if (val != val) {
4121 jsonenc_putstr(e, "\"NaN\"");
4122 } else {
4123 return false;
4124 }
4125 return true;
4126 }
4127
upb_JsonEncode_Double(jsonenc * e,double val)4128 static void upb_JsonEncode_Double(jsonenc* e, double val) {
4129 if (upb_JsonEncode_HandleSpecialDoubles(e, val)) return;
4130 char buf[32];
4131 _upb_EncodeRoundTripDouble(val, buf, sizeof(buf));
4132 jsonenc_putstr(e, buf);
4133 }
4134
upb_JsonEncode_Float(jsonenc * e,float val)4135 static void upb_JsonEncode_Float(jsonenc* e, float val) {
4136 if (upb_JsonEncode_HandleSpecialDoubles(e, val)) return;
4137 char buf[32];
4138 _upb_EncodeRoundTripFloat(val, buf, sizeof(buf));
4139 jsonenc_putstr(e, buf);
4140 }
4141
jsonenc_wrapper(jsonenc * e,const upb_Message * msg,const upb_MessageDef * m)4142 static void jsonenc_wrapper(jsonenc* e, const upb_Message* msg,
4143 const upb_MessageDef* m) {
4144 const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(m, 1);
4145 upb_MessageValue val = upb_Message_Get(msg, val_f);
4146 jsonenc_scalar(e, val, val_f);
4147 }
4148
jsonenc_getanymsg(jsonenc * e,upb_StringView type_url)4149 static const upb_MessageDef* jsonenc_getanymsg(jsonenc* e,
4150 upb_StringView type_url) {
4151 /* Find last '/', if any. */
4152 const char* end = type_url.data + type_url.size;
4153 const char* ptr = end;
4154 const upb_MessageDef* ret;
4155
4156 if (!e->ext_pool) {
4157 jsonenc_err(e, "Tried to encode Any, but no symtab was provided");
4158 }
4159
4160 if (type_url.size == 0) goto badurl;
4161
4162 while (true) {
4163 if (--ptr == type_url.data) {
4164 /* Type URL must contain at least one '/', with host before. */
4165 goto badurl;
4166 }
4167 if (*ptr == '/') {
4168 ptr++;
4169 break;
4170 }
4171 }
4172
4173 ret = upb_DefPool_FindMessageByNameWithSize(e->ext_pool, ptr, end - ptr);
4174
4175 if (!ret) {
4176 jsonenc_errf(e, "Couldn't find Any type: %.*s", (int)(end - ptr), ptr);
4177 }
4178
4179 return ret;
4180
4181 badurl:
4182 jsonenc_errf(e, "Bad type URL: " UPB_STRINGVIEW_FORMAT,
4183 UPB_STRINGVIEW_ARGS(type_url));
4184 }
4185
jsonenc_any(jsonenc * e,const upb_Message * msg,const upb_MessageDef * m)4186 static void jsonenc_any(jsonenc* e, const upb_Message* msg,
4187 const upb_MessageDef* m) {
4188 const upb_FieldDef* type_url_f = upb_MessageDef_FindFieldByNumber(m, 1);
4189 const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(m, 2);
4190 upb_StringView type_url = upb_Message_Get(msg, type_url_f).str_val;
4191 upb_StringView value = upb_Message_Get(msg, value_f).str_val;
4192 const upb_MessageDef* any_m = jsonenc_getanymsg(e, type_url);
4193 const upb_MiniTable* any_layout = upb_MessageDef_MiniTable(any_m);
4194 upb_Arena* arena = jsonenc_arena(e);
4195 upb_Message* any = upb_Message_New(any_m, arena);
4196
4197 if (upb_Decode(value.data, value.size, any, any_layout, NULL, 0, arena) !=
4198 kUpb_DecodeStatus_Ok) {
4199 jsonenc_err(e, "Error decoding message in Any");
4200 }
4201
4202 jsonenc_putstr(e, "{\"@type\":");
4203 jsonenc_string(e, type_url);
4204
4205 if (upb_MessageDef_WellKnownType(any_m) == kUpb_WellKnown_Unspecified) {
4206 /* Regular messages: {"@type": "...","foo": 1, "bar": 2} */
4207 jsonenc_msgfields(e, any, any_m, false);
4208 } else {
4209 /* Well-known type: {"@type": "...","value": <well-known encoding>} */
4210 jsonenc_putstr(e, ",\"value\":");
4211 jsonenc_msgfield(e, any, any_m);
4212 }
4213
4214 jsonenc_putstr(e, "}");
4215 }
4216
jsonenc_putsep(jsonenc * e,const char * str,bool * first)4217 static void jsonenc_putsep(jsonenc* e, const char* str, bool* first) {
4218 if (*first) {
4219 *first = false;
4220 } else {
4221 jsonenc_putstr(e, str);
4222 }
4223 }
4224
jsonenc_fieldpath(jsonenc * e,upb_StringView path)4225 static void jsonenc_fieldpath(jsonenc* e, upb_StringView path) {
4226 const char* ptr = path.data;
4227 const char* end = ptr + path.size;
4228
4229 while (ptr < end) {
4230 char ch = *ptr;
4231
4232 if (ch >= 'A' && ch <= 'Z') {
4233 jsonenc_err(e, "Field mask element may not have upper-case letter.");
4234 } else if (ch == '_') {
4235 if (ptr == end - 1 || *(ptr + 1) < 'a' || *(ptr + 1) > 'z') {
4236 jsonenc_err(e, "Underscore must be followed by a lowercase letter.");
4237 }
4238 ch = *++ptr - 32;
4239 }
4240
4241 jsonenc_putbytes(e, &ch, 1);
4242 ptr++;
4243 }
4244 }
4245
jsonenc_fieldmask(jsonenc * e,const upb_Message * msg,const upb_MessageDef * m)4246 static void jsonenc_fieldmask(jsonenc* e, const upb_Message* msg,
4247 const upb_MessageDef* m) {
4248 const upb_FieldDef* paths_f = upb_MessageDef_FindFieldByNumber(m, 1);
4249 const upb_Array* paths = upb_Message_Get(msg, paths_f).array_val;
4250 bool first = true;
4251 size_t i, n = 0;
4252
4253 if (paths) n = upb_Array_Size(paths);
4254
4255 jsonenc_putstr(e, "\"");
4256
4257 for (i = 0; i < n; i++) {
4258 jsonenc_putsep(e, ",", &first);
4259 jsonenc_fieldpath(e, upb_Array_Get(paths, i).str_val);
4260 }
4261
4262 jsonenc_putstr(e, "\"");
4263 }
4264
jsonenc_struct(jsonenc * e,const upb_Message * msg,const upb_MessageDef * m)4265 static void jsonenc_struct(jsonenc* e, const upb_Message* msg,
4266 const upb_MessageDef* m) {
4267 const upb_FieldDef* fields_f = upb_MessageDef_FindFieldByNumber(m, 1);
4268 const upb_Map* fields = upb_Message_Get(msg, fields_f).map_val;
4269 const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(fields_f);
4270 const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(entry_m, 2);
4271 size_t iter = kUpb_Map_Begin;
4272 bool first = true;
4273
4274 jsonenc_putstr(e, "{");
4275
4276 if (fields) {
4277 while (upb_MapIterator_Next(fields, &iter)) {
4278 upb_MessageValue key = upb_MapIterator_Key(fields, iter);
4279 upb_MessageValue val = upb_MapIterator_Value(fields, iter);
4280
4281 jsonenc_putsep(e, ",", &first);
4282 jsonenc_string(e, key.str_val);
4283 jsonenc_putstr(e, ":");
4284 jsonenc_value(e, val.msg_val, upb_FieldDef_MessageSubDef(value_f));
4285 }
4286 }
4287
4288 jsonenc_putstr(e, "}");
4289 }
4290
jsonenc_listvalue(jsonenc * e,const upb_Message * msg,const upb_MessageDef * m)4291 static void jsonenc_listvalue(jsonenc* e, const upb_Message* msg,
4292 const upb_MessageDef* m) {
4293 const upb_FieldDef* values_f = upb_MessageDef_FindFieldByNumber(m, 1);
4294 const upb_MessageDef* values_m = upb_FieldDef_MessageSubDef(values_f);
4295 const upb_Array* values = upb_Message_Get(msg, values_f).array_val;
4296 size_t i;
4297 bool first = true;
4298
4299 jsonenc_putstr(e, "[");
4300
4301 if (values) {
4302 const size_t size = upb_Array_Size(values);
4303 for (i = 0; i < size; i++) {
4304 upb_MessageValue elem = upb_Array_Get(values, i);
4305
4306 jsonenc_putsep(e, ",", &first);
4307 jsonenc_value(e, elem.msg_val, values_m);
4308 }
4309 }
4310
4311 jsonenc_putstr(e, "]");
4312 }
4313
jsonenc_value(jsonenc * e,const upb_Message * msg,const upb_MessageDef * m)4314 static void jsonenc_value(jsonenc* e, const upb_Message* msg,
4315 const upb_MessageDef* m) {
4316 /* TODO(haberman): do we want a reflection method to get oneof case? */
4317 size_t iter = kUpb_Message_Begin;
4318 const upb_FieldDef* f;
4319 upb_MessageValue val;
4320
4321 if (!upb_Message_Next(msg, m, NULL, &f, &val, &iter)) {
4322 jsonenc_err(e, "No value set in Value proto");
4323 }
4324
4325 switch (upb_FieldDef_Number(f)) {
4326 case 1:
4327 jsonenc_putstr(e, "null");
4328 break;
4329 case 2:
4330 upb_JsonEncode_Double(e, val.double_val);
4331 break;
4332 case 3:
4333 jsonenc_string(e, val.str_val);
4334 break;
4335 case 4:
4336 jsonenc_putstr(e, val.bool_val ? "true" : "false");
4337 break;
4338 case 5:
4339 jsonenc_struct(e, val.msg_val, upb_FieldDef_MessageSubDef(f));
4340 break;
4341 case 6:
4342 jsonenc_listvalue(e, val.msg_val, upb_FieldDef_MessageSubDef(f));
4343 break;
4344 }
4345 }
4346
jsonenc_msgfield(jsonenc * e,const upb_Message * msg,const upb_MessageDef * m)4347 static void jsonenc_msgfield(jsonenc* e, const upb_Message* msg,
4348 const upb_MessageDef* m) {
4349 switch (upb_MessageDef_WellKnownType(m)) {
4350 case kUpb_WellKnown_Unspecified:
4351 jsonenc_msg(e, msg, m);
4352 break;
4353 case kUpb_WellKnown_Any:
4354 jsonenc_any(e, msg, m);
4355 break;
4356 case kUpb_WellKnown_FieldMask:
4357 jsonenc_fieldmask(e, msg, m);
4358 break;
4359 case kUpb_WellKnown_Duration:
4360 jsonenc_duration(e, msg, m);
4361 break;
4362 case kUpb_WellKnown_Timestamp:
4363 jsonenc_timestamp(e, msg, m);
4364 break;
4365 case kUpb_WellKnown_DoubleValue:
4366 case kUpb_WellKnown_FloatValue:
4367 case kUpb_WellKnown_Int64Value:
4368 case kUpb_WellKnown_UInt64Value:
4369 case kUpb_WellKnown_Int32Value:
4370 case kUpb_WellKnown_UInt32Value:
4371 case kUpb_WellKnown_StringValue:
4372 case kUpb_WellKnown_BytesValue:
4373 case kUpb_WellKnown_BoolValue:
4374 jsonenc_wrapper(e, msg, m);
4375 break;
4376 case kUpb_WellKnown_Value:
4377 jsonenc_value(e, msg, m);
4378 break;
4379 case kUpb_WellKnown_ListValue:
4380 jsonenc_listvalue(e, msg, m);
4381 break;
4382 case kUpb_WellKnown_Struct:
4383 jsonenc_struct(e, msg, m);
4384 break;
4385 }
4386 }
4387
jsonenc_scalar(jsonenc * e,upb_MessageValue val,const upb_FieldDef * f)4388 static void jsonenc_scalar(jsonenc* e, upb_MessageValue val,
4389 const upb_FieldDef* f) {
4390 switch (upb_FieldDef_CType(f)) {
4391 case kUpb_CType_Bool:
4392 jsonenc_putstr(e, val.bool_val ? "true" : "false");
4393 break;
4394 case kUpb_CType_Float:
4395 upb_JsonEncode_Float(e, val.float_val);
4396 break;
4397 case kUpb_CType_Double:
4398 upb_JsonEncode_Double(e, val.double_val);
4399 break;
4400 case kUpb_CType_Int32:
4401 jsonenc_printf(e, "%" PRId32, val.int32_val);
4402 break;
4403 case kUpb_CType_UInt32:
4404 jsonenc_printf(e, "%" PRIu32, val.uint32_val);
4405 break;
4406 case kUpb_CType_Int64:
4407 jsonenc_printf(e, "\"%" PRId64 "\"", val.int64_val);
4408 break;
4409 case kUpb_CType_UInt64:
4410 jsonenc_printf(e, "\"%" PRIu64 "\"", val.uint64_val);
4411 break;
4412 case kUpb_CType_String:
4413 jsonenc_string(e, val.str_val);
4414 break;
4415 case kUpb_CType_Bytes:
4416 jsonenc_bytes(e, val.str_val);
4417 break;
4418 case kUpb_CType_Enum:
4419 jsonenc_enum(val.int32_val, f, e);
4420 break;
4421 case kUpb_CType_Message:
4422 jsonenc_msgfield(e, val.msg_val, upb_FieldDef_MessageSubDef(f));
4423 break;
4424 }
4425 }
4426
jsonenc_mapkey(jsonenc * e,upb_MessageValue val,const upb_FieldDef * f)4427 static void jsonenc_mapkey(jsonenc* e, upb_MessageValue val,
4428 const upb_FieldDef* f) {
4429 jsonenc_putstr(e, "\"");
4430
4431 switch (upb_FieldDef_CType(f)) {
4432 case kUpb_CType_Bool:
4433 jsonenc_putstr(e, val.bool_val ? "true" : "false");
4434 break;
4435 case kUpb_CType_Int32:
4436 jsonenc_printf(e, "%" PRId32, val.int32_val);
4437 break;
4438 case kUpb_CType_UInt32:
4439 jsonenc_printf(e, "%" PRIu32, val.uint32_val);
4440 break;
4441 case kUpb_CType_Int64:
4442 jsonenc_printf(e, "%" PRId64, val.int64_val);
4443 break;
4444 case kUpb_CType_UInt64:
4445 jsonenc_printf(e, "%" PRIu64, val.uint64_val);
4446 break;
4447 case kUpb_CType_String:
4448 jsonenc_stringbody(e, val.str_val);
4449 break;
4450 default:
4451 UPB_UNREACHABLE();
4452 }
4453
4454 jsonenc_putstr(e, "\":");
4455 }
4456
jsonenc_array(jsonenc * e,const upb_Array * arr,const upb_FieldDef * f)4457 static void jsonenc_array(jsonenc* e, const upb_Array* arr,
4458 const upb_FieldDef* f) {
4459 size_t i;
4460 size_t size = arr ? upb_Array_Size(arr) : 0;
4461 bool first = true;
4462
4463 jsonenc_putstr(e, "[");
4464
4465 for (i = 0; i < size; i++) {
4466 jsonenc_putsep(e, ",", &first);
4467 jsonenc_scalar(e, upb_Array_Get(arr, i), f);
4468 }
4469
4470 jsonenc_putstr(e, "]");
4471 }
4472
jsonenc_map(jsonenc * e,const upb_Map * map,const upb_FieldDef * f)4473 static void jsonenc_map(jsonenc* e, const upb_Map* map, const upb_FieldDef* f) {
4474 const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f);
4475 const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry, 1);
4476 const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry, 2);
4477 size_t iter = kUpb_Map_Begin;
4478 bool first = true;
4479
4480 jsonenc_putstr(e, "{");
4481
4482 if (map) {
4483 while (upb_MapIterator_Next(map, &iter)) {
4484 jsonenc_putsep(e, ",", &first);
4485 jsonenc_mapkey(e, upb_MapIterator_Key(map, iter), key_f);
4486 jsonenc_scalar(e, upb_MapIterator_Value(map, iter), val_f);
4487 }
4488 }
4489
4490 jsonenc_putstr(e, "}");
4491 }
4492
jsonenc_fieldval(jsonenc * e,const upb_FieldDef * f,upb_MessageValue val,bool * first)4493 static void jsonenc_fieldval(jsonenc* e, const upb_FieldDef* f,
4494 upb_MessageValue val, bool* first) {
4495 const char* name;
4496
4497 jsonenc_putsep(e, ",", first);
4498
4499 if (upb_FieldDef_IsExtension(f)) {
4500 // TODO: For MessageSet, I would have expected this to print the message
4501 // name here, but Python doesn't appear to do this. We should do more
4502 // research here about what various implementations do.
4503 jsonenc_printf(e, "\"[%s]\":", upb_FieldDef_FullName(f));
4504 } else {
4505 if (e->options & upb_JsonEncode_UseProtoNames) {
4506 name = upb_FieldDef_Name(f);
4507 } else {
4508 name = upb_FieldDef_JsonName(f);
4509 }
4510 jsonenc_printf(e, "\"%s\":", name);
4511 }
4512
4513 if (upb_FieldDef_IsMap(f)) {
4514 jsonenc_map(e, val.map_val, f);
4515 } else if (upb_FieldDef_IsRepeated(f)) {
4516 jsonenc_array(e, val.array_val, f);
4517 } else {
4518 jsonenc_scalar(e, val, f);
4519 }
4520 }
4521
jsonenc_msgfields(jsonenc * e,const upb_Message * msg,const upb_MessageDef * m,bool first)4522 static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg,
4523 const upb_MessageDef* m, bool first) {
4524 upb_MessageValue val;
4525 const upb_FieldDef* f;
4526
4527 if (e->options & upb_JsonEncode_EmitDefaults) {
4528 /* Iterate over all fields. */
4529 int i = 0;
4530 int n = upb_MessageDef_FieldCount(m);
4531 for (i = 0; i < n; i++) {
4532 f = upb_MessageDef_Field(m, i);
4533 if (!upb_FieldDef_HasPresence(f) || upb_Message_Has(msg, f)) {
4534 jsonenc_fieldval(e, f, upb_Message_Get(msg, f), &first);
4535 }
4536 }
4537 } else {
4538 /* Iterate over non-empty fields. */
4539 size_t iter = kUpb_Message_Begin;
4540 while (upb_Message_Next(msg, m, e->ext_pool, &f, &val, &iter)) {
4541 jsonenc_fieldval(e, f, val, &first);
4542 }
4543 }
4544 }
4545
jsonenc_msg(jsonenc * e,const upb_Message * msg,const upb_MessageDef * m)4546 static void jsonenc_msg(jsonenc* e, const upb_Message* msg,
4547 const upb_MessageDef* m) {
4548 jsonenc_putstr(e, "{");
4549 jsonenc_msgfields(e, msg, m, true);
4550 jsonenc_putstr(e, "}");
4551 }
4552
jsonenc_nullz(jsonenc * e,size_t size)4553 static size_t jsonenc_nullz(jsonenc* e, size_t size) {
4554 size_t ret = e->ptr - e->buf + e->overflow;
4555
4556 if (size > 0) {
4557 if (e->ptr == e->end) e->ptr--;
4558 *e->ptr = '\0';
4559 }
4560
4561 return ret;
4562 }
4563
upb_JsonEncode(const upb_Message * msg,const upb_MessageDef * m,const upb_DefPool * ext_pool,int options,char * buf,size_t size,upb_Status * status)4564 size_t upb_JsonEncode(const upb_Message* msg, const upb_MessageDef* m,
4565 const upb_DefPool* ext_pool, int options, char* buf,
4566 size_t size, upb_Status* status) {
4567 jsonenc e;
4568
4569 e.buf = buf;
4570 e.ptr = buf;
4571 e.end = UPB_PTRADD(buf, size);
4572 e.overflow = 0;
4573 e.options = options;
4574 e.ext_pool = ext_pool;
4575 e.status = status;
4576 e.arena = NULL;
4577
4578 if (setjmp(e.err)) return -1;
4579
4580 jsonenc_msgfield(&e, msg, m);
4581 if (e.arena) upb_Arena_Free(e.arena);
4582 return jsonenc_nullz(&e, size);
4583 }
4584
4585 /** upb/mini_table.c ************************************************************/
4586
4587 #include <inttypes.h>
4588 #include <setjmp.h>
4589
4590
4591 // Must be last.
4592
4593 typedef enum {
4594 kUpb_EncodedType_Double = 0,
4595 kUpb_EncodedType_Float = 1,
4596 kUpb_EncodedType_Fixed32 = 2,
4597 kUpb_EncodedType_Fixed64 = 3,
4598 kUpb_EncodedType_SFixed32 = 4,
4599 kUpb_EncodedType_SFixed64 = 5,
4600 kUpb_EncodedType_Int32 = 6,
4601 kUpb_EncodedType_UInt32 = 7,
4602 kUpb_EncodedType_SInt32 = 8,
4603 kUpb_EncodedType_Int64 = 9,
4604 kUpb_EncodedType_UInt64 = 10,
4605 kUpb_EncodedType_SInt64 = 11,
4606 kUpb_EncodedType_Enum = 12,
4607 kUpb_EncodedType_Bool = 13,
4608 kUpb_EncodedType_Bytes = 14,
4609 kUpb_EncodedType_String = 15,
4610 kUpb_EncodedType_Group = 16,
4611 kUpb_EncodedType_Message = 17,
4612
4613 kUpb_EncodedType_RepeatedBase = 20,
4614 } upb_EncodedType;
4615
4616 typedef enum {
4617 kUpb_EncodedFieldModifier_FlipPacked = 1 << 0,
4618 kUpb_EncodedFieldModifier_IsClosedEnum = 1 << 1,
4619 // upb only.
4620 kUpb_EncodedFieldModifier_IsProto3Singular = 1 << 2,
4621 kUpb_EncodedFieldModifier_IsRequired = 1 << 3,
4622 } upb_EncodedFieldModifier;
4623
4624 enum {
4625 kUpb_EncodedValue_MinField = ' ',
4626 kUpb_EncodedValue_MaxField = 'K',
4627 kUpb_EncodedValue_MinModifier = 'L',
4628 kUpb_EncodedValue_MaxModifier = '[',
4629 kUpb_EncodedValue_End = '^',
4630 kUpb_EncodedValue_MinSkip = '_',
4631 kUpb_EncodedValue_MaxSkip = '~',
4632 kUpb_EncodedValue_OneofSeparator = '~',
4633 kUpb_EncodedValue_FieldSeparator = '|',
4634 kUpb_EncodedValue_MinOneofField = ' ',
4635 kUpb_EncodedValue_MaxOneofField = 'b',
4636 kUpb_EncodedValue_MaxEnumMask = 'A',
4637 };
4638
upb_ToBase92(int8_t ch)4639 char upb_ToBase92(int8_t ch) {
4640 static const char kUpb_ToBase92[] = {
4641 ' ', '!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/',
4642 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
4643 '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
4644 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
4645 'Z', '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
4646 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
4647 'w', 'x', 'y', 'z', '{', '|', '}', '~',
4648 };
4649
4650 UPB_ASSERT(0 <= ch && ch < 92);
4651 return kUpb_ToBase92[ch];
4652 }
4653
upb_FromBase92(uint8_t ch)4654 char upb_FromBase92(uint8_t ch) {
4655 static const int8_t kUpb_FromBase92[] = {
4656 0, 1, -1, 2, 3, 4, 5, -1, 6, 7, 8, 9, 10, 11, 12, 13,
4657 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
4658 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
4659 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, 58, 59, 60,
4660 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
4661 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
4662 };
4663
4664 if (' ' > ch || ch > '~') return -1;
4665 return kUpb_FromBase92[ch - ' '];
4666 }
4667
upb_IsTypePackable(upb_FieldType type)4668 bool upb_IsTypePackable(upb_FieldType type) {
4669 // clang-format off
4670 static const unsigned kUnpackableTypes =
4671 (1 << kUpb_FieldType_String) |
4672 (1 << kUpb_FieldType_Bytes) |
4673 (1 << kUpb_FieldType_Message) |
4674 (1 << kUpb_FieldType_Group);
4675 // clang-format on
4676 return (1 << type) & ~kUnpackableTypes;
4677 }
4678
4679 /** upb_MtDataEncoder *********************************************************/
4680
4681 typedef struct {
4682 uint64_t present_values_mask;
4683 uint32_t last_written_value;
4684 } upb_MtDataEncoderInternal_EnumState;
4685
4686 typedef struct {
4687 uint64_t msg_modifiers;
4688 uint32_t last_field_num;
4689 enum {
4690 kUpb_OneofState_NotStarted,
4691 kUpb_OneofState_StartedOneof,
4692 kUpb_OneofState_EmittedOneofField,
4693 } oneof_state;
4694 } upb_MtDataEncoderInternal_MsgState;
4695
4696 typedef struct {
4697 char* buf_start; // Only for checking kUpb_MtDataEncoder_MinSize.
4698 union {
4699 upb_MtDataEncoderInternal_EnumState enum_state;
4700 upb_MtDataEncoderInternal_MsgState msg_state;
4701 } state;
4702 } upb_MtDataEncoderInternal;
4703
upb_MtDataEncoder_GetInternal(upb_MtDataEncoder * e,char * buf_start)4704 static upb_MtDataEncoderInternal* upb_MtDataEncoder_GetInternal(
4705 upb_MtDataEncoder* e, char* buf_start) {
4706 UPB_ASSERT(sizeof(upb_MtDataEncoderInternal) <= sizeof(e->internal));
4707 upb_MtDataEncoderInternal* ret = (upb_MtDataEncoderInternal*)e->internal;
4708 ret->buf_start = buf_start;
4709 return ret;
4710 }
4711
upb_MtDataEncoder_Put(upb_MtDataEncoder * e,char * ptr,char ch)4712 static char* upb_MtDataEncoder_Put(upb_MtDataEncoder* e, char* ptr, char ch) {
4713 upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
4714 UPB_ASSERT(ptr - in->buf_start < kUpb_MtDataEncoder_MinSize);
4715 if (ptr == e->end) return NULL;
4716 *ptr++ = upb_ToBase92(ch);
4717 return ptr;
4718 }
4719
upb_MtDataEncoder_PutBase92Varint(upb_MtDataEncoder * e,char * ptr,uint32_t val,int min,int max)4720 static char* upb_MtDataEncoder_PutBase92Varint(upb_MtDataEncoder* e, char* ptr,
4721 uint32_t val, int min, int max) {
4722 int shift = _upb_Log2Ceiling(upb_FromBase92(max) - upb_FromBase92(min) + 1);
4723 UPB_ASSERT(shift <= 6);
4724 uint32_t mask = (1 << shift) - 1;
4725 do {
4726 uint32_t bits = val & mask;
4727 ptr = upb_MtDataEncoder_Put(e, ptr, bits + upb_FromBase92(min));
4728 if (!ptr) return NULL;
4729 val >>= shift;
4730 } while (val);
4731 return ptr;
4732 }
4733
upb_MtDataEncoder_PutModifier(upb_MtDataEncoder * e,char * ptr,uint64_t mod)4734 char* upb_MtDataEncoder_PutModifier(upb_MtDataEncoder* e, char* ptr,
4735 uint64_t mod) {
4736 if (mod) {
4737 ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, mod,
4738 kUpb_EncodedValue_MinModifier,
4739 kUpb_EncodedValue_MaxModifier);
4740 }
4741 return ptr;
4742 }
4743
upb_MtDataEncoder_StartMessage(upb_MtDataEncoder * e,char * ptr,uint64_t msg_mod)4744 char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr,
4745 uint64_t msg_mod) {
4746 upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
4747 in->state.msg_state.msg_modifiers = msg_mod;
4748 in->state.msg_state.last_field_num = 0;
4749 in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
4750 return upb_MtDataEncoder_PutModifier(e, ptr, msg_mod);
4751 }
4752
upb_MtDataEncoder_PutField(upb_MtDataEncoder * e,char * ptr,upb_FieldType type,uint32_t field_num,uint64_t field_mod)4753 char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
4754 upb_FieldType type, uint32_t field_num,
4755 uint64_t field_mod) {
4756 static const char kUpb_TypeToEncoded[] = {
4757 [kUpb_FieldType_Double] = kUpb_EncodedType_Double,
4758 [kUpb_FieldType_Float] = kUpb_EncodedType_Float,
4759 [kUpb_FieldType_Int64] = kUpb_EncodedType_Int64,
4760 [kUpb_FieldType_UInt64] = kUpb_EncodedType_UInt64,
4761 [kUpb_FieldType_Int32] = kUpb_EncodedType_Int32,
4762 [kUpb_FieldType_Fixed64] = kUpb_EncodedType_Fixed64,
4763 [kUpb_FieldType_Fixed32] = kUpb_EncodedType_Fixed32,
4764 [kUpb_FieldType_Bool] = kUpb_EncodedType_Bool,
4765 [kUpb_FieldType_String] = kUpb_EncodedType_String,
4766 [kUpb_FieldType_Group] = kUpb_EncodedType_Group,
4767 [kUpb_FieldType_Message] = kUpb_EncodedType_Message,
4768 [kUpb_FieldType_Bytes] = kUpb_EncodedType_Bytes,
4769 [kUpb_FieldType_UInt32] = kUpb_EncodedType_UInt32,
4770 [kUpb_FieldType_Enum] = kUpb_EncodedType_Enum,
4771 [kUpb_FieldType_SFixed32] = kUpb_EncodedType_SFixed32,
4772 [kUpb_FieldType_SFixed64] = kUpb_EncodedType_SFixed64,
4773 [kUpb_FieldType_SInt32] = kUpb_EncodedType_SInt32,
4774 [kUpb_FieldType_SInt64] = kUpb_EncodedType_SInt64,
4775 };
4776
4777 upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
4778 if (field_num <= in->state.msg_state.last_field_num) return NULL;
4779 if (in->state.msg_state.last_field_num + 1 != field_num) {
4780 // Put skip.
4781 UPB_ASSERT(field_num > in->state.msg_state.last_field_num);
4782 uint32_t skip = field_num - in->state.msg_state.last_field_num;
4783 ptr = upb_MtDataEncoder_PutBase92Varint(
4784 e, ptr, skip, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
4785 if (!ptr) return NULL;
4786 }
4787 in->state.msg_state.last_field_num = field_num;
4788
4789 uint32_t encoded_modifiers = 0;
4790
4791 // Put field type.
4792 if (type == kUpb_FieldType_Enum &&
4793 !(field_mod & kUpb_FieldModifier_IsClosedEnum)) {
4794 type = kUpb_FieldType_Int32;
4795 }
4796
4797 int encoded_type = kUpb_TypeToEncoded[type];
4798 if (field_mod & kUpb_FieldModifier_IsRepeated) {
4799 // Repeated fields shift the type number up (unlike other modifiers which
4800 // are bit flags).
4801 encoded_type += kUpb_EncodedType_RepeatedBase;
4802
4803 if (upb_IsTypePackable(type)) {
4804 bool field_is_packed = field_mod & kUpb_FieldModifier_IsPacked;
4805 bool default_is_packed = in->state.msg_state.msg_modifiers &
4806 kUpb_MessageModifier_DefaultIsPacked;
4807 if (field_is_packed != default_is_packed) {
4808 encoded_modifiers |= kUpb_EncodedFieldModifier_FlipPacked;
4809 }
4810 }
4811 }
4812 ptr = upb_MtDataEncoder_Put(e, ptr, encoded_type);
4813 if (!ptr) return NULL;
4814
4815 if (field_mod & kUpb_FieldModifier_IsProto3Singular) {
4816 encoded_modifiers |= kUpb_EncodedFieldModifier_IsProto3Singular;
4817 }
4818 if (field_mod & kUpb_FieldModifier_IsRequired) {
4819 encoded_modifiers |= kUpb_EncodedFieldModifier_IsRequired;
4820 }
4821 return upb_MtDataEncoder_PutModifier(e, ptr, encoded_modifiers);
4822 }
4823
upb_MtDataEncoder_StartOneof(upb_MtDataEncoder * e,char * ptr)4824 char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr) {
4825 upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
4826 if (in->state.msg_state.oneof_state == kUpb_OneofState_NotStarted) {
4827 ptr = upb_MtDataEncoder_Put(e, ptr, upb_FromBase92(kUpb_EncodedValue_End));
4828 } else {
4829 ptr = upb_MtDataEncoder_Put(
4830 e, ptr, upb_FromBase92(kUpb_EncodedValue_OneofSeparator));
4831 }
4832 in->state.msg_state.oneof_state = kUpb_OneofState_StartedOneof;
4833 return ptr;
4834 }
4835
upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder * e,char * ptr,uint32_t field_num)4836 char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
4837 uint32_t field_num) {
4838 upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
4839 if (in->state.msg_state.oneof_state == kUpb_OneofState_EmittedOneofField) {
4840 ptr = upb_MtDataEncoder_Put(
4841 e, ptr, upb_FromBase92(kUpb_EncodedValue_FieldSeparator));
4842 if (!ptr) return NULL;
4843 }
4844 ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, field_num, upb_ToBase92(0),
4845 upb_ToBase92(63));
4846 in->state.msg_state.oneof_state = kUpb_OneofState_EmittedOneofField;
4847 return ptr;
4848 }
4849
upb_MtDataEncoder_StartEnum(upb_MtDataEncoder * e)4850 void upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e) {
4851 upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, NULL);
4852 in->state.enum_state.present_values_mask = 0;
4853 in->state.enum_state.last_written_value = 0;
4854 }
4855
upb_MtDataEncoder_FlushDenseEnumMask(upb_MtDataEncoder * e,char * ptr)4856 static char* upb_MtDataEncoder_FlushDenseEnumMask(upb_MtDataEncoder* e,
4857 char* ptr) {
4858 upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
4859 ptr = upb_MtDataEncoder_Put(e, ptr, in->state.enum_state.present_values_mask);
4860 in->state.enum_state.present_values_mask = 0;
4861 in->state.enum_state.last_written_value += 5;
4862 return ptr;
4863 }
4864
upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder * e,char * ptr,uint32_t val)4865 char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
4866 uint32_t val) {
4867 // TODO(b/229641772): optimize this encoding.
4868 upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
4869 UPB_ASSERT(val >= in->state.enum_state.last_written_value);
4870 uint32_t delta = val - in->state.enum_state.last_written_value;
4871 if (delta >= 5 && in->state.enum_state.present_values_mask) {
4872 ptr = upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
4873 delta -= 5;
4874 }
4875
4876 if (delta >= 5) {
4877 ptr = upb_MtDataEncoder_PutBase92Varint(
4878 e, ptr, delta, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
4879 in->state.enum_state.last_written_value += delta;
4880 delta = 0;
4881 }
4882
4883 UPB_ASSERT((in->state.enum_state.present_values_mask >> delta) == 0);
4884 in->state.enum_state.present_values_mask |= 1ULL << delta;
4885 return ptr;
4886 }
4887
upb_MtDataEncoder_EndEnum(upb_MtDataEncoder * e,char * ptr)4888 char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) {
4889 upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
4890 if (!in->state.enum_state.present_values_mask) return ptr;
4891 return upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
4892 }
4893
upb_MiniTable_FindFieldByNumber(const upb_MiniTable * table,uint32_t number)4894 const upb_MiniTable_Field* upb_MiniTable_FindFieldByNumber(
4895 const upb_MiniTable* table, uint32_t number) {
4896 int n = table->field_count;
4897 for (int i = 0; i < n; i++) {
4898 if (table->fields[i].number == number) {
4899 return &table->fields[i];
4900 }
4901 }
4902 return NULL;
4903 }
4904
4905 /** Data decoder **************************************************************/
4906
4907 // Note: we sort by this number when calculating layout order.
4908 typedef enum {
4909 kUpb_LayoutItemType_OneofCase, // Oneof case.
4910 kUpb_LayoutItemType_OneofField, // Oneof field data.
4911 kUpb_LayoutItemType_Field, // Non-oneof field data.
4912
4913 kUpb_LayoutItemType_Max = kUpb_LayoutItemType_Field,
4914 } upb_LayoutItemType;
4915
4916 #define kUpb_LayoutItem_IndexSentinel ((uint16_t)-1)
4917
4918 typedef struct {
4919 // Index of the corresponding field. When this is a oneof field, the field's
4920 // offset will be the index of the next field in a linked list.
4921 uint16_t field_index;
4922 uint16_t offset;
4923 upb_FieldRep rep;
4924 upb_LayoutItemType type;
4925 } upb_LayoutItem;
4926
4927 typedef struct {
4928 upb_LayoutItem* data;
4929 size_t size;
4930 size_t capacity;
4931 } upb_LayoutItemVector;
4932
4933 typedef struct {
4934 const char* end;
4935 upb_MiniTable* table;
4936 upb_MiniTable_Field* fields;
4937 upb_MiniTablePlatform platform;
4938 upb_LayoutItemVector vec;
4939 upb_Arena* arena;
4940 upb_Status* status;
4941 jmp_buf err;
4942 } upb_MtDecoder;
4943
4944 UPB_PRINTF(2, 3)
upb_MtDecoder_ErrorFormat(upb_MtDecoder * d,const char * fmt,...)4945 UPB_NORETURN static void upb_MtDecoder_ErrorFormat(upb_MtDecoder* d,
4946 const char* fmt, ...) {
4947 va_list argp;
4948 upb_Status_SetErrorMessage(d->status, "Error building mini table: ");
4949 va_start(argp, fmt);
4950 upb_Status_VAppendErrorFormat(d->status, fmt, argp);
4951 va_end(argp);
4952 UPB_LONGJMP(d->err, 1);
4953 }
4954
upb_MtDecoder_CheckOutOfMemory(upb_MtDecoder * d,const void * ptr)4955 static void upb_MtDecoder_CheckOutOfMemory(upb_MtDecoder* d, const void* ptr) {
4956 if (!ptr) upb_MtDecoder_ErrorFormat(d, "Out of memory");
4957 }
4958
4959 // In each field's offset, we temporarily store a presence classifier:
4960 enum PresenceClass {
4961 kNoPresence = 0,
4962 kHasbitPresence = 1,
4963 kRequiredPresence = 2,
4964 kOneofBase = 3,
4965 // Negative values refer to a specific oneof with that number. Positive
4966 // values >= kOneofBase indicate that this field is in a oneof, and specify
4967 // the next field in this oneof's linked list.
4968 };
4969
upb_MiniTable_DecodeBase92Varint(upb_MtDecoder * d,const char * ptr,char first_ch,uint8_t min,uint8_t max,uint32_t * out_val)4970 static const char* upb_MiniTable_DecodeBase92Varint(upb_MtDecoder* d,
4971 const char* ptr,
4972 char first_ch, uint8_t min,
4973 uint8_t max,
4974 uint32_t* out_val) {
4975 uint32_t val = 0;
4976 uint32_t shift = 0;
4977 const int bits_per_char =
4978 _upb_Log2Ceiling(upb_FromBase92(max) - upb_FromBase92(min));
4979 char ch = first_ch;
4980 while (1) {
4981 uint32_t bits = upb_FromBase92(ch) - upb_FromBase92(min);
4982 UPB_ASSERT(shift < 32);
4983 val |= bits << shift;
4984 if (ptr == d->end || *ptr < min || max < *ptr) {
4985 *out_val = val;
4986 return ptr;
4987 }
4988 ch = *ptr++;
4989 shift += bits_per_char;
4990 }
4991 }
4992
upb_MiniTable_HasSub(upb_MiniTable_Field * field,uint64_t msg_modifiers)4993 static bool upb_MiniTable_HasSub(upb_MiniTable_Field* field,
4994 uint64_t msg_modifiers) {
4995 switch (field->descriptortype) {
4996 case kUpb_FieldType_Message:
4997 case kUpb_FieldType_Group:
4998 case kUpb_FieldType_Enum:
4999 return true;
5000 case kUpb_FieldType_String:
5001 if (!(msg_modifiers & kUpb_MessageModifier_ValidateUtf8)) {
5002 field->descriptortype = kUpb_FieldType_Bytes;
5003 }
5004 return false;
5005 default:
5006 return false;
5007 }
5008 }
5009
upb_MtDecoder_FieldIsPackable(upb_MiniTable_Field * field)5010 static bool upb_MtDecoder_FieldIsPackable(upb_MiniTable_Field* field) {
5011 return (field->mode & kUpb_FieldMode_Array) &&
5012 upb_IsTypePackable(field->descriptortype);
5013 }
5014
upb_MiniTable_SetTypeAndSub(upb_MiniTable_Field * field,upb_FieldType type,uint32_t * sub_count,uint64_t msg_modifiers)5015 static void upb_MiniTable_SetTypeAndSub(upb_MiniTable_Field* field,
5016 upb_FieldType type, uint32_t* sub_count,
5017 uint64_t msg_modifiers) {
5018 field->descriptortype = type;
5019 if (upb_MiniTable_HasSub(field, msg_modifiers)) {
5020 field->submsg_index = sub_count ? (*sub_count)++ : 0;
5021 } else {
5022 field->submsg_index = kUpb_NoSub;
5023 }
5024
5025 if (upb_MtDecoder_FieldIsPackable(field) &&
5026 (msg_modifiers & kUpb_MessageModifier_DefaultIsPacked)) {
5027 field->mode |= kUpb_LabelFlags_IsPacked;
5028 }
5029 }
5030
upb_MiniTable_SetField(upb_MtDecoder * d,uint8_t ch,upb_MiniTable_Field * field,uint64_t msg_modifiers,uint32_t * sub_count)5031 static void upb_MiniTable_SetField(upb_MtDecoder* d, uint8_t ch,
5032 upb_MiniTable_Field* field,
5033 uint64_t msg_modifiers,
5034 uint32_t* sub_count) {
5035 static const char kUpb_EncodedToFieldRep[] = {
5036 [kUpb_EncodedType_Double] = kUpb_FieldRep_8Byte,
5037 [kUpb_EncodedType_Float] = kUpb_FieldRep_4Byte,
5038 [kUpb_EncodedType_Int64] = kUpb_FieldRep_8Byte,
5039 [kUpb_EncodedType_UInt64] = kUpb_FieldRep_8Byte,
5040 [kUpb_EncodedType_Int32] = kUpb_FieldRep_4Byte,
5041 [kUpb_EncodedType_Fixed64] = kUpb_FieldRep_8Byte,
5042 [kUpb_EncodedType_Fixed32] = kUpb_FieldRep_4Byte,
5043 [kUpb_EncodedType_Bool] = kUpb_FieldRep_1Byte,
5044 [kUpb_EncodedType_String] = kUpb_FieldRep_StringView,
5045 [kUpb_EncodedType_Group] = kUpb_FieldRep_Pointer,
5046 [kUpb_EncodedType_Message] = kUpb_FieldRep_Pointer,
5047 [kUpb_EncodedType_Bytes] = kUpb_FieldRep_StringView,
5048 [kUpb_EncodedType_UInt32] = kUpb_FieldRep_4Byte,
5049 [kUpb_EncodedType_Enum] = kUpb_FieldRep_4Byte,
5050 [kUpb_EncodedType_SFixed32] = kUpb_FieldRep_4Byte,
5051 [kUpb_EncodedType_SFixed64] = kUpb_FieldRep_8Byte,
5052 [kUpb_EncodedType_SInt32] = kUpb_FieldRep_4Byte,
5053 [kUpb_EncodedType_SInt64] = kUpb_FieldRep_8Byte,
5054 };
5055
5056 static const char kUpb_EncodedToType[] = {
5057 [kUpb_EncodedType_Double] = kUpb_FieldType_Double,
5058 [kUpb_EncodedType_Float] = kUpb_FieldType_Float,
5059 [kUpb_EncodedType_Int64] = kUpb_FieldType_Int64,
5060 [kUpb_EncodedType_UInt64] = kUpb_FieldType_UInt64,
5061 [kUpb_EncodedType_Int32] = kUpb_FieldType_Int32,
5062 [kUpb_EncodedType_Fixed64] = kUpb_FieldType_Fixed64,
5063 [kUpb_EncodedType_Fixed32] = kUpb_FieldType_Fixed32,
5064 [kUpb_EncodedType_Bool] = kUpb_FieldType_Bool,
5065 [kUpb_EncodedType_String] = kUpb_FieldType_String,
5066 [kUpb_EncodedType_Group] = kUpb_FieldType_Group,
5067 [kUpb_EncodedType_Message] = kUpb_FieldType_Message,
5068 [kUpb_EncodedType_Bytes] = kUpb_FieldType_Bytes,
5069 [kUpb_EncodedType_UInt32] = kUpb_FieldType_UInt32,
5070 [kUpb_EncodedType_Enum] = kUpb_FieldType_Enum,
5071 [kUpb_EncodedType_SFixed32] = kUpb_FieldType_SFixed32,
5072 [kUpb_EncodedType_SFixed64] = kUpb_FieldType_SFixed64,
5073 [kUpb_EncodedType_SInt32] = kUpb_FieldType_SInt32,
5074 [kUpb_EncodedType_SInt64] = kUpb_FieldType_SInt64,
5075 };
5076
5077 int8_t type = upb_FromBase92(ch);
5078 if (ch >= upb_ToBase92(kUpb_EncodedType_RepeatedBase)) {
5079 type -= kUpb_EncodedType_RepeatedBase;
5080 field->mode = kUpb_FieldMode_Array;
5081 field->mode |= kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift;
5082 field->offset = kNoPresence;
5083 } else {
5084 field->mode = kUpb_FieldMode_Scalar;
5085 field->mode |= kUpb_EncodedToFieldRep[type] << kUpb_FieldRep_Shift;
5086 field->offset = kHasbitPresence;
5087 }
5088 if (type >= 18) {
5089 upb_MtDecoder_ErrorFormat(d, "Invalid field type: %d", (int)type);
5090 UPB_UNREACHABLE();
5091 }
5092 upb_MiniTable_SetTypeAndSub(field, kUpb_EncodedToType[type], sub_count,
5093 msg_modifiers);
5094 }
5095
upb_MtDecoder_ModifyField(upb_MtDecoder * d,uint32_t message_modifiers,uint32_t field_modifiers,upb_MiniTable_Field * field)5096 static void upb_MtDecoder_ModifyField(upb_MtDecoder* d,
5097 uint32_t message_modifiers,
5098 uint32_t field_modifiers,
5099 upb_MiniTable_Field* field) {
5100 if (field_modifiers & kUpb_EncodedFieldModifier_FlipPacked) {
5101 if (!upb_MtDecoder_FieldIsPackable(field)) {
5102 upb_MtDecoder_ErrorFormat(
5103 d, "Cannot flip packed on unpackable field %" PRIu32, field->number);
5104 UPB_UNREACHABLE();
5105 }
5106 field->mode ^= kUpb_LabelFlags_IsPacked;
5107 }
5108
5109 bool singular = field_modifiers & kUpb_EncodedFieldModifier_IsProto3Singular;
5110 bool required = field_modifiers & kUpb_EncodedFieldModifier_IsRequired;
5111
5112 // Validate.
5113 if ((singular || required) && field->offset != kHasbitPresence) {
5114 upb_MtDecoder_ErrorFormat(
5115 d, "Invalid modifier(s) for repeated field %" PRIu32, field->number);
5116 UPB_UNREACHABLE();
5117 }
5118 if (singular && required) {
5119 upb_MtDecoder_ErrorFormat(
5120 d, "Field %" PRIu32 " cannot be both singular and required",
5121 field->number);
5122 UPB_UNREACHABLE();
5123 }
5124
5125 if (singular) field->offset = kNoPresence;
5126 if (required) {
5127 field->offset = kRequiredPresence;
5128 }
5129 }
5130
upb_MtDecoder_PushItem(upb_MtDecoder * d,upb_LayoutItem item)5131 static void upb_MtDecoder_PushItem(upb_MtDecoder* d, upb_LayoutItem item) {
5132 if (d->vec.size == d->vec.capacity) {
5133 size_t new_cap = UPB_MAX(8, d->vec.size * 2);
5134 d->vec.data = realloc(d->vec.data, new_cap * sizeof(*d->vec.data));
5135 upb_MtDecoder_CheckOutOfMemory(d, d->vec.data);
5136 d->vec.capacity = new_cap;
5137 }
5138 d->vec.data[d->vec.size++] = item;
5139 }
5140
upb_MtDecoder_PushOneof(upb_MtDecoder * d,upb_LayoutItem item)5141 static void upb_MtDecoder_PushOneof(upb_MtDecoder* d, upb_LayoutItem item) {
5142 if (item.field_index == kUpb_LayoutItem_IndexSentinel) {
5143 upb_MtDecoder_ErrorFormat(d, "Empty oneof");
5144 UPB_UNREACHABLE();
5145 }
5146 item.field_index -= kOneofBase;
5147
5148 // Push oneof data.
5149 item.type = kUpb_LayoutItemType_OneofField;
5150 upb_MtDecoder_PushItem(d, item);
5151
5152 // Push oneof case.
5153 item.rep = kUpb_FieldRep_4Byte; // Field Number.
5154 item.type = kUpb_LayoutItemType_OneofCase;
5155 upb_MtDecoder_PushItem(d, item);
5156 }
5157
upb_MtDecoder_SizeOfRep(upb_FieldRep rep,upb_MiniTablePlatform platform)5158 size_t upb_MtDecoder_SizeOfRep(upb_FieldRep rep,
5159 upb_MiniTablePlatform platform) {
5160 static const uint8_t kRepToSize32[] = {
5161 [kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
5162 [kUpb_FieldRep_Pointer] = 4, [kUpb_FieldRep_StringView] = 8,
5163 [kUpb_FieldRep_8Byte] = 8,
5164 };
5165 static const uint8_t kRepToSize64[] = {
5166 [kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
5167 [kUpb_FieldRep_Pointer] = 8, [kUpb_FieldRep_StringView] = 16,
5168 [kUpb_FieldRep_8Byte] = 8,
5169 };
5170 UPB_ASSERT(sizeof(upb_StringView) ==
5171 UPB_SIZE(kRepToSize32, kRepToSize64)[kUpb_FieldRep_StringView]);
5172 return platform == kUpb_MiniTablePlatform_32Bit ? kRepToSize32[rep]
5173 : kRepToSize64[rep];
5174 }
5175
upb_MtDecoder_AlignOfRep(upb_FieldRep rep,upb_MiniTablePlatform platform)5176 size_t upb_MtDecoder_AlignOfRep(upb_FieldRep rep,
5177 upb_MiniTablePlatform platform) {
5178 static const uint8_t kRepToAlign32[] = {
5179 [kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
5180 [kUpb_FieldRep_Pointer] = 4, [kUpb_FieldRep_StringView] = 4,
5181 [kUpb_FieldRep_8Byte] = 8,
5182 };
5183 static const uint8_t kRepToAlign64[] = {
5184 [kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
5185 [kUpb_FieldRep_Pointer] = 8, [kUpb_FieldRep_StringView] = 8,
5186 [kUpb_FieldRep_8Byte] = 8,
5187 };
5188 UPB_ASSERT(UPB_ALIGN_OF(upb_StringView) ==
5189 UPB_SIZE(kRepToAlign32, kRepToAlign64)[kUpb_FieldRep_StringView]);
5190 return platform == kUpb_MiniTablePlatform_32Bit ? kRepToAlign32[rep]
5191 : kRepToAlign64[rep];
5192 }
5193
upb_MtDecoder_DecodeOneofField(upb_MtDecoder * d,const char * ptr,char first_ch,upb_LayoutItem * item)5194 static const char* upb_MtDecoder_DecodeOneofField(upb_MtDecoder* d,
5195 const char* ptr,
5196 char first_ch,
5197 upb_LayoutItem* item) {
5198 uint32_t field_num;
5199 ptr = upb_MiniTable_DecodeBase92Varint(
5200 d, ptr, first_ch, kUpb_EncodedValue_MinOneofField,
5201 kUpb_EncodedValue_MaxOneofField, &field_num);
5202 upb_MiniTable_Field* f =
5203 (void*)upb_MiniTable_FindFieldByNumber(d->table, field_num);
5204
5205 if (!f) {
5206 upb_MtDecoder_ErrorFormat(d,
5207 "Couldn't add field number %" PRIu32
5208 " to oneof, no such field number.",
5209 field_num);
5210 UPB_UNREACHABLE();
5211 }
5212 if (f->offset != kHasbitPresence) {
5213 upb_MtDecoder_ErrorFormat(
5214 d,
5215 "Cannot add repeated, required, or singular field %" PRIu32
5216 " to oneof.",
5217 field_num);
5218 UPB_UNREACHABLE();
5219 }
5220
5221 // Oneof storage must be large enough to accommodate the largest member.
5222 int rep = f->mode >> kUpb_FieldRep_Shift;
5223 if (upb_MtDecoder_SizeOfRep(rep, d->platform) >
5224 upb_MtDecoder_SizeOfRep(item->rep, d->platform)) {
5225 item->rep = rep;
5226 }
5227 // Prepend this field to the linked list.
5228 f->offset = item->field_index;
5229 item->field_index = (f - d->fields) + kOneofBase;
5230 return ptr;
5231 }
5232
upb_MtDecoder_DecodeOneofs(upb_MtDecoder * d,const char * ptr)5233 static const char* upb_MtDecoder_DecodeOneofs(upb_MtDecoder* d,
5234 const char* ptr) {
5235 upb_LayoutItem item = {.rep = 0,
5236 .field_index = kUpb_LayoutItem_IndexSentinel};
5237 while (ptr < d->end) {
5238 char ch = *ptr++;
5239 if (ch == kUpb_EncodedValue_FieldSeparator) {
5240 // Field separator, no action needed.
5241 } else if (ch == kUpb_EncodedValue_OneofSeparator) {
5242 // End of oneof.
5243 upb_MtDecoder_PushOneof(d, item);
5244 item.field_index = kUpb_LayoutItem_IndexSentinel; // Move to next oneof.
5245 } else {
5246 ptr = upb_MtDecoder_DecodeOneofField(d, ptr, ch, &item);
5247 }
5248 }
5249
5250 // Push final oneof.
5251 upb_MtDecoder_PushOneof(d, item);
5252 return ptr;
5253 }
5254
upb_MtDecoder_ParseModifier(upb_MtDecoder * d,const char * ptr,char first_ch,upb_MiniTable_Field * last_field,uint64_t * msg_modifiers)5255 static const char* upb_MtDecoder_ParseModifier(upb_MtDecoder* d,
5256 const char* ptr, char first_ch,
5257 upb_MiniTable_Field* last_field,
5258 uint64_t* msg_modifiers) {
5259 uint32_t mod;
5260 ptr = upb_MiniTable_DecodeBase92Varint(d, ptr, first_ch,
5261 kUpb_EncodedValue_MinModifier,
5262 kUpb_EncodedValue_MaxModifier, &mod);
5263 if (last_field) {
5264 upb_MtDecoder_ModifyField(d, *msg_modifiers, mod, last_field);
5265 } else {
5266 if (!d->table) {
5267 upb_MtDecoder_ErrorFormat(d, "Extensions cannot have message modifiers");
5268 UPB_UNREACHABLE();
5269 }
5270 *msg_modifiers = mod;
5271 }
5272
5273 return ptr;
5274 }
5275
upb_MtDecoder_AllocateSubs(upb_MtDecoder * d,uint32_t sub_count)5276 static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, uint32_t sub_count) {
5277 size_t subs_bytes = sizeof(*d->table->subs) * sub_count;
5278 d->table->subs = upb_Arena_Malloc(d->arena, subs_bytes);
5279 upb_MtDecoder_CheckOutOfMemory(d, d->table->subs);
5280 }
5281
upb_MtDecoder_Parse(upb_MtDecoder * d,const char * ptr,size_t len,void * fields,size_t field_size,uint16_t * field_count,uint32_t * sub_count)5282 static void upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, size_t len,
5283 void* fields, size_t field_size,
5284 uint16_t* field_count, uint32_t* sub_count) {
5285 uint64_t msg_modifiers = 0;
5286 uint32_t last_field_number = 0;
5287 upb_MiniTable_Field* last_field = NULL;
5288 bool need_dense_below = d->table != NULL;
5289
5290 d->end = UPB_PTRADD(ptr, len);
5291
5292 while (ptr < d->end) {
5293 char ch = *ptr++;
5294 if (ch <= kUpb_EncodedValue_MaxField) {
5295 upb_MiniTable_Field* field = fields;
5296 *field_count += 1;
5297 fields = (char*)fields + field_size;
5298 field->number = ++last_field_number;
5299 last_field = field;
5300 upb_MiniTable_SetField(d, ch, field, msg_modifiers, sub_count);
5301 } else if (kUpb_EncodedValue_MinModifier <= ch &&
5302 ch <= kUpb_EncodedValue_MaxModifier) {
5303 ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, last_field, &msg_modifiers);
5304 if (msg_modifiers & kUpb_MessageModifier_IsExtendable) {
5305 d->table->ext |= kUpb_ExtMode_Extendable;
5306 }
5307 } else if (ch == kUpb_EncodedValue_End) {
5308 if (!d->table) {
5309 upb_MtDecoder_ErrorFormat(d, "Extensions cannot have oneofs.");
5310 UPB_UNREACHABLE();
5311 }
5312 ptr = upb_MtDecoder_DecodeOneofs(d, ptr);
5313 } else if (kUpb_EncodedValue_MinSkip <= ch &&
5314 ch <= kUpb_EncodedValue_MaxSkip) {
5315 if (need_dense_below) {
5316 d->table->dense_below = d->table->field_count;
5317 need_dense_below = false;
5318 }
5319 uint32_t skip;
5320 ptr = upb_MiniTable_DecodeBase92Varint(d, ptr, ch,
5321 kUpb_EncodedValue_MinSkip,
5322 kUpb_EncodedValue_MaxSkip, &skip);
5323 last_field_number += skip;
5324 last_field_number--; // Next field seen will increment.
5325 }
5326 }
5327
5328 if (need_dense_below) {
5329 d->table->dense_below = d->table->field_count;
5330 }
5331 }
5332
upb_MtDecoder_ParseMessage(upb_MtDecoder * d,const char * data,size_t len)5333 static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data,
5334 size_t len) {
5335 // Buffer length is an upper bound on the number of fields. We will return
5336 // what we don't use.
5337 d->fields = upb_Arena_Malloc(d->arena, sizeof(*d->fields) * len);
5338 upb_MtDecoder_CheckOutOfMemory(d, d->fields);
5339
5340 uint32_t sub_count = 0;
5341 d->table->field_count = 0;
5342 d->table->fields = d->fields;
5343 upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields),
5344 &d->table->field_count, &sub_count);
5345
5346 upb_Arena_ShrinkLast(d->arena, d->fields, sizeof(*d->fields) * len,
5347 sizeof(*d->fields) * d->table->field_count);
5348 d->table->fields = d->fields;
5349 upb_MtDecoder_AllocateSubs(d, sub_count);
5350 }
5351
upb_MtDecoder_CompareFields(const void * _a,const void * _b)5352 int upb_MtDecoder_CompareFields(const void* _a, const void* _b) {
5353 const upb_LayoutItem* a = _a;
5354 const upb_LayoutItem* b = _b;
5355 // Currently we just sort by:
5356 // 1. rep (smallest fields first)
5357 // 2. type (oneof cases first)
5358 // 2. field_index (smallest numbers first)
5359 // The main goal of this is to reduce space lost to padding.
5360 // Later we may have more subtle reasons to prefer a different ordering.
5361 const int rep_bits = _upb_Log2Ceiling(kUpb_FieldRep_Max);
5362 const int type_bits = _upb_Log2Ceiling(kUpb_LayoutItemType_Max);
5363 const int idx_bits = (sizeof(a->field_index) * 8);
5364 UPB_ASSERT(idx_bits + rep_bits + type_bits < 32);
5365 #define UPB_COMBINE(rep, ty, idx) (((rep << type_bits) | ty) << idx_bits) | idx
5366 uint32_t a_packed = UPB_COMBINE(a->rep, a->type, a->field_index);
5367 uint32_t b_packed = UPB_COMBINE(b->rep, b->type, b->field_index);
5368 assert(a_packed != b_packed);
5369 #undef UPB_COMBINE
5370 return a_packed < b_packed ? -1 : 1;
5371 }
5372
upb_MtDecoder_SortLayoutItems(upb_MtDecoder * d)5373 static bool upb_MtDecoder_SortLayoutItems(upb_MtDecoder* d) {
5374 // Add items for all non-oneof fields (oneofs were already added).
5375 int n = d->table->field_count;
5376 for (int i = 0; i < n; i++) {
5377 upb_MiniTable_Field* f = &d->fields[i];
5378 if (f->offset >= kOneofBase) continue;
5379 upb_LayoutItem item = {.field_index = i,
5380 .rep = f->mode >> kUpb_FieldRep_Shift,
5381 .type = kUpb_LayoutItemType_Field};
5382 upb_MtDecoder_PushItem(d, item);
5383 }
5384
5385 if (d->vec.size) {
5386 qsort(d->vec.data, d->vec.size, sizeof(*d->vec.data),
5387 upb_MtDecoder_CompareFields);
5388 }
5389
5390 return true;
5391 }
5392
upb_MiniTable_DivideRoundUp(size_t n,size_t d)5393 static size_t upb_MiniTable_DivideRoundUp(size_t n, size_t d) {
5394 return (n + d - 1) / d;
5395 }
5396
upb_MtDecoder_AssignHasbits(upb_MiniTable * ret)5397 static void upb_MtDecoder_AssignHasbits(upb_MiniTable* ret) {
5398 int n = ret->field_count;
5399 int last_hasbit = 0; // 0 cannot be used.
5400
5401 // First assign required fields, which must have the lowest hasbits.
5402 for (int i = 0; i < n; i++) {
5403 upb_MiniTable_Field* field = (upb_MiniTable_Field*)&ret->fields[i];
5404 if (field->offset == kRequiredPresence) {
5405 field->presence = ++last_hasbit;
5406 } else if (field->offset == kNoPresence) {
5407 field->presence = 0;
5408 }
5409 }
5410 ret->required_count = last_hasbit;
5411
5412 // Next assign non-required hasbit fields.
5413 for (int i = 0; i < n; i++) {
5414 upb_MiniTable_Field* field = (upb_MiniTable_Field*)&ret->fields[i];
5415 if (field->offset == kHasbitPresence) {
5416 field->presence = ++last_hasbit;
5417 }
5418 }
5419
5420 ret->size = last_hasbit ? upb_MiniTable_DivideRoundUp(last_hasbit + 1, 8) : 0;
5421 }
5422
upb_MtDecoder_Place(upb_MtDecoder * d,upb_FieldRep rep)5423 size_t upb_MtDecoder_Place(upb_MtDecoder* d, upb_FieldRep rep) {
5424 size_t size = upb_MtDecoder_SizeOfRep(rep, d->platform);
5425 size_t align = upb_MtDecoder_AlignOfRep(rep, d->platform);
5426 size_t ret = UPB_ALIGN_UP(d->table->size, align);
5427 d->table->size = ret + size;
5428 return ret;
5429 }
5430
upb_MtDecoder_AssignOffsets(upb_MtDecoder * d)5431 static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) {
5432 upb_LayoutItem* end = UPB_PTRADD(d->vec.data, d->vec.size);
5433
5434 // Compute offsets.
5435 for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
5436 item->offset = upb_MtDecoder_Place(d, item->rep);
5437 }
5438
5439 // Assign oneof case offsets. We must do these first, since assigning
5440 // actual offsets will overwrite the links of the linked list.
5441 for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
5442 if (item->type != kUpb_LayoutItemType_OneofCase) continue;
5443 upb_MiniTable_Field* f = &d->fields[item->field_index];
5444 while (true) {
5445 f->presence = ~item->offset;
5446 if (f->offset == kUpb_LayoutItem_IndexSentinel) break;
5447 UPB_ASSERT(f->offset - kOneofBase < d->table->field_count);
5448 f = &d->fields[f->offset - kOneofBase];
5449 }
5450 }
5451
5452 // Assign offsets.
5453 for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
5454 upb_MiniTable_Field* f = &d->fields[item->field_index];
5455 switch (item->type) {
5456 case kUpb_LayoutItemType_OneofField:
5457 while (true) {
5458 uint16_t next_offset = f->offset;
5459 f->offset = item->offset;
5460 if (next_offset == kUpb_LayoutItem_IndexSentinel) break;
5461 f = &d->fields[next_offset - kOneofBase];
5462 }
5463 break;
5464 case kUpb_LayoutItemType_Field:
5465 f->offset = item->offset;
5466 break;
5467 default:
5468 break;
5469 }
5470 }
5471
5472 // The fasttable parser (supported on 64-bit only) depends on this being a
5473 // multiple of 8 in order to satisfy UPB_MALLOC_ALIGN, which is also 8.
5474 //
5475 // On 32-bit we could potentially make this smaller, but there is no
5476 // compelling reason to optimize this right now.
5477 d->table->size = UPB_ALIGN_UP(d->table->size, 8);
5478 }
5479
upb_MiniTable_BuildWithBuf(const char * data,size_t len,upb_MiniTablePlatform platform,upb_Arena * arena,void ** buf,size_t * buf_size,upb_Status * status)5480 upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len,
5481 upb_MiniTablePlatform platform,
5482 upb_Arena* arena, void** buf,
5483 size_t* buf_size,
5484 upb_Status* status) {
5485 upb_MtDecoder decoder = {
5486 .platform = platform,
5487 .vec =
5488 {
5489 .data = *buf,
5490 .capacity = *buf_size / sizeof(*decoder.vec.data),
5491 .size = 0,
5492 },
5493 .arena = arena,
5494 .status = status,
5495 .table = upb_Arena_Malloc(arena, sizeof(*decoder.table)),
5496 };
5497
5498 if (UPB_SETJMP(decoder.err)) {
5499 decoder.table = NULL;
5500 goto done;
5501 }
5502
5503 upb_MtDecoder_CheckOutOfMemory(&decoder, decoder.table);
5504
5505 decoder.table->size = 0;
5506 decoder.table->field_count = 0;
5507 decoder.table->ext = kUpb_ExtMode_NonExtendable;
5508 decoder.table->dense_below = 0;
5509 decoder.table->table_mask = -1;
5510 decoder.table->required_count = 0;
5511
5512 upb_MtDecoder_ParseMessage(&decoder, data, len);
5513 upb_MtDecoder_AssignHasbits(decoder.table);
5514 upb_MtDecoder_SortLayoutItems(&decoder);
5515 upb_MtDecoder_AssignOffsets(&decoder);
5516
5517 done:
5518 *buf = decoder.vec.data;
5519 *buf_size = decoder.vec.capacity / sizeof(*decoder.vec.data);
5520 return decoder.table;
5521 }
5522
upb_MiniTable_BuildMessageSet(upb_MiniTablePlatform platform,upb_Arena * arena)5523 upb_MiniTable* upb_MiniTable_BuildMessageSet(upb_MiniTablePlatform platform,
5524 upb_Arena* arena) {
5525 upb_MiniTable* ret = upb_Arena_Malloc(arena, sizeof(*ret));
5526 if (!ret) return NULL;
5527
5528 ret->size = 0;
5529 ret->field_count = 0;
5530 ret->ext = kUpb_ExtMode_IsMessageSet;
5531 ret->dense_below = 0;
5532 ret->table_mask = -1;
5533 ret->required_count = 0;
5534 return ret;
5535 }
5536
upb_MiniTable_BuildMapEntry(upb_FieldType key_type,upb_FieldType value_type,bool value_is_proto3_enum,upb_MiniTablePlatform platform,upb_Arena * arena)5537 upb_MiniTable* upb_MiniTable_BuildMapEntry(upb_FieldType key_type,
5538 upb_FieldType value_type,
5539 bool value_is_proto3_enum,
5540 upb_MiniTablePlatform platform,
5541 upb_Arena* arena) {
5542 upb_MiniTable* ret = upb_Arena_Malloc(arena, sizeof(*ret));
5543 upb_MiniTable_Field* fields = upb_Arena_Malloc(arena, sizeof(*fields) * 2);
5544 if (!ret || !fields) return NULL;
5545
5546 upb_MiniTable_Sub* subs = NULL;
5547 if (value_is_proto3_enum) value_type = kUpb_FieldType_Int32;
5548 if (value_type == kUpb_FieldType_Message ||
5549 value_type == kUpb_FieldType_Group || value_type == kUpb_FieldType_Enum) {
5550 subs = upb_Arena_Malloc(arena, sizeof(*subs));
5551 if (!subs) return NULL;
5552 }
5553
5554 size_t field_size =
5555 upb_MtDecoder_SizeOfRep(kUpb_FieldRep_StringView, platform);
5556
5557 fields[0].number = 1;
5558 fields[1].number = 2;
5559 fields[0].mode = kUpb_FieldMode_Scalar;
5560 fields[1].mode = kUpb_FieldMode_Scalar;
5561 fields[0].presence = 0;
5562 fields[1].presence = 0;
5563 fields[0].offset = 0;
5564 fields[1].offset = field_size;
5565
5566 upb_MiniTable_SetTypeAndSub(&fields[0], key_type, NULL, 0);
5567 upb_MiniTable_SetTypeAndSub(&fields[1], value_type, NULL, 0);
5568
5569 ret->size = UPB_ALIGN_UP(2 * field_size, 8);
5570 ret->field_count = 2;
5571 ret->ext = kUpb_ExtMode_NonExtendable | kUpb_ExtMode_IsMapEntry;
5572 ret->dense_below = 2;
5573 ret->table_mask = -1;
5574 ret->required_count = 0;
5575 ret->subs = subs;
5576 ret->fields = fields;
5577 return ret;
5578 }
5579
upb_MiniTable_BuildEnumValue(upb_MtDecoder * d,upb_MiniTable_Enum * table,uint32_t val,upb_Arena * arena)5580 static bool upb_MiniTable_BuildEnumValue(upb_MtDecoder* d,
5581 upb_MiniTable_Enum* table,
5582 uint32_t val, upb_Arena* arena) {
5583 if (val < 64) {
5584 table->mask |= 1ULL << val;
5585 return true;
5586 }
5587
5588 int32_t* values = (void*)table->values;
5589 values = upb_Arena_Realloc(arena, values, table->value_count * 4,
5590 (table->value_count + 1) * 4);
5591 upb_MtDecoder_CheckOutOfMemory(d, values);
5592 values[table->value_count++] = (int32_t)val;
5593 table->values = values;
5594 return true;
5595 }
5596
upb_MiniTable_BuildEnum(const char * data,size_t len,upb_Arena * arena,upb_Status * status)5597 upb_MiniTable_Enum* upb_MiniTable_BuildEnum(const char* data, size_t len,
5598 upb_Arena* arena,
5599 upb_Status* status) {
5600 upb_MtDecoder d = {
5601 .status = status,
5602 .end = UPB_PTRADD(data, len),
5603 };
5604
5605 if (UPB_SETJMP(d.err)) {
5606 return NULL;
5607 }
5608
5609 upb_MiniTable_Enum* table = upb_Arena_Malloc(arena, sizeof(*table));
5610 upb_MtDecoder_CheckOutOfMemory(&d, table);
5611
5612 table->mask = 0;
5613 table->value_count = 0;
5614 table->values = NULL;
5615
5616 const char* ptr = data;
5617 uint32_t base = 0;
5618
5619 while (ptr < d.end) {
5620 char ch = *ptr++;
5621 if (ch <= kUpb_EncodedValue_MaxEnumMask) {
5622 uint32_t mask = upb_FromBase92(ch);
5623 for (int i = 0; i < 5; i++, base++, mask >>= 1) {
5624 if (mask & 1) {
5625 if (!upb_MiniTable_BuildEnumValue(&d, table, base, arena)) {
5626 return NULL;
5627 }
5628 }
5629 }
5630 } else if (kUpb_EncodedValue_MinSkip <= ch &&
5631 ch <= kUpb_EncodedValue_MaxSkip) {
5632 uint32_t skip;
5633 ptr = upb_MiniTable_DecodeBase92Varint(&d, ptr, ch,
5634 kUpb_EncodedValue_MinSkip,
5635 kUpb_EncodedValue_MaxSkip, &skip);
5636 base += skip;
5637 } else {
5638 upb_Status_SetErrorFormat(status, "Unexpected character: %c", ch);
5639 return NULL;
5640 }
5641 }
5642
5643 return table;
5644 }
5645
upb_MiniTable_BuildExtension(const char * data,size_t len,upb_MiniTable_Extension * ext,upb_MiniTable_Sub sub,upb_Status * status)5646 bool upb_MiniTable_BuildExtension(const char* data, size_t len,
5647 upb_MiniTable_Extension* ext,
5648 upb_MiniTable_Sub sub, upb_Status* status) {
5649 upb_MtDecoder decoder = {
5650 .arena = NULL,
5651 .status = status,
5652 .table = NULL,
5653 };
5654
5655 if (UPB_SETJMP(decoder.err)) {
5656 return false;
5657 }
5658
5659 uint16_t count = 0;
5660 upb_MtDecoder_Parse(&decoder, data, len, ext, sizeof(*ext), &count, NULL);
5661 ext->field.mode |= kUpb_LabelFlags_IsExtension;
5662 ext->field.offset = 0;
5663 return true;
5664 }
5665
upb_MiniTable_Build(const char * data,size_t len,upb_MiniTablePlatform platform,upb_Arena * arena,upb_Status * status)5666 upb_MiniTable* upb_MiniTable_Build(const char* data, size_t len,
5667 upb_MiniTablePlatform platform,
5668 upb_Arena* arena, upb_Status* status) {
5669 void* buf = NULL;
5670 size_t size = 0;
5671 upb_MiniTable* ret = upb_MiniTable_BuildWithBuf(data, len, platform, arena,
5672 &buf, &size, status);
5673 free(buf);
5674 return ret;
5675 }
5676
upb_MiniTable_SetSubMessage(upb_MiniTable * table,upb_MiniTable_Field * field,const upb_MiniTable * sub)5677 void upb_MiniTable_SetSubMessage(upb_MiniTable* table,
5678 upb_MiniTable_Field* field,
5679 const upb_MiniTable* sub) {
5680 UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
5681 (uintptr_t)field <
5682 (uintptr_t)(table->fields + table->field_count));
5683 if (sub->ext & kUpb_ExtMode_IsMapEntry) {
5684 field->mode =
5685 (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift) | kUpb_FieldMode_Map;
5686 }
5687 upb_MiniTable_Sub* table_sub = (void*)&table->subs[field->submsg_index];
5688 table_sub->submsg = sub;
5689 }
5690
upb_MiniTable_SetSubEnum(upb_MiniTable * table,upb_MiniTable_Field * field,const upb_MiniTable_Enum * sub)5691 void upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTable_Field* field,
5692 const upb_MiniTable_Enum* sub) {
5693 UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
5694 (uintptr_t)field <
5695 (uintptr_t)(table->fields + table->field_count));
5696 upb_MiniTable_Sub* table_sub = (void*)&table->subs[field->submsg_index];
5697 table_sub->subenum = sub;
5698 }
5699
5700 /** upb/def.c ************************************************************/
5701
5702 #include <ctype.h>
5703 #include <errno.h>
5704 #include <setjmp.h>
5705 #include <stdlib.h>
5706 #include <string.h>
5707
5708
5709 /* Must be last. */
5710
5711 typedef struct {
5712 size_t len;
5713 char str[1]; /* Null-terminated string data follows. */
5714 } str_t;
5715
5716 /* The upb core does not generally have a concept of default instances. However
5717 * for descriptor options we make an exception since the max size is known and
5718 * modest (<200 bytes). All types can share a default instance since it is
5719 * initialized to zeroes.
5720 *
5721 * We have to allocate an extra pointer for upb's internal metadata. */
5722 static const char opt_default_buf[_UPB_MAXOPT_SIZE + sizeof(void*)] = {0};
5723 static const char* opt_default = &opt_default_buf[sizeof(void*)];
5724
5725 struct upb_FieldDef {
5726 const google_protobuf_FieldOptions* opts;
5727 const upb_FileDef* file;
5728 const upb_MessageDef* msgdef;
5729 const char* full_name;
5730 const char* json_name;
5731 union {
5732 int64_t sint;
5733 uint64_t uint;
5734 double dbl;
5735 float flt;
5736 bool boolean;
5737 str_t* str;
5738 } defaultval;
5739 union {
5740 const upb_OneofDef* oneof;
5741 const upb_MessageDef* extension_scope;
5742 } scope;
5743 union {
5744 const upb_MessageDef* msgdef;
5745 const upb_EnumDef* enumdef;
5746 const google_protobuf_FieldDescriptorProto* unresolved;
5747 } sub;
5748 uint32_t number_;
5749 uint16_t index_;
5750 uint16_t layout_index; /* Index into msgdef->layout->fields or file->exts */
5751 bool has_default;
5752 bool is_extension_;
5753 bool packed_;
5754 bool proto3_optional_;
5755 bool has_json_name_;
5756 upb_FieldType type_;
5757 upb_Label label_;
5758 #if UINTPTR_MAX == 0xffffffff
5759 uint32_t padding; // Increase size to a multiple of 8.
5760 #endif
5761 };
5762
5763 struct upb_ExtensionRange {
5764 const google_protobuf_ExtensionRangeOptions* opts;
5765 int32_t start;
5766 int32_t end;
5767 };
5768
5769 struct upb_MessageDef {
5770 const google_protobuf_MessageOptions* opts;
5771 const upb_MiniTable* layout;
5772 const upb_FileDef* file;
5773 const upb_MessageDef* containing_type;
5774 const char* full_name;
5775
5776 /* Tables for looking up fields by number and name. */
5777 upb_inttable itof;
5778 upb_strtable ntof;
5779
5780 /* All nested defs.
5781 * MEM: We could save some space here by putting nested defs in a contiguous
5782 * region and calculating counts from offsets or vice-versa. */
5783 const upb_FieldDef* fields;
5784 const upb_OneofDef* oneofs;
5785 const upb_ExtensionRange* ext_ranges;
5786 const upb_StringView* res_names;
5787 const upb_MessageDef* nested_msgs;
5788 const upb_MessageReservedRange* res_ranges;
5789 const upb_EnumDef* nested_enums;
5790 const upb_FieldDef* nested_exts;
5791 int field_count;
5792 int real_oneof_count;
5793 int oneof_count;
5794 int ext_range_count;
5795 int res_range_count;
5796 int res_name_count;
5797 int nested_msg_count;
5798 int nested_enum_count;
5799 int nested_ext_count;
5800 bool in_message_set;
5801 upb_WellKnown well_known_type;
5802 #if UINTPTR_MAX == 0xffffffff
5803 uint32_t padding; // Increase size to a multiple of 8.
5804 #endif
5805 };
5806
5807 struct upb_EnumDef {
5808 const google_protobuf_EnumOptions* opts;
5809 const upb_MiniTable_Enum* layout; // Only for proto2.
5810 const upb_FileDef* file;
5811 const upb_MessageDef* containing_type; // Could be merged with "file".
5812 const char* full_name;
5813 upb_strtable ntoi;
5814 upb_inttable iton;
5815 const upb_EnumValueDef* values;
5816 const upb_EnumReservedRange* res_ranges;
5817 const upb_StringView* res_names;
5818 int value_count;
5819 int res_range_count;
5820 int res_name_count;
5821 int32_t defaultval;
5822 #if UINTPTR_MAX == 0xffffffff
5823 uint32_t padding; // Increase size to a multiple of 8.
5824 #endif
5825 };
5826
5827 struct upb_EnumValueDef {
5828 const google_protobuf_EnumValueOptions* opts;
5829 const upb_EnumDef* parent;
5830 const char* full_name;
5831 int32_t number;
5832 };
5833
5834 struct upb_OneofDef {
5835 const google_protobuf_OneofOptions* opts;
5836 const upb_MessageDef* parent;
5837 const char* full_name;
5838 int field_count;
5839 bool synthetic;
5840 const upb_FieldDef** fields;
5841 upb_strtable ntof;
5842 upb_inttable itof;
5843 #if UINTPTR_MAX == 0xffffffff
5844 uint32_t padding; // Increase size to a multiple of 8.
5845 #endif
5846 };
5847
5848 struct upb_FileDef {
5849 const google_protobuf_FileOptions* opts;
5850 const char* name;
5851 const char* package;
5852
5853 const upb_FileDef** deps;
5854 const int32_t* public_deps;
5855 const int32_t* weak_deps;
5856 const upb_MessageDef* top_lvl_msgs;
5857 const upb_EnumDef* top_lvl_enums;
5858 const upb_FieldDef* top_lvl_exts;
5859 const upb_ServiceDef* services;
5860 const upb_MiniTable_Extension** ext_layouts;
5861 const upb_DefPool* symtab;
5862
5863 int dep_count;
5864 int public_dep_count;
5865 int weak_dep_count;
5866 int top_lvl_msg_count;
5867 int top_lvl_enum_count;
5868 int top_lvl_ext_count;
5869 int service_count;
5870 int ext_count; /* All exts in the file. */
5871 upb_Syntax syntax;
5872 };
5873
5874 struct upb_MethodDef {
5875 const google_protobuf_MethodOptions* opts;
5876 upb_ServiceDef* service;
5877 const char* full_name;
5878 const upb_MessageDef* input_type;
5879 const upb_MessageDef* output_type;
5880 int index;
5881 bool client_streaming;
5882 bool server_streaming;
5883 };
5884
5885 struct upb_ServiceDef {
5886 const google_protobuf_ServiceOptions* opts;
5887 const upb_FileDef* file;
5888 const char* full_name;
5889 upb_MethodDef* methods;
5890 int method_count;
5891 int index;
5892 };
5893
5894 struct upb_DefPool {
5895 upb_Arena* arena;
5896 upb_strtable syms; /* full_name -> packed def ptr */
5897 upb_strtable files; /* file_name -> upb_FileDef* */
5898 upb_inttable exts; /* upb_MiniTable_Extension* -> upb_FieldDef* */
5899 upb_ExtensionRegistry* extreg;
5900 size_t bytes_loaded;
5901 };
5902
5903 /* Inside a symtab we store tagged pointers to specific def types. */
5904 typedef enum {
5905 UPB_DEFTYPE_MASK = 7,
5906
5907 /* Only inside symtab table. */
5908 UPB_DEFTYPE_EXT = 0,
5909 UPB_DEFTYPE_MSG = 1,
5910 UPB_DEFTYPE_ENUM = 2,
5911 UPB_DEFTYPE_ENUMVAL = 3,
5912 UPB_DEFTYPE_SERVICE = 4,
5913
5914 /* Only inside message table. */
5915 UPB_DEFTYPE_FIELD = 0,
5916 UPB_DEFTYPE_ONEOF = 1,
5917 UPB_DEFTYPE_FIELD_JSONNAME = 2,
5918
5919 /* Only inside file table. */
5920 UPB_DEFTYPE_FILE = 0,
5921 UPB_DEFTYPE_LAYOUT = 1
5922 } upb_deftype_t;
5923
5924 #define FIELD_TYPE_UNSPECIFIED 0
5925
5926 struct upb_MessageReservedRange {
5927 int32_t start;
5928 int32_t end;
5929 };
5930
5931 struct symtab_addctx {
5932 upb_DefPool* symtab;
5933 upb_FileDef* file; /* File we are building. */
5934 upb_Arena* arena; /* Allocate defs here. */
5935 upb_Arena* tmp_arena; /* For temporary allocations. */
5936 const upb_MiniTable_File* layout; /* NULL if we should build layouts. */
5937 int enum_count; /* Count of enums built so far. */
5938 int msg_count; /* Count of messages built so far. */
5939 int ext_count; /* Count of extensions built so far. */
5940 upb_Status* status; /* Record errors here. */
5941 jmp_buf err; /* longjmp() on error. */
5942 };
5943
deftype(upb_value v)5944 static upb_deftype_t deftype(upb_value v) {
5945 uintptr_t num = (uintptr_t)upb_value_getconstptr(v);
5946 return num & UPB_DEFTYPE_MASK;
5947 }
5948
unpack_def(upb_value v,upb_deftype_t type)5949 static const void* unpack_def(upb_value v, upb_deftype_t type) {
5950 uintptr_t num = (uintptr_t)upb_value_getconstptr(v);
5951 return (num & UPB_DEFTYPE_MASK) == type
5952 ? (const void*)(num & ~UPB_DEFTYPE_MASK)
5953 : NULL;
5954 }
5955
pack_def(const void * ptr,upb_deftype_t type)5956 static upb_value pack_def(const void* ptr, upb_deftype_t type) {
5957 // Our 3-bit pointer tagging requires all pointers to be multiples of 8.
5958 // The arena will always yield 8-byte-aligned addresses, however we put
5959 // the defs into arrays. For each element in the array to be 8-byte-aligned,
5960 // the sizes of each def type must also be a multiple of 8.
5961 //
5962 // If any of these asserts fail, we need to add or remove padding on 32-bit
5963 // machines (64-bit machines will have 8-byte alignment already due to
5964 // pointers, which all of these structs have).
5965 UPB_ASSERT((sizeof(upb_FieldDef) & UPB_DEFTYPE_MASK) == 0);
5966 UPB_ASSERT((sizeof(upb_MessageDef) & UPB_DEFTYPE_MASK) == 0);
5967 UPB_ASSERT((sizeof(upb_EnumDef) & UPB_DEFTYPE_MASK) == 0);
5968 UPB_ASSERT((sizeof(upb_EnumValueDef) & UPB_DEFTYPE_MASK) == 0);
5969 UPB_ASSERT((sizeof(upb_ServiceDef) & UPB_DEFTYPE_MASK) == 0);
5970 UPB_ASSERT((sizeof(upb_OneofDef) & UPB_DEFTYPE_MASK) == 0);
5971 uintptr_t num = (uintptr_t)ptr;
5972 UPB_ASSERT((num & UPB_DEFTYPE_MASK) == 0);
5973 num |= type;
5974 return upb_value_constptr((const void*)num);
5975 }
5976
5977 /* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
upb_isbetween(uint8_t c,uint8_t low,uint8_t high)5978 static bool upb_isbetween(uint8_t c, uint8_t low, uint8_t high) {
5979 return c >= low && c <= high;
5980 }
5981
upb_ascii_lower(char ch)5982 static char upb_ascii_lower(char ch) {
5983 // Per ASCII this will lower-case a letter. If the result is a letter, the
5984 // input was definitely a letter. If the output is not a letter, this may
5985 // have transformed the character unpredictably.
5986 return ch | 0x20;
5987 }
5988
upb_isletter(char c)5989 static bool upb_isletter(char c) {
5990 char lower = upb_ascii_lower(c);
5991 return upb_isbetween(lower, 'a', 'z') || c == '_';
5992 }
5993
upb_isalphanum(char c)5994 static bool upb_isalphanum(char c) {
5995 return upb_isletter(c) || upb_isbetween(c, '0', '9');
5996 }
5997
shortdefname(const char * fullname)5998 static const char* shortdefname(const char* fullname) {
5999 const char* p;
6000
6001 if (fullname == NULL) {
6002 return NULL;
6003 } else if ((p = strrchr(fullname, '.')) == NULL) {
6004 /* No '.' in the name, return the full string. */
6005 return fullname;
6006 } else {
6007 /* Return one past the last '.'. */
6008 return p + 1;
6009 }
6010 }
6011
6012 /* All submessage fields are lower than all other fields.
6013 * Secondly, fields are increasing in order. */
field_rank(const upb_FieldDef * f)6014 uint32_t field_rank(const upb_FieldDef* f) {
6015 uint32_t ret = upb_FieldDef_Number(f);
6016 const uint32_t high_bit = 1 << 30;
6017 UPB_ASSERT(ret < high_bit);
6018 if (!upb_FieldDef_IsSubMessage(f)) ret |= high_bit;
6019 return ret;
6020 }
6021
cmp_fields(const void * p1,const void * p2)6022 int cmp_fields(const void* p1, const void* p2) {
6023 const upb_FieldDef* f1 = *(upb_FieldDef* const*)p1;
6024 const upb_FieldDef* f2 = *(upb_FieldDef* const*)p2;
6025 return field_rank(f1) - field_rank(f2);
6026 }
6027
upb_Status_setoom(upb_Status * status)6028 static void upb_Status_setoom(upb_Status* status) {
6029 upb_Status_SetErrorMessage(status, "out of memory");
6030 }
6031
assign_msg_wellknowntype(upb_MessageDef * m)6032 static void assign_msg_wellknowntype(upb_MessageDef* m) {
6033 const char* name = upb_MessageDef_FullName(m);
6034 if (name == NULL) {
6035 m->well_known_type = kUpb_WellKnown_Unspecified;
6036 return;
6037 }
6038 if (!strcmp(name, "google.protobuf.Any")) {
6039 m->well_known_type = kUpb_WellKnown_Any;
6040 } else if (!strcmp(name, "google.protobuf.FieldMask")) {
6041 m->well_known_type = kUpb_WellKnown_FieldMask;
6042 } else if (!strcmp(name, "google.protobuf.Duration")) {
6043 m->well_known_type = kUpb_WellKnown_Duration;
6044 } else if (!strcmp(name, "google.protobuf.Timestamp")) {
6045 m->well_known_type = kUpb_WellKnown_Timestamp;
6046 } else if (!strcmp(name, "google.protobuf.DoubleValue")) {
6047 m->well_known_type = kUpb_WellKnown_DoubleValue;
6048 } else if (!strcmp(name, "google.protobuf.FloatValue")) {
6049 m->well_known_type = kUpb_WellKnown_FloatValue;
6050 } else if (!strcmp(name, "google.protobuf.Int64Value")) {
6051 m->well_known_type = kUpb_WellKnown_Int64Value;
6052 } else if (!strcmp(name, "google.protobuf.UInt64Value")) {
6053 m->well_known_type = kUpb_WellKnown_UInt64Value;
6054 } else if (!strcmp(name, "google.protobuf.Int32Value")) {
6055 m->well_known_type = kUpb_WellKnown_Int32Value;
6056 } else if (!strcmp(name, "google.protobuf.UInt32Value")) {
6057 m->well_known_type = kUpb_WellKnown_UInt32Value;
6058 } else if (!strcmp(name, "google.protobuf.BoolValue")) {
6059 m->well_known_type = kUpb_WellKnown_BoolValue;
6060 } else if (!strcmp(name, "google.protobuf.StringValue")) {
6061 m->well_known_type = kUpb_WellKnown_StringValue;
6062 } else if (!strcmp(name, "google.protobuf.BytesValue")) {
6063 m->well_known_type = kUpb_WellKnown_BytesValue;
6064 } else if (!strcmp(name, "google.protobuf.Value")) {
6065 m->well_known_type = kUpb_WellKnown_Value;
6066 } else if (!strcmp(name, "google.protobuf.ListValue")) {
6067 m->well_known_type = kUpb_WellKnown_ListValue;
6068 } else if (!strcmp(name, "google.protobuf.Struct")) {
6069 m->well_known_type = kUpb_WellKnown_Struct;
6070 } else {
6071 m->well_known_type = kUpb_WellKnown_Unspecified;
6072 }
6073 }
6074
6075 /* upb_EnumDef ****************************************************************/
6076
upb_EnumDef_Options(const upb_EnumDef * e)6077 const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) {
6078 return e->opts;
6079 }
6080
upb_EnumDef_HasOptions(const upb_EnumDef * e)6081 bool upb_EnumDef_HasOptions(const upb_EnumDef* e) {
6082 return e->opts != (void*)opt_default;
6083 }
6084
upb_EnumDef_FullName(const upb_EnumDef * e)6085 const char* upb_EnumDef_FullName(const upb_EnumDef* e) { return e->full_name; }
6086
upb_EnumDef_Name(const upb_EnumDef * e)6087 const char* upb_EnumDef_Name(const upb_EnumDef* e) {
6088 return shortdefname(e->full_name);
6089 }
6090
upb_EnumDef_File(const upb_EnumDef * e)6091 const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e) { return e->file; }
6092
upb_EnumDef_ContainingType(const upb_EnumDef * e)6093 const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e) {
6094 return e->containing_type;
6095 }
6096
upb_EnumDef_Default(const upb_EnumDef * e)6097 int32_t upb_EnumDef_Default(const upb_EnumDef* e) {
6098 UPB_ASSERT(upb_EnumDef_FindValueByNumber(e, e->defaultval));
6099 return e->defaultval;
6100 }
6101
upb_EnumDef_ReservedRangeCount(const upb_EnumDef * e)6102 int upb_EnumDef_ReservedRangeCount(const upb_EnumDef* e) {
6103 return e->res_range_count;
6104 }
6105
6106 /* upb_EnumReservedRange ******************************************************/
6107
6108 struct upb_EnumReservedRange {
6109 int32_t start;
6110 int32_t end;
6111 };
6112
_upb_EnumReservedRange_At(const upb_EnumReservedRange * r,int i)6113 upb_EnumReservedRange* _upb_EnumReservedRange_At(const upb_EnumReservedRange* r,
6114 int i) {
6115 return (upb_EnumReservedRange*)&r[i];
6116 }
6117
upb_EnumReservedRange_Start(const upb_EnumReservedRange * r)6118 int32_t upb_EnumReservedRange_Start(const upb_EnumReservedRange* r) {
6119 return r->start;
6120 }
upb_EnumReservedRange_End(const upb_EnumReservedRange * r)6121 int32_t upb_EnumReservedRange_End(const upb_EnumReservedRange* r) {
6122 return r->end;
6123 }
6124
symtab_errf(symtab_addctx * ctx,const char * fmt,...)6125 UPB_NORETURN UPB_NOINLINE UPB_PRINTF(2, 3) static void symtab_errf(
6126 symtab_addctx* ctx, const char* fmt, ...) {
6127 va_list argp;
6128 va_start(argp, fmt);
6129 upb_Status_VSetErrorFormat(ctx->status, fmt, argp);
6130 va_end(argp);
6131 UPB_LONGJMP(ctx->err, 1);
6132 }
6133
_upb_EnumReservedRanges_New(symtab_addctx * ctx,int n,const google_protobuf_EnumDescriptorProto_EnumReservedRange * const * protos,const upb_EnumDef * e)6134 upb_EnumReservedRange* _upb_EnumReservedRanges_New(
6135 symtab_addctx* ctx, int n,
6136 const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* protos,
6137 const upb_EnumDef* e) {
6138 upb_EnumReservedRange* r =
6139 upb_Arena_Malloc(ctx->arena, sizeof(upb_EnumReservedRange) * n);
6140
6141 for (int i = 0; i < n; i++) {
6142 const int32_t start =
6143 google_protobuf_EnumDescriptorProto_EnumReservedRange_start(protos[i]);
6144 const int32_t end =
6145 google_protobuf_EnumDescriptorProto_EnumReservedRange_end(protos[i]);
6146
6147 // A full validation would also check that each range is disjoint, and that
6148 // none of the fields overlap with the extension ranges, but we are just
6149 // sanity checking here.
6150
6151 // Note: Not a typo! Unlike extension ranges and message reserved ranges,
6152 // the end value of an enum reserved range is *inclusive*!
6153 if (end < start) {
6154 symtab_errf(ctx, "Reserved range (%d, %d) is invalid, enum=%s\n",
6155 (int)start, (int)end, upb_EnumDef_FullName(e));
6156 }
6157
6158 r[i].start = start;
6159 r[i].end = end;
6160 }
6161
6162 return r;
6163 }
6164
upb_EnumDef_ReservedRange(const upb_EnumDef * e,int i)6165 const upb_EnumReservedRange* upb_EnumDef_ReservedRange(const upb_EnumDef* e,
6166 int i) {
6167 UPB_ASSERT(0 <= i && i < e->res_range_count);
6168 return _upb_EnumReservedRange_At(e->res_ranges, i);
6169 }
6170
upb_EnumDef_ReservedNameCount(const upb_EnumDef * e)6171 int upb_EnumDef_ReservedNameCount(const upb_EnumDef* e) {
6172 return e->res_name_count;
6173 }
6174
upb_EnumDef_ReservedName(const upb_EnumDef * e,int i)6175 upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i) {
6176 UPB_ASSERT(0 <= i && i < e->res_name_count);
6177 return e->res_names[i];
6178 }
6179
upb_EnumDef_ValueCount(const upb_EnumDef * e)6180 int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; }
6181
upb_EnumDef_FindValueByNameWithSize(const upb_EnumDef * def,const char * name,size_t len)6182 const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize(
6183 const upb_EnumDef* def, const char* name, size_t len) {
6184 upb_value v;
6185 return upb_strtable_lookup2(&def->ntoi, name, len, &v)
6186 ? upb_value_getconstptr(v)
6187 : NULL;
6188 }
6189
upb_EnumDef_FindValueByNumber(const upb_EnumDef * def,int32_t num)6190 const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* def,
6191 int32_t num) {
6192 upb_value v;
6193 return upb_inttable_lookup(&def->iton, num, &v) ? upb_value_getconstptr(v)
6194 : NULL;
6195 }
6196
upb_EnumDef_CheckNumber(const upb_EnumDef * e,int32_t num)6197 bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num) {
6198 // We could use upb_EnumDef_FindValueByNumber(e, num) != NULL, but we expect
6199 // this to be faster (especially for small numbers).
6200 return upb_MiniTable_Enum_CheckValue(e->layout, num);
6201 }
6202
upb_EnumDef_Value(const upb_EnumDef * e,int i)6203 const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) {
6204 UPB_ASSERT(0 <= i && i < e->value_count);
6205 return &e->values[i];
6206 }
6207
6208 /* upb_EnumValueDef ***********************************************************/
6209
upb_EnumValueDef_Options(const upb_EnumValueDef * e)6210 const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options(
6211 const upb_EnumValueDef* e) {
6212 return e->opts;
6213 }
6214
upb_EnumValueDef_HasOptions(const upb_EnumValueDef * e)6215 bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* e) {
6216 return e->opts != (void*)opt_default;
6217 }
6218
upb_EnumValueDef_Enum(const upb_EnumValueDef * ev)6219 const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* ev) {
6220 return ev->parent;
6221 }
6222
upb_EnumValueDef_FullName(const upb_EnumValueDef * ev)6223 const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* ev) {
6224 return ev->full_name;
6225 }
6226
upb_EnumValueDef_Name(const upb_EnumValueDef * ev)6227 const char* upb_EnumValueDef_Name(const upb_EnumValueDef* ev) {
6228 return shortdefname(ev->full_name);
6229 }
6230
upb_EnumValueDef_Number(const upb_EnumValueDef * ev)6231 int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* ev) {
6232 return ev->number;
6233 }
6234
upb_EnumValueDef_Index(const upb_EnumValueDef * ev)6235 uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* ev) {
6236 // Compute index in our parent's array.
6237 return ev - ev->parent->values;
6238 }
6239
6240 /* upb_ExtensionRange
6241 * ***************************************************************/
6242
upb_ExtensionRange_Options(const upb_ExtensionRange * r)6243 const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options(
6244 const upb_ExtensionRange* r) {
6245 return r->opts;
6246 }
6247
upb_ExtensionRange_HasOptions(const upb_ExtensionRange * r)6248 bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r) {
6249 return r->opts != (void*)opt_default;
6250 }
6251
upb_ExtensionRange_Start(const upb_ExtensionRange * e)6252 int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* e) {
6253 return e->start;
6254 }
6255
upb_ExtensionRange_End(const upb_ExtensionRange * e)6256 int32_t upb_ExtensionRange_End(const upb_ExtensionRange* e) { return e->end; }
6257
6258 /* upb_FieldDef ***************************************************************/
6259
upb_FieldDef_Options(const upb_FieldDef * f)6260 const google_protobuf_FieldOptions* upb_FieldDef_Options(
6261 const upb_FieldDef* f) {
6262 return f->opts;
6263 }
6264
upb_FieldDef_HasOptions(const upb_FieldDef * f)6265 bool upb_FieldDef_HasOptions(const upb_FieldDef* f) {
6266 return f->opts != (void*)opt_default;
6267 }
6268
upb_FieldDef_FullName(const upb_FieldDef * f)6269 const char* upb_FieldDef_FullName(const upb_FieldDef* f) {
6270 return f->full_name;
6271 }
6272
upb_FieldDef_CType(const upb_FieldDef * f)6273 upb_CType upb_FieldDef_CType(const upb_FieldDef* f) {
6274 switch (f->type_) {
6275 case kUpb_FieldType_Double:
6276 return kUpb_CType_Double;
6277 case kUpb_FieldType_Float:
6278 return kUpb_CType_Float;
6279 case kUpb_FieldType_Int64:
6280 case kUpb_FieldType_SInt64:
6281 case kUpb_FieldType_SFixed64:
6282 return kUpb_CType_Int64;
6283 case kUpb_FieldType_Int32:
6284 case kUpb_FieldType_SFixed32:
6285 case kUpb_FieldType_SInt32:
6286 return kUpb_CType_Int32;
6287 case kUpb_FieldType_UInt64:
6288 case kUpb_FieldType_Fixed64:
6289 return kUpb_CType_UInt64;
6290 case kUpb_FieldType_UInt32:
6291 case kUpb_FieldType_Fixed32:
6292 return kUpb_CType_UInt32;
6293 case kUpb_FieldType_Enum:
6294 return kUpb_CType_Enum;
6295 case kUpb_FieldType_Bool:
6296 return kUpb_CType_Bool;
6297 case kUpb_FieldType_String:
6298 return kUpb_CType_String;
6299 case kUpb_FieldType_Bytes:
6300 return kUpb_CType_Bytes;
6301 case kUpb_FieldType_Group:
6302 case kUpb_FieldType_Message:
6303 return kUpb_CType_Message;
6304 }
6305 UPB_UNREACHABLE();
6306 }
6307
upb_FieldDef_Type(const upb_FieldDef * f)6308 upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f) { return f->type_; }
6309
upb_FieldDef_Index(const upb_FieldDef * f)6310 uint32_t upb_FieldDef_Index(const upb_FieldDef* f) { return f->index_; }
6311
upb_FieldDef_Label(const upb_FieldDef * f)6312 upb_Label upb_FieldDef_Label(const upb_FieldDef* f) { return f->label_; }
6313
upb_FieldDef_Number(const upb_FieldDef * f)6314 uint32_t upb_FieldDef_Number(const upb_FieldDef* f) { return f->number_; }
6315
upb_FieldDef_IsExtension(const upb_FieldDef * f)6316 bool upb_FieldDef_IsExtension(const upb_FieldDef* f) {
6317 return f->is_extension_;
6318 }
6319
upb_FieldDef_IsPacked(const upb_FieldDef * f)6320 bool upb_FieldDef_IsPacked(const upb_FieldDef* f) { return f->packed_; }
6321
upb_FieldDef_Name(const upb_FieldDef * f)6322 const char* upb_FieldDef_Name(const upb_FieldDef* f) {
6323 return shortdefname(f->full_name);
6324 }
6325
upb_FieldDef_JsonName(const upb_FieldDef * f)6326 const char* upb_FieldDef_JsonName(const upb_FieldDef* f) {
6327 return f->json_name;
6328 }
6329
upb_FieldDef_HasJsonName(const upb_FieldDef * f)6330 bool upb_FieldDef_HasJsonName(const upb_FieldDef* f) {
6331 return f->has_json_name_;
6332 }
6333
upb_FieldDef_File(const upb_FieldDef * f)6334 const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f) { return f->file; }
6335
upb_FieldDef_ContainingType(const upb_FieldDef * f)6336 const upb_MessageDef* upb_FieldDef_ContainingType(const upb_FieldDef* f) {
6337 return f->msgdef;
6338 }
6339
upb_FieldDef_ExtensionScope(const upb_FieldDef * f)6340 const upb_MessageDef* upb_FieldDef_ExtensionScope(const upb_FieldDef* f) {
6341 return f->is_extension_ ? f->scope.extension_scope : NULL;
6342 }
6343
upb_FieldDef_ContainingOneof(const upb_FieldDef * f)6344 const upb_OneofDef* upb_FieldDef_ContainingOneof(const upb_FieldDef* f) {
6345 return f->is_extension_ ? NULL : f->scope.oneof;
6346 }
6347
upb_FieldDef_RealContainingOneof(const upb_FieldDef * f)6348 const upb_OneofDef* upb_FieldDef_RealContainingOneof(const upb_FieldDef* f) {
6349 const upb_OneofDef* oneof = upb_FieldDef_ContainingOneof(f);
6350 if (!oneof || upb_OneofDef_IsSynthetic(oneof)) return NULL;
6351 return oneof;
6352 }
6353
upb_FieldDef_Default(const upb_FieldDef * f)6354 upb_MessageValue upb_FieldDef_Default(const upb_FieldDef* f) {
6355 UPB_ASSERT(!upb_FieldDef_IsSubMessage(f));
6356 upb_MessageValue ret;
6357
6358 switch (upb_FieldDef_CType(f)) {
6359 case kUpb_CType_Bool:
6360 return (upb_MessageValue){.bool_val = f->defaultval.boolean};
6361 case kUpb_CType_Int64:
6362 return (upb_MessageValue){.int64_val = f->defaultval.sint};
6363 case kUpb_CType_UInt64:
6364 return (upb_MessageValue){.uint64_val = f->defaultval.uint};
6365 case kUpb_CType_Enum:
6366 case kUpb_CType_Int32:
6367 return (upb_MessageValue){.int32_val = (int32_t)f->defaultval.sint};
6368 case kUpb_CType_UInt32:
6369 return (upb_MessageValue){.uint32_val = (uint32_t)f->defaultval.uint};
6370 case kUpb_CType_Float:
6371 return (upb_MessageValue){.float_val = f->defaultval.flt};
6372 case kUpb_CType_Double:
6373 return (upb_MessageValue){.double_val = f->defaultval.dbl};
6374 case kUpb_CType_String:
6375 case kUpb_CType_Bytes: {
6376 str_t* str = f->defaultval.str;
6377 if (str) {
6378 return (upb_MessageValue){
6379 .str_val = (upb_StringView){.data = str->str, .size = str->len}};
6380 } else {
6381 return (upb_MessageValue){
6382 .str_val = (upb_StringView){.data = NULL, .size = 0}};
6383 }
6384 }
6385 default:
6386 UPB_UNREACHABLE();
6387 }
6388
6389 return ret;
6390 }
6391
upb_FieldDef_MessageSubDef(const upb_FieldDef * f)6392 const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f) {
6393 return upb_FieldDef_CType(f) == kUpb_CType_Message ? f->sub.msgdef : NULL;
6394 }
6395
upb_FieldDef_EnumSubDef(const upb_FieldDef * f)6396 const upb_EnumDef* upb_FieldDef_EnumSubDef(const upb_FieldDef* f) {
6397 return upb_FieldDef_CType(f) == kUpb_CType_Enum ? f->sub.enumdef : NULL;
6398 }
6399
upb_FieldDef_MiniTable(const upb_FieldDef * f)6400 const upb_MiniTable_Field* upb_FieldDef_MiniTable(const upb_FieldDef* f) {
6401 UPB_ASSERT(!upb_FieldDef_IsExtension(f));
6402 return &f->msgdef->layout->fields[f->layout_index];
6403 }
6404
_upb_FieldDef_ExtensionMiniTable(const upb_FieldDef * f)6405 const upb_MiniTable_Extension* _upb_FieldDef_ExtensionMiniTable(
6406 const upb_FieldDef* f) {
6407 UPB_ASSERT(upb_FieldDef_IsExtension(f));
6408 return f->file->ext_layouts[f->layout_index];
6409 }
6410
_upb_FieldDef_IsProto3Optional(const upb_FieldDef * f)6411 bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f) {
6412 return f->proto3_optional_;
6413 }
6414
upb_FieldDef_IsSubMessage(const upb_FieldDef * f)6415 bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f) {
6416 return upb_FieldDef_CType(f) == kUpb_CType_Message;
6417 }
6418
upb_FieldDef_IsString(const upb_FieldDef * f)6419 bool upb_FieldDef_IsString(const upb_FieldDef* f) {
6420 return upb_FieldDef_CType(f) == kUpb_CType_String ||
6421 upb_FieldDef_CType(f) == kUpb_CType_Bytes;
6422 }
6423
upb_FieldDef_IsRepeated(const upb_FieldDef * f)6424 bool upb_FieldDef_IsRepeated(const upb_FieldDef* f) {
6425 return upb_FieldDef_Label(f) == kUpb_Label_Repeated;
6426 }
6427
upb_FieldDef_IsPrimitive(const upb_FieldDef * f)6428 bool upb_FieldDef_IsPrimitive(const upb_FieldDef* f) {
6429 return !upb_FieldDef_IsString(f) && !upb_FieldDef_IsSubMessage(f);
6430 }
6431
upb_FieldDef_IsMap(const upb_FieldDef * f)6432 bool upb_FieldDef_IsMap(const upb_FieldDef* f) {
6433 return upb_FieldDef_IsRepeated(f) && upb_FieldDef_IsSubMessage(f) &&
6434 upb_MessageDef_IsMapEntry(upb_FieldDef_MessageSubDef(f));
6435 }
6436
upb_FieldDef_HasDefault(const upb_FieldDef * f)6437 bool upb_FieldDef_HasDefault(const upb_FieldDef* f) { return f->has_default; }
6438
upb_FieldDef_HasSubDef(const upb_FieldDef * f)6439 bool upb_FieldDef_HasSubDef(const upb_FieldDef* f) {
6440 return upb_FieldDef_IsSubMessage(f) ||
6441 upb_FieldDef_CType(f) == kUpb_CType_Enum;
6442 }
6443
upb_FieldDef_HasPresence(const upb_FieldDef * f)6444 bool upb_FieldDef_HasPresence(const upb_FieldDef* f) {
6445 if (upb_FieldDef_IsRepeated(f)) return false;
6446 return upb_FieldDef_IsSubMessage(f) || upb_FieldDef_ContainingOneof(f) ||
6447 f->file->syntax == kUpb_Syntax_Proto2;
6448 }
6449
between(int32_t x,int32_t low,int32_t high)6450 static bool between(int32_t x, int32_t low, int32_t high) {
6451 return x >= low && x <= high;
6452 }
6453
upb_FieldDef_checklabel(int32_t label)6454 bool upb_FieldDef_checklabel(int32_t label) { return between(label, 1, 3); }
upb_FieldDef_checktype(int32_t type)6455 bool upb_FieldDef_checktype(int32_t type) { return between(type, 1, 11); }
upb_FieldDef_checkintfmt(int32_t fmt)6456 bool upb_FieldDef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); }
6457
upb_FieldDef_checkdescriptortype(int32_t type)6458 bool upb_FieldDef_checkdescriptortype(int32_t type) {
6459 return between(type, 1, 18);
6460 }
6461
6462 /* upb_MessageDef
6463 * *****************************************************************/
6464
upb_MessageDef_Options(const upb_MessageDef * m)6465 const google_protobuf_MessageOptions* upb_MessageDef_Options(
6466 const upb_MessageDef* m) {
6467 return m->opts;
6468 }
6469
upb_MessageDef_HasOptions(const upb_MessageDef * m)6470 bool upb_MessageDef_HasOptions(const upb_MessageDef* m) {
6471 return m->opts != (void*)opt_default;
6472 }
6473
upb_MessageDef_FullName(const upb_MessageDef * m)6474 const char* upb_MessageDef_FullName(const upb_MessageDef* m) {
6475 return m->full_name;
6476 }
6477
upb_MessageDef_File(const upb_MessageDef * m)6478 const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m) {
6479 return m->file;
6480 }
6481
upb_MessageDef_ContainingType(const upb_MessageDef * m)6482 const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m) {
6483 return m->containing_type;
6484 }
6485
upb_MessageDef_Name(const upb_MessageDef * m)6486 const char* upb_MessageDef_Name(const upb_MessageDef* m) {
6487 return shortdefname(m->full_name);
6488 }
6489
upb_MessageDef_Syntax(const upb_MessageDef * m)6490 upb_Syntax upb_MessageDef_Syntax(const upb_MessageDef* m) {
6491 return m->file->syntax;
6492 }
6493
upb_MessageDef_FindFieldByNumber(const upb_MessageDef * m,uint32_t i)6494 const upb_FieldDef* upb_MessageDef_FindFieldByNumber(const upb_MessageDef* m,
6495 uint32_t i) {
6496 upb_value val;
6497 return upb_inttable_lookup(&m->itof, i, &val) ? upb_value_getconstptr(val)
6498 : NULL;
6499 }
6500
upb_MessageDef_FindFieldByNameWithSize(const upb_MessageDef * m,const char * name,size_t len)6501 const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize(
6502 const upb_MessageDef* m, const char* name, size_t len) {
6503 upb_value val;
6504
6505 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
6506 return NULL;
6507 }
6508
6509 return unpack_def(val, UPB_DEFTYPE_FIELD);
6510 }
6511
upb_MessageDef_FindOneofByNameWithSize(const upb_MessageDef * m,const char * name,size_t len)6512 const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize(
6513 const upb_MessageDef* m, const char* name, size_t len) {
6514 upb_value val;
6515
6516 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
6517 return NULL;
6518 }
6519
6520 return unpack_def(val, UPB_DEFTYPE_ONEOF);
6521 }
6522
upb_MessageDef_FindByNameWithSize(const upb_MessageDef * m,const char * name,size_t len,const upb_FieldDef ** out_f,const upb_OneofDef ** out_o)6523 bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m,
6524 const char* name, size_t len,
6525 const upb_FieldDef** out_f,
6526 const upb_OneofDef** out_o) {
6527 upb_value val;
6528
6529 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
6530 return false;
6531 }
6532
6533 const upb_FieldDef* f = unpack_def(val, UPB_DEFTYPE_FIELD);
6534 const upb_OneofDef* o = unpack_def(val, UPB_DEFTYPE_ONEOF);
6535 if (out_f) *out_f = f;
6536 if (out_o) *out_o = o;
6537 return f || o; /* False if this was a JSON name. */
6538 }
6539
upb_MessageDef_FindByJsonNameWithSize(const upb_MessageDef * m,const char * name,size_t len)6540 const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize(
6541 const upb_MessageDef* m, const char* name, size_t len) {
6542 upb_value val;
6543 const upb_FieldDef* f;
6544
6545 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
6546 return NULL;
6547 }
6548
6549 f = unpack_def(val, UPB_DEFTYPE_FIELD);
6550 if (!f) f = unpack_def(val, UPB_DEFTYPE_FIELD_JSONNAME);
6551
6552 return f;
6553 }
6554
upb_MessageDef_numfields(const upb_MessageDef * m)6555 int upb_MessageDef_numfields(const upb_MessageDef* m) { return m->field_count; }
6556
upb_MessageDef_numoneofs(const upb_MessageDef * m)6557 int upb_MessageDef_numoneofs(const upb_MessageDef* m) { return m->oneof_count; }
6558
upb_MessageDef_numrealoneofs(const upb_MessageDef * m)6559 int upb_MessageDef_numrealoneofs(const upb_MessageDef* m) {
6560 return m->real_oneof_count;
6561 }
6562
upb_MessageDef_ExtensionRangeCount(const upb_MessageDef * m)6563 int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m) {
6564 return m->ext_range_count;
6565 }
6566
upb_MessageDef_ReservedRangeCount(const upb_MessageDef * m)6567 int upb_MessageDef_ReservedRangeCount(const upb_MessageDef* m) {
6568 return m->res_range_count;
6569 }
6570
upb_MessageDef_ReservedNameCount(const upb_MessageDef * m)6571 int upb_MessageDef_ReservedNameCount(const upb_MessageDef* m) {
6572 return m->res_name_count;
6573 }
6574
upb_MessageDef_FieldCount(const upb_MessageDef * m)6575 int upb_MessageDef_FieldCount(const upb_MessageDef* m) {
6576 return m->field_count;
6577 }
6578
upb_MessageDef_OneofCount(const upb_MessageDef * m)6579 int upb_MessageDef_OneofCount(const upb_MessageDef* m) {
6580 return m->oneof_count;
6581 }
6582
upb_MessageDef_NestedMessageCount(const upb_MessageDef * m)6583 int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m) {
6584 return m->nested_msg_count;
6585 }
6586
upb_MessageDef_NestedEnumCount(const upb_MessageDef * m)6587 int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m) {
6588 return m->nested_enum_count;
6589 }
6590
upb_MessageDef_NestedExtensionCount(const upb_MessageDef * m)6591 int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m) {
6592 return m->nested_ext_count;
6593 }
6594
upb_MessageDef_realoneofcount(const upb_MessageDef * m)6595 int upb_MessageDef_realoneofcount(const upb_MessageDef* m) {
6596 return m->real_oneof_count;
6597 }
6598
upb_MessageDef_MiniTable(const upb_MessageDef * m)6599 const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m) {
6600 return m->layout;
6601 }
6602
upb_MessageDef_ExtensionRange(const upb_MessageDef * m,int i)6603 const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m,
6604 int i) {
6605 UPB_ASSERT(0 <= i && i < m->ext_range_count);
6606 return &m->ext_ranges[i];
6607 }
6608
_upb_MessageReservedRange_At(const upb_MessageReservedRange * r,int i)6609 upb_MessageReservedRange* _upb_MessageReservedRange_At(
6610 const upb_MessageReservedRange* r, int i) {
6611 return (upb_MessageReservedRange*)&r[i];
6612 }
6613
upb_MessageDef_ReservedRange(const upb_MessageDef * m,int i)6614 const upb_MessageReservedRange* upb_MessageDef_ReservedRange(
6615 const upb_MessageDef* m, int i) {
6616 UPB_ASSERT(0 <= i && i < m->res_range_count);
6617 return _upb_MessageReservedRange_At(m->res_ranges, i);
6618 }
6619
upb_MessageDef_ReservedName(const upb_MessageDef * m,int i)6620 upb_StringView upb_MessageDef_ReservedName(const upb_MessageDef* m, int i) {
6621 UPB_ASSERT(0 <= i && i < m->res_name_count);
6622 return m->res_names[i];
6623 }
6624
upb_MessageReservedRange_Start(const upb_MessageReservedRange * r)6625 int32_t upb_MessageReservedRange_Start(const upb_MessageReservedRange* r) {
6626 return r->start;
6627 }
upb_MessageReservedRange_End(const upb_MessageReservedRange * r)6628 int32_t upb_MessageReservedRange_End(const upb_MessageReservedRange* r) {
6629 return r->end;
6630 }
6631
_upb_MessageReservedRanges_New(symtab_addctx * ctx,int n,const google_protobuf_DescriptorProto_ReservedRange * const * protos,const upb_MessageDef * m)6632 upb_MessageReservedRange* _upb_MessageReservedRanges_New(
6633 symtab_addctx* ctx, int n,
6634 const google_protobuf_DescriptorProto_ReservedRange* const* protos,
6635 const upb_MessageDef* m) {
6636 upb_MessageReservedRange* r =
6637 upb_Arena_Malloc(ctx->arena, sizeof(upb_MessageReservedRange) * n);
6638
6639 for (int i = 0; i < n; i++) {
6640 const int32_t start = google_protobuf_DescriptorProto_ReservedRange_start(protos[i]);
6641 const int32_t end = google_protobuf_DescriptorProto_ReservedRange_end(protos[i]);
6642 const int32_t max = kUpb_MaxFieldNumber + 1;
6643
6644 // A full validation would also check that each range is disjoint, and that
6645 // none of the fields overlap with the extension ranges, but we are just
6646 // sanity checking here.
6647 if (start < 1 || end <= start || end > max) {
6648 symtab_errf(ctx,
6649 "Reserved range (%d, %d) is invalid, message=%s\n",
6650 (int)start, (int)end, upb_MessageDef_FullName(m));
6651 }
6652
6653 r[i].start = start;
6654 r[i].end = end;
6655 }
6656
6657 return r;
6658 }
6659
upb_MessageDef_Field(const upb_MessageDef * m,int i)6660 const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, int i) {
6661 UPB_ASSERT(0 <= i && i < m->field_count);
6662 return &m->fields[i];
6663 }
6664
upb_MessageDef_Oneof(const upb_MessageDef * m,int i)6665 const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, int i) {
6666 UPB_ASSERT(0 <= i && i < m->oneof_count);
6667 return &m->oneofs[i];
6668 }
6669
upb_MessageDef_NestedMessage(const upb_MessageDef * m,int i)6670 const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m,
6671 int i) {
6672 UPB_ASSERT(0 <= i && i < m->nested_msg_count);
6673 return &m->nested_msgs[i];
6674 }
6675
upb_MessageDef_NestedEnum(const upb_MessageDef * m,int i)6676 const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i) {
6677 UPB_ASSERT(0 <= i && i < m->nested_enum_count);
6678 return &m->nested_enums[i];
6679 }
6680
upb_MessageDef_NestedExtension(const upb_MessageDef * m,int i)6681 const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m,
6682 int i) {
6683 UPB_ASSERT(0 <= i && i < m->nested_ext_count);
6684 return &m->nested_exts[i];
6685 }
6686
upb_MessageDef_WellKnownType(const upb_MessageDef * m)6687 upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m) {
6688 return m->well_known_type;
6689 }
6690
6691 /* upb_OneofDef ***************************************************************/
6692
upb_OneofDef_Options(const upb_OneofDef * o)6693 const google_protobuf_OneofOptions* upb_OneofDef_Options(
6694 const upb_OneofDef* o) {
6695 return o->opts;
6696 }
6697
upb_OneofDef_HasOptions(const upb_OneofDef * o)6698 bool upb_OneofDef_HasOptions(const upb_OneofDef* o) {
6699 return o->opts != (void*)opt_default;
6700 }
6701
upb_OneofDef_Name(const upb_OneofDef * o)6702 const char* upb_OneofDef_Name(const upb_OneofDef* o) {
6703 return shortdefname(o->full_name);
6704 }
6705
upb_OneofDef_ContainingType(const upb_OneofDef * o)6706 const upb_MessageDef* upb_OneofDef_ContainingType(const upb_OneofDef* o) {
6707 return o->parent;
6708 }
6709
upb_OneofDef_FieldCount(const upb_OneofDef * o)6710 int upb_OneofDef_FieldCount(const upb_OneofDef* o) { return o->field_count; }
6711
upb_OneofDef_Field(const upb_OneofDef * o,int i)6712 const upb_FieldDef* upb_OneofDef_Field(const upb_OneofDef* o, int i) {
6713 UPB_ASSERT(i < o->field_count);
6714 return o->fields[i];
6715 }
6716
upb_OneofDef_numfields(const upb_OneofDef * o)6717 int upb_OneofDef_numfields(const upb_OneofDef* o) { return o->field_count; }
6718
upb_OneofDef_Index(const upb_OneofDef * o)6719 uint32_t upb_OneofDef_Index(const upb_OneofDef* o) {
6720 // Compute index in our parent's array.
6721 return o - o->parent->oneofs;
6722 }
6723
upb_OneofDef_IsSynthetic(const upb_OneofDef * o)6724 bool upb_OneofDef_IsSynthetic(const upb_OneofDef* o) { return o->synthetic; }
6725
upb_OneofDef_LookupNameWithSize(const upb_OneofDef * o,const char * name,size_t length)6726 const upb_FieldDef* upb_OneofDef_LookupNameWithSize(const upb_OneofDef* o,
6727 const char* name,
6728 size_t length) {
6729 upb_value val;
6730 return upb_strtable_lookup2(&o->ntof, name, length, &val)
6731 ? upb_value_getptr(val)
6732 : NULL;
6733 }
6734
upb_OneofDef_LookupNumber(const upb_OneofDef * o,uint32_t num)6735 const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o,
6736 uint32_t num) {
6737 upb_value val;
6738 return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val)
6739 : NULL;
6740 }
6741
6742 /* upb_FileDef ****************************************************************/
6743
upb_FileDef_Options(const upb_FileDef * f)6744 const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f) {
6745 return f->opts;
6746 }
6747
upb_FileDef_HasOptions(const upb_FileDef * f)6748 bool upb_FileDef_HasOptions(const upb_FileDef* f) {
6749 return f->opts != (void*)opt_default;
6750 }
6751
upb_FileDef_Name(const upb_FileDef * f)6752 const char* upb_FileDef_Name(const upb_FileDef* f) { return f->name; }
6753
upb_FileDef_Package(const upb_FileDef * f)6754 const char* upb_FileDef_Package(const upb_FileDef* f) {
6755 return f->package ? f->package : "";
6756 }
6757
upb_FileDef_Syntax(const upb_FileDef * f)6758 upb_Syntax upb_FileDef_Syntax(const upb_FileDef* f) { return f->syntax; }
6759
upb_FileDef_TopLevelMessageCount(const upb_FileDef * f)6760 int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f) {
6761 return f->top_lvl_msg_count;
6762 }
6763
upb_FileDef_DependencyCount(const upb_FileDef * f)6764 int upb_FileDef_DependencyCount(const upb_FileDef* f) { return f->dep_count; }
6765
upb_FileDef_PublicDependencyCount(const upb_FileDef * f)6766 int upb_FileDef_PublicDependencyCount(const upb_FileDef* f) {
6767 return f->public_dep_count;
6768 }
6769
upb_FileDef_WeakDependencyCount(const upb_FileDef * f)6770 int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) {
6771 return f->weak_dep_count;
6772 }
6773
_upb_FileDef_PublicDependencyIndexes(const upb_FileDef * f)6774 const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) {
6775 return f->public_deps;
6776 }
6777
_upb_FileDef_WeakDependencyIndexes(const upb_FileDef * f)6778 const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f) {
6779 return f->weak_deps;
6780 }
6781
upb_FileDef_TopLevelEnumCount(const upb_FileDef * f)6782 int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) {
6783 return f->top_lvl_enum_count;
6784 }
6785
upb_FileDef_TopLevelExtensionCount(const upb_FileDef * f)6786 int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f) {
6787 return f->top_lvl_ext_count;
6788 }
6789
upb_FileDef_ServiceCount(const upb_FileDef * f)6790 int upb_FileDef_ServiceCount(const upb_FileDef* f) { return f->service_count; }
6791
upb_FileDef_Dependency(const upb_FileDef * f,int i)6792 const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i) {
6793 UPB_ASSERT(0 <= i && i < f->dep_count);
6794 return f->deps[i];
6795 }
6796
upb_FileDef_PublicDependency(const upb_FileDef * f,int i)6797 const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i) {
6798 UPB_ASSERT(0 <= i && i < f->public_dep_count);
6799 return f->deps[f->public_deps[i]];
6800 }
6801
upb_FileDef_WeakDependency(const upb_FileDef * f,int i)6802 const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i) {
6803 UPB_ASSERT(0 <= i && i < f->public_dep_count);
6804 return f->deps[f->weak_deps[i]];
6805 }
6806
upb_FileDef_TopLevelMessage(const upb_FileDef * f,int i)6807 const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i) {
6808 UPB_ASSERT(0 <= i && i < f->top_lvl_msg_count);
6809 return &f->top_lvl_msgs[i];
6810 }
6811
upb_FileDef_TopLevelEnum(const upb_FileDef * f,int i)6812 const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i) {
6813 UPB_ASSERT(0 <= i && i < f->top_lvl_enum_count);
6814 return &f->top_lvl_enums[i];
6815 }
6816
upb_FileDef_TopLevelExtension(const upb_FileDef * f,int i)6817 const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i) {
6818 UPB_ASSERT(0 <= i && i < f->top_lvl_ext_count);
6819 return &f->top_lvl_exts[i];
6820 }
6821
upb_FileDef_Service(const upb_FileDef * f,int i)6822 const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i) {
6823 UPB_ASSERT(0 <= i && i < f->service_count);
6824 return &f->services[i];
6825 }
6826
upb_FileDef_Pool(const upb_FileDef * f)6827 const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f) { return f->symtab; }
6828
6829 /* upb_MethodDef **************************************************************/
6830
upb_MethodDef_Options(const upb_MethodDef * m)6831 const google_protobuf_MethodOptions* upb_MethodDef_Options(
6832 const upb_MethodDef* m) {
6833 return m->opts;
6834 }
6835
upb_MethodDef_HasOptions(const upb_MethodDef * m)6836 bool upb_MethodDef_HasOptions(const upb_MethodDef* m) {
6837 return m->opts != (void*)opt_default;
6838 }
6839
upb_MethodDef_FullName(const upb_MethodDef * m)6840 const char* upb_MethodDef_FullName(const upb_MethodDef* m) {
6841 return m->full_name;
6842 }
6843
upb_MethodDef_Index(const upb_MethodDef * m)6844 int upb_MethodDef_Index(const upb_MethodDef* m) { return m->index; }
6845
upb_MethodDef_Name(const upb_MethodDef * m)6846 const char* upb_MethodDef_Name(const upb_MethodDef* m) {
6847 return shortdefname(m->full_name);
6848 }
6849
upb_MethodDef_Service(const upb_MethodDef * m)6850 const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m) {
6851 return m->service;
6852 }
6853
upb_MethodDef_InputType(const upb_MethodDef * m)6854 const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m) {
6855 return m->input_type;
6856 }
6857
upb_MethodDef_OutputType(const upb_MethodDef * m)6858 const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m) {
6859 return m->output_type;
6860 }
6861
upb_MethodDef_ClientStreaming(const upb_MethodDef * m)6862 bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m) {
6863 return m->client_streaming;
6864 }
6865
upb_MethodDef_ServerStreaming(const upb_MethodDef * m)6866 bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m) {
6867 return m->server_streaming;
6868 }
6869
6870 /* upb_ServiceDef *************************************************************/
6871
upb_ServiceDef_Options(const upb_ServiceDef * s)6872 const google_protobuf_ServiceOptions* upb_ServiceDef_Options(
6873 const upb_ServiceDef* s) {
6874 return s->opts;
6875 }
6876
upb_ServiceDef_HasOptions(const upb_ServiceDef * s)6877 bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s) {
6878 return s->opts != (void*)opt_default;
6879 }
6880
upb_ServiceDef_FullName(const upb_ServiceDef * s)6881 const char* upb_ServiceDef_FullName(const upb_ServiceDef* s) {
6882 return s->full_name;
6883 }
6884
upb_ServiceDef_Name(const upb_ServiceDef * s)6885 const char* upb_ServiceDef_Name(const upb_ServiceDef* s) {
6886 return shortdefname(s->full_name);
6887 }
6888
upb_ServiceDef_Index(const upb_ServiceDef * s)6889 int upb_ServiceDef_Index(const upb_ServiceDef* s) { return s->index; }
6890
upb_ServiceDef_File(const upb_ServiceDef * s)6891 const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s) {
6892 return s->file;
6893 }
6894
upb_ServiceDef_MethodCount(const upb_ServiceDef * s)6895 int upb_ServiceDef_MethodCount(const upb_ServiceDef* s) {
6896 return s->method_count;
6897 }
6898
upb_ServiceDef_Method(const upb_ServiceDef * s,int i)6899 const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i) {
6900 return i < 0 || i >= s->method_count ? NULL : &s->methods[i];
6901 }
6902
upb_ServiceDef_FindMethodByName(const upb_ServiceDef * s,const char * name)6903 const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s,
6904 const char* name) {
6905 for (int i = 0; i < s->method_count; i++) {
6906 if (strcmp(name, upb_MethodDef_Name(&s->methods[i])) == 0) {
6907 return &s->methods[i];
6908 }
6909 }
6910 return NULL;
6911 }
6912
6913 /* upb_DefPool ****************************************************************/
6914
upb_DefPool_Free(upb_DefPool * s)6915 void upb_DefPool_Free(upb_DefPool* s) {
6916 upb_Arena_Free(s->arena);
6917 upb_gfree(s);
6918 }
6919
upb_DefPool_New(void)6920 upb_DefPool* upb_DefPool_New(void) {
6921 upb_DefPool* s = upb_gmalloc(sizeof(*s));
6922
6923 if (!s) {
6924 return NULL;
6925 }
6926
6927 s->arena = upb_Arena_New();
6928 s->bytes_loaded = 0;
6929
6930 if (!upb_strtable_init(&s->syms, 32, s->arena) ||
6931 !upb_strtable_init(&s->files, 4, s->arena) ||
6932 !upb_inttable_init(&s->exts, s->arena)) {
6933 goto err;
6934 }
6935
6936 s->extreg = upb_ExtensionRegistry_New(s->arena);
6937 if (!s->extreg) goto err;
6938 return s;
6939
6940 err:
6941 upb_Arena_Free(s->arena);
6942 upb_gfree(s);
6943 return NULL;
6944 }
6945
symtab_lookup(const upb_DefPool * s,const char * sym,upb_deftype_t type)6946 static const void* symtab_lookup(const upb_DefPool* s, const char* sym,
6947 upb_deftype_t type) {
6948 upb_value v;
6949 return upb_strtable_lookup(&s->syms, sym, &v) ? unpack_def(v, type) : NULL;
6950 }
6951
symtab_lookup2(const upb_DefPool * s,const char * sym,size_t size,upb_deftype_t type)6952 static const void* symtab_lookup2(const upb_DefPool* s, const char* sym,
6953 size_t size, upb_deftype_t type) {
6954 upb_value v;
6955 return upb_strtable_lookup2(&s->syms, sym, size, &v) ? unpack_def(v, type)
6956 : NULL;
6957 }
6958
upb_DefPool_FindMessageByName(const upb_DefPool * s,const char * sym)6959 const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s,
6960 const char* sym) {
6961 return symtab_lookup(s, sym, UPB_DEFTYPE_MSG);
6962 }
6963
upb_DefPool_FindMessageByNameWithSize(const upb_DefPool * s,const char * sym,size_t len)6964 const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize(
6965 const upb_DefPool* s, const char* sym, size_t len) {
6966 return symtab_lookup2(s, sym, len, UPB_DEFTYPE_MSG);
6967 }
6968
upb_DefPool_FindEnumByName(const upb_DefPool * s,const char * sym)6969 const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s,
6970 const char* sym) {
6971 return symtab_lookup(s, sym, UPB_DEFTYPE_ENUM);
6972 }
6973
upb_DefPool_FindEnumByNameval(const upb_DefPool * s,const char * sym)6974 const upb_EnumValueDef* upb_DefPool_FindEnumByNameval(const upb_DefPool* s,
6975 const char* sym) {
6976 return symtab_lookup(s, sym, UPB_DEFTYPE_ENUMVAL);
6977 }
6978
upb_DefPool_FindFileByName(const upb_DefPool * s,const char * name)6979 const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s,
6980 const char* name) {
6981 upb_value v;
6982 return upb_strtable_lookup(&s->files, name, &v)
6983 ? unpack_def(v, UPB_DEFTYPE_FILE)
6984 : NULL;
6985 }
6986
upb_DefPool_FindFileByNameWithSize(const upb_DefPool * s,const char * name,size_t len)6987 const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s,
6988 const char* name,
6989 size_t len) {
6990 upb_value v;
6991 return upb_strtable_lookup2(&s->files, name, len, &v)
6992 ? unpack_def(v, UPB_DEFTYPE_FILE)
6993 : NULL;
6994 }
6995
upb_DefPool_FindExtensionByNameWithSize(const upb_DefPool * s,const char * name,size_t size)6996 const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize(
6997 const upb_DefPool* s, const char* name, size_t size) {
6998 upb_value v;
6999 if (!upb_strtable_lookup2(&s->syms, name, size, &v)) return NULL;
7000
7001 switch (deftype(v)) {
7002 case UPB_DEFTYPE_FIELD:
7003 return unpack_def(v, UPB_DEFTYPE_FIELD);
7004 case UPB_DEFTYPE_MSG: {
7005 const upb_MessageDef* m = unpack_def(v, UPB_DEFTYPE_MSG);
7006 return m->in_message_set ? &m->nested_exts[0] : NULL;
7007 }
7008 default:
7009 break;
7010 }
7011
7012 return NULL;
7013 }
7014
upb_DefPool_FindExtensionByName(const upb_DefPool * s,const char * sym)7015 const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s,
7016 const char* sym) {
7017 return upb_DefPool_FindExtensionByNameWithSize(s, sym, strlen(sym));
7018 }
7019
upb_DefPool_FindServiceByName(const upb_DefPool * s,const char * name)7020 const upb_ServiceDef* upb_DefPool_FindServiceByName(const upb_DefPool* s,
7021 const char* name) {
7022 return symtab_lookup(s, name, UPB_DEFTYPE_SERVICE);
7023 }
7024
upb_DefPool_FindServiceByNameWithSize(const upb_DefPool * s,const char * name,size_t size)7025 const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize(
7026 const upb_DefPool* s, const char* name, size_t size) {
7027 return symtab_lookup2(s, name, size, UPB_DEFTYPE_SERVICE);
7028 }
7029
upb_DefPool_FindFileContainingSymbol(const upb_DefPool * s,const char * name)7030 const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s,
7031 const char* name) {
7032 upb_value v;
7033 // TODO(haberman): non-extension fields and oneofs.
7034 if (upb_strtable_lookup(&s->syms, name, &v)) {
7035 switch (deftype(v)) {
7036 case UPB_DEFTYPE_EXT: {
7037 const upb_FieldDef* f = unpack_def(v, UPB_DEFTYPE_EXT);
7038 return upb_FieldDef_File(f);
7039 }
7040 case UPB_DEFTYPE_MSG: {
7041 const upb_MessageDef* m = unpack_def(v, UPB_DEFTYPE_MSG);
7042 return upb_MessageDef_File(m);
7043 }
7044 case UPB_DEFTYPE_ENUM: {
7045 const upb_EnumDef* e = unpack_def(v, UPB_DEFTYPE_ENUM);
7046 return upb_EnumDef_File(e);
7047 }
7048 case UPB_DEFTYPE_ENUMVAL: {
7049 const upb_EnumValueDef* ev = unpack_def(v, UPB_DEFTYPE_ENUMVAL);
7050 return upb_EnumDef_File(upb_EnumValueDef_Enum(ev));
7051 }
7052 case UPB_DEFTYPE_SERVICE: {
7053 const upb_ServiceDef* service = unpack_def(v, UPB_DEFTYPE_SERVICE);
7054 return upb_ServiceDef_File(service);
7055 }
7056 default:
7057 UPB_UNREACHABLE();
7058 }
7059 }
7060
7061 const char* last_dot = strrchr(name, '.');
7062 if (last_dot) {
7063 const upb_MessageDef* parent =
7064 upb_DefPool_FindMessageByNameWithSize(s, name, last_dot - name);
7065 if (parent) {
7066 const char* shortname = last_dot + 1;
7067 if (upb_MessageDef_FindByNameWithSize(parent, shortname,
7068 strlen(shortname), NULL, NULL)) {
7069 return upb_MessageDef_File(parent);
7070 }
7071 }
7072 }
7073
7074 return NULL;
7075 }
7076
7077 /* Code to build defs from descriptor protos. *********************************/
7078
7079 /* There is a question of how much validation to do here. It will be difficult
7080 * to perfectly match the amount of validation performed by proto2. But since
7081 * this code is used to directly build defs from Ruby (for example) we do need
7082 * to validate important constraints like uniqueness of names and numbers. */
7083
7084 #define CHK_OOM(x) \
7085 if (!(x)) { \
7086 symtab_oomerr(ctx); \
7087 }
7088
symtab_oomerr(symtab_addctx * ctx)7089 UPB_NORETURN UPB_NOINLINE static void symtab_oomerr(symtab_addctx* ctx) {
7090 upb_Status_setoom(ctx->status);
7091 UPB_LONGJMP(ctx->err, 1);
7092 }
7093
symtab_alloc(symtab_addctx * ctx,size_t bytes)7094 void* symtab_alloc(symtab_addctx* ctx, size_t bytes) {
7095 if (bytes == 0) return NULL;
7096 void* ret = upb_Arena_Malloc(ctx->arena, bytes);
7097 if (!ret) symtab_oomerr(ctx);
7098 return ret;
7099 }
7100
7101 // We want to copy the options verbatim into the destination options proto.
7102 // We use serialize+parse as our deep copy.
7103 #define SET_OPTIONS(target, desc_type, options_type, proto) \
7104 if (google_protobuf_##desc_type##_has_options(proto)) { \
7105 size_t size; \
7106 char* pb = google_protobuf_##options_type##_serialize( \
7107 google_protobuf_##desc_type##_options(proto), ctx->tmp_arena, &size); \
7108 CHK_OOM(pb); \
7109 target = google_protobuf_##options_type##_parse(pb, size, ctx->arena); \
7110 CHK_OOM(target); \
7111 } else { \
7112 target = (const google_protobuf_##options_type*)opt_default; \
7113 }
7114
check_ident(symtab_addctx * ctx,upb_StringView name,bool full)7115 static void check_ident(symtab_addctx* ctx, upb_StringView name, bool full) {
7116 const char* str = name.data;
7117 size_t len = name.size;
7118 bool start = true;
7119 size_t i;
7120 for (i = 0; i < len; i++) {
7121 char c = str[i];
7122 if (c == '.') {
7123 if (start || !full) {
7124 symtab_errf(ctx, "invalid name: unexpected '.' (%.*s)", (int)len, str);
7125 }
7126 start = true;
7127 } else if (start) {
7128 if (!upb_isletter(c)) {
7129 symtab_errf(
7130 ctx,
7131 "invalid name: path components must start with a letter (%.*s)",
7132 (int)len, str);
7133 }
7134 start = false;
7135 } else {
7136 if (!upb_isalphanum(c)) {
7137 symtab_errf(ctx, "invalid name: non-alphanumeric character (%.*s)",
7138 (int)len, str);
7139 }
7140 }
7141 }
7142 if (start) {
7143 symtab_errf(ctx, "invalid name: empty part (%.*s)", (int)len, str);
7144 }
7145 }
7146
div_round_up(size_t n,size_t d)7147 static size_t div_round_up(size_t n, size_t d) { return (n + d - 1) / d; }
7148
upb_MessageValue_sizeof(upb_CType type)7149 static size_t upb_MessageValue_sizeof(upb_CType type) {
7150 switch (type) {
7151 case kUpb_CType_Double:
7152 case kUpb_CType_Int64:
7153 case kUpb_CType_UInt64:
7154 return 8;
7155 case kUpb_CType_Enum:
7156 case kUpb_CType_Int32:
7157 case kUpb_CType_UInt32:
7158 case kUpb_CType_Float:
7159 return 4;
7160 case kUpb_CType_Bool:
7161 return 1;
7162 case kUpb_CType_Message:
7163 return sizeof(void*);
7164 case kUpb_CType_Bytes:
7165 case kUpb_CType_String:
7166 return sizeof(upb_StringView);
7167 }
7168 UPB_UNREACHABLE();
7169 }
7170
upb_msg_fielddefsize(const upb_FieldDef * f)7171 static uint8_t upb_msg_fielddefsize(const upb_FieldDef* f) {
7172 if (upb_MessageDef_IsMapEntry(upb_FieldDef_ContainingType(f))) {
7173 upb_MapEntry ent;
7174 UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v));
7175 return sizeof(ent.k);
7176 } else if (upb_FieldDef_IsRepeated(f)) {
7177 return sizeof(void*);
7178 } else {
7179 return upb_MessageValue_sizeof(upb_FieldDef_CType(f));
7180 }
7181 }
7182
upb_MiniTable_place(symtab_addctx * ctx,upb_MiniTable * l,size_t size,const upb_MessageDef * m)7183 static uint32_t upb_MiniTable_place(symtab_addctx* ctx, upb_MiniTable* l,
7184 size_t size, const upb_MessageDef* m) {
7185 size_t ofs = UPB_ALIGN_UP(l->size, size);
7186 size_t next = ofs + size;
7187
7188 if (next > UINT16_MAX) {
7189 symtab_errf(ctx, "size of message %s exceeded max size of %zu bytes",
7190 upb_MessageDef_FullName(m), (size_t)UINT16_MAX);
7191 }
7192
7193 l->size = next;
7194 return ofs;
7195 }
7196
field_number_cmp(const void * p1,const void * p2)7197 static int field_number_cmp(const void* p1, const void* p2) {
7198 const upb_MiniTable_Field* f1 = p1;
7199 const upb_MiniTable_Field* f2 = p2;
7200 return f1->number - f2->number;
7201 }
7202
assign_layout_indices(const upb_MessageDef * m,upb_MiniTable * l,upb_MiniTable_Field * fields)7203 static void assign_layout_indices(const upb_MessageDef* m, upb_MiniTable* l,
7204 upb_MiniTable_Field* fields) {
7205 int i;
7206 int n = upb_MessageDef_numfields(m);
7207 int dense_below = 0;
7208 for (i = 0; i < n; i++) {
7209 upb_FieldDef* f =
7210 (upb_FieldDef*)upb_MessageDef_FindFieldByNumber(m, fields[i].number);
7211 UPB_ASSERT(f);
7212 f->layout_index = i;
7213 if (i < UINT8_MAX && fields[i].number == i + 1 &&
7214 (i == 0 || fields[i - 1].number == i)) {
7215 dense_below = i + 1;
7216 }
7217 }
7218 l->dense_below = dense_below;
7219 }
7220
map_descriptortype(const upb_FieldDef * f)7221 static uint8_t map_descriptortype(const upb_FieldDef* f) {
7222 uint8_t type = upb_FieldDef_Type(f);
7223 /* See TableDescriptorType() in upbc/generator.cc for details and
7224 * rationale of these exceptions. */
7225 if (type == kUpb_FieldType_String && f->file->syntax == kUpb_Syntax_Proto2) {
7226 return kUpb_FieldType_Bytes;
7227 } else if (type == kUpb_FieldType_Enum &&
7228 (f->sub.enumdef->file->syntax == kUpb_Syntax_Proto3 ||
7229 UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 ||
7230 // TODO(https://github.com/protocolbuffers/upb/issues/541):
7231 // fix map enum values to check for unknown enum values and put
7232 // them in the unknown field set.
7233 upb_MessageDef_IsMapEntry(upb_FieldDef_ContainingType(f)))) {
7234 return kUpb_FieldType_Int32;
7235 }
7236 return type;
7237 }
7238
fill_fieldlayout(upb_MiniTable_Field * field,const upb_FieldDef * f)7239 static void fill_fieldlayout(upb_MiniTable_Field* field,
7240 const upb_FieldDef* f) {
7241 field->number = upb_FieldDef_Number(f);
7242 field->descriptortype = map_descriptortype(f);
7243
7244 if (upb_FieldDef_IsMap(f)) {
7245 field->mode =
7246 kUpb_FieldMode_Map | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift);
7247 } else if (upb_FieldDef_IsRepeated(f)) {
7248 field->mode =
7249 kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift);
7250 } else {
7251 /* Maps descriptor type -> elem_size_lg2. */
7252 static const uint8_t sizes[] = {
7253 -1, /* invalid descriptor type */
7254 kUpb_FieldRep_8Byte, /* DOUBLE */
7255 kUpb_FieldRep_4Byte, /* FLOAT */
7256 kUpb_FieldRep_8Byte, /* INT64 */
7257 kUpb_FieldRep_8Byte, /* UINT64 */
7258 kUpb_FieldRep_4Byte, /* INT32 */
7259 kUpb_FieldRep_8Byte, /* FIXED64 */
7260 kUpb_FieldRep_4Byte, /* FIXED32 */
7261 kUpb_FieldRep_1Byte, /* BOOL */
7262 kUpb_FieldRep_StringView, /* STRING */
7263 kUpb_FieldRep_Pointer, /* GROUP */
7264 kUpb_FieldRep_Pointer, /* MESSAGE */
7265 kUpb_FieldRep_StringView, /* BYTES */
7266 kUpb_FieldRep_4Byte, /* UINT32 */
7267 kUpb_FieldRep_4Byte, /* ENUM */
7268 kUpb_FieldRep_4Byte, /* SFIXED32 */
7269 kUpb_FieldRep_8Byte, /* SFIXED64 */
7270 kUpb_FieldRep_4Byte, /* SINT32 */
7271 kUpb_FieldRep_8Byte, /* SINT64 */
7272 };
7273 field->mode = kUpb_FieldMode_Scalar |
7274 (sizes[field->descriptortype] << kUpb_FieldRep_Shift);
7275 }
7276
7277 if (upb_FieldDef_IsPacked(f)) {
7278 field->mode |= kUpb_LabelFlags_IsPacked;
7279 }
7280
7281 if (upb_FieldDef_IsExtension(f)) {
7282 field->mode |= kUpb_LabelFlags_IsExtension;
7283 }
7284 }
7285
7286 /* This function is the dynamic equivalent of message_layout.{cc,h} in upbc.
7287 * It computes a dynamic layout for all of the fields in |m|. */
make_layout(symtab_addctx * ctx,const upb_MessageDef * m)7288 static void make_layout(symtab_addctx* ctx, const upb_MessageDef* m) {
7289 upb_MiniTable* l = (upb_MiniTable*)m->layout;
7290 size_t field_count = upb_MessageDef_numfields(m);
7291 size_t sublayout_count = 0;
7292 upb_MiniTable_Sub* subs;
7293 upb_MiniTable_Field* fields;
7294
7295 memset(l, 0, sizeof(*l) + sizeof(_upb_FastTable_Entry));
7296
7297 /* Count sub-messages. */
7298 for (size_t i = 0; i < field_count; i++) {
7299 const upb_FieldDef* f = &m->fields[i];
7300 if (upb_FieldDef_IsSubMessage(f)) {
7301 sublayout_count++;
7302 }
7303 if (upb_FieldDef_CType(f) == kUpb_CType_Enum &&
7304 f->sub.enumdef->file->syntax == kUpb_Syntax_Proto2) {
7305 sublayout_count++;
7306 }
7307 }
7308
7309 fields = symtab_alloc(ctx, field_count * sizeof(*fields));
7310 subs = symtab_alloc(ctx, sublayout_count * sizeof(*subs));
7311
7312 l->field_count = upb_MessageDef_numfields(m);
7313 l->fields = fields;
7314 l->subs = subs;
7315 l->table_mask = 0;
7316 l->required_count = 0;
7317
7318 if (upb_MessageDef_ExtensionRangeCount(m) > 0) {
7319 if (google_protobuf_MessageOptions_message_set_wire_format(m->opts)) {
7320 l->ext = kUpb_ExtMode_IsMessageSet;
7321 } else {
7322 l->ext = kUpb_ExtMode_Extendable;
7323 }
7324 } else {
7325 l->ext = kUpb_ExtMode_NonExtendable;
7326 }
7327
7328 /* TODO(haberman): initialize fast tables so that reflection-based parsing
7329 * can get the same speeds as linked-in types. */
7330 l->fasttable[0].field_parser = &fastdecode_generic;
7331 l->fasttable[0].field_data = 0;
7332
7333 if (upb_MessageDef_IsMapEntry(m)) {
7334 /* TODO(haberman): refactor this method so this special case is more
7335 * elegant. */
7336 const upb_FieldDef* key = upb_MessageDef_FindFieldByNumber(m, 1);
7337 const upb_FieldDef* val = upb_MessageDef_FindFieldByNumber(m, 2);
7338 if (key == NULL || val == NULL) {
7339 symtab_errf(ctx, "Malformed map entry from message: %s",
7340 upb_MessageDef_FullName(m));
7341 }
7342 fields[0].number = 1;
7343 fields[1].number = 2;
7344 fields[0].mode = kUpb_FieldMode_Scalar;
7345 fields[1].mode = kUpb_FieldMode_Scalar;
7346 fields[0].presence = 0;
7347 fields[1].presence = 0;
7348 fields[0].descriptortype = map_descriptortype(key);
7349 fields[1].descriptortype = map_descriptortype(val);
7350 fields[0].offset = 0;
7351 fields[1].offset = sizeof(upb_StringView);
7352 fields[1].submsg_index = 0;
7353
7354 if (upb_FieldDef_CType(val) == kUpb_CType_Message) {
7355 subs[0].submsg = upb_FieldDef_MessageSubDef(val)->layout;
7356 }
7357
7358 upb_FieldDef* fielddefs = (upb_FieldDef*)&m->fields[0];
7359 UPB_ASSERT(fielddefs[0].number_ == 1);
7360 UPB_ASSERT(fielddefs[1].number_ == 2);
7361 fielddefs[0].layout_index = 0;
7362 fielddefs[1].layout_index = 1;
7363
7364 l->field_count = 2;
7365 l->size = 2 * sizeof(upb_StringView);
7366 l->size = UPB_ALIGN_UP(l->size, 8);
7367 l->dense_below = 2;
7368 return;
7369 }
7370
7371 /* Allocate data offsets in three stages:
7372 *
7373 * 1. hasbits.
7374 * 2. regular fields.
7375 * 3. oneof fields.
7376 *
7377 * OPT: There is a lot of room for optimization here to minimize the size.
7378 */
7379
7380 /* Assign hasbits for required fields first. */
7381 size_t hasbit = 0;
7382
7383 for (int i = 0; i < m->field_count; i++) {
7384 const upb_FieldDef* f = &m->fields[i];
7385 upb_MiniTable_Field* field = &fields[upb_FieldDef_Index(f)];
7386 if (upb_FieldDef_Label(f) == kUpb_Label_Required) {
7387 field->presence = ++hasbit;
7388 if (hasbit >= 63) {
7389 symtab_errf(ctx, "Message with >=63 required fields: %s",
7390 upb_MessageDef_FullName(m));
7391 }
7392 l->required_count++;
7393 }
7394 }
7395
7396 /* Allocate hasbits and set basic field attributes. */
7397 sublayout_count = 0;
7398 for (int i = 0; i < m->field_count; i++) {
7399 const upb_FieldDef* f = &m->fields[i];
7400 upb_MiniTable_Field* field = &fields[upb_FieldDef_Index(f)];
7401
7402 fill_fieldlayout(field, f);
7403
7404 if (field->descriptortype == kUpb_FieldType_Message ||
7405 field->descriptortype == kUpb_FieldType_Group) {
7406 field->submsg_index = sublayout_count++;
7407 subs[field->submsg_index].submsg = upb_FieldDef_MessageSubDef(f)->layout;
7408 } else if (field->descriptortype == kUpb_FieldType_Enum) {
7409 field->submsg_index = sublayout_count++;
7410 subs[field->submsg_index].subenum = upb_FieldDef_EnumSubDef(f)->layout;
7411 UPB_ASSERT(subs[field->submsg_index].subenum);
7412 }
7413
7414 if (upb_FieldDef_Label(f) == kUpb_Label_Required) {
7415 /* Hasbit was already assigned. */
7416 } else if (upb_FieldDef_HasPresence(f) &&
7417 !upb_FieldDef_RealContainingOneof(f)) {
7418 /* We don't use hasbit 0, so that 0 can indicate "no presence" in the
7419 * table. This wastes one hasbit, but we don't worry about it for now. */
7420 field->presence = ++hasbit;
7421 } else {
7422 field->presence = 0;
7423 }
7424 }
7425
7426 /* Account for space used by hasbits. */
7427 l->size = hasbit ? div_round_up(hasbit + 1, 8) : 0;
7428
7429 /* Allocate non-oneof fields. */
7430 for (int i = 0; i < m->field_count; i++) {
7431 const upb_FieldDef* f = &m->fields[i];
7432 size_t field_size = upb_msg_fielddefsize(f);
7433 size_t index = upb_FieldDef_Index(f);
7434
7435 if (upb_FieldDef_RealContainingOneof(f)) {
7436 /* Oneofs are handled separately below. */
7437 continue;
7438 }
7439
7440 fields[index].offset = upb_MiniTable_place(ctx, l, field_size, m);
7441 }
7442
7443 /* Allocate oneof fields. Each oneof field consists of a uint32 for the case
7444 * and space for the actual data. */
7445 for (int i = 0; i < m->oneof_count; i++) {
7446 const upb_OneofDef* o = &m->oneofs[i];
7447 size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
7448 size_t field_size = 0;
7449 uint32_t case_offset;
7450 uint32_t data_offset;
7451
7452 if (upb_OneofDef_IsSynthetic(o)) continue;
7453
7454 if (o->field_count == 0) {
7455 symtab_errf(ctx, "Oneof must have at least one field (%s)", o->full_name);
7456 }
7457
7458 /* Calculate field size: the max of all field sizes. */
7459 for (int j = 0; j < o->field_count; j++) {
7460 const upb_FieldDef* f = o->fields[j];
7461 field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
7462 }
7463
7464 /* Align and allocate case offset. */
7465 case_offset = upb_MiniTable_place(ctx, l, case_size, m);
7466 data_offset = upb_MiniTable_place(ctx, l, field_size, m);
7467
7468 for (int i = 0; i < o->field_count; i++) {
7469 const upb_FieldDef* f = o->fields[i];
7470 fields[upb_FieldDef_Index(f)].offset = data_offset;
7471 fields[upb_FieldDef_Index(f)].presence = ~case_offset;
7472 }
7473 }
7474
7475 /* Size of the entire structure should be a multiple of its greatest
7476 * alignment. TODO: track overall alignment for real? */
7477 l->size = UPB_ALIGN_UP(l->size, 8);
7478
7479 /* Sort fields by number. */
7480 if (fields) {
7481 qsort(fields, upb_MessageDef_numfields(m), sizeof(*fields),
7482 field_number_cmp);
7483 }
7484 assign_layout_indices(m, l, fields);
7485 }
7486
strviewdup(symtab_addctx * ctx,upb_StringView view)7487 static char* strviewdup(symtab_addctx* ctx, upb_StringView view) {
7488 char* ret = upb_strdup2(view.data, view.size, ctx->arena);
7489 CHK_OOM(ret);
7490 return ret;
7491 }
7492
streql2(const char * a,size_t n,const char * b)7493 static bool streql2(const char* a, size_t n, const char* b) {
7494 return n == strlen(b) && memcmp(a, b, n) == 0;
7495 }
7496
streql_view(upb_StringView view,const char * b)7497 static bool streql_view(upb_StringView view, const char* b) {
7498 return streql2(view.data, view.size, b);
7499 }
7500
makefullname(symtab_addctx * ctx,const char * prefix,upb_StringView name)7501 static const char* makefullname(symtab_addctx* ctx, const char* prefix,
7502 upb_StringView name) {
7503 if (prefix) {
7504 /* ret = prefix + '.' + name; */
7505 size_t n = strlen(prefix);
7506 char* ret = symtab_alloc(ctx, n + name.size + 2);
7507 strcpy(ret, prefix);
7508 ret[n] = '.';
7509 memcpy(&ret[n + 1], name.data, name.size);
7510 ret[n + 1 + name.size] = '\0';
7511 return ret;
7512 } else {
7513 return strviewdup(ctx, name);
7514 }
7515 }
7516
finalize_oneofs(symtab_addctx * ctx,upb_MessageDef * m)7517 static void finalize_oneofs(symtab_addctx* ctx, upb_MessageDef* m) {
7518 int i;
7519 int synthetic_count = 0;
7520 upb_OneofDef* mutable_oneofs = (upb_OneofDef*)m->oneofs;
7521
7522 for (i = 0; i < m->oneof_count; i++) {
7523 upb_OneofDef* o = &mutable_oneofs[i];
7524
7525 if (o->synthetic && o->field_count != 1) {
7526 symtab_errf(ctx, "Synthetic oneofs must have one field, not %d: %s",
7527 o->field_count, upb_OneofDef_Name(o));
7528 }
7529
7530 if (o->synthetic) {
7531 synthetic_count++;
7532 } else if (synthetic_count != 0) {
7533 symtab_errf(ctx, "Synthetic oneofs must be after all other oneofs: %s",
7534 upb_OneofDef_Name(o));
7535 }
7536
7537 o->fields = symtab_alloc(ctx, sizeof(upb_FieldDef*) * o->field_count);
7538 o->field_count = 0;
7539 }
7540
7541 for (i = 0; i < m->field_count; i++) {
7542 const upb_FieldDef* f = &m->fields[i];
7543 upb_OneofDef* o = (upb_OneofDef*)upb_FieldDef_ContainingOneof(f);
7544 if (o) {
7545 o->fields[o->field_count++] = f;
7546 }
7547 }
7548
7549 m->real_oneof_count = m->oneof_count - synthetic_count;
7550 }
7551
getjsonname(const char * name,char * buf,size_t len)7552 size_t getjsonname(const char* name, char* buf, size_t len) {
7553 size_t src, dst = 0;
7554 bool ucase_next = false;
7555
7556 #define WRITE(byte) \
7557 ++dst; \
7558 if (dst < len) \
7559 buf[dst - 1] = byte; \
7560 else if (dst == len) \
7561 buf[dst - 1] = '\0'
7562
7563 if (!name) {
7564 WRITE('\0');
7565 return 0;
7566 }
7567
7568 /* Implement the transformation as described in the spec:
7569 * 1. upper case all letters after an underscore.
7570 * 2. remove all underscores.
7571 */
7572 for (src = 0; name[src]; src++) {
7573 if (name[src] == '_') {
7574 ucase_next = true;
7575 continue;
7576 }
7577
7578 if (ucase_next) {
7579 WRITE(toupper(name[src]));
7580 ucase_next = false;
7581 } else {
7582 WRITE(name[src]);
7583 }
7584 }
7585
7586 WRITE('\0');
7587 return dst;
7588
7589 #undef WRITE
7590 }
7591
makejsonname(symtab_addctx * ctx,const char * name)7592 static char* makejsonname(symtab_addctx* ctx, const char* name) {
7593 size_t size = getjsonname(name, NULL, 0);
7594 char* json_name = symtab_alloc(ctx, size);
7595 getjsonname(name, json_name, size);
7596 return json_name;
7597 }
7598
7599 /* Adds a symbol |v| to the symtab, which must be a def pointer previously
7600 * packed with pack_def(). The def's pointer to upb_FileDef* must be set before
7601 * adding, so we know which entries to remove if building this file fails. */
symtab_add(symtab_addctx * ctx,const char * name,upb_value v)7602 static void symtab_add(symtab_addctx* ctx, const char* name, upb_value v) {
7603 // TODO: table should support an operation "tryinsert" to avoid the double
7604 // lookup.
7605 if (upb_strtable_lookup(&ctx->symtab->syms, name, NULL)) {
7606 symtab_errf(ctx, "duplicate symbol '%s'", name);
7607 }
7608 size_t len = strlen(name);
7609 CHK_OOM(upb_strtable_insert(&ctx->symtab->syms, name, len, v,
7610 ctx->symtab->arena));
7611 }
7612
remove_component(char * base,size_t * len)7613 static bool remove_component(char* base, size_t* len) {
7614 if (*len == 0) return false;
7615
7616 for (size_t i = *len - 1; i > 0; i--) {
7617 if (base[i] == '.') {
7618 *len = i;
7619 return true;
7620 }
7621 }
7622
7623 *len = 0;
7624 return true;
7625 }
7626
7627 /* Given a symbol and the base symbol inside which it is defined, find the
7628 * symbol's definition in t. */
symtab_resolveany(symtab_addctx * ctx,const char * from_name_dbg,const char * base,upb_StringView sym,upb_deftype_t * type)7629 static const void* symtab_resolveany(symtab_addctx* ctx,
7630 const char* from_name_dbg,
7631 const char* base, upb_StringView sym,
7632 upb_deftype_t* type) {
7633 const upb_strtable* t = &ctx->symtab->syms;
7634 if (sym.size == 0) goto notfound;
7635 upb_value v;
7636 if (sym.data[0] == '.') {
7637 /* Symbols starting with '.' are absolute, so we do a single lookup.
7638 * Slice to omit the leading '.' */
7639 if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) {
7640 goto notfound;
7641 }
7642 } else {
7643 /* Remove components from base until we find an entry or run out. */
7644 size_t baselen = base ? strlen(base) : 0;
7645 char* tmp = malloc(sym.size + baselen + 1);
7646 while (1) {
7647 char* p = tmp;
7648 if (baselen) {
7649 memcpy(p, base, baselen);
7650 p[baselen] = '.';
7651 p += baselen + 1;
7652 }
7653 memcpy(p, sym.data, sym.size);
7654 p += sym.size;
7655 if (upb_strtable_lookup2(t, tmp, p - tmp, &v)) {
7656 break;
7657 }
7658 if (!remove_component(tmp, &baselen)) {
7659 free(tmp);
7660 goto notfound;
7661 }
7662 }
7663 free(tmp);
7664 }
7665
7666 *type = deftype(v);
7667 return unpack_def(v, *type);
7668
7669 notfound:
7670 symtab_errf(ctx, "couldn't resolve name '" UPB_STRINGVIEW_FORMAT "'",
7671 UPB_STRINGVIEW_ARGS(sym));
7672 }
7673
symtab_resolve(symtab_addctx * ctx,const char * from_name_dbg,const char * base,upb_StringView sym,upb_deftype_t type)7674 static const void* symtab_resolve(symtab_addctx* ctx, const char* from_name_dbg,
7675 const char* base, upb_StringView sym,
7676 upb_deftype_t type) {
7677 upb_deftype_t found_type;
7678 const void* ret =
7679 symtab_resolveany(ctx, from_name_dbg, base, sym, &found_type);
7680 if (ret && found_type != type) {
7681 symtab_errf(ctx,
7682 "type mismatch when resolving %s: couldn't find "
7683 "name " UPB_STRINGVIEW_FORMAT " with type=%d",
7684 from_name_dbg, UPB_STRINGVIEW_ARGS(sym), (int)type);
7685 }
7686 return ret;
7687 }
7688
create_oneofdef(symtab_addctx * ctx,upb_MessageDef * m,const google_protobuf_OneofDescriptorProto * oneof_proto,const upb_OneofDef * _o)7689 static void create_oneofdef(
7690 symtab_addctx* ctx, upb_MessageDef* m,
7691 const google_protobuf_OneofDescriptorProto* oneof_proto,
7692 const upb_OneofDef* _o) {
7693 upb_OneofDef* o = (upb_OneofDef*)_o;
7694 upb_StringView name = google_protobuf_OneofDescriptorProto_name(oneof_proto);
7695 upb_value v;
7696
7697 o->parent = m;
7698 o->full_name = makefullname(ctx, m->full_name, name);
7699 o->field_count = 0;
7700 o->synthetic = false;
7701
7702 SET_OPTIONS(o->opts, OneofDescriptorProto, OneofOptions, oneof_proto);
7703
7704 upb_value existing_v;
7705 if (upb_strtable_lookup2(&m->ntof, name.data, name.size, &existing_v)) {
7706 symtab_errf(ctx, "duplicate oneof name (%s)", o->full_name);
7707 }
7708
7709 v = pack_def(o, UPB_DEFTYPE_ONEOF);
7710 CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, v, ctx->arena));
7711
7712 CHK_OOM(upb_inttable_init(&o->itof, ctx->arena));
7713 CHK_OOM(upb_strtable_init(&o->ntof, 4, ctx->arena));
7714 }
7715
newstr(symtab_addctx * ctx,const char * data,size_t len)7716 static str_t* newstr(symtab_addctx* ctx, const char* data, size_t len) {
7717 str_t* ret = symtab_alloc(ctx, sizeof(*ret) + len);
7718 CHK_OOM(ret);
7719 ret->len = len;
7720 if (len) memcpy(ret->str, data, len);
7721 ret->str[len] = '\0';
7722 return ret;
7723 }
7724
upb_DefPool_TryGetChar(const char ** src,const char * end,char * ch)7725 static bool upb_DefPool_TryGetChar(const char** src, const char* end,
7726 char* ch) {
7727 if (*src == end) return false;
7728 *ch = **src;
7729 *src += 1;
7730 return true;
7731 }
7732
upb_DefPool_TryGetHexDigit(symtab_addctx * ctx,const upb_FieldDef * f,const char ** src,const char * end)7733 static char upb_DefPool_TryGetHexDigit(symtab_addctx* ctx,
7734 const upb_FieldDef* f, const char** src,
7735 const char* end) {
7736 char ch;
7737 if (!upb_DefPool_TryGetChar(src, end, &ch)) return -1;
7738 if ('0' <= ch && ch <= '9') {
7739 return ch - '0';
7740 }
7741 ch = upb_ascii_lower(ch);
7742 if ('a' <= ch && ch <= 'f') {
7743 return ch - 'a' + 0xa;
7744 }
7745 *src -= 1; // Char wasn't actually a hex digit.
7746 return -1;
7747 }
7748
upb_DefPool_ParseHexEscape(symtab_addctx * ctx,const upb_FieldDef * f,const char ** src,const char * end)7749 static char upb_DefPool_ParseHexEscape(symtab_addctx* ctx,
7750 const upb_FieldDef* f, const char** src,
7751 const char* end) {
7752 char hex_digit = upb_DefPool_TryGetHexDigit(ctx, f, src, end);
7753 if (hex_digit < 0) {
7754 symtab_errf(ctx,
7755 "\\x cannot be followed by non-hex digit in field '%s' default",
7756 upb_FieldDef_FullName(f));
7757 return 0;
7758 }
7759 unsigned int ret = hex_digit;
7760 while ((hex_digit = upb_DefPool_TryGetHexDigit(ctx, f, src, end)) >= 0) {
7761 ret = (ret << 4) | hex_digit;
7762 }
7763 if (ret > 0xff) {
7764 symtab_errf(ctx, "Value of hex escape in field %s exceeds 8 bits",
7765 upb_FieldDef_FullName(f));
7766 return 0;
7767 }
7768 return ret;
7769 }
7770
upb_DefPool_TryGetOctalDigit(const char ** src,const char * end)7771 char upb_DefPool_TryGetOctalDigit(const char** src, const char* end) {
7772 char ch;
7773 if (!upb_DefPool_TryGetChar(src, end, &ch)) return -1;
7774 if ('0' <= ch && ch <= '7') {
7775 return ch - '0';
7776 }
7777 *src -= 1; // Char wasn't actually an octal digit.
7778 return -1;
7779 }
7780
upb_DefPool_ParseOctalEscape(symtab_addctx * ctx,const upb_FieldDef * f,const char ** src,const char * end)7781 static char upb_DefPool_ParseOctalEscape(symtab_addctx* ctx,
7782 const upb_FieldDef* f,
7783 const char** src, const char* end) {
7784 char ch = 0;
7785 for (int i = 0; i < 3; i++) {
7786 char digit;
7787 if ((digit = upb_DefPool_TryGetOctalDigit(src, end)) >= 0) {
7788 ch = (ch << 3) | digit;
7789 }
7790 }
7791 return ch;
7792 }
7793
upb_DefPool_ParseEscape(symtab_addctx * ctx,const upb_FieldDef * f,const char ** src,const char * end)7794 static char upb_DefPool_ParseEscape(symtab_addctx* ctx, const upb_FieldDef* f,
7795 const char** src, const char* end) {
7796 char ch;
7797 if (!upb_DefPool_TryGetChar(src, end, &ch)) {
7798 symtab_errf(ctx, "unterminated escape sequence in field %s",
7799 upb_FieldDef_FullName(f));
7800 return 0;
7801 }
7802 switch (ch) {
7803 case 'a':
7804 return '\a';
7805 case 'b':
7806 return '\b';
7807 case 'f':
7808 return '\f';
7809 case 'n':
7810 return '\n';
7811 case 'r':
7812 return '\r';
7813 case 't':
7814 return '\t';
7815 case 'v':
7816 return '\v';
7817 case '\\':
7818 return '\\';
7819 case '\'':
7820 return '\'';
7821 case '\"':
7822 return '\"';
7823 case '?':
7824 return '\?';
7825 case 'x':
7826 case 'X':
7827 return upb_DefPool_ParseHexEscape(ctx, f, src, end);
7828 case '0':
7829 case '1':
7830 case '2':
7831 case '3':
7832 case '4':
7833 case '5':
7834 case '6':
7835 case '7':
7836 *src -= 1;
7837 return upb_DefPool_ParseOctalEscape(ctx, f, src, end);
7838 }
7839 symtab_errf(ctx, "Unknown escape sequence: \\%c", ch);
7840 }
7841
unescape(symtab_addctx * ctx,const upb_FieldDef * f,const char * data,size_t len)7842 static str_t* unescape(symtab_addctx* ctx, const upb_FieldDef* f,
7843 const char* data, size_t len) {
7844 // Size here is an upper bound; escape sequences could ultimately shrink it.
7845 str_t* ret = symtab_alloc(ctx, sizeof(*ret) + len);
7846 char* dst = &ret->str[0];
7847 const char* src = data;
7848 const char* end = data + len;
7849
7850 while (src < end) {
7851 if (*src == '\\') {
7852 src++;
7853 *dst++ = upb_DefPool_ParseEscape(ctx, f, &src, end);
7854 } else {
7855 *dst++ = *src++;
7856 }
7857 }
7858
7859 ret->len = dst - &ret->str[0];
7860 return ret;
7861 }
7862
parse_default(symtab_addctx * ctx,const char * str,size_t len,upb_FieldDef * f)7863 static void parse_default(symtab_addctx* ctx, const char* str, size_t len,
7864 upb_FieldDef* f) {
7865 char* end;
7866 char nullz[64];
7867 errno = 0;
7868
7869 switch (upb_FieldDef_CType(f)) {
7870 case kUpb_CType_Int32:
7871 case kUpb_CType_Int64:
7872 case kUpb_CType_UInt32:
7873 case kUpb_CType_UInt64:
7874 case kUpb_CType_Double:
7875 case kUpb_CType_Float:
7876 /* Standard C number parsing functions expect null-terminated strings. */
7877 if (len >= sizeof(nullz) - 1) {
7878 symtab_errf(ctx, "Default too long: %.*s", (int)len, str);
7879 }
7880 memcpy(nullz, str, len);
7881 nullz[len] = '\0';
7882 str = nullz;
7883 break;
7884 default:
7885 break;
7886 }
7887
7888 switch (upb_FieldDef_CType(f)) {
7889 case kUpb_CType_Int32: {
7890 long val = strtol(str, &end, 0);
7891 if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) {
7892 goto invalid;
7893 }
7894 f->defaultval.sint = val;
7895 break;
7896 }
7897 case kUpb_CType_Enum: {
7898 const upb_EnumDef* e = f->sub.enumdef;
7899 const upb_EnumValueDef* ev =
7900 upb_EnumDef_FindValueByNameWithSize(e, str, len);
7901 if (!ev) {
7902 goto invalid;
7903 }
7904 f->defaultval.sint = ev->number;
7905 break;
7906 }
7907 case kUpb_CType_Int64: {
7908 long long val = strtoll(str, &end, 0);
7909 if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) {
7910 goto invalid;
7911 }
7912 f->defaultval.sint = val;
7913 break;
7914 }
7915 case kUpb_CType_UInt32: {
7916 unsigned long val = strtoul(str, &end, 0);
7917 if (val > UINT32_MAX || errno == ERANGE || *end) {
7918 goto invalid;
7919 }
7920 f->defaultval.uint = val;
7921 break;
7922 }
7923 case kUpb_CType_UInt64: {
7924 unsigned long long val = strtoull(str, &end, 0);
7925 if (val > UINT64_MAX || errno == ERANGE || *end) {
7926 goto invalid;
7927 }
7928 f->defaultval.uint = val;
7929 break;
7930 }
7931 case kUpb_CType_Double: {
7932 double val = strtod(str, &end);
7933 if (errno == ERANGE || *end) {
7934 goto invalid;
7935 }
7936 f->defaultval.dbl = val;
7937 break;
7938 }
7939 case kUpb_CType_Float: {
7940 float val = strtof(str, &end);
7941 if (errno == ERANGE || *end) {
7942 goto invalid;
7943 }
7944 f->defaultval.flt = val;
7945 break;
7946 }
7947 case kUpb_CType_Bool: {
7948 if (streql2(str, len, "false")) {
7949 f->defaultval.boolean = false;
7950 } else if (streql2(str, len, "true")) {
7951 f->defaultval.boolean = true;
7952 } else {
7953 goto invalid;
7954 }
7955 break;
7956 }
7957 case kUpb_CType_String:
7958 f->defaultval.str = newstr(ctx, str, len);
7959 break;
7960 case kUpb_CType_Bytes:
7961 f->defaultval.str = unescape(ctx, f, str, len);
7962 break;
7963 case kUpb_CType_Message:
7964 /* Should not have a default value. */
7965 symtab_errf(ctx, "Message should not have a default (%s)",
7966 upb_FieldDef_FullName(f));
7967 }
7968
7969 return;
7970
7971 invalid:
7972 symtab_errf(ctx, "Invalid default '%.*s' for field %s of type %d", (int)len,
7973 str, upb_FieldDef_FullName(f), (int)upb_FieldDef_Type(f));
7974 }
7975
set_default_default(symtab_addctx * ctx,upb_FieldDef * f)7976 static void set_default_default(symtab_addctx* ctx, upb_FieldDef* f) {
7977 switch (upb_FieldDef_CType(f)) {
7978 case kUpb_CType_Int32:
7979 case kUpb_CType_Int64:
7980 f->defaultval.sint = 0;
7981 break;
7982 case kUpb_CType_UInt64:
7983 case kUpb_CType_UInt32:
7984 f->defaultval.uint = 0;
7985 break;
7986 case kUpb_CType_Double:
7987 case kUpb_CType_Float:
7988 f->defaultval.dbl = 0;
7989 break;
7990 case kUpb_CType_String:
7991 case kUpb_CType_Bytes:
7992 f->defaultval.str = newstr(ctx, NULL, 0);
7993 break;
7994 case kUpb_CType_Bool:
7995 f->defaultval.boolean = false;
7996 break;
7997 case kUpb_CType_Enum:
7998 f->defaultval.sint = f->sub.enumdef->values[0].number;
7999 case kUpb_CType_Message:
8000 break;
8001 }
8002 }
8003
create_fielddef(symtab_addctx * ctx,const char * prefix,upb_MessageDef * m,const google_protobuf_FieldDescriptorProto * field_proto,const upb_FieldDef * _f,bool is_extension)8004 static void create_fielddef(
8005 symtab_addctx* ctx, const char* prefix, upb_MessageDef* m,
8006 const google_protobuf_FieldDescriptorProto* field_proto,
8007 const upb_FieldDef* _f, bool is_extension) {
8008 upb_FieldDef* f = (upb_FieldDef*)_f;
8009 upb_StringView name;
8010 const char* full_name;
8011 const char* json_name;
8012 const char* shortname;
8013 int32_t field_number;
8014
8015 f->file = ctx->file; /* Must happen prior to symtab_add(). */
8016
8017 if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) {
8018 symtab_errf(ctx, "field has no name");
8019 }
8020
8021 name = google_protobuf_FieldDescriptorProto_name(field_proto);
8022 check_ident(ctx, name, false);
8023 full_name = makefullname(ctx, prefix, name);
8024 shortname = shortdefname(full_name);
8025
8026 if (google_protobuf_FieldDescriptorProto_has_json_name(field_proto)) {
8027 json_name = strviewdup(
8028 ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto));
8029 f->has_json_name_ = true;
8030 } else {
8031 json_name = makejsonname(ctx, shortname);
8032 f->has_json_name_ = false;
8033 }
8034
8035 field_number = google_protobuf_FieldDescriptorProto_number(field_proto);
8036
8037 f->full_name = full_name;
8038 f->json_name = json_name;
8039 f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto);
8040 f->number_ = field_number;
8041 f->scope.oneof = NULL;
8042 f->proto3_optional_ =
8043 google_protobuf_FieldDescriptorProto_proto3_optional(field_proto);
8044
8045 bool has_type = google_protobuf_FieldDescriptorProto_has_type(field_proto);
8046 bool has_type_name =
8047 google_protobuf_FieldDescriptorProto_has_type_name(field_proto);
8048
8049 f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto);
8050
8051 if (has_type) {
8052 switch (f->type_) {
8053 case kUpb_FieldType_Message:
8054 case kUpb_FieldType_Group:
8055 case kUpb_FieldType_Enum:
8056 if (!has_type_name) {
8057 symtab_errf(ctx, "field of type %d requires type name (%s)",
8058 (int)f->type_, full_name);
8059 }
8060 break;
8061 default:
8062 if (has_type_name) {
8063 symtab_errf(ctx, "invalid type for field with type_name set (%s, %d)",
8064 full_name, (int)f->type_);
8065 }
8066 }
8067 } else if (has_type_name) {
8068 f->type_ =
8069 FIELD_TYPE_UNSPECIFIED; // We'll fill this in in resolve_fielddef().
8070 }
8071
8072 if (!is_extension) {
8073 /* direct message field. */
8074 upb_value v, field_v, json_v, existing_v;
8075 size_t json_size;
8076
8077 if (field_number <= 0 || field_number > kUpb_MaxFieldNumber) {
8078 symtab_errf(ctx, "invalid field number (%u)", field_number);
8079 }
8080
8081 f->index_ = f - m->fields;
8082 f->msgdef = m;
8083 f->is_extension_ = false;
8084
8085 field_v = pack_def(f, UPB_DEFTYPE_FIELD);
8086 json_v = pack_def(f, UPB_DEFTYPE_FIELD_JSONNAME);
8087 v = upb_value_constptr(f);
8088 json_size = strlen(json_name);
8089
8090 if (upb_strtable_lookup(&m->ntof, shortname, &existing_v)) {
8091 symtab_errf(ctx, "duplicate field name (%s)", shortname);
8092 }
8093
8094 CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, field_v,
8095 ctx->arena));
8096
8097 if (strcmp(shortname, json_name) != 0) {
8098 if (upb_strtable_lookup(&m->ntof, json_name, &v)) {
8099 symtab_errf(ctx, "duplicate json_name (%s)", json_name);
8100 } else {
8101 CHK_OOM(upb_strtable_insert(&m->ntof, json_name, json_size, json_v,
8102 ctx->arena));
8103 }
8104 }
8105
8106 if (upb_inttable_lookup(&m->itof, field_number, NULL)) {
8107 symtab_errf(ctx, "duplicate field number (%u)", field_number);
8108 }
8109
8110 CHK_OOM(upb_inttable_insert(&m->itof, field_number, v, ctx->arena));
8111
8112 if (ctx->layout) {
8113 const upb_MiniTable_Field* fields = m->layout->fields;
8114 int count = m->layout->field_count;
8115 bool found = false;
8116 for (int i = 0; i < count; i++) {
8117 if (fields[i].number == field_number) {
8118 f->layout_index = i;
8119 found = true;
8120 break;
8121 }
8122 }
8123 UPB_ASSERT(found);
8124 }
8125 } else {
8126 /* extension field. */
8127 f->is_extension_ = true;
8128 f->scope.extension_scope = m;
8129 symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_EXT));
8130 f->layout_index = ctx->ext_count++;
8131 if (ctx->layout) {
8132 UPB_ASSERT(ctx->file->ext_layouts[f->layout_index]->field.number ==
8133 field_number);
8134 }
8135 }
8136
8137 if (f->type_ < kUpb_FieldType_Double || f->type_ > kUpb_FieldType_SInt64) {
8138 symtab_errf(ctx, "invalid type for field %s (%d)", f->full_name, f->type_);
8139 }
8140
8141 if (f->label_ < kUpb_Label_Optional || f->label_ > kUpb_Label_Repeated) {
8142 symtab_errf(ctx, "invalid label for field %s (%d)", f->full_name,
8143 f->label_);
8144 }
8145
8146 /* We can't resolve the subdef or (in the case of extensions) the containing
8147 * message yet, because it may not have been defined yet. We stash a pointer
8148 * to the field_proto until later when we can properly resolve it. */
8149 f->sub.unresolved = field_proto;
8150
8151 if (f->label_ == kUpb_Label_Required &&
8152 f->file->syntax == kUpb_Syntax_Proto3) {
8153 symtab_errf(ctx, "proto3 fields cannot be required (%s)", f->full_name);
8154 }
8155
8156 if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) {
8157 uint32_t oneof_index = google_protobuf_FieldDescriptorProto_oneof_index(field_proto);
8158 upb_OneofDef* oneof;
8159 upb_value v = upb_value_constptr(f);
8160
8161 if (upb_FieldDef_Label(f) != kUpb_Label_Optional) {
8162 symtab_errf(ctx, "fields in oneof must have OPTIONAL label (%s)",
8163 f->full_name);
8164 }
8165
8166 if (!m) {
8167 symtab_errf(ctx, "oneof_index provided for extension field (%s)",
8168 f->full_name);
8169 }
8170
8171 if (oneof_index >= m->oneof_count) {
8172 symtab_errf(ctx, "oneof_index out of range (%s)", f->full_name);
8173 }
8174
8175 oneof = (upb_OneofDef*)&m->oneofs[oneof_index];
8176 f->scope.oneof = oneof;
8177
8178 oneof->field_count++;
8179 if (f->proto3_optional_) {
8180 oneof->synthetic = true;
8181 }
8182 CHK_OOM(upb_inttable_insert(&oneof->itof, f->number_, v, ctx->arena));
8183 CHK_OOM(
8184 upb_strtable_insert(&oneof->ntof, name.data, name.size, v, ctx->arena));
8185 } else {
8186 if (f->proto3_optional_ && !is_extension) {
8187 symtab_errf(ctx, "field with proto3_optional was not in a oneof (%s)",
8188 f->full_name);
8189 }
8190 }
8191
8192 SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto);
8193
8194 if (google_protobuf_FieldOptions_has_packed(f->opts)) {
8195 f->packed_ = google_protobuf_FieldOptions_packed(f->opts);
8196 } else {
8197 /* Repeated fields default to packed for proto3 only. */
8198 f->packed_ = upb_FieldDef_IsPrimitive(f) &&
8199 f->label_ == kUpb_Label_Repeated &&
8200 f->file->syntax == kUpb_Syntax_Proto3;
8201 }
8202 }
8203
create_service(symtab_addctx * ctx,const google_protobuf_ServiceDescriptorProto * svc_proto,const upb_ServiceDef * _s)8204 static void create_service(
8205 symtab_addctx* ctx, const google_protobuf_ServiceDescriptorProto* svc_proto,
8206 const upb_ServiceDef* _s) {
8207 upb_ServiceDef* s = (upb_ServiceDef*)_s;
8208 upb_StringView name;
8209 const google_protobuf_MethodDescriptorProto* const* methods;
8210 size_t i, n;
8211
8212 s->file = ctx->file; /* Must happen prior to symtab_add. */
8213
8214 name = google_protobuf_ServiceDescriptorProto_name(svc_proto);
8215 check_ident(ctx, name, false);
8216 s->full_name = makefullname(ctx, ctx->file->package, name);
8217 symtab_add(ctx, s->full_name, pack_def(s, UPB_DEFTYPE_SERVICE));
8218
8219 methods = google_protobuf_ServiceDescriptorProto_method(svc_proto, &n);
8220
8221 s->method_count = n;
8222 s->methods = symtab_alloc(ctx, sizeof(*s->methods) * n);
8223
8224 SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions, svc_proto);
8225
8226 for (i = 0; i < n; i++) {
8227 const google_protobuf_MethodDescriptorProto* method_proto = methods[i];
8228 upb_MethodDef* m = (upb_MethodDef*)&s->methods[i];
8229 upb_StringView name =
8230 google_protobuf_MethodDescriptorProto_name(method_proto);
8231
8232 m->service = s;
8233 m->full_name = makefullname(ctx, s->full_name, name);
8234 m->index = i;
8235 m->client_streaming =
8236 google_protobuf_MethodDescriptorProto_client_streaming(method_proto);
8237 m->server_streaming =
8238 google_protobuf_MethodDescriptorProto_server_streaming(method_proto);
8239 m->input_type = symtab_resolve(
8240 ctx, m->full_name, m->full_name,
8241 google_protobuf_MethodDescriptorProto_input_type(method_proto),
8242 UPB_DEFTYPE_MSG);
8243 m->output_type = symtab_resolve(
8244 ctx, m->full_name, m->full_name,
8245 google_protobuf_MethodDescriptorProto_output_type(method_proto),
8246 UPB_DEFTYPE_MSG);
8247
8248 SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions, method_proto);
8249 }
8250 }
8251
count_bits_debug(uint64_t x)8252 static int count_bits_debug(uint64_t x) {
8253 // For assertions only, speed does not matter.
8254 int n = 0;
8255 while (x) {
8256 if (x & 1) n++;
8257 x >>= 1;
8258 }
8259 return n;
8260 }
8261
compare_int32(const void * a_ptr,const void * b_ptr)8262 static int compare_int32(const void* a_ptr, const void* b_ptr) {
8263 int32_t a = *(int32_t*)a_ptr;
8264 int32_t b = *(int32_t*)b_ptr;
8265 return a < b ? -1 : (a == b ? 0 : 1);
8266 }
8267
create_enumlayout(symtab_addctx * ctx,const upb_EnumDef * e)8268 upb_MiniTable_Enum* create_enumlayout(symtab_addctx* ctx,
8269 const upb_EnumDef* e) {
8270 int n = 0;
8271 uint64_t mask = 0;
8272
8273 for (int i = 0; i < e->value_count; i++) {
8274 uint32_t val = (uint32_t)e->values[i].number;
8275 if (val < 64) {
8276 mask |= 1ULL << val;
8277 } else {
8278 n++;
8279 }
8280 }
8281
8282 int32_t* values = symtab_alloc(ctx, sizeof(*values) * n);
8283
8284 if (n) {
8285 int32_t* p = values;
8286
8287 // Add values outside the bitmask range to the list, as described in the
8288 // comments for upb_MiniTable_Enum.
8289 for (int i = 0; i < e->value_count; i++) {
8290 int32_t val = e->values[i].number;
8291 if ((uint32_t)val >= 64) {
8292 *p++ = val;
8293 }
8294 }
8295 UPB_ASSERT(p == values + n);
8296 }
8297
8298 // Enums can have duplicate values; we must sort+uniq them.
8299 if (values) qsort(values, n, sizeof(*values), &compare_int32);
8300
8301 int dst = 0;
8302 for (int i = 0; i < n; dst++) {
8303 int32_t val = values[i];
8304 while (i < n && values[i] == val) i++; // Skip duplicates.
8305 values[dst] = val;
8306 }
8307 n = dst;
8308
8309 UPB_ASSERT(upb_inttable_count(&e->iton) == n + count_bits_debug(mask));
8310
8311 upb_MiniTable_Enum* layout = symtab_alloc(ctx, sizeof(*layout));
8312 layout->value_count = n;
8313 layout->mask = mask;
8314 layout->values = values;
8315
8316 return layout;
8317 }
8318
create_enumvaldef(symtab_addctx * ctx,const char * prefix,const google_protobuf_EnumValueDescriptorProto * val_proto,upb_EnumDef * e,int i)8319 static void create_enumvaldef(
8320 symtab_addctx* ctx, const char* prefix,
8321 const google_protobuf_EnumValueDescriptorProto* val_proto, upb_EnumDef* e,
8322 int i) {
8323 upb_EnumValueDef* val = (upb_EnumValueDef*)&e->values[i];
8324 upb_StringView name =
8325 google_protobuf_EnumValueDescriptorProto_name(val_proto);
8326 upb_value v = upb_value_constptr(val);
8327
8328 val->parent = e; /* Must happen prior to symtab_add(). */
8329 val->full_name = makefullname(ctx, prefix, name);
8330 val->number = google_protobuf_EnumValueDescriptorProto_number(val_proto);
8331 symtab_add(ctx, val->full_name, pack_def(val, UPB_DEFTYPE_ENUMVAL));
8332
8333 SET_OPTIONS(val->opts, EnumValueDescriptorProto, EnumValueOptions, val_proto);
8334
8335 if (i == 0 && e->file->syntax == kUpb_Syntax_Proto3 && val->number != 0) {
8336 symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)",
8337 e->full_name);
8338 }
8339
8340 CHK_OOM(upb_strtable_insert(&e->ntoi, name.data, name.size, v, ctx->arena));
8341
8342 // Multiple enumerators can have the same number, first one wins.
8343 if (!upb_inttable_lookup(&e->iton, val->number, NULL)) {
8344 CHK_OOM(upb_inttable_insert(&e->iton, val->number, v, ctx->arena));
8345 }
8346 }
8347
_upb_EnumReservedNames_New(symtab_addctx * ctx,int n,const upb_StringView * protos)8348 static upb_StringView* _upb_EnumReservedNames_New(
8349 symtab_addctx* ctx, int n, const upb_StringView* protos) {
8350 upb_StringView* sv =
8351 upb_Arena_Malloc(ctx->arena, sizeof(upb_StringView) * n);
8352 for (size_t i = 0; i < n; i++) {
8353 sv[i].data =
8354 upb_strdup2(protos[i].data, protos[i].size, ctx->arena);
8355 sv[i].size = protos[i].size;
8356 }
8357 return sv;
8358 }
8359
create_enumdef(symtab_addctx * ctx,const char * prefix,const google_protobuf_EnumDescriptorProto * enum_proto,const upb_MessageDef * containing_type,const upb_EnumDef * _e)8360 static void create_enumdef(
8361 symtab_addctx* ctx, const char* prefix,
8362 const google_protobuf_EnumDescriptorProto* enum_proto,
8363 const upb_MessageDef* containing_type, const upb_EnumDef* _e) {
8364 upb_EnumDef* e = (upb_EnumDef*)_e;
8365 ;
8366 const google_protobuf_EnumValueDescriptorProto* const* values;
8367 const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* res_ranges;
8368 const upb_StringView* res_names;
8369 upb_StringView name;
8370 size_t i, n, n_res_range, n_res_name;
8371
8372 e->file = ctx->file; /* Must happen prior to symtab_add() */
8373 e->containing_type = containing_type;
8374
8375 name = google_protobuf_EnumDescriptorProto_name(enum_proto);
8376 check_ident(ctx, name, false);
8377
8378 e->full_name = makefullname(ctx, prefix, name);
8379 symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM));
8380
8381 values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n);
8382 CHK_OOM(upb_strtable_init(&e->ntoi, n, ctx->arena));
8383 CHK_OOM(upb_inttable_init(&e->iton, ctx->arena));
8384
8385 e->defaultval = 0;
8386 e->value_count = n;
8387 e->values = symtab_alloc(ctx, sizeof(*e->values) * n);
8388
8389 if (n == 0) {
8390 symtab_errf(ctx, "enums must contain at least one value (%s)",
8391 e->full_name);
8392 }
8393
8394 res_ranges =
8395 google_protobuf_EnumDescriptorProto_reserved_range(enum_proto, &n_res_range);
8396 e->res_range_count = n_res_range;
8397 e->res_ranges = _upb_EnumReservedRanges_New(ctx, n_res_range, res_ranges, e);
8398
8399 res_names = google_protobuf_EnumDescriptorProto_reserved_name(enum_proto, &n_res_name);
8400 e->res_name_count = n_res_name;
8401 e->res_names = _upb_EnumReservedNames_New(ctx, n_res_name, res_names);
8402
8403 SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto);
8404
8405 for (i = 0; i < n; i++) {
8406 create_enumvaldef(ctx, prefix, values[i], e, i);
8407 }
8408
8409 upb_inttable_compact(&e->iton, ctx->arena);
8410
8411 if (e->file->syntax == kUpb_Syntax_Proto2) {
8412 if (ctx->layout) {
8413 UPB_ASSERT(ctx->enum_count < ctx->layout->enum_count);
8414 e->layout = ctx->layout->enums[ctx->enum_count++];
8415 UPB_ASSERT(upb_inttable_count(&e->iton) ==
8416 e->layout->value_count + count_bits_debug(e->layout->mask));
8417 } else {
8418 e->layout = create_enumlayout(ctx, e);
8419 }
8420 } else {
8421 e->layout = NULL;
8422 }
8423 }
8424
8425 static void msgdef_create_nested(
8426 symtab_addctx* ctx, const google_protobuf_DescriptorProto* msg_proto,
8427 upb_MessageDef* m);
8428
_upb_ReservedNames_New(symtab_addctx * ctx,int n,const upb_StringView * protos)8429 static upb_StringView* _upb_ReservedNames_New(symtab_addctx* ctx, int n,
8430 const upb_StringView* protos) {
8431 upb_StringView* sv = upb_Arena_Malloc(ctx->arena, sizeof(upb_StringView) * n);
8432 for (size_t i = 0; i < n; i++) {
8433 sv[i].data =
8434 upb_strdup2(protos[i].data, protos[i].size, ctx->arena);
8435 sv[i].size = protos[i].size;
8436 }
8437 return sv;
8438 }
8439
create_msgdef(symtab_addctx * ctx,const char * prefix,const google_protobuf_DescriptorProto * msg_proto,const upb_MessageDef * containing_type,const upb_MessageDef * _m)8440 static void create_msgdef(symtab_addctx* ctx, const char* prefix,
8441 const google_protobuf_DescriptorProto* msg_proto,
8442 const upb_MessageDef* containing_type,
8443 const upb_MessageDef* _m) {
8444 upb_MessageDef* m = (upb_MessageDef*)_m;
8445 const google_protobuf_OneofDescriptorProto* const* oneofs;
8446 const google_protobuf_FieldDescriptorProto* const* fields;
8447 const google_protobuf_DescriptorProto_ExtensionRange* const* ext_ranges;
8448
8449 const google_protobuf_DescriptorProto_ReservedRange* const* res_ranges;
8450 const upb_StringView* res_names;
8451 size_t i, n_oneof, n_field, n_ext_range;
8452 size_t n_res_range, n_res_name;
8453 upb_StringView name;
8454
8455 m->file = ctx->file; /* Must happen prior to symtab_add(). */
8456 m->containing_type = containing_type;
8457
8458 name = google_protobuf_DescriptorProto_name(msg_proto);
8459 check_ident(ctx, name, false);
8460
8461 m->full_name = makefullname(ctx, prefix, name);
8462 symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG));
8463
8464 oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof);
8465 fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field);
8466 ext_ranges =
8467 google_protobuf_DescriptorProto_extension_range(msg_proto, &n_ext_range);
8468 res_ranges = google_protobuf_DescriptorProto_reserved_range(msg_proto, &n_res_range);
8469 res_names = google_protobuf_DescriptorProto_reserved_name(msg_proto, &n_res_name);
8470
8471 CHK_OOM(upb_inttable_init(&m->itof, ctx->arena));
8472 CHK_OOM(upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena));
8473
8474 if (ctx->layout) {
8475 /* create_fielddef() below depends on this being set. */
8476 UPB_ASSERT(ctx->msg_count < ctx->layout->msg_count);
8477 m->layout = ctx->layout->msgs[ctx->msg_count++];
8478 UPB_ASSERT(n_field == m->layout->field_count);
8479 } else {
8480 /* Allocate now (to allow cross-linking), populate later. */
8481 m->layout =
8482 symtab_alloc(ctx, sizeof(*m->layout) + sizeof(_upb_FastTable_Entry));
8483 }
8484
8485 SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto);
8486
8487 m->oneof_count = n_oneof;
8488 m->oneofs = symtab_alloc(ctx, sizeof(*m->oneofs) * n_oneof);
8489 for (i = 0; i < n_oneof; i++) {
8490 create_oneofdef(ctx, m, oneofs[i], &m->oneofs[i]);
8491 }
8492
8493 m->field_count = n_field;
8494 m->fields = symtab_alloc(ctx, sizeof(*m->fields) * n_field);
8495 for (i = 0; i < n_field; i++) {
8496 create_fielddef(ctx, m->full_name, m, fields[i], &m->fields[i],
8497 /* is_extension= */ false);
8498 }
8499
8500 m->ext_range_count = n_ext_range;
8501 m->ext_ranges = symtab_alloc(ctx, sizeof(*m->ext_ranges) * n_ext_range);
8502 for (i = 0; i < n_ext_range; i++) {
8503 const google_protobuf_DescriptorProto_ExtensionRange* r = ext_ranges[i];
8504 upb_ExtensionRange* r_def = (upb_ExtensionRange*)&m->ext_ranges[i];
8505 int32_t start = google_protobuf_DescriptorProto_ExtensionRange_start(r);
8506 int32_t end = google_protobuf_DescriptorProto_ExtensionRange_end(r);
8507 int32_t max =
8508 google_protobuf_MessageOptions_message_set_wire_format(m->opts)
8509 ? INT32_MAX
8510 : kUpb_MaxFieldNumber + 1;
8511
8512 // A full validation would also check that each range is disjoint, and that
8513 // none of the fields overlap with the extension ranges, but we are just
8514 // sanity checking here.
8515 if (start < 1 || end <= start || end > max) {
8516 symtab_errf(ctx, "Extension range (%d, %d) is invalid, message=%s\n",
8517 (int)start, (int)end, m->full_name);
8518 }
8519
8520 r_def->start = start;
8521 r_def->end = end;
8522 SET_OPTIONS(r_def->opts, DescriptorProto_ExtensionRange,
8523 ExtensionRangeOptions, r);
8524 }
8525
8526 m->res_range_count = n_res_range;
8527 m->res_ranges =
8528 _upb_MessageReservedRanges_New(ctx, n_res_range, res_ranges, m);
8529
8530 m->res_name_count = n_res_name;
8531 m->res_names = _upb_ReservedNames_New(ctx, n_res_name, res_names);
8532
8533 finalize_oneofs(ctx, m);
8534 assign_msg_wellknowntype(m);
8535 upb_inttable_compact(&m->itof, ctx->arena);
8536 msgdef_create_nested(ctx, msg_proto, m);
8537 }
8538
msgdef_create_nested(symtab_addctx * ctx,const google_protobuf_DescriptorProto * msg_proto,upb_MessageDef * m)8539 static void msgdef_create_nested(
8540 symtab_addctx* ctx, const google_protobuf_DescriptorProto* msg_proto,
8541 upb_MessageDef* m) {
8542 size_t n;
8543
8544 const google_protobuf_EnumDescriptorProto* const* enums =
8545 google_protobuf_DescriptorProto_enum_type(msg_proto, &n);
8546 m->nested_enum_count = n;
8547 m->nested_enums = symtab_alloc(ctx, sizeof(*m->nested_enums) * n);
8548 for (size_t i = 0; i < n; i++) {
8549 m->nested_enum_count = i + 1;
8550 create_enumdef(ctx, m->full_name, enums[i], m, &m->nested_enums[i]);
8551 }
8552
8553 const google_protobuf_FieldDescriptorProto* const* exts =
8554 google_protobuf_DescriptorProto_extension(msg_proto, &n);
8555 m->nested_ext_count = n;
8556 m->nested_exts = symtab_alloc(ctx, sizeof(*m->nested_exts) * n);
8557 for (size_t i = 0; i < n; i++) {
8558 create_fielddef(ctx, m->full_name, m, exts[i], &m->nested_exts[i],
8559 /* is_extension= */ true);
8560 ((upb_FieldDef*)&m->nested_exts[i])->index_ = i;
8561 }
8562
8563 const google_protobuf_DescriptorProto* const* msgs =
8564 google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
8565 m->nested_msg_count = n;
8566 m->nested_msgs = symtab_alloc(ctx, sizeof(*m->nested_msgs) * n);
8567 for (size_t i = 0; i < n; i++) {
8568 create_msgdef(ctx, m->full_name, msgs[i], m, &m->nested_msgs[i]);
8569 }
8570 }
8571
resolve_subdef(symtab_addctx * ctx,const char * prefix,upb_FieldDef * f)8572 static void resolve_subdef(symtab_addctx* ctx, const char* prefix,
8573 upb_FieldDef* f) {
8574 const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved;
8575 upb_StringView name =
8576 google_protobuf_FieldDescriptorProto_type_name(field_proto);
8577 bool has_name =
8578 google_protobuf_FieldDescriptorProto_has_type_name(field_proto);
8579 switch ((int)f->type_) {
8580 case FIELD_TYPE_UNSPECIFIED: {
8581 // Type was not specified and must be inferred.
8582 UPB_ASSERT(has_name);
8583 upb_deftype_t type;
8584 const void* def =
8585 symtab_resolveany(ctx, f->full_name, prefix, name, &type);
8586 switch (type) {
8587 case UPB_DEFTYPE_ENUM:
8588 f->sub.enumdef = def;
8589 f->type_ = kUpb_FieldType_Enum;
8590 break;
8591 case UPB_DEFTYPE_MSG:
8592 f->sub.msgdef = def;
8593 f->type_ = kUpb_FieldType_Message; // It appears there is no way of
8594 // this being a group.
8595 break;
8596 default:
8597 symtab_errf(ctx, "Couldn't resolve type name for field %s",
8598 f->full_name);
8599 }
8600 }
8601 case kUpb_FieldType_Message:
8602 case kUpb_FieldType_Group:
8603 UPB_ASSERT(has_name);
8604 f->sub.msgdef =
8605 symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_MSG);
8606 break;
8607 case kUpb_FieldType_Enum:
8608 UPB_ASSERT(has_name);
8609 f->sub.enumdef =
8610 symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_ENUM);
8611 break;
8612 default:
8613 // No resolution necessary.
8614 break;
8615 }
8616 }
8617
resolve_extension(symtab_addctx * ctx,const char * prefix,upb_FieldDef * f,const google_protobuf_FieldDescriptorProto * field_proto)8618 static void resolve_extension(
8619 symtab_addctx* ctx, const char* prefix, upb_FieldDef* f,
8620 const google_protobuf_FieldDescriptorProto* field_proto) {
8621 if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) {
8622 symtab_errf(ctx, "extension for field '%s' had no extendee", f->full_name);
8623 }
8624
8625 upb_StringView name =
8626 google_protobuf_FieldDescriptorProto_extendee(field_proto);
8627 const upb_MessageDef* m =
8628 symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_MSG);
8629 f->msgdef = m;
8630
8631 bool found = false;
8632
8633 for (int i = 0, n = m->ext_range_count; i < n; i++) {
8634 const upb_ExtensionRange* r = &m->ext_ranges[i];
8635 if (r->start <= f->number_ && f->number_ < r->end) {
8636 found = true;
8637 break;
8638 }
8639 }
8640
8641 if (!found) {
8642 symtab_errf(ctx,
8643 "field number %u in extension %s has no extension range in "
8644 "message %s",
8645 (unsigned)f->number_, f->full_name, f->msgdef->full_name);
8646 }
8647
8648 const upb_MiniTable_Extension* ext = ctx->file->ext_layouts[f->layout_index];
8649 if (ctx->layout) {
8650 UPB_ASSERT(upb_FieldDef_Number(f) == ext->field.number);
8651 } else {
8652 upb_MiniTable_Extension* mut_ext = (upb_MiniTable_Extension*)ext;
8653 fill_fieldlayout(&mut_ext->field, f);
8654 mut_ext->field.presence = 0;
8655 mut_ext->field.offset = 0;
8656 mut_ext->field.submsg_index = 0;
8657 mut_ext->extendee = f->msgdef->layout;
8658 mut_ext->sub.submsg = f->sub.msgdef->layout;
8659 }
8660
8661 CHK_OOM(upb_inttable_insert(&ctx->symtab->exts, (uintptr_t)ext,
8662 upb_value_constptr(f), ctx->arena));
8663 }
8664
resolve_default(symtab_addctx * ctx,upb_FieldDef * f,const google_protobuf_FieldDescriptorProto * field_proto)8665 static void resolve_default(
8666 symtab_addctx* ctx, upb_FieldDef* f,
8667 const google_protobuf_FieldDescriptorProto* field_proto) {
8668 // Have to delay resolving of the default value until now because of the enum
8669 // case, since enum defaults are specified with a label.
8670 if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) {
8671 upb_StringView defaultval =
8672 google_protobuf_FieldDescriptorProto_default_value(field_proto);
8673
8674 if (f->file->syntax == kUpb_Syntax_Proto3) {
8675 symtab_errf(ctx, "proto3 fields cannot have explicit defaults (%s)",
8676 f->full_name);
8677 }
8678
8679 if (upb_FieldDef_IsSubMessage(f)) {
8680 symtab_errf(ctx, "message fields cannot have explicit defaults (%s)",
8681 f->full_name);
8682 }
8683
8684 parse_default(ctx, defaultval.data, defaultval.size, f);
8685 f->has_default = true;
8686 } else {
8687 set_default_default(ctx, f);
8688 f->has_default = false;
8689 }
8690 }
8691
resolve_fielddef(symtab_addctx * ctx,const char * prefix,upb_FieldDef * f)8692 static void resolve_fielddef(symtab_addctx* ctx, const char* prefix,
8693 upb_FieldDef* f) {
8694 // We have to stash this away since resolve_subdef() may overwrite it.
8695 const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved;
8696
8697 resolve_subdef(ctx, prefix, f);
8698 resolve_default(ctx, f, field_proto);
8699
8700 if (f->is_extension_) {
8701 resolve_extension(ctx, prefix, f, field_proto);
8702 }
8703 }
8704
resolve_msgdef(symtab_addctx * ctx,upb_MessageDef * m)8705 static void resolve_msgdef(symtab_addctx* ctx, upb_MessageDef* m) {
8706 for (int i = 0; i < m->field_count; i++) {
8707 resolve_fielddef(ctx, m->full_name, (upb_FieldDef*)&m->fields[i]);
8708 }
8709
8710 m->in_message_set = false;
8711 for (int i = 0; i < m->nested_ext_count; i++) {
8712 upb_FieldDef* ext = (upb_FieldDef*)&m->nested_exts[i];
8713 resolve_fielddef(ctx, m->full_name, ext);
8714 if (ext->type_ == kUpb_FieldType_Message &&
8715 ext->label_ == kUpb_Label_Optional && ext->sub.msgdef == m &&
8716 google_protobuf_MessageOptions_message_set_wire_format(
8717 ext->msgdef->opts)) {
8718 m->in_message_set = true;
8719 }
8720 }
8721
8722 if (!ctx->layout) make_layout(ctx, m);
8723
8724 for (int i = 0; i < m->nested_msg_count; i++) {
8725 resolve_msgdef(ctx, (upb_MessageDef*)&m->nested_msgs[i]);
8726 }
8727 }
8728
count_exts_in_msg(const google_protobuf_DescriptorProto * msg_proto)8729 static int count_exts_in_msg(const google_protobuf_DescriptorProto* msg_proto) {
8730 size_t n;
8731 google_protobuf_DescriptorProto_extension(msg_proto, &n);
8732 int ext_count = n;
8733
8734 const google_protobuf_DescriptorProto* const* nested_msgs =
8735 google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
8736 for (size_t i = 0; i < n; i++) {
8737 ext_count += count_exts_in_msg(nested_msgs[i]);
8738 }
8739
8740 return ext_count;
8741 }
8742
build_filedef(symtab_addctx * ctx,upb_FileDef * file,const google_protobuf_FileDescriptorProto * file_proto)8743 static void build_filedef(
8744 symtab_addctx* ctx, upb_FileDef* file,
8745 const google_protobuf_FileDescriptorProto* file_proto) {
8746 const google_protobuf_DescriptorProto* const* msgs;
8747 const google_protobuf_EnumDescriptorProto* const* enums;
8748 const google_protobuf_FieldDescriptorProto* const* exts;
8749 const google_protobuf_ServiceDescriptorProto* const* services;
8750 const upb_StringView* strs;
8751 const int32_t* public_deps;
8752 const int32_t* weak_deps;
8753 size_t i, n;
8754
8755 file->symtab = ctx->symtab;
8756
8757 /* Count all extensions in the file, to build a flat array of layouts. */
8758 google_protobuf_FileDescriptorProto_extension(file_proto, &n);
8759 int ext_count = n;
8760 msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
8761 for (int i = 0; i < n; i++) {
8762 ext_count += count_exts_in_msg(msgs[i]);
8763 }
8764 file->ext_count = ext_count;
8765
8766 if (ctx->layout) {
8767 /* We are using the ext layouts that were passed in. */
8768 file->ext_layouts = ctx->layout->exts;
8769 if (ctx->layout->ext_count != file->ext_count) {
8770 symtab_errf(ctx, "Extension count did not match layout (%d vs %d)",
8771 ctx->layout->ext_count, file->ext_count);
8772 }
8773 } else {
8774 /* We are building ext layouts from scratch. */
8775 file->ext_layouts =
8776 symtab_alloc(ctx, sizeof(*file->ext_layouts) * file->ext_count);
8777 upb_MiniTable_Extension* ext =
8778 symtab_alloc(ctx, sizeof(*ext) * file->ext_count);
8779 for (int i = 0; i < file->ext_count; i++) {
8780 file->ext_layouts[i] = &ext[i];
8781 }
8782 }
8783
8784 if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) {
8785 symtab_errf(ctx, "File has no name");
8786 }
8787
8788 file->name =
8789 strviewdup(ctx, google_protobuf_FileDescriptorProto_name(file_proto));
8790
8791 upb_StringView package = google_protobuf_FileDescriptorProto_package(file_proto);
8792 if (package.size) {
8793 check_ident(ctx, package, true);
8794 file->package = strviewdup(ctx, package);
8795 } else {
8796 file->package = NULL;
8797 }
8798
8799 if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) {
8800 upb_StringView syntax =
8801 google_protobuf_FileDescriptorProto_syntax(file_proto);
8802
8803 if (streql_view(syntax, "proto2")) {
8804 file->syntax = kUpb_Syntax_Proto2;
8805 } else if (streql_view(syntax, "proto3")) {
8806 file->syntax = kUpb_Syntax_Proto3;
8807 } else {
8808 symtab_errf(ctx, "Invalid syntax '" UPB_STRINGVIEW_FORMAT "'",
8809 UPB_STRINGVIEW_ARGS(syntax));
8810 }
8811 } else {
8812 file->syntax = kUpb_Syntax_Proto2;
8813 }
8814
8815 /* Read options. */
8816 SET_OPTIONS(file->opts, FileDescriptorProto, FileOptions, file_proto);
8817
8818 /* Verify dependencies. */
8819 strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n);
8820 file->dep_count = n;
8821 file->deps = symtab_alloc(ctx, sizeof(*file->deps) * n);
8822
8823 for (i = 0; i < n; i++) {
8824 upb_StringView str = strs[i];
8825 file->deps[i] =
8826 upb_DefPool_FindFileByNameWithSize(ctx->symtab, str.data, str.size);
8827 if (!file->deps[i]) {
8828 symtab_errf(ctx,
8829 "Depends on file '" UPB_STRINGVIEW_FORMAT
8830 "', but it has not been loaded",
8831 UPB_STRINGVIEW_ARGS(str));
8832 }
8833 }
8834
8835 public_deps =
8836 google_protobuf_FileDescriptorProto_public_dependency(file_proto, &n);
8837 file->public_dep_count = n;
8838 file->public_deps = symtab_alloc(ctx, sizeof(*file->public_deps) * n);
8839 int32_t* mutable_public_deps = (int32_t*)file->public_deps;
8840 for (i = 0; i < n; i++) {
8841 if (public_deps[i] >= file->dep_count) {
8842 symtab_errf(ctx, "public_dep %d is out of range", (int)public_deps[i]);
8843 }
8844 mutable_public_deps[i] = public_deps[i];
8845 }
8846
8847 weak_deps =
8848 google_protobuf_FileDescriptorProto_weak_dependency(file_proto, &n);
8849 file->weak_dep_count = n;
8850 file->weak_deps = symtab_alloc(ctx, sizeof(*file->weak_deps) * n);
8851 int32_t* mutable_weak_deps = (int32_t*)file->weak_deps;
8852 for (i = 0; i < n; i++) {
8853 if (weak_deps[i] >= file->dep_count) {
8854 symtab_errf(ctx, "weak_dep %d is out of range", (int)weak_deps[i]);
8855 }
8856 mutable_weak_deps[i] = weak_deps[i];
8857 }
8858
8859 /* Create enums. */
8860 enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
8861 file->top_lvl_enum_count = n;
8862 file->top_lvl_enums = symtab_alloc(ctx, sizeof(*file->top_lvl_enums) * n);
8863 for (i = 0; i < n; i++) {
8864 create_enumdef(ctx, file->package, enums[i], NULL, &file->top_lvl_enums[i]);
8865 }
8866
8867 /* Create extensions. */
8868 exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n);
8869 file->top_lvl_ext_count = n;
8870 file->top_lvl_exts = symtab_alloc(ctx, sizeof(*file->top_lvl_exts) * n);
8871 for (i = 0; i < n; i++) {
8872 create_fielddef(ctx, file->package, NULL, exts[i], &file->top_lvl_exts[i],
8873 /* is_extension= */ true);
8874 ((upb_FieldDef*)&file->top_lvl_exts[i])->index_ = i;
8875 }
8876
8877 /* Create messages. */
8878 msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
8879 file->top_lvl_msg_count = n;
8880 file->top_lvl_msgs = symtab_alloc(ctx, sizeof(*file->top_lvl_msgs) * n);
8881 for (i = 0; i < n; i++) {
8882 create_msgdef(ctx, file->package, msgs[i], NULL, &file->top_lvl_msgs[i]);
8883 }
8884
8885 /* Create services. */
8886 services = google_protobuf_FileDescriptorProto_service(file_proto, &n);
8887 file->service_count = n;
8888 file->services = symtab_alloc(ctx, sizeof(*file->services) * n);
8889 for (i = 0; i < n; i++) {
8890 create_service(ctx, services[i], &file->services[i]);
8891 ((upb_ServiceDef*)&file->services[i])->index = i;
8892 }
8893
8894 /* Now that all names are in the table, build layouts and resolve refs. */
8895 for (i = 0; i < (size_t)file->top_lvl_ext_count; i++) {
8896 resolve_fielddef(ctx, file->package, (upb_FieldDef*)&file->top_lvl_exts[i]);
8897 }
8898
8899 for (i = 0; i < (size_t)file->top_lvl_msg_count; i++) {
8900 resolve_msgdef(ctx, (upb_MessageDef*)&file->top_lvl_msgs[i]);
8901 }
8902
8903 if (file->ext_count) {
8904 CHK_OOM(_upb_extreg_add(ctx->symtab->extreg, file->ext_layouts,
8905 file->ext_count));
8906 }
8907 }
8908
remove_filedef(upb_DefPool * s,upb_FileDef * file)8909 static void remove_filedef(upb_DefPool* s, upb_FileDef* file) {
8910 intptr_t iter = UPB_INTTABLE_BEGIN;
8911 upb_StringView key;
8912 upb_value val;
8913 while (upb_strtable_next2(&s->syms, &key, &val, &iter)) {
8914 const upb_FileDef* f;
8915 switch (deftype(val)) {
8916 case UPB_DEFTYPE_EXT:
8917 f = upb_FieldDef_File(unpack_def(val, UPB_DEFTYPE_EXT));
8918 break;
8919 case UPB_DEFTYPE_MSG:
8920 f = upb_MessageDef_File(unpack_def(val, UPB_DEFTYPE_MSG));
8921 break;
8922 case UPB_DEFTYPE_ENUM:
8923 f = upb_EnumDef_File(unpack_def(val, UPB_DEFTYPE_ENUM));
8924 break;
8925 case UPB_DEFTYPE_ENUMVAL:
8926 f = upb_EnumDef_File(
8927 upb_EnumValueDef_Enum(unpack_def(val, UPB_DEFTYPE_ENUMVAL)));
8928 break;
8929 case UPB_DEFTYPE_SERVICE:
8930 f = upb_ServiceDef_File(unpack_def(val, UPB_DEFTYPE_SERVICE));
8931 break;
8932 default:
8933 UPB_UNREACHABLE();
8934 }
8935
8936 if (f == file) upb_strtable_removeiter(&s->syms, &iter);
8937 }
8938 }
8939
_upb_DefPool_AddFile(upb_DefPool * s,const google_protobuf_FileDescriptorProto * file_proto,const upb_MiniTable_File * layout,upb_Status * status)8940 static const upb_FileDef* _upb_DefPool_AddFile(
8941 upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto,
8942 const upb_MiniTable_File* layout, upb_Status* status) {
8943 symtab_addctx ctx;
8944 upb_StringView name = google_protobuf_FileDescriptorProto_name(file_proto);
8945 upb_value v;
8946
8947 if (upb_strtable_lookup2(&s->files, name.data, name.size, &v)) {
8948 if (unpack_def(v, UPB_DEFTYPE_FILE)) {
8949 upb_Status_SetErrorFormat(status, "duplicate file name (%.*s)",
8950 UPB_STRINGVIEW_ARGS(name));
8951 return NULL;
8952 }
8953 const upb_MiniTable_File* registered = unpack_def(v, UPB_DEFTYPE_LAYOUT);
8954 UPB_ASSERT(registered);
8955 if (layout && layout != registered) {
8956 upb_Status_SetErrorFormat(
8957 status, "tried to build with a different layout (filename=%.*s)",
8958 UPB_STRINGVIEW_ARGS(name));
8959 return NULL;
8960 }
8961 layout = registered;
8962 }
8963
8964 ctx.symtab = s;
8965 ctx.layout = layout;
8966 ctx.msg_count = 0;
8967 ctx.enum_count = 0;
8968 ctx.ext_count = 0;
8969 ctx.status = status;
8970 ctx.file = NULL;
8971 ctx.arena = upb_Arena_New();
8972 ctx.tmp_arena = upb_Arena_New();
8973
8974 if (!ctx.arena || !ctx.tmp_arena) {
8975 if (ctx.arena) upb_Arena_Free(ctx.arena);
8976 if (ctx.tmp_arena) upb_Arena_Free(ctx.tmp_arena);
8977 upb_Status_setoom(status);
8978 return NULL;
8979 }
8980
8981 if (UPB_UNLIKELY(UPB_SETJMP(ctx.err))) {
8982 UPB_ASSERT(!upb_Status_IsOk(status));
8983 if (ctx.file) {
8984 remove_filedef(s, ctx.file);
8985 ctx.file = NULL;
8986 }
8987 } else {
8988 ctx.file = symtab_alloc(&ctx, sizeof(*ctx.file));
8989 build_filedef(&ctx, ctx.file, file_proto);
8990 upb_strtable_insert(&s->files, name.data, name.size,
8991 pack_def(ctx.file, UPB_DEFTYPE_FILE), ctx.arena);
8992 UPB_ASSERT(upb_Status_IsOk(status));
8993 upb_Arena_Fuse(s->arena, ctx.arena);
8994 }
8995
8996 upb_Arena_Free(ctx.arena);
8997 upb_Arena_Free(ctx.tmp_arena);
8998 return ctx.file;
8999 }
9000
upb_DefPool_AddFile(upb_DefPool * s,const google_protobuf_FileDescriptorProto * file_proto,upb_Status * status)9001 const upb_FileDef* upb_DefPool_AddFile(
9002 upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto,
9003 upb_Status* status) {
9004 return _upb_DefPool_AddFile(s, file_proto, NULL, status);
9005 }
9006
9007 /* Include here since we want most of this file to be stdio-free. */
9008 #include <stdio.h>
9009
_upb_DefPool_LoadDefInitEx(upb_DefPool * s,const _upb_DefPool_Init * init,bool rebuild_minitable)9010 bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init,
9011 bool rebuild_minitable) {
9012 /* Since this function should never fail (it would indicate a bug in upb) we
9013 * print errors to stderr instead of returning error status to the user. */
9014 _upb_DefPool_Init** deps = init->deps;
9015 google_protobuf_FileDescriptorProto* file;
9016 upb_Arena* arena;
9017 upb_Status status;
9018
9019 upb_Status_Clear(&status);
9020
9021 if (upb_DefPool_FindFileByName(s, init->filename)) {
9022 return true;
9023 }
9024
9025 arena = upb_Arena_New();
9026
9027 for (; *deps; deps++) {
9028 if (!_upb_DefPool_LoadDefInitEx(s, *deps, rebuild_minitable)) goto err;
9029 }
9030
9031 file = google_protobuf_FileDescriptorProto_parse_ex(
9032 init->descriptor.data, init->descriptor.size, NULL,
9033 kUpb_DecodeOption_AliasString, arena);
9034 s->bytes_loaded += init->descriptor.size;
9035
9036 if (!file) {
9037 upb_Status_SetErrorFormat(
9038 &status,
9039 "Failed to parse compiled-in descriptor for file '%s'. This should "
9040 "never happen.",
9041 init->filename);
9042 goto err;
9043 }
9044
9045 const upb_MiniTable_File* mt = rebuild_minitable ? NULL : init->layout;
9046 if (!_upb_DefPool_AddFile(s, file, mt, &status)) {
9047 goto err;
9048 }
9049
9050 upb_Arena_Free(arena);
9051 return true;
9052
9053 err:
9054 fprintf(stderr,
9055 "Error loading compiled-in descriptor for file '%s' (this should "
9056 "never happen): %s\n",
9057 init->filename, upb_Status_ErrorMessage(&status));
9058 upb_Arena_Free(arena);
9059 return false;
9060 }
9061
_upb_DefPool_BytesLoaded(const upb_DefPool * s)9062 size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s) {
9063 return s->bytes_loaded;
9064 }
9065
_upb_DefPool_Arena(const upb_DefPool * s)9066 upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s) { return s->arena; }
9067
_upb_DefPool_FindExtensionByMiniTable(const upb_DefPool * s,const upb_MiniTable_Extension * ext)9068 const upb_FieldDef* _upb_DefPool_FindExtensionByMiniTable(
9069 const upb_DefPool* s, const upb_MiniTable_Extension* ext) {
9070 upb_value v;
9071 bool ok = upb_inttable_lookup(&s->exts, (uintptr_t)ext, &v);
9072 UPB_ASSERT(ok);
9073 return upb_value_getconstptr(v);
9074 }
9075
upb_DefPool_FindExtensionByNumber(const upb_DefPool * s,const upb_MessageDef * m,int32_t fieldnum)9076 const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s,
9077 const upb_MessageDef* m,
9078 int32_t fieldnum) {
9079 const upb_MiniTable* l = upb_MessageDef_MiniTable(m);
9080 const upb_MiniTable_Extension* ext = _upb_extreg_get(s->extreg, l, fieldnum);
9081 return ext ? _upb_DefPool_FindExtensionByMiniTable(s, ext) : NULL;
9082 }
9083
_upb_DefPool_registerlayout(upb_DefPool * s,const char * filename,const upb_MiniTable_File * file)9084 bool _upb_DefPool_registerlayout(upb_DefPool* s, const char* filename,
9085 const upb_MiniTable_File* file) {
9086 if (upb_DefPool_FindFileByName(s, filename)) return false;
9087 upb_value v = pack_def(file, UPB_DEFTYPE_LAYOUT);
9088 return upb_strtable_insert(&s->files, filename, strlen(filename), v,
9089 s->arena);
9090 }
9091
upb_DefPool_ExtensionRegistry(const upb_DefPool * s)9092 const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry(
9093 const upb_DefPool* s) {
9094 return s->extreg;
9095 }
9096
upb_DefPool_GetAllExtensions(const upb_DefPool * s,const upb_MessageDef * m,size_t * count)9097 const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s,
9098 const upb_MessageDef* m,
9099 size_t* count) {
9100 size_t n = 0;
9101 intptr_t iter = UPB_INTTABLE_BEGIN;
9102 uintptr_t key;
9103 upb_value val;
9104 // This is O(all exts) instead of O(exts for m). If we need this to be
9105 // efficient we may need to make extreg into a two-level table, or have a
9106 // second per-message index.
9107 while (upb_inttable_next2(&s->exts, &key, &val, &iter)) {
9108 const upb_FieldDef* f = upb_value_getconstptr(val);
9109 if (upb_FieldDef_ContainingType(f) == m) n++;
9110 }
9111 const upb_FieldDef** exts = malloc(n * sizeof(*exts));
9112 iter = UPB_INTTABLE_BEGIN;
9113 size_t i = 0;
9114 while (upb_inttable_next2(&s->exts, &key, &val, &iter)) {
9115 const upb_FieldDef* f = upb_value_getconstptr(val);
9116 if (upb_FieldDef_ContainingType(f) == m) exts[i++] = f;
9117 }
9118 *count = n;
9119 return exts;
9120 }
9121
9122 #undef CHK_OOM
9123
9124 /** upb/reflection.c ************************************************************/
9125
9126 #include <string.h>
9127
9128
get_field_size(const upb_MiniTable_Field * f)9129 static size_t get_field_size(const upb_MiniTable_Field* f) {
9130 static unsigned char sizes[] = {
9131 0, /* 0 */
9132 8, /* kUpb_FieldType_Double */
9133 4, /* kUpb_FieldType_Float */
9134 8, /* kUpb_FieldType_Int64 */
9135 8, /* kUpb_FieldType_UInt64 */
9136 4, /* kUpb_FieldType_Int32 */
9137 8, /* kUpb_FieldType_Fixed64 */
9138 4, /* kUpb_FieldType_Fixed32 */
9139 1, /* kUpb_FieldType_Bool */
9140 sizeof(upb_StringView), /* kUpb_FieldType_String */
9141 sizeof(void*), /* kUpb_FieldType_Group */
9142 sizeof(void*), /* kUpb_FieldType_Message */
9143 sizeof(upb_StringView), /* kUpb_FieldType_Bytes */
9144 4, /* kUpb_FieldType_UInt32 */
9145 4, /* kUpb_FieldType_Enum */
9146 4, /* kUpb_FieldType_SFixed32 */
9147 8, /* kUpb_FieldType_SFixed64 */
9148 4, /* kUpb_FieldType_SInt32 */
9149 8, /* kUpb_FieldType_SInt64 */
9150 };
9151 return upb_IsRepeatedOrMap(f) ? sizeof(void*) : sizes[f->descriptortype];
9152 }
9153
9154 /** upb_Message
9155 * *******************************************************************/
9156
upb_Message_New(const upb_MessageDef * m,upb_Arena * a)9157 upb_Message* upb_Message_New(const upb_MessageDef* m, upb_Arena* a) {
9158 return _upb_Message_New(upb_MessageDef_MiniTable(m), a);
9159 }
9160
in_oneof(const upb_MiniTable_Field * field)9161 static bool in_oneof(const upb_MiniTable_Field* field) {
9162 return field->presence < 0;
9163 }
9164
_upb_Message_Getraw(const upb_Message * msg,const upb_FieldDef * f)9165 static upb_MessageValue _upb_Message_Getraw(const upb_Message* msg,
9166 const upb_FieldDef* f) {
9167 const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f);
9168 const char* mem = UPB_PTR_AT(msg, field->offset, char);
9169 upb_MessageValue val = {0};
9170 memcpy(&val, mem, get_field_size(field));
9171 return val;
9172 }
9173
upb_Message_Has(const upb_Message * msg,const upb_FieldDef * f)9174 bool upb_Message_Has(const upb_Message* msg, const upb_FieldDef* f) {
9175 assert(upb_FieldDef_HasPresence(f));
9176 if (upb_FieldDef_IsExtension(f)) {
9177 const upb_MiniTable_Extension* ext = _upb_FieldDef_ExtensionMiniTable(f);
9178 return _upb_Message_Getext(msg, ext) != NULL;
9179 } else {
9180 const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f);
9181 if (in_oneof(field)) {
9182 return _upb_getoneofcase_field(msg, field) == field->number;
9183 } else if (field->presence > 0) {
9184 return _upb_hasbit_field(msg, field);
9185 } else {
9186 UPB_ASSERT(field->descriptortype == kUpb_FieldType_Message ||
9187 field->descriptortype == kUpb_FieldType_Group);
9188 return _upb_Message_Getraw(msg, f).msg_val != NULL;
9189 }
9190 }
9191 }
9192
upb_Message_WhichOneof(const upb_Message * msg,const upb_OneofDef * o)9193 const upb_FieldDef* upb_Message_WhichOneof(const upb_Message* msg,
9194 const upb_OneofDef* o) {
9195 const upb_FieldDef* f = upb_OneofDef_Field(o, 0);
9196 if (upb_OneofDef_IsSynthetic(o)) {
9197 UPB_ASSERT(upb_OneofDef_FieldCount(o) == 1);
9198 return upb_Message_Has(msg, f) ? f : NULL;
9199 } else {
9200 const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f);
9201 uint32_t oneof_case = _upb_getoneofcase_field(msg, field);
9202 f = oneof_case ? upb_OneofDef_LookupNumber(o, oneof_case) : NULL;
9203 UPB_ASSERT((f != NULL) == (oneof_case != 0));
9204 return f;
9205 }
9206 }
9207
upb_Message_Get(const upb_Message * msg,const upb_FieldDef * f)9208 upb_MessageValue upb_Message_Get(const upb_Message* msg,
9209 const upb_FieldDef* f) {
9210 if (upb_FieldDef_IsExtension(f)) {
9211 const upb_Message_Extension* ext =
9212 _upb_Message_Getext(msg, _upb_FieldDef_ExtensionMiniTable(f));
9213 if (ext) {
9214 upb_MessageValue val;
9215 memcpy(&val, &ext->data, sizeof(val));
9216 return val;
9217 } else if (upb_FieldDef_IsRepeated(f)) {
9218 return (upb_MessageValue){.array_val = NULL};
9219 }
9220 } else if (!upb_FieldDef_HasPresence(f) || upb_Message_Has(msg, f)) {
9221 return _upb_Message_Getraw(msg, f);
9222 }
9223 return upb_FieldDef_Default(f);
9224 }
9225
upb_Message_Mutable(upb_Message * msg,const upb_FieldDef * f,upb_Arena * a)9226 upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg,
9227 const upb_FieldDef* f,
9228 upb_Arena* a) {
9229 UPB_ASSERT(upb_FieldDef_IsSubMessage(f) || upb_FieldDef_IsRepeated(f));
9230 if (upb_FieldDef_HasPresence(f) && !upb_Message_Has(msg, f)) {
9231 // We need to skip the upb_Message_Get() call in this case.
9232 goto make;
9233 }
9234
9235 upb_MessageValue val = upb_Message_Get(msg, f);
9236 if (val.array_val) {
9237 return (upb_MutableMessageValue){.array = (upb_Array*)val.array_val};
9238 }
9239
9240 upb_MutableMessageValue ret;
9241 make:
9242 if (!a) return (upb_MutableMessageValue){.array = NULL};
9243 if (upb_FieldDef_IsMap(f)) {
9244 const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f);
9245 const upb_FieldDef* key =
9246 upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_KeyFieldNumber);
9247 const upb_FieldDef* value =
9248 upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_ValueFieldNumber);
9249 ret.map =
9250 upb_Map_New(a, upb_FieldDef_CType(key), upb_FieldDef_CType(value));
9251 } else if (upb_FieldDef_IsRepeated(f)) {
9252 ret.array = upb_Array_New(a, upb_FieldDef_CType(f));
9253 } else {
9254 UPB_ASSERT(upb_FieldDef_IsSubMessage(f));
9255 ret.msg = upb_Message_New(upb_FieldDef_MessageSubDef(f), a);
9256 }
9257
9258 val.array_val = ret.array;
9259 upb_Message_Set(msg, f, val, a);
9260
9261 return ret;
9262 }
9263
upb_Message_Set(upb_Message * msg,const upb_FieldDef * f,upb_MessageValue val,upb_Arena * a)9264 bool upb_Message_Set(upb_Message* msg, const upb_FieldDef* f,
9265 upb_MessageValue val, upb_Arena* a) {
9266 if (upb_FieldDef_IsExtension(f)) {
9267 upb_Message_Extension* ext = _upb_Message_GetOrCreateExtension(
9268 msg, _upb_FieldDef_ExtensionMiniTable(f), a);
9269 if (!ext) return false;
9270 memcpy(&ext->data, &val, sizeof(val));
9271 } else {
9272 const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f);
9273 char* mem = UPB_PTR_AT(msg, field->offset, char);
9274 memcpy(mem, &val, get_field_size(field));
9275 if (field->presence > 0) {
9276 _upb_sethas_field(msg, field);
9277 } else if (in_oneof(field)) {
9278 *_upb_oneofcase_field(msg, field) = field->number;
9279 }
9280 }
9281 return true;
9282 }
9283
upb_Message_ClearField(upb_Message * msg,const upb_FieldDef * f)9284 void upb_Message_ClearField(upb_Message* msg, const upb_FieldDef* f) {
9285 if (upb_FieldDef_IsExtension(f)) {
9286 _upb_Message_Clearext(msg, _upb_FieldDef_ExtensionMiniTable(f));
9287 } else {
9288 const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f);
9289 char* mem = UPB_PTR_AT(msg, field->offset, char);
9290
9291 if (field->presence > 0) {
9292 _upb_clearhas_field(msg, field);
9293 } else if (in_oneof(field)) {
9294 uint32_t* oneof_case = _upb_oneofcase_field(msg, field);
9295 if (*oneof_case != field->number) return;
9296 *oneof_case = 0;
9297 }
9298
9299 memset(mem, 0, get_field_size(field));
9300 }
9301 }
9302
upb_Message_Clear(upb_Message * msg,const upb_MessageDef * m)9303 void upb_Message_Clear(upb_Message* msg, const upb_MessageDef* m) {
9304 _upb_Message_Clear(msg, upb_MessageDef_MiniTable(m));
9305 }
9306
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)9307 bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m,
9308 const upb_DefPool* ext_pool, const upb_FieldDef** out_f,
9309 upb_MessageValue* out_val, size_t* iter) {
9310 size_t i = *iter;
9311 size_t n = upb_MessageDef_FieldCount(m);
9312 const upb_MessageValue zero = {0};
9313 UPB_UNUSED(ext_pool);
9314
9315 /* Iterate over normal fields, returning the first one that is set. */
9316 while (++i < n) {
9317 const upb_FieldDef* f = upb_MessageDef_Field(m, i);
9318 upb_MessageValue val = _upb_Message_Getraw(msg, f);
9319
9320 /* Skip field if unset or empty. */
9321 if (upb_FieldDef_HasPresence(f)) {
9322 if (!upb_Message_Has(msg, f)) continue;
9323 } else {
9324 upb_MessageValue test = val;
9325 if (upb_FieldDef_IsString(f) && !upb_FieldDef_IsRepeated(f)) {
9326 /* Clear string pointer, only size matters (ptr could be non-NULL). */
9327 test.str_val.data = NULL;
9328 }
9329 /* Continue if NULL or 0. */
9330 if (memcmp(&test, &zero, sizeof(test)) == 0) continue;
9331
9332 /* Continue on empty array or map. */
9333 if (upb_FieldDef_IsMap(f)) {
9334 if (upb_Map_Size(test.map_val) == 0) continue;
9335 } else if (upb_FieldDef_IsRepeated(f)) {
9336 if (upb_Array_Size(test.array_val) == 0) continue;
9337 }
9338 }
9339
9340 *out_val = val;
9341 *out_f = f;
9342 *iter = i;
9343 return true;
9344 }
9345
9346 if (ext_pool) {
9347 /* Return any extensions that are set. */
9348 size_t count;
9349 const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &count);
9350 if (i - n < count) {
9351 ext += count - 1 - (i - n);
9352 memcpy(out_val, &ext->data, sizeof(*out_val));
9353 *out_f = _upb_DefPool_FindExtensionByMiniTable(ext_pool, ext->ext);
9354 *iter = i;
9355 return true;
9356 }
9357 }
9358
9359 *iter = i;
9360 return false;
9361 }
9362
_upb_Message_DiscardUnknown(upb_Message * msg,const upb_MessageDef * m,int depth)9363 bool _upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m,
9364 int depth) {
9365 size_t iter = kUpb_Message_Begin;
9366 const upb_FieldDef* f;
9367 upb_MessageValue val;
9368 bool ret = true;
9369
9370 if (--depth == 0) return false;
9371
9372 _upb_Message_DiscardUnknown_shallow(msg);
9373
9374 while (upb_Message_Next(msg, m, NULL /*ext_pool*/, &f, &val, &iter)) {
9375 const upb_MessageDef* subm = upb_FieldDef_MessageSubDef(f);
9376 if (!subm) continue;
9377 if (upb_FieldDef_IsMap(f)) {
9378 const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(subm, 2);
9379 const upb_MessageDef* val_m = upb_FieldDef_MessageSubDef(val_f);
9380 upb_Map* map = (upb_Map*)val.map_val;
9381 size_t iter = kUpb_Map_Begin;
9382
9383 if (!val_m) continue;
9384
9385 while (upb_MapIterator_Next(map, &iter)) {
9386 upb_MessageValue map_val = upb_MapIterator_Value(map, iter);
9387 if (!_upb_Message_DiscardUnknown((upb_Message*)map_val.msg_val, val_m,
9388 depth)) {
9389 ret = false;
9390 }
9391 }
9392 } else if (upb_FieldDef_IsRepeated(f)) {
9393 const upb_Array* arr = val.array_val;
9394 size_t i, n = upb_Array_Size(arr);
9395 for (i = 0; i < n; i++) {
9396 upb_MessageValue elem = upb_Array_Get(arr, i);
9397 if (!_upb_Message_DiscardUnknown((upb_Message*)elem.msg_val, subm,
9398 depth)) {
9399 ret = false;
9400 }
9401 }
9402 } else {
9403 if (!_upb_Message_DiscardUnknown((upb_Message*)val.msg_val, subm,
9404 depth)) {
9405 ret = false;
9406 }
9407 }
9408 }
9409
9410 return ret;
9411 }
9412
upb_Message_DiscardUnknown(upb_Message * msg,const upb_MessageDef * m,int maxdepth)9413 bool upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m,
9414 int maxdepth) {
9415 return _upb_Message_DiscardUnknown(msg, m, maxdepth);
9416 }
9417
9418 /** upb/decode.c ************************************************************/
9419
9420 #include <setjmp.h>
9421 #include <string.h>
9422
9423
9424 /* Must be last. */
9425
9426 /* Maps descriptor type -> elem_size_lg2. */
9427 static const uint8_t desctype_to_elem_size_lg2[] = {
9428 -1, /* invalid descriptor type */
9429 3, /* DOUBLE */
9430 2, /* FLOAT */
9431 3, /* INT64 */
9432 3, /* UINT64 */
9433 2, /* INT32 */
9434 3, /* FIXED64 */
9435 2, /* FIXED32 */
9436 0, /* BOOL */
9437 UPB_SIZE(3, 4), /* STRING */
9438 UPB_SIZE(2, 3), /* GROUP */
9439 UPB_SIZE(2, 3), /* MESSAGE */
9440 UPB_SIZE(3, 4), /* BYTES */
9441 2, /* UINT32 */
9442 2, /* ENUM */
9443 2, /* SFIXED32 */
9444 3, /* SFIXED64 */
9445 2, /* SINT32 */
9446 3, /* SINT64 */
9447 };
9448
9449 /* Maps descriptor type -> upb map size. */
9450 static const uint8_t desctype_to_mapsize[] = {
9451 -1, /* invalid descriptor type */
9452 8, /* DOUBLE */
9453 4, /* FLOAT */
9454 8, /* INT64 */
9455 8, /* UINT64 */
9456 4, /* INT32 */
9457 8, /* FIXED64 */
9458 4, /* FIXED32 */
9459 1, /* BOOL */
9460 UPB_MAPTYPE_STRING, /* STRING */
9461 sizeof(void*), /* GROUP */
9462 sizeof(void*), /* MESSAGE */
9463 UPB_MAPTYPE_STRING, /* BYTES */
9464 4, /* UINT32 */
9465 4, /* ENUM */
9466 4, /* SFIXED32 */
9467 8, /* SFIXED64 */
9468 4, /* SINT32 */
9469 8, /* SINT64 */
9470 };
9471
9472 static const unsigned FIXED32_OK_MASK = (1 << kUpb_FieldType_Float) |
9473 (1 << kUpb_FieldType_Fixed32) |
9474 (1 << kUpb_FieldType_SFixed32);
9475
9476 static const unsigned FIXED64_OK_MASK = (1 << kUpb_FieldType_Double) |
9477 (1 << kUpb_FieldType_Fixed64) |
9478 (1 << kUpb_FieldType_SFixed64);
9479
9480 /* Three fake field types for MessageSet. */
9481 #define TYPE_MSGSET_ITEM 19
9482 #define TYPE_COUNT 19
9483
9484 /* Op: an action to be performed for a wire-type/field-type combination. */
9485 #define OP_UNKNOWN -1 /* Unknown field. */
9486 #define OP_MSGSET_ITEM -2
9487 #define OP_SCALAR_LG2(n) (n) /* n in [0, 2, 3] => op in [0, 2, 3] */
9488 #define OP_ENUM 1
9489 #define OP_STRING 4
9490 #define OP_BYTES 5
9491 #define OP_SUBMSG 6
9492 /* Scalar fields use only ops above. Repeated fields can use any op. */
9493 #define OP_FIXPCK_LG2(n) (n + 5) /* n in [2, 3] => op in [7, 8] */
9494 #define OP_VARPCK_LG2(n) (n + 9) /* n in [0, 2, 3] => op in [9, 11, 12] */
9495 #define OP_PACKED_ENUM 13
9496
9497 static const int8_t varint_ops[] = {
9498 OP_UNKNOWN, /* field not found */
9499 OP_UNKNOWN, /* DOUBLE */
9500 OP_UNKNOWN, /* FLOAT */
9501 OP_SCALAR_LG2(3), /* INT64 */
9502 OP_SCALAR_LG2(3), /* UINT64 */
9503 OP_SCALAR_LG2(2), /* INT32 */
9504 OP_UNKNOWN, /* FIXED64 */
9505 OP_UNKNOWN, /* FIXED32 */
9506 OP_SCALAR_LG2(0), /* BOOL */
9507 OP_UNKNOWN, /* STRING */
9508 OP_UNKNOWN, /* GROUP */
9509 OP_UNKNOWN, /* MESSAGE */
9510 OP_UNKNOWN, /* BYTES */
9511 OP_SCALAR_LG2(2), /* UINT32 */
9512 OP_ENUM, /* ENUM */
9513 OP_UNKNOWN, /* SFIXED32 */
9514 OP_UNKNOWN, /* SFIXED64 */
9515 OP_SCALAR_LG2(2), /* SINT32 */
9516 OP_SCALAR_LG2(3), /* SINT64 */
9517 OP_UNKNOWN, /* MSGSET_ITEM */
9518 };
9519
9520 static const int8_t delim_ops[] = {
9521 /* For non-repeated field type. */
9522 OP_UNKNOWN, /* field not found */
9523 OP_UNKNOWN, /* DOUBLE */
9524 OP_UNKNOWN, /* FLOAT */
9525 OP_UNKNOWN, /* INT64 */
9526 OP_UNKNOWN, /* UINT64 */
9527 OP_UNKNOWN, /* INT32 */
9528 OP_UNKNOWN, /* FIXED64 */
9529 OP_UNKNOWN, /* FIXED32 */
9530 OP_UNKNOWN, /* BOOL */
9531 OP_STRING, /* STRING */
9532 OP_UNKNOWN, /* GROUP */
9533 OP_SUBMSG, /* MESSAGE */
9534 OP_BYTES, /* BYTES */
9535 OP_UNKNOWN, /* UINT32 */
9536 OP_UNKNOWN, /* ENUM */
9537 OP_UNKNOWN, /* SFIXED32 */
9538 OP_UNKNOWN, /* SFIXED64 */
9539 OP_UNKNOWN, /* SINT32 */
9540 OP_UNKNOWN, /* SINT64 */
9541 OP_UNKNOWN, /* MSGSET_ITEM */
9542 /* For repeated field type. */
9543 OP_FIXPCK_LG2(3), /* REPEATED DOUBLE */
9544 OP_FIXPCK_LG2(2), /* REPEATED FLOAT */
9545 OP_VARPCK_LG2(3), /* REPEATED INT64 */
9546 OP_VARPCK_LG2(3), /* REPEATED UINT64 */
9547 OP_VARPCK_LG2(2), /* REPEATED INT32 */
9548 OP_FIXPCK_LG2(3), /* REPEATED FIXED64 */
9549 OP_FIXPCK_LG2(2), /* REPEATED FIXED32 */
9550 OP_VARPCK_LG2(0), /* REPEATED BOOL */
9551 OP_STRING, /* REPEATED STRING */
9552 OP_SUBMSG, /* REPEATED GROUP */
9553 OP_SUBMSG, /* REPEATED MESSAGE */
9554 OP_BYTES, /* REPEATED BYTES */
9555 OP_VARPCK_LG2(2), /* REPEATED UINT32 */
9556 OP_PACKED_ENUM, /* REPEATED ENUM */
9557 OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */
9558 OP_FIXPCK_LG2(3), /* REPEATED SFIXED64 */
9559 OP_VARPCK_LG2(2), /* REPEATED SINT32 */
9560 OP_VARPCK_LG2(3), /* REPEATED SINT64 */
9561 /* Omitting MSGSET_*, because we never emit a repeated msgset type */
9562 };
9563
9564 typedef union {
9565 bool bool_val;
9566 uint32_t uint32_val;
9567 uint64_t uint64_val;
9568 uint32_t size;
9569 } wireval;
9570
9571 static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
9572 const upb_MiniTable* layout);
9573
decode_err(upb_Decoder * d,upb_DecodeStatus status)9574 UPB_NORETURN static void* decode_err(upb_Decoder* d, upb_DecodeStatus status) {
9575 assert(status != kUpb_DecodeStatus_Ok);
9576 UPB_LONGJMP(d->err, status);
9577 }
9578
fastdecode_err(upb_Decoder * d,int status)9579 const char* fastdecode_err(upb_Decoder* d, int status) {
9580 assert(status != kUpb_DecodeStatus_Ok);
9581 UPB_LONGJMP(d->err, status);
9582 return NULL;
9583 }
decode_verifyutf8(upb_Decoder * d,const char * buf,int len)9584 static void decode_verifyutf8(upb_Decoder* d, const char* buf, int len) {
9585 if (!decode_verifyutf8_inl(buf, len))
9586 decode_err(d, kUpb_DecodeStatus_BadUtf8);
9587 }
9588
decode_reserve(upb_Decoder * d,upb_Array * arr,size_t elem)9589 static bool decode_reserve(upb_Decoder* d, upb_Array* arr, size_t elem) {
9590 bool need_realloc = arr->size - arr->len < elem;
9591 if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, &d->arena)) {
9592 decode_err(d, kUpb_DecodeStatus_OutOfMemory);
9593 }
9594 return need_realloc;
9595 }
9596
9597 typedef struct {
9598 const char* ptr;
9599 uint64_t val;
9600 } decode_vret;
9601
9602 UPB_NOINLINE
decode_longvarint64(const char * ptr,uint64_t val)9603 static decode_vret decode_longvarint64(const char* ptr, uint64_t val) {
9604 decode_vret ret = {NULL, 0};
9605 uint64_t byte;
9606 int i;
9607 for (i = 1; i < 10; i++) {
9608 byte = (uint8_t)ptr[i];
9609 val += (byte - 1) << (i * 7);
9610 if (!(byte & 0x80)) {
9611 ret.ptr = ptr + i + 1;
9612 ret.val = val;
9613 return ret;
9614 }
9615 }
9616 return ret;
9617 }
9618
9619 UPB_FORCEINLINE
decode_varint64(upb_Decoder * d,const char * ptr,uint64_t * val)9620 static const char* decode_varint64(upb_Decoder* d, const char* ptr,
9621 uint64_t* val) {
9622 uint64_t byte = (uint8_t)*ptr;
9623 if (UPB_LIKELY((byte & 0x80) == 0)) {
9624 *val = byte;
9625 return ptr + 1;
9626 } else {
9627 decode_vret res = decode_longvarint64(ptr, byte);
9628 if (!res.ptr) return decode_err(d, kUpb_DecodeStatus_Malformed);
9629 *val = res.val;
9630 return res.ptr;
9631 }
9632 }
9633
9634 UPB_FORCEINLINE
decode_tag(upb_Decoder * d,const char * ptr,uint32_t * val)9635 static const char* decode_tag(upb_Decoder* d, const char* ptr, uint32_t* val) {
9636 uint64_t byte = (uint8_t)*ptr;
9637 if (UPB_LIKELY((byte & 0x80) == 0)) {
9638 *val = byte;
9639 return ptr + 1;
9640 } else {
9641 const char* start = ptr;
9642 decode_vret res = decode_longvarint64(ptr, byte);
9643 if (!res.ptr || res.ptr - start > 5 || res.val > UINT32_MAX) {
9644 return decode_err(d, kUpb_DecodeStatus_Malformed);
9645 }
9646 *val = res.val;
9647 return res.ptr;
9648 }
9649 }
9650
9651 UPB_FORCEINLINE
upb_Decoder_DecodeSize(upb_Decoder * d,const char * ptr,uint32_t * size)9652 static const char* upb_Decoder_DecodeSize(upb_Decoder* d, const char* ptr,
9653 uint32_t* size) {
9654 uint64_t size64;
9655 ptr = decode_varint64(d, ptr, &size64);
9656 if (size64 >= INT32_MAX || ptr - d->end + (int)size64 > d->limit) {
9657 decode_err(d, kUpb_DecodeStatus_Malformed);
9658 }
9659 *size = size64;
9660 return ptr;
9661 }
9662
decode_munge_int32(wireval * val)9663 static void decode_munge_int32(wireval* val) {
9664 if (!_upb_IsLittleEndian()) {
9665 /* The next stage will memcpy(dst, &val, 4) */
9666 val->uint32_val = val->uint64_val;
9667 }
9668 }
9669
decode_munge(int type,wireval * val)9670 static void decode_munge(int type, wireval* val) {
9671 switch (type) {
9672 case kUpb_FieldType_Bool:
9673 val->bool_val = val->uint64_val != 0;
9674 break;
9675 case kUpb_FieldType_SInt32: {
9676 uint32_t n = val->uint64_val;
9677 val->uint32_val = (n >> 1) ^ -(int32_t)(n & 1);
9678 break;
9679 }
9680 case kUpb_FieldType_SInt64: {
9681 uint64_t n = val->uint64_val;
9682 val->uint64_val = (n >> 1) ^ -(int64_t)(n & 1);
9683 break;
9684 }
9685 case kUpb_FieldType_Int32:
9686 case kUpb_FieldType_UInt32:
9687 case kUpb_FieldType_Enum:
9688 decode_munge_int32(val);
9689 break;
9690 }
9691 }
9692
decode_newsubmsg(upb_Decoder * d,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * field)9693 static upb_Message* decode_newsubmsg(upb_Decoder* d,
9694 const upb_MiniTable_Sub* subs,
9695 const upb_MiniTable_Field* field) {
9696 const upb_MiniTable* subl = subs[field->submsg_index].submsg;
9697 upb_Message* msg = _upb_Message_New_inl(subl, &d->arena);
9698 if (!msg) decode_err(d, kUpb_DecodeStatus_OutOfMemory);
9699 return msg;
9700 }
9701
9702 UPB_NOINLINE
decode_isdonefallback(upb_Decoder * d,const char * ptr,int overrun)9703 const char* decode_isdonefallback(upb_Decoder* d, const char* ptr,
9704 int overrun) {
9705 int status;
9706 ptr = decode_isdonefallback_inl(d, ptr, overrun, &status);
9707 if (ptr == NULL) {
9708 return decode_err(d, status);
9709 }
9710 return ptr;
9711 }
9712
decode_readstr(upb_Decoder * d,const char * ptr,int size,upb_StringView * str)9713 static const char* decode_readstr(upb_Decoder* d, const char* ptr, int size,
9714 upb_StringView* str) {
9715 if (d->options & kUpb_DecodeOption_AliasString) {
9716 str->data = ptr;
9717 } else {
9718 char* data = upb_Arena_Malloc(&d->arena, size);
9719 if (!data) return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
9720 memcpy(data, ptr, size);
9721 str->data = data;
9722 }
9723 str->size = size;
9724 return ptr + size;
9725 }
9726
9727 UPB_FORCEINLINE
decode_tosubmsg2(upb_Decoder * d,const char * ptr,upb_Message * submsg,const upb_MiniTable * subl,int size)9728 static const char* decode_tosubmsg2(upb_Decoder* d, const char* ptr,
9729 upb_Message* submsg,
9730 const upb_MiniTable* subl, int size) {
9731 int saved_delta = decode_pushlimit(d, ptr, size);
9732 if (--d->depth < 0) return decode_err(d, kUpb_DecodeStatus_MaxDepthExceeded);
9733 ptr = decode_msg(d, ptr, submsg, subl);
9734 if (d->end_group != DECODE_NOGROUP)
9735 return decode_err(d, kUpb_DecodeStatus_Malformed);
9736 decode_poplimit(d, ptr, saved_delta);
9737 d->depth++;
9738 return ptr;
9739 }
9740
9741 UPB_FORCEINLINE
decode_tosubmsg(upb_Decoder * d,const char * ptr,upb_Message * submsg,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * field,int size)9742 static const char* decode_tosubmsg(upb_Decoder* d, const char* ptr,
9743 upb_Message* submsg,
9744 const upb_MiniTable_Sub* subs,
9745 const upb_MiniTable_Field* field, int size) {
9746 return decode_tosubmsg2(d, ptr, submsg, subs[field->submsg_index].submsg,
9747 size);
9748 }
9749
9750 UPB_FORCEINLINE
decode_group(upb_Decoder * d,const char * ptr,upb_Message * submsg,const upb_MiniTable * subl,uint32_t number)9751 static const char* decode_group(upb_Decoder* d, const char* ptr,
9752 upb_Message* submsg, const upb_MiniTable* subl,
9753 uint32_t number) {
9754 if (--d->depth < 0) return decode_err(d, kUpb_DecodeStatus_MaxDepthExceeded);
9755 if (decode_isdone(d, &ptr)) {
9756 return decode_err(d, kUpb_DecodeStatus_Malformed);
9757 }
9758 ptr = decode_msg(d, ptr, submsg, subl);
9759 if (d->end_group != number) return decode_err(d, kUpb_DecodeStatus_Malformed);
9760 d->end_group = DECODE_NOGROUP;
9761 d->depth++;
9762 return ptr;
9763 }
9764
9765 UPB_FORCEINLINE
decode_togroup(upb_Decoder * d,const char * ptr,upb_Message * submsg,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * field)9766 static const char* decode_togroup(upb_Decoder* d, const char* ptr,
9767 upb_Message* submsg,
9768 const upb_MiniTable_Sub* subs,
9769 const upb_MiniTable_Field* field) {
9770 const upb_MiniTable* subl = subs[field->submsg_index].submsg;
9771 return decode_group(d, ptr, submsg, subl, field->number);
9772 }
9773
upb_Decoder_EncodeVarint32(uint32_t val,char * ptr)9774 static char* upb_Decoder_EncodeVarint32(uint32_t val, char* ptr) {
9775 do {
9776 uint8_t byte = val & 0x7fU;
9777 val >>= 7;
9778 if (val) byte |= 0x80U;
9779 *(ptr++) = byte;
9780 } while (val);
9781 return ptr;
9782 }
9783
upb_Decode_AddUnknownVarints(upb_Decoder * d,upb_Message * msg,uint32_t val1,uint32_t val2)9784 static void upb_Decode_AddUnknownVarints(upb_Decoder* d, upb_Message* msg,
9785 uint32_t val1, uint32_t val2) {
9786 char buf[20];
9787 char* end = buf;
9788 end = upb_Decoder_EncodeVarint32(val1, end);
9789 end = upb_Decoder_EncodeVarint32(val2, end);
9790
9791 if (!_upb_Message_AddUnknown(msg, buf, end - buf, &d->arena)) {
9792 decode_err(d, kUpb_DecodeStatus_OutOfMemory);
9793 }
9794 }
9795
9796 UPB_NOINLINE
decode_checkenum_slow(upb_Decoder * d,const char * ptr,upb_Message * msg,const upb_MiniTable_Enum * e,const upb_MiniTable_Field * field,uint32_t v)9797 static bool decode_checkenum_slow(upb_Decoder* d, const char* ptr,
9798 upb_Message* msg, const upb_MiniTable_Enum* e,
9799 const upb_MiniTable_Field* field,
9800 uint32_t v) {
9801 // OPT: binary search long lists?
9802 int n = e->value_count;
9803 for (int i = 0; i < n; i++) {
9804 if ((uint32_t)e->values[i] == v) return true;
9805 }
9806
9807 // Unrecognized enum goes into unknown fields.
9808 // For packed fields the tag could be arbitrarily far in the past, so we
9809 // just re-encode the tag and value here.
9810 uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint;
9811 upb_Message* unknown_msg =
9812 field->mode & kUpb_LabelFlags_IsExtension ? d->unknown_msg : msg;
9813 upb_Decode_AddUnknownVarints(d, unknown_msg, tag, v);
9814 return false;
9815 }
9816
9817 UPB_FORCEINLINE
decode_checkenum(upb_Decoder * d,const char * ptr,upb_Message * msg,const upb_MiniTable_Enum * e,const upb_MiniTable_Field * field,wireval * val)9818 static bool decode_checkenum(upb_Decoder* d, const char* ptr, upb_Message* msg,
9819 const upb_MiniTable_Enum* e,
9820 const upb_MiniTable_Field* field, wireval* val) {
9821 uint32_t v = val->uint32_val;
9822
9823 if (UPB_LIKELY(v < 64) && UPB_LIKELY(((1ULL << v) & e->mask))) return true;
9824
9825 return decode_checkenum_slow(d, ptr, msg, e, field, v);
9826 }
9827
9828 UPB_NOINLINE
decode_enum_toarray(upb_Decoder * d,const char * ptr,upb_Message * msg,upb_Array * arr,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * field,wireval * val)9829 static const char* decode_enum_toarray(upb_Decoder* d, const char* ptr,
9830 upb_Message* msg, upb_Array* arr,
9831 const upb_MiniTable_Sub* subs,
9832 const upb_MiniTable_Field* field,
9833 wireval* val) {
9834 const upb_MiniTable_Enum* e = subs[field->submsg_index].subenum;
9835 if (!decode_checkenum(d, ptr, msg, e, field, val)) return ptr;
9836 void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void);
9837 arr->len++;
9838 memcpy(mem, val, 4);
9839 return ptr;
9840 }
9841
9842 UPB_FORCEINLINE
decode_fixed_packed(upb_Decoder * d,const char * ptr,upb_Array * arr,wireval * val,const upb_MiniTable_Field * field,int lg2)9843 static const char* decode_fixed_packed(upb_Decoder* d, const char* ptr,
9844 upb_Array* arr, wireval* val,
9845 const upb_MiniTable_Field* field,
9846 int lg2) {
9847 int mask = (1 << lg2) - 1;
9848 size_t count = val->size >> lg2;
9849 if ((val->size & mask) != 0) {
9850 // Length isn't a round multiple of elem size.
9851 return decode_err(d, kUpb_DecodeStatus_Malformed);
9852 }
9853 decode_reserve(d, arr, count);
9854 void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
9855 arr->len += count;
9856 // Note: if/when the decoder supports multi-buffer input, we will need to
9857 // handle buffer seams here.
9858 if (_upb_IsLittleEndian()) {
9859 memcpy(mem, ptr, val->size);
9860 ptr += val->size;
9861 } else {
9862 const char* end = ptr + val->size;
9863 char* dst = mem;
9864 while (ptr < end) {
9865 if (lg2 == 2) {
9866 uint32_t val;
9867 memcpy(&val, ptr, sizeof(val));
9868 val = _upb_BigEndian_Swap32(val);
9869 memcpy(dst, &val, sizeof(val));
9870 } else {
9871 UPB_ASSERT(lg2 == 3);
9872 uint64_t val;
9873 memcpy(&val, ptr, sizeof(val));
9874 val = _upb_BigEndian_Swap64(val);
9875 memcpy(dst, &val, sizeof(val));
9876 }
9877 ptr += 1 << lg2;
9878 dst += 1 << lg2;
9879 }
9880 }
9881
9882 return ptr;
9883 }
9884
9885 UPB_FORCEINLINE
decode_varint_packed(upb_Decoder * d,const char * ptr,upb_Array * arr,wireval * val,const upb_MiniTable_Field * field,int lg2)9886 static const char* decode_varint_packed(upb_Decoder* d, const char* ptr,
9887 upb_Array* arr, wireval* val,
9888 const upb_MiniTable_Field* field,
9889 int lg2) {
9890 int scale = 1 << lg2;
9891 int saved_limit = decode_pushlimit(d, ptr, val->size);
9892 char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
9893 while (!decode_isdone(d, &ptr)) {
9894 wireval elem;
9895 ptr = decode_varint64(d, ptr, &elem.uint64_val);
9896 decode_munge(field->descriptortype, &elem);
9897 if (decode_reserve(d, arr, 1)) {
9898 out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
9899 }
9900 arr->len++;
9901 memcpy(out, &elem, scale);
9902 out += scale;
9903 }
9904 decode_poplimit(d, ptr, saved_limit);
9905 return ptr;
9906 }
9907
9908 UPB_NOINLINE
decode_enum_packed(upb_Decoder * d,const char * ptr,upb_Message * msg,upb_Array * arr,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * field,wireval * val)9909 static const char* decode_enum_packed(upb_Decoder* d, const char* ptr,
9910 upb_Message* msg, upb_Array* arr,
9911 const upb_MiniTable_Sub* subs,
9912 const upb_MiniTable_Field* field,
9913 wireval* val) {
9914 const upb_MiniTable_Enum* e = subs[field->submsg_index].subenum;
9915 int saved_limit = decode_pushlimit(d, ptr, val->size);
9916 char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void);
9917 while (!decode_isdone(d, &ptr)) {
9918 wireval elem;
9919 ptr = decode_varint64(d, ptr, &elem.uint64_val);
9920 decode_munge_int32(&elem);
9921 if (!decode_checkenum(d, ptr, msg, e, field, &elem)) {
9922 continue;
9923 }
9924 if (decode_reserve(d, arr, 1)) {
9925 out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void);
9926 }
9927 arr->len++;
9928 memcpy(out, &elem, 4);
9929 out += 4;
9930 }
9931 decode_poplimit(d, ptr, saved_limit);
9932 return ptr;
9933 }
9934
decode_toarray(upb_Decoder * d,const char * ptr,upb_Message * msg,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * field,wireval * val,int op)9935 static const char* decode_toarray(upb_Decoder* d, const char* ptr,
9936 upb_Message* msg,
9937 const upb_MiniTable_Sub* subs,
9938 const upb_MiniTable_Field* field,
9939 wireval* val, int op) {
9940 upb_Array** arrp = UPB_PTR_AT(msg, field->offset, void);
9941 upb_Array* arr = *arrp;
9942 void* mem;
9943
9944 if (arr) {
9945 decode_reserve(d, arr, 1);
9946 } else {
9947 size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype];
9948 arr = _upb_Array_New(&d->arena, 4, lg2);
9949 if (!arr) return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
9950 *arrp = arr;
9951 }
9952
9953 switch (op) {
9954 case OP_SCALAR_LG2(0):
9955 case OP_SCALAR_LG2(2):
9956 case OP_SCALAR_LG2(3):
9957 /* Append scalar value. */
9958 mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << op, void);
9959 arr->len++;
9960 memcpy(mem, val, 1 << op);
9961 return ptr;
9962 case OP_STRING:
9963 decode_verifyutf8(d, ptr, val->size);
9964 /* Fallthrough. */
9965 case OP_BYTES: {
9966 /* Append bytes. */
9967 upb_StringView* str = (upb_StringView*)_upb_array_ptr(arr) + arr->len;
9968 arr->len++;
9969 return decode_readstr(d, ptr, val->size, str);
9970 }
9971 case OP_SUBMSG: {
9972 /* Append submessage / group. */
9973 upb_Message* submsg = decode_newsubmsg(d, subs, field);
9974 *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void*), upb_Message*) =
9975 submsg;
9976 arr->len++;
9977 if (UPB_UNLIKELY(field->descriptortype == kUpb_FieldType_Group)) {
9978 return decode_togroup(d, ptr, submsg, subs, field);
9979 } else {
9980 return decode_tosubmsg(d, ptr, submsg, subs, field, val->size);
9981 }
9982 }
9983 case OP_FIXPCK_LG2(2):
9984 case OP_FIXPCK_LG2(3):
9985 return decode_fixed_packed(d, ptr, arr, val, field,
9986 op - OP_FIXPCK_LG2(0));
9987 case OP_VARPCK_LG2(0):
9988 case OP_VARPCK_LG2(2):
9989 case OP_VARPCK_LG2(3):
9990 return decode_varint_packed(d, ptr, arr, val, field,
9991 op - OP_VARPCK_LG2(0));
9992 case OP_ENUM:
9993 return decode_enum_toarray(d, ptr, msg, arr, subs, field, val);
9994 case OP_PACKED_ENUM:
9995 return decode_enum_packed(d, ptr, msg, arr, subs, field, val);
9996 default:
9997 UPB_UNREACHABLE();
9998 }
9999 }
10000
decode_tomap(upb_Decoder * d,const char * ptr,upb_Message * msg,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * field,wireval * val)10001 static const char* decode_tomap(upb_Decoder* d, const char* ptr,
10002 upb_Message* msg, const upb_MiniTable_Sub* subs,
10003 const upb_MiniTable_Field* field,
10004 wireval* val) {
10005 upb_Map** map_p = UPB_PTR_AT(msg, field->offset, upb_Map*);
10006 upb_Map* map = *map_p;
10007 upb_MapEntry ent;
10008 const upb_MiniTable* entry = subs[field->submsg_index].submsg;
10009
10010 if (!map) {
10011 /* Lazily create map. */
10012 const upb_MiniTable_Field* key_field = &entry->fields[0];
10013 const upb_MiniTable_Field* val_field = &entry->fields[1];
10014 char key_size = desctype_to_mapsize[key_field->descriptortype];
10015 char val_size = desctype_to_mapsize[val_field->descriptortype];
10016 UPB_ASSERT(key_field->offset == 0);
10017 UPB_ASSERT(val_field->offset == sizeof(upb_StringView));
10018 map = _upb_Map_New(&d->arena, key_size, val_size);
10019 *map_p = map;
10020 }
10021
10022 /* Parse map entry. */
10023 memset(&ent, 0, sizeof(ent));
10024
10025 if (entry->fields[1].descriptortype == kUpb_FieldType_Message ||
10026 entry->fields[1].descriptortype == kUpb_FieldType_Group) {
10027 /* Create proactively to handle the case where it doesn't appear. */
10028 ent.v.val =
10029 upb_value_ptr(_upb_Message_New(entry->subs[0].submsg, &d->arena));
10030 }
10031
10032 const char* start = ptr;
10033 ptr = decode_tosubmsg(d, ptr, &ent.k, subs, field, val->size);
10034 // check if ent had any unknown fields
10035 size_t size;
10036 upb_Message_GetUnknown(&ent.k, &size);
10037 if (size != 0) {
10038 uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Delimited;
10039 upb_Decode_AddUnknownVarints(d, msg, tag, (uint32_t)(ptr - start));
10040 if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) {
10041 decode_err(d, kUpb_DecodeStatus_OutOfMemory);
10042 }
10043 } else {
10044 if (_upb_Map_Insert(map, &ent.k, map->key_size, &ent.v, map->val_size,
10045 &d->arena) == _kUpb_MapInsertStatus_OutOfMemory) {
10046 decode_err(d, kUpb_DecodeStatus_OutOfMemory);
10047 }
10048 }
10049 return ptr;
10050 }
10051
decode_tomsg(upb_Decoder * d,const char * ptr,upb_Message * msg,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * field,wireval * val,int op)10052 static const char* decode_tomsg(upb_Decoder* d, const char* ptr,
10053 upb_Message* msg, const upb_MiniTable_Sub* subs,
10054 const upb_MiniTable_Field* field, wireval* val,
10055 int op) {
10056 void* mem = UPB_PTR_AT(msg, field->offset, void);
10057 int type = field->descriptortype;
10058
10059 if (UPB_UNLIKELY(op == OP_ENUM) &&
10060 !decode_checkenum(d, ptr, msg, subs[field->submsg_index].subenum, field,
10061 val)) {
10062 return ptr;
10063 }
10064
10065 /* Set presence if necessary. */
10066 if (field->presence > 0) {
10067 _upb_sethas_field(msg, field);
10068 } else if (field->presence < 0) {
10069 /* Oneof case */
10070 uint32_t* oneof_case = _upb_oneofcase_field(msg, field);
10071 if (op == OP_SUBMSG && *oneof_case != field->number) {
10072 memset(mem, 0, sizeof(void*));
10073 }
10074 *oneof_case = field->number;
10075 }
10076
10077 /* Store into message. */
10078 switch (op) {
10079 case OP_SUBMSG: {
10080 upb_Message** submsgp = mem;
10081 upb_Message* submsg = *submsgp;
10082 if (!submsg) {
10083 submsg = decode_newsubmsg(d, subs, field);
10084 *submsgp = submsg;
10085 }
10086 if (UPB_UNLIKELY(type == kUpb_FieldType_Group)) {
10087 ptr = decode_togroup(d, ptr, submsg, subs, field);
10088 } else {
10089 ptr = decode_tosubmsg(d, ptr, submsg, subs, field, val->size);
10090 }
10091 break;
10092 }
10093 case OP_STRING:
10094 decode_verifyutf8(d, ptr, val->size);
10095 /* Fallthrough. */
10096 case OP_BYTES:
10097 return decode_readstr(d, ptr, val->size, mem);
10098 case OP_SCALAR_LG2(3):
10099 memcpy(mem, val, 8);
10100 break;
10101 case OP_ENUM:
10102 case OP_SCALAR_LG2(2):
10103 memcpy(mem, val, 4);
10104 break;
10105 case OP_SCALAR_LG2(0):
10106 memcpy(mem, val, 1);
10107 break;
10108 default:
10109 UPB_UNREACHABLE();
10110 }
10111
10112 return ptr;
10113 }
10114
10115 UPB_NOINLINE
decode_checkrequired(upb_Decoder * d,const char * ptr,const upb_Message * msg,const upb_MiniTable * l)10116 const char* decode_checkrequired(upb_Decoder* d, const char* ptr,
10117 const upb_Message* msg,
10118 const upb_MiniTable* l) {
10119 assert(l->required_count);
10120 if (UPB_LIKELY((d->options & kUpb_DecodeOption_CheckRequired) == 0)) {
10121 return ptr;
10122 }
10123 uint64_t msg_head;
10124 memcpy(&msg_head, msg, 8);
10125 msg_head = _upb_BigEndian_Swap64(msg_head);
10126 if (upb_MiniTable_requiredmask(l) & ~msg_head) {
10127 d->missing_required = true;
10128 }
10129 return ptr;
10130 }
10131
10132 UPB_FORCEINLINE
decode_tryfastdispatch(upb_Decoder * d,const char ** ptr,upb_Message * msg,const upb_MiniTable * layout)10133 static bool decode_tryfastdispatch(upb_Decoder* d, const char** ptr,
10134 upb_Message* msg,
10135 const upb_MiniTable* layout) {
10136 #if UPB_FASTTABLE
10137 if (layout && layout->table_mask != (unsigned char)-1) {
10138 uint16_t tag = fastdecode_loadtag(*ptr);
10139 intptr_t table = decode_totable(layout);
10140 *ptr = fastdecode_tagdispatch(d, *ptr, msg, table, 0, tag);
10141 return true;
10142 }
10143 #endif
10144 return false;
10145 }
10146
upb_Decoder_SkipField(upb_Decoder * d,const char * ptr,uint32_t tag)10147 static const char* upb_Decoder_SkipField(upb_Decoder* d, const char* ptr,
10148 uint32_t tag) {
10149 int field_number = tag >> 3;
10150 int wire_type = tag & 7;
10151 switch (wire_type) {
10152 case kUpb_WireType_Varint: {
10153 uint64_t val;
10154 return decode_varint64(d, ptr, &val);
10155 }
10156 case kUpb_WireType_64Bit:
10157 return ptr + 8;
10158 case kUpb_WireType_32Bit:
10159 return ptr + 4;
10160 case kUpb_WireType_Delimited: {
10161 uint32_t size;
10162 ptr = upb_Decoder_DecodeSize(d, ptr, &size);
10163 return ptr + size;
10164 }
10165 case kUpb_WireType_StartGroup:
10166 return decode_group(d, ptr, NULL, NULL, field_number);
10167 default:
10168 decode_err(d, kUpb_DecodeStatus_Malformed);
10169 }
10170 }
10171
10172 enum {
10173 kStartItemTag = ((1 << 3) | kUpb_WireType_StartGroup),
10174 kEndItemTag = ((1 << 3) | kUpb_WireType_EndGroup),
10175 kTypeIdTag = ((2 << 3) | kUpb_WireType_Varint),
10176 kMessageTag = ((3 << 3) | kUpb_WireType_Delimited),
10177 };
10178
upb_Decoder_AddKnownMessageSetItem(upb_Decoder * d,upb_Message * msg,const upb_MiniTable_Extension * item_mt,const char * data,uint32_t size)10179 static void upb_Decoder_AddKnownMessageSetItem(
10180 upb_Decoder* d, upb_Message* msg, const upb_MiniTable_Extension* item_mt,
10181 const char* data, uint32_t size) {
10182 upb_Message_Extension* ext =
10183 _upb_Message_GetOrCreateExtension(msg, item_mt, &d->arena);
10184 if (UPB_UNLIKELY(!ext)) decode_err(d, kUpb_DecodeStatus_OutOfMemory);
10185 upb_Message* submsg = decode_newsubmsg(d, &ext->ext->sub, &ext->ext->field);
10186 upb_DecodeStatus status = upb_Decode(data, size, submsg, item_mt->sub.submsg,
10187 d->extreg, d->options, &d->arena);
10188 memcpy(&ext->data, &submsg, sizeof(submsg));
10189 if (status != kUpb_DecodeStatus_Ok) decode_err(d, status);
10190 }
10191
upb_Decoder_AddUnknownMessageSetItem(upb_Decoder * d,upb_Message * msg,uint32_t type_id,const char * message_data,uint32_t message_size)10192 static void upb_Decoder_AddUnknownMessageSetItem(upb_Decoder* d,
10193 upb_Message* msg,
10194 uint32_t type_id,
10195 const char* message_data,
10196 uint32_t message_size) {
10197 char buf[60];
10198 char* ptr = buf;
10199 ptr = upb_Decoder_EncodeVarint32(kStartItemTag, ptr);
10200 ptr = upb_Decoder_EncodeVarint32(kTypeIdTag, ptr);
10201 ptr = upb_Decoder_EncodeVarint32(type_id, ptr);
10202 ptr = upb_Decoder_EncodeVarint32(kMessageTag, ptr);
10203 ptr = upb_Decoder_EncodeVarint32(message_size, ptr);
10204 char* split = ptr;
10205
10206 ptr = upb_Decoder_EncodeVarint32(kEndItemTag, ptr);
10207 char* end = ptr;
10208
10209 if (!_upb_Message_AddUnknown(msg, buf, split - buf, &d->arena) ||
10210 !_upb_Message_AddUnknown(msg, message_data, message_size, &d->arena) ||
10211 !_upb_Message_AddUnknown(msg, split, end - split, &d->arena)) {
10212 decode_err(d, kUpb_DecodeStatus_OutOfMemory);
10213 }
10214 }
10215
upb_Decoder_AddMessageSetItem(upb_Decoder * d,upb_Message * msg,const upb_MiniTable * layout,uint32_t type_id,const char * data,uint32_t size)10216 static void upb_Decoder_AddMessageSetItem(upb_Decoder* d, upb_Message* msg,
10217 const upb_MiniTable* layout,
10218 uint32_t type_id, const char* data,
10219 uint32_t size) {
10220 const upb_MiniTable_Extension* item_mt =
10221 _upb_extreg_get(d->extreg, layout, type_id);
10222 if (item_mt) {
10223 upb_Decoder_AddKnownMessageSetItem(d, msg, item_mt, data, size);
10224 } else {
10225 upb_Decoder_AddUnknownMessageSetItem(d, msg, type_id, data, size);
10226 }
10227 }
10228
upb_Decoder_DecodeMessageSetItem(upb_Decoder * d,const char * ptr,upb_Message * msg,const upb_MiniTable * layout)10229 static const char* upb_Decoder_DecodeMessageSetItem(
10230 upb_Decoder* d, const char* ptr, upb_Message* msg,
10231 const upb_MiniTable* layout) {
10232 uint32_t type_id = 0;
10233 upb_StringView preserved = {NULL, 0};
10234 typedef enum {
10235 kUpb_HaveId = 1 << 0,
10236 kUpb_HavePayload = 1 << 1,
10237 } StateMask;
10238 StateMask state_mask = 0;
10239 while (!decode_isdone(d, &ptr)) {
10240 uint32_t tag;
10241 ptr = decode_tag(d, ptr, &tag);
10242 switch (tag) {
10243 case kEndItemTag:
10244 return ptr;
10245 case kTypeIdTag: {
10246 uint64_t tmp;
10247 ptr = decode_varint64(d, ptr, &tmp);
10248 if (state_mask & kUpb_HaveId) break; // Ignore dup.
10249 state_mask |= kUpb_HaveId;
10250 type_id = tmp;
10251 if (state_mask & kUpb_HavePayload) {
10252 upb_Decoder_AddMessageSetItem(d, msg, layout, type_id, preserved.data,
10253 preserved.size);
10254 }
10255 break;
10256 }
10257 case kMessageTag: {
10258 uint32_t size;
10259 ptr = upb_Decoder_DecodeSize(d, ptr, &size);
10260 const char* data = ptr;
10261 ptr += size;
10262 if (state_mask & kUpb_HavePayload) break; // Ignore dup.
10263 state_mask |= kUpb_HavePayload;
10264 if (state_mask & kUpb_HaveId) {
10265 upb_Decoder_AddMessageSetItem(d, msg, layout, type_id, data, size);
10266 } else {
10267 // Out of order, we must preserve the payload.
10268 preserved.data = data;
10269 preserved.size = size;
10270 }
10271 break;
10272 }
10273 default:
10274 // We do not preserve unexpected fields inside a message set item.
10275 ptr = upb_Decoder_SkipField(d, ptr, tag);
10276 break;
10277 }
10278 }
10279 decode_err(d, kUpb_DecodeStatus_Malformed);
10280 }
10281
decode_findfield(upb_Decoder * d,const upb_MiniTable * l,uint32_t field_number,int * last_field_index)10282 static const upb_MiniTable_Field* decode_findfield(upb_Decoder* d,
10283 const upb_MiniTable* l,
10284 uint32_t field_number,
10285 int* last_field_index) {
10286 static upb_MiniTable_Field none = {0, 0, 0, 0, 0, 0};
10287 if (l == NULL) return &none;
10288
10289 size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX
10290 if (idx < l->dense_below) {
10291 /* Fastest case: index into dense fields. */
10292 goto found;
10293 }
10294
10295 if (l->dense_below < l->field_count) {
10296 /* Linear search non-dense fields. Resume scanning from last_field_index
10297 * since fields are usually in order. */
10298 int last = *last_field_index;
10299 for (idx = last; idx < l->field_count; idx++) {
10300 if (l->fields[idx].number == field_number) {
10301 goto found;
10302 }
10303 }
10304
10305 for (idx = l->dense_below; idx < last; idx++) {
10306 if (l->fields[idx].number == field_number) {
10307 goto found;
10308 }
10309 }
10310 }
10311
10312 if (d->extreg) {
10313 switch (l->ext) {
10314 case kUpb_ExtMode_Extendable: {
10315 const upb_MiniTable_Extension* ext =
10316 _upb_extreg_get(d->extreg, l, field_number);
10317 if (ext) return &ext->field;
10318 break;
10319 }
10320 case kUpb_ExtMode_IsMessageSet:
10321 if (field_number == _UPB_MSGSET_ITEM) {
10322 static upb_MiniTable_Field item = {0, 0, 0, 0, TYPE_MSGSET_ITEM, 0};
10323 return &item;
10324 }
10325 break;
10326 }
10327 }
10328
10329 return &none; /* Unknown field. */
10330
10331 found:
10332 UPB_ASSERT(l->fields[idx].number == field_number);
10333 *last_field_index = idx;
10334 return &l->fields[idx];
10335 }
10336
10337 UPB_FORCEINLINE
decode_wireval(upb_Decoder * d,const char * ptr,const upb_MiniTable_Field * field,int wire_type,wireval * val,int * op)10338 static const char* decode_wireval(upb_Decoder* d, const char* ptr,
10339 const upb_MiniTable_Field* field,
10340 int wire_type, wireval* val, int* op) {
10341 switch (wire_type) {
10342 case kUpb_WireType_Varint:
10343 ptr = decode_varint64(d, ptr, &val->uint64_val);
10344 *op = varint_ops[field->descriptortype];
10345 decode_munge(field->descriptortype, val);
10346 return ptr;
10347 case kUpb_WireType_32Bit:
10348 memcpy(&val->uint32_val, ptr, 4);
10349 val->uint32_val = _upb_BigEndian_Swap32(val->uint32_val);
10350 *op = OP_SCALAR_LG2(2);
10351 if (((1 << field->descriptortype) & FIXED32_OK_MASK) == 0) {
10352 *op = OP_UNKNOWN;
10353 }
10354 return ptr + 4;
10355 case kUpb_WireType_64Bit:
10356 memcpy(&val->uint64_val, ptr, 8);
10357 val->uint64_val = _upb_BigEndian_Swap64(val->uint64_val);
10358 *op = OP_SCALAR_LG2(3);
10359 if (((1 << field->descriptortype) & FIXED64_OK_MASK) == 0) {
10360 *op = OP_UNKNOWN;
10361 }
10362 return ptr + 8;
10363 case kUpb_WireType_Delimited: {
10364 int ndx = field->descriptortype;
10365 if (upb_FieldMode_Get(field) == kUpb_FieldMode_Array) ndx += TYPE_COUNT;
10366 ptr = upb_Decoder_DecodeSize(d, ptr, &val->size);
10367 *op = delim_ops[ndx];
10368 return ptr;
10369 }
10370 case kUpb_WireType_StartGroup:
10371 val->uint32_val = field->number;
10372 if (field->descriptortype == kUpb_FieldType_Group) {
10373 *op = OP_SUBMSG;
10374 } else if (field->descriptortype == TYPE_MSGSET_ITEM) {
10375 *op = OP_MSGSET_ITEM;
10376 } else {
10377 *op = OP_UNKNOWN;
10378 }
10379 return ptr;
10380 default:
10381 break;
10382 }
10383 return decode_err(d, kUpb_DecodeStatus_Malformed);
10384 }
10385
10386 UPB_FORCEINLINE
decode_known(upb_Decoder * d,const char * ptr,upb_Message * msg,const upb_MiniTable * layout,const upb_MiniTable_Field * field,int op,wireval * val)10387 static const char* decode_known(upb_Decoder* d, const char* ptr,
10388 upb_Message* msg, const upb_MiniTable* layout,
10389 const upb_MiniTable_Field* field, int op,
10390 wireval* val) {
10391 const upb_MiniTable_Sub* subs = layout->subs;
10392 uint8_t mode = field->mode;
10393
10394 if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) {
10395 const upb_MiniTable_Extension* ext_layout =
10396 (const upb_MiniTable_Extension*)field;
10397 upb_Message_Extension* ext =
10398 _upb_Message_GetOrCreateExtension(msg, ext_layout, &d->arena);
10399 if (UPB_UNLIKELY(!ext)) return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
10400 d->unknown_msg = msg;
10401 msg = &ext->data;
10402 subs = &ext->ext->sub;
10403 }
10404
10405 switch (mode & kUpb_FieldMode_Mask) {
10406 case kUpb_FieldMode_Array:
10407 return decode_toarray(d, ptr, msg, subs, field, val, op);
10408 case kUpb_FieldMode_Map:
10409 return decode_tomap(d, ptr, msg, subs, field, val);
10410 case kUpb_FieldMode_Scalar:
10411 return decode_tomsg(d, ptr, msg, subs, field, val, op);
10412 default:
10413 UPB_UNREACHABLE();
10414 }
10415 }
10416
decode_reverse_skip_varint(const char * ptr,uint32_t val)10417 static const char* decode_reverse_skip_varint(const char* ptr, uint32_t val) {
10418 uint32_t seen = 0;
10419 do {
10420 ptr--;
10421 seen <<= 7;
10422 seen |= *ptr & 0x7f;
10423 } while (seen != val);
10424 return ptr;
10425 }
10426
decode_unknown(upb_Decoder * d,const char * ptr,upb_Message * msg,int field_number,int wire_type,wireval val)10427 static const char* decode_unknown(upb_Decoder* d, const char* ptr,
10428 upb_Message* msg, int field_number,
10429 int wire_type, wireval val) {
10430 if (field_number == 0) return decode_err(d, kUpb_DecodeStatus_Malformed);
10431
10432 // Since unknown fields are the uncommon case, we do a little extra work here
10433 // to walk backwards through the buffer to find the field start. This frees
10434 // up a register in the fast paths (when the field is known), which leads to
10435 // significant speedups in benchmarks.
10436 const char* start = ptr;
10437
10438 if (wire_type == kUpb_WireType_Delimited) ptr += val.size;
10439 if (msg) {
10440 switch (wire_type) {
10441 case kUpb_WireType_Varint:
10442 case kUpb_WireType_Delimited:
10443 start--;
10444 while (start[-1] & 0x80) start--;
10445 break;
10446 case kUpb_WireType_32Bit:
10447 start -= 4;
10448 break;
10449 case kUpb_WireType_64Bit:
10450 start -= 8;
10451 break;
10452 default:
10453 break;
10454 }
10455
10456 assert(start == d->debug_valstart);
10457 uint32_t tag = ((uint32_t)field_number << 3) | wire_type;
10458 start = decode_reverse_skip_varint(start, tag);
10459 assert(start == d->debug_tagstart);
10460
10461 if (wire_type == kUpb_WireType_StartGroup) {
10462 d->unknown = start;
10463 d->unknown_msg = msg;
10464 ptr = decode_group(d, ptr, NULL, NULL, field_number);
10465 start = d->unknown;
10466 d->unknown = NULL;
10467 }
10468 if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) {
10469 return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
10470 }
10471 } else if (wire_type == kUpb_WireType_StartGroup) {
10472 ptr = decode_group(d, ptr, NULL, NULL, field_number);
10473 }
10474 return ptr;
10475 }
10476
10477 UPB_NOINLINE
decode_msg(upb_Decoder * d,const char * ptr,upb_Message * msg,const upb_MiniTable * layout)10478 static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
10479 const upb_MiniTable* layout) {
10480 int last_field_index = 0;
10481
10482 #if UPB_FASTTABLE
10483 // The first time we want to skip fast dispatch, because we may have just been
10484 // invoked by the fast parser to handle a case that it bailed on.
10485 if (!decode_isdone(d, &ptr)) goto nofast;
10486 #endif
10487
10488 while (!decode_isdone(d, &ptr)) {
10489 uint32_t tag;
10490 const upb_MiniTable_Field* field;
10491 int field_number;
10492 int wire_type;
10493 wireval val;
10494 int op;
10495
10496 if (decode_tryfastdispatch(d, &ptr, msg, layout)) break;
10497
10498 #if UPB_FASTTABLE
10499 nofast:
10500 #endif
10501
10502 #ifndef NDEBUG
10503 d->debug_tagstart = ptr;
10504 #endif
10505
10506 UPB_ASSERT(ptr < d->limit_ptr);
10507 ptr = decode_tag(d, ptr, &tag);
10508 field_number = tag >> 3;
10509 wire_type = tag & 7;
10510
10511 #ifndef NDEBUG
10512 d->debug_valstart = ptr;
10513 #endif
10514
10515 if (wire_type == kUpb_WireType_EndGroup) {
10516 d->end_group = field_number;
10517 return ptr;
10518 }
10519
10520 field = decode_findfield(d, layout, field_number, &last_field_index);
10521 ptr = decode_wireval(d, ptr, field, wire_type, &val, &op);
10522
10523 if (op >= 0) {
10524 ptr = decode_known(d, ptr, msg, layout, field, op, &val);
10525 } else {
10526 switch (op) {
10527 case OP_UNKNOWN:
10528 ptr = decode_unknown(d, ptr, msg, field_number, wire_type, val);
10529 break;
10530 case OP_MSGSET_ITEM:
10531 ptr = upb_Decoder_DecodeMessageSetItem(d, ptr, msg, layout);
10532 break;
10533 }
10534 }
10535 }
10536
10537 return UPB_UNLIKELY(layout && layout->required_count)
10538 ? decode_checkrequired(d, ptr, msg, layout)
10539 : ptr;
10540 }
10541
fastdecode_generic(struct upb_Decoder * d,const char * ptr,upb_Message * msg,intptr_t table,uint64_t hasbits,uint64_t data)10542 const char* fastdecode_generic(struct upb_Decoder* d, const char* ptr,
10543 upb_Message* msg, intptr_t table,
10544 uint64_t hasbits, uint64_t data) {
10545 (void)data;
10546 *(uint32_t*)msg |= hasbits;
10547 return decode_msg(d, ptr, msg, decode_totablep(table));
10548 }
10549
decode_top(struct upb_Decoder * d,const char * buf,void * msg,const upb_MiniTable * l)10550 static upb_DecodeStatus decode_top(struct upb_Decoder* d, const char* buf,
10551 void* msg, const upb_MiniTable* l) {
10552 if (!decode_tryfastdispatch(d, &buf, msg, l)) {
10553 decode_msg(d, buf, msg, l);
10554 }
10555 if (d->end_group != DECODE_NOGROUP) return kUpb_DecodeStatus_Malformed;
10556 if (d->missing_required) return kUpb_DecodeStatus_MissingRequired;
10557 return kUpb_DecodeStatus_Ok;
10558 }
10559
upb_Decode(const char * buf,size_t size,void * msg,const upb_MiniTable * l,const upb_ExtensionRegistry * extreg,int options,upb_Arena * arena)10560 upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg,
10561 const upb_MiniTable* l,
10562 const upb_ExtensionRegistry* extreg, int options,
10563 upb_Arena* arena) {
10564 upb_Decoder state;
10565 unsigned depth = (unsigned)options >> 16;
10566
10567 if (size <= 16) {
10568 memset(&state.patch, 0, 32);
10569 if (size) memcpy(&state.patch, buf, size);
10570 buf = state.patch;
10571 state.end = buf + size;
10572 state.limit = 0;
10573 options &= ~kUpb_DecodeOption_AliasString; // Can't alias patch buf.
10574 } else {
10575 state.end = buf + size - 16;
10576 state.limit = 16;
10577 }
10578
10579 state.extreg = extreg;
10580 state.limit_ptr = state.end;
10581 state.unknown = NULL;
10582 state.depth = depth ? depth : 64;
10583 state.end_group = DECODE_NOGROUP;
10584 state.options = (uint16_t)options;
10585 state.missing_required = false;
10586 state.arena.head = arena->head;
10587 state.arena.last_size = arena->last_size;
10588 state.arena.cleanup_metadata = arena->cleanup_metadata;
10589 state.arena.parent = arena;
10590
10591 upb_DecodeStatus status = UPB_SETJMP(state.err);
10592 if (UPB_LIKELY(status == kUpb_DecodeStatus_Ok)) {
10593 status = decode_top(&state, buf, msg, l);
10594 }
10595
10596 arena->head.ptr = state.arena.head.ptr;
10597 arena->head.end = state.arena.head.end;
10598 arena->cleanup_metadata = state.arena.cleanup_metadata;
10599 return status;
10600 }
10601
10602 #undef OP_UNKNOWN
10603 #undef OP_SKIP
10604 #undef OP_SCALAR_LG2
10605 #undef OP_FIXPCK_LG2
10606 #undef OP_VARPCK_LG2
10607 #undef OP_STRING
10608 #undef OP_BYTES
10609 #undef OP_SUBMSG
10610
10611 /** upb/encode.c ************************************************************/
10612 /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
10613
10614
10615 #include <setjmp.h>
10616 #include <string.h>
10617
10618
10619 /* Must be last. */
10620
10621 #define UPB_PB_VARINT_MAX_LEN 10
10622
10623 UPB_NOINLINE
encode_varint64(uint64_t val,char * buf)10624 static size_t encode_varint64(uint64_t val, char* buf) {
10625 size_t i = 0;
10626 do {
10627 uint8_t byte = val & 0x7fU;
10628 val >>= 7;
10629 if (val) byte |= 0x80U;
10630 buf[i++] = byte;
10631 } while (val);
10632 return i;
10633 }
10634
encode_zz32(int32_t n)10635 static uint32_t encode_zz32(int32_t n) {
10636 return ((uint32_t)n << 1) ^ (n >> 31);
10637 }
encode_zz64(int64_t n)10638 static uint64_t encode_zz64(int64_t n) {
10639 return ((uint64_t)n << 1) ^ (n >> 63);
10640 }
10641
10642 typedef struct {
10643 jmp_buf err;
10644 upb_alloc* alloc;
10645 char *buf, *ptr, *limit;
10646 int options;
10647 int depth;
10648 _upb_mapsorter sorter;
10649 } upb_encstate;
10650
upb_roundup_pow2(size_t bytes)10651 static size_t upb_roundup_pow2(size_t bytes) {
10652 size_t ret = 128;
10653 while (ret < bytes) {
10654 ret *= 2;
10655 }
10656 return ret;
10657 }
10658
encode_err(upb_encstate * e)10659 UPB_NORETURN static void encode_err(upb_encstate* e) { UPB_LONGJMP(e->err, 1); }
10660
10661 UPB_NOINLINE
encode_growbuffer(upb_encstate * e,size_t bytes)10662 static void encode_growbuffer(upb_encstate* e, size_t bytes) {
10663 size_t old_size = e->limit - e->buf;
10664 size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
10665 char* new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size);
10666
10667 if (!new_buf) encode_err(e);
10668
10669 /* We want previous data at the end, realloc() put it at the beginning. */
10670 if (old_size > 0) {
10671 memmove(new_buf + new_size - old_size, e->buf, old_size);
10672 }
10673
10674 e->ptr = new_buf + new_size - (e->limit - e->ptr);
10675 e->limit = new_buf + new_size;
10676 e->buf = new_buf;
10677
10678 e->ptr -= bytes;
10679 }
10680
10681 /* Call to ensure that at least "bytes" bytes are available for writing at
10682 * e->ptr. Returns false if the bytes could not be allocated. */
10683 UPB_FORCEINLINE
encode_reserve(upb_encstate * e,size_t bytes)10684 static void encode_reserve(upb_encstate* e, size_t bytes) {
10685 if ((size_t)(e->ptr - e->buf) < bytes) {
10686 encode_growbuffer(e, bytes);
10687 return;
10688 }
10689
10690 e->ptr -= bytes;
10691 }
10692
10693 /* Writes the given bytes to the buffer, handling reserve/advance. */
encode_bytes(upb_encstate * e,const void * data,size_t len)10694 static void encode_bytes(upb_encstate* e, const void* data, size_t len) {
10695 if (len == 0) return; /* memcpy() with zero size is UB */
10696 encode_reserve(e, len);
10697 memcpy(e->ptr, data, len);
10698 }
10699
encode_fixed64(upb_encstate * e,uint64_t val)10700 static void encode_fixed64(upb_encstate* e, uint64_t val) {
10701 val = _upb_BigEndian_Swap64(val);
10702 encode_bytes(e, &val, sizeof(uint64_t));
10703 }
10704
encode_fixed32(upb_encstate * e,uint32_t val)10705 static void encode_fixed32(upb_encstate* e, uint32_t val) {
10706 val = _upb_BigEndian_Swap32(val);
10707 encode_bytes(e, &val, sizeof(uint32_t));
10708 }
10709
10710 UPB_NOINLINE
encode_longvarint(upb_encstate * e,uint64_t val)10711 static void encode_longvarint(upb_encstate* e, uint64_t val) {
10712 size_t len;
10713 char* start;
10714
10715 encode_reserve(e, UPB_PB_VARINT_MAX_LEN);
10716 len = encode_varint64(val, e->ptr);
10717 start = e->ptr + UPB_PB_VARINT_MAX_LEN - len;
10718 memmove(start, e->ptr, len);
10719 e->ptr = start;
10720 }
10721
10722 UPB_FORCEINLINE
encode_varint(upb_encstate * e,uint64_t val)10723 static void encode_varint(upb_encstate* e, uint64_t val) {
10724 if (val < 128 && e->ptr != e->buf) {
10725 --e->ptr;
10726 *e->ptr = val;
10727 } else {
10728 encode_longvarint(e, val);
10729 }
10730 }
10731
encode_double(upb_encstate * e,double d)10732 static void encode_double(upb_encstate* e, double d) {
10733 uint64_t u64;
10734 UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
10735 memcpy(&u64, &d, sizeof(uint64_t));
10736 encode_fixed64(e, u64);
10737 }
10738
encode_float(upb_encstate * e,float d)10739 static void encode_float(upb_encstate* e, float d) {
10740 uint32_t u32;
10741 UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
10742 memcpy(&u32, &d, sizeof(uint32_t));
10743 encode_fixed32(e, u32);
10744 }
10745
encode_tag(upb_encstate * e,uint32_t field_number,uint8_t wire_type)10746 static void encode_tag(upb_encstate* e, uint32_t field_number,
10747 uint8_t wire_type) {
10748 encode_varint(e, (field_number << 3) | wire_type);
10749 }
10750
encode_fixedarray(upb_encstate * e,const upb_Array * arr,size_t elem_size,uint32_t tag)10751 static void encode_fixedarray(upb_encstate* e, const upb_Array* arr,
10752 size_t elem_size, uint32_t tag) {
10753 size_t bytes = arr->len * elem_size;
10754 const char* data = _upb_array_constptr(arr);
10755 const char* ptr = data + bytes - elem_size;
10756
10757 if (tag || !_upb_IsLittleEndian()) {
10758 while (true) {
10759 if (elem_size == 4) {
10760 uint32_t val;
10761 memcpy(&val, ptr, sizeof(val));
10762 val = _upb_BigEndian_Swap32(val);
10763 encode_bytes(e, &val, elem_size);
10764 } else {
10765 UPB_ASSERT(elem_size == 8);
10766 uint64_t val;
10767 memcpy(&val, ptr, sizeof(val));
10768 val = _upb_BigEndian_Swap64(val);
10769 encode_bytes(e, &val, elem_size);
10770 }
10771
10772 if (tag) encode_varint(e, tag);
10773 if (ptr == data) break;
10774 ptr -= elem_size;
10775 }
10776 } else {
10777 encode_bytes(e, data, bytes);
10778 }
10779 }
10780
10781 static void encode_message(upb_encstate* e, const upb_Message* msg,
10782 const upb_MiniTable* m, size_t* size);
10783
encode_scalar(upb_encstate * e,const void * _field_mem,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * f)10784 static void encode_scalar(upb_encstate* e, const void* _field_mem,
10785 const upb_MiniTable_Sub* subs,
10786 const upb_MiniTable_Field* f) {
10787 const char* field_mem = _field_mem;
10788 int wire_type;
10789
10790 #define CASE(ctype, type, wtype, encodeval) \
10791 { \
10792 ctype val = *(ctype*)field_mem; \
10793 encode_##type(e, encodeval); \
10794 wire_type = wtype; \
10795 break; \
10796 }
10797
10798 switch (f->descriptortype) {
10799 case kUpb_FieldType_Double:
10800 CASE(double, double, kUpb_WireType_64Bit, val);
10801 case kUpb_FieldType_Float:
10802 CASE(float, float, kUpb_WireType_32Bit, val);
10803 case kUpb_FieldType_Int64:
10804 case kUpb_FieldType_UInt64:
10805 CASE(uint64_t, varint, kUpb_WireType_Varint, val);
10806 case kUpb_FieldType_UInt32:
10807 CASE(uint32_t, varint, kUpb_WireType_Varint, val);
10808 case kUpb_FieldType_Int32:
10809 case kUpb_FieldType_Enum:
10810 CASE(int32_t, varint, kUpb_WireType_Varint, (int64_t)val);
10811 case kUpb_FieldType_SFixed64:
10812 case kUpb_FieldType_Fixed64:
10813 CASE(uint64_t, fixed64, kUpb_WireType_64Bit, val);
10814 case kUpb_FieldType_Fixed32:
10815 case kUpb_FieldType_SFixed32:
10816 CASE(uint32_t, fixed32, kUpb_WireType_32Bit, val);
10817 case kUpb_FieldType_Bool:
10818 CASE(bool, varint, kUpb_WireType_Varint, val);
10819 case kUpb_FieldType_SInt32:
10820 CASE(int32_t, varint, kUpb_WireType_Varint, encode_zz32(val));
10821 case kUpb_FieldType_SInt64:
10822 CASE(int64_t, varint, kUpb_WireType_Varint, encode_zz64(val));
10823 case kUpb_FieldType_String:
10824 case kUpb_FieldType_Bytes: {
10825 upb_StringView view = *(upb_StringView*)field_mem;
10826 encode_bytes(e, view.data, view.size);
10827 encode_varint(e, view.size);
10828 wire_type = kUpb_WireType_Delimited;
10829 break;
10830 }
10831 case kUpb_FieldType_Group: {
10832 size_t size;
10833 void* submsg = *(void**)field_mem;
10834 const upb_MiniTable* subm = subs[f->submsg_index].submsg;
10835 if (submsg == NULL) {
10836 return;
10837 }
10838 if (--e->depth == 0) encode_err(e);
10839 encode_tag(e, f->number, kUpb_WireType_EndGroup);
10840 encode_message(e, submsg, subm, &size);
10841 wire_type = kUpb_WireType_StartGroup;
10842 e->depth++;
10843 break;
10844 }
10845 case kUpb_FieldType_Message: {
10846 size_t size;
10847 void* submsg = *(void**)field_mem;
10848 const upb_MiniTable* subm = subs[f->submsg_index].submsg;
10849 if (submsg == NULL) {
10850 return;
10851 }
10852 if (--e->depth == 0) encode_err(e);
10853 encode_message(e, submsg, subm, &size);
10854 encode_varint(e, size);
10855 wire_type = kUpb_WireType_Delimited;
10856 e->depth++;
10857 break;
10858 }
10859 default:
10860 UPB_UNREACHABLE();
10861 }
10862 #undef CASE
10863
10864 encode_tag(e, f->number, wire_type);
10865 }
10866
encode_array(upb_encstate * e,const upb_Message * msg,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * f)10867 static void encode_array(upb_encstate* e, const upb_Message* msg,
10868 const upb_MiniTable_Sub* subs,
10869 const upb_MiniTable_Field* f) {
10870 const upb_Array* arr = *UPB_PTR_AT(msg, f->offset, upb_Array*);
10871 bool packed = f->mode & kUpb_LabelFlags_IsPacked;
10872 size_t pre_len = e->limit - e->ptr;
10873
10874 if (arr == NULL || arr->len == 0) {
10875 return;
10876 }
10877
10878 #define VARINT_CASE(ctype, encode) \
10879 { \
10880 const ctype* start = _upb_array_constptr(arr); \
10881 const ctype* ptr = start + arr->len; \
10882 uint32_t tag = packed ? 0 : (f->number << 3) | kUpb_WireType_Varint; \
10883 do { \
10884 ptr--; \
10885 encode_varint(e, encode); \
10886 if (tag) encode_varint(e, tag); \
10887 } while (ptr != start); \
10888 } \
10889 break;
10890
10891 #define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type))
10892
10893 switch (f->descriptortype) {
10894 case kUpb_FieldType_Double:
10895 encode_fixedarray(e, arr, sizeof(double), TAG(kUpb_WireType_64Bit));
10896 break;
10897 case kUpb_FieldType_Float:
10898 encode_fixedarray(e, arr, sizeof(float), TAG(kUpb_WireType_32Bit));
10899 break;
10900 case kUpb_FieldType_SFixed64:
10901 case kUpb_FieldType_Fixed64:
10902 encode_fixedarray(e, arr, sizeof(uint64_t), TAG(kUpb_WireType_64Bit));
10903 break;
10904 case kUpb_FieldType_Fixed32:
10905 case kUpb_FieldType_SFixed32:
10906 encode_fixedarray(e, arr, sizeof(uint32_t), TAG(kUpb_WireType_32Bit));
10907 break;
10908 case kUpb_FieldType_Int64:
10909 case kUpb_FieldType_UInt64:
10910 VARINT_CASE(uint64_t, *ptr);
10911 case kUpb_FieldType_UInt32:
10912 VARINT_CASE(uint32_t, *ptr);
10913 case kUpb_FieldType_Int32:
10914 case kUpb_FieldType_Enum:
10915 VARINT_CASE(int32_t, (int64_t)*ptr);
10916 case kUpb_FieldType_Bool:
10917 VARINT_CASE(bool, *ptr);
10918 case kUpb_FieldType_SInt32:
10919 VARINT_CASE(int32_t, encode_zz32(*ptr));
10920 case kUpb_FieldType_SInt64:
10921 VARINT_CASE(int64_t, encode_zz64(*ptr));
10922 case kUpb_FieldType_String:
10923 case kUpb_FieldType_Bytes: {
10924 const upb_StringView* start = _upb_array_constptr(arr);
10925 const upb_StringView* ptr = start + arr->len;
10926 do {
10927 ptr--;
10928 encode_bytes(e, ptr->data, ptr->size);
10929 encode_varint(e, ptr->size);
10930 encode_tag(e, f->number, kUpb_WireType_Delimited);
10931 } while (ptr != start);
10932 return;
10933 }
10934 case kUpb_FieldType_Group: {
10935 const void* const* start = _upb_array_constptr(arr);
10936 const void* const* ptr = start + arr->len;
10937 const upb_MiniTable* subm = subs[f->submsg_index].submsg;
10938 if (--e->depth == 0) encode_err(e);
10939 do {
10940 size_t size;
10941 ptr--;
10942 encode_tag(e, f->number, kUpb_WireType_EndGroup);
10943 encode_message(e, *ptr, subm, &size);
10944 encode_tag(e, f->number, kUpb_WireType_StartGroup);
10945 } while (ptr != start);
10946 e->depth++;
10947 return;
10948 }
10949 case kUpb_FieldType_Message: {
10950 const void* const* start = _upb_array_constptr(arr);
10951 const void* const* ptr = start + arr->len;
10952 const upb_MiniTable* subm = subs[f->submsg_index].submsg;
10953 if (--e->depth == 0) encode_err(e);
10954 do {
10955 size_t size;
10956 ptr--;
10957 encode_message(e, *ptr, subm, &size);
10958 encode_varint(e, size);
10959 encode_tag(e, f->number, kUpb_WireType_Delimited);
10960 } while (ptr != start);
10961 e->depth++;
10962 return;
10963 }
10964 }
10965 #undef VARINT_CASE
10966
10967 if (packed) {
10968 encode_varint(e, e->limit - e->ptr - pre_len);
10969 encode_tag(e, f->number, kUpb_WireType_Delimited);
10970 }
10971 }
10972
encode_mapentry(upb_encstate * e,uint32_t number,const upb_MiniTable * layout,const upb_MapEntry * ent)10973 static void encode_mapentry(upb_encstate* e, uint32_t number,
10974 const upb_MiniTable* layout,
10975 const upb_MapEntry* ent) {
10976 const upb_MiniTable_Field* key_field = &layout->fields[0];
10977 const upb_MiniTable_Field* val_field = &layout->fields[1];
10978 size_t pre_len = e->limit - e->ptr;
10979 size_t size;
10980 encode_scalar(e, &ent->v, layout->subs, val_field);
10981 encode_scalar(e, &ent->k, layout->subs, key_field);
10982 size = (e->limit - e->ptr) - pre_len;
10983 encode_varint(e, size);
10984 encode_tag(e, number, kUpb_WireType_Delimited);
10985 }
10986
encode_map(upb_encstate * e,const upb_Message * msg,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * f)10987 static void encode_map(upb_encstate* e, const upb_Message* msg,
10988 const upb_MiniTable_Sub* subs,
10989 const upb_MiniTable_Field* f) {
10990 const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*);
10991 const upb_MiniTable* layout = subs[f->submsg_index].submsg;
10992 UPB_ASSERT(layout->field_count == 2);
10993
10994 if (map == NULL) return;
10995
10996 if (e->options & kUpb_Encode_Deterministic) {
10997 _upb_sortedmap sorted;
10998 _upb_mapsorter_pushmap(&e->sorter, layout->fields[0].descriptortype, map,
10999 &sorted);
11000 upb_MapEntry ent;
11001 while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) {
11002 encode_mapentry(e, f->number, layout, &ent);
11003 }
11004 _upb_mapsorter_popmap(&e->sorter, &sorted);
11005 } else {
11006 upb_strtable_iter i;
11007 upb_strtable_begin(&i, &map->table);
11008 for (; !upb_strtable_done(&i); upb_strtable_next(&i)) {
11009 upb_StringView key = upb_strtable_iter_key(&i);
11010 const upb_value val = upb_strtable_iter_value(&i);
11011 upb_MapEntry ent;
11012 _upb_map_fromkey(key, &ent.k, map->key_size);
11013 _upb_map_fromvalue(val, &ent.v, map->val_size);
11014 encode_mapentry(e, f->number, layout, &ent);
11015 }
11016 }
11017 }
11018
encode_shouldencode(upb_encstate * e,const upb_Message * msg,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * f)11019 static bool encode_shouldencode(upb_encstate* e, const upb_Message* msg,
11020 const upb_MiniTable_Sub* subs,
11021 const upb_MiniTable_Field* f) {
11022 if (f->presence == 0) {
11023 /* Proto3 presence or map/array. */
11024 const void* mem = UPB_PTR_AT(msg, f->offset, void);
11025 switch (f->mode >> kUpb_FieldRep_Shift) {
11026 case kUpb_FieldRep_1Byte: {
11027 char ch;
11028 memcpy(&ch, mem, 1);
11029 return ch != 0;
11030 }
11031 #if UINTPTR_MAX == 0xffffffff
11032 case kUpb_FieldRep_Pointer:
11033 #endif
11034 case kUpb_FieldRep_4Byte: {
11035 uint32_t u32;
11036 memcpy(&u32, mem, 4);
11037 return u32 != 0;
11038 }
11039 #if UINTPTR_MAX != 0xffffffff
11040 case kUpb_FieldRep_Pointer:
11041 #endif
11042 case kUpb_FieldRep_8Byte: {
11043 uint64_t u64;
11044 memcpy(&u64, mem, 8);
11045 return u64 != 0;
11046 }
11047 case kUpb_FieldRep_StringView: {
11048 const upb_StringView* str = (const upb_StringView*)mem;
11049 return str->size != 0;
11050 }
11051 default:
11052 UPB_UNREACHABLE();
11053 }
11054 } else if (f->presence > 0) {
11055 /* Proto2 presence: hasbit. */
11056 return _upb_hasbit_field(msg, f);
11057 } else {
11058 /* Field is in a oneof. */
11059 return _upb_getoneofcase_field(msg, f) == f->number;
11060 }
11061 }
11062
encode_field(upb_encstate * e,const upb_Message * msg,const upb_MiniTable_Sub * subs,const upb_MiniTable_Field * field)11063 static void encode_field(upb_encstate* e, const upb_Message* msg,
11064 const upb_MiniTable_Sub* subs,
11065 const upb_MiniTable_Field* field) {
11066 switch (upb_FieldMode_Get(field)) {
11067 case kUpb_FieldMode_Array:
11068 encode_array(e, msg, subs, field);
11069 break;
11070 case kUpb_FieldMode_Map:
11071 encode_map(e, msg, subs, field);
11072 break;
11073 case kUpb_FieldMode_Scalar:
11074 encode_scalar(e, UPB_PTR_AT(msg, field->offset, void), subs, field);
11075 break;
11076 default:
11077 UPB_UNREACHABLE();
11078 }
11079 }
11080
11081 /* message MessageSet {
11082 * repeated group Item = 1 {
11083 * required int32 type_id = 2;
11084 * required string message = 3;
11085 * }
11086 * } */
encode_msgset_item(upb_encstate * e,const upb_Message_Extension * ext)11087 static void encode_msgset_item(upb_encstate* e,
11088 const upb_Message_Extension* ext) {
11089 size_t size;
11090 encode_tag(e, 1, kUpb_WireType_EndGroup);
11091 encode_message(e, ext->data.ptr, ext->ext->sub.submsg, &size);
11092 encode_varint(e, size);
11093 encode_tag(e, 3, kUpb_WireType_Delimited);
11094 encode_varint(e, ext->ext->field.number);
11095 encode_tag(e, 2, kUpb_WireType_Varint);
11096 encode_tag(e, 1, kUpb_WireType_StartGroup);
11097 }
11098
encode_message(upb_encstate * e,const upb_Message * msg,const upb_MiniTable * m,size_t * size)11099 static void encode_message(upb_encstate* e, const upb_Message* msg,
11100 const upb_MiniTable* m, size_t* size) {
11101 size_t pre_len = e->limit - e->ptr;
11102
11103 if ((e->options & kUpb_Encode_CheckRequired) && m->required_count) {
11104 uint64_t msg_head;
11105 memcpy(&msg_head, msg, 8);
11106 msg_head = _upb_BigEndian_Swap64(msg_head);
11107 if (upb_MiniTable_requiredmask(m) & ~msg_head) {
11108 encode_err(e);
11109 }
11110 }
11111
11112 if ((e->options & kUpb_Encode_SkipUnknown) == 0) {
11113 size_t unknown_size;
11114 const char* unknown = upb_Message_GetUnknown(msg, &unknown_size);
11115
11116 if (unknown) {
11117 encode_bytes(e, unknown, unknown_size);
11118 }
11119 }
11120
11121 if (m->ext != kUpb_ExtMode_NonExtendable) {
11122 /* Encode all extensions together. Unlike C++, we do not attempt to keep
11123 * these in field number order relative to normal fields or even to each
11124 * other. */
11125 size_t ext_count;
11126 const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &ext_count);
11127 if (ext_count) {
11128 const upb_Message_Extension* end = ext + ext_count;
11129 for (; ext != end; ext++) {
11130 if (UPB_UNLIKELY(m->ext == kUpb_ExtMode_IsMessageSet)) {
11131 encode_msgset_item(e, ext);
11132 } else {
11133 encode_field(e, &ext->data, &ext->ext->sub, &ext->ext->field);
11134 }
11135 }
11136 }
11137 }
11138
11139 if (m->field_count) {
11140 const upb_MiniTable_Field* f = &m->fields[m->field_count];
11141 const upb_MiniTable_Field* first = &m->fields[0];
11142 while (f != first) {
11143 f--;
11144 if (encode_shouldencode(e, msg, m->subs, f)) {
11145 encode_field(e, msg, m->subs, f);
11146 }
11147 }
11148 }
11149
11150 *size = (e->limit - e->ptr) - pre_len;
11151 }
11152
upb_Encode(const void * msg,const upb_MiniTable * l,int options,upb_Arena * arena,size_t * size)11153 char* upb_Encode(const void* msg, const upb_MiniTable* l, int options,
11154 upb_Arena* arena, size_t* size) {
11155 upb_encstate e;
11156 unsigned depth = (unsigned)options >> 16;
11157
11158 e.alloc = upb_Arena_Alloc(arena);
11159 e.buf = NULL;
11160 e.limit = NULL;
11161 e.ptr = NULL;
11162 e.depth = depth ? depth : 64;
11163 e.options = options;
11164 _upb_mapsorter_init(&e.sorter);
11165 char* ret = NULL;
11166
11167 if (UPB_SETJMP(e.err)) {
11168 *size = 0;
11169 ret = NULL;
11170 } else {
11171 encode_message(&e, msg, l, size);
11172 *size = e.limit - e.ptr;
11173 if (*size == 0) {
11174 static char ch;
11175 ret = &ch;
11176 } else {
11177 UPB_ASSERT(e.ptr);
11178 ret = e.ptr;
11179 }
11180 }
11181
11182 _upb_mapsorter_destroy(&e.sorter);
11183 return ret;
11184 }
11185
11186 /** upb/msg.c ************************************************************/
11187
11188
11189 /** upb_Message ***************************************************************/
11190
11191 static const size_t overhead = sizeof(upb_Message_InternalData);
11192
upb_Message_Getinternal_const(const upb_Message * msg)11193 static const upb_Message_Internal* upb_Message_Getinternal_const(
11194 const upb_Message* msg) {
11195 ptrdiff_t size = sizeof(upb_Message_Internal);
11196 return (upb_Message_Internal*)((char*)msg - size);
11197 }
11198
_upb_Message_New(const upb_MiniTable * l,upb_Arena * a)11199 upb_Message* _upb_Message_New(const upb_MiniTable* l, upb_Arena* a) {
11200 return _upb_Message_New_inl(l, a);
11201 }
11202
_upb_Message_Clear(upb_Message * msg,const upb_MiniTable * l)11203 void _upb_Message_Clear(upb_Message* msg, const upb_MiniTable* l) {
11204 void* mem = UPB_PTR_AT(msg, -sizeof(upb_Message_Internal), char);
11205 memset(mem, 0, upb_msg_sizeof(l));
11206 }
11207
realloc_internal(upb_Message * msg,size_t need,upb_Arena * arena)11208 static bool realloc_internal(upb_Message* msg, size_t need, upb_Arena* arena) {
11209 upb_Message_Internal* in = upb_Message_Getinternal(msg);
11210 if (!in->internal) {
11211 /* No internal data, allocate from scratch. */
11212 size_t size = UPB_MAX(128, _upb_Log2CeilingSize(need + overhead));
11213 upb_Message_InternalData* internal = upb_Arena_Malloc(arena, size);
11214 if (!internal) return false;
11215 internal->size = size;
11216 internal->unknown_end = overhead;
11217 internal->ext_begin = size;
11218 in->internal = internal;
11219 } else if (in->internal->ext_begin - in->internal->unknown_end < need) {
11220 /* Internal data is too small, reallocate. */
11221 size_t new_size = _upb_Log2CeilingSize(in->internal->size + need);
11222 size_t ext_bytes = in->internal->size - in->internal->ext_begin;
11223 size_t new_ext_begin = new_size - ext_bytes;
11224 upb_Message_InternalData* internal =
11225 upb_Arena_Realloc(arena, in->internal, in->internal->size, new_size);
11226 if (!internal) return false;
11227 if (ext_bytes) {
11228 /* Need to move extension data to the end. */
11229 char* ptr = (char*)internal;
11230 memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes);
11231 }
11232 internal->ext_begin = new_ext_begin;
11233 internal->size = new_size;
11234 in->internal = internal;
11235 }
11236 UPB_ASSERT(in->internal->ext_begin - in->internal->unknown_end >= need);
11237 return true;
11238 }
11239
_upb_Message_AddUnknown(upb_Message * msg,const char * data,size_t len,upb_Arena * arena)11240 bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len,
11241 upb_Arena* arena) {
11242 if (!realloc_internal(msg, len, arena)) return false;
11243 upb_Message_Internal* in = upb_Message_Getinternal(msg);
11244 memcpy(UPB_PTR_AT(in->internal, in->internal->unknown_end, char), data, len);
11245 in->internal->unknown_end += len;
11246 return true;
11247 }
11248
_upb_Message_DiscardUnknown_shallow(upb_Message * msg)11249 void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) {
11250 upb_Message_Internal* in = upb_Message_Getinternal(msg);
11251 if (in->internal) {
11252 in->internal->unknown_end = overhead;
11253 }
11254 }
11255
upb_Message_GetUnknown(const upb_Message * msg,size_t * len)11256 const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len) {
11257 const upb_Message_Internal* in = upb_Message_Getinternal_const(msg);
11258 if (in->internal) {
11259 *len = in->internal->unknown_end - overhead;
11260 return (char*)(in->internal + 1);
11261 } else {
11262 *len = 0;
11263 return NULL;
11264 }
11265 }
11266
_upb_Message_Getexts(const upb_Message * msg,size_t * count)11267 const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg,
11268 size_t* count) {
11269 const upb_Message_Internal* in = upb_Message_Getinternal_const(msg);
11270 if (in->internal) {
11271 *count = (in->internal->size - in->internal->ext_begin) /
11272 sizeof(upb_Message_Extension);
11273 return UPB_PTR_AT(in->internal, in->internal->ext_begin, void);
11274 } else {
11275 *count = 0;
11276 return NULL;
11277 }
11278 }
11279
_upb_Message_Getext(const upb_Message * msg,const upb_MiniTable_Extension * e)11280 const upb_Message_Extension* _upb_Message_Getext(
11281 const upb_Message* msg, const upb_MiniTable_Extension* e) {
11282 size_t n;
11283 const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &n);
11284
11285 /* For now we use linear search exclusively to find extensions. If this
11286 * becomes an issue due to messages with lots of extensions, we can introduce
11287 * a table of some sort. */
11288 for (size_t i = 0; i < n; i++) {
11289 if (ext[i].ext == e) {
11290 return &ext[i];
11291 }
11292 }
11293
11294 return NULL;
11295 }
11296
_upb_Message_Clearext(upb_Message * msg,const upb_MiniTable_Extension * ext_l)11297 void _upb_Message_Clearext(upb_Message* msg,
11298 const upb_MiniTable_Extension* ext_l) {
11299 upb_Message_Internal* in = upb_Message_Getinternal(msg);
11300 if (!in->internal) return;
11301 const upb_Message_Extension* base =
11302 UPB_PTR_AT(in->internal, in->internal->ext_begin, void);
11303 upb_Message_Extension* ext =
11304 (upb_Message_Extension*)_upb_Message_Getext(msg, ext_l);
11305 if (ext) {
11306 *ext = *base;
11307 in->internal->ext_begin += sizeof(upb_Message_Extension);
11308 }
11309 }
11310
_upb_Message_GetOrCreateExtension(upb_Message * msg,const upb_MiniTable_Extension * e,upb_Arena * arena)11311 upb_Message_Extension* _upb_Message_GetOrCreateExtension(
11312 upb_Message* msg, const upb_MiniTable_Extension* e, upb_Arena* arena) {
11313 upb_Message_Extension* ext =
11314 (upb_Message_Extension*)_upb_Message_Getext(msg, e);
11315 if (ext) return ext;
11316 if (!realloc_internal(msg, sizeof(upb_Message_Extension), arena)) return NULL;
11317 upb_Message_Internal* in = upb_Message_Getinternal(msg);
11318 in->internal->ext_begin -= sizeof(upb_Message_Extension);
11319 ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void);
11320 memset(ext, 0, sizeof(upb_Message_Extension));
11321 ext->ext = e;
11322 return ext;
11323 }
11324
upb_Message_ExtensionCount(const upb_Message * msg)11325 size_t upb_Message_ExtensionCount(const upb_Message* msg) {
11326 size_t count;
11327 _upb_Message_Getexts(msg, &count);
11328 return count;
11329 }
11330
11331 /** upb_Array *****************************************************************/
11332
_upb_array_realloc(upb_Array * arr,size_t min_size,upb_Arena * arena)11333 bool _upb_array_realloc(upb_Array* arr, size_t min_size, upb_Arena* arena) {
11334 size_t new_size = UPB_MAX(arr->size, 4);
11335 int elem_size_lg2 = arr->data & 7;
11336 size_t old_bytes = arr->size << elem_size_lg2;
11337 size_t new_bytes;
11338 void* ptr = _upb_array_ptr(arr);
11339
11340 /* Log2 ceiling of size. */
11341 while (new_size < min_size) new_size *= 2;
11342
11343 new_bytes = new_size << elem_size_lg2;
11344 ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes);
11345
11346 if (!ptr) {
11347 return false;
11348 }
11349
11350 arr->data = _upb_tag_arrptr(ptr, elem_size_lg2);
11351 arr->size = new_size;
11352 return true;
11353 }
11354
getorcreate_array(upb_Array ** arr_ptr,int elem_size_lg2,upb_Arena * arena)11355 static upb_Array* getorcreate_array(upb_Array** arr_ptr, int elem_size_lg2,
11356 upb_Arena* arena) {
11357 upb_Array* arr = *arr_ptr;
11358 if (!arr) {
11359 arr = _upb_Array_New(arena, 4, elem_size_lg2);
11360 if (!arr) return NULL;
11361 *arr_ptr = arr;
11362 }
11363 return arr;
11364 }
11365
_upb_Array_Resize_fallback(upb_Array ** arr_ptr,size_t size,int elem_size_lg2,upb_Arena * arena)11366 void* _upb_Array_Resize_fallback(upb_Array** arr_ptr, size_t size,
11367 int elem_size_lg2, upb_Arena* arena) {
11368 upb_Array* arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
11369 return arr && _upb_Array_Resize(arr, size, arena) ? _upb_array_ptr(arr)
11370 : NULL;
11371 }
11372
_upb_Array_Append_fallback(upb_Array ** arr_ptr,const void * value,int elem_size_lg2,upb_Arena * arena)11373 bool _upb_Array_Append_fallback(upb_Array** arr_ptr, const void* value,
11374 int elem_size_lg2, upb_Arena* arena) {
11375 upb_Array* arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
11376 if (!arr) return false;
11377
11378 size_t elems = arr->len;
11379
11380 if (!_upb_Array_Resize(arr, elems + 1, arena)) {
11381 return false;
11382 }
11383
11384 char* data = _upb_array_ptr(arr);
11385 memcpy(data + (elems << elem_size_lg2), value, 1 << elem_size_lg2);
11386 return true;
11387 }
11388
11389 /** upb_Map *******************************************************************/
11390
_upb_Map_New(upb_Arena * a,size_t key_size,size_t value_size)11391 upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) {
11392 upb_Map* map = upb_Arena_Malloc(a, sizeof(upb_Map));
11393
11394 if (!map) {
11395 return NULL;
11396 }
11397
11398 upb_strtable_init(&map->table, 4, a);
11399 map->key_size = key_size;
11400 map->val_size = value_size;
11401
11402 return map;
11403 }
11404
_upb_mapsorter_getkeys(const void * _a,const void * _b,void * a_key,void * b_key,size_t size)11405 static void _upb_mapsorter_getkeys(const void* _a, const void* _b, void* a_key,
11406 void* b_key, size_t size) {
11407 const upb_tabent* const* a = _a;
11408 const upb_tabent* const* b = _b;
11409 upb_StringView a_tabkey = upb_tabstrview((*a)->key);
11410 upb_StringView b_tabkey = upb_tabstrview((*b)->key);
11411 _upb_map_fromkey(a_tabkey, a_key, size);
11412 _upb_map_fromkey(b_tabkey, b_key, size);
11413 }
11414
11415 #define UPB_COMPARE_INTEGERS(a, b) ((a) < (b) ? -1 : ((a) == (b) ? 0 : 1))
11416
_upb_mapsorter_cmpi64(const void * _a,const void * _b)11417 static int _upb_mapsorter_cmpi64(const void* _a, const void* _b) {
11418 int64_t a, b;
11419 _upb_mapsorter_getkeys(_a, _b, &a, &b, 8);
11420 return UPB_COMPARE_INTEGERS(a, b);
11421 }
11422
_upb_mapsorter_cmpu64(const void * _a,const void * _b)11423 static int _upb_mapsorter_cmpu64(const void* _a, const void* _b) {
11424 uint64_t a, b;
11425 _upb_mapsorter_getkeys(_a, _b, &a, &b, 8);
11426 return UPB_COMPARE_INTEGERS(a, b);
11427 }
11428
_upb_mapsorter_cmpi32(const void * _a,const void * _b)11429 static int _upb_mapsorter_cmpi32(const void* _a, const void* _b) {
11430 int32_t a, b;
11431 _upb_mapsorter_getkeys(_a, _b, &a, &b, 4);
11432 return UPB_COMPARE_INTEGERS(a, b);
11433 }
11434
_upb_mapsorter_cmpu32(const void * _a,const void * _b)11435 static int _upb_mapsorter_cmpu32(const void* _a, const void* _b) {
11436 uint32_t a, b;
11437 _upb_mapsorter_getkeys(_a, _b, &a, &b, 4);
11438 return UPB_COMPARE_INTEGERS(a, b);
11439 }
11440
_upb_mapsorter_cmpbool(const void * _a,const void * _b)11441 static int _upb_mapsorter_cmpbool(const void* _a, const void* _b) {
11442 bool a, b;
11443 _upb_mapsorter_getkeys(_a, _b, &a, &b, 1);
11444 return UPB_COMPARE_INTEGERS(a, b);
11445 }
11446
_upb_mapsorter_cmpstr(const void * _a,const void * _b)11447 static int _upb_mapsorter_cmpstr(const void* _a, const void* _b) {
11448 upb_StringView a, b;
11449 _upb_mapsorter_getkeys(_a, _b, &a, &b, UPB_MAPTYPE_STRING);
11450 size_t common_size = UPB_MIN(a.size, b.size);
11451 int cmp = memcmp(a.data, b.data, common_size);
11452 if (cmp) return -cmp;
11453 return UPB_COMPARE_INTEGERS(a.size, b.size);
11454 }
11455
11456 #undef UPB_COMPARE_INTEGERS
11457
_upb_mapsorter_pushmap(_upb_mapsorter * s,upb_FieldType key_type,const upb_Map * map,_upb_sortedmap * sorted)11458 bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type,
11459 const upb_Map* map, _upb_sortedmap* sorted) {
11460 int map_size = _upb_Map_Size(map);
11461 sorted->start = s->size;
11462 sorted->pos = sorted->start;
11463 sorted->end = sorted->start + map_size;
11464
11465 /* Grow s->entries if necessary. */
11466 if (sorted->end > s->cap) {
11467 s->cap = _upb_Log2CeilingSize(sorted->end);
11468 s->entries = realloc(s->entries, s->cap * sizeof(*s->entries));
11469 if (!s->entries) return false;
11470 }
11471
11472 s->size = sorted->end;
11473
11474 /* Copy non-empty entries from the table to s->entries. */
11475 upb_tabent const** dst = &s->entries[sorted->start];
11476 const upb_tabent* src = map->table.t.entries;
11477 const upb_tabent* end = src + upb_table_size(&map->table.t);
11478 for (; src < end; src++) {
11479 if (!upb_tabent_isempty(src)) {
11480 *dst = src;
11481 dst++;
11482 }
11483 }
11484 UPB_ASSERT(dst == &s->entries[sorted->end]);
11485
11486 /* Sort entries according to the key type. */
11487
11488 int (*compar)(const void*, const void*);
11489
11490 switch (key_type) {
11491 case kUpb_FieldType_Int64:
11492 case kUpb_FieldType_SFixed64:
11493 case kUpb_FieldType_SInt64:
11494 compar = _upb_mapsorter_cmpi64;
11495 break;
11496 case kUpb_FieldType_UInt64:
11497 case kUpb_FieldType_Fixed64:
11498 compar = _upb_mapsorter_cmpu64;
11499 break;
11500 case kUpb_FieldType_Int32:
11501 case kUpb_FieldType_SInt32:
11502 case kUpb_FieldType_SFixed32:
11503 case kUpb_FieldType_Enum:
11504 compar = _upb_mapsorter_cmpi32;
11505 break;
11506 case kUpb_FieldType_UInt32:
11507 case kUpb_FieldType_Fixed32:
11508 compar = _upb_mapsorter_cmpu32;
11509 break;
11510 case kUpb_FieldType_Bool:
11511 compar = _upb_mapsorter_cmpbool;
11512 break;
11513 case kUpb_FieldType_String:
11514 case kUpb_FieldType_Bytes:
11515 compar = _upb_mapsorter_cmpstr;
11516 break;
11517 default:
11518 UPB_UNREACHABLE();
11519 }
11520
11521 qsort(&s->entries[sorted->start], map_size, sizeof(*s->entries), compar);
11522 return true;
11523 }
11524
11525 /** upb_ExtensionRegistry *****************************************************/
11526
11527 struct upb_ExtensionRegistry {
11528 upb_Arena* arena;
11529 upb_strtable exts; /* Key is upb_MiniTable* concatenated with fieldnum. */
11530 };
11531
11532 #define EXTREG_KEY_SIZE (sizeof(upb_MiniTable*) + sizeof(uint32_t))
11533
extreg_key(char * buf,const upb_MiniTable * l,uint32_t fieldnum)11534 static void extreg_key(char* buf, const upb_MiniTable* l, uint32_t fieldnum) {
11535 memcpy(buf, &l, sizeof(l));
11536 memcpy(buf + sizeof(l), &fieldnum, sizeof(fieldnum));
11537 }
11538
upb_ExtensionRegistry_New(upb_Arena * arena)11539 upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) {
11540 upb_ExtensionRegistry* r = upb_Arena_Malloc(arena, sizeof(*r));
11541 if (!r) return NULL;
11542 r->arena = arena;
11543 if (!upb_strtable_init(&r->exts, 8, arena)) return NULL;
11544 return r;
11545 }
11546
_upb_extreg_add(upb_ExtensionRegistry * r,const upb_MiniTable_Extension ** e,size_t count)11547 bool _upb_extreg_add(upb_ExtensionRegistry* r,
11548 const upb_MiniTable_Extension** e, size_t count) {
11549 char buf[EXTREG_KEY_SIZE];
11550 const upb_MiniTable_Extension** start = e;
11551 const upb_MiniTable_Extension** end = UPB_PTRADD(e, count);
11552 for (; e < end; e++) {
11553 const upb_MiniTable_Extension* ext = *e;
11554 extreg_key(buf, ext->extendee, ext->field.number);
11555 upb_value v;
11556 if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
11557 goto failure;
11558 }
11559 if (!upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE,
11560 upb_value_constptr(ext), r->arena)) {
11561 goto failure;
11562 }
11563 }
11564 return true;
11565
11566 failure:
11567 /* Back out the entries previously added. */
11568 for (end = e, e = start; e < end; e++) {
11569 const upb_MiniTable_Extension* ext = *e;
11570 extreg_key(buf, ext->extendee, ext->field.number);
11571 upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
11572 }
11573 return false;
11574 }
11575
_upb_extreg_get(const upb_ExtensionRegistry * r,const upb_MiniTable * l,uint32_t num)11576 const upb_MiniTable_Extension* _upb_extreg_get(const upb_ExtensionRegistry* r,
11577 const upb_MiniTable* l,
11578 uint32_t num) {
11579 char buf[EXTREG_KEY_SIZE];
11580 upb_value v;
11581 extreg_key(buf, l, num);
11582 if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
11583 return upb_value_getconstptr(v);
11584 } else {
11585 return NULL;
11586 }
11587 }
11588
11589 /** upb/table.c ************************************************************/
11590 /*
11591 * upb_table Implementation
11592 *
11593 * Implementation is heavily inspired by Lua's ltable.c.
11594 */
11595
11596 #include <string.h>
11597
11598
11599 /* Must be last. */
11600
11601 #define UPB_MAXARRSIZE 16 /* 64k. */
11602
11603 /* From Chromium. */
11604 #define ARRAY_SIZE(x) \
11605 ((sizeof(x) / sizeof(0 [x])) / ((size_t)(!(sizeof(x) % sizeof(0 [x])))))
11606
11607 static const double MAX_LOAD = 0.85;
11608
11609 /* The minimum utilization of the array part of a mixed hash/array table. This
11610 * is a speed/memory-usage tradeoff (though it's not straightforward because of
11611 * cache effects). The lower this is, the more memory we'll use. */
11612 static const double MIN_DENSITY = 0.1;
11613
is_pow2(uint64_t v)11614 static bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
11615
_upb_value_val(uint64_t val)11616 static upb_value _upb_value_val(uint64_t val) {
11617 upb_value ret;
11618 _upb_value_setval(&ret, val);
11619 return ret;
11620 }
11621
log2ceil(uint64_t v)11622 static int log2ceil(uint64_t v) {
11623 int ret = 0;
11624 bool pow2 = is_pow2(v);
11625 while (v >>= 1) ret++;
11626 ret = pow2 ? ret : ret + 1; /* Ceiling. */
11627 return UPB_MIN(UPB_MAXARRSIZE, ret);
11628 }
11629
upb_strdup2(const char * s,size_t len,upb_Arena * a)11630 char* upb_strdup2(const char* s, size_t len, upb_Arena* a) {
11631 size_t n;
11632 char* p;
11633
11634 /* Prevent overflow errors. */
11635 if (len == SIZE_MAX) return NULL;
11636 /* Always null-terminate, even if binary data; but don't rely on the input to
11637 * have a null-terminating byte since it may be a raw binary buffer. */
11638 n = len + 1;
11639 p = upb_Arena_Malloc(a, n);
11640 if (p) {
11641 memcpy(p, s, len);
11642 p[len] = 0;
11643 }
11644 return p;
11645 }
11646
11647 /* A type to represent the lookup key of either a strtable or an inttable. */
11648 typedef union {
11649 uintptr_t num;
11650 struct {
11651 const char* str;
11652 size_t len;
11653 } str;
11654 } lookupkey_t;
11655
strkey2(const char * str,size_t len)11656 static lookupkey_t strkey2(const char* str, size_t len) {
11657 lookupkey_t k;
11658 k.str.str = str;
11659 k.str.len = len;
11660 return k;
11661 }
11662
intkey(uintptr_t key)11663 static lookupkey_t intkey(uintptr_t key) {
11664 lookupkey_t k;
11665 k.num = key;
11666 return k;
11667 }
11668
11669 typedef uint32_t hashfunc_t(upb_tabkey key);
11670 typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2);
11671
11672 /* Base table (shared code) ***************************************************/
11673
upb_inthash(uintptr_t key)11674 static uint32_t upb_inthash(uintptr_t key) { return (uint32_t)key; }
11675
upb_getentry(const upb_table * t,uint32_t hash)11676 static const upb_tabent* upb_getentry(const upb_table* t, uint32_t hash) {
11677 return t->entries + (hash & t->mask);
11678 }
11679
upb_arrhas(upb_tabval key)11680 static bool upb_arrhas(upb_tabval key) { return key.val != (uint64_t)-1; }
11681
isfull(upb_table * t)11682 static bool isfull(upb_table* t) { return t->count == t->max_count; }
11683
init(upb_table * t,uint8_t size_lg2,upb_Arena * a)11684 static bool init(upb_table* t, uint8_t size_lg2, upb_Arena* a) {
11685 size_t bytes;
11686
11687 t->count = 0;
11688 t->size_lg2 = size_lg2;
11689 t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
11690 t->max_count = upb_table_size(t) * MAX_LOAD;
11691 bytes = upb_table_size(t) * sizeof(upb_tabent);
11692 if (bytes > 0) {
11693 t->entries = upb_Arena_Malloc(a, bytes);
11694 if (!t->entries) return false;
11695 memset(t->entries, 0, bytes);
11696 } else {
11697 t->entries = NULL;
11698 }
11699 return true;
11700 }
11701
emptyent(upb_table * t,upb_tabent * e)11702 static upb_tabent* emptyent(upb_table* t, upb_tabent* e) {
11703 upb_tabent* begin = t->entries;
11704 upb_tabent* end = begin + upb_table_size(t);
11705 for (e = e + 1; e < end; e++) {
11706 if (upb_tabent_isempty(e)) return e;
11707 }
11708 for (e = begin; e < end; e++) {
11709 if (upb_tabent_isempty(e)) return e;
11710 }
11711 UPB_ASSERT(false);
11712 return NULL;
11713 }
11714
getentry_mutable(upb_table * t,uint32_t hash)11715 static upb_tabent* getentry_mutable(upb_table* t, uint32_t hash) {
11716 return (upb_tabent*)upb_getentry(t, hash);
11717 }
11718
findentry(const upb_table * t,lookupkey_t key,uint32_t hash,eqlfunc_t * eql)11719 static const upb_tabent* findentry(const upb_table* t, lookupkey_t key,
11720 uint32_t hash, eqlfunc_t* eql) {
11721 const upb_tabent* e;
11722
11723 if (t->size_lg2 == 0) return NULL;
11724 e = upb_getentry(t, hash);
11725 if (upb_tabent_isempty(e)) return NULL;
11726 while (1) {
11727 if (eql(e->key, key)) return e;
11728 if ((e = e->next) == NULL) return NULL;
11729 }
11730 }
11731
findentry_mutable(upb_table * t,lookupkey_t key,uint32_t hash,eqlfunc_t * eql)11732 static upb_tabent* findentry_mutable(upb_table* t, lookupkey_t key,
11733 uint32_t hash, eqlfunc_t* eql) {
11734 return (upb_tabent*)findentry(t, key, hash, eql);
11735 }
11736
lookup(const upb_table * t,lookupkey_t key,upb_value * v,uint32_t hash,eqlfunc_t * eql)11737 static bool lookup(const upb_table* t, lookupkey_t key, upb_value* v,
11738 uint32_t hash, eqlfunc_t* eql) {
11739 const upb_tabent* e = findentry(t, key, hash, eql);
11740 if (e) {
11741 if (v) {
11742 _upb_value_setval(v, e->val.val);
11743 }
11744 return true;
11745 } else {
11746 return false;
11747 }
11748 }
11749
11750 /* The given key must not already exist in the table. */
insert(upb_table * t,lookupkey_t key,upb_tabkey tabkey,upb_value val,uint32_t hash,hashfunc_t * hashfunc,eqlfunc_t * eql)11751 static void insert(upb_table* t, lookupkey_t key, upb_tabkey tabkey,
11752 upb_value val, uint32_t hash, hashfunc_t* hashfunc,
11753 eqlfunc_t* eql) {
11754 upb_tabent* mainpos_e;
11755 upb_tabent* our_e;
11756
11757 UPB_ASSERT(findentry(t, key, hash, eql) == NULL);
11758
11759 t->count++;
11760 mainpos_e = getentry_mutable(t, hash);
11761 our_e = mainpos_e;
11762
11763 if (upb_tabent_isempty(mainpos_e)) {
11764 /* Our main position is empty; use it. */
11765 our_e->next = NULL;
11766 } else {
11767 /* Collision. */
11768 upb_tabent* new_e = emptyent(t, mainpos_e);
11769 /* Head of collider's chain. */
11770 upb_tabent* chain = getentry_mutable(t, hashfunc(mainpos_e->key));
11771 if (chain == mainpos_e) {
11772 /* Existing ent is in its main position (it has the same hash as us, and
11773 * is the head of our chain). Insert to new ent and append to this chain.
11774 */
11775 new_e->next = mainpos_e->next;
11776 mainpos_e->next = new_e;
11777 our_e = new_e;
11778 } else {
11779 /* Existing ent is not in its main position (it is a node in some other
11780 * chain). This implies that no existing ent in the table has our hash.
11781 * Evict it (updating its chain) and use its ent for head of our chain. */
11782 *new_e = *mainpos_e; /* copies next. */
11783 while (chain->next != mainpos_e) {
11784 chain = (upb_tabent*)chain->next;
11785 UPB_ASSERT(chain);
11786 }
11787 chain->next = new_e;
11788 our_e = mainpos_e;
11789 our_e->next = NULL;
11790 }
11791 }
11792 our_e->key = tabkey;
11793 our_e->val.val = val.val;
11794 UPB_ASSERT(findentry(t, key, hash, eql) == our_e);
11795 }
11796
rm(upb_table * t,lookupkey_t key,upb_value * val,upb_tabkey * removed,uint32_t hash,eqlfunc_t * eql)11797 static bool rm(upb_table* t, lookupkey_t key, upb_value* val,
11798 upb_tabkey* removed, uint32_t hash, eqlfunc_t* eql) {
11799 upb_tabent* chain = getentry_mutable(t, hash);
11800 if (upb_tabent_isempty(chain)) return false;
11801 if (eql(chain->key, key)) {
11802 /* Element to remove is at the head of its chain. */
11803 t->count--;
11804 if (val) _upb_value_setval(val, chain->val.val);
11805 if (removed) *removed = chain->key;
11806 if (chain->next) {
11807 upb_tabent* move = (upb_tabent*)chain->next;
11808 *chain = *move;
11809 move->key = 0; /* Make the slot empty. */
11810 } else {
11811 chain->key = 0; /* Make the slot empty. */
11812 }
11813 return true;
11814 } else {
11815 /* Element to remove is either in a non-head position or not in the
11816 * table. */
11817 while (chain->next && !eql(chain->next->key, key)) {
11818 chain = (upb_tabent*)chain->next;
11819 }
11820 if (chain->next) {
11821 /* Found element to remove. */
11822 upb_tabent* rm = (upb_tabent*)chain->next;
11823 t->count--;
11824 if (val) _upb_value_setval(val, chain->next->val.val);
11825 if (removed) *removed = rm->key;
11826 rm->key = 0; /* Make the slot empty. */
11827 chain->next = rm->next;
11828 return true;
11829 } else {
11830 /* Element to remove is not in the table. */
11831 return false;
11832 }
11833 }
11834 }
11835
next(const upb_table * t,size_t i)11836 static size_t next(const upb_table* t, size_t i) {
11837 do {
11838 if (++i >= upb_table_size(t)) return SIZE_MAX - 1; /* Distinct from -1. */
11839 } while (upb_tabent_isempty(&t->entries[i]));
11840
11841 return i;
11842 }
11843
begin(const upb_table * t)11844 static size_t begin(const upb_table* t) { return next(t, -1); }
11845
11846 /* upb_strtable ***************************************************************/
11847
11848 /* A simple "subclass" of upb_table that only adds a hash function for strings.
11849 */
11850
strcopy(lookupkey_t k2,upb_Arena * a)11851 static upb_tabkey strcopy(lookupkey_t k2, upb_Arena* a) {
11852 uint32_t len = (uint32_t)k2.str.len;
11853 char* str = upb_Arena_Malloc(a, k2.str.len + sizeof(uint32_t) + 1);
11854 if (str == NULL) return 0;
11855 memcpy(str, &len, sizeof(uint32_t));
11856 if (k2.str.len) memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len);
11857 str[sizeof(uint32_t) + k2.str.len] = '\0';
11858 return (uintptr_t)str;
11859 }
11860
11861 /* Adapted from ABSL's wyhash. */
11862
UnalignedLoad64(const void * p)11863 static uint64_t UnalignedLoad64(const void* p) {
11864 uint64_t val;
11865 memcpy(&val, p, 8);
11866 return val;
11867 }
11868
UnalignedLoad32(const void * p)11869 static uint32_t UnalignedLoad32(const void* p) {
11870 uint32_t val;
11871 memcpy(&val, p, 4);
11872 return val;
11873 }
11874
11875 #if defined(_MSC_VER) && defined(_M_X64)
11876 #include <intrin.h>
11877 #endif
11878
11879 /* Computes a * b, returning the low 64 bits of the result and storing the high
11880 * 64 bits in |*high|. */
upb_umul128(uint64_t v0,uint64_t v1,uint64_t * out_high)11881 static uint64_t upb_umul128(uint64_t v0, uint64_t v1, uint64_t* out_high) {
11882 #ifdef __SIZEOF_INT128__
11883 __uint128_t p = v0;
11884 p *= v1;
11885 *out_high = (uint64_t)(p >> 64);
11886 return (uint64_t)p;
11887 #elif defined(_MSC_VER) && defined(_M_X64)
11888 return _umul128(v0, v1, out_high);
11889 #else
11890 uint64_t a32 = v0 >> 32;
11891 uint64_t a00 = v0 & 0xffffffff;
11892 uint64_t b32 = v1 >> 32;
11893 uint64_t b00 = v1 & 0xffffffff;
11894 uint64_t high = a32 * b32;
11895 uint64_t low = a00 * b00;
11896 uint64_t mid1 = a32 * b00;
11897 uint64_t mid2 = a00 * b32;
11898 low += (mid1 << 32) + (mid2 << 32);
11899 // Omit carry bit, for mixing we do not care about exact numerical precision.
11900 high += (mid1 >> 32) + (mid2 >> 32);
11901 *out_high = high;
11902 return low;
11903 #endif
11904 }
11905
WyhashMix(uint64_t v0,uint64_t v1)11906 static uint64_t WyhashMix(uint64_t v0, uint64_t v1) {
11907 uint64_t high;
11908 uint64_t low = upb_umul128(v0, v1, &high);
11909 return low ^ high;
11910 }
11911
Wyhash(const void * data,size_t len,uint64_t seed,const uint64_t salt[])11912 static uint64_t Wyhash(const void* data, size_t len, uint64_t seed,
11913 const uint64_t salt[]) {
11914 const uint8_t* ptr = (const uint8_t*)data;
11915 uint64_t starting_length = (uint64_t)len;
11916 uint64_t current_state = seed ^ salt[0];
11917
11918 if (len > 64) {
11919 // If we have more than 64 bytes, we're going to handle chunks of 64
11920 // bytes at a time. We're going to build up two separate hash states
11921 // which we will then hash together.
11922 uint64_t duplicated_state = current_state;
11923
11924 do {
11925 uint64_t a = UnalignedLoad64(ptr);
11926 uint64_t b = UnalignedLoad64(ptr + 8);
11927 uint64_t c = UnalignedLoad64(ptr + 16);
11928 uint64_t d = UnalignedLoad64(ptr + 24);
11929 uint64_t e = UnalignedLoad64(ptr + 32);
11930 uint64_t f = UnalignedLoad64(ptr + 40);
11931 uint64_t g = UnalignedLoad64(ptr + 48);
11932 uint64_t h = UnalignedLoad64(ptr + 56);
11933
11934 uint64_t cs0 = WyhashMix(a ^ salt[1], b ^ current_state);
11935 uint64_t cs1 = WyhashMix(c ^ salt[2], d ^ current_state);
11936 current_state = (cs0 ^ cs1);
11937
11938 uint64_t ds0 = WyhashMix(e ^ salt[3], f ^ duplicated_state);
11939 uint64_t ds1 = WyhashMix(g ^ salt[4], h ^ duplicated_state);
11940 duplicated_state = (ds0 ^ ds1);
11941
11942 ptr += 64;
11943 len -= 64;
11944 } while (len > 64);
11945
11946 current_state = current_state ^ duplicated_state;
11947 }
11948
11949 // We now have a data `ptr` with at most 64 bytes and the current state
11950 // of the hashing state machine stored in current_state.
11951 while (len > 16) {
11952 uint64_t a = UnalignedLoad64(ptr);
11953 uint64_t b = UnalignedLoad64(ptr + 8);
11954
11955 current_state = WyhashMix(a ^ salt[1], b ^ current_state);
11956
11957 ptr += 16;
11958 len -= 16;
11959 }
11960
11961 // We now have a data `ptr` with at most 16 bytes.
11962 uint64_t a = 0;
11963 uint64_t b = 0;
11964 if (len > 8) {
11965 // When we have at least 9 and at most 16 bytes, set A to the first 64
11966 // bits of the input and B to the last 64 bits of the input. Yes, they will
11967 // overlap in the middle if we are working with less than the full 16
11968 // bytes.
11969 a = UnalignedLoad64(ptr);
11970 b = UnalignedLoad64(ptr + len - 8);
11971 } else if (len > 3) {
11972 // If we have at least 4 and at most 8 bytes, set A to the first 32
11973 // bits and B to the last 32 bits.
11974 a = UnalignedLoad32(ptr);
11975 b = UnalignedLoad32(ptr + len - 4);
11976 } else if (len > 0) {
11977 // If we have at least 1 and at most 3 bytes, read all of the provided
11978 // bits into A, with some adjustments.
11979 a = ((ptr[0] << 16) | (ptr[len >> 1] << 8) | ptr[len - 1]);
11980 b = 0;
11981 } else {
11982 a = 0;
11983 b = 0;
11984 }
11985
11986 uint64_t w = WyhashMix(a ^ salt[1], b ^ current_state);
11987 uint64_t z = salt[1] ^ starting_length;
11988 return WyhashMix(w, z);
11989 }
11990
11991 const uint64_t kWyhashSalt[5] = {
11992 0x243F6A8885A308D3ULL, 0x13198A2E03707344ULL, 0xA4093822299F31D0ULL,
11993 0x082EFA98EC4E6C89ULL, 0x452821E638D01377ULL,
11994 };
11995
_upb_Hash(const void * p,size_t n,uint64_t seed)11996 uint32_t _upb_Hash(const void* p, size_t n, uint64_t seed) {
11997 return Wyhash(p, n, seed, kWyhashSalt);
11998 }
11999
_upb_Hash_NoSeed(const char * p,size_t n)12000 static uint32_t _upb_Hash_NoSeed(const char* p, size_t n) {
12001 return _upb_Hash(p, n, 0);
12002 }
12003
strhash(upb_tabkey key)12004 static uint32_t strhash(upb_tabkey key) {
12005 uint32_t len;
12006 char* str = upb_tabstr(key, &len);
12007 return _upb_Hash_NoSeed(str, len);
12008 }
12009
streql(upb_tabkey k1,lookupkey_t k2)12010 static bool streql(upb_tabkey k1, lookupkey_t k2) {
12011 uint32_t len;
12012 char* str = upb_tabstr(k1, &len);
12013 return len == k2.str.len && (len == 0 || memcmp(str, k2.str.str, len) == 0);
12014 }
12015
upb_strtable_init(upb_strtable * t,size_t expected_size,upb_Arena * a)12016 bool upb_strtable_init(upb_strtable* t, size_t expected_size, upb_Arena* a) {
12017 // Multiply by approximate reciprocal of MAX_LOAD (0.85), with pow2
12018 // denominator.
12019 size_t need_entries = (expected_size + 1) * 1204 / 1024;
12020 UPB_ASSERT(need_entries >= expected_size * 0.85);
12021 int size_lg2 = _upb_Log2Ceiling(need_entries);
12022 return init(&t->t, size_lg2, a);
12023 }
12024
upb_strtable_clear(upb_strtable * t)12025 void upb_strtable_clear(upb_strtable* t) {
12026 size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent);
12027 t->t.count = 0;
12028 memset((char*)t->t.entries, 0, bytes);
12029 }
12030
upb_strtable_resize(upb_strtable * t,size_t size_lg2,upb_Arena * a)12031 bool upb_strtable_resize(upb_strtable* t, size_t size_lg2, upb_Arena* a) {
12032 upb_strtable new_table;
12033 upb_strtable_iter i;
12034
12035 if (!init(&new_table.t, size_lg2, a)) return false;
12036 upb_strtable_begin(&i, t);
12037 for (; !upb_strtable_done(&i); upb_strtable_next(&i)) {
12038 upb_StringView key = upb_strtable_iter_key(&i);
12039 upb_strtable_insert(&new_table, key.data, key.size,
12040 upb_strtable_iter_value(&i), a);
12041 }
12042 *t = new_table;
12043 return true;
12044 }
12045
upb_strtable_insert(upb_strtable * t,const char * k,size_t len,upb_value v,upb_Arena * a)12046 bool upb_strtable_insert(upb_strtable* t, const char* k, size_t len,
12047 upb_value v, upb_Arena* a) {
12048 lookupkey_t key;
12049 upb_tabkey tabkey;
12050 uint32_t hash;
12051
12052 if (isfull(&t->t)) {
12053 /* Need to resize. New table of double the size, add old elements to it. */
12054 if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) {
12055 return false;
12056 }
12057 }
12058
12059 key = strkey2(k, len);
12060 tabkey = strcopy(key, a);
12061 if (tabkey == 0) return false;
12062
12063 hash = _upb_Hash_NoSeed(key.str.str, key.str.len);
12064 insert(&t->t, key, tabkey, v, hash, &strhash, &streql);
12065 return true;
12066 }
12067
upb_strtable_lookup2(const upb_strtable * t,const char * key,size_t len,upb_value * v)12068 bool upb_strtable_lookup2(const upb_strtable* t, const char* key, size_t len,
12069 upb_value* v) {
12070 uint32_t hash = _upb_Hash_NoSeed(key, len);
12071 return lookup(&t->t, strkey2(key, len), v, hash, &streql);
12072 }
12073
upb_strtable_remove2(upb_strtable * t,const char * key,size_t len,upb_value * val)12074 bool upb_strtable_remove2(upb_strtable* t, const char* key, size_t len,
12075 upb_value* val) {
12076 uint32_t hash = _upb_Hash_NoSeed(key, len);
12077 upb_tabkey tabkey;
12078 return rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql);
12079 }
12080
12081 /* Iteration */
12082
upb_strtable_begin(upb_strtable_iter * i,const upb_strtable * t)12083 void upb_strtable_begin(upb_strtable_iter* i, const upb_strtable* t) {
12084 i->t = t;
12085 i->index = begin(&t->t);
12086 }
12087
upb_strtable_next(upb_strtable_iter * i)12088 void upb_strtable_next(upb_strtable_iter* i) {
12089 i->index = next(&i->t->t, i->index);
12090 }
12091
upb_strtable_done(const upb_strtable_iter * i)12092 bool upb_strtable_done(const upb_strtable_iter* i) {
12093 if (!i->t) return true;
12094 return i->index >= upb_table_size(&i->t->t) ||
12095 upb_tabent_isempty(str_tabent(i));
12096 }
12097
upb_strtable_iter_key(const upb_strtable_iter * i)12098 upb_StringView upb_strtable_iter_key(const upb_strtable_iter* i) {
12099 upb_StringView key;
12100 uint32_t len;
12101 UPB_ASSERT(!upb_strtable_done(i));
12102 key.data = upb_tabstr(str_tabent(i)->key, &len);
12103 key.size = len;
12104 return key;
12105 }
12106
upb_strtable_iter_value(const upb_strtable_iter * i)12107 upb_value upb_strtable_iter_value(const upb_strtable_iter* i) {
12108 UPB_ASSERT(!upb_strtable_done(i));
12109 return _upb_value_val(str_tabent(i)->val.val);
12110 }
12111
upb_strtable_iter_setdone(upb_strtable_iter * i)12112 void upb_strtable_iter_setdone(upb_strtable_iter* i) {
12113 i->t = NULL;
12114 i->index = SIZE_MAX;
12115 }
12116
upb_strtable_iter_isequal(const upb_strtable_iter * i1,const upb_strtable_iter * i2)12117 bool upb_strtable_iter_isequal(const upb_strtable_iter* i1,
12118 const upb_strtable_iter* i2) {
12119 if (upb_strtable_done(i1) && upb_strtable_done(i2)) return true;
12120 return i1->t == i2->t && i1->index == i2->index;
12121 }
12122
12123 /* upb_inttable ***************************************************************/
12124
12125 /* For inttables we use a hybrid structure where small keys are kept in an
12126 * array and large keys are put in the hash table. */
12127
inthash(upb_tabkey key)12128 static uint32_t inthash(upb_tabkey key) { return upb_inthash(key); }
12129
inteql(upb_tabkey k1,lookupkey_t k2)12130 static bool inteql(upb_tabkey k1, lookupkey_t k2) { return k1 == k2.num; }
12131
mutable_array(upb_inttable * t)12132 static upb_tabval* mutable_array(upb_inttable* t) {
12133 return (upb_tabval*)t->array;
12134 }
12135
inttable_val(upb_inttable * t,uintptr_t key)12136 static upb_tabval* inttable_val(upb_inttable* t, uintptr_t key) {
12137 if (key < t->array_size) {
12138 return upb_arrhas(t->array[key]) ? &(mutable_array(t)[key]) : NULL;
12139 } else {
12140 upb_tabent* e =
12141 findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql);
12142 return e ? &e->val : NULL;
12143 }
12144 }
12145
inttable_val_const(const upb_inttable * t,uintptr_t key)12146 static const upb_tabval* inttable_val_const(const upb_inttable* t,
12147 uintptr_t key) {
12148 return inttable_val((upb_inttable*)t, key);
12149 }
12150
upb_inttable_count(const upb_inttable * t)12151 size_t upb_inttable_count(const upb_inttable* t) {
12152 return t->t.count + t->array_count;
12153 }
12154
check(upb_inttable * t)12155 static void check(upb_inttable* t) {
12156 UPB_UNUSED(t);
12157 #if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG)
12158 {
12159 /* This check is very expensive (makes inserts/deletes O(N)). */
12160 size_t count = 0;
12161 upb_inttable_iter i;
12162 upb_inttable_begin(&i, t);
12163 for (; !upb_inttable_done(&i); upb_inttable_next(&i), count++) {
12164 UPB_ASSERT(upb_inttable_lookup(t, upb_inttable_iter_key(&i), NULL));
12165 }
12166 UPB_ASSERT(count == upb_inttable_count(t));
12167 }
12168 #endif
12169 }
12170
upb_inttable_sizedinit(upb_inttable * t,size_t asize,int hsize_lg2,upb_Arena * a)12171 bool upb_inttable_sizedinit(upb_inttable* t, size_t asize, int hsize_lg2,
12172 upb_Arena* a) {
12173 size_t array_bytes;
12174
12175 if (!init(&t->t, hsize_lg2, a)) return false;
12176 /* Always make the array part at least 1 long, so that we know key 0
12177 * won't be in the hash part, which simplifies things. */
12178 t->array_size = UPB_MAX(1, asize);
12179 t->array_count = 0;
12180 array_bytes = t->array_size * sizeof(upb_value);
12181 t->array = upb_Arena_Malloc(a, array_bytes);
12182 if (!t->array) {
12183 return false;
12184 }
12185 memset(mutable_array(t), 0xff, array_bytes);
12186 check(t);
12187 return true;
12188 }
12189
upb_inttable_init(upb_inttable * t,upb_Arena * a)12190 bool upb_inttable_init(upb_inttable* t, upb_Arena* a) {
12191 return upb_inttable_sizedinit(t, 0, 4, a);
12192 }
12193
upb_inttable_insert(upb_inttable * t,uintptr_t key,upb_value val,upb_Arena * a)12194 bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val,
12195 upb_Arena* a) {
12196 upb_tabval tabval;
12197 tabval.val = val.val;
12198 UPB_ASSERT(
12199 upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */
12200
12201 if (key < t->array_size) {
12202 UPB_ASSERT(!upb_arrhas(t->array[key]));
12203 t->array_count++;
12204 mutable_array(t)[key].val = val.val;
12205 } else {
12206 if (isfull(&t->t)) {
12207 /* Need to resize the hash part, but we re-use the array part. */
12208 size_t i;
12209 upb_table new_table;
12210
12211 if (!init(&new_table, t->t.size_lg2 + 1, a)) {
12212 return false;
12213 }
12214
12215 for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
12216 const upb_tabent* e = &t->t.entries[i];
12217 uint32_t hash;
12218 upb_value v;
12219
12220 _upb_value_setval(&v, e->val.val);
12221 hash = upb_inthash(e->key);
12222 insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql);
12223 }
12224
12225 UPB_ASSERT(t->t.count == new_table.count);
12226
12227 t->t = new_table;
12228 }
12229 insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql);
12230 }
12231 check(t);
12232 return true;
12233 }
12234
upb_inttable_lookup(const upb_inttable * t,uintptr_t key,upb_value * v)12235 bool upb_inttable_lookup(const upb_inttable* t, uintptr_t key, upb_value* v) {
12236 const upb_tabval* table_v = inttable_val_const(t, key);
12237 if (!table_v) return false;
12238 if (v) _upb_value_setval(v, table_v->val);
12239 return true;
12240 }
12241
upb_inttable_replace(upb_inttable * t,uintptr_t key,upb_value val)12242 bool upb_inttable_replace(upb_inttable* t, uintptr_t key, upb_value val) {
12243 upb_tabval* table_v = inttable_val(t, key);
12244 if (!table_v) return false;
12245 table_v->val = val.val;
12246 return true;
12247 }
12248
upb_inttable_remove(upb_inttable * t,uintptr_t key,upb_value * val)12249 bool upb_inttable_remove(upb_inttable* t, uintptr_t key, upb_value* val) {
12250 bool success;
12251 if (key < t->array_size) {
12252 if (upb_arrhas(t->array[key])) {
12253 upb_tabval empty = UPB_TABVALUE_EMPTY_INIT;
12254 t->array_count--;
12255 if (val) {
12256 _upb_value_setval(val, t->array[key].val);
12257 }
12258 mutable_array(t)[key] = empty;
12259 success = true;
12260 } else {
12261 success = false;
12262 }
12263 } else {
12264 success = rm(&t->t, intkey(key), val, NULL, upb_inthash(key), &inteql);
12265 }
12266 check(t);
12267 return success;
12268 }
12269
upb_inttable_compact(upb_inttable * t,upb_Arena * a)12270 void upb_inttable_compact(upb_inttable* t, upb_Arena* a) {
12271 /* A power-of-two histogram of the table keys. */
12272 size_t counts[UPB_MAXARRSIZE + 1] = {0};
12273
12274 /* The max key in each bucket. */
12275 uintptr_t max[UPB_MAXARRSIZE + 1] = {0};
12276
12277 upb_inttable_iter i;
12278 size_t arr_count;
12279 int size_lg2;
12280 upb_inttable new_t;
12281
12282 upb_inttable_begin(&i, t);
12283 for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
12284 uintptr_t key = upb_inttable_iter_key(&i);
12285 int bucket = log2ceil(key);
12286 max[bucket] = UPB_MAX(max[bucket], key);
12287 counts[bucket]++;
12288 }
12289
12290 /* Find the largest power of two that satisfies the MIN_DENSITY
12291 * definition (while actually having some keys). */
12292 arr_count = upb_inttable_count(t);
12293
12294 for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 0; size_lg2--) {
12295 if (counts[size_lg2] == 0) {
12296 /* We can halve again without losing any entries. */
12297 continue;
12298 } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) {
12299 break;
12300 }
12301
12302 arr_count -= counts[size_lg2];
12303 }
12304
12305 UPB_ASSERT(arr_count <= upb_inttable_count(t));
12306
12307 {
12308 /* Insert all elements into new, perfectly-sized table. */
12309 size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */
12310 size_t hash_count = upb_inttable_count(t) - arr_count;
12311 size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
12312 int hashsize_lg2 = log2ceil(hash_size);
12313
12314 upb_inttable_sizedinit(&new_t, arr_size, hashsize_lg2, a);
12315 upb_inttable_begin(&i, t);
12316 for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
12317 uintptr_t k = upb_inttable_iter_key(&i);
12318 upb_inttable_insert(&new_t, k, upb_inttable_iter_value(&i), a);
12319 }
12320 UPB_ASSERT(new_t.array_size == arr_size);
12321 UPB_ASSERT(new_t.t.size_lg2 == hashsize_lg2);
12322 }
12323 *t = new_t;
12324 }
12325
12326 /* Iteration. */
12327
int_tabent(const upb_inttable_iter * i)12328 static const upb_tabent* int_tabent(const upb_inttable_iter* i) {
12329 UPB_ASSERT(!i->array_part);
12330 return &i->t->t.entries[i->index];
12331 }
12332
int_arrent(const upb_inttable_iter * i)12333 static upb_tabval int_arrent(const upb_inttable_iter* i) {
12334 UPB_ASSERT(i->array_part);
12335 return i->t->array[i->index];
12336 }
12337
upb_inttable_begin(upb_inttable_iter * i,const upb_inttable * t)12338 void upb_inttable_begin(upb_inttable_iter* i, const upb_inttable* t) {
12339 i->t = t;
12340 i->index = -1;
12341 i->array_part = true;
12342 upb_inttable_next(i);
12343 }
12344
upb_inttable_next(upb_inttable_iter * iter)12345 void upb_inttable_next(upb_inttable_iter* iter) {
12346 const upb_inttable* t = iter->t;
12347 if (iter->array_part) {
12348 while (++iter->index < t->array_size) {
12349 if (upb_arrhas(int_arrent(iter))) {
12350 return;
12351 }
12352 }
12353 iter->array_part = false;
12354 iter->index = begin(&t->t);
12355 } else {
12356 iter->index = next(&t->t, iter->index);
12357 }
12358 }
12359
upb_inttable_next2(const upb_inttable * t,uintptr_t * key,upb_value * val,intptr_t * iter)12360 bool upb_inttable_next2(const upb_inttable* t, uintptr_t* key, upb_value* val,
12361 intptr_t* iter) {
12362 intptr_t i = *iter;
12363 if (i < t->array_size) {
12364 while (++i < t->array_size) {
12365 upb_tabval ent = t->array[i];
12366 if (upb_arrhas(ent)) {
12367 *key = i;
12368 *val = _upb_value_val(ent.val);
12369 *iter = i;
12370 return true;
12371 }
12372 }
12373 }
12374
12375 size_t tab_idx = next(&t->t, i == -1 ? -1 : i - t->array_size);
12376 if (tab_idx < upb_table_size(&t->t)) {
12377 upb_tabent* ent = &t->t.entries[tab_idx];
12378 *key = ent->key;
12379 *val = _upb_value_val(ent->val.val);
12380 *iter = tab_idx + t->array_size;
12381 return true;
12382 }
12383
12384 return false;
12385 }
12386
upb_inttable_removeiter(upb_inttable * t,intptr_t * iter)12387 void upb_inttable_removeiter(upb_inttable* t, intptr_t* iter) {
12388 intptr_t i = *iter;
12389 if (i < t->array_size) {
12390 t->array_count--;
12391 mutable_array(t)[i].val = -1;
12392 } else {
12393 upb_tabent* ent = &t->t.entries[i - t->array_size];
12394 upb_tabent* prev = NULL;
12395
12396 // Linear search, not great.
12397 upb_tabent* end = &t->t.entries[upb_table_size(&t->t)];
12398 for (upb_tabent* e = t->t.entries; e != end; e++) {
12399 if (e->next == ent) {
12400 prev = e;
12401 break;
12402 }
12403 }
12404
12405 if (prev) {
12406 prev->next = ent->next;
12407 }
12408
12409 t->t.count--;
12410 ent->key = 0;
12411 ent->next = NULL;
12412 }
12413 }
12414
upb_strtable_next2(const upb_strtable * t,upb_StringView * key,upb_value * val,intptr_t * iter)12415 bool upb_strtable_next2(const upb_strtable* t, upb_StringView* key,
12416 upb_value* val, intptr_t* iter) {
12417 size_t tab_idx = next(&t->t, *iter);
12418 if (tab_idx < upb_table_size(&t->t)) {
12419 upb_tabent* ent = &t->t.entries[tab_idx];
12420 uint32_t len;
12421 key->data = upb_tabstr(ent->key, &len);
12422 key->size = len;
12423 *val = _upb_value_val(ent->val.val);
12424 *iter = tab_idx;
12425 return true;
12426 }
12427
12428 return false;
12429 }
12430
upb_strtable_removeiter(upb_strtable * t,intptr_t * iter)12431 void upb_strtable_removeiter(upb_strtable* t, intptr_t* iter) {
12432 intptr_t i = *iter;
12433 upb_tabent* ent = &t->t.entries[i];
12434 upb_tabent* prev = NULL;
12435
12436 // Linear search, not great.
12437 upb_tabent* end = &t->t.entries[upb_table_size(&t->t)];
12438 for (upb_tabent* e = t->t.entries; e != end; e++) {
12439 if (e->next == ent) {
12440 prev = e;
12441 break;
12442 }
12443 }
12444
12445 if (prev) {
12446 prev->next = ent->next;
12447 }
12448
12449 t->t.count--;
12450 ent->key = 0;
12451 ent->next = NULL;
12452 }
12453
upb_inttable_done(const upb_inttable_iter * i)12454 bool upb_inttable_done(const upb_inttable_iter* i) {
12455 if (!i->t) return true;
12456 if (i->array_part) {
12457 return i->index >= i->t->array_size || !upb_arrhas(int_arrent(i));
12458 } else {
12459 return i->index >= upb_table_size(&i->t->t) ||
12460 upb_tabent_isempty(int_tabent(i));
12461 }
12462 }
12463
upb_inttable_iter_key(const upb_inttable_iter * i)12464 uintptr_t upb_inttable_iter_key(const upb_inttable_iter* i) {
12465 UPB_ASSERT(!upb_inttable_done(i));
12466 return i->array_part ? i->index : int_tabent(i)->key;
12467 }
12468
upb_inttable_iter_value(const upb_inttable_iter * i)12469 upb_value upb_inttable_iter_value(const upb_inttable_iter* i) {
12470 UPB_ASSERT(!upb_inttable_done(i));
12471 return _upb_value_val(i->array_part ? i->t->array[i->index].val
12472 : int_tabent(i)->val.val);
12473 }
12474
upb_inttable_iter_setdone(upb_inttable_iter * i)12475 void upb_inttable_iter_setdone(upb_inttable_iter* i) {
12476 i->t = NULL;
12477 i->index = SIZE_MAX;
12478 i->array_part = false;
12479 }
12480
upb_inttable_iter_isequal(const upb_inttable_iter * i1,const upb_inttable_iter * i2)12481 bool upb_inttable_iter_isequal(const upb_inttable_iter* i1,
12482 const upb_inttable_iter* i2) {
12483 if (upb_inttable_done(i1) && upb_inttable_done(i2)) return true;
12484 return i1->t == i2->t && i1->index == i2->index &&
12485 i1->array_part == i2->array_part;
12486 }
12487
12488 /** upb/upb.c ************************************************************/
12489 #include <errno.h>
12490 #include <float.h>
12491 #include <stdarg.h>
12492 #include <stddef.h>
12493 #include <stdint.h>
12494 #include <stdio.h>
12495 #include <stdlib.h>
12496 #include <string.h>
12497
12498
12499 // Must be last.
12500
12501 /* upb_Status *****************************************************************/
12502
upb_Status_Clear(upb_Status * status)12503 void upb_Status_Clear(upb_Status* status) {
12504 if (!status) return;
12505 status->ok = true;
12506 status->msg[0] = '\0';
12507 }
12508
upb_Status_IsOk(const upb_Status * status)12509 bool upb_Status_IsOk(const upb_Status* status) { return status->ok; }
12510
upb_Status_ErrorMessage(const upb_Status * status)12511 const char* upb_Status_ErrorMessage(const upb_Status* status) {
12512 return status->msg;
12513 }
12514
upb_Status_SetErrorMessage(upb_Status * status,const char * msg)12515 void upb_Status_SetErrorMessage(upb_Status* status, const char* msg) {
12516 if (!status) return;
12517 status->ok = false;
12518 strncpy(status->msg, msg, _kUpb_Status_MaxMessage - 1);
12519 status->msg[_kUpb_Status_MaxMessage - 1] = '\0';
12520 }
12521
upb_Status_SetErrorFormat(upb_Status * status,const char * fmt,...)12522 void upb_Status_SetErrorFormat(upb_Status* status, const char* fmt, ...) {
12523 va_list args;
12524 va_start(args, fmt);
12525 upb_Status_VSetErrorFormat(status, fmt, args);
12526 va_end(args);
12527 }
12528
upb_Status_VSetErrorFormat(upb_Status * status,const char * fmt,va_list args)12529 void upb_Status_VSetErrorFormat(upb_Status* status, const char* fmt,
12530 va_list args) {
12531 if (!status) return;
12532 status->ok = false;
12533 vsnprintf(status->msg, sizeof(status->msg), fmt, args);
12534 status->msg[_kUpb_Status_MaxMessage - 1] = '\0';
12535 }
12536
upb_Status_VAppendErrorFormat(upb_Status * status,const char * fmt,va_list args)12537 void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt,
12538 va_list args) {
12539 size_t len;
12540 if (!status) return;
12541 status->ok = false;
12542 len = strlen(status->msg);
12543 vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args);
12544 status->msg[_kUpb_Status_MaxMessage - 1] = '\0';
12545 }
12546
12547 /* upb_alloc ******************************************************************/
12548
upb_global_allocfunc(upb_alloc * alloc,void * ptr,size_t oldsize,size_t size)12549 static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize,
12550 size_t size) {
12551 UPB_UNUSED(alloc);
12552 UPB_UNUSED(oldsize);
12553 if (size == 0) {
12554 free(ptr);
12555 return NULL;
12556 } else {
12557 return realloc(ptr, size);
12558 }
12559 }
12560
upb_cleanup_pointer(uintptr_t cleanup_metadata)12561 static uint32_t* upb_cleanup_pointer(uintptr_t cleanup_metadata) {
12562 return (uint32_t*)(cleanup_metadata & ~0x1);
12563 }
12564
upb_cleanup_has_initial_block(uintptr_t cleanup_metadata)12565 static bool upb_cleanup_has_initial_block(uintptr_t cleanup_metadata) {
12566 return cleanup_metadata & 0x1;
12567 }
12568
upb_cleanup_metadata(uint32_t * cleanup,bool has_initial_block)12569 static uintptr_t upb_cleanup_metadata(uint32_t* cleanup,
12570 bool has_initial_block) {
12571 return (uintptr_t)cleanup | has_initial_block;
12572 }
12573
12574 upb_alloc upb_alloc_global = {&upb_global_allocfunc};
12575
12576 /* upb_Arena ******************************************************************/
12577
12578 struct mem_block {
12579 struct mem_block* next;
12580 uint32_t size;
12581 uint32_t cleanups;
12582 /* Data follows. */
12583 };
12584
12585 typedef struct cleanup_ent {
12586 upb_CleanupFunc* cleanup;
12587 void* ud;
12588 } cleanup_ent;
12589
12590 static const size_t memblock_reserve =
12591 UPB_ALIGN_UP(sizeof(mem_block), UPB_MALLOC_ALIGN);
12592
arena_findroot(upb_Arena * a)12593 static upb_Arena* arena_findroot(upb_Arena* a) {
12594 /* Path splitting keeps time complexity down, see:
12595 * https://en.wikipedia.org/wiki/Disjoint-set_data_structure */
12596 while (a->parent != a) {
12597 upb_Arena* next = a->parent;
12598 a->parent = next->parent;
12599 a = next;
12600 }
12601 return a;
12602 }
12603
upb_Arena_addblock(upb_Arena * a,upb_Arena * root,void * ptr,size_t size)12604 static void upb_Arena_addblock(upb_Arena* a, upb_Arena* root, void* ptr,
12605 size_t size) {
12606 mem_block* block = ptr;
12607
12608 /* The block is for arena |a|, but should appear in the freelist of |root|. */
12609 block->next = root->freelist;
12610 block->size = (uint32_t)size;
12611 block->cleanups = 0;
12612 root->freelist = block;
12613 a->last_size = block->size;
12614 if (!root->freelist_tail) root->freelist_tail = block;
12615
12616 a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char);
12617 a->head.end = UPB_PTR_AT(block, size, char);
12618 a->cleanup_metadata = upb_cleanup_metadata(
12619 &block->cleanups, upb_cleanup_has_initial_block(a->cleanup_metadata));
12620
12621 UPB_POISON_MEMORY_REGION(a->head.ptr, a->head.end - a->head.ptr);
12622 }
12623
upb_Arena_Allocblock(upb_Arena * a,size_t size)12624 static bool upb_Arena_Allocblock(upb_Arena* a, size_t size) {
12625 upb_Arena* root = arena_findroot(a);
12626 size_t block_size = UPB_MAX(size, a->last_size * 2) + memblock_reserve;
12627 mem_block* block = upb_malloc(root->block_alloc, block_size);
12628
12629 if (!block) return false;
12630 upb_Arena_addblock(a, root, block, block_size);
12631 return true;
12632 }
12633
_upb_Arena_SlowMalloc(upb_Arena * a,size_t size)12634 void* _upb_Arena_SlowMalloc(upb_Arena* a, size_t size) {
12635 if (!upb_Arena_Allocblock(a, size)) return NULL; /* Out of memory. */
12636 UPB_ASSERT(_upb_ArenaHas(a) >= size);
12637 return upb_Arena_Malloc(a, size);
12638 }
12639
upb_Arena_doalloc(upb_alloc * alloc,void * ptr,size_t oldsize,size_t size)12640 static void* upb_Arena_doalloc(upb_alloc* alloc, void* ptr, size_t oldsize,
12641 size_t size) {
12642 upb_Arena* a = (upb_Arena*)alloc; /* upb_alloc is initial member. */
12643 return upb_Arena_Realloc(a, ptr, oldsize, size);
12644 }
12645
12646 /* Public Arena API ***********************************************************/
12647
arena_initslow(void * mem,size_t n,upb_alloc * alloc)12648 upb_Arena* arena_initslow(void* mem, size_t n, upb_alloc* alloc) {
12649 const size_t first_block_overhead = sizeof(upb_Arena) + memblock_reserve;
12650 upb_Arena* a;
12651
12652 /* We need to malloc the initial block. */
12653 n = first_block_overhead + 256;
12654 if (!alloc || !(mem = upb_malloc(alloc, n))) {
12655 return NULL;
12656 }
12657
12658 a = UPB_PTR_AT(mem, n - sizeof(*a), upb_Arena);
12659 n -= sizeof(*a);
12660
12661 a->head.alloc.func = &upb_Arena_doalloc;
12662 a->block_alloc = alloc;
12663 a->parent = a;
12664 a->refcount = 1;
12665 a->freelist = NULL;
12666 a->freelist_tail = NULL;
12667 a->cleanup_metadata = upb_cleanup_metadata(NULL, false);
12668
12669 upb_Arena_addblock(a, a, mem, n);
12670
12671 return a;
12672 }
12673
upb_Arena_Init(void * mem,size_t n,upb_alloc * alloc)12674 upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc) {
12675 upb_Arena* a;
12676
12677 if (n) {
12678 /* Align initial pointer up so that we return properly-aligned pointers. */
12679 void* aligned = (void*)UPB_ALIGN_UP((uintptr_t)mem, UPB_MALLOC_ALIGN);
12680 size_t delta = (uintptr_t)aligned - (uintptr_t)mem;
12681 n = delta <= n ? n - delta : 0;
12682 mem = aligned;
12683 }
12684
12685 /* Round block size down to alignof(*a) since we will allocate the arena
12686 * itself at the end. */
12687 n = UPB_ALIGN_DOWN(n, UPB_ALIGN_OF(upb_Arena));
12688
12689 if (UPB_UNLIKELY(n < sizeof(upb_Arena))) {
12690 return arena_initslow(mem, n, alloc);
12691 }
12692
12693 a = UPB_PTR_AT(mem, n - sizeof(*a), upb_Arena);
12694
12695 a->head.alloc.func = &upb_Arena_doalloc;
12696 a->block_alloc = alloc;
12697 a->parent = a;
12698 a->refcount = 1;
12699 a->last_size = UPB_MAX(128, n);
12700 a->head.ptr = mem;
12701 a->head.end = UPB_PTR_AT(mem, n - sizeof(*a), char);
12702 a->freelist = NULL;
12703 a->cleanup_metadata = upb_cleanup_metadata(NULL, true);
12704
12705 return a;
12706 }
12707
arena_dofree(upb_Arena * a)12708 static void arena_dofree(upb_Arena* a) {
12709 mem_block* block = a->freelist;
12710 UPB_ASSERT(a->parent == a);
12711 UPB_ASSERT(a->refcount == 0);
12712
12713 while (block) {
12714 /* Load first since we are deleting block. */
12715 mem_block* next = block->next;
12716
12717 if (block->cleanups > 0) {
12718 cleanup_ent* end = UPB_PTR_AT(block, block->size, void);
12719 cleanup_ent* ptr = end - block->cleanups;
12720
12721 for (; ptr < end; ptr++) {
12722 ptr->cleanup(ptr->ud);
12723 }
12724 }
12725
12726 upb_free(a->block_alloc, block);
12727 block = next;
12728 }
12729 }
12730
upb_Arena_Free(upb_Arena * a)12731 void upb_Arena_Free(upb_Arena* a) {
12732 a = arena_findroot(a);
12733 if (--a->refcount == 0) arena_dofree(a);
12734 }
12735
upb_Arena_AddCleanup(upb_Arena * a,void * ud,upb_CleanupFunc * func)12736 bool upb_Arena_AddCleanup(upb_Arena* a, void* ud, upb_CleanupFunc* func) {
12737 cleanup_ent* ent;
12738 uint32_t* cleanups = upb_cleanup_pointer(a->cleanup_metadata);
12739
12740 if (!cleanups || _upb_ArenaHas(a) < sizeof(cleanup_ent)) {
12741 if (!upb_Arena_Allocblock(a, 128)) return false; /* Out of memory. */
12742 UPB_ASSERT(_upb_ArenaHas(a) >= sizeof(cleanup_ent));
12743 cleanups = upb_cleanup_pointer(a->cleanup_metadata);
12744 }
12745
12746 a->head.end -= sizeof(cleanup_ent);
12747 ent = (cleanup_ent*)a->head.end;
12748 (*cleanups)++;
12749 UPB_UNPOISON_MEMORY_REGION(ent, sizeof(cleanup_ent));
12750
12751 ent->cleanup = func;
12752 ent->ud = ud;
12753
12754 return true;
12755 }
12756
upb_Arena_Fuse(upb_Arena * a1,upb_Arena * a2)12757 bool upb_Arena_Fuse(upb_Arena* a1, upb_Arena* a2) {
12758 upb_Arena* r1 = arena_findroot(a1);
12759 upb_Arena* r2 = arena_findroot(a2);
12760
12761 if (r1 == r2) return true; /* Already fused. */
12762
12763 /* Do not fuse initial blocks since we cannot lifetime extend them. */
12764 if (upb_cleanup_has_initial_block(r1->cleanup_metadata)) return false;
12765 if (upb_cleanup_has_initial_block(r2->cleanup_metadata)) return false;
12766
12767 /* Only allow fuse with a common allocator */
12768 if (r1->block_alloc != r2->block_alloc) return false;
12769
12770 /* We want to join the smaller tree to the larger tree.
12771 * So swap first if they are backwards. */
12772 if (r1->refcount < r2->refcount) {
12773 upb_Arena* tmp = r1;
12774 r1 = r2;
12775 r2 = tmp;
12776 }
12777
12778 /* r1 takes over r2's freelist and refcount. */
12779 r1->refcount += r2->refcount;
12780 if (r2->freelist_tail) {
12781 UPB_ASSERT(r2->freelist_tail->next == NULL);
12782 r2->freelist_tail->next = r1->freelist;
12783 r1->freelist = r2->freelist;
12784 }
12785 r2->parent = r1;
12786 return true;
12787 }
12788
12789 /* Miscellaneous utilities ****************************************************/
12790
upb_FixLocale(char * p)12791 static void upb_FixLocale(char* p) {
12792 /* printf() is dependent on locales; sadly there is no easy and portable way
12793 * to avoid this. This little post-processing step will translate 1,2 -> 1.2
12794 * since JSON needs the latter. Arguably a hack, but it is simple and the
12795 * alternatives are far more complicated, platform-dependent, and/or larger
12796 * in code size. */
12797 for (; *p; p++) {
12798 if (*p == ',') *p = '.';
12799 }
12800 }
12801
_upb_EncodeRoundTripDouble(double val,char * buf,size_t size)12802 void _upb_EncodeRoundTripDouble(double val, char* buf, size_t size) {
12803 assert(size >= kUpb_RoundTripBufferSize);
12804 snprintf(buf, size, "%.*g", DBL_DIG, val);
12805 if (strtod(buf, NULL) != val) {
12806 snprintf(buf, size, "%.*g", DBL_DIG + 2, val);
12807 assert(strtod(buf, NULL) == val);
12808 }
12809 upb_FixLocale(buf);
12810 }
12811
_upb_EncodeRoundTripFloat(float val,char * buf,size_t size)12812 void _upb_EncodeRoundTripFloat(float val, char* buf, size_t size) {
12813 assert(size >= kUpb_RoundTripBufferSize);
12814 snprintf(buf, size, "%.*g", FLT_DIG, val);
12815 if (strtof(buf, NULL) != val) {
12816 snprintf(buf, size, "%.*g", FLT_DIG + 3, val);
12817 assert(strtof(buf, NULL) == val);
12818 }
12819 upb_FixLocale(buf);
12820 }
12821
12822 /** upb/port_undef.inc ************************************************************/
12823 /* See port_def.inc. This should #undef all macros #defined there. */
12824
12825 #undef UPB_SIZE
12826 #undef UPB_PTR_AT
12827 #undef UPB_READ_ONEOF
12828 #undef UPB_WRITE_ONEOF
12829 #undef UPB_MAPTYPE_STRING
12830 #undef UPB_INLINE
12831 #undef UPB_ALIGN_UP
12832 #undef UPB_ALIGN_DOWN
12833 #undef UPB_ALIGN_MALLOC
12834 #undef UPB_ALIGN_OF
12835 #undef UPB_MALLOC_ALIGN
12836 #undef UPB_LIKELY
12837 #undef UPB_UNLIKELY
12838 #undef UPB_FORCEINLINE
12839 #undef UPB_NOINLINE
12840 #undef UPB_NORETURN
12841 #undef UPB_PRINTF
12842 #undef UPB_MAX
12843 #undef UPB_MIN
12844 #undef UPB_UNUSED
12845 #undef UPB_ASSUME
12846 #undef UPB_ASSERT
12847 #undef UPB_UNREACHABLE
12848 #undef UPB_SETJMP
12849 #undef UPB_LONGJMP
12850 #undef UPB_PTRADD
12851 #undef UPB_MUSTTAIL
12852 #undef UPB_FASTTABLE_SUPPORTED
12853 #undef UPB_FASTTABLE
12854 #undef UPB_FASTTABLE_INIT
12855 #undef UPB_POISON_MEMORY_REGION
12856 #undef UPB_UNPOISON_MEMORY_REGION
12857 #undef UPB_ASAN
12858 #undef UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3
12859