google-protobuf 4.36.2-java → 4.37.0.rc.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/message.c +199 -37
- data/ext/google/protobuf_c/message.h +2 -1
- data/ext/google/protobuf_c/protobuf.c +75 -6
- data/ext/google/protobuf_c/protobuf.h +1 -0
- data/ext/google/protobuf_c/ruby-upb.c +1324 -531
- data/ext/google/protobuf_c/ruby-upb.h +2282 -805
- data/ext/google/protobuf_c/shared_message.c +9 -1
- data/lib/google/protobuf/ffi/internal/convert.rb +32 -10
- data/lib/google/protobuf/ffi/map.rb +0 -1
- data/lib/google/protobuf/ffi/message.rb +10 -2
- data/lib/google/protobuf/ffi/repeated_field.rb +9 -1
- data/lib/google/protobuf/json_enumvalue_options_pb.rb +1 -1
- data/lib/google/protobuf/json_options_pb.rb +1 -1
- data/lib/google/protobuf/repeated_field.rb +2 -2
- data/lib/google/protobuf_java.jar +0 -0
- metadata +19 -19
|
@@ -84,6 +84,19 @@
|
|
|
84
84
|
#define UPB_HAS_BUILTIN(x) 0
|
|
85
85
|
#endif
|
|
86
86
|
|
|
87
|
+
// UPB_MEMCPY_INLINE(dst, src, n): memcpy() of a compile-time constant number
|
|
88
|
+
// of bytes `n`, which the compiler never turns into a call to the library
|
|
89
|
+
// memcpy(). A plain memcpy() of a constant size is usually inlined as loads and
|
|
90
|
+
// stores too, but the compiler can merge such copies of different sizes (e.g.
|
|
91
|
+
// the cases of a switch on the size) into one copy of a variable size, which
|
|
92
|
+
// it then can't inline; the merge can even happen before the compiler uses the
|
|
93
|
+
// UPB_ASSUME()s about the size.
|
|
94
|
+
#if UPB_HAS_BUILTIN(__builtin_memcpy_inline)
|
|
95
|
+
#define UPB_MEMCPY_INLINE(dst, src, n) __builtin_memcpy_inline(dst, src, n)
|
|
96
|
+
#else
|
|
97
|
+
#define UPB_MEMCPY_INLINE(dst, src, n) memcpy(dst, src, n)
|
|
98
|
+
#endif
|
|
99
|
+
|
|
87
100
|
#ifdef __has_extension
|
|
88
101
|
#define UPB_HAS_EXTENSION(x) __has_extension(x)
|
|
89
102
|
#else
|
|
@@ -129,6 +142,14 @@ Error, UINTPTR_MAX is undefined
|
|
|
129
142
|
(((SIZE_MAX - offsetof(type, member[0])) / \
|
|
130
143
|
(offsetof(type, member[1]) - offsetof(type, member[0]))) < (size_t)count)
|
|
131
144
|
|
|
145
|
+
// Inverse of UPB_SIZEOF_FLEX; given the size in memory, how many elements can
|
|
146
|
+
// the flexible array member store?
|
|
147
|
+
#define UPB_FLEX_CAPACITY(type, member, size) \
|
|
148
|
+
((size) < sizeof(type) \
|
|
149
|
+
? (size_t)0 \
|
|
150
|
+
: ((size) - offsetof(type, member[0])) / \
|
|
151
|
+
(offsetof(type, member[1]) - offsetof(type, member[0])))
|
|
152
|
+
|
|
132
153
|
#define UPB_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
|
133
154
|
|
|
134
155
|
#define UPB_MAPTYPE_STRING 0
|
|
@@ -304,12 +325,11 @@ Error, UINTPTR_MAX is undefined
|
|
|
304
325
|
#define UPB_NODEREF
|
|
305
326
|
#endif
|
|
306
327
|
|
|
307
|
-
|
|
308
|
-
#if false && UPB_HAS_C_ATTRIBUTE(nodiscard)
|
|
328
|
+
#if UPB_HAS_C_ATTRIBUTE(nodiscard)
|
|
309
329
|
#define UPB_NODISCARD [[nodiscard]]
|
|
310
|
-
#elif
|
|
330
|
+
#elif UPB_HAS_ATTRIBUTE(warn_unused_result)
|
|
311
331
|
#define UPB_NODISCARD __attribute__((warn_unused_result))
|
|
312
|
-
#elif
|
|
332
|
+
#elif UPB_HAS_CPP_ATTRIBUTE(nodiscard)
|
|
313
333
|
#define UPB_NODISCARD [[nodiscard]]
|
|
314
334
|
#else
|
|
315
335
|
#define UPB_NODISCARD
|
|
@@ -495,7 +515,7 @@ Error, UINTPTR_MAX is undefined
|
|
|
495
515
|
|
|
496
516
|
/* aarch64 supports big and little endian modes; fasttable performs multibyte
|
|
497
517
|
* tag loads assumes the tag of a varint is in the low bits. */
|
|
498
|
-
#if (defined(__x86_64__) || defined(__AARCH64EL__)) && \
|
|
518
|
+
#if !defined(_WIN32) && (defined(__x86_64__) || defined(__AARCH64EL__)) && \
|
|
499
519
|
UPB_HAS_ATTRIBUTE(preserve_none) && UPB_HAS_ATTRIBUTE(musttail)
|
|
500
520
|
#define UPB_FASTTABLE_SUPPORTED 1
|
|
501
521
|
#else
|
|
@@ -514,7 +534,11 @@ Error, UINTPTR_MAX is undefined
|
|
|
514
534
|
* This is useful for releasing code that might be used on multiple platforms,
|
|
515
535
|
* for example the PHP or Ruby C extensions. */
|
|
516
536
|
#elif defined(UPB_TRY_ENABLE_FASTTABLE)
|
|
517
|
-
#
|
|
537
|
+
#if UPB_FASTTABLE_SUPPORTED
|
|
538
|
+
#define UPB_FASTTABLE 1
|
|
539
|
+
#else
|
|
540
|
+
#define UPB_FASTTABLE 0
|
|
541
|
+
#endif
|
|
518
542
|
#else
|
|
519
543
|
#define UPB_FASTTABLE 0
|
|
520
544
|
#endif
|
|
@@ -542,6 +566,25 @@ Error, UINTPTR_MAX is undefined
|
|
|
542
566
|
#define UPB_DEPRECATED
|
|
543
567
|
#endif
|
|
544
568
|
|
|
569
|
+
#if defined(__clang__)
|
|
570
|
+
#define UPB_IGNORE_DEPRECATION_START \
|
|
571
|
+
_Pragma("clang diagnostic push") \
|
|
572
|
+
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
|
|
573
|
+
#define UPB_IGNORE_DEPRECATION_STOP _Pragma("clang diagnostic pop")
|
|
574
|
+
#elif defined(__GNUC__)
|
|
575
|
+
#define UPB_IGNORE_DEPRECATION_START \
|
|
576
|
+
_Pragma("GCC diagnostic push") \
|
|
577
|
+
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
|
578
|
+
#define UPB_IGNORE_DEPRECATION_STOP _Pragma("GCC diagnostic pop")
|
|
579
|
+
#elif defined(_MSC_VER)
|
|
580
|
+
#define UPB_IGNORE_DEPRECATION_START \
|
|
581
|
+
__pragma(warning(push)) __pragma(warning(disable : 4996))
|
|
582
|
+
#define UPB_IGNORE_DEPRECATION_STOP __pragma(warning(pop))
|
|
583
|
+
#else
|
|
584
|
+
#define UPB_IGNORE_DEPRECATION_START
|
|
585
|
+
#define UPB_IGNORE_DEPRECATION_STOP
|
|
586
|
+
#endif
|
|
587
|
+
|
|
545
588
|
#if defined(UPB_IS_GOOGLE3) && \
|
|
546
589
|
(!defined(UPB_BOOTSTRAP_STAGE) || UPB_BOOTSTRAP_STAGE != 0)
|
|
547
590
|
#define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init
|
|
@@ -568,6 +611,12 @@ Error, UINTPTR_MAX is undefined
|
|
|
568
611
|
#define UPB_RETAIN
|
|
569
612
|
#endif
|
|
570
613
|
|
|
614
|
+
#if defined(__GNUC__) || defined(__clang__)
|
|
615
|
+
#define UPB_HIDDEN __attribute__((visibility("hidden")))
|
|
616
|
+
#else
|
|
617
|
+
#define UPB_HIDDEN
|
|
618
|
+
#endif
|
|
619
|
+
|
|
571
620
|
// Linker arrays combine elements from multiple translation units into a single
|
|
572
621
|
// array that can be iterated over at runtime.
|
|
573
622
|
//
|
|
@@ -621,7 +670,7 @@ Error, UINTPTR_MAX is undefined
|
|
|
621
670
|
|
|
622
671
|
#elif defined(__MACH__)
|
|
623
672
|
|
|
624
|
-
/* As described in: https://stackoverflow.com/a/22366882 */
|
|
673
|
+
/* As described in: https://stackoverflow.com/a/22366882 */
|
|
625
674
|
#define UPB_LINKARR_APPEND(name) \
|
|
626
675
|
__attribute__(( \
|
|
627
676
|
section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
|
|
@@ -640,10 +689,10 @@ Error, UINTPTR_MAX is undefined
|
|
|
640
689
|
|
|
641
690
|
#elif defined(_MSC_VER)
|
|
642
691
|
|
|
643
|
-
/* See:
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
692
|
+
/* See:
|
|
693
|
+
* https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155
|
|
694
|
+
* https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165
|
|
695
|
+
* https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */
|
|
647
696
|
#define UPB_STRINGIFY_INTERNAL(x) #x
|
|
648
697
|
#define UPB_STRINGIFY(x) UPB_STRINGIFY_INTERNAL(x)
|
|
649
698
|
#define UPB_CONCAT(a, b, c) a##b##c
|
|
@@ -652,7 +701,7 @@ Error, UINTPTR_MAX is undefined
|
|
|
652
701
|
#define UPB_LINKARR_APPEND(name) \
|
|
653
702
|
__pragma(section(UPB_LINKARR_NAME(name, $j), read)) \
|
|
654
703
|
__declspec(allocate(UPB_LINKARR_NAME(name, $j)))
|
|
655
|
-
// clang-format off
|
|
704
|
+
// clang-format off
|
|
656
705
|
#define UPB_LINKARR_DECLARE(name, type) \
|
|
657
706
|
__pragma(message(UPB_LINKARR_NAME(name, $j))) \
|
|
658
707
|
__pragma(section(UPB_LINKARR_NAME(name, $a), read)) \
|
|
@@ -663,13 +712,13 @@ Error, UINTPTR_MAX is undefined
|
|
|
663
712
|
type __stop_linkarr_##name; \
|
|
664
713
|
UPB_LINKARR_APPEND(name) \
|
|
665
714
|
__declspec(selectany) type UPB_linkarr_internal_empty_##name[1] = {0}
|
|
666
|
-
// clang-format on
|
|
715
|
+
// clang-format on
|
|
667
716
|
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)
|
|
668
717
|
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
|
|
669
718
|
|
|
670
719
|
#else
|
|
671
720
|
|
|
672
|
-
// Linker arrays are not supported on this platform. Make macros no-ops.
|
|
721
|
+
// Linker arrays are not supported on this platform. Make macros no-ops.
|
|
673
722
|
#define UPB_LINKARR_APPEND(name)
|
|
674
723
|
#define UPB_LINKARR_DECLARE(name, type) \
|
|
675
724
|
UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
|
|
@@ -2682,7 +2731,7 @@ UPB_INLINE int _upb_popcnt32(uint32_t i) {
|
|
|
2682
2731
|
|
|
2683
2732
|
#undef UPB_FAST_POPCOUNT32
|
|
2684
2733
|
|
|
2685
|
-
UPB_INLINE uint8_t _upb_log2_table_size(upb_table* t) {
|
|
2734
|
+
UPB_INLINE uint8_t _upb_log2_table_size(const upb_table* t) {
|
|
2686
2735
|
return _upb_popcnt32(t->mask);
|
|
2687
2736
|
}
|
|
2688
2737
|
|
|
@@ -2715,25 +2764,7 @@ typedef bool eqlfunc_t(upb_key k1, upb_value v1, lookupkey_t k2);
|
|
|
2715
2764
|
|
|
2716
2765
|
/* Base table (shared code) ***************************************************/
|
|
2717
2766
|
|
|
2718
|
-
static
|
|
2719
|
-
UPB_STATIC_ASSERT(sizeof(uintptr_t) == 4 || sizeof(uintptr_t) == 8,
|
|
2720
|
-
"Pointers don't fit");
|
|
2721
|
-
if (sizeof(uintptr_t) == 8) {
|
|
2722
|
-
return (uint32_t)key ^ (uint32_t)((uint64_t)key >> 32);
|
|
2723
|
-
} else {
|
|
2724
|
-
return (uint32_t)key;
|
|
2725
|
-
}
|
|
2726
|
-
}
|
|
2727
|
-
|
|
2728
|
-
static upb_tabent* upb_getentry(const upb_table* t, uint32_t hash) {
|
|
2729
|
-
return t->entries + (hash & t->mask);
|
|
2730
|
-
}
|
|
2731
|
-
|
|
2732
|
-
static bool isfull(upb_table* t) {
|
|
2733
|
-
uint32_t size = upb_table_size(t);
|
|
2734
|
-
// 0.875 load factor
|
|
2735
|
-
return t->count == (size - (size >> 3));
|
|
2736
|
-
}
|
|
2767
|
+
static bool isfull(upb_table* t) { return upb_table_isfull(t); }
|
|
2737
2768
|
|
|
2738
2769
|
static bool init(upb_table* t, uint8_t size_lg2, upb_Arena* a) {
|
|
2739
2770
|
if (size_lg2 >= 32) {
|
|
@@ -2742,10 +2773,10 @@ static bool init(upb_table* t, uint8_t size_lg2, upb_Arena* a) {
|
|
|
2742
2773
|
t->count = 0;
|
|
2743
2774
|
uint32_t size = 1U << size_lg2;
|
|
2744
2775
|
t->mask = size - 1; // 0 mask if size_lg2 is 0
|
|
2745
|
-
|
|
2776
|
+
size_t bytes;
|
|
2777
|
+
if (upb_MulOverflow(upb_table_size(t), sizeof(upb_tabent), &bytes)) {
|
|
2746
2778
|
return false;
|
|
2747
2779
|
}
|
|
2748
|
-
size_t bytes = upb_table_size(t) * sizeof(upb_tabent);
|
|
2749
2780
|
if (bytes > 0) {
|
|
2750
2781
|
t->entries = upb_Arena_Malloc(a, bytes);
|
|
2751
2782
|
if (!t->entries) return false;
|
|
@@ -3173,14 +3204,6 @@ static bool streql(upb_key k1, upb_value v1, lookupkey_t k2) {
|
|
|
3173
3204
|
(k1s->size == 0 || memcmp(k1s->data, k2s.data, k1s->size) == 0);
|
|
3174
3205
|
}
|
|
3175
3206
|
|
|
3176
|
-
/** Calculates the number of entries required to hold an expected number of
|
|
3177
|
-
* values, within the table's load factor. */
|
|
3178
|
-
static size_t _upb_entries_needed_for(size_t expected_size) {
|
|
3179
|
-
size_t need_entries = expected_size + 1 + expected_size / 7;
|
|
3180
|
-
UPB_ASSERT(need_entries - (need_entries >> 3) >= expected_size);
|
|
3181
|
-
return need_entries;
|
|
3182
|
-
}
|
|
3183
|
-
|
|
3184
3207
|
bool upb_strtable_init(upb_strtable* t, size_t expected_size, upb_Arena* a) {
|
|
3185
3208
|
int size_lg2 = upb_Log2Ceiling(_upb_entries_needed_for(expected_size));
|
|
3186
3209
|
return init(&t->t, size_lg2, a);
|
|
@@ -3193,34 +3216,78 @@ void upb_strtable_clear(upb_strtable* t) {
|
|
|
3193
3216
|
}
|
|
3194
3217
|
|
|
3195
3218
|
bool upb_strtable_resize(upb_strtable* t, size_t size_lg2, upb_Arena* a) {
|
|
3219
|
+
if (t->t.entries != NULL && _upb_log2_table_size(&t->t) >= size_lg2) {
|
|
3220
|
+
return true;
|
|
3221
|
+
}
|
|
3196
3222
|
upb_strtable new_table;
|
|
3197
3223
|
if (!init(&new_table.t, size_lg2, a)) return false;
|
|
3198
3224
|
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3225
|
+
if (t->t.count > 0) {
|
|
3226
|
+
intptr_t iter = UPB_STRTABLE_BEGIN;
|
|
3227
|
+
upb_StringView sv;
|
|
3228
|
+
upb_value val;
|
|
3229
|
+
while (upb_strtable_next2(t, &sv, &val, &iter)) {
|
|
3230
|
+
// Unlike normal insert, does not copy string data or possibly reallocate
|
|
3231
|
+
// the table
|
|
3232
|
+
// The data pointer used in the table is guaranteed to point at a
|
|
3233
|
+
// upb_SizePrefixString, we just need to back up by the size of the
|
|
3234
|
+
// uint32_t length prefix.
|
|
3235
|
+
const upb_SizePrefixString* keystr =
|
|
3236
|
+
(const upb_SizePrefixString*)(sv.data - sizeof(uint32_t));
|
|
3237
|
+
UPB_ASSERT(keystr->data == sv.data);
|
|
3238
|
+
UPB_ASSERT(keystr->size == sv.size);
|
|
3239
|
+
|
|
3240
|
+
lookupkey_t lookupkey = {.str = sv};
|
|
3241
|
+
upb_key tabkey = {.str = keystr};
|
|
3242
|
+
uint32_t hash = _upb_Hash_NoSeed(sv.data, sv.size);
|
|
3243
|
+
insert(&new_table.t, lookupkey, tabkey, val, hash, &strhash, &streql);
|
|
3244
|
+
}
|
|
3217
3245
|
}
|
|
3218
3246
|
*t = new_table;
|
|
3219
3247
|
return true;
|
|
3220
3248
|
}
|
|
3221
3249
|
|
|
3222
|
-
bool
|
|
3223
|
-
|
|
3250
|
+
bool upb_strtable_copy(upb_strtable* dest, const upb_strtable* src,
|
|
3251
|
+
upb_Arena* a) {
|
|
3252
|
+
if (src->t.count == 0) {
|
|
3253
|
+
return upb_strtable_init(dest, 0, a);
|
|
3254
|
+
}
|
|
3255
|
+
dest->t.count = src->t.count;
|
|
3256
|
+
dest->t.mask = src->t.mask;
|
|
3257
|
+
dest->t.entries =
|
|
3258
|
+
upb_Arena_Malloc(a, upb_table_size(&src->t) * sizeof(upb_tabent));
|
|
3259
|
+
if (!dest->t.entries) return false;
|
|
3260
|
+
upb_tabent* restrict dest_entries = dest->t.entries;
|
|
3261
|
+
const upb_tabent* restrict src_entries = src->t.entries;
|
|
3262
|
+
size_t table_size = upb_table_size(&src->t);
|
|
3263
|
+
for (size_t i = 0; i < table_size; i++) {
|
|
3264
|
+
upb_tabent* dest_ent = &dest_entries[i];
|
|
3265
|
+
const upb_tabent* src_ent = &src_entries[i];
|
|
3266
|
+
if (!upb_tabent_isempty(src_ent)) {
|
|
3267
|
+
upb_StringView sv = upb_key_strview(src_ent->key);
|
|
3268
|
+
upb_SizePrefixString* size_prefix_string =
|
|
3269
|
+
upb_SizePrefixString_Copy(sv, a);
|
|
3270
|
+
if (!size_prefix_string) return false;
|
|
3271
|
+
dest_ent->key.str = size_prefix_string;
|
|
3272
|
+
// The caller is responsible for cloning values if they are not
|
|
3273
|
+
// primitives.
|
|
3274
|
+
dest_ent->val = src_ent->val;
|
|
3275
|
+
if (UPB_UNPREDICTABLE(upb_tabent_hasnext(src_ent))) {
|
|
3276
|
+
size_t offset = upb_tabent_next(src_ent) - src_entries;
|
|
3277
|
+
upb_tabent_setnext(dest_ent, dest_entries + offset);
|
|
3278
|
+
} else {
|
|
3279
|
+
upb_tabent_clearnext(dest_ent);
|
|
3280
|
+
}
|
|
3281
|
+
} else {
|
|
3282
|
+
*dest_ent = (upb_tabent){};
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
return true;
|
|
3286
|
+
}
|
|
3287
|
+
|
|
3288
|
+
// Inserts `k`, whose hash is `hash`, which must not already be in the table.
|
|
3289
|
+
UPB_FORCEINLINE bool strtable_insert(upb_strtable* t, const char* k, size_t len,
|
|
3290
|
+
upb_value v, uint32_t hash, upb_Arena* a) {
|
|
3224
3291
|
if (isfull(&t->t)) {
|
|
3225
3292
|
/* Need to resize. New table of double the size, add old elements to it. */
|
|
3226
3293
|
if (!upb_strtable_resize(t, _upb_log2_table_size(&t->t) + 1, a)) {
|
|
@@ -3234,11 +3301,29 @@ bool upb_strtable_insert(upb_strtable* t, const char* k, size_t len,
|
|
|
3234
3301
|
|
|
3235
3302
|
lookupkey_t lookupkey = {.str = sv};
|
|
3236
3303
|
upb_key key = {.str = size_prefix_string};
|
|
3237
|
-
uint32_t hash = _upb_Hash_NoSeed(k, len);
|
|
3238
3304
|
insert(&t->t, lookupkey, key, v, hash, &strhash, &streql);
|
|
3239
3305
|
return true;
|
|
3240
3306
|
}
|
|
3241
3307
|
|
|
3308
|
+
bool upb_strtable_insert(upb_strtable* t, const char* k, size_t len,
|
|
3309
|
+
upb_value v, upb_Arena* a) {
|
|
3310
|
+
return strtable_insert(t, k, len, v, _upb_Hash_NoSeed(k, len), a);
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
bool upb_strtable_insert_or_replace(upb_strtable* t, const char* k, size_t len,
|
|
3314
|
+
upb_value v, bool* replaced, upb_Arena* a) {
|
|
3315
|
+
uint32_t hash = _upb_Hash_NoSeed(k, len);
|
|
3316
|
+
upb_tabent* e = findentry_mutable(&t->t, strkey2(k, len), hash, &streql);
|
|
3317
|
+
if (e) {
|
|
3318
|
+
e->val = v;
|
|
3319
|
+
*replaced = true;
|
|
3320
|
+
return true;
|
|
3321
|
+
}
|
|
3322
|
+
*replaced = false;
|
|
3323
|
+
if (UPB_UNLIKELY(t->t.entries == NULL) && !init(&t->t, 3, a)) return false;
|
|
3324
|
+
return strtable_insert(t, k, len, v, hash, a);
|
|
3325
|
+
}
|
|
3326
|
+
|
|
3242
3327
|
bool upb_strtable_lookup2(const upb_strtable* t, const char* key, size_t len,
|
|
3243
3328
|
upb_value* v) {
|
|
3244
3329
|
uint32_t hash = _upb_Hash_NoSeed(key, len);
|
|
@@ -3411,8 +3496,6 @@ static bool inteql(upb_key k1, upb_value v1, lookupkey_t k2) {
|
|
|
3411
3496
|
return k1.num == k2.num;
|
|
3412
3497
|
}
|
|
3413
3498
|
|
|
3414
|
-
size_t upb_inttable_count(const upb_inttable* t) { return t->t.count; }
|
|
3415
|
-
|
|
3416
3499
|
static void check(upb_inttable* t) {
|
|
3417
3500
|
UPB_UNUSED(t);
|
|
3418
3501
|
#if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG)
|
|
@@ -3442,25 +3525,161 @@ bool upb_inttable_init(upb_inttable* t, upb_Arena* a) {
|
|
|
3442
3525
|
return upb_inttable_sizedinit(t, 3, a);
|
|
3443
3526
|
}
|
|
3444
3527
|
|
|
3445
|
-
bool
|
|
3446
|
-
|
|
3447
|
-
if (
|
|
3448
|
-
|
|
3528
|
+
bool upb_inttable_copy(upb_inttable* dest, const upb_inttable* src,
|
|
3529
|
+
upb_Arena* a) {
|
|
3530
|
+
if (src->t.count == 0) {
|
|
3531
|
+
return upb_inttable_sizedinit(dest, 0, a);
|
|
3532
|
+
}
|
|
3449
3533
|
|
|
3450
|
-
|
|
3451
|
-
|
|
3534
|
+
if (!upb_inttable_sizedinit(
|
|
3535
|
+
dest, src->t.mask ? _upb_log2_table_size(&src->t) : 0, a)) {
|
|
3536
|
+
return false;
|
|
3537
|
+
}
|
|
3538
|
+
dest->t.count = src->t.count;
|
|
3539
|
+
|
|
3540
|
+
upb_tabent* restrict dest_entries = dest->t.entries;
|
|
3541
|
+
const upb_tabent* restrict src_entries = src->t.entries;
|
|
3542
|
+
size_t table_size = upb_table_size(&src->t);
|
|
3543
|
+
for (size_t i = 0; i < table_size; i++) {
|
|
3544
|
+
upb_tabent* dest_ent = &dest_entries[i];
|
|
3545
|
+
const upb_tabent* src_ent = &src_entries[i];
|
|
3546
|
+
if (!upb_tabent_isempty(src_ent)) {
|
|
3547
|
+
// The caller is responsible for cloning these if they are not primitives.
|
|
3548
|
+
dest_ent->key = src_ent->key;
|
|
3549
|
+
dest_ent->val = src_ent->val;
|
|
3550
|
+
if (UPB_UNPREDICTABLE(upb_tabent_hasnext(src_ent))) {
|
|
3551
|
+
size_t offset = upb_tabent_next(src_ent) - src_entries;
|
|
3552
|
+
upb_tabent_setnext(dest_ent, dest_entries + offset);
|
|
3553
|
+
} else {
|
|
3554
|
+
upb_tabent_clearnext(dest_ent);
|
|
3555
|
+
}
|
|
3556
|
+
} else {
|
|
3557
|
+
*dest_ent = (upb_tabent){};
|
|
3452
3558
|
}
|
|
3559
|
+
}
|
|
3560
|
+
return true;
|
|
3561
|
+
}
|
|
3562
|
+
|
|
3563
|
+
// Attempts to grow the inttable in-place. If a table has primitive keys and
|
|
3564
|
+
// values, insertions generally don't allocate anything in between the table's
|
|
3565
|
+
// allocations; in that case, growing the table in place uses half the total
|
|
3566
|
+
// memory compared to allocating new chunks and copying over.
|
|
3567
|
+
static bool upb_inttable_trygrow(upb_inttable* t, size_t size_lg2,
|
|
3568
|
+
upb_Arena* a) {
|
|
3569
|
+
if (size_lg2 >= 32) {
|
|
3570
|
+
return false;
|
|
3571
|
+
}
|
|
3572
|
+
size_t old_size = upb_table_size(&t->t);
|
|
3573
|
+
size_t old_bytes = old_size * sizeof(upb_tabent);
|
|
3574
|
+
size_t new_size = (size_t)1 << size_lg2;
|
|
3575
|
+
size_t new_bytes = new_size * sizeof(upb_tabent);
|
|
3576
|
+
if (new_bytes <= old_bytes || !t->t.entries) {
|
|
3577
|
+
return false;
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3580
|
+
if (!upb_Arena_TryExtend(a, t->t.entries, old_bytes, new_bytes)) {
|
|
3581
|
+
return false;
|
|
3582
|
+
}
|
|
3583
|
+
|
|
3584
|
+
// Zero out the newly extended region of the table buffer.
|
|
3585
|
+
memset(t->t.entries + old_size, 0,
|
|
3586
|
+
(new_size - old_size) * sizeof(upb_tabent));
|
|
3453
3587
|
|
|
3588
|
+
// This one-past-the-end pointer is guaranteed to be distinct from NULL and
|
|
3589
|
+
// any valid internal collision chain pointer in the entire table.
|
|
3590
|
+
upb_tabent* unhashed_marker = t->t.entries + new_size;
|
|
3591
|
+
|
|
3592
|
+
// Mark all existing occupied entries as UNHASHED using the distinct
|
|
3593
|
+
// marker. Because e->next != NULL, these pending slots are fully protected
|
|
3594
|
+
// from being claimed by emptyent() during collision chain formation.
|
|
3595
|
+
for (size_t i = 0; i < old_size; i++) {
|
|
3596
|
+
upb_tabent* e = &t->t.entries[i];
|
|
3597
|
+
if (!upb_tabent_isempty(e)) {
|
|
3598
|
+
upb_tabent_setnext(e, unhashed_marker);
|
|
3599
|
+
}
|
|
3600
|
+
}
|
|
3601
|
+
|
|
3602
|
+
const uint32_t mask = new_size - 1;
|
|
3603
|
+
t->t.mask = mask;
|
|
3604
|
+
t->t.count = 0; // Reset count as insert will increment it back up
|
|
3605
|
+
|
|
3606
|
+
// Trace and resolve all destinations.
|
|
3607
|
+
for (size_t i = 0; i < old_size; i++) {
|
|
3608
|
+
upb_tabent* current = &t->t.entries[i];
|
|
3609
|
+
if (!upb_tabent_hasnext(current) ||
|
|
3610
|
+
upb_tabent_next(current) != unhashed_marker) {
|
|
3611
|
+
continue; // Slot is already hashed or empty.
|
|
3612
|
+
}
|
|
3613
|
+
|
|
3614
|
+
// Pop the leading unhashed entry to begin our trace cycle.
|
|
3615
|
+
upb_key tabkey = current->key;
|
|
3616
|
+
upb_value val = current->val;
|
|
3617
|
+
upb_tabent_clear(current);
|
|
3618
|
+
|
|
3619
|
+
// This inner loop clears at least one unhashed slot per iteration, for
|
|
3620
|
+
// total O(n) time across the whole rehash.
|
|
3621
|
+
while (true) {
|
|
3622
|
+
uint32_t hash = inthash(tabkey, val);
|
|
3623
|
+
upb_tabent* target_bucket = &t->t.entries[hash & mask];
|
|
3624
|
+
|
|
3625
|
+
if (upb_tabent_hasnext(target_bucket) &&
|
|
3626
|
+
upb_tabent_next(target_bucket) == unhashed_marker) {
|
|
3627
|
+
// Primary bucket contains a pending unhashed entry. Extract it, clear
|
|
3628
|
+
// the bucket, place our entry, and trace the evicted one.
|
|
3629
|
+
upb_key next_tabkey = target_bucket->key;
|
|
3630
|
+
upb_value next_val = target_bucket->val;
|
|
3631
|
+
|
|
3632
|
+
upb_tabent_clear(target_bucket);
|
|
3633
|
+
|
|
3634
|
+
insert(&t->t, intkey(tabkey.num), tabkey, val, hash, &inthash, &inteql);
|
|
3635
|
+
|
|
3636
|
+
tabkey = next_tabkey;
|
|
3637
|
+
val = next_val;
|
|
3638
|
+
} else {
|
|
3639
|
+
// Primary bucket is either empty or holds an already-hashed chain.
|
|
3640
|
+
// The standard insert() function perfectly resolves both cases.
|
|
3641
|
+
insert(&t->t, intkey(tabkey.num), tabkey, val, hash, &inthash, &inteql);
|
|
3642
|
+
break;
|
|
3643
|
+
}
|
|
3644
|
+
}
|
|
3645
|
+
}
|
|
3646
|
+
return true;
|
|
3647
|
+
}
|
|
3648
|
+
|
|
3649
|
+
bool upb_inttable_resize(upb_inttable* t, size_t size_lg2, upb_Arena* a) {
|
|
3650
|
+
if (t->t.entries != NULL && _upb_log2_table_size(&t->t) >= size_lg2) {
|
|
3651
|
+
return true;
|
|
3652
|
+
}
|
|
3653
|
+
if (t->t.entries != NULL && upb_inttable_trygrow(t, size_lg2, a)) {
|
|
3654
|
+
return true;
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3657
|
+
upb_table new_table;
|
|
3658
|
+
if (!init(&new_table, size_lg2, a)) return false;
|
|
3659
|
+
|
|
3660
|
+
if (t->t.count > 0) {
|
|
3454
3661
|
for (size_t i = begin(&t->t); i < upb_table_size(&t->t);
|
|
3455
3662
|
i = next(&t->t, i)) {
|
|
3456
3663
|
const upb_tabent* e = &t->t.entries[i];
|
|
3457
3664
|
insert(&new_table, intkey(e->key.num), e->key, e->val,
|
|
3458
3665
|
inthash(e->key, e->val), &inthash, &inteql);
|
|
3459
3666
|
}
|
|
3667
|
+
}
|
|
3460
3668
|
|
|
3461
|
-
|
|
3669
|
+
UPB_ASSERT(t->t.count == new_table.count);
|
|
3670
|
+
t->t = new_table;
|
|
3671
|
+
return true;
|
|
3672
|
+
}
|
|
3673
|
+
|
|
3674
|
+
UPB_NOINLINE static bool upb_inttable_grow(upb_inttable* t, upb_Arena* a) {
|
|
3675
|
+
size_t new_size = _upb_log2_table_size(&t->t) + 1;
|
|
3676
|
+
return upb_inttable_resize(t, new_size, a);
|
|
3677
|
+
}
|
|
3462
3678
|
|
|
3463
|
-
|
|
3679
|
+
bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val,
|
|
3680
|
+
upb_Arena* a) {
|
|
3681
|
+
if (UPB_UNLIKELY(isfull(&t->t))) {
|
|
3682
|
+
if (!upb_inttable_grow(t, a)) return false;
|
|
3464
3683
|
}
|
|
3465
3684
|
upb_key tabkey = {.num = key};
|
|
3466
3685
|
insert(&t->t, intkey(key), tabkey, val, upb_inthash(key), &inthash, &inteql);
|
|
@@ -3468,6 +3687,23 @@ bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val,
|
|
|
3468
3687
|
return true;
|
|
3469
3688
|
}
|
|
3470
3689
|
|
|
3690
|
+
bool upb_inttable_insert_or_replace_slow(upb_inttable* t, uintptr_t key,
|
|
3691
|
+
upb_value val, bool* replaced,
|
|
3692
|
+
upb_Arena* a) {
|
|
3693
|
+
upb_tabent* e =
|
|
3694
|
+
findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql);
|
|
3695
|
+
if (e) {
|
|
3696
|
+
e->val = val;
|
|
3697
|
+
*replaced = true;
|
|
3698
|
+
return true;
|
|
3699
|
+
}
|
|
3700
|
+
*replaced = false;
|
|
3701
|
+
if (UPB_UNLIKELY(t->t.entries == NULL) && !upb_inttable_init(t, a)) {
|
|
3702
|
+
return false;
|
|
3703
|
+
}
|
|
3704
|
+
return upb_inttable_insert(t, key, val, a);
|
|
3705
|
+
}
|
|
3706
|
+
|
|
3471
3707
|
bool upb_inttable_lookup(const upb_inttable* t, uintptr_t key, upb_value* v) {
|
|
3472
3708
|
return lookup(&t->t, intkey(key), v, upb_inthash(key), &inteql);
|
|
3473
3709
|
}
|
|
@@ -3536,9 +3772,11 @@ upb_value upb_inttable_iter_value(const upb_inttable* t, intptr_t iter) {
|
|
|
3536
3772
|
#include <stdarg.h>
|
|
3537
3773
|
#include <stddef.h>
|
|
3538
3774
|
#include <stdint.h>
|
|
3775
|
+
#include <stdio.h>
|
|
3539
3776
|
#include <stdlib.h>
|
|
3540
3777
|
#include <string.h>
|
|
3541
3778
|
|
|
3779
|
+
#include "utf8_range.h"
|
|
3542
3780
|
|
|
3543
3781
|
// Must be last.
|
|
3544
3782
|
|
|
@@ -3938,8 +4176,9 @@ static void jsondec_resize(jsondec* d, char** buf, char** end, char** buf_end) {
|
|
|
3938
4176
|
size_t oldsize = *buf_end - *buf;
|
|
3939
4177
|
size_t len = *end - *buf;
|
|
3940
4178
|
|
|
3941
|
-
|
|
3942
|
-
|
|
4179
|
+
size_t size;
|
|
4180
|
+
jsondec_checkoom(d, !upb_MulOverflow(oldsize, (size_t)2, &size));
|
|
4181
|
+
size = UPB_MAX(8, size);
|
|
3943
4182
|
|
|
3944
4183
|
*buf = upb_Arena_Realloc(d->arena, *buf, len, size);
|
|
3945
4184
|
jsondec_checkoom(d, *buf);
|
|
@@ -4849,7 +5088,7 @@ static upb_StringView jsondec_mask(jsondec* d, const char* buf,
|
|
|
4849
5088
|
}
|
|
4850
5089
|
|
|
4851
5090
|
out = upb_Arena_Malloc(d->arena, ret.size);
|
|
4852
|
-
jsondec_checkoom(d, out
|
|
5091
|
+
jsondec_checkoom(d, out);
|
|
4853
5092
|
ptr = buf;
|
|
4854
5093
|
ret.data = out;
|
|
4855
5094
|
|
|
@@ -5097,6 +5336,23 @@ int upb_JsonDecodeDetectingNonconformance(const char* buf, size_t size,
|
|
|
5097
5336
|
|
|
5098
5337
|
if (size == 0) return true;
|
|
5099
5338
|
|
|
5339
|
+
UPB_ASSERT(!((options & upb_JsonDecode_ValidateUtf8_Disable) &&
|
|
5340
|
+
(options & upb_JsonDecode_ValidateUtf8_Enforce)));
|
|
5341
|
+
|
|
5342
|
+
if (!(options & upb_JsonDecode_ValidateUtf8_Disable)) {
|
|
5343
|
+
if (!utf8_range_IsValid(buf, size)) {
|
|
5344
|
+
if (options & upb_JsonDecode_ValidateUtf8_Enforce) {
|
|
5345
|
+
upb_Status_SetErrorMessage(status, "Invalid UTF-8 in JSON input");
|
|
5346
|
+
return kUpb_JsonDecodeResult_Error;
|
|
5347
|
+
} else {
|
|
5348
|
+
fprintf(
|
|
5349
|
+
stderr,
|
|
5350
|
+
"Invalid UTF-8 in JSON input. This will be rejected starting in "
|
|
5351
|
+
"the 2027-Q1 breaking change\n");
|
|
5352
|
+
}
|
|
5353
|
+
}
|
|
5354
|
+
}
|
|
5355
|
+
|
|
5100
5356
|
d.ptr = buf;
|
|
5101
5357
|
d.end = buf + size;
|
|
5102
5358
|
d.arena = arena;
|
|
@@ -5166,6 +5422,9 @@ static upb_Arena* jsonenc_arena(jsonenc* e) {
|
|
|
5166
5422
|
/* Create lazily, since it's only needed for Any */
|
|
5167
5423
|
if (!e->arena) {
|
|
5168
5424
|
e->arena = upb_Arena_New();
|
|
5425
|
+
if (!e->arena) {
|
|
5426
|
+
jsonenc_err(e, "Out of memory");
|
|
5427
|
+
}
|
|
5169
5428
|
}
|
|
5170
5429
|
return e->arena;
|
|
5171
5430
|
}
|
|
@@ -5317,9 +5576,14 @@ static void jsonenc_enum(int32_t val, const upb_FieldDef* f, jsonenc* e) {
|
|
|
5317
5576
|
}
|
|
5318
5577
|
|
|
5319
5578
|
static void jsonenc_bytes(jsonenc* e, upb_StringView str) {
|
|
5320
|
-
/*
|
|
5321
|
-
|
|
5579
|
+
/* Regular base64 (RFC 4648 section 4) by default; the URL- and filename-safe
|
|
5580
|
+
* alphabet (RFC 4648 section 5) when upb_JsonEncode_WebSafeBase64 is set. */
|
|
5581
|
+
static const char kBase64[] =
|
|
5322
5582
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
5583
|
+
static const char kWebSafeBase64[] =
|
|
5584
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
5585
|
+
const char* base64 =
|
|
5586
|
+
(e->options & upb_JsonEncode_WebSafeBase64) ? kWebSafeBase64 : kBase64;
|
|
5323
5587
|
const unsigned char* ptr = (unsigned char*)str.data;
|
|
5324
5588
|
const unsigned char* end = UPB_PTRADD(ptr, str.size);
|
|
5325
5589
|
char buf[4];
|
|
@@ -5355,43 +5619,47 @@ static void jsonenc_bytes(jsonenc* e, upb_StringView str) {
|
|
|
5355
5619
|
jsonenc_putstr(e, "\"");
|
|
5356
5620
|
}
|
|
5357
5621
|
|
|
5622
|
+
static void jsonenc_put_escaped_char(jsonenc* e, char ch) {
|
|
5623
|
+
switch (ch) {
|
|
5624
|
+
case '\n':
|
|
5625
|
+
jsonenc_putstr(e, "\\n");
|
|
5626
|
+
break;
|
|
5627
|
+
case '\r':
|
|
5628
|
+
jsonenc_putstr(e, "\\r");
|
|
5629
|
+
break;
|
|
5630
|
+
case '\t':
|
|
5631
|
+
jsonenc_putstr(e, "\\t");
|
|
5632
|
+
break;
|
|
5633
|
+
case '\"':
|
|
5634
|
+
jsonenc_putstr(e, "\\\"");
|
|
5635
|
+
break;
|
|
5636
|
+
case '\f':
|
|
5637
|
+
jsonenc_putstr(e, "\\f");
|
|
5638
|
+
break;
|
|
5639
|
+
case '\b':
|
|
5640
|
+
jsonenc_putstr(e, "\\b");
|
|
5641
|
+
break;
|
|
5642
|
+
case '\\':
|
|
5643
|
+
jsonenc_putstr(e, "\\\\");
|
|
5644
|
+
break;
|
|
5645
|
+
default:
|
|
5646
|
+
if ((uint8_t)ch < 0x20) {
|
|
5647
|
+
jsonenc_printf(e, "\\u%04x", (int)(uint8_t)ch);
|
|
5648
|
+
} else {
|
|
5649
|
+
/* This could be a non-ASCII byte. We rely on the string being valid
|
|
5650
|
+
* UTF-8. */
|
|
5651
|
+
jsonenc_putbytes(e, &ch, 1);
|
|
5652
|
+
}
|
|
5653
|
+
break;
|
|
5654
|
+
}
|
|
5655
|
+
}
|
|
5656
|
+
|
|
5358
5657
|
static void jsonenc_stringbody(jsonenc* e, upb_StringView str) {
|
|
5359
5658
|
const char* ptr = str.data;
|
|
5360
5659
|
const char* end = UPB_PTRADD(ptr, str.size);
|
|
5361
5660
|
|
|
5362
5661
|
while (ptr < end) {
|
|
5363
|
-
|
|
5364
|
-
case '\n':
|
|
5365
|
-
jsonenc_putstr(e, "\\n");
|
|
5366
|
-
break;
|
|
5367
|
-
case '\r':
|
|
5368
|
-
jsonenc_putstr(e, "\\r");
|
|
5369
|
-
break;
|
|
5370
|
-
case '\t':
|
|
5371
|
-
jsonenc_putstr(e, "\\t");
|
|
5372
|
-
break;
|
|
5373
|
-
case '\"':
|
|
5374
|
-
jsonenc_putstr(e, "\\\"");
|
|
5375
|
-
break;
|
|
5376
|
-
case '\f':
|
|
5377
|
-
jsonenc_putstr(e, "\\f");
|
|
5378
|
-
break;
|
|
5379
|
-
case '\b':
|
|
5380
|
-
jsonenc_putstr(e, "\\b");
|
|
5381
|
-
break;
|
|
5382
|
-
case '\\':
|
|
5383
|
-
jsonenc_putstr(e, "\\\\");
|
|
5384
|
-
break;
|
|
5385
|
-
default:
|
|
5386
|
-
if ((uint8_t)*ptr < 0x20) {
|
|
5387
|
-
jsonenc_printf(e, "\\u%04x", (int)(uint8_t)*ptr);
|
|
5388
|
-
} else {
|
|
5389
|
-
/* This could be a non-ASCII byte. We rely on the string being valid
|
|
5390
|
-
* UTF-8. */
|
|
5391
|
-
jsonenc_putbytes(e, ptr, 1);
|
|
5392
|
-
}
|
|
5393
|
-
break;
|
|
5394
|
-
}
|
|
5662
|
+
jsonenc_put_escaped_char(e, *ptr);
|
|
5395
5663
|
ptr++;
|
|
5396
5664
|
}
|
|
5397
5665
|
}
|
|
@@ -5483,6 +5751,10 @@ static void jsonenc_any(jsonenc* e, const upb_Message* msg,
|
|
|
5483
5751
|
const upb_MiniTable* any_layout = upb_MessageDef_MiniTable(any_m);
|
|
5484
5752
|
upb_Arena* arena = jsonenc_arena(e);
|
|
5485
5753
|
upb_Message* any = upb_Message_New(any_layout, arena);
|
|
5754
|
+
if (!any) {
|
|
5755
|
+
jsonenc_err(e, "Out of memory");
|
|
5756
|
+
return;
|
|
5757
|
+
}
|
|
5486
5758
|
|
|
5487
5759
|
if (upb_Decode(value.data, value.size, any, any_layout, NULL, 0, arena) !=
|
|
5488
5760
|
kUpb_DecodeStatus_Ok) {
|
|
@@ -5535,7 +5807,7 @@ static void jsonenc_fieldpath(jsonenc* e, upb_StringView path) {
|
|
|
5535
5807
|
ch = *++ptr - 32;
|
|
5536
5808
|
}
|
|
5537
5809
|
|
|
5538
|
-
|
|
5810
|
+
jsonenc_put_escaped_char(e, ch);
|
|
5539
5811
|
ptr++;
|
|
5540
5812
|
}
|
|
5541
5813
|
}
|
|
@@ -6013,6 +6285,7 @@ int upb_Unicode_ToUTF8(uint32_t cp, char* out) {
|
|
|
6013
6285
|
}
|
|
6014
6286
|
|
|
6015
6287
|
|
|
6288
|
+
#include <stdint.h>
|
|
6016
6289
|
#include <stdlib.h>
|
|
6017
6290
|
|
|
6018
6291
|
// Must be last.
|
|
@@ -6030,9 +6303,58 @@ static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize,
|
|
|
6030
6303
|
}
|
|
6031
6304
|
}
|
|
6032
6305
|
|
|
6033
|
-
|
|
6306
|
+
#ifdef UPB_ALLOCATION_COUNT
|
|
6307
|
+
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
|
|
6308
|
+
!defined(__STDC_NO_THREADS__)) || \
|
|
6309
|
+
UPB_HAS_EXTENSION(c_thread_local)
|
|
6310
|
+
#define UPB_THREAD_LOCAL _Thread_local
|
|
6311
|
+
#elif defined(_MSC_VER)
|
|
6312
|
+
#define UPB_THREAD_LOCAL __declspec(thread)
|
|
6313
|
+
#elif defined(__GNUC__) || defined(__clang__)
|
|
6314
|
+
#define UPB_THREAD_LOCAL __thread
|
|
6315
|
+
#else
|
|
6316
|
+
#define UPB_THREAD_LOCAL
|
|
6317
|
+
#endif
|
|
6318
|
+
|
|
6319
|
+
UPB_THREAD_LOCAL size_t upb_arena_alloc_count = 0;
|
|
6320
|
+
UPB_THREAD_LOCAL size_t upb_arena_alloc_fail_on = SIZE_MAX;
|
|
6321
|
+
|
|
6322
|
+
#undef UPB_THREAD_LOCAL
|
|
6323
|
+
#endif
|
|
6324
|
+
|
|
6325
|
+
UPB_NODISCARD bool upb_AllocationCount_IsAvailable(void) {
|
|
6326
|
+
#ifdef UPB_ALLOCATION_COUNT
|
|
6327
|
+
return true;
|
|
6328
|
+
#else
|
|
6329
|
+
return false;
|
|
6330
|
+
#endif
|
|
6331
|
+
}
|
|
6332
|
+
|
|
6333
|
+
UPB_NODISCARD size_t upb_AllocationCount_Get(void) {
|
|
6334
|
+
#ifdef UPB_ALLOCATION_COUNT
|
|
6335
|
+
return upb_arena_alloc_count;
|
|
6336
|
+
#else
|
|
6337
|
+
return 0;
|
|
6338
|
+
#endif
|
|
6339
|
+
}
|
|
6340
|
+
|
|
6341
|
+
void upb_AllocationCount_Reset(void) {
|
|
6342
|
+
#ifdef UPB_ALLOCATION_COUNT
|
|
6343
|
+
upb_arena_alloc_count = 0;
|
|
6344
|
+
upb_arena_alloc_fail_on = SIZE_MAX;
|
|
6345
|
+
#endif
|
|
6346
|
+
}
|
|
6347
|
+
|
|
6348
|
+
void upb_AllocationCount_FailOn(size_t n) {
|
|
6349
|
+
#ifdef UPB_ALLOCATION_COUNT
|
|
6350
|
+
upb_arena_alloc_fail_on = n;
|
|
6351
|
+
#endif
|
|
6352
|
+
}
|
|
6353
|
+
|
|
6354
|
+
upb_alloc upb_alloc_global = {&upb_global_allocfunc, NULL};
|
|
6034
6355
|
|
|
6035
6356
|
|
|
6357
|
+
#include <limits.h>
|
|
6036
6358
|
#include <string.h>
|
|
6037
6359
|
|
|
6038
6360
|
|
|
@@ -6102,10 +6424,6 @@ typedef struct upb_ArenaInternal {
|
|
|
6102
6424
|
// Total space allocated in blocks, atomic only for SpaceAllocated
|
|
6103
6425
|
UPB_ATOMIC(uintptr_t) space_allocated;
|
|
6104
6426
|
|
|
6105
|
-
// The cleanup for the allocator. This is called after all the blocks are
|
|
6106
|
-
// freed in an arena.
|
|
6107
|
-
upb_AllocCleanupFunc* upb_alloc_cleanup;
|
|
6108
|
-
|
|
6109
6427
|
// When multiple arenas are fused together, each arena points to a parent
|
|
6110
6428
|
// arena (root points to itself). The root tracks how many live arenas
|
|
6111
6429
|
// reference it.
|
|
@@ -6440,6 +6758,17 @@ void UPB_PRIVATE(_upb_Arena_UseBlock)(upb_Arena* a, void* ptr, size_t size) {
|
|
|
6440
6758
|
size = UPB_ALIGN_DOWN(size, UPB_MALLOC_ALIGN);
|
|
6441
6759
|
#endif
|
|
6442
6760
|
if (size <= UPB_PRIVATE(_upb_ArenaHas)(a)) return;
|
|
6761
|
+
|
|
6762
|
+
// Harvest remaining space from the retired active block into power-of-2
|
|
6763
|
+
// pool bins.
|
|
6764
|
+
if (a->UPB_ONLYBITS(ptr) && a->UPB_ONLYBITS(end)) {
|
|
6765
|
+
char* curr = (char*)a->UPB_ONLYBITS(ptr);
|
|
6766
|
+
char* end = (char*)a->UPB_ONLYBITS(end);
|
|
6767
|
+
if (end > curr) {
|
|
6768
|
+
UPB_PRIVATE(_upb_Arena_Harvest)(a, curr, end - curr);
|
|
6769
|
+
}
|
|
6770
|
+
}
|
|
6771
|
+
|
|
6443
6772
|
a->UPB_ONLYBITS(ptr) = ptr;
|
|
6444
6773
|
a->UPB_ONLYBITS(end) = UPB_PTR_AT(ptr, size, char);
|
|
6445
6774
|
UPB_PRIVATE(upb_Xsan_PoisonRegion)(ptr, size);
|
|
@@ -6524,11 +6853,62 @@ void* UPB_PRIVATE(_upb_Arena_SlowMalloc)(upb_Arena* a, size_t span) {
|
|
|
6524
6853
|
} else {
|
|
6525
6854
|
UPB_PRIVATE(_upb_Arena_UseBlock)(a, block, block_size);
|
|
6526
6855
|
UPB_ASSERT(UPB_PRIVATE(_upb_ArenaHas)(a) >= span);
|
|
6527
|
-
return
|
|
6856
|
+
return _upb_Arena_Malloc_Unchecked(a, size);
|
|
6857
|
+
}
|
|
6858
|
+
}
|
|
6859
|
+
|
|
6860
|
+
// Having a sentinel empty pool allows us to unconditionally load the bin count,
|
|
6861
|
+
// avoiding a branch to check for null on the hot path.
|
|
6862
|
+
const UPB_PRIVATE(_upb_ArenaPool) UPB_PRIVATE(_upb_Arena_EmptyPool) = {0};
|
|
6863
|
+
|
|
6864
|
+
static size_t _upb_Arena_PoolCapacity(size_t size) {
|
|
6865
|
+
UPB_ASSERT(size >= sizeof(UPB_PRIVATE(_upb_ArenaPool)));
|
|
6866
|
+
return (size - offsetof(UPB_PRIVATE(_upb_ArenaPool), UPB_PRIVATE(bins)[0])) /
|
|
6867
|
+
sizeof(void*);
|
|
6868
|
+
}
|
|
6869
|
+
|
|
6870
|
+
void UPB_PRIVATE(_upb_Arena_GrowPool)(upb_Arena* a, void* ptr, size_t size) {
|
|
6871
|
+
UPB_ASSERT(a);
|
|
6872
|
+
UPB_ASSERT(ptr);
|
|
6873
|
+
UPB_PRIVATE(upb_Xsan_PoisonRegion)(ptr, size);
|
|
6874
|
+
UPB_ASSERT(size >= UPB_PRIVATE(kUpb_Arena_MinPoolBlockSize));
|
|
6875
|
+
|
|
6876
|
+
const size_t kMaxBins =
|
|
6877
|
+
(sizeof(size_t) * CHAR_BIT) - _UPB_ARENA_MIN_POOL_BIN_LG2;
|
|
6878
|
+
size_t new_cap = UPB_MIN(kMaxBins, _upb_Arena_PoolCapacity(size));
|
|
6879
|
+
|
|
6880
|
+
UPB_PRIVATE(_upb_ArenaPool)* new_pool =
|
|
6881
|
+
(UPB_PRIVATE(_upb_ArenaPool)*)UPB_PRIVATE(upb_Xsan_NewUnpoisonedRegion)(
|
|
6882
|
+
UPB_XSAN(a), ptr,
|
|
6883
|
+
UPB_SIZEOF_FLEX(UPB_PRIVATE(_upb_ArenaPool), UPB_PRIVATE(bins),
|
|
6884
|
+
new_cap));
|
|
6885
|
+
UPB_PRIVATE(_upb_ArenaPool)* old_pool = a->UPB_ONLYBITS(pool);
|
|
6886
|
+
size_t old_num_bins = old_pool->UPB_PRIVATE(num_bins);
|
|
6887
|
+
|
|
6888
|
+
UPB_PRIVATE(_upb_ArenaFreeBlock)** dst = new_pool->UPB_PRIVATE(bins);
|
|
6889
|
+
UPB_PRIVATE(_upb_ArenaFreeBlock)** src = old_pool->UPB_PRIVATE(bins);
|
|
6890
|
+
|
|
6891
|
+
size_t i;
|
|
6892
|
+
for (i = 0; i < old_num_bins; i++) {
|
|
6893
|
+
*dst++ = *src++;
|
|
6894
|
+
}
|
|
6895
|
+
if (old_pool != &UPB_PRIVATE(_upb_Arena_EmptyPool)) {
|
|
6896
|
+
UPB_PRIVATE(upb_Xsan_PoisonRegion)(
|
|
6897
|
+
old_pool, UPB_SIZEOF_FLEX(UPB_PRIVATE(_upb_ArenaPool),
|
|
6898
|
+
UPB_PRIVATE(bins), old_num_bins));
|
|
6899
|
+
}
|
|
6900
|
+
for (i = old_num_bins; i < new_cap; i++) {
|
|
6901
|
+
*dst++ = NULL;
|
|
6528
6902
|
}
|
|
6903
|
+
|
|
6904
|
+
new_pool->UPB_PRIVATE(num_bins) = new_cap;
|
|
6905
|
+
a->UPB_ONLYBITS(pool) = new_pool;
|
|
6529
6906
|
}
|
|
6530
6907
|
|
|
6531
6908
|
static upb_Arena* _upb_Arena_InitSlow(upb_alloc* alloc, size_t first_size) {
|
|
6909
|
+
if (!upb_AllocationCount_IncrementAndCheck()) {
|
|
6910
|
+
return NULL;
|
|
6911
|
+
}
|
|
6532
6912
|
if (!alloc) return NULL;
|
|
6533
6913
|
|
|
6534
6914
|
// We need to malloc the initial block.
|
|
@@ -6546,6 +6926,8 @@ static upb_Arena* _upb_Arena_InitSlow(upb_alloc* alloc, size_t first_size) {
|
|
|
6546
6926
|
a->body.size_hint = UPB_MIN(block_size, UINT32_MAX);
|
|
6547
6927
|
a->head.UPB_ONLYBITS(ptr) = NULL;
|
|
6548
6928
|
a->head.UPB_ONLYBITS(end) = NULL;
|
|
6929
|
+
a->head.UPB_ONLYBITS(pool) =
|
|
6930
|
+
(UPB_PRIVATE(_upb_ArenaPool)*)&UPB_PRIVATE(_upb_Arena_EmptyPool);
|
|
6549
6931
|
|
|
6550
6932
|
upb_Atomic_Init(&a->body.parent_or_count, _upb_Arena_TaggedFromRefcount(1));
|
|
6551
6933
|
upb_Atomic_Init(&a->body.next, NULL);
|
|
@@ -6556,7 +6938,6 @@ static upb_Arena* _upb_Arena_InitSlow(upb_alloc* alloc, size_t first_size) {
|
|
|
6556
6938
|
#ifndef NDEBUG
|
|
6557
6939
|
a->body.refs = NULL;
|
|
6558
6940
|
#endif
|
|
6559
|
-
a->body.upb_alloc_cleanup = NULL;
|
|
6560
6941
|
UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(&a->body));
|
|
6561
6942
|
|
|
6562
6943
|
UPB_PRIVATE(_upb_Arena_AddBlock)(&a->head, block);
|
|
@@ -6601,10 +6982,11 @@ upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc) {
|
|
|
6601
6982
|
#endif
|
|
6602
6983
|
a->body.size_hint = 128;
|
|
6603
6984
|
a->body.last_block_size = 128;
|
|
6604
|
-
a->body.upb_alloc_cleanup = NULL;
|
|
6605
6985
|
a->body.block_alloc = _upb_Arena_MakeBlockAlloc(alloc, 1);
|
|
6606
6986
|
a->head.UPB_PRIVATE(ptr) = (void*)UPB_ALIGN_MALLOC((uintptr_t)(a + 1));
|
|
6607
6987
|
a->head.UPB_PRIVATE(end) = UPB_PTR_AT(mem, n, char);
|
|
6988
|
+
a->head.UPB_ONLYBITS(pool) =
|
|
6989
|
+
(UPB_PRIVATE(_upb_ArenaPool)*)&UPB_PRIVATE(_upb_Arena_EmptyPool);
|
|
6608
6990
|
UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(&a->body));
|
|
6609
6991
|
#ifdef UPB_TRACING_ENABLED
|
|
6610
6992
|
upb_Arena_LogInit(&a->head, n);
|
|
@@ -6628,7 +7010,6 @@ static void _upb_Arena_DoFree(upb_ArenaInternal* ai) {
|
|
|
6628
7010
|
}
|
|
6629
7011
|
upb_alloc* block_alloc = _upb_ArenaInternal_BlockAlloc(ai);
|
|
6630
7012
|
upb_MemBlock* block = ai->blocks;
|
|
6631
|
-
upb_AllocCleanupFunc* alloc_cleanup = ai->upb_alloc_cleanup;
|
|
6632
7013
|
while (block != NULL) {
|
|
6633
7014
|
// Load first since we are deleting block.
|
|
6634
7015
|
upb_MemBlock* next_block = block->next;
|
|
@@ -6642,8 +7023,8 @@ static void _upb_Arena_DoFree(upb_ArenaInternal* ai) {
|
|
|
6642
7023
|
}
|
|
6643
7024
|
block = next_block;
|
|
6644
7025
|
}
|
|
6645
|
-
if (
|
|
6646
|
-
|
|
7026
|
+
if (block_alloc && block_alloc->cleanup != NULL) {
|
|
7027
|
+
block_alloc->cleanup(block_alloc);
|
|
6647
7028
|
}
|
|
6648
7029
|
ai = next_arena;
|
|
6649
7030
|
}
|
|
@@ -6795,13 +7176,6 @@ static void _upb_Arena_DoFuseArenaLists(upb_ArenaInternal* const parent,
|
|
|
6795
7176
|
_upb_Arena_LinkBackward(child, old_parent_tail);
|
|
6796
7177
|
}
|
|
6797
7178
|
|
|
6798
|
-
void upb_Arena_SetAllocCleanup(upb_Arena* a, upb_AllocCleanupFunc* func) {
|
|
6799
|
-
UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a));
|
|
6800
|
-
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6801
|
-
UPB_ASSERT(ai->upb_alloc_cleanup == NULL);
|
|
6802
|
-
ai->upb_alloc_cleanup = func;
|
|
6803
|
-
}
|
|
6804
|
-
|
|
6805
7179
|
// Thread safe.
|
|
6806
7180
|
static upb_ArenaInternal* _upb_Arena_DoFuse(upb_ArenaInternal** ai1,
|
|
6807
7181
|
upb_ArenaInternal** ai2,
|
|
@@ -7124,7 +7498,7 @@ upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i) {
|
|
|
7124
7498
|
upb_MessageValue ret;
|
|
7125
7499
|
const char* data = upb_Array_DataPtr(arr);
|
|
7126
7500
|
const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr);
|
|
7127
|
-
|
|
7501
|
+
UPB_PRIVATE(_upb_Array_CopyElem)(&ret, data + (i << lg2), lg2);
|
|
7128
7502
|
return ret;
|
|
7129
7503
|
}
|
|
7130
7504
|
|
|
@@ -7144,7 +7518,7 @@ void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue val) {
|
|
|
7144
7518
|
UPB_ASSERT(i < upb_Array_Size(arr));
|
|
7145
7519
|
char* data = upb_Array_MutableDataPtr(arr);
|
|
7146
7520
|
const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr);
|
|
7147
|
-
|
|
7521
|
+
UPB_PRIVATE(_upb_Array_CopyElem)(data + (i << lg2), &val, lg2);
|
|
7148
7522
|
}
|
|
7149
7523
|
|
|
7150
7524
|
bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) {
|
|
@@ -7184,8 +7558,8 @@ bool upb_Array_AppendAll(upb_Array* dst, const upb_Array* src,
|
|
|
7184
7558
|
size_t src_len = upb_Array_Size(src);
|
|
7185
7559
|
if (src_len == 0) return true;
|
|
7186
7560
|
size_t dst_len = upb_Array_Size(dst);
|
|
7187
|
-
size_t len
|
|
7188
|
-
if (UPB_UNLIKELY(
|
|
7561
|
+
size_t len;
|
|
7562
|
+
if (UPB_UNLIKELY(upb_AddOverflow(dst_len, src_len, &len))) return false;
|
|
7189
7563
|
if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(dst, len, arena)) {
|
|
7190
7564
|
return false;
|
|
7191
7565
|
}
|
|
@@ -7211,10 +7585,11 @@ bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count,
|
|
|
7211
7585
|
UPB_ASSERT(!upb_Array_IsFrozen(arr));
|
|
7212
7586
|
UPB_ASSERT(arena);
|
|
7213
7587
|
UPB_ASSERT(i <= arr->UPB_PRIVATE(size));
|
|
7214
|
-
|
|
7588
|
+
size_t new_size;
|
|
7589
|
+
const bool ok = !upb_AddOverflow(arr->UPB_PRIVATE(size), count, &new_size);
|
|
7590
|
+
UPB_ASSERT(ok);
|
|
7215
7591
|
const size_t oldsize = arr->UPB_PRIVATE(size);
|
|
7216
|
-
if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(
|
|
7217
|
-
arr, arr->UPB_PRIVATE(size) + count, arena)) {
|
|
7592
|
+
if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(arr, new_size, arena)) {
|
|
7218
7593
|
return false;
|
|
7219
7594
|
}
|
|
7220
7595
|
upb_Array_Move(arr, i + count, i, oldsize - i);
|
|
@@ -7227,8 +7602,9 @@ bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count,
|
|
|
7227
7602
|
*/
|
|
7228
7603
|
void upb_Array_Delete(upb_Array* arr, size_t i, size_t count) {
|
|
7229
7604
|
UPB_ASSERT(!upb_Array_IsFrozen(arr));
|
|
7230
|
-
|
|
7231
|
-
|
|
7605
|
+
size_t end;
|
|
7606
|
+
const bool ok = !upb_AddOverflow(i, count, &end);
|
|
7607
|
+
UPB_ASSERT(ok);
|
|
7232
7608
|
UPB_ASSERT(end <= arr->UPB_PRIVATE(size));
|
|
7233
7609
|
upb_Array_Move(arr, i, end, arr->UPB_PRIVATE(size) - end);
|
|
7234
7610
|
arr->UPB_PRIVATE(size) -= count;
|
|
@@ -7252,32 +7628,43 @@ bool upb_Array_Resize(upb_Array* arr, size_t size, upb_Arena* arena) {
|
|
|
7252
7628
|
|
|
7253
7629
|
bool UPB_PRIVATE(_upb_Array_Realloc)(upb_Array* array, size_t min_capacity,
|
|
7254
7630
|
upb_Arena* arena) {
|
|
7255
|
-
size_t
|
|
7631
|
+
size_t target_capacity = UPB_MAX(min_capacity, 4);
|
|
7632
|
+
size_t new_capacity = upb_RoundUpToPowerOfTwo(target_capacity);
|
|
7633
|
+
if (new_capacity == SIZE_MAX) return false;
|
|
7634
|
+
|
|
7256
7635
|
const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array);
|
|
7257
7636
|
size_t old_bytes = array->UPB_PRIVATE(capacity) << lg2;
|
|
7258
7637
|
void* ptr = upb_Array_MutableDataPtr(array);
|
|
7259
|
-
|
|
7260
|
-
// Log2 ceiling of size.
|
|
7261
|
-
while (new_capacity < min_capacity) {
|
|
7262
|
-
if (upb_ShlOverflow(&new_capacity, 1)) {
|
|
7263
|
-
new_capacity = SIZE_MAX;
|
|
7264
|
-
break;
|
|
7265
|
-
}
|
|
7266
|
-
}
|
|
7267
|
-
|
|
7268
|
-
// If capacity doubling overflowed to SIZE_MAX, fail. No valid array can hold
|
|
7269
|
-
// SIZE_MAX elements, and downstream size calculations would overflow.
|
|
7270
|
-
if (new_capacity == SIZE_MAX) return false;
|
|
7638
|
+
UPB_ASSERT(ptr);
|
|
7271
7639
|
|
|
7272
7640
|
size_t new_bytes = new_capacity;
|
|
7273
7641
|
if (upb_ShlOverflow(&new_bytes, lg2)) {
|
|
7274
7642
|
return false;
|
|
7275
7643
|
}
|
|
7276
|
-
|
|
7277
|
-
|
|
7644
|
+
if (upb_Arena_TryExtend(arena, ptr, old_bytes, new_bytes)) {
|
|
7645
|
+
array->UPB_PRIVATE(capacity) = new_capacity;
|
|
7646
|
+
} else {
|
|
7647
|
+
size_t pool_bytes =
|
|
7648
|
+
UPB_MAX(new_bytes, UPB_PRIVATE(kUpb_Arena_MinPoolBlockSize));
|
|
7649
|
+
|
|
7650
|
+
void* new_ptr = upb_Arena_AllocPool(arena, pool_bytes);
|
|
7651
|
+
if (!new_ptr) return false;
|
|
7652
|
+
|
|
7653
|
+
if (old_bytes > 0) {
|
|
7654
|
+
memcpy(new_ptr, ptr, old_bytes);
|
|
7655
|
+
}
|
|
7656
|
+
|
|
7657
|
+
const size_t array_size =
|
|
7658
|
+
UPB_ALIGN_UP(sizeof(struct upb_Array), UPB_MALLOC_ALIGN);
|
|
7659
|
+
bool is_contiguous = (ptr == UPB_PTR_AT(array, array_size, void));
|
|
7660
|
+
if (!is_contiguous) {
|
|
7661
|
+
UPB_PRIVATE(_upb_Arena_Harvest)(arena, ptr, old_bytes);
|
|
7662
|
+
}
|
|
7278
7663
|
|
|
7279
|
-
|
|
7280
|
-
|
|
7664
|
+
ptr = new_ptr;
|
|
7665
|
+
UPB_PRIVATE(_upb_Array_SetTaggedPtr)(array, ptr, lg2);
|
|
7666
|
+
array->UPB_PRIVATE(capacity) = pool_bytes >> lg2;
|
|
7667
|
+
}
|
|
7281
7668
|
return true;
|
|
7282
7669
|
}
|
|
7283
7670
|
|
|
@@ -7376,12 +7763,13 @@ upb_MapInsertStatus upb_Map_Insert(upb_Map* map, upb_MessageValue key,
|
|
|
7376
7763
|
bool upb_Map_Delete(upb_Map* map, upb_MessageValue key, upb_MessageValue* val) {
|
|
7377
7764
|
upb_value v;
|
|
7378
7765
|
const bool removed = _upb_Map_Delete(map, &key, map->key_size, &v);
|
|
7379
|
-
if (val) _upb_map_fromvalue(v, val, map->val_size);
|
|
7766
|
+
if (removed && val) _upb_map_fromvalue(v, val, map->val_size);
|
|
7380
7767
|
return removed;
|
|
7381
7768
|
}
|
|
7382
7769
|
|
|
7383
7770
|
bool upb_Map_Next(const upb_Map* map, upb_MessageValue* key,
|
|
7384
7771
|
upb_MessageValue* val, size_t* iter) {
|
|
7772
|
+
if (_upb_Map_Size(map) == 0) return false;
|
|
7385
7773
|
upb_value v;
|
|
7386
7774
|
bool ret;
|
|
7387
7775
|
if (map->UPB_PRIVATE(is_strtable)) {
|
|
@@ -7394,7 +7782,7 @@ bool upb_Map_Next(const upb_Map* map, upb_MessageValue* key,
|
|
|
7394
7782
|
uintptr_t intkey;
|
|
7395
7783
|
ret = upb_inttable_next(&map->t.inttable, &intkey, &v, (intptr_t*)iter);
|
|
7396
7784
|
if (ret) {
|
|
7397
|
-
|
|
7785
|
+
_upb_map_memcpy(key, &intkey, map->key_size);
|
|
7398
7786
|
}
|
|
7399
7787
|
}
|
|
7400
7788
|
if (ret) {
|
|
@@ -7418,18 +7806,6 @@ bool upb_MapIterator_Next(const upb_Map* map, size_t* iter) {
|
|
|
7418
7806
|
return _upb_map_next(map, iter);
|
|
7419
7807
|
}
|
|
7420
7808
|
|
|
7421
|
-
bool upb_MapIterator_Done(const upb_Map* map, size_t iter) {
|
|
7422
|
-
UPB_ASSERT(iter != kUpb_Map_Begin);
|
|
7423
|
-
if (map->UPB_PRIVATE(is_strtable)) {
|
|
7424
|
-
upb_strtable_iter i;
|
|
7425
|
-
i.t = &map->t.strtable;
|
|
7426
|
-
i.index = iter;
|
|
7427
|
-
return upb_strtable_done(&i);
|
|
7428
|
-
} else {
|
|
7429
|
-
return upb_inttable_done(&map->t.inttable, iter);
|
|
7430
|
-
}
|
|
7431
|
-
}
|
|
7432
|
-
|
|
7433
7809
|
// Returns the key and value for this entry of the map.
|
|
7434
7810
|
upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter) {
|
|
7435
7811
|
upb_MessageValue ret;
|
|
@@ -7440,7 +7816,7 @@ upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter) {
|
|
|
7440
7816
|
_upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size);
|
|
7441
7817
|
} else {
|
|
7442
7818
|
uintptr_t intkey = upb_inttable_iter_key(&map->t.inttable, iter);
|
|
7443
|
-
|
|
7819
|
+
_upb_map_memcpy(&ret, &intkey, map->key_size);
|
|
7444
7820
|
}
|
|
7445
7821
|
return ret;
|
|
7446
7822
|
}
|
|
@@ -7465,7 +7841,7 @@ void upb_Map_Freeze(upb_Map* map, const upb_MiniTable* m) {
|
|
|
7465
7841
|
if (upb_Map_IsFrozen(map)) return;
|
|
7466
7842
|
UPB_PRIVATE(_upb_Map_ShallowFreeze)(map);
|
|
7467
7843
|
|
|
7468
|
-
if (m) {
|
|
7844
|
+
if (m && _upb_Map_Size(map) > 0) {
|
|
7469
7845
|
size_t iter = kUpb_Map_Begin;
|
|
7470
7846
|
upb_MessageValue key, val;
|
|
7471
7847
|
|
|
@@ -7481,11 +7857,10 @@ upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) {
|
|
|
7481
7857
|
upb_Map* map = upb_Arena_Malloc(a, sizeof(upb_Map));
|
|
7482
7858
|
if (!map) return NULL;
|
|
7483
7859
|
|
|
7860
|
+
memset(&map->t, 0, sizeof(map->t));
|
|
7484
7861
|
if (key_size <= sizeof(uintptr_t) && key_size != UPB_MAPTYPE_STRING) {
|
|
7485
|
-
if (!upb_inttable_init(&map->t.inttable, a)) return NULL;
|
|
7486
7862
|
map->UPB_PRIVATE(is_strtable) = false;
|
|
7487
7863
|
} else {
|
|
7488
|
-
if (!upb_strtable_init(&map->t.strtable, 4, a)) return NULL;
|
|
7489
7864
|
map->UPB_PRIVATE(is_strtable) = true;
|
|
7490
7865
|
}
|
|
7491
7866
|
map->key_size = key_size;
|
|
@@ -7495,6 +7870,29 @@ upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) {
|
|
|
7495
7870
|
return map;
|
|
7496
7871
|
}
|
|
7497
7872
|
|
|
7873
|
+
bool _upb_Map_Reserve(upb_Map* map, size_t size, upb_Arena* arena) {
|
|
7874
|
+
UPB_ASSERT(!upb_Map_IsFrozen(map));
|
|
7875
|
+
if (size == 0) return true;
|
|
7876
|
+
|
|
7877
|
+
size_t target = _upb_entries_needed_for(size);
|
|
7878
|
+
if (target < 8) target = 8;
|
|
7879
|
+
int size_lg2 = upb_Log2Ceiling(target);
|
|
7880
|
+
|
|
7881
|
+
if (_upb_Map_Capacity(map) >= ((size_t)1 << size_lg2)) {
|
|
7882
|
+
return true;
|
|
7883
|
+
}
|
|
7884
|
+
|
|
7885
|
+
if (map->UPB_PRIVATE(is_strtable)) {
|
|
7886
|
+
return upb_strtable_resize(&map->t.strtable, size_lg2, arena);
|
|
7887
|
+
} else {
|
|
7888
|
+
return upb_inttable_resize(&map->t.inttable, size_lg2, arena);
|
|
7889
|
+
}
|
|
7890
|
+
}
|
|
7891
|
+
|
|
7892
|
+
bool upb_Map_Reserve(upb_Map* map, size_t size, upb_Arena* arena) {
|
|
7893
|
+
return _upb_Map_Reserve(map, size, arena);
|
|
7894
|
+
}
|
|
7895
|
+
|
|
7498
7896
|
|
|
7499
7897
|
#include <stdint.h>
|
|
7500
7898
|
#include <stdlib.h>
|
|
@@ -7635,8 +8033,8 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type,
|
|
|
7635
8033
|
static int _upb_mapsorter_cmpext(const void* _a, const void* _b) {
|
|
7636
8034
|
const upb_Extension* const* a = _a;
|
|
7637
8035
|
const upb_Extension* const* b = _b;
|
|
7638
|
-
uint32_t a_num =
|
|
7639
|
-
uint32_t b_num =
|
|
8036
|
+
uint32_t a_num = upb_MiniTableField_Number(upb_Extension_MiniTableField(*a));
|
|
8037
|
+
uint32_t b_num = upb_MiniTableField_Number(upb_Extension_MiniTableField(*b));
|
|
7640
8038
|
UPB_ASSERT(a_num != b_num);
|
|
7641
8039
|
return a_num < b_num ? -1 : 1;
|
|
7642
8040
|
}
|
|
@@ -7698,8 +8096,8 @@ UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(upb_Message* msg,
|
|
|
7698
8096
|
// represents the end of that allocation.
|
|
7699
8097
|
size_t prev_alloc_size =
|
|
7700
8098
|
(existing->data + existing->size) - (char*)existing;
|
|
7701
|
-
|
|
7702
|
-
|
|
8099
|
+
size_t new_alloc_size;
|
|
8100
|
+
if (!upb_AddOverflow(prev_alloc_size, len, &new_alloc_size)) {
|
|
7703
8101
|
if (upb_Arena_TryExtend(arena, existing, prev_alloc_size,
|
|
7704
8102
|
new_alloc_size)) {
|
|
7705
8103
|
memcpy(UPB_PTR_AT(existing, prev_alloc_size, void), data, len);
|
|
@@ -7722,8 +8120,9 @@ UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(upb_Message* msg,
|
|
|
7722
8120
|
if (!view) return false;
|
|
7723
8121
|
view->data = data;
|
|
7724
8122
|
} else {
|
|
7725
|
-
|
|
7726
|
-
|
|
8123
|
+
size_t total_size;
|
|
8124
|
+
if (upb_AddOverflow(sizeof(upb_StringView), len, &total_size)) return false;
|
|
8125
|
+
view = upb_Arena_Malloc(arena, total_size);
|
|
7727
8126
|
if (!view) return false;
|
|
7728
8127
|
char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char);
|
|
7729
8128
|
memcpy(copy, data, len);
|
|
@@ -7745,10 +8144,9 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg,
|
|
|
7745
8144
|
UPB_ASSERT(count > 0);
|
|
7746
8145
|
size_t total_len = 0;
|
|
7747
8146
|
for (size_t i = 0; i < count; i++) {
|
|
7748
|
-
if (
|
|
8147
|
+
if (upb_AddOverflow(total_len, data[i].size, &total_len)) {
|
|
7749
8148
|
return false;
|
|
7750
8149
|
}
|
|
7751
|
-
total_len += data[i].size;
|
|
7752
8150
|
}
|
|
7753
8151
|
|
|
7754
8152
|
{
|
|
@@ -7760,8 +8158,8 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg,
|
|
|
7760
8158
|
if (!upb_TaggedAuxPtr_IsUnknownAliased(ptr)) {
|
|
7761
8159
|
size_t prev_alloc_size =
|
|
7762
8160
|
(existing->data + existing->size) - (char*)existing;
|
|
7763
|
-
|
|
7764
|
-
|
|
8161
|
+
size_t new_alloc_size;
|
|
8162
|
+
if (!upb_AddOverflow(prev_alloc_size, total_len, &new_alloc_size)) {
|
|
7765
8163
|
if (upb_Arena_TryExtend(arena, existing, prev_alloc_size,
|
|
7766
8164
|
new_alloc_size)) {
|
|
7767
8165
|
char* copy = UPB_PTR_AT(existing, prev_alloc_size, char);
|
|
@@ -7778,11 +8176,13 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg,
|
|
|
7778
8176
|
}
|
|
7779
8177
|
}
|
|
7780
8178
|
|
|
7781
|
-
|
|
8179
|
+
size_t total_size;
|
|
8180
|
+
if (upb_AddOverflow(sizeof(upb_StringView), total_len, &total_size)) {
|
|
8181
|
+
return false;
|
|
8182
|
+
}
|
|
7782
8183
|
if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) return false;
|
|
7783
8184
|
|
|
7784
|
-
upb_StringView* view =
|
|
7785
|
-
upb_Arena_Malloc(arena, sizeof(upb_StringView) + total_len);
|
|
8185
|
+
upb_StringView* view = upb_Arena_Malloc(arena, total_size);
|
|
7786
8186
|
if (!view) return false;
|
|
7787
8187
|
char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char);
|
|
7788
8188
|
view->data = copy;
|
|
@@ -7805,6 +8205,7 @@ void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) {
|
|
|
7805
8205
|
uint32_t size = 0;
|
|
7806
8206
|
for (uint32_t i = 0; i < in->size; i++) {
|
|
7807
8207
|
upb_TaggedAuxPtr tagged_ptr = in->aux_data[i];
|
|
8208
|
+
// Only keep semantically known fields (i.e., canonical extensions).
|
|
7808
8209
|
if (upb_TaggedAuxPtr_IsSemanticallyKnown(tagged_ptr)) {
|
|
7809
8210
|
in->aux_data[size++] = tagged_ptr;
|
|
7810
8211
|
}
|
|
@@ -7812,26 +8213,6 @@ void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) {
|
|
|
7812
8213
|
in->size = size;
|
|
7813
8214
|
}
|
|
7814
8215
|
|
|
7815
|
-
upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(upb_Message* msg,
|
|
7816
|
-
upb_StringView* data,
|
|
7817
|
-
uintptr_t* iter,
|
|
7818
|
-
upb_Arena* arena) {
|
|
7819
|
-
upb_MessageUnknown unknown;
|
|
7820
|
-
unknown.type = kUpb_MessageUnknownType_StringView;
|
|
7821
|
-
unknown.value.bytes = *data;
|
|
7822
|
-
|
|
7823
|
-
upb_Message_DeleteUnknownStatus res =
|
|
7824
|
-
upb_Message_DeleteUnknown2(msg, &unknown, iter, arena);
|
|
7825
|
-
UPB_ASSERT(unknown.type == kUpb_MessageUnknownType_StringView);
|
|
7826
|
-
if (res == kUpb_DeleteUnknown_IterUpdated ||
|
|
7827
|
-
res == kUpb_DeleteUnknown_DeletedLast) {
|
|
7828
|
-
// the unknown data remains the same on the result of
|
|
7829
|
-
// kUpb_DeleteUnknown_AllocFail.
|
|
7830
|
-
*data = unknown.value.bytes;
|
|
7831
|
-
}
|
|
7832
|
-
return res;
|
|
7833
|
-
}
|
|
7834
|
-
|
|
7835
8216
|
size_t upb_Message_ExtensionCount(const upb_Message* msg) {
|
|
7836
8217
|
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
|
|
7837
8218
|
if (!in) return 0;
|
|
@@ -7886,20 +8267,13 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) {
|
|
|
7886
8267
|
// TODO: b/376969853 - use iterator API
|
|
7887
8268
|
uint32_t size = in ? in->size : 0;
|
|
7888
8269
|
for (size_t i = 0; i < size; i++) {
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
continue;
|
|
7895
|
-
}
|
|
7896
|
-
const upb_Extension* ext = aux.extension;
|
|
7897
|
-
const upb_MiniTableExtension* e = ext->ext;
|
|
7898
|
-
const upb_MiniTableField* f = &e->UPB_PRIVATE(field);
|
|
7899
|
-
const upb_MiniTable* m2 = upb_MiniTableExtension_GetSubMessage(e);
|
|
8270
|
+
const upb_Extension* ext =
|
|
8271
|
+
upb_TaggedAuxPtr_TryGetExtension(in->aux_data[i]);
|
|
8272
|
+
if (!ext) continue;
|
|
8273
|
+
const upb_MiniTableField* f = upb_Extension_MiniTableField(ext);
|
|
8274
|
+
const upb_MiniTable* m2 = upb_MiniTable_SubMessage(f);
|
|
7900
8275
|
|
|
7901
|
-
upb_MessageValue val;
|
|
7902
|
-
memcpy(&val, &(ext->data), sizeof(upb_MessageValue));
|
|
8276
|
+
upb_MessageValue val = upb_Extension_GetValue(ext);
|
|
7903
8277
|
|
|
7904
8278
|
switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f)) {
|
|
7905
8279
|
case kUpb_FieldMode_Array: {
|
|
@@ -7920,6 +8294,25 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) {
|
|
|
7920
8294
|
}
|
|
7921
8295
|
}
|
|
7922
8296
|
|
|
8297
|
+
bool upb_Message_NextSerializableField(const upb_Message* msg,
|
|
8298
|
+
const upb_MiniTable* mt,
|
|
8299
|
+
const upb_MiniTableField** f,
|
|
8300
|
+
uintptr_t* iter) {
|
|
8301
|
+
const size_t field_count = upb_MiniTable_FieldCount(mt);
|
|
8302
|
+
uintptr_t i = *iter;
|
|
8303
|
+
while (i < field_count) {
|
|
8304
|
+
const upb_MiniTableField* field = upb_MiniTable_GetFieldByIndex(mt, i);
|
|
8305
|
+
if (UPB_PRIVATE(_upb_Message_FieldIsSet)(msg, field)) {
|
|
8306
|
+
*f = field;
|
|
8307
|
+
*iter = i + 1;
|
|
8308
|
+
return true;
|
|
8309
|
+
}
|
|
8310
|
+
i++;
|
|
8311
|
+
}
|
|
8312
|
+
*iter = i;
|
|
8313
|
+
return false;
|
|
8314
|
+
}
|
|
8315
|
+
|
|
7923
8316
|
|
|
7924
8317
|
#include <stddef.h>
|
|
7925
8318
|
#include <stdint.h>
|
|
@@ -7928,6 +8321,33 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) {
|
|
|
7928
8321
|
|
|
7929
8322
|
// Must be last.
|
|
7930
8323
|
|
|
8324
|
+
bool upb_Message_NextWireFormatUnknown(const struct upb_Message* msg,
|
|
8325
|
+
struct upb_Arena** arena,
|
|
8326
|
+
upb_StringView* data, uintptr_t* iter) {
|
|
8327
|
+
upb_MessageUnknown unknown;
|
|
8328
|
+
if (!upb_Message_NextUnknown2(msg, &unknown, iter)) {
|
|
8329
|
+
return false;
|
|
8330
|
+
}
|
|
8331
|
+
if (unknown.type == kUpb_MessageUnknownType_StringView) {
|
|
8332
|
+
*data = unknown.value.bytes;
|
|
8333
|
+
return true;
|
|
8334
|
+
}
|
|
8335
|
+
UPB_ASSERT(unknown.type == kUpb_MessageUnknownType_NonCanonicalExtension);
|
|
8336
|
+
if (!*arena) {
|
|
8337
|
+
*arena = upb_Arena_New();
|
|
8338
|
+
if (!*arena) {
|
|
8339
|
+
return false;
|
|
8340
|
+
}
|
|
8341
|
+
}
|
|
8342
|
+
upb_EncodeStatus status =
|
|
8343
|
+
upb_EncodeExtension(unknown.value.extension, *arena, data,
|
|
8344
|
+
/*encode_options=*/0);
|
|
8345
|
+
if (status != kUpb_EncodeStatus_Ok) {
|
|
8346
|
+
return false;
|
|
8347
|
+
}
|
|
8348
|
+
return true;
|
|
8349
|
+
}
|
|
8350
|
+
|
|
7931
8351
|
static upb_FindUnknownRet2 upb_FindUnknownRet2_ParseError(void) {
|
|
7932
8352
|
return (upb_FindUnknownRet2){.status = kUpb_FindUnknown_ParseError};
|
|
7933
8353
|
}
|
|
@@ -7967,8 +8387,8 @@ upb_FindUnknownRet2 upb_Message_FindUnknown2(const struct upb_Message* msg,
|
|
|
7967
8387
|
}
|
|
7968
8388
|
} else if (ret.unknown.type ==
|
|
7969
8389
|
kUpb_MessageUnknownType_NonCanonicalExtension) {
|
|
7970
|
-
uint32_t ext_field_number =
|
|
7971
|
-
|
|
8390
|
+
uint32_t ext_field_number = upb_MiniTableField_Number(
|
|
8391
|
+
upb_Extension_MiniTableField(ret.unknown.value.extension));
|
|
7972
8392
|
if (ext_field_number == field_number) {
|
|
7973
8393
|
ret.status = kUpb_FindUnknown_Ok;
|
|
7974
8394
|
return ret;
|
|
@@ -8052,9 +8472,28 @@ upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown2(
|
|
|
8052
8472
|
suffix->size = (prefix->data + prefix->size) - suffix->data;
|
|
8053
8473
|
prefix->size = data_bytes->data - prefix->data;
|
|
8054
8474
|
}
|
|
8055
|
-
return upb_Message_NextUnknown2(msg, data, iter)
|
|
8056
|
-
? kUpb_DeleteUnknown_IterUpdated
|
|
8057
|
-
: kUpb_DeleteUnknown_DeletedLast;
|
|
8475
|
+
return upb_Message_NextUnknown2(msg, data, iter)
|
|
8476
|
+
? kUpb_DeleteUnknown_IterUpdated
|
|
8477
|
+
: kUpb_DeleteUnknown_DeletedLast;
|
|
8478
|
+
}
|
|
8479
|
+
|
|
8480
|
+
upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(
|
|
8481
|
+
struct upb_Message* msg, upb_StringView* data, uintptr_t* iter,
|
|
8482
|
+
struct upb_Arena* arena) {
|
|
8483
|
+
upb_MessageUnknown unknown;
|
|
8484
|
+
unknown.type = kUpb_MessageUnknownType_StringView;
|
|
8485
|
+
unknown.value.bytes = *data;
|
|
8486
|
+
|
|
8487
|
+
upb_Message_DeleteUnknownStatus res =
|
|
8488
|
+
upb_Message_DeleteUnknown2(msg, &unknown, iter, arena);
|
|
8489
|
+
UPB_ASSERT(unknown.type == kUpb_MessageUnknownType_StringView);
|
|
8490
|
+
if (res == kUpb_DeleteUnknown_IterUpdated ||
|
|
8491
|
+
res == kUpb_DeleteUnknown_DeletedLast) {
|
|
8492
|
+
// the unknown data remains the same on the result of
|
|
8493
|
+
// kUpb_DeleteUnknown_AllocFail.
|
|
8494
|
+
*data = unknown.value.bytes;
|
|
8495
|
+
}
|
|
8496
|
+
return res;
|
|
8058
8497
|
}
|
|
8059
8498
|
|
|
8060
8499
|
|
|
@@ -8104,10 +8543,15 @@ static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2,
|
|
|
8104
8543
|
// Check for trivial equality.
|
|
8105
8544
|
if (map1 == map2) return true;
|
|
8106
8545
|
|
|
8107
|
-
// Must have identical element counts
|
|
8546
|
+
// Must have identical element counts, unless we are doing a partial
|
|
8547
|
+
// comparison.
|
|
8108
8548
|
size_t size1 = map1 ? upb_Map_Size(map1) : 0;
|
|
8109
8549
|
size_t size2 = map2 ? upb_Map_Size(map2) : 0;
|
|
8110
|
-
if (
|
|
8550
|
+
if (options & kUpb_CompareOption_Partial) {
|
|
8551
|
+
if (size1 < size2) return false;
|
|
8552
|
+
} else {
|
|
8553
|
+
if (size1 != size2) return false;
|
|
8554
|
+
}
|
|
8111
8555
|
|
|
8112
8556
|
const upb_MiniTableField* f = upb_MiniTable_MapValue(m);
|
|
8113
8557
|
const upb_MiniTable* m2_value = upb_MiniTable_SubMessage(f);
|
|
@@ -8115,8 +8559,8 @@ static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2,
|
|
|
8115
8559
|
|
|
8116
8560
|
upb_MessageValue key, val1, val2;
|
|
8117
8561
|
size_t iter = kUpb_Map_Begin;
|
|
8118
|
-
while (upb_Map_Next(
|
|
8119
|
-
if (!upb_Map_Get(
|
|
8562
|
+
while (upb_Map_Next(map2, &key, &val2, &iter)) {
|
|
8563
|
+
if (!upb_Map_Get(map1, key, &val1)) return false;
|
|
8120
8564
|
if (!upb_MessageValue_IsEqual(val1, val2, ctype, m2_value, options))
|
|
8121
8565
|
return false;
|
|
8122
8566
|
}
|
|
@@ -8124,10 +8568,65 @@ static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2,
|
|
|
8124
8568
|
return true;
|
|
8125
8569
|
}
|
|
8126
8570
|
|
|
8571
|
+
static bool _upb_Message_BaseFieldsArePartiallyEqual(const upb_Message* msg1,
|
|
8572
|
+
const upb_Message* msg2,
|
|
8573
|
+
const upb_MiniTable* m,
|
|
8574
|
+
int options) {
|
|
8575
|
+
size_t iter2 = kUpb_BaseField_Begin;
|
|
8576
|
+
const upb_MiniTableField* f2;
|
|
8577
|
+
upb_MessageValue val2;
|
|
8578
|
+
|
|
8579
|
+
// Iterate through all base fields present/set in msg2 (expected).
|
|
8580
|
+
while (UPB_PRIVATE(_upb_Message_NextBaseField)(msg2, m, &f2, &val2, &iter2)) {
|
|
8581
|
+
// Get the corresponding field data from msg1 (actual).
|
|
8582
|
+
const void* src1 = UPB_PRIVATE(_upb_Message_DataPtr)(msg1, f2);
|
|
8583
|
+
upb_MessageValue val1;
|
|
8584
|
+
UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f2, &val1, src1);
|
|
8585
|
+
|
|
8586
|
+
// Verify presence in msg1 (actual):
|
|
8587
|
+
// - For fields with explicit presence, msg1 must also have the field set.
|
|
8588
|
+
// - For non-presence fields (proto3 scalars), msg1's field must not be
|
|
8589
|
+
// zero/default.
|
|
8590
|
+
if (upb_MiniTableField_HasPresence(f2)) {
|
|
8591
|
+
if (!upb_Message_HasBaseField(msg1, f2)) return false;
|
|
8592
|
+
} else {
|
|
8593
|
+
if (UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(f2, src1)) return false;
|
|
8594
|
+
}
|
|
8595
|
+
|
|
8596
|
+
const upb_MiniTable* subm = upb_MiniTable_SubMessage(f2);
|
|
8597
|
+
const upb_CType ctype = upb_MiniTableField_CType(f2);
|
|
8598
|
+
|
|
8599
|
+
// Compare field values according to the field mode (array, map, or
|
|
8600
|
+
// scalar), passing comparison options recursively for submessages.
|
|
8601
|
+
bool eq;
|
|
8602
|
+
switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f2)) {
|
|
8603
|
+
case kUpb_FieldMode_Array:
|
|
8604
|
+
eq = _upb_Array_IsEqual(val1.array_val, val2.array_val, ctype, subm,
|
|
8605
|
+
options);
|
|
8606
|
+
break;
|
|
8607
|
+
case kUpb_FieldMode_Map:
|
|
8608
|
+
eq = _upb_Map_IsEqual(val1.map_val, val2.map_val, subm, options);
|
|
8609
|
+
break;
|
|
8610
|
+
case kUpb_FieldMode_Scalar:
|
|
8611
|
+
eq = upb_MessageValue_IsEqual(val1, val2, ctype, subm, options);
|
|
8612
|
+
break;
|
|
8613
|
+
}
|
|
8614
|
+
if (!eq) return false;
|
|
8615
|
+
}
|
|
8616
|
+
return true;
|
|
8617
|
+
}
|
|
8618
|
+
|
|
8127
8619
|
static bool _upb_Message_BaseFieldsAreEqual(const upb_Message* msg1,
|
|
8128
8620
|
const upb_Message* msg2,
|
|
8129
8621
|
const upb_MiniTable* m,
|
|
8130
8622
|
int options) {
|
|
8623
|
+
// In partial comparison mode, we only check fields that are present in msg2
|
|
8624
|
+
// (the expected message). Any extra fields present in msg1 (the actual
|
|
8625
|
+
// message) are ignored.
|
|
8626
|
+
if (options & kUpb_CompareOption_Partial) {
|
|
8627
|
+
return _upb_Message_BaseFieldsArePartiallyEqual(msg1, msg2, m, options);
|
|
8628
|
+
}
|
|
8629
|
+
|
|
8131
8630
|
// Iterate over all base fields for each message.
|
|
8132
8631
|
// The order will always match if the messages are equal.
|
|
8133
8632
|
size_t iter1 = kUpb_BaseField_Begin;
|
|
@@ -8171,18 +8670,18 @@ static bool _upb_Message_ExtensionsAreEqual(const upb_Message* msg1,
|
|
|
8171
8670
|
const upb_MiniTable* m,
|
|
8172
8671
|
int options) {
|
|
8173
8672
|
const upb_MiniTableExtension* e;
|
|
8174
|
-
upb_MessageValue
|
|
8673
|
+
upb_MessageValue val2;
|
|
8175
8674
|
|
|
8176
|
-
// Iterate over all extensions for
|
|
8675
|
+
// Iterate over all extensions for msg2, and search msg1 for each extension.
|
|
8177
8676
|
size_t count1 = 0;
|
|
8178
|
-
size_t
|
|
8179
|
-
while (upb_Message_NextExtension(
|
|
8180
|
-
const upb_Extension*
|
|
8181
|
-
if (!
|
|
8677
|
+
size_t iter2 = kUpb_Message_ExtensionBegin;
|
|
8678
|
+
while (upb_Message_NextExtension(msg2, &e, &val2, &iter2)) {
|
|
8679
|
+
const upb_Extension* ext1 = UPB_PRIVATE(_upb_Message_Getext)(msg1, e);
|
|
8680
|
+
if (!ext1) return false;
|
|
8182
8681
|
|
|
8183
8682
|
count1++;
|
|
8184
8683
|
|
|
8185
|
-
const upb_MessageValue
|
|
8684
|
+
const upb_MessageValue val1 = upb_Extension_GetValue(ext1);
|
|
8186
8685
|
const upb_MiniTableField* f = &e->UPB_PRIVATE(field);
|
|
8187
8686
|
const upb_MiniTable* subm = upb_MiniTableField_IsSubMessage(f)
|
|
8188
8687
|
? upb_MiniTableExtension_GetSubMessage(e)
|
|
@@ -8206,9 +8705,11 @@ static bool _upb_Message_ExtensionsAreEqual(const upb_Message* msg1,
|
|
|
8206
8705
|
if (!eq) return false;
|
|
8207
8706
|
}
|
|
8208
8707
|
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8708
|
+
if (!(options & kUpb_CompareOption_Partial)) {
|
|
8709
|
+
// Must have identical extension counts (this catches the case where msg1
|
|
8710
|
+
// has extensions that msg2 doesn't).
|
|
8711
|
+
if (count1 != upb_Message_ExtensionCount(msg1)) return false;
|
|
8712
|
+
}
|
|
8212
8713
|
|
|
8213
8714
|
return true;
|
|
8214
8715
|
}
|
|
@@ -8223,13 +8724,16 @@ bool upb_Message_IsEqual(const upb_Message* msg1, const upb_Message* msg2,
|
|
|
8223
8724
|
if (!(options & kUpb_CompareOption_IncludeUnknownFields)) return true;
|
|
8224
8725
|
|
|
8225
8726
|
// The wire encoder enforces a maximum depth of 100 so we match that here.
|
|
8226
|
-
return
|
|
8727
|
+
return _upb_Message_UnknownFieldsAreEqual(msg1, msg2, 100) ==
|
|
8227
8728
|
kUpb_UnknownCompareResult_Equal;
|
|
8228
8729
|
}
|
|
8229
8730
|
|
|
8230
8731
|
|
|
8732
|
+
#include <setjmp.h>
|
|
8231
8733
|
#include <stdint.h>
|
|
8734
|
+
#include <stdio.h>
|
|
8232
8735
|
#include <stdlib.h>
|
|
8736
|
+
#include <string.h>
|
|
8233
8737
|
|
|
8234
8738
|
|
|
8235
8739
|
// Must be last.
|
|
@@ -8255,6 +8759,7 @@ struct upb_UnknownFields {
|
|
|
8255
8759
|
|
|
8256
8760
|
typedef struct {
|
|
8257
8761
|
upb_EpsCopyInputStream stream;
|
|
8762
|
+
upb_encstate encoder; // For encoding non-canonical extensions.
|
|
8258
8763
|
upb_Arena* arena;
|
|
8259
8764
|
upb_UnknownField* tmp;
|
|
8260
8765
|
size_t tmp_size;
|
|
@@ -8282,10 +8787,17 @@ static void upb_UnknownFields_Grow(upb_UnknownField_Context* ctx,
|
|
|
8282
8787
|
upb_UnknownField** ptr,
|
|
8283
8788
|
upb_UnknownField** end) {
|
|
8284
8789
|
size_t old = (*ptr - *base);
|
|
8285
|
-
size_t new
|
|
8790
|
+
size_t new;
|
|
8791
|
+
if (upb_MulOverflow((uint32_t)2, old, &new)) {
|
|
8792
|
+
upb_UnknownFields_OutOfMemory(ctx);
|
|
8793
|
+
}
|
|
8794
|
+
new = UPB_MAX(4, new);
|
|
8795
|
+
size_t new_bytes;
|
|
8796
|
+
if (upb_MulOverflow(new, sizeof(**base), &new_bytes)) {
|
|
8797
|
+
upb_UnknownFields_OutOfMemory(ctx);
|
|
8798
|
+
}
|
|
8286
8799
|
|
|
8287
|
-
*base = upb_Arena_Realloc(ctx->arena, *base, old * sizeof(**base),
|
|
8288
|
-
new * sizeof(**base));
|
|
8800
|
+
*base = upb_Arena_Realloc(ctx->arena, *base, old * sizeof(**base), new_bytes);
|
|
8289
8801
|
if (!*base) upb_UnknownFields_OutOfMemory(ctx);
|
|
8290
8802
|
|
|
8291
8803
|
*ptr = *base + old;
|
|
@@ -8333,11 +8845,25 @@ static void upb_UnknownFields_SortRecursive(upb_UnknownField* arr, size_t start,
|
|
|
8333
8845
|
static void upb_UnknownFields_Sort(upb_UnknownField_Context* ctx,
|
|
8334
8846
|
upb_UnknownFields* fields) {
|
|
8335
8847
|
if (ctx->tmp_size < fields->size) {
|
|
8336
|
-
|
|
8848
|
+
size_t oldsize;
|
|
8849
|
+
if (upb_MulOverflow(sizeof(*ctx->tmp), ctx->tmp_size, &oldsize)) {
|
|
8850
|
+
upb_UnknownFields_OutOfMemory(ctx);
|
|
8851
|
+
}
|
|
8337
8852
|
ctx->tmp_size = UPB_MAX(8, ctx->tmp_size);
|
|
8338
|
-
while (ctx->tmp_size < fields->size)
|
|
8339
|
-
|
|
8340
|
-
|
|
8853
|
+
while (ctx->tmp_size < fields->size) {
|
|
8854
|
+
if (upb_MulOverflow((uint32_t)2, ctx->tmp_size, &ctx->tmp_size)) {
|
|
8855
|
+
upb_UnknownFields_OutOfMemory(ctx);
|
|
8856
|
+
}
|
|
8857
|
+
}
|
|
8858
|
+
size_t newsize;
|
|
8859
|
+
if (upb_MulOverflow(ctx->tmp_size, sizeof(*ctx->tmp), &newsize)) {
|
|
8860
|
+
upb_UnknownFields_OutOfMemory(ctx);
|
|
8861
|
+
}
|
|
8862
|
+
upb_UnknownField* tmp = upb_grealloc(ctx->tmp, oldsize, newsize);
|
|
8863
|
+
if (!tmp) {
|
|
8864
|
+
upb_UnknownFields_OutOfMemory(ctx);
|
|
8865
|
+
}
|
|
8866
|
+
ctx->tmp = tmp;
|
|
8341
8867
|
}
|
|
8342
8868
|
upb_UnknownFields_SortRecursive(fields->fields, 0, fields->size, ctx->tmp);
|
|
8343
8869
|
}
|
|
@@ -8463,11 +8989,37 @@ static upb_UnknownFields* upb_UnknownFields_Build(upb_UnknownField_Context* ctx,
|
|
|
8463
8989
|
.last_tag = 0,
|
|
8464
8990
|
};
|
|
8465
8991
|
uintptr_t iter = kUpb_Message_UnknownBegin;
|
|
8466
|
-
|
|
8467
|
-
while (
|
|
8468
|
-
|
|
8469
|
-
|
|
8470
|
-
|
|
8992
|
+
upb_MessageUnknown data;
|
|
8993
|
+
while (upb_Message_NextUnknown2(msg, &data, &iter)) {
|
|
8994
|
+
const char* ptr;
|
|
8995
|
+
size_t size;
|
|
8996
|
+
if (data.type == kUpb_MessageUnknownType_StringView) {
|
|
8997
|
+
upb_StringView view = data.value.bytes;
|
|
8998
|
+
ptr = view.data;
|
|
8999
|
+
size = view.size;
|
|
9000
|
+
} else {
|
|
9001
|
+
UPB_ASSERT(data.type == kUpb_MessageUnknownType_NonCanonicalExtension);
|
|
9002
|
+
char* enc_buf = upb_BackAlloc_Init(&ctx->encoder.alloc, ctx->arena);
|
|
9003
|
+
ctx->encoder.status = kUpb_EncodeStatus_Ok;
|
|
9004
|
+
// Encode non-canonical extension to buffer.
|
|
9005
|
+
const upb_Extension* ext = (const upb_Extension*)data.value.extension;
|
|
9006
|
+
bool is_message_set = false;
|
|
9007
|
+
const upb_MiniTableExtension* ext_mt =
|
|
9008
|
+
upb_Extension_MiniTableExtension(ext);
|
|
9009
|
+
const upb_MiniTable* extendee = upb_MiniTableExtension_Extendee(ext_mt);
|
|
9010
|
+
if (extendee) {
|
|
9011
|
+
is_message_set = upb_MiniTable_IsMessageSet(extendee);
|
|
9012
|
+
}
|
|
9013
|
+
UPB_PRIVATE(_upb_Encode_Extension)(&ctx->encoder, ext_mt,
|
|
9014
|
+
upb_Extension_GetValue(ext),
|
|
9015
|
+
is_message_set, &enc_buf, &size,
|
|
9016
|
+
/*options=*/0);
|
|
9017
|
+
ptr = enc_buf;
|
|
9018
|
+
}
|
|
9019
|
+
|
|
9020
|
+
upb_EpsCopyInputStream_Init(&ctx->stream, &ptr, size);
|
|
9021
|
+
upb_CombineUnknownFields(ctx, &builder, &ptr);
|
|
9022
|
+
UPB_ASSERT(upb_EpsCopyInputStream_IsDone(&ctx->stream, &ptr) &&
|
|
8471
9023
|
!upb_EpsCopyInputStream_IsError(&ctx->stream));
|
|
8472
9024
|
}
|
|
8473
9025
|
upb_UnknownFields* fields = upb_UnknownFields_DoBuild(ctx, &builder);
|
|
@@ -8535,16 +9087,30 @@ static upb_UnknownCompareResult upb_UnknownField_Compare(
|
|
|
8535
9087
|
if (UPB_SETJMP(ctx->err) == 0) {
|
|
8536
9088
|
ret = upb_UnknownField_DoCompare(ctx, msg1, msg2);
|
|
8537
9089
|
} else {
|
|
9090
|
+
// If status is still Equal, the jump must have originated from the Encoder
|
|
9091
|
+
// (which only updates ctx->encoder.status). We must map it to a context
|
|
9092
|
+
// error.
|
|
9093
|
+
if (ctx->status == kUpb_UnknownCompareResult_Equal) {
|
|
9094
|
+
if (ctx->encoder.status == kUpb_EncodeStatus_OutOfMemory) {
|
|
9095
|
+
ctx->status = kUpb_UnknownCompareResult_OutOfMemory;
|
|
9096
|
+
} else if (ctx->encoder.status == kUpb_EncodeStatus_MaxDepthExceeded) {
|
|
9097
|
+
ctx->status = kUpb_UnknownCompareResult_MaxDepthExceeded;
|
|
9098
|
+
} else {
|
|
9099
|
+
ctx->status = kUpb_UnknownCompareResult_OutOfMemory;
|
|
9100
|
+
}
|
|
9101
|
+
upb_BackAlloc_Abort(&ctx->encoder.alloc);
|
|
9102
|
+
}
|
|
8538
9103
|
ret = ctx->status;
|
|
8539
9104
|
UPB_ASSERT(ret != kUpb_UnknownCompareResult_Equal);
|
|
8540
9105
|
}
|
|
8541
9106
|
|
|
9107
|
+
UPB_PRIVATE(_upb_encstate_destroy)(&ctx->encoder);
|
|
8542
9108
|
upb_Arena_Free(ctx->arena);
|
|
8543
9109
|
upb_gfree(ctx->tmp);
|
|
8544
9110
|
return ret;
|
|
8545
9111
|
}
|
|
8546
9112
|
|
|
8547
|
-
upb_UnknownCompareResult
|
|
9113
|
+
upb_UnknownCompareResult _upb_Message_UnknownFieldsAreEqual(
|
|
8548
9114
|
const upb_Message* msg1, const upb_Message* msg2, int max_depth) {
|
|
8549
9115
|
bool msg1_empty = !upb_Message_HasUnknown(msg1);
|
|
8550
9116
|
bool msg2_empty = !upb_Message_HasUnknown(msg2);
|
|
@@ -8560,6 +9126,7 @@ upb_UnknownCompareResult UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)(
|
|
|
8560
9126
|
};
|
|
8561
9127
|
|
|
8562
9128
|
if (!ctx.arena) return kUpb_UnknownCompareResult_OutOfMemory;
|
|
9129
|
+
UPB_PRIVATE(_upb_encstate_init)(&ctx.encoder, &ctx.err, ctx.arena);
|
|
8563
9130
|
|
|
8564
9131
|
return upb_UnknownField_Compare(&ctx, msg1, msg2);
|
|
8565
9132
|
}
|
|
@@ -8578,10 +9145,11 @@ static upb_StringView upb_Clone_StringView(upb_StringView str,
|
|
|
8578
9145
|
return upb_StringView_FromDataAndSize(NULL, 0);
|
|
8579
9146
|
}
|
|
8580
9147
|
void* cloned_data = upb_Arena_Malloc(arena, str.size);
|
|
8581
|
-
|
|
8582
|
-
|
|
9148
|
+
if (cloned_data == NULL) {
|
|
9149
|
+
return upb_StringView_FromDataAndSize(NULL, 0);
|
|
9150
|
+
}
|
|
8583
9151
|
memcpy(cloned_data, str.data, str.size);
|
|
8584
|
-
return
|
|
9152
|
+
return upb_StringView_FromDataAndSize(cloned_data, str.size);
|
|
8585
9153
|
}
|
|
8586
9154
|
|
|
8587
9155
|
static bool upb_Clone_MessageValue(void* value, upb_CType value_type,
|
|
@@ -8621,30 +9189,81 @@ static bool upb_Clone_MessageValue(void* value, upb_CType value_type,
|
|
|
8621
9189
|
UPB_UNREACHABLE();
|
|
8622
9190
|
}
|
|
8623
9191
|
|
|
9192
|
+
static bool upb_Clone_MapValue(upb_value* tabval, size_t map_val_size,
|
|
9193
|
+
upb_CType value_field_type,
|
|
9194
|
+
const upb_MiniTable* value_sub, upb_Arena* arena,
|
|
9195
|
+
upb_value* cloned_tabval) {
|
|
9196
|
+
upb_MessageValue val;
|
|
9197
|
+
_upb_map_fromvalue(*tabval, &val, map_val_size);
|
|
9198
|
+
if (!upb_Clone_MessageValue(&val, value_field_type, value_sub, arena)) {
|
|
9199
|
+
return false;
|
|
9200
|
+
}
|
|
9201
|
+
*cloned_tabval = (upb_value){0}; // Initialize
|
|
9202
|
+
if (!_upb_map_tovalue(&val, map_val_size, cloned_tabval, arena)) {
|
|
9203
|
+
return false;
|
|
9204
|
+
}
|
|
9205
|
+
return true;
|
|
9206
|
+
}
|
|
9207
|
+
|
|
8624
9208
|
upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type,
|
|
8625
9209
|
upb_CType value_type,
|
|
8626
9210
|
const upb_MiniTable* map_entry_table,
|
|
8627
9211
|
upb_Arena* arena) {
|
|
8628
|
-
upb_Map* cloned_map =
|
|
9212
|
+
upb_Map* cloned_map = upb_Arena_Malloc(arena, sizeof(upb_Map));
|
|
8629
9213
|
if (cloned_map == NULL) {
|
|
8630
9214
|
return NULL;
|
|
8631
9215
|
}
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
9216
|
+
cloned_map->key_size = map->key_size;
|
|
9217
|
+
cloned_map->val_size = map->val_size;
|
|
9218
|
+
cloned_map->UPB_PRIVATE(is_frozen) = false;
|
|
9219
|
+
cloned_map->UPB_PRIVATE(is_strtable) = map->UPB_PRIVATE(is_strtable);
|
|
9220
|
+
|
|
9221
|
+
const upb_MiniTableField* value_field =
|
|
9222
|
+
upb_MiniTable_MapValue(map_entry_table);
|
|
9223
|
+
const upb_MiniTable* value_sub = upb_MiniTable_SubMessage(value_field);
|
|
9224
|
+
upb_CType value_field_type = upb_MiniTableField_CType(value_field);
|
|
9225
|
+
|
|
9226
|
+
bool is_primitive = value_field_type != kUpb_CType_Message &&
|
|
9227
|
+
value_field_type != kUpb_CType_String &&
|
|
9228
|
+
value_field_type != kUpb_CType_Bytes;
|
|
9229
|
+
|
|
9230
|
+
if (map->UPB_PRIVATE(is_strtable)) {
|
|
9231
|
+
if (!upb_strtable_copy(&cloned_map->t.strtable, &map->t.strtable, arena)) {
|
|
8643
9232
|
return NULL;
|
|
8644
9233
|
}
|
|
8645
|
-
if (!
|
|
9234
|
+
if (!is_primitive) {
|
|
9235
|
+
intptr_t iter = UPB_STRTABLE_BEGIN;
|
|
9236
|
+
upb_StringView key;
|
|
9237
|
+
upb_value tabval;
|
|
9238
|
+
while (
|
|
9239
|
+
upb_strtable_next2(&cloned_map->t.strtable, &key, &tabval, &iter)) {
|
|
9240
|
+
upb_value cloned_tabval;
|
|
9241
|
+
if (!upb_Clone_MapValue(&tabval, map->val_size, value_field_type,
|
|
9242
|
+
value_sub, arena, &cloned_tabval)) {
|
|
9243
|
+
return NULL;
|
|
9244
|
+
}
|
|
9245
|
+
upb_strtable_setentryvalue(&cloned_map->t.strtable, iter,
|
|
9246
|
+
cloned_tabval);
|
|
9247
|
+
}
|
|
9248
|
+
}
|
|
9249
|
+
} else {
|
|
9250
|
+
if (!upb_inttable_copy(&cloned_map->t.inttable, &map->t.inttable, arena)) {
|
|
8646
9251
|
return NULL;
|
|
8647
9252
|
}
|
|
9253
|
+
if (!is_primitive) {
|
|
9254
|
+
intptr_t iter = UPB_INTTABLE_BEGIN;
|
|
9255
|
+
uintptr_t key;
|
|
9256
|
+
upb_value tabval;
|
|
9257
|
+
while (upb_inttable_next(&cloned_map->t.inttable, &key, &tabval, &iter)) {
|
|
9258
|
+
upb_value cloned_tabval;
|
|
9259
|
+
if (!upb_Clone_MapValue(&tabval, map->val_size, value_field_type,
|
|
9260
|
+
value_sub, arena, &cloned_tabval)) {
|
|
9261
|
+
return NULL;
|
|
9262
|
+
}
|
|
9263
|
+
upb_inttable_setentryvalue(&cloned_map->t.inttable, iter,
|
|
9264
|
+
cloned_tabval);
|
|
9265
|
+
}
|
|
9266
|
+
}
|
|
8648
9267
|
}
|
|
8649
9268
|
return cloned_map;
|
|
8650
9269
|
}
|
|
@@ -8705,19 +9324,23 @@ static bool upb_Message_Array_DeepClone(const upb_Array* array,
|
|
|
8705
9324
|
? upb_MiniTable_GetSubMessageTable(field)
|
|
8706
9325
|
: NULL,
|
|
8707
9326
|
arena);
|
|
9327
|
+
if (!cloned_array) return false;
|
|
8708
9328
|
|
|
8709
9329
|
// Clear out upb_Array* due to parent memcpy.
|
|
8710
9330
|
upb_Message_SetBaseField(clone, field, &cloned_array);
|
|
8711
9331
|
return true;
|
|
8712
9332
|
}
|
|
8713
9333
|
|
|
8714
|
-
static bool upb_Clone_ExtensionValue(
|
|
8715
|
-
|
|
8716
|
-
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
|
|
9334
|
+
static bool upb_Clone_ExtensionValue(const upb_MiniTableField* field,
|
|
9335
|
+
const upb_Extension* source,
|
|
9336
|
+
upb_Extension* dest, upb_Arena* arena) {
|
|
9337
|
+
upb_MessageValue val = upb_Extension_GetValue(source);
|
|
9338
|
+
if (!upb_Clone_MessageValue(&val, upb_MiniTableField_CType(field),
|
|
9339
|
+
upb_MiniTable_SubMessage(field), arena)) {
|
|
9340
|
+
return false;
|
|
9341
|
+
}
|
|
9342
|
+
upb_Extension_SetValue(dest, val);
|
|
9343
|
+
return true;
|
|
8721
9344
|
}
|
|
8722
9345
|
|
|
8723
9346
|
upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
|
|
@@ -8739,9 +9362,8 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
|
|
|
8739
9362
|
upb_MiniTable_GetSubMessageTable(field);
|
|
8740
9363
|
upb_Message* dst_sub_message =
|
|
8741
9364
|
upb_Message_DeepClone(sub_message, sub_message_table, arena);
|
|
8742
|
-
if (dst_sub_message == NULL)
|
|
8743
|
-
|
|
8744
|
-
}
|
|
9365
|
+
if (dst_sub_message == NULL) goto err;
|
|
9366
|
+
|
|
8745
9367
|
upb_Message_SetBaseFieldMessage(dst, field, dst_sub_message);
|
|
8746
9368
|
}
|
|
8747
9369
|
} break;
|
|
@@ -8749,10 +9371,10 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
|
|
|
8749
9371
|
case kUpb_CType_Bytes: {
|
|
8750
9372
|
upb_StringView str = upb_Message_GetString(src, field, empty_string);
|
|
8751
9373
|
if (str.size != 0) {
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
9374
|
+
upb_StringView cloned_str = upb_Clone_StringView(str, arena);
|
|
9375
|
+
if (cloned_str.data == NULL) goto err;
|
|
9376
|
+
|
|
9377
|
+
if (!upb_Message_SetString(dst, field, cloned_str, arena)) goto err;
|
|
8756
9378
|
}
|
|
8757
9379
|
} break;
|
|
8758
9380
|
default:
|
|
@@ -8764,7 +9386,7 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
|
|
|
8764
9386
|
const upb_Map* map = upb_Message_GetMap(src, field);
|
|
8765
9387
|
if (map != NULL) {
|
|
8766
9388
|
if (!upb_Message_Map_DeepClone(map, mini_table, field, dst, arena)) {
|
|
8767
|
-
|
|
9389
|
+
goto err;
|
|
8768
9390
|
}
|
|
8769
9391
|
}
|
|
8770
9392
|
} else {
|
|
@@ -8772,7 +9394,7 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
|
|
|
8772
9394
|
if (array != NULL) {
|
|
8773
9395
|
if (!upb_Message_Array_DeepClone(array, mini_table, field, dst,
|
|
8774
9396
|
arena)) {
|
|
8775
|
-
|
|
9397
|
+
goto err;
|
|
8776
9398
|
}
|
|
8777
9399
|
}
|
|
8778
9400
|
}
|
|
@@ -8784,41 +9406,45 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
|
|
|
8784
9406
|
|
|
8785
9407
|
for (size_t i = 0; i < in->size; i++) {
|
|
8786
9408
|
upb_TaggedAuxPtr tagged_ptr = in->aux_data[i];
|
|
8787
|
-
if (
|
|
8788
|
-
// Clone
|
|
8789
|
-
const upb_Extension* msg_ext =
|
|
8790
|
-
|
|
8791
|
-
|
|
8792
|
-
|
|
8793
|
-
|
|
8794
|
-
|
|
9409
|
+
if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) {
|
|
9410
|
+
// Clone a canonical or non-canonical upb_Extension*.
|
|
9411
|
+
const upb_Extension* msg_ext = upb_TaggedAuxPtr_Extension(tagged_ptr);
|
|
9412
|
+
const upb_MiniTableField* field = upb_Extension_MiniTableField(msg_ext);
|
|
9413
|
+
upb_Extension* dst_ext =
|
|
9414
|
+
UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)(
|
|
9415
|
+
dst, upb_Extension_MiniTableExtension(msg_ext), arena,
|
|
9416
|
+
upb_TaggedAuxPtr_Type(tagged_ptr));
|
|
9417
|
+
if (!dst_ext) goto err;
|
|
9418
|
+
|
|
8795
9419
|
if (upb_MiniTableField_IsScalar(field)) {
|
|
8796
|
-
if (!upb_Clone_ExtensionValue(
|
|
8797
|
-
|
|
9420
|
+
if (!upb_Clone_ExtensionValue(field, msg_ext, dst_ext, arena)) {
|
|
9421
|
+
goto err;
|
|
8798
9422
|
}
|
|
8799
9423
|
} else {
|
|
8800
|
-
upb_Array* msg_array = (
|
|
9424
|
+
const upb_Array* msg_array = upb_Extension_GetArray(msg_ext);
|
|
8801
9425
|
UPB_ASSERT(msg_array);
|
|
8802
|
-
upb_Array* cloned_array =
|
|
8803
|
-
msg_array, upb_MiniTableField_CType(field),
|
|
8804
|
-
|
|
8805
|
-
if (!cloned_array)
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
dst_ext->data.array_val = cloned_array;
|
|
9426
|
+
upb_Array* cloned_array =
|
|
9427
|
+
upb_Array_DeepClone(msg_array, upb_MiniTableField_CType(field),
|
|
9428
|
+
upb_MiniTable_SubMessage(field), arena);
|
|
9429
|
+
if (!cloned_array) goto err;
|
|
9430
|
+
|
|
9431
|
+
upb_Extension_SetArray(dst_ext, cloned_array);
|
|
8809
9432
|
}
|
|
8810
9433
|
} else if (upb_TaggedAuxPtr_IsUnknownStringView(tagged_ptr)) {
|
|
8811
|
-
// Clone unknown
|
|
9434
|
+
// Clone an aliased or non-aliased unknown upb_StringView.
|
|
8812
9435
|
upb_StringView* unknown = upb_TaggedPtrAux_StringViewRepr(tagged_ptr);
|
|
8813
9436
|
// Make a copy into destination arena.
|
|
8814
9437
|
if (!UPB_PRIVATE(_upb_Message_AddUnknown)(
|
|
8815
9438
|
dst, unknown->data, unknown->size, arena, kUpb_AddUnknown_Copy)) {
|
|
8816
|
-
|
|
9439
|
+
goto err;
|
|
8817
9440
|
}
|
|
8818
9441
|
}
|
|
8819
9442
|
}
|
|
8820
|
-
|
|
8821
9443
|
return dst;
|
|
9444
|
+
|
|
9445
|
+
err:
|
|
9446
|
+
upb_Message_Clear(dst, mini_table);
|
|
9447
|
+
return NULL;
|
|
8822
9448
|
}
|
|
8823
9449
|
|
|
8824
9450
|
bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src,
|
|
@@ -8834,6 +9460,7 @@ bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src,
|
|
|
8834
9460
|
upb_Message* upb_Message_DeepClone(const upb_Message* msg,
|
|
8835
9461
|
const upb_MiniTable* m, upb_Arena* arena) {
|
|
8836
9462
|
upb_Message* clone = upb_Message_New(m, arena);
|
|
9463
|
+
if (!clone) return NULL;
|
|
8837
9464
|
return _upb_Message_Copy(clone, msg, m, arena);
|
|
8838
9465
|
}
|
|
8839
9466
|
|
|
@@ -8843,50 +9470,7 @@ bool upb_Message_ShallowCopy(upb_Message* dst, const upb_Message* src,
|
|
|
8843
9470
|
UPB_ASSERT(!upb_Message_IsFrozen(dst));
|
|
8844
9471
|
memcpy(dst, src, m->UPB_PRIVATE(size));
|
|
8845
9472
|
|
|
8846
|
-
|
|
8847
|
-
if (!in) return true;
|
|
8848
|
-
|
|
8849
|
-
size_t size = UPB_SIZEOF_FLEX(upb_Message_Internal, aux_data, in->size);
|
|
8850
|
-
upb_Message_Internal* dst_in = upb_Arena_Malloc(arena, size);
|
|
8851
|
-
if (!dst_in) return false;
|
|
8852
|
-
|
|
8853
|
-
dst_in->size = in->size;
|
|
8854
|
-
dst_in->capacity = in->size;
|
|
8855
|
-
|
|
8856
|
-
for (size_t i = 0; i < in->size; i++) {
|
|
8857
|
-
upb_TaggedAux aux;
|
|
8858
|
-
switch (upb_TaggedAux_Get(in->aux_data[i], &aux)) {
|
|
8859
|
-
case kUpb_TaggedAuxType_CanonicalExtension: {
|
|
8860
|
-
const upb_Extension* msg_ext = aux.extension;
|
|
8861
|
-
upb_Extension* dst_ext = upb_Arena_Malloc(arena, sizeof(upb_Extension));
|
|
8862
|
-
if (!dst_ext) return false;
|
|
8863
|
-
*dst_ext = *msg_ext;
|
|
8864
|
-
dst_in->aux_data[i] = upb_TaggedAuxPtr_MakeCanonicalExtension(dst_ext);
|
|
8865
|
-
break;
|
|
8866
|
-
}
|
|
8867
|
-
case kUpb_TaggedAuxType_Unknown:
|
|
8868
|
-
case kUpb_TaggedAuxType_AliasedUnknown: {
|
|
8869
|
-
upb_StringView* dst_sv =
|
|
8870
|
-
upb_Arena_Malloc(arena, sizeof(upb_StringView));
|
|
8871
|
-
if (!dst_sv) return false;
|
|
8872
|
-
*dst_sv = *aux.unknown_data;
|
|
8873
|
-
dst_in->aux_data[i] = upb_TaggedAuxPtr_MakeUnknownDataAliased(dst_sv);
|
|
8874
|
-
break;
|
|
8875
|
-
}
|
|
8876
|
-
case kUpb_TaggedAuxType_NonCanonicalExtension: {
|
|
8877
|
-
const upb_Extension* msg_ext = aux.extension;
|
|
8878
|
-
upb_Extension* dst_ext = upb_Arena_Malloc(arena, sizeof(upb_Extension));
|
|
8879
|
-
if (!dst_ext) return false;
|
|
8880
|
-
*dst_ext = *msg_ext;
|
|
8881
|
-
dst_in->aux_data[i] =
|
|
8882
|
-
upb_TaggedAuxPtr_MakeNonCanonicalExtension(dst_ext);
|
|
8883
|
-
break;
|
|
8884
|
-
}
|
|
8885
|
-
}
|
|
8886
|
-
}
|
|
8887
|
-
|
|
8888
|
-
UPB_PRIVATE(_upb_Message_SetInternal)(dst, dst_in);
|
|
8889
|
-
return true;
|
|
9473
|
+
return UPB_PRIVATE(_upb_Message_CopyInternal)(dst, src, arena);
|
|
8890
9474
|
}
|
|
8891
9475
|
|
|
8892
9476
|
// Performs a shallow clone.
|
|
@@ -8915,6 +9499,7 @@ bool upb_Message_MergeFrom(upb_Message* dst, const upb_Message* src,
|
|
|
8915
9499
|
// so we don't want to unnecessarily have the bad API or bloat the passed-in
|
|
8916
9500
|
// arena with this very-short-term allocation.
|
|
8917
9501
|
upb_Arena* encode_arena = upb_Arena_New();
|
|
9502
|
+
if (!encode_arena) return false;
|
|
8918
9503
|
upb_EncodeStatus e_status = upb_Encode(src, mt, 0, encode_arena, &buf, &size);
|
|
8919
9504
|
if (e_status != kUpb_EncodeStatus_Ok) {
|
|
8920
9505
|
upb_Arena_Free(encode_arena);
|
|
@@ -8931,7 +9516,6 @@ bool upb_Message_MergeFrom(upb_Message* dst, const upb_Message* src,
|
|
|
8931
9516
|
|
|
8932
9517
|
|
|
8933
9518
|
#include <stdint.h>
|
|
8934
|
-
#include <string.h>
|
|
8935
9519
|
|
|
8936
9520
|
|
|
8937
9521
|
// Must be last.
|
|
@@ -8946,7 +9530,7 @@ const upb_Extension* UPB_PRIVATE(_upb_Message_Getext)(
|
|
|
8946
9530
|
if (upb_TaggedAuxPtr_IsCanonicalExtension(tagged_ptr)) {
|
|
8947
9531
|
const upb_Extension* ext =
|
|
8948
9532
|
upb_TaggedAuxPtr_CanonicalExtension(tagged_ptr);
|
|
8949
|
-
if (ext
|
|
9533
|
+
if (upb_Extension_MiniTableExtension(ext) == e) {
|
|
8950
9534
|
return ext;
|
|
8951
9535
|
}
|
|
8952
9536
|
}
|
|
@@ -8955,35 +9539,40 @@ const upb_Extension* UPB_PRIVATE(_upb_Message_Getext)(
|
|
|
8955
9539
|
return NULL;
|
|
8956
9540
|
}
|
|
8957
9541
|
|
|
8958
|
-
|
|
9542
|
+
upb_Extension* UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)(
|
|
8959
9543
|
struct upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* a,
|
|
8960
|
-
|
|
9544
|
+
upb_TaggedAuxType tag) {
|
|
8961
9545
|
UPB_ASSERT(!upb_Message_IsFrozen(msg));
|
|
8962
|
-
|
|
8963
|
-
|
|
8964
|
-
|
|
9546
|
+
// For Canonical Extensions, we check whether the extension has already been
|
|
9547
|
+
// set. If we find an extension with the same pointer and tag, we reuse it to
|
|
9548
|
+
// prevent duplicate entries for the same extension.
|
|
9549
|
+
//
|
|
9550
|
+
// For Non-Canonical Extensions, we do NOT reuse them, matching the behavior
|
|
9551
|
+
// of adding a unknown StringView (through `_upb_Message_AddUnknown`) which
|
|
9552
|
+
// accumulates.
|
|
9553
|
+
if (tag == kUpb_TaggedAuxType_CanonicalExtension) {
|
|
9554
|
+
upb_Extension* ext =
|
|
9555
|
+
(upb_Extension*)UPB_PRIVATE(_upb_Message_Getext)(msg, e);
|
|
9556
|
+
if (ext) return ext;
|
|
9557
|
+
}
|
|
8965
9558
|
if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, a)) return NULL;
|
|
8966
9559
|
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
|
|
8967
|
-
ext =
|
|
9560
|
+
upb_Extension* ext = UPB_PRIVATE(_upb_Extension_New)(e, a);
|
|
8968
9561
|
if (!ext) return NULL;
|
|
8969
|
-
|
|
8970
|
-
ext->ext = e;
|
|
8971
|
-
in->aux_data[in->size++] =
|
|
8972
|
-
canonical ? upb_TaggedAuxPtr_MakeCanonicalExtension(ext)
|
|
8973
|
-
: upb_TaggedAuxPtr_MakeNonCanonicalExtension(ext);
|
|
9562
|
+
in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeExtension(ext, tag);
|
|
8974
9563
|
return ext;
|
|
8975
9564
|
}
|
|
8976
9565
|
|
|
8977
9566
|
upb_Extension* UPB_PRIVATE(_upb_Message_GetOrCreateExtension)(
|
|
8978
9567
|
struct upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* a) {
|
|
8979
|
-
return
|
|
8980
|
-
|
|
9568
|
+
return UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)(
|
|
9569
|
+
msg, e, a, kUpb_TaggedAuxType_CanonicalExtension);
|
|
8981
9570
|
}
|
|
8982
9571
|
|
|
8983
9572
|
upb_Extension* UPB_PRIVATE(_upb_Message_CreateNonCanonicalExtension)(
|
|
8984
9573
|
struct upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* a) {
|
|
8985
|
-
return
|
|
8986
|
-
|
|
9574
|
+
return UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)(
|
|
9575
|
+
msg, e, a, kUpb_TaggedAuxType_NonCanonicalExtension);
|
|
8987
9576
|
}
|
|
8988
9577
|
|
|
8989
9578
|
|
|
@@ -9025,8 +9614,19 @@ const float kUpb_FltInfinity = UPB_INFINITY;
|
|
|
9025
9614
|
const double kUpb_Infinity = UPB_INFINITY;
|
|
9026
9615
|
const double kUpb_NaN = UPB_NAN;
|
|
9027
9616
|
|
|
9028
|
-
|
|
9029
|
-
|
|
9617
|
+
UPB_INLINE size_t _upb_Message_InternalBlockSize(uint32_t count) {
|
|
9618
|
+
size_t bytes = UPB_SIZEOF_FLEX(upb_Message_Internal, aux_data, count);
|
|
9619
|
+
return upb_RoundUpToPowerOfTwo(
|
|
9620
|
+
UPB_MAX(bytes, UPB_PRIVATE(kUpb_Arena_MinPoolBlockSize)));
|
|
9621
|
+
}
|
|
9622
|
+
|
|
9623
|
+
UPB_INLINE uint32_t _upb_Message_InternalCapacity(size_t block_bytes) {
|
|
9624
|
+
size_t capacity =
|
|
9625
|
+
UPB_FLEX_CAPACITY(upb_Message_Internal, aux_data, block_bytes);
|
|
9626
|
+
if (capacity > UINT32_MAX) {
|
|
9627
|
+
return UINT32_MAX;
|
|
9628
|
+
}
|
|
9629
|
+
return (uint32_t)capacity;
|
|
9030
9630
|
}
|
|
9031
9631
|
|
|
9032
9632
|
bool UPB_PRIVATE(_upb_Message_ReserveSlot)(struct upb_Message* msg,
|
|
@@ -9035,32 +9635,88 @@ bool UPB_PRIVATE(_upb_Message_ReserveSlot)(struct upb_Message* msg,
|
|
|
9035
9635
|
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
|
|
9036
9636
|
if (!in) {
|
|
9037
9637
|
// No internal data, allocate from scratch.
|
|
9038
|
-
|
|
9039
|
-
in =
|
|
9638
|
+
size_t block_bytes = _upb_Message_InternalBlockSize(1);
|
|
9639
|
+
in = (upb_Message_Internal*)upb_Arena_AllocPool(a, block_bytes);
|
|
9040
9640
|
if (!in) return false;
|
|
9041
9641
|
in->size = 0;
|
|
9042
|
-
in->capacity =
|
|
9642
|
+
in->capacity = _upb_Message_InternalCapacity(block_bytes);
|
|
9043
9643
|
UPB_PRIVATE(_upb_Message_SetInternal)(msg, in);
|
|
9044
9644
|
} else if (in->capacity == in->size) {
|
|
9045
9645
|
if (in->size == UINT32_MAX) return false;
|
|
9046
9646
|
// Internal data is too small, reallocate.
|
|
9047
|
-
size_t needed_pow2 = upb_RoundUpToPowerOfTwo(in->size + 1);
|
|
9048
|
-
if (needed_pow2 > UINT32_MAX) return false;
|
|
9049
|
-
uint32_t new_capacity = needed_pow2;
|
|
9050
9647
|
if (UPB_SIZEOF_FLEX_WOULD_OVERFLOW(upb_Message_Internal, aux_data,
|
|
9051
|
-
|
|
9648
|
+
in->size + 1)) {
|
|
9052
9649
|
return false;
|
|
9053
9650
|
}
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9651
|
+
size_t old_bytes =
|
|
9652
|
+
UPB_SIZEOF_FLEX(upb_Message_Internal, aux_data, in->capacity);
|
|
9653
|
+
size_t new_bytes = _upb_Message_InternalBlockSize(in->size + 1);
|
|
9654
|
+
if (new_bytes == SIZE_MAX ||
|
|
9655
|
+
_upb_Message_InternalCapacity(new_bytes) > UINT32_MAX) {
|
|
9656
|
+
return false;
|
|
9657
|
+
}
|
|
9658
|
+
if (upb_Arena_TryExtend(a, in, old_bytes, new_bytes)) {
|
|
9659
|
+
in->capacity = _upb_Message_InternalCapacity(new_bytes);
|
|
9660
|
+
} else {
|
|
9661
|
+
upb_Message_Internal* new_in =
|
|
9662
|
+
(upb_Message_Internal*)upb_Arena_AllocPool(a, new_bytes);
|
|
9663
|
+
if (!new_in) return false;
|
|
9664
|
+
memcpy(new_in, in,
|
|
9665
|
+
UPB_SIZEOF_FLEX(upb_Message_Internal, aux_data, in->size));
|
|
9666
|
+
new_in->capacity = _upb_Message_InternalCapacity(new_bytes);
|
|
9667
|
+
UPB_PRIVATE(_upb_Arena_Harvest)(a, in, old_bytes);
|
|
9668
|
+
in = new_in;
|
|
9669
|
+
UPB_PRIVATE(_upb_Message_SetInternal)(msg, in);
|
|
9670
|
+
}
|
|
9059
9671
|
}
|
|
9060
9672
|
UPB_ASSERT(in->capacity - in->size >= 1);
|
|
9061
9673
|
return true;
|
|
9062
9674
|
}
|
|
9063
9675
|
|
|
9676
|
+
bool UPB_PRIVATE(_upb_Message_CopyInternal)(struct upb_Message* dst,
|
|
9677
|
+
const struct upb_Message* src,
|
|
9678
|
+
upb_Arena* arena) {
|
|
9679
|
+
const upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(src);
|
|
9680
|
+
if (!in) return true;
|
|
9681
|
+
|
|
9682
|
+
size_t needed_bytes =
|
|
9683
|
+
UPB_SIZEOF_FLEX(upb_Message_Internal, aux_data, in->size);
|
|
9684
|
+
size_t block_bytes = _upb_Message_InternalBlockSize(in->size);
|
|
9685
|
+
upb_Message_Internal* dst_in = NULL;
|
|
9686
|
+
if (block_bytes != SIZE_MAX) {
|
|
9687
|
+
dst_in = (upb_Message_Internal*)upb_Arena_TryAllocPool(arena, block_bytes);
|
|
9688
|
+
}
|
|
9689
|
+
if (!dst_in) {
|
|
9690
|
+
block_bytes = needed_bytes;
|
|
9691
|
+
dst_in = upb_Arena_Malloc(arena, block_bytes);
|
|
9692
|
+
if (!dst_in) return false;
|
|
9693
|
+
}
|
|
9694
|
+
|
|
9695
|
+
dst_in->size = 0;
|
|
9696
|
+
dst_in->capacity = _upb_Message_InternalCapacity(block_bytes);
|
|
9697
|
+
|
|
9698
|
+
for (size_t i = 0; i < in->size; i++) {
|
|
9699
|
+
upb_TaggedAuxPtr tagged_ptr = in->aux_data[i];
|
|
9700
|
+
if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) {
|
|
9701
|
+
const upb_Extension* msg_ext = upb_TaggedAuxPtr_Extension(tagged_ptr);
|
|
9702
|
+
upb_Extension* dst_ext =
|
|
9703
|
+
UPB_PRIVATE(_upb_Extension_Clone)(msg_ext, arena);
|
|
9704
|
+
if (!dst_ext) return false;
|
|
9705
|
+
dst_in->aux_data[dst_in->size++] = upb_TaggedAuxPtr_MakeExtension(
|
|
9706
|
+
dst_ext, upb_TaggedAuxPtr_Type(tagged_ptr));
|
|
9707
|
+
} else if (upb_TaggedAuxPtr_IsUnknownStringView(tagged_ptr)) {
|
|
9708
|
+
upb_StringView* dst_sv = upb_Arena_Malloc(arena, sizeof(upb_StringView));
|
|
9709
|
+
if (!dst_sv) return false;
|
|
9710
|
+
*dst_sv = *upb_TaggedPtrAux_StringViewRepr(tagged_ptr);
|
|
9711
|
+
dst_in->aux_data[dst_in->size++] =
|
|
9712
|
+
upb_TaggedAuxPtr_MakeUnknownDataAliased(dst_sv);
|
|
9713
|
+
}
|
|
9714
|
+
}
|
|
9715
|
+
|
|
9716
|
+
UPB_PRIVATE(_upb_Message_SetInternal)(dst, dst_in);
|
|
9717
|
+
return true;
|
|
9718
|
+
}
|
|
9719
|
+
|
|
9064
9720
|
#ifdef UPB_TRACING_ENABLED
|
|
9065
9721
|
static void (*_message_trace_handler)(const upb_MiniTable*, const upb_Arena*);
|
|
9066
9722
|
|
|
@@ -9678,7 +10334,9 @@ static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d,
|
|
|
9678
10334
|
size_t u32_ofs = ofs / kUpb_SubmsgOffsetBytes;
|
|
9679
10335
|
UPB_ASSERT((ofs % 4) == 0);
|
|
9680
10336
|
UPB_ASSERT((i * sizeof(upb_MiniTableField) + ofs) % ptr_size == 0);
|
|
9681
|
-
|
|
10337
|
+
// u32_ofs must be strictly less than UINT16_MAX: UINT16_MAX is reserved as
|
|
10338
|
+
// kUpb_NoSub, the sentinel meaning "this field has no submessage".
|
|
10339
|
+
if (u32_ofs >= UINT16_MAX) {
|
|
9682
10340
|
upb_MdDecoder_ErrorJmp(&d->base, "Submessage offset overflow");
|
|
9683
10341
|
}
|
|
9684
10342
|
f->UPB_PRIVATE(submsg_ofs) = u32_ofs;
|
|
@@ -9743,6 +10401,9 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr,
|
|
|
9743
10401
|
if (skip == 0) {
|
|
9744
10402
|
upb_MdDecoder_ErrorJmp(&d->base, "Invalid skip value: 0");
|
|
9745
10403
|
}
|
|
10404
|
+
if (skip > UINT32_MAX - last_field_number) {
|
|
10405
|
+
upb_MdDecoder_ErrorJmp(&d->base, "Field number overflow");
|
|
10406
|
+
}
|
|
9746
10407
|
last_field_number += skip;
|
|
9747
10408
|
last_field_number--; // Next field seen will increment.
|
|
9748
10409
|
} else {
|
|
@@ -9763,7 +10424,9 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data,
|
|
|
9763
10424
|
sizeof(upb_MiniTableField) + sizeof(upb_MiniTableSubInternal);
|
|
9764
10425
|
// Buffer length is an upper bound on the number of fields. We will return
|
|
9765
10426
|
// what we don't use.
|
|
9766
|
-
|
|
10427
|
+
size_t initial_bytes;
|
|
10428
|
+
if (upb_MulOverflow(bytes_per_field, len, &initial_bytes) ||
|
|
10429
|
+
upb_AddOverflow(initial_bytes, (size_t)4, &initial_bytes)) {
|
|
9767
10430
|
upb_MdDecoder_ErrorJmp(&d->base, "MiniDescriptor is too large");
|
|
9768
10431
|
}
|
|
9769
10432
|
// Max size used per field is a upb_MiniTableField and a
|
|
@@ -9774,7 +10437,6 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data,
|
|
|
9774
10437
|
UPB_ALIGN_OF(upb_MiniTableField) <=
|
|
9775
10438
|
4,
|
|
9776
10439
|
"alignment difference is too large");
|
|
9777
|
-
const size_t initial_bytes = bytes_per_field * len + 4;
|
|
9778
10440
|
d->fields = upb_Arena_Malloc(d->arena, initial_bytes);
|
|
9779
10441
|
upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields);
|
|
9780
10442
|
|
|
@@ -9866,6 +10528,9 @@ static void upb_MtDecoder_AssignHasbits(upb_MtDecoder* d) {
|
|
|
9866
10528
|
upb_MiniTableField* field =
|
|
9867
10529
|
(upb_MiniTableField*)&d->table.UPB_PRIVATE(fields)[i];
|
|
9868
10530
|
if (field->UPB_PRIVATE(offset) == kHasbitPresence) {
|
|
10531
|
+
if (last_hasbit >= INT16_MAX) {
|
|
10532
|
+
upb_MdDecoder_ErrorJmp(&d->base, "Too many fields with presence");
|
|
10533
|
+
}
|
|
9869
10534
|
field->presence = ++last_hasbit;
|
|
9870
10535
|
}
|
|
9871
10536
|
}
|
|
@@ -9895,6 +10560,12 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) {
|
|
|
9895
10560
|
for (upb_OneOfLayoutItem* item = d->oneofs.data; item < oneof_end; item++) {
|
|
9896
10561
|
upb_MiniTableField* f = &d->fields[item->field_index];
|
|
9897
10562
|
uint16_t case_offset = upb_MtDecoder_Place(d, kUpb_OneOf_CaseFieldRep);
|
|
10563
|
+
// The case offset is stored negated in the int16_t presence field, so it
|
|
10564
|
+
// must fit in the positive int16_t range or it would alias a hasbit index.
|
|
10565
|
+
if (case_offset > INT16_MAX) {
|
|
10566
|
+
upb_MdDecoder_ErrorJmp(&d->base,
|
|
10567
|
+
"Message size exceeded maximum size for oneofs");
|
|
10568
|
+
}
|
|
9898
10569
|
uint16_t data_offset = upb_MtDecoder_Place(d, item->rep);
|
|
9899
10570
|
while (true) {
|
|
9900
10571
|
f->presence = ~case_offset;
|
|
@@ -10036,11 +10707,15 @@ done:
|
|
|
10036
10707
|
|
|
10037
10708
|
#if UPB_FASTTABLE
|
|
10038
10709
|
upb_DecodeFast_TableEntry fasttable[32];
|
|
10039
|
-
int fasttable_size =
|
|
10040
|
-
|
|
10710
|
+
int fasttable_size = 0;
|
|
10711
|
+
if (decoder->platform == kUpb_MiniTablePlatform_64Bit) {
|
|
10712
|
+
fasttable_size = upb_DecodeFast_BuildTable(&decoder->table, fasttable);
|
|
10713
|
+
mt_size += fasttable_size * sizeof(fasttable[0]);
|
|
10714
|
+
}
|
|
10041
10715
|
#endif
|
|
10042
10716
|
|
|
10043
10717
|
upb_MiniTable* ret = upb_Arena_Malloc(decoder->arena, mt_size);
|
|
10718
|
+
upb_MdDecoder_CheckOutOfMemory(&decoder->base, ret);
|
|
10044
10719
|
memcpy(ret, &decoder->table, sizeof(*ret));
|
|
10045
10720
|
|
|
10046
10721
|
#if UPB_FASTTABLE
|
|
@@ -10240,41 +10915,63 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
|
|
|
10240
10915
|
UPB_ASSERT(sub);
|
|
10241
10916
|
|
|
10242
10917
|
const bool sub_is_map = sub->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry;
|
|
10918
|
+
const bool table_is_map = table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry;
|
|
10243
10919
|
|
|
10244
10920
|
switch (field->UPB_PRIVATE(descriptortype)) {
|
|
10245
10921
|
case kUpb_FieldType_Message:
|
|
10246
10922
|
if (sub_is_map) {
|
|
10247
|
-
const bool table_is_map =
|
|
10248
|
-
table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry;
|
|
10249
10923
|
if (UPB_UNLIKELY(table_is_map)) return false;
|
|
10250
10924
|
|
|
10925
|
+
// A map field on the parent table must be repeated, and cannot be in a
|
|
10926
|
+
// oneof or an extension.
|
|
10927
|
+
UPB_ASSERT(!upb_MiniTableField_IsMap(field));
|
|
10928
|
+
if (UPB_UNLIKELY(!upb_MiniTableField_IsArray(field) ||
|
|
10929
|
+
upb_MiniTableField_IsInOneof(field) ||
|
|
10930
|
+
upb_MiniTableField_IsExtension(field))) {
|
|
10931
|
+
return false;
|
|
10932
|
+
}
|
|
10933
|
+
|
|
10251
10934
|
field->UPB_PRIVATE(mode) =
|
|
10252
10935
|
(field->UPB_PRIVATE(mode) & ~kUpb_FieldMode_Mask) |
|
|
10253
10936
|
kUpb_FieldMode_Map;
|
|
10254
10937
|
|
|
10255
10938
|
#if UPB_FASTTABLE
|
|
10256
|
-
//
|
|
10257
|
-
//
|
|
10258
|
-
// overwrite the fasttable entry (if any) that we built for this field
|
|
10259
|
-
// previously.
|
|
10939
|
+
// Update fasttable entry with specialized map decoder function pointer
|
|
10940
|
+
// and metadata.
|
|
10260
10941
|
int size = table->UPB_PRIVATE(table_mask) == 0xff
|
|
10261
10942
|
? 0
|
|
10262
10943
|
: ((table->UPB_PRIVATE(table_mask) >> 3) + 1);
|
|
10263
10944
|
for (int i = 0; i < size; i++) {
|
|
10264
10945
|
_upb_FastTable_Entry* entry = &table->UPB_PRIVATE(fasttable)[i];
|
|
10265
|
-
uint32_t field_number =
|
|
10266
|
-
|
|
10946
|
+
uint32_t field_number =
|
|
10947
|
+
upb_DecodeFastData_GetFieldNumber(entry->field_data);
|
|
10267
10948
|
if (field_number == upb_MiniTableField_Number(field)) {
|
|
10268
|
-
|
|
10269
|
-
|
|
10949
|
+
uint16_t expected_tag =
|
|
10950
|
+
upb_DecodeFastData_GetExpectedTag(entry->field_data);
|
|
10951
|
+
uint64_t subofs = upb_DecodeFastData_GetSubofs(entry->field_data);
|
|
10952
|
+
upb_DecodeFast_TableEntry fast_entry;
|
|
10953
|
+
if (upb_DecodeFast_TryFillMapEntry(field, sub, expected_tag, subofs,
|
|
10954
|
+
&fast_entry)) {
|
|
10955
|
+
entry->field_parser =
|
|
10956
|
+
upb_DecodeFast_GetFunctionPointer(fast_entry.function_idx);
|
|
10957
|
+
entry->field_data = fast_entry.function_data;
|
|
10958
|
+
} else {
|
|
10959
|
+
entry->field_parser = &_upb_FastDecoder_DecodeGeneric;
|
|
10960
|
+
entry->field_data = 0;
|
|
10961
|
+
}
|
|
10270
10962
|
}
|
|
10271
10963
|
}
|
|
10272
10964
|
#endif
|
|
10965
|
+
} else if (table_is_map) {
|
|
10966
|
+
// If table is a map entry, only field 2 (value) can be a submessage.
|
|
10967
|
+
if (UPB_UNLIKELY(upb_MiniTableField_Number(field) != 2)) {
|
|
10968
|
+
return false;
|
|
10969
|
+
}
|
|
10273
10970
|
}
|
|
10274
10971
|
break;
|
|
10275
10972
|
|
|
10276
10973
|
case kUpb_FieldType_Group:
|
|
10277
|
-
if (UPB_UNLIKELY(sub_is_map)) return false;
|
|
10974
|
+
if (UPB_UNLIKELY(sub_is_map || table_is_map)) return false;
|
|
10278
10975
|
break;
|
|
10279
10976
|
|
|
10280
10977
|
default:
|
|
@@ -10284,9 +10981,7 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
|
|
|
10284
10981
|
upb_MiniTableSubInternal* table_sub =
|
|
10285
10982
|
UPB_PTR_AT(field, field->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes,
|
|
10286
10983
|
upb_MiniTableSubInternal);
|
|
10287
|
-
|
|
10288
|
-
// this function repeatedly.
|
|
10289
|
-
// UPB_ASSERT(upb_MiniTable_GetSubMessageTable(table, field) == NULL);
|
|
10984
|
+
UPB_ASSERT(upb_MiniTable_GetSubMessageTable(field) == NULL);
|
|
10290
10985
|
table_sub->UPB_PRIVATE(submsg) = sub;
|
|
10291
10986
|
return true;
|
|
10292
10987
|
}
|
|
@@ -10302,20 +10997,25 @@ bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field,
|
|
|
10302
10997
|
return false;
|
|
10303
10998
|
}
|
|
10304
10999
|
|
|
10305
|
-
if (
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
11000
|
+
if (table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry) {
|
|
11001
|
+
if (UPB_UNLIKELY(upb_MiniTableField_Number(field) != 2)) {
|
|
11002
|
+
return false;
|
|
11003
|
+
}
|
|
11004
|
+
if (!upb_MiniTableEnum_CheckValue(sub, 0)) {
|
|
11005
|
+
// An enum used in a map must include 0 as a value. This matches a check
|
|
11006
|
+
// performed in protoc ("Enum value in map must define 0 as the first
|
|
11007
|
+
// value"). Protoc should ensure that we never get here.
|
|
11008
|
+
//
|
|
11009
|
+
// This ends up being important if we receive wire messages where a map
|
|
11010
|
+
// entry omits the value (and thus defaults to 0).
|
|
11011
|
+
return false;
|
|
11012
|
+
}
|
|
10314
11013
|
}
|
|
10315
11014
|
|
|
10316
11015
|
upb_MiniTableSubInternal* table_sub =
|
|
10317
11016
|
UPB_PTR_AT(field, field->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes,
|
|
10318
11017
|
upb_MiniTableSubInternal);
|
|
11018
|
+
UPB_ASSERT(upb_MiniTable_GetSubEnumTable(field) == NULL);
|
|
10319
11019
|
*table_sub = upb_MiniTableSub_FromEnum(sub);
|
|
10320
11020
|
return true;
|
|
10321
11021
|
}
|
|
@@ -10360,8 +11060,8 @@ bool upb_MiniTable_Link(upb_MiniTable* m, const upb_MiniTable** sub_tables,
|
|
|
10360
11060
|
upb_MiniTableField* f =
|
|
10361
11061
|
(upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(m, i);
|
|
10362
11062
|
if (upb_MiniTableField_CType(f) == kUpb_CType_Message) {
|
|
11063
|
+
if (msg_count >= sub_table_count) return false;
|
|
10363
11064
|
const upb_MiniTable* sub = sub_tables[msg_count++];
|
|
10364
|
-
if (msg_count > sub_table_count) return false;
|
|
10365
11065
|
if (sub && !upb_MiniTable_SetSubMessage(m, f, sub)) return false;
|
|
10366
11066
|
}
|
|
10367
11067
|
}
|
|
@@ -10370,8 +11070,8 @@ bool upb_MiniTable_Link(upb_MiniTable* m, const upb_MiniTable** sub_tables,
|
|
|
10370
11070
|
upb_MiniTableField* f =
|
|
10371
11071
|
(upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(m, i);
|
|
10372
11072
|
if (upb_MiniTableField_IsClosedEnum(f)) {
|
|
11073
|
+
if (enum_count >= sub_enum_count) return false;
|
|
10373
11074
|
const upb_MiniTableEnum* sub = sub_enums[enum_count++];
|
|
10374
|
-
if (enum_count > sub_enum_count) return false;
|
|
10375
11075
|
if (sub && !upb_MiniTable_SetSubEnum(m, f, sub)) return false;
|
|
10376
11076
|
}
|
|
10377
11077
|
}
|
|
@@ -11355,6 +12055,16 @@ const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s,
|
|
|
11355
12055
|
}
|
|
11356
12056
|
|
|
11357
12057
|
static void remove_filedef(upb_DefPool* s, upb_FileDef* file) {
|
|
12058
|
+
intptr_t ext_iter = UPB_INTTABLE_BEGIN;
|
|
12059
|
+
uintptr_t ext_key;
|
|
12060
|
+
upb_value ext_val;
|
|
12061
|
+
while (upb_inttable_next(&s->exts, &ext_key, &ext_val, &ext_iter)) {
|
|
12062
|
+
const upb_FieldDef* ext = upb_value_getconstptr(ext_val);
|
|
12063
|
+
if (upb_FieldDef_File(ext) == file) {
|
|
12064
|
+
upb_inttable_removeiter(&s->exts, &ext_iter);
|
|
12065
|
+
}
|
|
12066
|
+
}
|
|
12067
|
+
|
|
11358
12068
|
intptr_t iter = UPB_INTTABLE_BEGIN;
|
|
11359
12069
|
upb_StringView key;
|
|
11360
12070
|
upb_value val;
|
|
@@ -12067,10 +12777,10 @@ static int _upb_EnumValueDef_Compare(const void* p1, const void* p2) {
|
|
|
12067
12777
|
|
|
12068
12778
|
const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v,
|
|
12069
12779
|
size_t n, upb_Arena* a) {
|
|
12070
|
-
|
|
12780
|
+
size_t bytes;
|
|
12781
|
+
if (upb_MulOverflow(n, sizeof(void*), &bytes)) return NULL;
|
|
12071
12782
|
// TODO: Try to replace this arena alloc with a persistent scratch buffer.
|
|
12072
|
-
upb_EnumValueDef** out =
|
|
12073
|
-
(upb_EnumValueDef**)upb_Arena_Malloc(a, n * sizeof(void*));
|
|
12783
|
+
upb_EnumValueDef** out = (upb_EnumValueDef**)upb_Arena_Malloc(a, bytes);
|
|
12074
12784
|
if (!out) return NULL;
|
|
12075
12785
|
|
|
12076
12786
|
for (size_t i = 0; i < n; i++) {
|
|
@@ -13265,6 +13975,7 @@ struct upb_FileDef {
|
|
|
13265
13975
|
const upb_FileDef** deps;
|
|
13266
13976
|
const int32_t* public_deps;
|
|
13267
13977
|
const int32_t* weak_deps;
|
|
13978
|
+
const char** option_deps;
|
|
13268
13979
|
const upb_MessageDef* top_lvl_msgs;
|
|
13269
13980
|
const upb_EnumDef* top_lvl_enums;
|
|
13270
13981
|
const upb_FieldDef* top_lvl_exts;
|
|
@@ -13275,6 +13986,7 @@ struct upb_FileDef {
|
|
|
13275
13986
|
int dep_count;
|
|
13276
13987
|
int public_dep_count;
|
|
13277
13988
|
int weak_dep_count;
|
|
13989
|
+
int option_dep_count;
|
|
13278
13990
|
int top_lvl_msg_count;
|
|
13279
13991
|
int top_lvl_enum_count;
|
|
13280
13992
|
int top_lvl_ext_count;
|
|
@@ -13332,6 +14044,15 @@ int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) {
|
|
|
13332
14044
|
return f->weak_dep_count;
|
|
13333
14045
|
}
|
|
13334
14046
|
|
|
14047
|
+
const char* upb_FileDef_OptionDependency(const upb_FileDef* f, int i) {
|
|
14048
|
+
UPB_ASSERT(0 <= i && i < f->option_dep_count);
|
|
14049
|
+
return f->option_deps[i];
|
|
14050
|
+
}
|
|
14051
|
+
|
|
14052
|
+
int upb_FileDef_OptionDependencyCount(const upb_FileDef* f) {
|
|
14053
|
+
return f->option_dep_count;
|
|
14054
|
+
}
|
|
14055
|
+
|
|
13335
14056
|
const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) {
|
|
13336
14057
|
return f->public_deps;
|
|
13337
14058
|
}
|
|
@@ -13633,6 +14354,17 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx,
|
|
|
13633
14354
|
mutable_weak_deps[i] = weak_deps[i];
|
|
13634
14355
|
}
|
|
13635
14356
|
|
|
14357
|
+
const upb_StringView* option_deps;
|
|
14358
|
+
option_deps = google_protobuf_FileDescriptorProto_option_dependency(file_proto, &n);
|
|
14359
|
+
file->option_dep_count = n;
|
|
14360
|
+
file->option_deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, const char*, n);
|
|
14361
|
+
for (size_t i = 0; i < n; i++) {
|
|
14362
|
+
file->option_deps[i] = _strviewdup(ctx, option_deps[i]);
|
|
14363
|
+
if (strlen(file->option_deps[i]) != option_deps[i].size) {
|
|
14364
|
+
_upb_DefBuilder_Errf(ctx, "option_dependency contained embedded NULL");
|
|
14365
|
+
}
|
|
14366
|
+
}
|
|
14367
|
+
|
|
13636
14368
|
// Create enums.
|
|
13637
14369
|
enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
|
|
13638
14370
|
file->top_lvl_enum_count = n;
|
|
@@ -13755,9 +14487,9 @@ static void _upb_DefBuilder_CheckIdentNotFull(upb_DefBuilder* ctx,
|
|
|
13755
14487
|
const char c = name.data[i];
|
|
13756
14488
|
const char d = c | 0x20; // force lowercase
|
|
13757
14489
|
const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_');
|
|
13758
|
-
const bool
|
|
14490
|
+
const bool is_number = ('0' <= c) & (c <= '9');
|
|
13759
14491
|
|
|
13760
|
-
good &= is_alpha |
|
|
14492
|
+
good &= is_alpha | is_number;
|
|
13761
14493
|
}
|
|
13762
14494
|
|
|
13763
14495
|
if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, false);
|
|
@@ -13812,7 +14544,12 @@ const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx,
|
|
|
13812
14544
|
} else {
|
|
13813
14545
|
// Remove components from base until we find an entry or run out.
|
|
13814
14546
|
size_t baselen = base ? strlen(base) : 0;
|
|
13815
|
-
|
|
14547
|
+
size_t alloc_size;
|
|
14548
|
+
if (upb_AddOverflow(sym.size, baselen + 1, &alloc_size)) {
|
|
14549
|
+
_upb_DefBuilder_OomErr(ctx);
|
|
14550
|
+
}
|
|
14551
|
+
char* tmp = upb_gmalloc(alloc_size);
|
|
14552
|
+
if (!tmp) _upb_DefBuilder_OomErr(ctx);
|
|
13816
14553
|
while (1) {
|
|
13817
14554
|
char* p = tmp;
|
|
13818
14555
|
if (baselen) {
|
|
@@ -14004,10 +14741,10 @@ void _upb_DefBuilder_CheckIdentSlow(upb_DefBuilder* ctx, upb_StringView name,
|
|
|
14004
14741
|
}
|
|
14005
14742
|
start = true;
|
|
14006
14743
|
} else if (start) {
|
|
14007
|
-
if (!
|
|
14744
|
+
if (!upb_isalphanum(c)) {
|
|
14008
14745
|
_upb_DefBuilder_Errf(ctx,
|
|
14009
14746
|
"invalid name: path components must start with a "
|
|
14010
|
-
"letter (" UPB_STRINGVIEW_FORMAT ")",
|
|
14747
|
+
"letter or digit (" UPB_STRINGVIEW_FORMAT ")",
|
|
14011
14748
|
UPB_STRINGVIEW_ARGS(name));
|
|
14012
14749
|
}
|
|
14013
14750
|
start = false;
|
|
@@ -14108,12 +14845,10 @@ char* upb_strdup2(const char* s, size_t len, upb_Arena* a) {
|
|
|
14108
14845
|
size_t n;
|
|
14109
14846
|
char* p;
|
|
14110
14847
|
|
|
14111
|
-
|
|
14112
|
-
if (len == SIZE_MAX) return NULL;
|
|
14848
|
+
if (upb_AddOverflow(len, (size_t)1, &n)) return NULL;
|
|
14113
14849
|
|
|
14114
14850
|
// Always null-terminate, even if binary data; but don't rely on the input to
|
|
14115
14851
|
// have a null-terminating byte since it may be a raw binary buffer.
|
|
14116
|
-
n = len + 1;
|
|
14117
14852
|
p = upb_Arena_Malloc(a, n);
|
|
14118
14853
|
if (p) {
|
|
14119
14854
|
if (len != 0) memcpy(p, s, len);
|
|
@@ -14281,8 +15016,9 @@ bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m,
|
|
|
14281
15016
|
if (upb_TaggedAuxPtr_IsCanonicalExtension(tagged_ptr)) {
|
|
14282
15017
|
const upb_Extension* ext =
|
|
14283
15018
|
upb_TaggedAuxPtr_CanonicalExtension(tagged_ptr);
|
|
14284
|
-
|
|
14285
|
-
*out_f = upb_DefPool_FindExtensionByMiniTable(
|
|
15019
|
+
*out_val = upb_Extension_GetValue(ext);
|
|
15020
|
+
*out_f = upb_DefPool_FindExtensionByMiniTable(
|
|
15021
|
+
ext_pool, upb_Extension_MiniTableExtension(ext));
|
|
14286
15022
|
*iter = i;
|
|
14287
15023
|
return true;
|
|
14288
15024
|
}
|
|
@@ -14722,10 +15458,7 @@ void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m,
|
|
|
14722
15458
|
const char* shortname = upb_FieldDef_Name(f);
|
|
14723
15459
|
const size_t shortnamelen = strlen(shortname);
|
|
14724
15460
|
|
|
14725
|
-
|
|
14726
|
-
|
|
14727
|
-
upb_value existing_v;
|
|
14728
|
-
if (upb_strtable_lookup(&m->ntof, shortname, &existing_v)) {
|
|
15461
|
+
if (upb_strtable_lookup(&m->ntof, shortname, NULL)) {
|
|
14729
15462
|
_upb_DefBuilder_Errf(ctx, "duplicate field name (%s)", shortname);
|
|
14730
15463
|
}
|
|
14731
15464
|
|
|
@@ -14740,13 +15473,13 @@ void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m,
|
|
|
14740
15473
|
if (!skip_json_conflicts && strcmp(shortname, json_name) != 0 &&
|
|
14741
15474
|
google_protobuf_FeatureSet_json_format(m->resolved_features) ==
|
|
14742
15475
|
google_protobuf_FeatureSet_ALLOW &&
|
|
14743
|
-
upb_strtable_lookup(&m->ntof, json_name,
|
|
15476
|
+
upb_strtable_lookup(&m->ntof, json_name, NULL)) {
|
|
14744
15477
|
_upb_DefBuilder_Errf(
|
|
14745
15478
|
ctx, "duplicate json_name for (%s) with original field name (%s)",
|
|
14746
15479
|
shortname, json_name);
|
|
14747
15480
|
}
|
|
14748
15481
|
|
|
14749
|
-
if (upb_strtable_lookup(&m->jtof, json_name,
|
|
15482
|
+
if (upb_strtable_lookup(&m->jtof, json_name, NULL)) {
|
|
14750
15483
|
if (!skip_json_conflicts) {
|
|
14751
15484
|
_upb_DefBuilder_Errf(ctx, "duplicate json_name (%s)", json_name);
|
|
14752
15485
|
}
|
|
@@ -14761,7 +15494,8 @@ void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m,
|
|
|
14761
15494
|
_upb_DefBuilder_Errf(ctx, "duplicate field number (%u)", field_number);
|
|
14762
15495
|
}
|
|
14763
15496
|
|
|
14764
|
-
ok = upb_inttable_insert(&m->itof, field_number,
|
|
15497
|
+
ok = upb_inttable_insert(&m->itof, field_number, upb_value_constptr(f),
|
|
15498
|
+
ctx->arena);
|
|
14765
15499
|
if (!ok) _upb_DefBuilder_OomErr(ctx);
|
|
14766
15500
|
}
|
|
14767
15501
|
|
|
@@ -15743,10 +16477,16 @@ static upb_StringView default_string(upb_ToProto_Context* ctx,
|
|
|
15743
16477
|
return printf_dup(ctx, "%" PRId32, d.int32_val);
|
|
15744
16478
|
case kUpb_CType_UInt32:
|
|
15745
16479
|
return printf_dup(ctx, "%" PRIu32, d.uint32_val);
|
|
15746
|
-
case kUpb_CType_Float:
|
|
15747
|
-
|
|
15748
|
-
|
|
15749
|
-
return
|
|
16480
|
+
case kUpb_CType_Float: {
|
|
16481
|
+
char buf[kUpb_RoundTripBufferSize];
|
|
16482
|
+
_upb_EncodeRoundTripFloat(d.float_val, buf, sizeof(buf));
|
|
16483
|
+
return strviewdup(ctx, buf);
|
|
16484
|
+
}
|
|
16485
|
+
case kUpb_CType_Double: {
|
|
16486
|
+
char buf[kUpb_RoundTripBufferSize];
|
|
16487
|
+
_upb_EncodeRoundTripDouble(d.double_val, buf, sizeof(buf));
|
|
16488
|
+
return strviewdup(ctx, buf);
|
|
16489
|
+
}
|
|
15750
16490
|
case kUpb_CType_String:
|
|
15751
16491
|
return strviewdup2(ctx, d.str_val);
|
|
15752
16492
|
case kUpb_CType_Bytes:
|
|
@@ -16155,6 +16895,13 @@ static google_protobuf_FileDescriptorProto* filedef_toproto(upb_ToProto_Context*
|
|
|
16155
16895
|
const int32_t* weak_dep_nums = _upb_FileDef_WeakDependencyIndexes(f);
|
|
16156
16896
|
if (n) memcpy(weak_deps, weak_dep_nums, n * sizeof(int32_t));
|
|
16157
16897
|
|
|
16898
|
+
n = upb_FileDef_OptionDependencyCount(f);
|
|
16899
|
+
upb_StringView* option_deps =
|
|
16900
|
+
google_protobuf_FileDescriptorProto_resize_option_dependency(proto, n, ctx->arena);
|
|
16901
|
+
for (size_t i = 0; i < n; i++) {
|
|
16902
|
+
option_deps[i] = strviewdup(ctx, upb_FileDef_OptionDependency(f, i));
|
|
16903
|
+
}
|
|
16904
|
+
|
|
16158
16905
|
n = upb_FileDef_TopLevelMessageCount(f);
|
|
16159
16906
|
google_protobuf_DescriptorProto** msgs =
|
|
16160
16907
|
google_protobuf_FileDescriptorProto_resize_message_type(proto, n, ctx->arena);
|
|
@@ -16390,16 +17137,12 @@ static void _upb_Decoder_Munge(const upb_MiniTableField* field, wireval* val) {
|
|
|
16390
17137
|
case kUpb_FieldType_Bool:
|
|
16391
17138
|
val->bool_val = val->uint64_val != 0;
|
|
16392
17139
|
break;
|
|
16393
|
-
case kUpb_FieldType_SInt32:
|
|
16394
|
-
|
|
16395
|
-
val->uint32_val = (n >> 1) ^ -(int32_t)(n & 1);
|
|
17140
|
+
case kUpb_FieldType_SInt32:
|
|
17141
|
+
val->uint32_val = _upb_Decoder_ZigZagDecode32(val->uint64_val);
|
|
16396
17142
|
break;
|
|
16397
|
-
|
|
16398
|
-
|
|
16399
|
-
uint64_t n = val->uint64_val;
|
|
16400
|
-
val->uint64_val = (n >> 1) ^ -(int64_t)(n & 1);
|
|
17143
|
+
case kUpb_FieldType_SInt64:
|
|
17144
|
+
val->uint64_val = _upb_Decoder_ZigZagDecode64(val->uint64_val);
|
|
16401
17145
|
break;
|
|
16402
|
-
}
|
|
16403
17146
|
case kUpb_FieldType_Int32:
|
|
16404
17147
|
case kUpb_FieldType_UInt32:
|
|
16405
17148
|
_upb_Decoder_MungeInt32(val);
|
|
@@ -16576,7 +17319,8 @@ static const char* _upb_Decoder_DecodeEnumPacked(
|
|
|
16576
17319
|
field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension
|
|
16577
17320
|
? d->original_msg
|
|
16578
17321
|
: msg;
|
|
16579
|
-
if (!_upb_Encoder_AddEnumValueToUnknown(unknown_msg,
|
|
17322
|
+
if (!_upb_Encoder_AddEnumValueToUnknown(unknown_msg,
|
|
17323
|
+
field->UPB_PRIVATE(number),
|
|
16580
17324
|
elem.uint64_val, &d->arena)) {
|
|
16581
17325
|
upb_ErrorHandler_ThrowError(d->err, kUpb_DecodeStatus_OutOfMemory);
|
|
16582
17326
|
}
|
|
@@ -16681,8 +17425,7 @@ static const char* _upb_Decoder_DecodeToArray(upb_Decoder* d, const char* ptr,
|
|
|
16681
17425
|
}
|
|
16682
17426
|
}
|
|
16683
17427
|
|
|
16684
|
-
|
|
16685
|
-
const upb_MiniTable* entry) {
|
|
17428
|
+
upb_Map* _upb_Decoder_CreateMap(upb_Decoder* d, const upb_MiniTable* entry) {
|
|
16686
17429
|
// Maps descriptor type -> upb map size
|
|
16687
17430
|
static const uint8_t kSizeInMap[] = {
|
|
16688
17431
|
[0] = -1, // invalid descriptor type
|
|
@@ -16798,6 +17541,14 @@ static const char* _upb_Decoder_DecodeToSubMessage(
|
|
|
16798
17541
|
} else if (upb_MiniTableField_IsInOneof(field)) {
|
|
16799
17542
|
// Oneof case
|
|
16800
17543
|
uint32_t* oneof_case = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, field);
|
|
17544
|
+
if (op == kUpb_DecodeOp_String || op == kUpb_DecodeOp_Bytes) {
|
|
17545
|
+
// Read the string before setting the oneof case, so that if the read
|
|
17546
|
+
// fails the case still points to the previous member, which is intact.
|
|
17547
|
+
ptr = _upb_Decoder_ReadString2(d, ptr, val->size, mem,
|
|
17548
|
+
op == kUpb_DecodeOp_String);
|
|
17549
|
+
*oneof_case = field->UPB_PRIVATE(number);
|
|
17550
|
+
return ptr;
|
|
17551
|
+
}
|
|
16801
17552
|
if (op == kUpb_DecodeOp_SubMessage &&
|
|
16802
17553
|
*oneof_case != field->UPB_PRIVATE(number)) {
|
|
16803
17554
|
memset(mem, 0, sizeof(void*));
|
|
@@ -16855,10 +17606,11 @@ static void upb_Decoder_AddKnownMessageSetItem(
|
|
|
16855
17606
|
if (UPB_UNLIKELY(!ext)) {
|
|
16856
17607
|
upb_ErrorHandler_ThrowError(d->err, kUpb_DecodeStatus_OutOfMemory);
|
|
16857
17608
|
}
|
|
16858
|
-
upb_Message
|
|
16859
|
-
|
|
16860
|
-
d,
|
|
16861
|
-
&
|
|
17609
|
+
upb_Message* submsg = upb_Extension_GetMutableMessage(ext);
|
|
17610
|
+
submsg = _upb_Decoder_NewSubMessage2(
|
|
17611
|
+
d, upb_MiniTableExtension_GetSubMessage(item_mt),
|
|
17612
|
+
&item_mt->UPB_PRIVATE(field), &submsg);
|
|
17613
|
+
upb_Extension_SetMessage(ext, submsg);
|
|
16862
17614
|
// upb_Decode_LimitDepth() takes uint32_t, d->depth - 1 can not be negative.
|
|
16863
17615
|
if (d->depth <= 1) {
|
|
16864
17616
|
upb_ErrorHandler_ThrowError(d->err, kUpb_DecodeStatus_MaxDepthExceeded);
|
|
@@ -17199,7 +17951,7 @@ const char* _upb_Decoder_DecodeKnownField(upb_Decoder* d, const char* ptr,
|
|
|
17199
17951
|
upb_ErrorHandler_ThrowError(d->err, kUpb_DecodeStatus_OutOfMemory);
|
|
17200
17952
|
}
|
|
17201
17953
|
d->original_msg = msg;
|
|
17202
|
-
msg =
|
|
17954
|
+
msg = UPB_PTR_AT(ext, UPB_ONLYBITS(kUpb_Extension_DataOffset), upb_Message);
|
|
17203
17955
|
}
|
|
17204
17956
|
|
|
17205
17957
|
switch (mode & kUpb_FieldMode_Mask) {
|
|
@@ -17683,6 +18435,51 @@ const char* upb_EncodeStatus_String(upb_EncodeStatus status) {
|
|
|
17683
18435
|
}
|
|
17684
18436
|
|
|
17685
18437
|
|
|
18438
|
+
#include <setjmp.h>
|
|
18439
|
+
#include <stddef.h>
|
|
18440
|
+
|
|
18441
|
+
|
|
18442
|
+
// Must be last.
|
|
18443
|
+
|
|
18444
|
+
static upb_EncodeStatus upb_DoEncodeExtension(upb_encstate* encoder, char* ptr,
|
|
18445
|
+
const struct upb_Extension* ext,
|
|
18446
|
+
bool is_message_set,
|
|
18447
|
+
upb_StringView* view,
|
|
18448
|
+
int encode_options) {
|
|
18449
|
+
if (UPB_SETJMP(*encoder->err) == 0) {
|
|
18450
|
+
char* buf = ptr;
|
|
18451
|
+
size_t size = 0;
|
|
18452
|
+
UPB_PRIVATE(_upb_Encode_Extension)(
|
|
18453
|
+
encoder, upb_Extension_MiniTableExtension(ext),
|
|
18454
|
+
upb_Extension_GetValue(ext), is_message_set, &buf, &size,
|
|
18455
|
+
encode_options);
|
|
18456
|
+
view->data = buf;
|
|
18457
|
+
view->size = size;
|
|
18458
|
+
} else {
|
|
18459
|
+
UPB_ASSERT(encoder->status != kUpb_EncodeStatus_Ok);
|
|
18460
|
+
upb_BackAlloc_Abort(&encoder->alloc);
|
|
18461
|
+
view->data = NULL;
|
|
18462
|
+
view->size = 0;
|
|
18463
|
+
}
|
|
18464
|
+
UPB_PRIVATE(_upb_encstate_destroy)(encoder);
|
|
18465
|
+
return encoder->status;
|
|
18466
|
+
}
|
|
18467
|
+
|
|
18468
|
+
upb_EncodeStatus upb_EncodeExtension(const struct upb_Extension* ext,
|
|
18469
|
+
struct upb_Arena* arena,
|
|
18470
|
+
upb_StringView* view, int encode_options) {
|
|
18471
|
+
const upb_MiniTable* extendee =
|
|
18472
|
+
upb_MiniTableExtension_Extendee(upb_Extension_MiniTableExtension(ext));
|
|
18473
|
+
bool is_message_set =
|
|
18474
|
+
extendee != NULL && upb_MiniTable_IsMessageSet(extendee);
|
|
18475
|
+
upb_encstate e;
|
|
18476
|
+
jmp_buf err;
|
|
18477
|
+
char* ptr = UPB_PRIVATE(_upb_encstate_init)(&e, &err, arena);
|
|
18478
|
+
return upb_DoEncodeExtension(&e, ptr, ext, is_message_set, view,
|
|
18479
|
+
encode_options);
|
|
18480
|
+
}
|
|
18481
|
+
|
|
18482
|
+
|
|
17686
18483
|
#include <stddef.h>
|
|
17687
18484
|
#include <stdint.h>
|
|
17688
18485
|
#include <string.h>
|
|
@@ -17726,12 +18523,12 @@ static size_t upb_BackAlloc_CalcBlockSize(upb_BackAlloc* a, size_t required,
|
|
|
17726
18523
|
|
|
17727
18524
|
static char* upb_BackAlloc_Realloc(upb_BackAlloc* a, char* ptr, size_t n) {
|
|
17728
18525
|
size_t copy = a->limit - ptr;
|
|
17729
|
-
|
|
18526
|
+
size_t required_block_size;
|
|
18527
|
+
if (upb_AddOverflow(copy, n, &required_block_size)) {
|
|
17730
18528
|
return NULL;
|
|
17731
18529
|
}
|
|
17732
18530
|
|
|
17733
18531
|
bool one_off = false;
|
|
17734
|
-
size_t required_block_size = copy + n;
|
|
17735
18532
|
size_t size = upb_BackAlloc_CalcBlockSize(a, required_block_size, &one_off);
|
|
17736
18533
|
|
|
17737
18534
|
char* block = UPB_PRIVATE(_upb_Arena_AllocBlock)(a->arena, &size);
|
|
@@ -17765,6 +18562,9 @@ static char* upb_BackAlloc_Realloc(upb_BackAlloc* a, char* ptr, size_t n) {
|
|
|
17765
18562
|
}
|
|
17766
18563
|
|
|
17767
18564
|
char* upb_BackAlloc_Grow(upb_BackAlloc* a, char* ptr, size_t n) {
|
|
18565
|
+
if (!upb_AllocationCount_IncrementAndCheck()) {
|
|
18566
|
+
return NULL;
|
|
18567
|
+
}
|
|
17768
18568
|
if (a->limit == a->buf) {
|
|
17769
18569
|
// First allocation: try to steal a block.
|
|
17770
18570
|
size_t size = n;
|
|
@@ -18341,21 +19141,23 @@ static char* encode_array(char* ptr, upb_encstate* e, const upb_Message* msg,
|
|
|
18341
19141
|
return ptr;
|
|
18342
19142
|
}
|
|
18343
19143
|
|
|
18344
|
-
|
|
18345
|
-
|
|
18346
|
-
|
|
18347
|
-
|
|
18348
|
-
|
|
19144
|
+
UPB_FORCEINLINE
|
|
19145
|
+
char* encode_mapentry(char* ptr, upb_encstate* e, uint32_t number,
|
|
19146
|
+
const upb_MiniTableField* key_field,
|
|
19147
|
+
const upb_MiniTableField* val_field,
|
|
19148
|
+
const upb_MapEntry* ent) {
|
|
18349
19149
|
size_t pre_len = upb_BackAlloc_Size(&e->alloc, ptr);
|
|
18350
|
-
|
|
19150
|
+
UPB_ASSUME(upb_MiniTableField_Number(val_field) == 2);
|
|
18351
19151
|
ptr = encode_scalar(ptr, e, &ent->v, val_field);
|
|
19152
|
+
UPB_ASSUME(upb_MiniTableField_Number(key_field) == 1);
|
|
18352
19153
|
ptr = encode_scalar(ptr, e, &ent->k, key_field);
|
|
18353
|
-
size = upb_BackAlloc_Size(&e->alloc, ptr) - pre_len;
|
|
19154
|
+
size_t size = upb_BackAlloc_Size(&e->alloc, ptr) - pre_len;
|
|
18354
19155
|
ptr = encode_length(ptr, e, size);
|
|
18355
19156
|
ptr = encode_tag(ptr, e, number, kUpb_WireType_Delimited);
|
|
18356
19157
|
return ptr;
|
|
18357
19158
|
}
|
|
18358
19159
|
|
|
19160
|
+
UPB_NOINLINE
|
|
18359
19161
|
static char* encode_map(char* ptr, upb_encstate* e, const upb_Message* msg,
|
|
18360
19162
|
const upb_MiniTableField* f) {
|
|
18361
19163
|
const upb_Map* map = *UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), const upb_Map*);
|
|
@@ -18364,14 +19166,20 @@ static char* encode_map(char* ptr, upb_encstate* e, const upb_Message* msg,
|
|
|
18364
19166
|
|
|
18365
19167
|
if (!map || !upb_Map_Size(map)) return ptr;
|
|
18366
19168
|
|
|
19169
|
+
uint32_t number = upb_MiniTableField_Number(f);
|
|
19170
|
+
uint32_t key_size = map->key_size;
|
|
19171
|
+
uint32_t val_size = map->val_size;
|
|
19172
|
+
const upb_MiniTableField* key_field = upb_MiniTable_MapKey(layout);
|
|
19173
|
+
const upb_MiniTableField* val_field = upb_MiniTable_MapValue(layout);
|
|
18367
19174
|
if (e->options & kUpb_EncodeOption_Deterministic) {
|
|
18368
19175
|
_upb_sortedmap sorted;
|
|
18369
|
-
_upb_mapsorter_pushmap(
|
|
18370
|
-
|
|
18371
|
-
|
|
19176
|
+
if (!_upb_mapsorter_pushmap(
|
|
19177
|
+
&e->sorter, key_field->UPB_PRIVATE(descriptortype), map, &sorted)) {
|
|
19178
|
+
encode_err(e, kUpb_EncodeStatus_OutOfMemory);
|
|
19179
|
+
}
|
|
18372
19180
|
upb_MapEntry ent;
|
|
18373
19181
|
while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) {
|
|
18374
|
-
ptr = encode_mapentry(ptr, e,
|
|
19182
|
+
ptr = encode_mapentry(ptr, e, number, key_field, val_field, &ent);
|
|
18375
19183
|
}
|
|
18376
19184
|
_upb_mapsorter_popmap(&e->sorter, &sorted);
|
|
18377
19185
|
} else {
|
|
@@ -18381,20 +19189,19 @@ static char* encode_map(char* ptr, upb_encstate* e, const upb_Message* msg,
|
|
|
18381
19189
|
upb_StringView strkey;
|
|
18382
19190
|
while (upb_strtable_next2(&map->t.strtable, &strkey, &val, &iter)) {
|
|
18383
19191
|
upb_MapEntry ent;
|
|
18384
|
-
_upb_map_fromkey(strkey, &ent.k,
|
|
18385
|
-
_upb_map_fromvalue(val, &ent.v,
|
|
18386
|
-
ptr =
|
|
18387
|
-
encode_mapentry(ptr, e, upb_MiniTableField_Number(f), layout, &ent);
|
|
19192
|
+
_upb_map_fromkey(strkey, &ent.k, key_size);
|
|
19193
|
+
_upb_map_fromvalue(val, &ent.v, val_size);
|
|
19194
|
+
ptr = encode_mapentry(ptr, e, number, key_field, val_field, &ent);
|
|
18388
19195
|
}
|
|
18389
19196
|
} else {
|
|
18390
19197
|
intptr_t iter = UPB_INTTABLE_BEGIN;
|
|
18391
19198
|
uintptr_t intkey = 0;
|
|
18392
19199
|
while (upb_inttable_next(&map->t.inttable, &intkey, &val, &iter)) {
|
|
18393
19200
|
upb_MapEntry ent;
|
|
18394
|
-
|
|
18395
|
-
|
|
18396
|
-
|
|
18397
|
-
|
|
19201
|
+
UPB_ASSUME(key_size != UPB_MAPTYPE_STRING);
|
|
19202
|
+
memcpy(&ent.k, &intkey, key_size);
|
|
19203
|
+
_upb_map_fromvalue(val, &ent.v, val_size);
|
|
19204
|
+
ptr = encode_mapentry(ptr, e, number, key_field, val_field, &ent);
|
|
18398
19205
|
}
|
|
18399
19206
|
}
|
|
18400
19207
|
}
|
|
@@ -18403,52 +19210,19 @@ static char* encode_map(char* ptr, upb_encstate* e, const upb_Message* msg,
|
|
|
18403
19210
|
|
|
18404
19211
|
static bool encode_shouldencode(const upb_Message* msg,
|
|
18405
19212
|
const upb_MiniTableField* f) {
|
|
18406
|
-
|
|
18407
|
-
// Proto3 presence or map/array.
|
|
18408
|
-
const void* mem = UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), void);
|
|
18409
|
-
switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) {
|
|
18410
|
-
case kUpb_FieldRep_1Byte: {
|
|
18411
|
-
char ch;
|
|
18412
|
-
memcpy(&ch, mem, 1);
|
|
18413
|
-
return ch != 0;
|
|
18414
|
-
}
|
|
18415
|
-
case kUpb_FieldRep_4Byte: {
|
|
18416
|
-
uint32_t u32;
|
|
18417
|
-
memcpy(&u32, mem, 4);
|
|
18418
|
-
return u32 != 0;
|
|
18419
|
-
}
|
|
18420
|
-
case kUpb_FieldRep_8Byte: {
|
|
18421
|
-
uint64_t u64;
|
|
18422
|
-
memcpy(&u64, mem, 8);
|
|
18423
|
-
return u64 != 0;
|
|
18424
|
-
}
|
|
18425
|
-
case kUpb_FieldRep_StringView: {
|
|
18426
|
-
const upb_StringView* str = (const upb_StringView*)mem;
|
|
18427
|
-
return str->size != 0;
|
|
18428
|
-
}
|
|
18429
|
-
default:
|
|
18430
|
-
UPB_UNREACHABLE();
|
|
18431
|
-
}
|
|
18432
|
-
} else if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)) {
|
|
18433
|
-
// Proto2 presence: hasbit.
|
|
18434
|
-
return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, f);
|
|
18435
|
-
} else {
|
|
18436
|
-
// Field is in a oneof.
|
|
18437
|
-
return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, f) ==
|
|
18438
|
-
upb_MiniTableField_Number(f);
|
|
18439
|
-
}
|
|
19213
|
+
return UPB_PRIVATE(_upb_Message_FieldIsSet)(msg, f);
|
|
18440
19214
|
}
|
|
18441
19215
|
|
|
18442
19216
|
static char* encode_field(char* ptr, upb_encstate* e, const upb_Message* msg,
|
|
18443
19217
|
const upb_MiniTableField* field) {
|
|
18444
19218
|
switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(field)) {
|
|
19219
|
+
case kUpb_FieldMode_Scalar:
|
|
19220
|
+
return encode_scalar(
|
|
19221
|
+
ptr, e, UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void), field);
|
|
18445
19222
|
case kUpb_FieldMode_Array:
|
|
18446
19223
|
return encode_array(ptr, e, msg, field);
|
|
18447
19224
|
case kUpb_FieldMode_Map:
|
|
18448
19225
|
return encode_map(ptr, e, msg, field);
|
|
18449
|
-
case kUpb_FieldMode_Scalar:
|
|
18450
|
-
return encode_scalar(
|
|
18451
|
-
ptr, e, UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void), field);
|
|
18452
19226
|
default:
|
|
18453
19227
|
UPB_UNREACHABLE();
|
|
18454
19228
|
}
|
|
@@ -18489,8 +19263,8 @@ static char* encode_exts(char* ptr, upb_encstate* e, const upb_MiniTable* m,
|
|
|
18489
19263
|
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
|
|
18490
19264
|
if (!in) return ptr;
|
|
18491
19265
|
|
|
18492
|
-
/* Encode all extensions together. Unlike C++, we do not attempt to
|
|
18493
|
-
* these in field number order relative to normal fields or even to each
|
|
19266
|
+
/* Encode all canonical extensions together. Unlike C++, we do not attempt to
|
|
19267
|
+
* keep these in field number order relative to normal fields or even to each
|
|
18494
19268
|
* other. */
|
|
18495
19269
|
uintptr_t iter = kUpb_Message_ExtensionBegin;
|
|
18496
19270
|
const upb_MiniTableExtension* ext;
|
|
@@ -18504,11 +19278,12 @@ static char* encode_exts(char* ptr, upb_encstate* e, const upb_MiniTable* m,
|
|
|
18504
19278
|
if (e->options & kUpb_EncodeOption_Deterministic) {
|
|
18505
19279
|
_upb_sortedmap sorted;
|
|
18506
19280
|
if (!_upb_mapsorter_pushexts(&e->sorter, in, &sorted)) {
|
|
18507
|
-
|
|
19281
|
+
encode_err(e, kUpb_EncodeStatus_OutOfMemory);
|
|
18508
19282
|
}
|
|
18509
19283
|
const upb_Extension* ext;
|
|
18510
19284
|
while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) {
|
|
18511
|
-
ptr = encode_ext(ptr, e, ext
|
|
19285
|
+
ptr = encode_ext(ptr, e, upb_Extension_MiniTableExtension(ext),
|
|
19286
|
+
upb_Extension_GetValue(ext),
|
|
18512
19287
|
UPB_PRIVATE(_upb_MiniTable_ExtModeBase)(m) ==
|
|
18513
19288
|
kUpb_ExtMode_IsMessageSet);
|
|
18514
19289
|
}
|
|
@@ -18535,22 +19310,27 @@ char* encode_message(char* ptr, upb_encstate* e, const upb_Message* msg,
|
|
|
18535
19310
|
}
|
|
18536
19311
|
}
|
|
18537
19312
|
|
|
18538
|
-
|
|
18539
|
-
|
|
18540
|
-
|
|
18541
|
-
|
|
18542
|
-
//
|
|
18543
|
-
//
|
|
18544
|
-
|
|
18545
|
-
|
|
18546
|
-
|
|
18547
|
-
|
|
18548
|
-
|
|
18549
|
-
|
|
18550
|
-
|
|
18551
|
-
|
|
18552
|
-
|
|
18553
|
-
|
|
19313
|
+
bool skip_unknown = (e->options & kUpb_EncodeOption_SkipUnknown) != 0;
|
|
19314
|
+
const upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
|
|
19315
|
+
if (!skip_unknown && in) {
|
|
19316
|
+
// Iterate backwards because the encoder builds the buffer in reverse
|
|
19317
|
+
// (from end to start). This ensures that unknown fields and non-canonical
|
|
19318
|
+
// extensions are emitted in their original forward order.
|
|
19319
|
+
size_t i = in->size;
|
|
19320
|
+
while (i > 0) {
|
|
19321
|
+
i--;
|
|
19322
|
+
upb_TaggedAuxPtr tagged_ptr = in->aux_data[i];
|
|
19323
|
+
if (upb_TaggedAuxPtr_IsUnknownStringView(tagged_ptr)) {
|
|
19324
|
+
const upb_StringView* unknown =
|
|
19325
|
+
upb_TaggedPtrAux_StringViewRepr(tagged_ptr);
|
|
19326
|
+
ptr = encode_bytes(ptr, e, unknown->data, unknown->size);
|
|
19327
|
+
} else if (upb_TaggedAuxPtr_IsNonCanonicalExtension(tagged_ptr)) {
|
|
19328
|
+
const upb_Extension* ext =
|
|
19329
|
+
upb_TaggedAuxPtr_NonCanonicalExtension(tagged_ptr);
|
|
19330
|
+
ptr = encode_ext(ptr, e, upb_Extension_MiniTableExtension(ext),
|
|
19331
|
+
upb_Extension_GetValue(ext),
|
|
19332
|
+
UPB_PRIVATE(_upb_MiniTable_ExtModeBase)(m) ==
|
|
19333
|
+
kUpb_ExtMode_IsMessageSet);
|
|
18554
19334
|
}
|
|
18555
19335
|
}
|
|
18556
19336
|
}
|
|
@@ -18617,6 +19397,12 @@ upb_EncodeStatus _upb_Encode(const upb_Message* msg, const upb_MiniTable* l,
|
|
|
18617
19397
|
return upb_Encoder_Encode(ptr, &e, msg, l, buf, size, prepend_len);
|
|
18618
19398
|
}
|
|
18619
19399
|
|
|
19400
|
+
char* UPB_PRIVATE(_upb_Encode_FieldToBuffer)(char* ptr, upb_encstate* e,
|
|
19401
|
+
const upb_Message* msg,
|
|
19402
|
+
const upb_MiniTableField* field) {
|
|
19403
|
+
return encode_field(ptr, e, msg, field);
|
|
19404
|
+
}
|
|
19405
|
+
|
|
18620
19406
|
upb_EncodeStatus UPB_PRIVATE(_upb_Encode_Field)(upb_encstate* e,
|
|
18621
19407
|
const upb_Message* msg,
|
|
18622
19408
|
const upb_MiniTableField* field,
|
|
@@ -18675,7 +19461,8 @@ const char* UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)(
|
|
|
18675
19461
|
e->limit_ptr = e->end + e->limit;
|
|
18676
19462
|
UPB_ASSERT(ptr < e->limit_ptr);
|
|
18677
19463
|
e->input_delta = (uintptr_t)old_end - (uintptr_t)new_start;
|
|
18678
|
-
UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(
|
|
19464
|
+
UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(
|
|
19465
|
+
e, kUpb_EpsCopyInputStream_SlopBytes);
|
|
18679
19466
|
return new_start;
|
|
18680
19467
|
} else {
|
|
18681
19468
|
UPB_ASSERT(overrun > e->limit);
|
|
@@ -18758,6 +19545,7 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
|
|
|
18758
19545
|
#undef UPB_SIZE
|
|
18759
19546
|
#undef UPB_PTR_AT
|
|
18760
19547
|
#undef UPB_SIZEOF_FLEX
|
|
19548
|
+
#undef UPB_FLEX_CAPACITY
|
|
18761
19549
|
#undef UPB_SIZEOF_FLEX_WOULD_OVERFLOW
|
|
18762
19550
|
#undef UPB_MAPTYPE_STRING
|
|
18763
19551
|
#undef UPB_EXPORT
|
|
@@ -18811,6 +19599,8 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
|
|
|
18811
19599
|
#undef UPB_MALLOC_ALIGN
|
|
18812
19600
|
#undef UPB_TSAN
|
|
18813
19601
|
#undef UPB_DEPRECATED
|
|
19602
|
+
#undef UPB_IGNORE_DEPRECATION_START
|
|
19603
|
+
#undef UPB_IGNORE_DEPRECATION_STOP
|
|
18814
19604
|
#undef UPB_GNUC_MIN
|
|
18815
19605
|
#undef UPB_CLANG_MIN
|
|
18816
19606
|
#undef UPB_DESCRIPTOR_UPB_H_FILENAME
|
|
@@ -18828,6 +19618,7 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
|
|
|
18828
19618
|
#undef UPB_HAS_ATTRIBUTE
|
|
18829
19619
|
#undef UPB_HAS_CPP_ATTRIBUTE
|
|
18830
19620
|
#undef UPB_HAS_BUILTIN
|
|
19621
|
+
#undef UPB_MEMCPY_INLINE
|
|
18831
19622
|
#undef UPB_HAS_EXTENSION
|
|
18832
19623
|
#undef UPB_HAS_FEATURE
|
|
18833
19624
|
#undef UPB_XSAN_MEMBER
|
|
@@ -18842,3 +19633,5 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
|
|
|
18842
19633
|
#undef _UPB_STRINGIFY
|
|
18843
19634
|
#undef _UPB_STRINGIFY2
|
|
18844
19635
|
#undef UPB_CONSTRUCTOR
|
|
19636
|
+
#undef UPB_RETAIN
|
|
19637
|
+
#undef UPB_HIDDEN
|