diff options
author | thegeorg <thegeorg@yandex-team.com> | 2023-03-28 10:11:46 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2023-03-28 10:11:46 +0300 |
commit | 14a9357e8d2d937e22b789d5aea09219a3e92c31 (patch) | |
tree | 9e899edffa271e32ae6272be3034a371b3742c2a /contrib/libs/grpc/third_party/upb | |
parent | 1911ec1bf2da9ae39eb5f31511a92b06b9631da1 (diff) | |
download | ydb-14a9357e8d2d937e22b789d5aea09219a3e92c31.tar.gz |
Update contrib/libs/grpc to 1.45.2
Diffstat (limited to 'contrib/libs/grpc/third_party/upb')
33 files changed, 5545 insertions, 3728 deletions
diff --git a/contrib/libs/grpc/third_party/upb/CMakeLists.darwin-x86_64.txt b/contrib/libs/grpc/third_party/upb/CMakeLists.darwin-x86_64.txt index 2978b68ec9..95e91287c1 100644 --- a/contrib/libs/grpc/third_party/upb/CMakeLists.darwin-x86_64.txt +++ b/contrib/libs/grpc/third_party/upb/CMakeLists.darwin-x86_64.txt @@ -22,6 +22,9 @@ target_include_directories(grpc-third_party-upb PRIVATE target_sources(grpc-third_party-upb PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/naive.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-neon.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-sse.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/decode.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/decode_fast.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/def.c diff --git a/contrib/libs/grpc/third_party/upb/CMakeLists.linux-aarch64.txt b/contrib/libs/grpc/third_party/upb/CMakeLists.linux-aarch64.txt index 61de386d30..a0963907a3 100644 --- a/contrib/libs/grpc/third_party/upb/CMakeLists.linux-aarch64.txt +++ b/contrib/libs/grpc/third_party/upb/CMakeLists.linux-aarch64.txt @@ -25,6 +25,9 @@ target_link_libraries(grpc-third_party-upb PUBLIC target_sources(grpc-third_party-upb PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/naive.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-neon.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-sse.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/decode.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/decode_fast.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/def.c diff --git a/contrib/libs/grpc/third_party/upb/CMakeLists.linux-x86_64.txt b/contrib/libs/grpc/third_party/upb/CMakeLists.linux-x86_64.txt index 61de386d30..a0963907a3 100644 --- a/contrib/libs/grpc/third_party/upb/CMakeLists.linux-x86_64.txt +++ b/contrib/libs/grpc/third_party/upb/CMakeLists.linux-x86_64.txt @@ -25,6 +25,9 @@ target_link_libraries(grpc-third_party-upb PUBLIC target_sources(grpc-third_party-upb PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/naive.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-neon.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-sse.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/decode.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/decode_fast.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/def.c diff --git a/contrib/libs/grpc/third_party/upb/CMakeLists.windows-x86_64.txt b/contrib/libs/grpc/third_party/upb/CMakeLists.windows-x86_64.txt index c5aaef0f2d..f9d6d5f4dd 100644 --- a/contrib/libs/grpc/third_party/upb/CMakeLists.windows-x86_64.txt +++ b/contrib/libs/grpc/third_party/upb/CMakeLists.windows-x86_64.txt @@ -21,6 +21,9 @@ target_include_directories(grpc-third_party-upb PRIVATE target_sources(grpc-third_party-upb PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/naive.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-neon.c + ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-sse.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/decode.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/decode_fast.c ${CMAKE_SOURCE_DIR}/contrib/libs/grpc/third_party/upb/upb/def.c diff --git a/contrib/libs/grpc/third_party/upb/third_party/utf8_range/LICENSE b/contrib/libs/grpc/third_party/upb/third_party/utf8_range/LICENSE new file mode 100644 index 0000000000..c1f087ecc8 --- /dev/null +++ b/contrib/libs/grpc/third_party/upb/third_party/utf8_range/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Yibo Cai + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/contrib/libs/grpc/third_party/upb/third_party/utf8_range/naive.c b/contrib/libs/grpc/third_party/upb/third_party/utf8_range/naive.c new file mode 100644 index 0000000000..9b7e5bb4be --- /dev/null +++ b/contrib/libs/grpc/third_party/upb/third_party/utf8_range/naive.c @@ -0,0 +1,92 @@ +#include <stdio.h> + +/* + * http://www.unicode.org/versions/Unicode6.0.0/ch03.pdf - page 94 + * + * Table 3-7. Well-Formed UTF-8 Byte Sequences + * + * +--------------------+------------+-------------+------------+-------------+ + * | Code Points | First Byte | Second Byte | Third Byte | Fourth Byte | + * +--------------------+------------+-------------+------------+-------------+ + * | U+0000..U+007F | 00..7F | | | | + * +--------------------+------------+-------------+------------+-------------+ + * | U+0080..U+07FF | C2..DF | 80..BF | | | + * +--------------------+------------+-------------+------------+-------------+ + * | U+0800..U+0FFF | E0 | A0..BF | 80..BF | | + * +--------------------+------------+-------------+------------+-------------+ + * | U+1000..U+CFFF | E1..EC | 80..BF | 80..BF | | + * +--------------------+------------+-------------+------------+-------------+ + * | U+D000..U+D7FF | ED | 80..9F | 80..BF | | + * +--------------------+------------+-------------+------------+-------------+ + * | U+E000..U+FFFF | EE..EF | 80..BF | 80..BF | | + * +--------------------+------------+-------------+------------+-------------+ + * | U+10000..U+3FFFF | F0 | 90..BF | 80..BF | 80..BF | + * +--------------------+------------+-------------+------------+-------------+ + * | U+40000..U+FFFFF | F1..F3 | 80..BF | 80..BF | 80..BF | + * +--------------------+------------+-------------+------------+-------------+ + * | U+100000..U+10FFFF | F4 | 80..8F | 80..BF | 80..BF | + * +--------------------+------------+-------------+------------+-------------+ + */ + +/* Return 0 - success, >0 - index(1 based) of first error char */ +int utf8_naive(const unsigned char *data, int len) +{ + int err_pos = 1; + + while (len) { + int bytes; + const unsigned char byte1 = data[0]; + + /* 00..7F */ + if (byte1 <= 0x7F) { + bytes = 1; + /* C2..DF, 80..BF */ + } else if (len >= 2 && byte1 >= 0xC2 && byte1 <= 0xDF && + (signed char)data[1] <= (signed char)0xBF) { + bytes = 2; + } else if (len >= 3) { + const unsigned char byte2 = data[1]; + + /* Is byte2, byte3 between 0x80 ~ 0xBF */ + const int byte2_ok = (signed char)byte2 <= (signed char)0xBF; + const int byte3_ok = (signed char)data[2] <= (signed char)0xBF; + + if (byte2_ok && byte3_ok && + /* E0, A0..BF, 80..BF */ + ((byte1 == 0xE0 && byte2 >= 0xA0) || + /* E1..EC, 80..BF, 80..BF */ + (byte1 >= 0xE1 && byte1 <= 0xEC) || + /* ED, 80..9F, 80..BF */ + (byte1 == 0xED && byte2 <= 0x9F) || + /* EE..EF, 80..BF, 80..BF */ + (byte1 >= 0xEE && byte1 <= 0xEF))) { + bytes = 3; + } else if (len >= 4) { + /* Is byte4 between 0x80 ~ 0xBF */ + const int byte4_ok = (signed char)data[3] <= (signed char)0xBF; + + if (byte2_ok && byte3_ok && byte4_ok && + /* F0, 90..BF, 80..BF, 80..BF */ + ((byte1 == 0xF0 && byte2 >= 0x90) || + /* F1..F3, 80..BF, 80..BF, 80..BF */ + (byte1 >= 0xF1 && byte1 <= 0xF3) || + /* F4, 80..8F, 80..BF, 80..BF */ + (byte1 == 0xF4 && byte2 <= 0x8F))) { + bytes = 4; + } else { + return err_pos; + } + } else { + return err_pos; + } + } else { + return err_pos; + } + + len -= bytes; + err_pos += bytes; + data += bytes; + } + + return 0; +} diff --git a/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-neon.c b/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-neon.c new file mode 100644 index 0000000000..683396540c --- /dev/null +++ b/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-neon.c @@ -0,0 +1,157 @@ +/* + * Process 2x16 bytes in each iteration. + * Comments removed for brevity. See range-neon.c for details. + */ +#if defined(__aarch64__) && defined(__ARM_NEON) + +#include <stdio.h> +#include <stdint.h> +#include <arm_neon.h> + +int utf8_naive(const unsigned char *data, int len); + +static const uint8_t _first_len_tbl[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, +}; + +static const uint8_t _first_range_tbl[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, +}; + +static const uint8_t _range_min_tbl[] = { + 0x00, 0x80, 0x80, 0x80, 0xA0, 0x80, 0x90, 0x80, + 0xC2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +static const uint8_t _range_max_tbl[] = { + 0x7F, 0xBF, 0xBF, 0xBF, 0xBF, 0x9F, 0xBF, 0x8F, + 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static const uint8_t _range_adjust_tbl[] = { + 2, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, +}; + +/* Return 0 on success, -1 on error */ +int utf8_range2(const unsigned char *data, int len) +{ + if (len >= 32) { + uint8x16_t prev_input = vdupq_n_u8(0); + uint8x16_t prev_first_len = vdupq_n_u8(0); + + const uint8x16_t first_len_tbl = vld1q_u8(_first_len_tbl); + const uint8x16_t first_range_tbl = vld1q_u8(_first_range_tbl); + const uint8x16_t range_min_tbl = vld1q_u8(_range_min_tbl); + const uint8x16_t range_max_tbl = vld1q_u8(_range_max_tbl); + const uint8x16x2_t range_adjust_tbl = vld2q_u8(_range_adjust_tbl); + + const uint8x16_t const_1 = vdupq_n_u8(1); + const uint8x16_t const_2 = vdupq_n_u8(2); + const uint8x16_t const_e0 = vdupq_n_u8(0xE0); + + uint8x16_t error1 = vdupq_n_u8(0); + uint8x16_t error2 = vdupq_n_u8(0); + uint8x16_t error3 = vdupq_n_u8(0); + uint8x16_t error4 = vdupq_n_u8(0); + + while (len >= 32) { + /******************* two blocks interleaved **********************/ + +#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ < 8) + /* gcc doesn't support vldq1_u8_x2 until version 8 */ + const uint8x16_t input_a = vld1q_u8(data); + const uint8x16_t input_b = vld1q_u8(data + 16); +#else + /* Forces a double load on Clang */ + const uint8x16x2_t input_pair = vld1q_u8_x2(data); + const uint8x16_t input_a = input_pair.val[0]; + const uint8x16_t input_b = input_pair.val[1]; +#endif + + const uint8x16_t high_nibbles_a = vshrq_n_u8(input_a, 4); + const uint8x16_t high_nibbles_b = vshrq_n_u8(input_b, 4); + + const uint8x16_t first_len_a = + vqtbl1q_u8(first_len_tbl, high_nibbles_a); + const uint8x16_t first_len_b = + vqtbl1q_u8(first_len_tbl, high_nibbles_b); + + uint8x16_t range_a = vqtbl1q_u8(first_range_tbl, high_nibbles_a); + uint8x16_t range_b = vqtbl1q_u8(first_range_tbl, high_nibbles_b); + + range_a = + vorrq_u8(range_a, vextq_u8(prev_first_len, first_len_a, 15)); + range_b = + vorrq_u8(range_b, vextq_u8(first_len_a, first_len_b, 15)); + + uint8x16_t tmp1_a, tmp2_a, tmp1_b, tmp2_b; + tmp1_a = vextq_u8(prev_first_len, first_len_a, 14); + tmp1_a = vqsubq_u8(tmp1_a, const_1); + range_a = vorrq_u8(range_a, tmp1_a); + + tmp1_b = vextq_u8(first_len_a, first_len_b, 14); + tmp1_b = vqsubq_u8(tmp1_b, const_1); + range_b = vorrq_u8(range_b, tmp1_b); + + tmp2_a = vextq_u8(prev_first_len, first_len_a, 13); + tmp2_a = vqsubq_u8(tmp2_a, const_2); + range_a = vorrq_u8(range_a, tmp2_a); + + tmp2_b = vextq_u8(first_len_a, first_len_b, 13); + tmp2_b = vqsubq_u8(tmp2_b, const_2); + range_b = vorrq_u8(range_b, tmp2_b); + + uint8x16_t shift1_a = vextq_u8(prev_input, input_a, 15); + uint8x16_t pos_a = vsubq_u8(shift1_a, const_e0); + range_a = vaddq_u8(range_a, vqtbl2q_u8(range_adjust_tbl, pos_a)); + + uint8x16_t shift1_b = vextq_u8(input_a, input_b, 15); + uint8x16_t pos_b = vsubq_u8(shift1_b, const_e0); + range_b = vaddq_u8(range_b, vqtbl2q_u8(range_adjust_tbl, pos_b)); + + uint8x16_t minv_a = vqtbl1q_u8(range_min_tbl, range_a); + uint8x16_t maxv_a = vqtbl1q_u8(range_max_tbl, range_a); + + uint8x16_t minv_b = vqtbl1q_u8(range_min_tbl, range_b); + uint8x16_t maxv_b = vqtbl1q_u8(range_max_tbl, range_b); + + error1 = vorrq_u8(error1, vcltq_u8(input_a, minv_a)); + error2 = vorrq_u8(error2, vcgtq_u8(input_a, maxv_a)); + + error3 = vorrq_u8(error3, vcltq_u8(input_b, minv_b)); + error4 = vorrq_u8(error4, vcgtq_u8(input_b, maxv_b)); + + /************************ next iteration *************************/ + prev_input = input_b; + prev_first_len = first_len_b; + + data += 32; + len -= 32; + } + error1 = vorrq_u8(error1, error2); + error1 = vorrq_u8(error1, error3); + error1 = vorrq_u8(error1, error4); + + if (vmaxvq_u8(error1)) + return -1; + + uint32_t token4; + vst1q_lane_u32(&token4, vreinterpretq_u32_u8(prev_input), 3); + + const int8_t *token = (const int8_t *)&token4; + int lookahead = 0; + if (token[3] > (int8_t)0xBF) + lookahead = 1; + else if (token[2] > (int8_t)0xBF) + lookahead = 2; + else if (token[1] > (int8_t)0xBF) + lookahead = 3; + + data -= lookahead; + len += lookahead; + } + + return utf8_naive(data, len); +} + +#endif diff --git a/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-sse.c b/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-sse.c new file mode 100644 index 0000000000..f3deb86006 --- /dev/null +++ b/contrib/libs/grpc/third_party/upb/third_party/utf8_range/range2-sse.c @@ -0,0 +1,170 @@ +/* + * Process 2x16 bytes in each iteration. + * Comments removed for brevity. See range-sse.c for details. + */ +#ifdef __SSE4_1__ + +#include <stdio.h> +#include <stdint.h> +#include <x86intrin.h> + +int utf8_naive(const unsigned char *data, int len); + +static const int8_t _first_len_tbl[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, +}; + +static const int8_t _first_range_tbl[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, +}; + +static const int8_t _range_min_tbl[] = { + 0x00, 0x80, 0x80, 0x80, 0xA0, 0x80, 0x90, 0x80, + 0xC2, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, +}; +static const int8_t _range_max_tbl[] = { + 0x7F, 0xBF, 0xBF, 0xBF, 0xBF, 0x9F, 0xBF, 0x8F, + 0xF4, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, +}; + +static const int8_t _df_ee_tbl[] = { + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, +}; +static const int8_t _ef_fe_tbl[] = { + 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +/* Return 0 on success, -1 on error */ +int utf8_range2(const unsigned char *data, int len) +{ + if (len >= 32) { + __m128i prev_input = _mm_set1_epi8(0); + __m128i prev_first_len = _mm_set1_epi8(0); + + const __m128i first_len_tbl = + _mm_loadu_si128((const __m128i *)_first_len_tbl); + const __m128i first_range_tbl = + _mm_loadu_si128((const __m128i *)_first_range_tbl); + const __m128i range_min_tbl = + _mm_loadu_si128((const __m128i *)_range_min_tbl); + const __m128i range_max_tbl = + _mm_loadu_si128((const __m128i *)_range_max_tbl); + const __m128i df_ee_tbl = + _mm_loadu_si128((const __m128i *)_df_ee_tbl); + const __m128i ef_fe_tbl = + _mm_loadu_si128((const __m128i *)_ef_fe_tbl); + + __m128i error = _mm_set1_epi8(0); + + while (len >= 32) { + /***************************** block 1 ****************************/ + const __m128i input_a = _mm_loadu_si128((const __m128i *)data); + + __m128i high_nibbles = + _mm_and_si128(_mm_srli_epi16(input_a, 4), _mm_set1_epi8(0x0F)); + + __m128i first_len_a = _mm_shuffle_epi8(first_len_tbl, high_nibbles); + + __m128i range_a = _mm_shuffle_epi8(first_range_tbl, high_nibbles); + + range_a = _mm_or_si128( + range_a, _mm_alignr_epi8(first_len_a, prev_first_len, 15)); + + __m128i tmp; + tmp = _mm_alignr_epi8(first_len_a, prev_first_len, 14); + tmp = _mm_subs_epu8(tmp, _mm_set1_epi8(1)); + range_a = _mm_or_si128(range_a, tmp); + + tmp = _mm_alignr_epi8(first_len_a, prev_first_len, 13); + tmp = _mm_subs_epu8(tmp, _mm_set1_epi8(2)); + range_a = _mm_or_si128(range_a, tmp); + + __m128i shift1, pos, range2; + shift1 = _mm_alignr_epi8(input_a, prev_input, 15); + pos = _mm_sub_epi8(shift1, _mm_set1_epi8(0xEF)); + tmp = _mm_subs_epu8(pos, _mm_set1_epi8(0xF0)); + range2 = _mm_shuffle_epi8(df_ee_tbl, tmp); + tmp = _mm_adds_epu8(pos, _mm_set1_epi8(0x70)); + range2 = _mm_add_epi8(range2, _mm_shuffle_epi8(ef_fe_tbl, tmp)); + + range_a = _mm_add_epi8(range_a, range2); + + __m128i minv = _mm_shuffle_epi8(range_min_tbl, range_a); + __m128i maxv = _mm_shuffle_epi8(range_max_tbl, range_a); + + tmp = _mm_or_si128( + _mm_cmplt_epi8(input_a, minv), + _mm_cmpgt_epi8(input_a, maxv) + ); + error = _mm_or_si128(error, tmp); + + /***************************** block 2 ****************************/ + const __m128i input_b = _mm_loadu_si128((const __m128i *)(data+16)); + + high_nibbles = + _mm_and_si128(_mm_srli_epi16(input_b, 4), _mm_set1_epi8(0x0F)); + + __m128i first_len_b = _mm_shuffle_epi8(first_len_tbl, high_nibbles); + + __m128i range_b = _mm_shuffle_epi8(first_range_tbl, high_nibbles); + + range_b = _mm_or_si128( + range_b, _mm_alignr_epi8(first_len_b, first_len_a, 15)); + + + tmp = _mm_alignr_epi8(first_len_b, first_len_a, 14); + tmp = _mm_subs_epu8(tmp, _mm_set1_epi8(1)); + range_b = _mm_or_si128(range_b, tmp); + + tmp = _mm_alignr_epi8(first_len_b, first_len_a, 13); + tmp = _mm_subs_epu8(tmp, _mm_set1_epi8(2)); + range_b = _mm_or_si128(range_b, tmp); + + shift1 = _mm_alignr_epi8(input_b, input_a, 15); + pos = _mm_sub_epi8(shift1, _mm_set1_epi8(0xEF)); + tmp = _mm_subs_epu8(pos, _mm_set1_epi8(0xF0)); + range2 = _mm_shuffle_epi8(df_ee_tbl, tmp); + tmp = _mm_adds_epu8(pos, _mm_set1_epi8(0x70)); + range2 = _mm_add_epi8(range2, _mm_shuffle_epi8(ef_fe_tbl, tmp)); + + range_b = _mm_add_epi8(range_b, range2); + + minv = _mm_shuffle_epi8(range_min_tbl, range_b); + maxv = _mm_shuffle_epi8(range_max_tbl, range_b); + + + tmp = _mm_or_si128( + _mm_cmplt_epi8(input_b, minv), + _mm_cmpgt_epi8(input_b, maxv) + ); + error = _mm_or_si128(error, tmp); + + /************************ next iteration **************************/ + prev_input = input_b; + prev_first_len = first_len_b; + + data += 32; + len -= 32; + } + + if (!_mm_testz_si128(error, error)) + return -1; + + int32_t token4 = _mm_extract_epi32(prev_input, 3); + const int8_t *token = (const int8_t *)&token4; + int lookahead = 0; + if (token[3] > (int8_t)0xBF) + lookahead = 1; + else if (token[2] > (int8_t)0xBF) + lookahead = 2; + else if (token[1] > (int8_t)0xBF) + lookahead = 3; + + data -= lookahead; + len += lookahead; + } + + return utf8_naive(data, len); +} + +#endif diff --git a/contrib/libs/grpc/third_party/upb/third_party/utf8_range/utf8_range.h b/contrib/libs/grpc/third_party/upb/third_party/utf8_range/utf8_range.h new file mode 100644 index 0000000000..3695587d5e --- /dev/null +++ b/contrib/libs/grpc/third_party/upb/third_party/utf8_range/utf8_range.h @@ -0,0 +1,9 @@ + +#if (defined(__ARM_NEON) && defined(__aarch64__)) || defined(__SSE4_1__) +int utf8_range2(const unsigned char* data, int len); +#else +int utf8_naive(const unsigned char* data, int len); +static inline int utf8_range2(const unsigned char* data, int len) { + return utf8_naive(data, len); +} +#endif diff --git a/contrib/libs/grpc/third_party/upb/upb/decode.c b/contrib/libs/grpc/third_party/upb/upb/decode.c index fc074d6d52..1e07d42c32 100644 --- a/contrib/libs/grpc/third_party/upb/upb/decode.c +++ b/contrib/libs/grpc/third_party/upb/upb/decode.c @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -39,25 +39,25 @@ /* Maps descriptor type -> elem_size_lg2. */ static const uint8_t desctype_to_elem_size_lg2[] = { - -1, /* invalid descriptor type */ - 3, /* DOUBLE */ - 2, /* FLOAT */ - 3, /* INT64 */ - 3, /* UINT64 */ - 2, /* INT32 */ - 3, /* FIXED64 */ - 2, /* FIXED32 */ - 0, /* BOOL */ - UPB_SIZE(3, 4), /* STRING */ - UPB_SIZE(2, 3), /* GROUP */ - UPB_SIZE(2, 3), /* MESSAGE */ - UPB_SIZE(3, 4), /* BYTES */ - 2, /* UINT32 */ - 2, /* ENUM */ - 2, /* SFIXED32 */ - 3, /* SFIXED64 */ - 2, /* SINT32 */ - 3, /* SINT64 */ + -1, /* invalid descriptor type */ + 3, /* DOUBLE */ + 2, /* FLOAT */ + 3, /* INT64 */ + 3, /* UINT64 */ + 2, /* INT32 */ + 3, /* FIXED64 */ + 2, /* FIXED32 */ + 0, /* BOOL */ + UPB_SIZE(3, 4), /* STRING */ + UPB_SIZE(2, 3), /* GROUP */ + UPB_SIZE(2, 3), /* MESSAGE */ + UPB_SIZE(3, 4), /* BYTES */ + 2, /* UINT32 */ + 2, /* ENUM */ + 2, /* SFIXED32 */ + 3, /* SFIXED64 */ + 2, /* SINT32 */ + 3, /* SINT64 */ }; /* Maps descriptor type -> upb map size. */ @@ -72,8 +72,8 @@ static const uint8_t desctype_to_mapsize[] = { 4, /* FIXED32 */ 1, /* BOOL */ UPB_MAPTYPE_STRING, /* STRING */ - sizeof(void *), /* GROUP */ - sizeof(void *), /* MESSAGE */ + sizeof(void*), /* GROUP */ + sizeof(void*), /* MESSAGE */ UPB_MAPTYPE_STRING, /* BYTES */ 4, /* UINT32 */ 4, /* ENUM */ @@ -83,13 +83,13 @@ static const uint8_t desctype_to_mapsize[] = { 8, /* SINT64 */ }; -static const unsigned FIXED32_OK_MASK = (1 << UPB_DTYPE_FLOAT) | - (1 << UPB_DTYPE_FIXED32) | - (1 << UPB_DTYPE_SFIXED32); +static const unsigned FIXED32_OK_MASK = (1 << kUpb_FieldType_Float) | + (1 << kUpb_FieldType_Fixed32) | + (1 << kUpb_FieldType_SFixed32); -static const unsigned FIXED64_OK_MASK = (1 << UPB_DTYPE_DOUBLE) | - (1 << UPB_DTYPE_FIXED64) | - (1 << UPB_DTYPE_SFIXED64); +static const unsigned FIXED64_OK_MASK = (1 << kUpb_FieldType_Double) | + (1 << kUpb_FieldType_Fixed64) | + (1 << kUpb_FieldType_SFixed64); /* Three fake field types for MessageSet. */ #define TYPE_MSGSET_ITEM 19 @@ -97,16 +97,18 @@ static const unsigned FIXED64_OK_MASK = (1 << UPB_DTYPE_DOUBLE) | #define TYPE_COUNT 20 /* Op: an action to be performed for a wire-type/field-type combination. */ -#define OP_UNKNOWN -1 /* Unknown field. */ +#define OP_UNKNOWN -1 /* Unknown field. */ #define OP_MSGSET_ITEM -2 #define OP_MSGSET_TYPEID -3 -#define OP_SCALAR_LG2(n) (n) /* n in [0, 2, 3] => op in [0, 2, 3] */ +#define OP_SCALAR_LG2(n) (n) /* n in [0, 2, 3] => op in [0, 2, 3] */ +#define OP_ENUM 1 #define OP_STRING 4 #define OP_BYTES 5 #define OP_SUBMSG 6 -/* Ops above are scalar-only. Repeated fields can use any op. */ -#define OP_FIXPCK_LG2(n) (n + 5) /* n in [2, 3] => op in [7, 8] */ -#define OP_VARPCK_LG2(n) (n + 9) /* n in [0, 2, 3] => op in [9, 11, 12] */ +/* Scalar fields use only ops above. Repeated fields can use any op. */ +#define OP_FIXPCK_LG2(n) (n + 5) /* n in [2, 3] => op in [7, 8] */ +#define OP_VARPCK_LG2(n) (n + 9) /* n in [0, 2, 3] => op in [9, 11, 12] */ +#define OP_PACKED_ENUM 13 static const int8_t varint_ops[] = { OP_UNKNOWN, /* field not found */ @@ -123,7 +125,7 @@ static const int8_t varint_ops[] = { OP_UNKNOWN, /* MESSAGE */ OP_UNKNOWN, /* BYTES */ OP_SCALAR_LG2(2), /* UINT32 */ - OP_SCALAR_LG2(2), /* ENUM */ + OP_ENUM, /* ENUM */ OP_UNKNOWN, /* SFIXED32 */ OP_UNKNOWN, /* SFIXED64 */ OP_SCALAR_LG2(2), /* SINT32 */ @@ -134,27 +136,27 @@ static const int8_t varint_ops[] = { static const int8_t delim_ops[] = { /* For non-repeated field type. */ - OP_UNKNOWN, /* field not found */ - OP_UNKNOWN, /* DOUBLE */ - OP_UNKNOWN, /* FLOAT */ - OP_UNKNOWN, /* INT64 */ - OP_UNKNOWN, /* UINT64 */ - OP_UNKNOWN, /* INT32 */ - OP_UNKNOWN, /* FIXED64 */ - OP_UNKNOWN, /* FIXED32 */ - OP_UNKNOWN, /* BOOL */ - OP_STRING, /* STRING */ - OP_UNKNOWN, /* GROUP */ - OP_SUBMSG, /* MESSAGE */ - OP_BYTES, /* BYTES */ - OP_UNKNOWN, /* UINT32 */ - OP_UNKNOWN, /* ENUM */ - OP_UNKNOWN, /* SFIXED32 */ - OP_UNKNOWN, /* SFIXED64 */ - OP_UNKNOWN, /* SINT32 */ - OP_UNKNOWN, /* SINT64 */ - OP_UNKNOWN, /* MSGSET_ITEM */ - OP_UNKNOWN, /* MSGSET TYPEID */ + OP_UNKNOWN, /* field not found */ + OP_UNKNOWN, /* DOUBLE */ + OP_UNKNOWN, /* FLOAT */ + OP_UNKNOWN, /* INT64 */ + OP_UNKNOWN, /* UINT64 */ + OP_UNKNOWN, /* INT32 */ + OP_UNKNOWN, /* FIXED64 */ + OP_UNKNOWN, /* FIXED32 */ + OP_UNKNOWN, /* BOOL */ + OP_STRING, /* STRING */ + OP_UNKNOWN, /* GROUP */ + OP_SUBMSG, /* MESSAGE */ + OP_BYTES, /* BYTES */ + OP_UNKNOWN, /* UINT32 */ + OP_UNKNOWN, /* ENUM */ + OP_UNKNOWN, /* SFIXED32 */ + OP_UNKNOWN, /* SFIXED64 */ + OP_UNKNOWN, /* SINT32 */ + OP_UNKNOWN, /* SINT64 */ + OP_UNKNOWN, /* MSGSET_ITEM */ + OP_UNKNOWN, /* MSGSET TYPEID */ /* For repeated field type. */ OP_FIXPCK_LG2(3), /* REPEATED DOUBLE */ OP_FIXPCK_LG2(2), /* REPEATED FLOAT */ @@ -169,7 +171,7 @@ static const int8_t delim_ops[] = { OP_SUBMSG, /* REPEATED MESSAGE */ OP_BYTES, /* REPEATED BYTES */ OP_VARPCK_LG2(2), /* REPEATED UINT32 */ - OP_VARPCK_LG2(2), /* REPEATED ENUM */ + OP_PACKED_ENUM, /* REPEATED ENUM */ OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */ OP_FIXPCK_LG2(3), /* REPEATED SFIXED64 */ OP_VARPCK_LG2(2), /* REPEATED SINT32 */ @@ -184,63 +186,39 @@ typedef union { uint32_t size; } wireval; -static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, - const upb_msglayout *layout); +static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg, + const upb_MiniTable* layout); -UPB_NORETURN static const char *decode_err(upb_decstate *d) { - UPB_LONGJMP(d->err, 1); +UPB_NORETURN static void* decode_err(upb_Decoder* d, upb_DecodeStatus status) { + assert(status != kUpb_DecodeStatus_Ok); + UPB_LONGJMP(d->err, status); } -// We don't want to mark this NORETURN, see comment in .h. -// Unfortunately this code to suppress the warning doesn't appear to be working. -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunknown-warning-option" -#pragma clang diagnostic ignored "-Wsuggest-attribute" -#endif - -const char *fastdecode_err(upb_decstate *d) { - longjmp(d->err, 1); +const char* fastdecode_err(upb_Decoder* d, int status) { + assert(status != kUpb_DecodeStatus_Ok); + UPB_LONGJMP(d->err, status); return NULL; } - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -const uint8_t upb_utf8_offsets[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static void decode_verifyutf8(upb_decstate *d, const char *buf, int len) { - if (!decode_verifyutf8_inl(buf, len)) decode_err(d); +static void decode_verifyutf8(upb_Decoder* d, const char* buf, int len) { + if (!decode_verifyutf8_inl(buf, len)) + decode_err(d, kUpb_DecodeStatus_BadUtf8); } -static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) { +static bool decode_reserve(upb_Decoder* d, upb_Array* arr, size_t elem) { bool need_realloc = arr->size - arr->len < elem; if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, &d->arena)) { - decode_err(d); + decode_err(d, kUpb_DecodeStatus_OutOfMemory); } return need_realloc; } typedef struct { - const char *ptr; + const char* ptr; uint64_t val; } decode_vret; UPB_NOINLINE -static decode_vret decode_longvarint64(const char *ptr, uint64_t val) { +static decode_vret decode_longvarint64(const char* ptr, uint64_t val) { decode_vret ret = {NULL, 0}; uint64_t byte; int i; @@ -257,85 +235,92 @@ static decode_vret decode_longvarint64(const char *ptr, uint64_t val) { } UPB_FORCEINLINE -static const char *decode_varint64(upb_decstate *d, const char *ptr, - uint64_t *val) { +static const char* decode_varint64(upb_Decoder* d, const char* ptr, + uint64_t* val) { uint64_t byte = (uint8_t)*ptr; if (UPB_LIKELY((byte & 0x80) == 0)) { *val = byte; return ptr + 1; } else { decode_vret res = decode_longvarint64(ptr, byte); - if (!res.ptr) return decode_err(d); + if (!res.ptr) return decode_err(d, kUpb_DecodeStatus_Malformed); *val = res.val; return res.ptr; } } UPB_FORCEINLINE -static const char *decode_tag(upb_decstate *d, const char *ptr, - uint32_t *val) { +static const char* decode_tag(upb_Decoder* d, const char* ptr, uint32_t* val) { uint64_t byte = (uint8_t)*ptr; if (UPB_LIKELY((byte & 0x80) == 0)) { *val = byte; return ptr + 1; } else { - const char *start = ptr; + const char* start = ptr; decode_vret res = decode_longvarint64(ptr, byte); - ptr = res.ptr; + if (!res.ptr || res.ptr - start > 5 || res.val > UINT32_MAX) { + return decode_err(d, kUpb_DecodeStatus_Malformed); + } *val = res.val; - if (!ptr || *val > UINT32_MAX || ptr - start > 5) return decode_err(d); - return ptr; + return res.ptr; } } -static void decode_munge(int type, wireval *val) { +static void decode_munge_int32(wireval* val) { + if (!_upb_IsLittleEndian()) { + /* The next stage will memcpy(dst, &val, 4) */ + val->uint32_val = val->uint64_val; + } +} + +static void decode_munge(int type, wireval* val) { switch (type) { - case UPB_DESCRIPTOR_TYPE_BOOL: + case kUpb_FieldType_Bool: val->bool_val = val->uint64_val != 0; break; - case UPB_DESCRIPTOR_TYPE_SINT32: { - uint32_t n = val->uint32_val; + case kUpb_FieldType_SInt32: { + uint32_t n = val->uint64_val; val->uint32_val = (n >> 1) ^ -(int32_t)(n & 1); break; } - case UPB_DESCRIPTOR_TYPE_SINT64: { + case kUpb_FieldType_SInt64: { uint64_t n = val->uint64_val; val->uint64_val = (n >> 1) ^ -(int64_t)(n & 1); break; } - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_UINT32: - if (!_upb_isle()) { - /* The next stage will memcpy(dst, &val, 4) */ - val->uint32_val = val->uint64_val; - } + case kUpb_FieldType_Int32: + case kUpb_FieldType_UInt32: + case kUpb_FieldType_Enum: + decode_munge_int32(val); break; } } -static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout_sub *subs, - const upb_msglayout_field *field) { - const upb_msglayout *subl = subs[field->submsg_index].submsg; - return _upb_msg_new_inl(subl, &d->arena); +static upb_Message* decode_newsubmsg(upb_Decoder* d, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field) { + const upb_MiniTable* subl = subs[field->submsg_index].submsg; + return _upb_Message_New_inl(subl, &d->arena); } UPB_NOINLINE -const char *decode_isdonefallback(upb_decstate *d, const char *ptr, +const char* decode_isdonefallback(upb_Decoder* d, const char* ptr, int overrun) { - ptr = decode_isdonefallback_inl(d, ptr, overrun); + int status; + ptr = decode_isdonefallback_inl(d, ptr, overrun, &status); if (ptr == NULL) { - return decode_err(d); + return decode_err(d, status); } return ptr; } -static const char *decode_readstr(upb_decstate *d, const char *ptr, int size, - upb_strview *str) { - if (d->alias) { +static const char* decode_readstr(upb_Decoder* d, const char* ptr, int size, + upb_StringView* str) { + if (d->options & kUpb_DecodeOption_AliasString) { str->data = ptr; } else { - char *data = upb_arena_malloc(&d->arena, size); - if (!data) return decode_err(d); + char* data = upb_Arena_Malloc(&d->arena, size); + if (!data) return decode_err(d, kUpb_DecodeStatus_OutOfMemory); memcpy(data, ptr, size); str->data = data; } @@ -344,61 +329,222 @@ static const char *decode_readstr(upb_decstate *d, const char *ptr, int size, } UPB_FORCEINLINE -static const char *decode_tosubmsg(upb_decstate *d, const char *ptr, - upb_msg *submsg, - const upb_msglayout_sub *subs, - const upb_msglayout_field *field, int size) { - const upb_msglayout *subl = subs[field->submsg_index].submsg; +static const char* decode_tosubmsg2(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTable* subl, int size) { int saved_delta = decode_pushlimit(d, ptr, size); - if (--d->depth < 0) return decode_err(d); - if (!decode_isdone(d, &ptr)) { - ptr = decode_msg(d, ptr, submsg, subl); - } - if (d->end_group != DECODE_NOGROUP) return decode_err(d); + if (--d->depth < 0) return decode_err(d, kUpb_DecodeStatus_MaxDepthExceeded); + ptr = decode_msg(d, ptr, submsg, subl); + if (d->end_group != DECODE_NOGROUP) + return decode_err(d, kUpb_DecodeStatus_Malformed); decode_poplimit(d, ptr, saved_delta); d->depth++; return ptr; } UPB_FORCEINLINE -static const char *decode_group(upb_decstate *d, const char *ptr, - upb_msg *submsg, const upb_msglayout *subl, +static const char* decode_tosubmsg(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field, int size) { + return decode_tosubmsg2(d, ptr, submsg, subs[field->submsg_index].submsg, + size); +} + +UPB_FORCEINLINE +static const char* decode_group(upb_Decoder* d, const char* ptr, + upb_Message* submsg, const upb_MiniTable* subl, uint32_t number) { - if (--d->depth < 0) return decode_err(d); + if (--d->depth < 0) return decode_err(d, kUpb_DecodeStatus_MaxDepthExceeded); if (decode_isdone(d, &ptr)) { - return decode_err(d); + return decode_err(d, kUpb_DecodeStatus_Malformed); } ptr = decode_msg(d, ptr, submsg, subl); - if (d->end_group != number) return decode_err(d); + if (d->end_group != number) return decode_err(d, kUpb_DecodeStatus_Malformed); d->end_group = DECODE_NOGROUP; d->depth++; return ptr; } UPB_FORCEINLINE -static const char *decode_togroup(upb_decstate *d, const char *ptr, - upb_msg *submsg, - const upb_msglayout_sub *subs, - const upb_msglayout_field *field) { - const upb_msglayout *subl = subs[field->submsg_index].submsg; +static const char* decode_togroup(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field) { + const upb_MiniTable* subl = subs[field->submsg_index].submsg; return decode_group(d, ptr, submsg, subl, field->number); } -static const char *decode_toarray(upb_decstate *d, const char *ptr, - upb_msg *msg, - const upb_msglayout_sub *subs, - const upb_msglayout_field *field, wireval *val, - int op) { - upb_array **arrp = UPB_PTR_AT(msg, field->offset, void); - upb_array *arr = *arrp; - void *mem; +static char* encode_varint32(uint32_t val, char* ptr) { + do { + uint8_t byte = val & 0x7fU; + val >>= 7; + if (val) byte |= 0x80U; + *(ptr++) = byte; + } while (val); + return ptr; +} + +UPB_NOINLINE +static bool decode_checkenum_slow(upb_Decoder* d, const char* ptr, + upb_Message* msg, const upb_MiniTable_Enum* e, + const upb_MiniTable_Field* field, + uint32_t v) { + // OPT: binary search long lists? + int n = e->value_count; + for (int i = 0; i < n; i++) { + if ((uint32_t)e->values[i] == v) return true; + } + + // Unrecognized enum goes into unknown fields. + // For packed fields the tag could be arbitrarily far in the past, so we + // just re-encode the tag here. + char buf[20]; + char* end = buf; + uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint; + end = encode_varint32(tag, end); + end = encode_varint32(v, end); + + if (!_upb_Message_AddUnknown(msg, buf, end - buf, &d->arena)) { + decode_err(d, kUpb_DecodeStatus_OutOfMemory); + } + + return false; +} + +UPB_FORCEINLINE +static bool decode_checkenum(upb_Decoder* d, const char* ptr, upb_Message* msg, + const upb_MiniTable_Enum* e, + const upb_MiniTable_Field* field, wireval* val) { + uint32_t v = val->uint32_val; + + if (UPB_LIKELY(v < 64) && UPB_LIKELY(((1ULL << v) & e->mask))) return true; + + return decode_checkenum_slow(d, ptr, msg, e, field, v); +} + +UPB_NOINLINE +static const char* decode_enum_toarray(upb_Decoder* d, const char* ptr, + upb_Message* msg, upb_Array* arr, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field, + wireval* val) { + const upb_MiniTable_Enum* e = subs[field->submsg_index].subenum; + if (!decode_checkenum(d, ptr, msg, e, field, val)) return ptr; + void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void); + arr->len++; + memcpy(mem, val, 4); + return ptr; +} + +UPB_FORCEINLINE +static const char* decode_fixed_packed(upb_Decoder* d, const char* ptr, + upb_Array* arr, wireval* val, + const upb_MiniTable_Field* field, + int lg2) { + int mask = (1 << lg2) - 1; + size_t count = val->size >> lg2; + if ((val->size & mask) != 0) { + // Length isn't a round multiple of elem size. + return decode_err(d, kUpb_DecodeStatus_Malformed); + } + decode_reserve(d, arr, count); + void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + arr->len += count; + // Note: if/when the decoder supports multi-buffer input, we will need to + // handle buffer seams here. + if (_upb_IsLittleEndian()) { + memcpy(mem, ptr, val->size); + ptr += val->size; + } else { + const char* end = ptr + val->size; + char* dst = mem; + while (ptr < end) { + if (lg2 == 2) { + uint32_t val; + memcpy(&val, ptr, sizeof(val)); + val = _upb_BigEndian_Swap32(val); + memcpy(dst, &val, sizeof(val)); + } else { + UPB_ASSERT(lg2 == 3); + uint64_t val; + memcpy(&val, ptr, sizeof(val)); + val = _upb_BigEndian_Swap64(val); + memcpy(dst, &val, sizeof(val)); + } + ptr += 1 << lg2; + dst += 1 << lg2; + } + } + + return ptr; +} + +UPB_FORCEINLINE +static const char* decode_varint_packed(upb_Decoder* d, const char* ptr, + upb_Array* arr, wireval* val, + const upb_MiniTable_Field* field, + int lg2) { + int scale = 1 << lg2; + int saved_limit = decode_pushlimit(d, ptr, val->size); + char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + while (!decode_isdone(d, &ptr)) { + wireval elem; + ptr = decode_varint64(d, ptr, &elem.uint64_val); + decode_munge(field->descriptortype, &elem); + if (decode_reserve(d, arr, 1)) { + out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + } + arr->len++; + memcpy(out, &elem, scale); + out += scale; + } + decode_poplimit(d, ptr, saved_limit); + return ptr; +} + +UPB_NOINLINE +static const char* decode_enum_packed(upb_Decoder* d, const char* ptr, + upb_Message* msg, upb_Array* arr, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field, + wireval* val) { + const upb_MiniTable_Enum* e = subs[field->submsg_index].subenum; + int saved_limit = decode_pushlimit(d, ptr, val->size); + char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void); + while (!decode_isdone(d, &ptr)) { + wireval elem; + ptr = decode_varint64(d, ptr, &elem.uint64_val); + decode_munge_int32(&elem); + if (!decode_checkenum(d, ptr, msg, e, field, &elem)) { + continue; + } + if (decode_reserve(d, arr, 1)) { + out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void); + } + arr->len++; + memcpy(out, &elem, 4); + out += 4; + } + decode_poplimit(d, ptr, saved_limit); + return ptr; +} + +static const char* decode_toarray(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field, + wireval* val, int op) { + upb_Array** arrp = UPB_PTR_AT(msg, field->offset, void); + upb_Array* arr = *arrp; + void* mem; if (arr) { decode_reserve(d, arr, 1); } else { size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype]; - arr = _upb_array_new(&d->arena, 4, lg2); - if (!arr) return decode_err(d); + arr = _upb_Array_New(&d->arena, 4, lg2); + if (!arr) return decode_err(d, kUpb_DecodeStatus_OutOfMemory); *arrp = arr; } @@ -416,112 +562,95 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr, /* Fallthrough. */ case OP_BYTES: { /* Append bytes. */ - upb_strview *str = (upb_strview*)_upb_array_ptr(arr) + arr->len; + upb_StringView* str = (upb_StringView*)_upb_array_ptr(arr) + arr->len; arr->len++; return decode_readstr(d, ptr, val->size, str); } case OP_SUBMSG: { /* Append submessage / group. */ - upb_msg *submsg = decode_newsubmsg(d, subs, field); - *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) = + upb_Message* submsg = decode_newsubmsg(d, subs, field); + *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void*), upb_Message*) = submsg; arr->len++; - if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) { + if (UPB_UNLIKELY(field->descriptortype == kUpb_FieldType_Group)) { return decode_togroup(d, ptr, submsg, subs, field); } else { return decode_tosubmsg(d, ptr, submsg, subs, field, val->size); } } case OP_FIXPCK_LG2(2): - case OP_FIXPCK_LG2(3): { - /* Fixed packed. */ - int lg2 = op - OP_FIXPCK_LG2(0); - int mask = (1 << lg2) - 1; - size_t count = val->size >> lg2; - if ((val->size & mask) != 0) { - return decode_err(d); /* Length isn't a round multiple of elem size. */ - } - decode_reserve(d, arr, count); - mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); - arr->len += count; - memcpy(mem, ptr, val->size); /* XXX: ptr boundary. */ - return ptr + val->size; - } + case OP_FIXPCK_LG2(3): + return decode_fixed_packed(d, ptr, arr, val, field, + op - OP_FIXPCK_LG2(0)); case OP_VARPCK_LG2(0): case OP_VARPCK_LG2(2): - case OP_VARPCK_LG2(3): { - /* Varint packed. */ - int lg2 = op - OP_VARPCK_LG2(0); - int scale = 1 << lg2; - int saved_limit = decode_pushlimit(d, ptr, val->size); - char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); - while (!decode_isdone(d, &ptr)) { - wireval elem; - ptr = decode_varint64(d, ptr, &elem.uint64_val); - decode_munge(field->descriptortype, &elem); - if (decode_reserve(d, arr, 1)) { - out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); - } - arr->len++; - memcpy(out, &elem, scale); - out += scale; - } - decode_poplimit(d, ptr, saved_limit); - return ptr; - } + case OP_VARPCK_LG2(3): + return decode_varint_packed(d, ptr, arr, val, field, + op - OP_VARPCK_LG2(0)); + case OP_ENUM: + return decode_enum_toarray(d, ptr, msg, arr, subs, field, val); + case OP_PACKED_ENUM: + return decode_enum_packed(d, ptr, msg, arr, subs, field, val); default: UPB_UNREACHABLE(); } } -static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg, - const upb_msglayout_sub *subs, - const upb_msglayout_field *field, - wireval *val) { - upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *); - upb_map *map = *map_p; - upb_map_entry ent; - const upb_msglayout *entry = subs[field->submsg_index].submsg; +static const char* decode_tomap(upb_Decoder* d, const char* ptr, + upb_Message* msg, const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field, + wireval* val) { + upb_Map** map_p = UPB_PTR_AT(msg, field->offset, upb_Map*); + upb_Map* map = *map_p; + upb_MapEntry ent; + const upb_MiniTable* entry = subs[field->submsg_index].submsg; if (!map) { /* Lazily create map. */ - const upb_msglayout_field *key_field = &entry->fields[0]; - const upb_msglayout_field *val_field = &entry->fields[1]; + const upb_MiniTable_Field* key_field = &entry->fields[0]; + const upb_MiniTable_Field* val_field = &entry->fields[1]; char key_size = desctype_to_mapsize[key_field->descriptortype]; char val_size = desctype_to_mapsize[val_field->descriptortype]; UPB_ASSERT(key_field->offset == 0); - UPB_ASSERT(val_field->offset == sizeof(upb_strview)); - map = _upb_map_new(&d->arena, key_size, val_size); + UPB_ASSERT(val_field->offset == sizeof(upb_StringView)); + map = _upb_Map_New(&d->arena, key_size, val_size); *map_p = map; } /* Parse map entry. */ memset(&ent, 0, sizeof(ent)); - if (entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE || - entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_GROUP) { + if (entry->fields[1].descriptortype == kUpb_FieldType_Message || + entry->fields[1].descriptortype == kUpb_FieldType_Group) { /* Create proactively to handle the case where it doesn't appear. */ - ent.v.val = upb_value_ptr(_upb_msg_new(entry->subs[0].submsg, &d->arena)); + ent.v.val = + upb_value_ptr(_upb_Message_New(entry->subs[0].submsg, &d->arena)); } ptr = decode_tosubmsg(d, ptr, &ent.k, subs, field, val->size); - _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, &d->arena); + _upb_Map_Set(map, &ent.k, map->key_size, &ent.v, map->val_size, &d->arena); return ptr; } -static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, - const upb_msglayout_sub *subs, - const upb_msglayout_field *field, wireval *val, +static const char* decode_tomsg(upb_Decoder* d, const char* ptr, + upb_Message* msg, const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field, wireval* val, int op) { - void *mem = UPB_PTR_AT(msg, field->offset, void); + void* mem = UPB_PTR_AT(msg, field->offset, void); int type = field->descriptortype; + if (UPB_UNLIKELY(op == OP_ENUM) && + !decode_checkenum(d, ptr, msg, subs[field->submsg_index].subenum, field, + val)) { + return ptr; + } + /* Set presence if necessary. */ if (field->presence > 0) { _upb_sethas_field(msg, field); } else if (field->presence < 0) { /* Oneof case */ - uint32_t *oneof_case = _upb_oneofcase_field(msg, field); + uint32_t* oneof_case = _upb_oneofcase_field(msg, field); if (op == OP_SUBMSG && *oneof_case != field->number) { memset(mem, 0, sizeof(void*)); } @@ -531,13 +660,13 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, /* Store into message. */ switch (op) { case OP_SUBMSG: { - upb_msg **submsgp = mem; - upb_msg *submsg = *submsgp; + upb_Message** submsgp = mem; + upb_Message* submsg = *submsgp; if (!submsg) { submsg = decode_newsubmsg(d, subs, field); *submsgp = submsg; } - if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) { + if (UPB_UNLIKELY(type == kUpb_FieldType_Group)) { ptr = decode_togroup(d, ptr, submsg, subs, field); } else { ptr = decode_tosubmsg(d, ptr, submsg, subs, field, val->size); @@ -552,6 +681,7 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, case OP_SCALAR_LG2(3): memcpy(mem, val, 8); break; + case OP_ENUM: case OP_SCALAR_LG2(2): memcpy(mem, val, 4); break; @@ -565,9 +695,27 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, return ptr; } +UPB_NOINLINE +const char* decode_checkrequired(upb_Decoder* d, const char* ptr, + const upb_Message* msg, + const upb_MiniTable* l) { + assert(l->required_count); + if (UPB_LIKELY((d->options & kUpb_DecodeOption_CheckRequired) == 0)) { + return ptr; + } + uint64_t msg_head; + memcpy(&msg_head, msg, 8); + msg_head = _upb_BigEndian_Swap64(msg_head); + if (upb_MiniTable_requiredmask(l) & ~msg_head) { + d->missing_required = true; + } + return ptr; +} + UPB_FORCEINLINE -static bool decode_tryfastdispatch(upb_decstate *d, const char **ptr, - upb_msg *msg, const upb_msglayout *layout) { +static bool decode_tryfastdispatch(upb_Decoder* d, const char** ptr, + upb_Message* msg, + const upb_MiniTable* layout) { #if UPB_FASTTABLE if (layout && layout->table_mask != (unsigned char)-1) { uint16_t tag = fastdecode_loadtag(*ptr); @@ -579,30 +727,32 @@ static bool decode_tryfastdispatch(upb_decstate *d, const char **ptr, return false; } -static const char *decode_msgset(upb_decstate *d, const char *ptr, upb_msg *msg, - const upb_msglayout *layout) { - // We create a temporary upb_msglayout here and abuse its fields as temporary +static const char* decode_msgset(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTable* layout) { + // We create a temporary upb_MiniTable here and abuse its fields as temporary // storage, to avoid creating lots of MessageSet-specific parsing code-paths: // 1. We store 'layout' in item_layout.subs. We will need this later as // a key to look up extensions for this MessageSet. - // 2. We use item_layout.fields as temporary storage to store the extension we + // 2. We use item_layout.fields as temporary storage to store the extension + // we // found when parsing the type id. - upb_msglayout item_layout = { - .subs = (const upb_msglayout_sub[]){{.submsg = layout}}, + upb_MiniTable item_layout = { + .subs = (const upb_MiniTable_Sub[]){{.submsg = layout}}, .fields = NULL, .size = 0, .field_count = 0, - .ext = _UPB_MSGEXT_MSGSET_ITEM, + .ext = upb_ExtMode_IsMessageSet_ITEM, .dense_below = 0, .table_mask = -1}; return decode_group(d, ptr, msg, &item_layout, 1); } -static const upb_msglayout_field *decode_findfield(upb_decstate *d, - const upb_msglayout *l, +static const upb_MiniTable_Field* decode_findfield(upb_Decoder* d, + const upb_MiniTable* l, uint32_t field_number, - int *last_field_index) { - static upb_msglayout_field none = {0, 0, 0, 0, 0, 0}; + int* last_field_index) { + static upb_MiniTable_Field none = {0, 0, 0, 0, 0, 0}; if (l == NULL) return &none; size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX @@ -630,22 +780,22 @@ static const upb_msglayout_field *decode_findfield(upb_decstate *d, if (d->extreg) { switch (l->ext) { - case _UPB_MSGEXT_EXTENDABLE: { - const upb_msglayout_ext *ext = + case upb_ExtMode_Extendable: { + const upb_MiniTable_Extension* ext = _upb_extreg_get(d->extreg, l, field_number); if (ext) return &ext->field; break; } - case _UPB_MSGEXT_MSGSET: + case upb_ExtMode_IsMessageSet: if (field_number == _UPB_MSGSET_ITEM) { - static upb_msglayout_field item = {0, 0, 0, 0, TYPE_MSGSET_ITEM, 0}; + static upb_MiniTable_Field item = {0, 0, 0, 0, TYPE_MSGSET_ITEM, 0}; return &item; } break; - case _UPB_MSGEXT_MSGSET_ITEM: + case upb_ExtMode_IsMessageSet_ITEM: switch (field_number) { case _UPB_MSGSET_TYPEID: { - static upb_msglayout_field type_id = { + static upb_MiniTable_Field type_id = { 0, 0, 0, 0, TYPE_MSGSET_TYPE_ID, 0}; return &type_id; } @@ -667,42 +817,42 @@ static const upb_msglayout_field *decode_findfield(upb_decstate *d, return &none; /* Unknown field. */ - found: +found: UPB_ASSERT(l->fields[idx].number == field_number); *last_field_index = idx; return &l->fields[idx]; - } +} UPB_FORCEINLINE -static const char *decode_wireval(upb_decstate *d, const char *ptr, - const upb_msglayout_field *field, - int wire_type, wireval *val, int *op) { +static const char* decode_wireval(upb_Decoder* d, const char* ptr, + const upb_MiniTable_Field* field, + int wire_type, wireval* val, int* op) { switch (wire_type) { - case UPB_WIRE_TYPE_VARINT: + case kUpb_WireType_Varint: ptr = decode_varint64(d, ptr, &val->uint64_val); *op = varint_ops[field->descriptortype]; decode_munge(field->descriptortype, val); return ptr; - case UPB_WIRE_TYPE_32BIT: + case kUpb_WireType_32Bit: memcpy(&val->uint32_val, ptr, 4); - val->uint32_val = _upb_be_swap32(val->uint32_val); + val->uint32_val = _upb_BigEndian_Swap32(val->uint32_val); *op = OP_SCALAR_LG2(2); if (((1 << field->descriptortype) & FIXED32_OK_MASK) == 0) { *op = OP_UNKNOWN; } return ptr + 4; - case UPB_WIRE_TYPE_64BIT: + case kUpb_WireType_64Bit: memcpy(&val->uint64_val, ptr, 8); - val->uint64_val = _upb_be_swap64(val->uint64_val); + val->uint64_val = _upb_BigEndian_Swap64(val->uint64_val); *op = OP_SCALAR_LG2(3); if (((1 << field->descriptortype) & FIXED64_OK_MASK) == 0) { *op = OP_UNKNOWN; } return ptr + 8; - case UPB_WIRE_TYPE_DELIMITED: { + case kUpb_WireType_Delimited: { int ndx = field->descriptortype; uint64_t size; - if (_upb_getmode(field) == _UPB_MODE_ARRAY) ndx += TYPE_COUNT; + if (upb_FieldMode_Get(field) == kUpb_FieldMode_Array) ndx += TYPE_COUNT; ptr = decode_varint64(d, ptr, &size); if (size >= INT32_MAX || ptr - d->end + (int32_t)size > d->limit) { break; /* Length overflow. */ @@ -711,9 +861,9 @@ static const char *decode_wireval(upb_decstate *d, const char *ptr, val->size = size; return ptr; } - case UPB_WIRE_TYPE_START_GROUP: + case kUpb_WireType_StartGroup: val->uint32_val = field->number; - if (field->descriptortype == UPB_DTYPE_GROUP) { + if (field->descriptortype == kUpb_FieldType_Group) { *op = OP_SUBMSG; } else if (field->descriptortype == TYPE_MSGSET_ITEM) { *op = OP_MSGSET_ITEM; @@ -724,87 +874,144 @@ static const char *decode_wireval(upb_decstate *d, const char *ptr, default: break; } - return decode_err(d); + return decode_err(d, kUpb_DecodeStatus_Malformed); } UPB_FORCEINLINE -static const char *decode_known(upb_decstate *d, const char *ptr, upb_msg *msg, - const upb_msglayout *layout, - const upb_msglayout_field *field, int op, - wireval *val) { - const upb_msglayout_sub *subs = layout->subs; +static const char* decode_known(upb_Decoder* d, const char* ptr, + upb_Message* msg, const upb_MiniTable* layout, + const upb_MiniTable_Field* field, int op, + wireval* val) { + const upb_MiniTable_Sub* subs = layout->subs; uint8_t mode = field->mode; - if (UPB_UNLIKELY(mode & _UPB_MODE_IS_EXTENSION)) { - const upb_msglayout_ext *ext_layout = (const upb_msglayout_ext*)field; - upb_msg_ext *ext = _upb_msg_getorcreateext(msg, ext_layout, &d->arena); - if (UPB_UNLIKELY(!ext)) return decode_err(d); + if (UPB_UNLIKELY(mode & upb_LabelFlags_IsExtension)) { + const upb_MiniTable_Extension* ext_layout = + (const upb_MiniTable_Extension*)field; + upb_Message_Extension* ext = + _upb_Message_Getorcreateext(msg, ext_layout, &d->arena); + if (UPB_UNLIKELY(!ext)) return decode_err(d, kUpb_DecodeStatus_OutOfMemory); msg = &ext->data; subs = &ext->ext->sub; } - switch (mode & _UPB_MODE_MASK) { - case _UPB_MODE_ARRAY: + switch (mode & kUpb_FieldMode_Mask) { + case kUpb_FieldMode_Array: return decode_toarray(d, ptr, msg, subs, field, val, op); - case _UPB_MODE_MAP: + case kUpb_FieldMode_Map: return decode_tomap(d, ptr, msg, subs, field, val); - case _UPB_MODE_SCALAR: + case kUpb_FieldMode_Scalar: return decode_tomsg(d, ptr, msg, subs, field, val, op); default: UPB_UNREACHABLE(); } } -UPB_FORCEINLINE -static const char *decode_unknown(upb_decstate *d, const char *ptr, - upb_msg *msg, int field_number, int wire_type, - wireval val, const char **field_start) { - if (field_number == 0) return decode_err(d); +static const char* decode_reverse_skip_varint(const char* ptr, uint32_t val) { + uint32_t seen = 0; + do { + ptr--; + seen <<= 7; + seen |= *ptr & 0x7f; + } while (seen != val); + return ptr; +} + +static const char* decode_unknown(upb_Decoder* d, const char* ptr, + upb_Message* msg, int field_number, + int wire_type, wireval val) { + if (field_number == 0) return decode_err(d, kUpb_DecodeStatus_Malformed); - if (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size; + // Since unknown fields are the uncommon case, we do a little extra work here + // to walk backwards through the buffer to find the field start. This frees + // up a register in the fast paths (when the field is known), which leads to + // significant speedups in benchmarks. + const char* start = ptr; + + if (wire_type == kUpb_WireType_Delimited) ptr += val.size; if (msg) { - if (wire_type == UPB_WIRE_TYPE_START_GROUP) { - d->unknown = *field_start; + switch (wire_type) { + case kUpb_WireType_Varint: + case kUpb_WireType_Delimited: + start--; + while (start[-1] & 0x80) start--; + break; + case kUpb_WireType_32Bit: + start -= 4; + break; + case kUpb_WireType_64Bit: + start -= 8; + break; + default: + break; + } + + assert(start == d->debug_valstart); + uint32_t tag = ((uint32_t)field_number << 3) | wire_type; + start = decode_reverse_skip_varint(start, tag); + assert(start == d->debug_tagstart); + + if (wire_type == kUpb_WireType_StartGroup) { + d->unknown = start; d->unknown_msg = msg; ptr = decode_group(d, ptr, NULL, NULL, field_number); + start = d->unknown; d->unknown_msg = NULL; - *field_start = d->unknown; + d->unknown = NULL; } - if (!_upb_msg_addunknown(msg, *field_start, ptr - *field_start, - &d->arena)) { - return decode_err(d); + if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) { + return decode_err(d, kUpb_DecodeStatus_OutOfMemory); } - } else if (wire_type == UPB_WIRE_TYPE_START_GROUP) { + } else if (wire_type == kUpb_WireType_StartGroup) { ptr = decode_group(d, ptr, NULL, NULL, field_number); } return ptr; } UPB_NOINLINE -static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, - const upb_msglayout *layout) { +static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg, + const upb_MiniTable* layout) { int last_field_index = 0; - while (true) { + +#if UPB_FASTTABLE + // The first time we want to skip fast dispatch, because we may have just been + // invoked by the fast parser to handle a case that it bailed on. + if (!decode_isdone(d, &ptr)) goto nofast; +#endif + + while (!decode_isdone(d, &ptr)) { uint32_t tag; - const upb_msglayout_field *field; + const upb_MiniTable_Field* field; int field_number; int wire_type; - const char *field_start = ptr; wireval val; int op; + if (decode_tryfastdispatch(d, &ptr, msg, layout)) break; + +#if UPB_FASTTABLE + nofast: +#endif + +#ifndef NDEBUG + d->debug_tagstart = ptr; +#endif + UPB_ASSERT(ptr < d->limit_ptr); ptr = decode_tag(d, ptr, &tag); field_number = tag >> 3; wire_type = tag & 7; - field = decode_findfield(d, layout, field_number, &last_field_index); +#ifndef NDEBUG + d->debug_valstart = ptr; +#endif - if (wire_type == UPB_WIRE_TYPE_END_GROUP) { + if (wire_type == kUpb_WireType_EndGroup) { d->end_group = field_number; return ptr; } + field = decode_findfield(d, layout, field_number, &last_field_index); ptr = decode_wireval(d, ptr, field, wire_type, &val, &op); if (op >= 0) { @@ -812,62 +1019,61 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, } else { switch (op) { case OP_UNKNOWN: - ptr = decode_unknown(d, ptr, msg, field_number, wire_type, val, - &field_start); + ptr = decode_unknown(d, ptr, msg, field_number, wire_type, val); break; case OP_MSGSET_ITEM: ptr = decode_msgset(d, ptr, msg, layout); break; case OP_MSGSET_TYPEID: { - const upb_msglayout_ext *ext = _upb_extreg_get( + const upb_MiniTable_Extension* ext = _upb_extreg_get( d->extreg, layout->subs[0].submsg, val.uint64_val); - if (ext) ((upb_msglayout *)layout)->fields = &ext->field; + if (ext) ((upb_MiniTable*)layout)->fields = &ext->field; break; } } } - - if (decode_isdone(d, &ptr)) return ptr; - if (decode_tryfastdispatch(d, &ptr, msg, layout)) return ptr; } + + return UPB_UNLIKELY(layout && layout->required_count) + ? decode_checkrequired(d, ptr, msg, layout) + : ptr; } -const char *fastdecode_generic(struct upb_decstate *d, const char *ptr, - upb_msg *msg, intptr_t table, uint64_t hasbits, - uint64_t data) { +const char* fastdecode_generic(struct upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data) { (void)data; *(uint32_t*)msg |= hasbits; return decode_msg(d, ptr, msg, decode_totablep(table)); } -static bool decode_top(struct upb_decstate *d, const char *buf, void *msg, - const upb_msglayout *l) { +static upb_DecodeStatus decode_top(struct upb_Decoder* d, const char* buf, + void* msg, const upb_MiniTable* l) { if (!decode_tryfastdispatch(d, &buf, msg, l)) { decode_msg(d, buf, msg, l); } - return d->end_group == DECODE_NOGROUP; + if (d->end_group != DECODE_NOGROUP) return kUpb_DecodeStatus_Malformed; + if (d->missing_required) return kUpb_DecodeStatus_MissingRequired; + return kUpb_DecodeStatus_Ok; } -bool _upb_decode(const char *buf, size_t size, void *msg, - const upb_msglayout *l, const upb_extreg *extreg, int options, - upb_arena *arena) { - bool ok; - upb_decstate state; +upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg, + const upb_MiniTable* l, + const upb_ExtensionRegistry* extreg, int options, + upb_Arena* arena) { + upb_Decoder state; unsigned depth = (unsigned)options >> 16; - if (size == 0) { - return true; - } else if (size <= 16) { + if (size <= 16) { memset(&state.patch, 0, 32); - memcpy(&state.patch, buf, size); + if (size) memcpy(&state.patch, buf, size); buf = state.patch; state.end = buf + size; state.limit = 0; - state.alias = false; + options &= ~kUpb_DecodeOption_AliasString; // Can't alias patch buf. } else { state.end = buf + size - 16; state.limit = 16; - state.alias = options & UPB_DECODE_ALIAS; } state.extreg = extreg; @@ -875,21 +1081,22 @@ bool _upb_decode(const char *buf, size_t size, void *msg, state.unknown_msg = NULL; state.depth = depth ? depth : 64; state.end_group = DECODE_NOGROUP; + state.options = (uint16_t)options; + state.missing_required = false; state.arena.head = arena->head; state.arena.last_size = arena->last_size; state.arena.cleanup_metadata = arena->cleanup_metadata; state.arena.parent = arena; - if (UPB_UNLIKELY(UPB_SETJMP(state.err))) { - ok = false; - } else { - ok = decode_top(&state, buf, msg, l); + upb_DecodeStatus status = UPB_SETJMP(state.err); + if (UPB_LIKELY(status == kUpb_DecodeStatus_Ok)) { + status = decode_top(&state, buf, msg, l); } arena->head.ptr = state.arena.head.ptr; arena->head.end = state.arena.head.end; arena->cleanup_metadata = state.arena.cleanup_metadata; - return ok; + return status; } #undef OP_UNKNOWN diff --git a/contrib/libs/grpc/third_party/upb/upb/decode.h b/contrib/libs/grpc/third_party/upb/upb/decode.h index 24008910c0..1fa8131b7d 100644 --- a/contrib/libs/grpc/third_party/upb/upb/decode.h +++ b/contrib/libs/grpc/third_party/upb/upb/decode.h @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -26,7 +26,7 @@ */ /* - * upb_decode: parsing into a upb_msg using a upb_msglayout. + * upb_decode: parsing into a upb_Message using a upb_MiniTable. */ #ifndef UPB_DECODE_H_ @@ -44,25 +44,51 @@ extern "C" { enum { /* If set, strings will alias the input buffer instead of copying into the * arena. */ - UPB_DECODE_ALIAS = 1, + kUpb_DecodeOption_AliasString = 1, + + /* If set, the parse will return failure if any message is missing any + * required fields when the message data ends. The parse will still continue, + * and the failure will only be reported at the end. + * + * IMPORTANT CAVEATS: + * + * 1. This can throw a false positive failure if an incomplete message is seen + * on the wire but is later completed when the sub-message occurs again. + * For this reason, a second pass is required to verify a failure, to be + * truly robust. + * + * 2. This can return a false success if you are decoding into a message that + * already has some sub-message fields present. If the sub-message does + * not occur in the binary payload, we will never visit it and discover the + * incomplete sub-message. For this reason, this check is only useful for + * implemting ParseFromString() semantics. For MergeFromString(), a + * post-parse validation step will always be necessary. */ + kUpb_DecodeOption_CheckRequired = 2, }; #define UPB_DECODE_MAXDEPTH(depth) ((depth) << 16) -bool _upb_decode(const char *buf, size_t size, upb_msg *msg, - const upb_msglayout *l, const upb_extreg *extreg, int options, - upb_arena *arena); +typedef enum { + kUpb_DecodeStatus_Ok = 0, + kUpb_DecodeStatus_Malformed = 1, // Wire format was corrupt + kUpb_DecodeStatus_OutOfMemory = 2, // Arena alloc failed + kUpb_DecodeStatus_BadUtf8 = 3, // String field had bad UTF-8 + kUpb_DecodeStatus_MaxDepthExceeded = 4, // Exceeded UPB_DECODE_MAXDEPTH + + // kUpb_DecodeOption_CheckRequired failed (see above), but the parse otherwise + // succeeded. + kUpb_DecodeStatus_MissingRequired = 5, +} upb_DecodeStatus; -UPB_INLINE -bool upb_decode(const char *buf, size_t size, upb_msg *msg, - const upb_msglayout *l, upb_arena *arena) { - return _upb_decode(buf, size, msg, l, NULL, 0, arena); -} +upb_DecodeStatus upb_Decode(const char* buf, size_t size, upb_Message* msg, + const upb_MiniTable* l, + const upb_ExtensionRegistry* extreg, int options, + upb_Arena* arena); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif #include "upb/port_undef.inc" -#endif /* UPB_DECODE_H_ */ +#endif /* UPB_DECODE_H_ */ diff --git a/contrib/libs/grpc/third_party/upb/upb/decode_fast.c b/contrib/libs/grpc/third_party/upb/upb/decode_fast.c index d38136aa4c..e05bf8e0db 100644 --- a/contrib/libs/grpc/third_party/upb/upb/decode_fast.c +++ b/contrib/libs/grpc/third_party/upb/upb/decode_fast.c @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -46,44 +46,48 @@ // The standard set of arguments passed to each parsing function. // Thanks to x86-64 calling conventions, these will stay in registers. -#define UPB_PARSE_PARAMS \ - upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, \ +#define UPB_PARSE_PARAMS \ + upb_Decoder *d, const char *ptr, upb_Message *msg, intptr_t table, \ uint64_t hasbits, uint64_t data #define UPB_PARSE_ARGS d, ptr, msg, table, hasbits, data -#define RETURN_GENERIC(m) \ - /* Uncomment either of these for debugging purposes. */ \ - /* fprintf(stderr, m); */ \ - /*__builtin_trap(); */ \ +#define RETURN_GENERIC(m) \ + /* Uncomment either of these for debugging purposes. */ \ + /* fprintf(stderr, m); */ \ + /*__builtin_trap(); */ \ return fastdecode_generic(d, ptr, msg, table, hasbits, 0); typedef enum { - CARD_s = 0, /* Singular (optional, non-repeated) */ - CARD_o = 1, /* Oneof */ - CARD_r = 2, /* Repeated */ - CARD_p = 3 /* Packed Repeated */ + CARD_s = 0, /* Singular (optional, non-repeated) */ + CARD_o = 1, /* Oneof */ + CARD_r = 2, /* Repeated */ + CARD_p = 3 /* Packed Repeated */ } upb_card; UPB_NOINLINE -static const char *fastdecode_isdonefallback(UPB_PARSE_PARAMS) { +static const char* fastdecode_isdonefallback(UPB_PARSE_PARAMS) { int overrun = data; - ptr = decode_isdonefallback_inl(d, ptr, overrun); + int status; + ptr = decode_isdonefallback_inl(d, ptr, overrun, &status); if (ptr == NULL) { - return fastdecode_err(d); + return fastdecode_err(d, status); } data = fastdecode_loadtag(ptr); UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); } UPB_FORCEINLINE -static const char *fastdecode_dispatch(UPB_PARSE_PARAMS) { +static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) { if (UPB_UNLIKELY(ptr >= d->limit_ptr)) { int overrun = ptr - d->end; if (UPB_LIKELY(overrun == d->limit)) { // Parse is finished. *(uint32_t*)msg |= hasbits; // Sync hasbits. - return ptr; + const upb_MiniTable* l = decode_totablep(table); + return UPB_UNLIKELY(l->required_count) + ? decode_checkrequired(d, ptr, msg, l) + : ptr; } else { data = overrun; UPB_MUSTTAIL return fastdecode_isdonefallback(UPB_PARSE_ARGS); @@ -105,7 +109,7 @@ static bool fastdecode_checktag(uint16_t data, int tagbytes) { } UPB_FORCEINLINE -static const char *fastdecode_longsize(const char *ptr, int *size) { +static const char* fastdecode_longsize(const char* ptr, int* size) { int i; UPB_ASSERT(*size & 0x80); *size &= 0xff; @@ -125,8 +129,8 @@ static const char *fastdecode_longsize(const char *ptr, int *size) { } UPB_FORCEINLINE -static bool fastdecode_boundscheck(const char *ptr, size_t len, - const char *end) { +static bool fastdecode_boundscheck(const char* ptr, size_t len, + const char* end) { uintptr_t uptr = (uintptr_t)ptr; uintptr_t uend = (uintptr_t)end + 16; uintptr_t res = uptr + len; @@ -134,8 +138,8 @@ static bool fastdecode_boundscheck(const char *ptr, size_t len, } UPB_FORCEINLINE -static bool fastdecode_boundscheck2(const char *ptr, size_t len, - const char *end) { +static bool fastdecode_boundscheck2(const char* ptr, size_t len, + const char* end) { // This is one extra branch compared to the more normal: // return (size_t)(end - ptr) < size; // However it is one less computation if we are just about to use "ptr + len": @@ -147,12 +151,12 @@ static bool fastdecode_boundscheck2(const char *ptr, size_t len, return res < uptr || res > uend; } -typedef const char *fastdecode_delimfunc(upb_decstate *d, const char *ptr, - void *ctx); +typedef const char* fastdecode_delimfunc(upb_Decoder* d, const char* ptr, + void* ctx); UPB_FORCEINLINE -static const char *fastdecode_delimited(upb_decstate *d, const char *ptr, - fastdecode_delimfunc *func, void *ctx) { +static const char* fastdecode_delimited(upb_Decoder* d, const char* ptr, + fastdecode_delimfunc* func, void* ctx) { ptr++; int len = (int8_t)ptr[-1]; if (fastdecode_boundscheck2(ptr, len, d->limit_ptr)) { @@ -177,7 +181,7 @@ static const char *fastdecode_delimited(upb_decstate *d, const char *ptr, } else { // Fast case: Sub-message is <128 bytes and fits in the current buffer. // This means we can preserve limit/limit_ptr verbatim. - const char *saved_limit_ptr = d->limit_ptr; + const char* saved_limit_ptr = d->limit_ptr; int saved_limit = d->limit; d->limit_ptr = ptr + len; d->limit = d->limit_ptr - d->end; @@ -193,8 +197,8 @@ static const char *fastdecode_delimited(upb_decstate *d, const char *ptr, /* singular, oneof, repeated field handling ***********************************/ typedef struct { - upb_array *arr; - void *end; + upb_Array* arr; + void* end; } fastdecode_arr; typedef enum { @@ -204,21 +208,21 @@ typedef enum { } fastdecode_next; typedef struct { - void *dst; + void* dst; fastdecode_next next; uint32_t tag; } fastdecode_nextret; UPB_FORCEINLINE -static void *fastdecode_resizearr(upb_decstate *d, void *dst, - fastdecode_arr *farr, int valbytes) { +static void* fastdecode_resizearr(upb_Decoder* d, void* dst, + fastdecode_arr* farr, int valbytes) { if (UPB_UNLIKELY(dst == farr->end)) { size_t old_size = farr->arr->size; size_t old_bytes = old_size * valbytes; size_t new_size = old_size * 2; size_t new_bytes = new_size * valbytes; - char *old_ptr = _upb_array_ptr(farr->arr); - char *new_ptr = upb_arena_realloc(&d->arena, old_ptr, old_bytes, new_bytes); + char* old_ptr = _upb_array_ptr(farr->arr); + char* new_ptr = upb_Arena_Realloc(&d->arena, old_ptr, old_bytes, new_bytes); uint8_t elem_size_lg2 = __builtin_ctz(valbytes); farr->arr->size = new_size; farr->arr->data = _upb_array_tagptr(new_ptr, elem_size_lg2); @@ -238,20 +242,20 @@ static bool fastdecode_tagmatch(uint32_t tag, uint64_t data, int tagbytes) { } UPB_FORCEINLINE -static void fastdecode_commitarr(void *dst, fastdecode_arr *farr, +static void fastdecode_commitarr(void* dst, fastdecode_arr* farr, int valbytes) { farr->arr->len = - (size_t)((char *)dst - (char *)_upb_array_ptr(farr->arr)) / valbytes; + (size_t)((char*)dst - (char*)_upb_array_ptr(farr->arr)) / valbytes; } UPB_FORCEINLINE -static fastdecode_nextret fastdecode_nextrepeated(upb_decstate *d, void *dst, - const char **ptr, - fastdecode_arr *farr, +static fastdecode_nextret fastdecode_nextrepeated(upb_Decoder* d, void* dst, + const char** ptr, + fastdecode_arr* farr, uint64_t data, int tagbytes, int valbytes) { fastdecode_nextret ret; - dst = (char *)dst + valbytes; + dst = (char*)dst + valbytes; if (UPB_LIKELY(!decode_isdone(d, ptr))) { ret.tag = fastdecode_loadtag(*ptr); @@ -271,16 +275,16 @@ static fastdecode_nextret fastdecode_nextrepeated(upb_decstate *d, void *dst, } UPB_FORCEINLINE -static void *fastdecode_fieldmem(upb_msg *msg, uint64_t data) { +static void* fastdecode_fieldmem(upb_Message* msg, uint64_t data) { size_t ofs = data >> 48; - return (char *)msg + ofs; + return (char*)msg + ofs; } UPB_FORCEINLINE -static void *fastdecode_getfield(upb_decstate *d, const char *ptr, upb_msg *msg, - uint64_t *data, uint64_t *hasbits, - fastdecode_arr *farr, int valbytes, - upb_card card) { +static void* fastdecode_getfield(upb_Decoder* d, const char* ptr, + upb_Message* msg, uint64_t* data, + uint64_t* hasbits, fastdecode_arr* farr, + int valbytes, upb_card card) { switch (card) { case CARD_s: { uint8_t hasbit_index = *data >> 24; @@ -290,20 +294,20 @@ static void *fastdecode_getfield(upb_decstate *d, const char *ptr, upb_msg *msg, } case CARD_o: { uint16_t case_ofs = *data >> 32; - uint32_t *oneof_case = UPB_PTR_AT(msg, case_ofs, uint32_t); + uint32_t* oneof_case = UPB_PTR_AT(msg, case_ofs, uint32_t); uint8_t field_number = *data >> 24; *oneof_case = field_number; return fastdecode_fieldmem(msg, *data); } case CARD_r: { - // Get pointer to upb_array and allocate/expand if necessary. + // Get pointer to upb_Array and allocate/expand if necessary. uint8_t elem_size_lg2 = __builtin_ctz(valbytes); - upb_array **arr_p = fastdecode_fieldmem(msg, *data); - char *begin; + upb_Array** arr_p = fastdecode_fieldmem(msg, *data); + char* begin; *(uint32_t*)msg |= *hasbits; *hasbits = 0; if (UPB_LIKELY(!*arr_p)) { - farr->arr = _upb_array_new(&d->arena, 8, elem_size_lg2); + farr->arr = _upb_Array_New(&d->arena, 8, elem_size_lg2); *arr_p = farr->arr; } else { farr->arr = *arr_p; @@ -319,17 +323,17 @@ static void *fastdecode_getfield(upb_decstate *d, const char *ptr, upb_msg *msg, } UPB_FORCEINLINE -static bool fastdecode_flippacked(uint64_t *data, int tagbytes) { +static bool fastdecode_flippacked(uint64_t* data, int tagbytes) { *data ^= (0x2 ^ 0x0); // Patch data to match packed wiretype. return fastdecode_checktag(*data, tagbytes); } -#define FASTDECODE_CHECKPACKED(tagbytes, card, func) \ - if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \ - if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) { \ - UPB_MUSTTAIL return func(UPB_PARSE_ARGS); \ - } \ - RETURN_GENERIC("packed check tag mismatch\n"); \ +#define FASTDECODE_CHECKPACKED(tagbytes, card, func) \ + if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \ + if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) { \ + UPB_MUSTTAIL return func(UPB_PARSE_ARGS); \ + } \ + RETURN_GENERIC("packed check tag mismatch\n"); \ } /* varint fields **************************************************************/ @@ -351,7 +355,7 @@ static uint64_t fastdecode_munge(uint64_t val, int valbytes, bool zigzag) { } UPB_FORCEINLINE -static const char *fastdecode_varint64(const char *ptr, uint64_t *val) { +static const char* fastdecode_varint64(const char* ptr, uint64_t* val) { ptr++; *val = (uint8_t)ptr[-1]; if (UPB_UNLIKELY(*val & 0x80)) { @@ -377,7 +381,7 @@ done: #define FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \ valbytes, card, zigzag, packed) \ uint64_t val; \ - void *dst; \ + void* dst; \ fastdecode_arr farr; \ \ FASTDECODE_CHECKPACKED(tagbytes, card, packed); \ @@ -397,8 +401,7 @@ done: \ ptr += tagbytes; \ ptr = fastdecode_varint64(ptr, &val); \ - if (ptr == NULL) \ - return fastdecode_err(d); \ + if (ptr == NULL) return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ val = fastdecode_munge(val, valbytes, zigzag); \ memcpy(dst, &val, valbytes); \ \ @@ -406,14 +409,14 @@ done: fastdecode_nextret ret = fastdecode_nextrepeated( \ d, dst, &ptr, &farr, data, tagbytes, valbytes); \ switch (ret.next) { \ - case FD_NEXT_SAMEFIELD: \ - dst = ret.dst; \ - goto again; \ - case FD_NEXT_OTHERFIELD: \ - data = ret.tag; \ - UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - case FD_NEXT_ATLIMIT: \ - return ptr; \ + case FD_NEXT_SAMEFIELD: \ + dst = ret.dst; \ + goto again; \ + case FD_NEXT_OTHERFIELD: \ + data = ret.tag; \ + UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ + case FD_NEXT_ATLIMIT: \ + return ptr; \ } \ } \ \ @@ -422,15 +425,15 @@ done: typedef struct { uint8_t valbytes; bool zigzag; - void *dst; + void* dst; fastdecode_arr farr; } fastdecode_varintdata; UPB_FORCEINLINE -static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr, - void *ctx) { - fastdecode_varintdata *data = ctx; - void *dst = data->dst; +static const char* fastdecode_topackedvarint(upb_Decoder* d, const char* ptr, + void* ctx) { + fastdecode_varintdata* data = ctx; + void* dst = data->dst; uint64_t val; while (!decode_isdone(d, &ptr)) { @@ -439,32 +442,32 @@ static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr, if (ptr == NULL) return NULL; val = fastdecode_munge(val, data->valbytes, data->zigzag); memcpy(dst, &val, data->valbytes); - dst = (char *)dst + data->valbytes; + dst = (char*)dst + data->valbytes; } fastdecode_commitarr(dst, &data->farr, data->valbytes); return ptr; } -#define FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \ - valbytes, zigzag, unpacked) \ - fastdecode_varintdata ctx = {valbytes, zigzag}; \ - \ - FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked); \ - \ - ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr, \ - valbytes, CARD_r); \ - if (UPB_UNLIKELY(!ctx.dst)) { \ - RETURN_GENERIC("need array resize\n"); \ - } \ - \ - ptr += tagbytes; \ - ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx); \ - \ - if (UPB_UNLIKELY(ptr == NULL)) { \ - return fastdecode_err(d); \ - } \ - \ +#define FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \ + valbytes, zigzag, unpacked) \ + fastdecode_varintdata ctx = {valbytes, zigzag}; \ + \ + FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked); \ + \ + ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr, \ + valbytes, CARD_r); \ + if (UPB_UNLIKELY(!ctx.dst)) { \ + RETURN_GENERIC("need array resize\n"); \ + } \ + \ + ptr += tagbytes; \ + ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx); \ + \ + if (UPB_UNLIKELY(ptr == NULL)) { \ + return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ + } \ + \ UPB_MUSTTAIL return fastdecode_dispatch(d, ptr, msg, table, hasbits, 0); #define FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, \ @@ -486,7 +489,7 @@ static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr, #define F(card, type, valbytes, tagbytes) \ UPB_NOINLINE \ - const char *upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ + const char* upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \ CARD_##card, type##_ZZ, \ upb_pr##type##valbytes##_##tagbytes##bt, \ @@ -522,48 +525,47 @@ TAGBYTES(p) #undef FASTDECODE_PACKEDVARINT #undef FASTDECODE_VARINT - /* fixed fields ***************************************************************/ -#define FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \ - valbytes, card, packed) \ - void *dst; \ - fastdecode_arr farr; \ - \ - FASTDECODE_CHECKPACKED(tagbytes, card, packed) \ - \ - dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \ - card); \ - if (card == CARD_r) { \ - if (UPB_UNLIKELY(!dst)) { \ - RETURN_GENERIC("couldn't allocate array in arena\n"); \ - } \ - } \ - \ - again: \ - if (card == CARD_r) { \ - dst = fastdecode_resizearr(d, dst, &farr, valbytes); \ - } \ - \ - ptr += tagbytes; \ - memcpy(dst, ptr, valbytes); \ - ptr += valbytes; \ - \ - if (card == CARD_r) { \ - fastdecode_nextret ret = fastdecode_nextrepeated( \ - d, dst, &ptr, &farr, data, tagbytes, valbytes); \ - switch (ret.next) { \ - case FD_NEXT_SAMEFIELD: \ - dst = ret.dst; \ - goto again; \ - case FD_NEXT_OTHERFIELD: \ - data = ret.tag; \ - UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - case FD_NEXT_ATLIMIT: \ - return ptr; \ - } \ - } \ - \ +#define FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \ + valbytes, card, packed) \ + void* dst; \ + fastdecode_arr farr; \ + \ + FASTDECODE_CHECKPACKED(tagbytes, card, packed) \ + \ + dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \ + card); \ + if (card == CARD_r) { \ + if (UPB_UNLIKELY(!dst)) { \ + RETURN_GENERIC("couldn't allocate array in arena\n"); \ + } \ + } \ + \ + again: \ + if (card == CARD_r) { \ + dst = fastdecode_resizearr(d, dst, &farr, valbytes); \ + } \ + \ + ptr += tagbytes; \ + memcpy(dst, ptr, valbytes); \ + ptr += valbytes; \ + \ + if (card == CARD_r) { \ + fastdecode_nextret ret = fastdecode_nextrepeated( \ + d, dst, &ptr, &farr, data, tagbytes, valbytes); \ + switch (ret.next) { \ + case FD_NEXT_SAMEFIELD: \ + dst = ret.dst; \ + goto again; \ + case FD_NEXT_OTHERFIELD: \ + data = ret.tag; \ + UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ + case FD_NEXT_ATLIMIT: \ + return ptr; \ + } \ + } \ + \ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); #define FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \ @@ -579,24 +581,24 @@ TAGBYTES(p) \ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr) || \ (size % valbytes) != 0)) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ } \ \ - upb_array **arr_p = fastdecode_fieldmem(msg, data); \ - upb_array *arr = *arr_p; \ + upb_Array** arr_p = fastdecode_fieldmem(msg, data); \ + upb_Array* arr = *arr_p; \ uint8_t elem_size_lg2 = __builtin_ctz(valbytes); \ int elems = size / valbytes; \ \ if (UPB_LIKELY(!arr)) { \ - *arr_p = arr = _upb_array_new(&d->arena, elems, elem_size_lg2); \ + *arr_p = arr = _upb_Array_New(&d->arena, elems, elem_size_lg2); \ if (!arr) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ } \ } else { \ - _upb_array_resize(arr, elems, &d->arena); \ + _upb_Array_Resize(arr, elems, &d->arena); \ } \ \ - char *dst = _upb_array_ptr(arr); \ + char* dst = _upb_array_ptr(arr); \ memcpy(dst, ptr, size); \ arr->len = elems; \ \ @@ -618,7 +620,7 @@ TAGBYTES(p) #define F(card, valbytes, tagbytes) \ UPB_NOINLINE \ - const char *upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ + const char* upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \ CARD_##card, upb_ppf##valbytes##_##tagbytes##bt, \ upb_prf##valbytes##_##tagbytes##bt); \ @@ -645,18 +647,19 @@ TAGBYTES(p) /* string fields **************************************************************/ -typedef const char *fastdecode_copystr_func(struct upb_decstate *d, - const char *ptr, upb_msg *msg, - const upb_msglayout *table, - uint64_t hasbits, upb_strview *dst); +typedef const char* fastdecode_copystr_func(struct upb_Decoder* d, + const char* ptr, upb_Message* msg, + const upb_MiniTable* table, + uint64_t hasbits, + upb_StringView* dst); UPB_NOINLINE -static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr, - upb_msg *msg, intptr_t table, +static const char* fastdecode_verifyutf8(upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, uint64_t hasbits, uint64_t data) { - upb_strview *dst = (upb_strview*)data; + upb_StringView* dst = (upb_StringView*)data; if (!decode_verifyutf8_inl(dst->data, dst->size)) { - return fastdecode_err(d); + return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); } UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); } @@ -670,16 +673,16 @@ static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr, \ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) { \ dst->size = 0; \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ } \ \ - if (d->alias) { \ + if (d->options & kUpb_DecodeOption_AliasString) { \ dst->data = ptr; \ dst->size = size; \ } else { \ - char *data = upb_arena_malloc(&d->arena, size); \ + char* data = upb_Arena_Malloc(&d->arena, size); \ if (!data) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_OutOfMemory); \ } \ memcpy(data, ptr, size); \ dst->data = data; \ @@ -695,27 +698,25 @@ static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr, } UPB_NOINLINE -static const char *fastdecode_longstring_utf8(struct upb_decstate *d, - const char *ptr, upb_msg *msg, +static const char* fastdecode_longstring_utf8(struct upb_Decoder* d, + const char* ptr, upb_Message* msg, intptr_t table, uint64_t hasbits, uint64_t data) { - upb_strview *dst = (upb_strview*)data; + upb_StringView* dst = (upb_StringView*)data; FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, true); } UPB_NOINLINE -static const char *fastdecode_longstring_noutf8(struct upb_decstate *d, - const char *ptr, upb_msg *msg, - intptr_t table, - uint64_t hasbits, - uint64_t data) { - upb_strview *dst = (upb_strview*)data; +static const char* fastdecode_longstring_noutf8( + struct upb_Decoder* d, const char* ptr, upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data) { + upb_StringView* dst = (upb_StringView*)data; FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, false); } UPB_FORCEINLINE -static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, - int copy, char *data, upb_strview *dst) { +static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size, + int copy, char* data, upb_StringView* dst) { d->arena.head.ptr += copy; dst->data = data; UPB_UNPOISON_MEMORY_REGION(data, copy); @@ -723,96 +724,95 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, UPB_POISON_MEMORY_REGION(data + size, copy - size); } -#define FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \ - card, validate_utf8) \ - upb_strview *dst; \ - fastdecode_arr farr; \ - int64_t size; \ - size_t arena_has; \ - size_t common_has; \ - char *buf; \ - \ - UPB_ASSERT(!d->alias); \ - UPB_ASSERT(fastdecode_checktag(data, tagbytes)); \ - \ - dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \ - sizeof(upb_strview), card); \ - \ - again: \ - if (card == CARD_r) { \ - dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview)); \ - } \ - \ - size = (uint8_t)ptr[tagbytes]; \ - ptr += tagbytes + 1; \ - dst->size = size; \ - \ - buf = d->arena.head.ptr; \ - arena_has = _upb_arenahas(&d->arena); \ - common_has = UPB_MIN(arena_has, (d->end - ptr) + 16); \ - \ - if (UPB_LIKELY(size <= 15 - tagbytes)) { \ - if (arena_has < 16) \ - goto longstr; \ - d->arena.head.ptr += 16; \ - memcpy(buf, ptr - tagbytes - 1, 16); \ - dst->data = buf + tagbytes + 1; \ - } else if (UPB_LIKELY(size <= 32)) { \ - if (UPB_UNLIKELY(common_has < 32)) \ - goto longstr; \ - fastdecode_docopy(d, ptr, size, 32, buf, dst); \ - } else if (UPB_LIKELY(size <= 64)) { \ - if (UPB_UNLIKELY(common_has < 64)) \ - goto longstr; \ - fastdecode_docopy(d, ptr, size, 64, buf, dst); \ - } else if (UPB_LIKELY(size < 128)) { \ - if (UPB_UNLIKELY(common_has < 128)) \ - goto longstr; \ - fastdecode_docopy(d, ptr, size, 128, buf, dst); \ - } else { \ - goto longstr; \ - } \ - \ - ptr += size; \ - \ - if (card == CARD_r) { \ - if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \ - return fastdecode_err(d); \ - } \ - fastdecode_nextret ret = fastdecode_nextrepeated( \ - d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \ - switch (ret.next) { \ - case FD_NEXT_SAMEFIELD: \ - dst = ret.dst; \ - goto again; \ - case FD_NEXT_OTHERFIELD: \ - data = ret.tag; \ - UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - case FD_NEXT_ATLIMIT: \ - return ptr; \ - } \ - } \ - \ - if (card != CARD_r && validate_utf8) { \ - data = (uint64_t)dst; \ - UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \ - } \ - \ - UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \ - \ - longstr: \ - ptr--; \ - if (validate_utf8) { \ - UPB_MUSTTAIL return fastdecode_longstring_utf8(d, ptr, msg, table, \ - hasbits, (uint64_t)dst); \ - } else { \ - UPB_MUSTTAIL return fastdecode_longstring_noutf8(d, ptr, msg, table, \ - hasbits, (uint64_t)dst); \ +#define FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \ + card, validate_utf8) \ + upb_StringView* dst; \ + fastdecode_arr farr; \ + int64_t size; \ + size_t arena_has; \ + size_t common_has; \ + char* buf; \ + \ + UPB_ASSERT((d->options & kUpb_DecodeOption_AliasString) == 0); \ + UPB_ASSERT(fastdecode_checktag(data, tagbytes)); \ + \ + dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \ + sizeof(upb_StringView), card); \ + \ + again: \ + if (card == CARD_r) { \ + dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_StringView)); \ + } \ + \ + size = (uint8_t)ptr[tagbytes]; \ + ptr += tagbytes + 1; \ + dst->size = size; \ + \ + buf = d->arena.head.ptr; \ + arena_has = _upb_ArenaHas(&d->arena); \ + common_has = UPB_MIN(arena_has, (d->end - ptr) + 16); \ + \ + if (UPB_LIKELY(size <= 15 - tagbytes)) { \ + if (arena_has < 16) goto longstr; \ + d->arena.head.ptr += 16; \ + memcpy(buf, ptr - tagbytes - 1, 16); \ + dst->data = buf + tagbytes + 1; \ + } else if (UPB_LIKELY(size <= 32)) { \ + if (UPB_UNLIKELY(common_has < 32)) goto longstr; \ + fastdecode_docopy(d, ptr, size, 32, buf, dst); \ + } else if (UPB_LIKELY(size <= 64)) { \ + if (UPB_UNLIKELY(common_has < 64)) goto longstr; \ + fastdecode_docopy(d, ptr, size, 64, buf, dst); \ + } else if (UPB_LIKELY(size < 128)) { \ + if (UPB_UNLIKELY(common_has < 128)) goto longstr; \ + fastdecode_docopy(d, ptr, size, 128, buf, dst); \ + } else { \ + goto longstr; \ + } \ + \ + ptr += size; \ + \ + if (card == CARD_r) { \ + if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \ + return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); \ + } \ + fastdecode_nextret ret = fastdecode_nextrepeated( \ + d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_StringView)); \ + switch (ret.next) { \ + case FD_NEXT_SAMEFIELD: \ + dst = ret.dst; \ + goto again; \ + case FD_NEXT_OTHERFIELD: \ + data = ret.tag; \ + UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ + case FD_NEXT_ATLIMIT: \ + return ptr; \ + } \ + } \ + \ + if (card != CARD_r && validate_utf8) { \ + data = (uint64_t)dst; \ + UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \ + } \ + \ + UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \ + \ + longstr: \ + if (card == CARD_r) { \ + fastdecode_commitarr(dst + 1, &farr, sizeof(upb_StringView)); \ + } \ + ptr--; \ + if (validate_utf8) { \ + UPB_MUSTTAIL return fastdecode_longstring_utf8(d, ptr, msg, table, \ + hasbits, (uint64_t)dst); \ + } else { \ + UPB_MUSTTAIL return fastdecode_longstring_noutf8(d, ptr, msg, table, \ + hasbits, (uint64_t)dst); \ } #define FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, card, \ copyfunc, validate_utf8) \ - upb_strview *dst; \ + upb_StringView* dst; \ fastdecode_arr farr; \ int64_t size; \ \ @@ -820,16 +820,16 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, RETURN_GENERIC("string field tag mismatch\n"); \ } \ \ - if (UPB_UNLIKELY(!d->alias)) { \ + if (UPB_UNLIKELY((d->options & kUpb_DecodeOption_AliasString) == 0)) { \ UPB_MUSTTAIL return copyfunc(UPB_PARSE_ARGS); \ } \ \ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \ - sizeof(upb_strview), card); \ + sizeof(upb_StringView), card); \ \ again: \ if (card == CARD_r) { \ - dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview)); \ + dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_StringView)); \ } \ \ size = (int8_t)ptr[tagbytes]; \ @@ -852,27 +852,27 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, \ if (card == CARD_r) { \ if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); \ } \ fastdecode_nextret ret = fastdecode_nextrepeated( \ - d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \ + d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_StringView)); \ switch (ret.next) { \ - case FD_NEXT_SAMEFIELD: \ - dst = ret.dst; \ - if (UPB_UNLIKELY(!d->alias)) { \ - /* Buffer flipped and we can't alias any more. Bounce to */ \ - /* copyfunc(), but via dispatch since we need to reload table */ \ - /* data also. */ \ - fastdecode_commitarr(dst, &farr, sizeof(upb_strview)); \ + case FD_NEXT_SAMEFIELD: \ + dst = ret.dst; \ + if (UPB_UNLIKELY((d->options & kUpb_DecodeOption_AliasString) == 0)) { \ + /* Buffer flipped and we can't alias any more. Bounce to */ \ + /* copyfunc(), but via dispatch since we need to reload table */ \ + /* data also. */ \ + fastdecode_commitarr(dst, &farr, sizeof(upb_StringView)); \ + data = ret.tag; \ + UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ + } \ + goto again; \ + case FD_NEXT_OTHERFIELD: \ data = ret.tag; \ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - } \ - goto again; \ - case FD_NEXT_OTHERFIELD: \ - data = ret.tag; \ - UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - case FD_NEXT_ATLIMIT: \ - return ptr; \ + case FD_NEXT_ATLIMIT: \ + return ptr; \ } \ } \ \ @@ -891,11 +891,11 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, #define F(card, tagbytes, type) \ UPB_NOINLINE \ - const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ + const char* upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \ CARD_##card, type##_VALIDATE); \ } \ - const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ + const char* upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \ FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, \ CARD_##card, upb_c##card##type##_##tagbytes##bt, \ type##_VALIDATE); \ @@ -924,12 +924,12 @@ TAGBYTES(r) /* message fields *************************************************************/ UPB_INLINE -upb_msg *decode_newmsg_ceil(upb_decstate *d, const upb_msglayout *l, - int msg_ceil_bytes) { - size_t size = l->size + sizeof(upb_msg_internal); - char *msg_data; +upb_Message* decode_newmsg_ceil(upb_Decoder* d, const upb_MiniTable* l, + int msg_ceil_bytes) { + size_t size = l->size + sizeof(upb_Message_Internal); + char* msg_data; if (UPB_LIKELY(msg_ceil_bytes > 0 && - _upb_arenahas(&d->arena) >= msg_ceil_bytes)) { + _upb_ArenaHas(&d->arena) >= msg_ceil_bytes)) { UPB_ASSERT(size <= (size_t)msg_ceil_bytes); msg_data = d->arena.head.ptr; d->arena.head.ptr += size; @@ -937,21 +937,21 @@ upb_msg *decode_newmsg_ceil(upb_decstate *d, const upb_msglayout *l, memset(msg_data, 0, msg_ceil_bytes); UPB_POISON_MEMORY_REGION(msg_data + size, msg_ceil_bytes - size); } else { - msg_data = (char*)upb_arena_malloc(&d->arena, size); + msg_data = (char*)upb_Arena_Malloc(&d->arena, size); memset(msg_data, 0, size); } - return msg_data + sizeof(upb_msg_internal); + return msg_data + sizeof(upb_Message_Internal); } typedef struct { intptr_t table; - upb_msg *msg; + upb_Message* msg; } fastdecode_submsgdata; UPB_FORCEINLINE -static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, - void *ctx) { - fastdecode_submsgdata *submsg = ctx; +static const char* fastdecode_tosubmsg(upb_Decoder* d, const char* ptr, + void* ctx) { + fastdecode_submsgdata* submsg = ctx; ptr = fastdecode_dispatch(d, ptr, submsg->msg, submsg->table, 0, 0); UPB_ASSUME(ptr != NULL); return ptr; @@ -964,12 +964,14 @@ static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, RETURN_GENERIC("submessage field tag mismatch\n"); \ } \ \ - if (--d->depth == 0) return fastdecode_err(d); \ + if (--d->depth == 0) { \ + return fastdecode_err(d, kUpb_DecodeStatus_MaxDepthExceeded); \ + } \ \ - upb_msg **dst; \ + upb_Message** dst; \ uint32_t submsg_idx = (data >> 16) & 0xff; \ - const upb_msglayout *tablep = decode_totablep(table); \ - const upb_msglayout *subtablep = tablep->subs[submsg_idx].submsg; \ + const upb_MiniTable* tablep = decode_totablep(table); \ + const upb_MiniTable* subtablep = tablep->subs[submsg_idx].submsg; \ fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \ fastdecode_arr farr; \ \ @@ -978,16 +980,16 @@ static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, } \ \ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \ - sizeof(upb_msg *), card); \ + sizeof(upb_Message*), card); \ \ if (card == CARD_s) { \ - *(uint32_t *)msg |= hasbits; \ + *(uint32_t*)msg |= hasbits; \ hasbits = 0; \ } \ \ again: \ if (card == CARD_r) { \ - dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_msg *)); \ + dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_Message*)); \ } \ \ submsg.msg = *dst; \ @@ -1000,12 +1002,12 @@ static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg); \ \ if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \ } \ \ if (card == CARD_r) { \ fastdecode_nextret ret = fastdecode_nextrepeated( \ - d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_msg *)); \ + d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_Message*)); \ switch (ret.next) { \ case FD_NEXT_SAMEFIELD: \ dst = ret.dst; \ @@ -1024,21 +1026,21 @@ static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); #define F(card, tagbytes, size_ceil, ceil_arg) \ - const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b( \ + const char* upb_p##card##m_##tagbytes##bt_max##size_ceil##b( \ UPB_PARSE_PARAMS) { \ FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, ceil_arg, \ CARD_##card); \ } #define SIZES(card, tagbytes) \ - F(card, tagbytes, 64, 64) \ + F(card, tagbytes, 64, 64) \ F(card, tagbytes, 128, 128) \ F(card, tagbytes, 192, 192) \ F(card, tagbytes, 256, 256) \ F(card, tagbytes, max, -1) #define TAGBYTES(card) \ - SIZES(card, 1) \ + SIZES(card, 1) \ SIZES(card, 2) TAGBYTES(s) @@ -1050,4 +1052,4 @@ TAGBYTES(r) #undef F #undef FASTDECODE_SUBMSG -#endif /* UPB_FASTTABLE */ +#endif /* UPB_FASTTABLE */ diff --git a/contrib/libs/grpc/third_party/upb/upb/decode_fast.h b/contrib/libs/grpc/third_party/upb/upb/decode_fast.h index a05cd80fe4..b04aeedb85 100644 --- a/contrib/libs/grpc/third_party/upb/upb/decode_fast.h +++ b/contrib/libs/grpc/third_party/upb/upb/decode_fast.h @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -64,22 +64,22 @@ #include "upb/msg.h" -struct upb_decstate; +struct upb_Decoder; // The fallback, generic parsing function that can handle any field type. // This just uses the regular (non-fast) parser to parse a single field. -const char *fastdecode_generic(struct upb_decstate *d, const char *ptr, - upb_msg *msg, intptr_t table, uint64_t hasbits, - uint64_t data); +const char* fastdecode_generic(struct upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data); -#define UPB_PARSE_PARAMS \ - struct upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, \ +#define UPB_PARSE_PARAMS \ + struct upb_Decoder *d, const char *ptr, upb_Message *msg, intptr_t table, \ uint64_t hasbits, uint64_t data /* primitive fields ***********************************************************/ #define F(card, type, valbytes, tagbytes) \ - const char *upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS); + const char* upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS); #define TYPES(card, tagbytes) \ F(card, b, 1, tagbytes) \ @@ -106,8 +106,8 @@ TAGBYTES(p) /* string fields **************************************************************/ #define F(card, tagbytes, type) \ - const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS); \ - const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS); + const char* upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS); \ + const char* upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS); #define UTF8(card, tagbytes) \ F(card, tagbytes, s) \ @@ -127,17 +127,17 @@ TAGBYTES(r) /* sub-message fields *********************************************************/ #define F(card, tagbytes, size_ceil, ceil_arg) \ - const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b(UPB_PARSE_PARAMS); + const char* upb_p##card##m_##tagbytes##bt_max##size_ceil##b(UPB_PARSE_PARAMS); #define SIZES(card, tagbytes) \ - F(card, tagbytes, 64, 64) \ + F(card, tagbytes, 64, 64) \ F(card, tagbytes, 128, 128) \ F(card, tagbytes, 192, 192) \ F(card, tagbytes, 256, 256) \ F(card, tagbytes, max, -1) #define TAGBYTES(card) \ - SIZES(card, 1) \ + SIZES(card, 1) \ SIZES(card, 2) TAGBYTES(s) @@ -150,4 +150,4 @@ TAGBYTES(r) #undef UPB_PARSE_PARAMS -#endif /* UPB_DECODE_FAST_H_ */ +#endif /* UPB_DECODE_FAST_H_ */ diff --git a/contrib/libs/grpc/third_party/upb/upb/decode_internal.h b/contrib/libs/grpc/third_party/upb/upb/decode_internal.h index 6d03084b37..11bb9aa095 100644 --- a/contrib/libs/grpc/third_party/upb/upb/decode_internal.h +++ b/contrib/libs/grpc/third_party/upb/upb/decode_internal.h @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -35,28 +35,37 @@ #include <setjmp.h> +#include "third_party/utf8_range/utf8_range.h" +#include "upb/decode.h" #include "upb/msg_internal.h" #include "upb/upb_internal.h" /* Must be last. */ #include "upb/port_def.inc" -#define DECODE_NOGROUP (uint32_t)-1 - -typedef struct upb_decstate { - const char *end; /* Can read up to 16 bytes slop beyond this. */ - const char *limit_ptr; /* = end + UPB_MIN(limit, 0) */ - upb_msg *unknown_msg; /* If non-NULL, add unknown data at buffer flip. */ - const char *unknown; /* Start of unknown data. */ - const upb_extreg *extreg; /* For looking up extensions during the parse. */ - int limit; /* Submessage limit relative to end. */ - int depth; - uint32_t end_group; /* field number of END_GROUP tag, else DECODE_NOGROUP */ - bool alias; +#define DECODE_NOGROUP (uint32_t) - 1 + +typedef struct upb_Decoder { + const char* end; /* Can read up to 16 bytes slop beyond this. */ + const char* limit_ptr; /* = end + UPB_MIN(limit, 0) */ + upb_Message* unknown_msg; /* If non-NULL, add unknown data at buffer flip. */ + const char* unknown; /* Start of unknown data. */ + const upb_ExtensionRegistry* + extreg; /* For looking up extensions during the parse. */ + int limit; /* Submessage limit relative to end. */ + int depth; /* Tracks recursion depth to bound stack usage. */ + uint32_t end_group; /* field number of END_GROUP tag, else DECODE_NOGROUP */ + uint16_t options; + bool missing_required; char patch[32]; - upb_arena arena; + upb_Arena arena; jmp_buf err; -} upb_decstate; + +#ifndef NDEBUG + const char* debug_tagstart; + const char* debug_valstart; +#endif +} upb_Decoder; /* Error function that will abort decoding with longjmp(). We can't declare this * UPB_NORETURN, even though it is appropriate, because if we do then compilers @@ -65,50 +74,58 @@ typedef struct upb_decstate { * of our optimizations. That is also why we must declare it in a separate file, * otherwise the compiler will see that it calls longjmp() and deduce that it is * noreturn. */ -const char *fastdecode_err(upb_decstate *d); +const char* fastdecode_err(upb_Decoder* d, int status); extern const uint8_t upb_utf8_offsets[]; UPB_INLINE -bool decode_verifyutf8_inl(const char *buf, int len) { - int i, j; - uint8_t offset; - - i = 0; - while (i < len) { - offset = upb_utf8_offsets[(uint8_t)buf[i]]; - if (offset == 0 || i + offset > len) { - return false; - } - for (j = i + 1; j < i + offset; j++) { - if ((buf[j] & 0xc0) != 0x80) { - return false; - } - } - i += offset; +bool decode_verifyutf8_inl(const char* ptr, int len) { + const char* end = ptr + len; + + // Check 8 bytes at a time for any non-ASCII char. + while (end - ptr >= 8) { + uint64_t data; + memcpy(&data, ptr, 8); + if (data & 0x8080808080808080) goto non_ascii; + ptr += 8; } - return i == len; + + // Check one byte at a time for non-ASCII. + while (ptr < end) { + if (*ptr & 0x80) goto non_ascii; + ptr++; + } + + return true; + +non_ascii: + return utf8_range2((const unsigned char*)ptr, end - ptr) == 0; } +const char* decode_checkrequired(upb_Decoder* d, const char* ptr, + const upb_Message* msg, + const upb_MiniTable* l); + /* x86-64 pointers always have the high 16 bits matching. So we can shift * left 8 and right 8 without loss of information. */ -UPB_INLINE intptr_t decode_totable(const upb_msglayout *tablep) { +UPB_INLINE intptr_t decode_totable(const upb_MiniTable* tablep) { return ((intptr_t)tablep << 8) | tablep->table_mask; } -UPB_INLINE const upb_msglayout *decode_totablep(intptr_t table) { - return (const upb_msglayout*)(table >> 8); +UPB_INLINE const upb_MiniTable* decode_totablep(intptr_t table) { + return (const upb_MiniTable*)(table >> 8); } UPB_INLINE -const char *decode_isdonefallback_inl(upb_decstate *d, const char *ptr, - int overrun) { +const char* decode_isdonefallback_inl(upb_Decoder* d, const char* ptr, + int overrun, int* status) { if (overrun < d->limit) { /* Need to copy remaining data into patch buffer. */ UPB_ASSERT(overrun < 16); if (d->unknown_msg) { - if (!_upb_msg_addunknown(d->unknown_msg, d->unknown, ptr - d->unknown, - &d->arena)) { + if (!_upb_Message_AddUnknown(d->unknown_msg, d->unknown, ptr - d->unknown, + &d->arena)) { + *status = kUpb_DecodeStatus_OutOfMemory; return NULL; } d->unknown = &d->patch[0] + overrun; @@ -119,19 +136,19 @@ const char *decode_isdonefallback_inl(upb_decstate *d, const char *ptr, d->end = &d->patch[16]; d->limit -= 16; d->limit_ptr = d->end + d->limit; - d->alias = false; + d->options &= ~kUpb_DecodeOption_AliasString; UPB_ASSERT(ptr < d->limit_ptr); return ptr; } else { + *status = kUpb_DecodeStatus_Malformed; return NULL; } } -const char *decode_isdonefallback(upb_decstate *d, const char *ptr, - int overrun); +const char* decode_isdonefallback(upb_Decoder* d, const char* ptr, int overrun); UPB_INLINE -bool decode_isdone(upb_decstate *d, const char **ptr) { +bool decode_isdone(upb_Decoder* d, const char** ptr) { int overrun = *ptr - d->end; if (UPB_LIKELY(*ptr < d->limit_ptr)) { return false; @@ -145,10 +162,10 @@ bool decode_isdone(upb_decstate *d, const char **ptr) { #if UPB_FASTTABLE UPB_INLINE -const char *fastdecode_tagdispatch(upb_decstate *d, const char *ptr, - upb_msg *msg, intptr_t table, - uint64_t hasbits, uint64_t tag) { - const upb_msglayout *table_p = decode_totablep(table); +const char* fastdecode_tagdispatch(upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t tag) { + const upb_MiniTable* table_p = decode_totablep(table); uint8_t mask = table; uint64_t data; size_t idx = tag & mask; @@ -166,11 +183,11 @@ UPB_INLINE uint32_t fastdecode_loadtag(const char* ptr) { return tag; } -UPB_INLINE void decode_checklimit(upb_decstate *d) { +UPB_INLINE void decode_checklimit(upb_Decoder* d) { UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit)); } -UPB_INLINE int decode_pushlimit(upb_decstate *d, const char *ptr, int size) { +UPB_INLINE int decode_pushlimit(upb_Decoder* d, const char* ptr, int size) { int limit = size + (int)(ptr - d->end); int delta = d->limit - limit; decode_checklimit(d); @@ -180,7 +197,7 @@ UPB_INLINE int decode_pushlimit(upb_decstate *d, const char *ptr, int size) { return delta; } -UPB_INLINE void decode_poplimit(upb_decstate *d, const char *ptr, +UPB_INLINE void decode_poplimit(upb_Decoder* d, const char* ptr, int saved_delta) { UPB_ASSERT(ptr - d->end == d->limit); decode_checklimit(d); @@ -191,4 +208,4 @@ UPB_INLINE void decode_poplimit(upb_decstate *d, const char *ptr, #include "upb/port_undef.inc" -#endif /* UPB_DECODE_INT_H_ */ +#endif /* UPB_DECODE_INT_H_ */ diff --git a/contrib/libs/grpc/third_party/upb/upb/def.c b/contrib/libs/grpc/third_party/upb/upb/def.c index b92f6176ac..363d8bb960 100644 --- a/contrib/libs/grpc/third_party/upb/upb/def.c +++ b/contrib/libs/grpc/third_party/upb/upb/def.c @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -41,121 +41,172 @@ typedef struct { size_t len; - char str[1]; /* Null-terminated string data follows. */ + char str[1]; /* Null-terminated string data follows. */ } str_t; -struct upb_fielddef { - const upb_filedef *file; - const upb_msgdef *msgdef; - const char *full_name; - const char *json_name; +/* The upb core does not generally have a concept of default instances. However + * for descriptor options we make an exception since the max size is known and + * modest (<200 bytes). All types can share a default instance since it is + * initialized to zeroes. + * + * We have to allocate an extra pointer for upb's internal metadata. */ +static const char opt_default_buf[_UPB_MAXOPT_SIZE + sizeof(void*)] = {0}; +static const char* opt_default = &opt_default_buf[sizeof(void*)]; + +struct upb_FieldDef { + const google_protobuf_FieldOptions* opts; + const upb_FileDef* file; + const upb_MessageDef* msgdef; + const char* full_name; + const char* json_name; union { int64_t sint; uint64_t uint; double dbl; float flt; bool boolean; - str_t *str; + str_t* str; } defaultval; - const upb_oneofdef *oneof; union { - const upb_msgdef *msgdef; - const upb_enumdef *enumdef; - const google_protobuf_FieldDescriptorProto *unresolved; + const upb_OneofDef* oneof; + const upb_MessageDef* extension_scope; + } scope; + union { + const upb_MessageDef* msgdef; + const upb_EnumDef* enumdef; + const google_protobuf_FieldDescriptorProto* unresolved; } sub; uint32_t number_; uint16_t index_; - uint16_t layout_index; + uint16_t layout_index; /* Index into msgdef->layout->fields or file->exts */ + bool has_default; bool is_extension_; - bool lazy_; bool packed_; bool proto3_optional_; - upb_descriptortype_t type_; - upb_label_t label_; + bool has_json_name_; + upb_FieldType type_; + upb_Label label_; }; -struct upb_extrange { - const google_protobuf_ExtensionRangeOptions *opts; +struct upb_ExtensionRange { + const google_protobuf_ExtensionRangeOptions* opts; int32_t start; int32_t end; }; -struct upb_msgdef { - const upb_msglayout *layout; - const upb_filedef *file; - const char *full_name; +struct upb_MessageDef { + const google_protobuf_MessageOptions* opts; + const upb_MiniTable* layout; + const upb_FileDef* file; + const upb_MessageDef* containing_type; + const char* full_name; /* Tables for looking up fields by number and name. */ upb_inttable itof; upb_strtable ntof; - const upb_extrange *ext_ranges; - const upb_fielddef *fields; - const upb_oneofdef *oneofs; + /* All nested defs. + * MEM: We could save some space here by putting nested defs in a contigous + * region and calculating counts from offets or vice-versa. */ + const upb_FieldDef* fields; + const upb_OneofDef* oneofs; + const upb_ExtensionRange* ext_ranges; + const upb_MessageDef* nested_msgs; + const upb_EnumDef* nested_enums; + const upb_FieldDef* nested_exts; int field_count; - int oneof_count; int real_oneof_count; + int oneof_count; int ext_range_count; - - /* Is this a map-entry message? */ - bool map_entry; - bool is_message_set; - upb_wellknowntype_t well_known_type; - const upb_fielddef *message_set_ext; + int nested_msg_count; + int nested_enum_count; + int nested_ext_count; + bool in_message_set; + upb_WellKnown well_known_type; }; -struct upb_enumdef { - const upb_filedef *file; - const char *full_name; +struct upb_EnumDef { + const google_protobuf_EnumOptions* opts; + const upb_MiniTable_Enum* layout; // Only for proto2. + const upb_FileDef* file; + const upb_MessageDef* containing_type; // Could be merged with "file". + const char* full_name; upb_strtable ntoi; upb_inttable iton; - const upb_enumvaldef *values; + const upb_EnumValueDef* values; int value_count; int32_t defaultval; }; -struct upb_enumvaldef { - const upb_enumdef *enum_; - const char *full_name; +struct upb_EnumValueDef { + const google_protobuf_EnumValueOptions* opts; + const upb_EnumDef* parent; + const char* full_name; int32_t number; }; -struct upb_oneofdef { - const upb_msgdef *parent; - const char *full_name; +struct upb_OneofDef { + const google_protobuf_OneofOptions* opts; + const upb_MessageDef* parent; + const char* full_name; int field_count; bool synthetic; - const upb_fielddef **fields; + const upb_FieldDef** fields; upb_strtable ntof; upb_inttable itof; }; -struct upb_filedef { - const char *name; - const char *package; - const char *phpprefix; - const char *phpnamespace; - - const upb_filedef **deps; - const upb_msgdef *msgs; - const upb_enumdef *enums; - const upb_fielddef *exts; - const upb_msglayout_ext **ext_layouts; - const upb_symtab *symtab; +struct upb_FileDef { + const google_protobuf_FileOptions* opts; + const char* name; + const char* package; + + const upb_FileDef** deps; + const int32_t* public_deps; + const int32_t* weak_deps; + const upb_MessageDef* top_lvl_msgs; + const upb_EnumDef* top_lvl_enums; + const upb_FieldDef* top_lvl_exts; + const upb_ServiceDef* services; + const upb_MiniTable_Extension** ext_layouts; + const upb_DefPool* symtab; int dep_count; - int msg_count; - int enum_count; - int ext_count; - upb_syntax_t syntax; + int public_dep_count; + int weak_dep_count; + int top_lvl_msg_count; + int top_lvl_enum_count; + int top_lvl_ext_count; + int service_count; + int ext_count; /* All exts in the file. */ + upb_Syntax syntax; +}; + +struct upb_MethodDef { + const google_protobuf_MethodOptions* opts; + upb_ServiceDef* service; + const char* full_name; + const upb_MessageDef* input_type; + const upb_MessageDef* output_type; + bool client_streaming; + bool server_streaming; }; -struct upb_symtab { - upb_arena *arena; +struct upb_ServiceDef { + const google_protobuf_ServiceOptions* opts; + const upb_FileDef* file; + const char* full_name; + upb_MethodDef* methods; + int method_count; + int index; +}; + +struct upb_DefPool { + upb_Arena* arena; upb_strtable syms; /* full_name -> packed def ptr */ - upb_strtable files; /* file_name -> upb_filedef* */ - upb_inttable exts; /* upb_msglayout_ext* -> upb_fielddef* */ - upb_extreg *extreg; + upb_strtable files; /* file_name -> upb_FileDef* */ + upb_inttable exts; /* upb_MiniTable_Extension* -> upb_FieldDef* */ + upb_ExtensionRegistry* extreg; size_t bytes_loaded; }; @@ -163,31 +214,38 @@ struct upb_symtab { typedef enum { UPB_DEFTYPE_MASK = 7, - UPB_DEFTYPE_FIELD = 0, - /* Only inside symtab table. */ + UPB_DEFTYPE_EXT = 0, UPB_DEFTYPE_MSG = 1, UPB_DEFTYPE_ENUM = 2, UPB_DEFTYPE_ENUMVAL = 3, + UPB_DEFTYPE_SERVICE = 4, /* Only inside message table. */ + UPB_DEFTYPE_FIELD = 0, UPB_DEFTYPE_ONEOF = 1, - UPB_DEFTYPE_FIELD_JSONNAME = 2 + UPB_DEFTYPE_FIELD_JSONNAME = 2, + + /* Only inside file table. */ + UPB_DEFTYPE_FILE = 0, + UPB_DEFTYPE_LAYOUT = 1 } upb_deftype_t; +#define FIELD_TYPE_UNSPECIFIED 0 + static upb_deftype_t deftype(upb_value v) { uintptr_t num = (uintptr_t)upb_value_getconstptr(v); return num & UPB_DEFTYPE_MASK; } -static const void *unpack_def(upb_value v, upb_deftype_t type) { +static const void* unpack_def(upb_value v, upb_deftype_t type) { uintptr_t num = (uintptr_t)upb_value_getconstptr(v); return (num & UPB_DEFTYPE_MASK) == type - ? (const void *)(num & ~UPB_DEFTYPE_MASK) + ? (const void*)(num & ~UPB_DEFTYPE_MASK) : NULL; } -static upb_value pack_def(const void *ptr, upb_deftype_t type) { +static upb_value pack_def(const void* ptr, upb_deftype_t type) { uintptr_t num = (uintptr_t)ptr; UPB_ASSERT((num & UPB_DEFTYPE_MASK) == 0); num |= type; @@ -195,20 +253,28 @@ static upb_value pack_def(const void *ptr, upb_deftype_t type) { } /* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */ -static bool upb_isbetween(char c, char low, char high) { +static bool upb_isbetween(uint8_t c, uint8_t low, uint8_t high) { return c >= low && c <= high; } +static char upb_ascii_lower(char ch) { + // Per ASCII this will lower-case a letter. If the result is a letter, the + // input was definitely a letter. If the output is not a letter, this may + // have transformed the character unpredictably. + return ch | 0x20; +} + static bool upb_isletter(char c) { - return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_'; + char lower = upb_ascii_lower(c); + return upb_isbetween(lower, 'a', 'z') || c == '_'; } static bool upb_isalphanum(char c) { return upb_isletter(c) || upb_isbetween(c, '0', '9'); } -static const char *shortdefname(const char *fullname) { - const char *p; +static const char* shortdefname(const char* fullname) { + const char* p; if (fullname == NULL) { return NULL; @@ -223,402 +289,417 @@ static const char *shortdefname(const char *fullname) { /* All submessage fields are lower than all other fields. * Secondly, fields are increasing in order. */ -uint32_t field_rank(const upb_fielddef *f) { - uint32_t ret = upb_fielddef_number(f); +uint32_t field_rank(const upb_FieldDef* f) { + uint32_t ret = upb_FieldDef_Number(f); const uint32_t high_bit = 1 << 30; UPB_ASSERT(ret < high_bit); - if (!upb_fielddef_issubmsg(f)) - ret |= high_bit; + if (!upb_FieldDef_IsSubMessage(f)) ret |= high_bit; return ret; } -int cmp_fields(const void *p1, const void *p2) { - const upb_fielddef *f1 = *(upb_fielddef*const*)p1; - const upb_fielddef *f2 = *(upb_fielddef*const*)p2; +int cmp_fields(const void* p1, const void* p2) { + const upb_FieldDef* f1 = *(upb_FieldDef* const*)p1; + const upb_FieldDef* f2 = *(upb_FieldDef* const*)p2; return field_rank(f1) - field_rank(f2); } -static void upb_status_setoom(upb_status *status) { - upb_status_seterrmsg(status, "out of memory"); +static void upb_Status_setoom(upb_Status* status) { + upb_Status_SetErrorMessage(status, "out of memory"); } -static void assign_msg_wellknowntype(upb_msgdef *m) { - const char *name = upb_msgdef_fullname(m); +static void assign_msg_wellknowntype(upb_MessageDef* m) { + const char* name = upb_MessageDef_FullName(m); if (name == NULL) { - m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; + m->well_known_type = kUpb_WellKnown_Unspecified; return; } if (!strcmp(name, "google.protobuf.Any")) { - m->well_known_type = UPB_WELLKNOWN_ANY; + m->well_known_type = kUpb_WellKnown_Any; } else if (!strcmp(name, "google.protobuf.FieldMask")) { - m->well_known_type = UPB_WELLKNOWN_FIELDMASK; + m->well_known_type = kUpb_WellKnown_FieldMask; } else if (!strcmp(name, "google.protobuf.Duration")) { - m->well_known_type = UPB_WELLKNOWN_DURATION; + m->well_known_type = kUpb_WellKnown_Duration; } else if (!strcmp(name, "google.protobuf.Timestamp")) { - m->well_known_type = UPB_WELLKNOWN_TIMESTAMP; + m->well_known_type = kUpb_WellKnown_Timestamp; } else if (!strcmp(name, "google.protobuf.DoubleValue")) { - m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE; + m->well_known_type = kUpb_WellKnown_DoubleValue; } else if (!strcmp(name, "google.protobuf.FloatValue")) { - m->well_known_type = UPB_WELLKNOWN_FLOATVALUE; + m->well_known_type = kUpb_WellKnown_FloatValue; } else if (!strcmp(name, "google.protobuf.Int64Value")) { - m->well_known_type = UPB_WELLKNOWN_INT64VALUE; + m->well_known_type = kUpb_WellKnown_Int64Value; } else if (!strcmp(name, "google.protobuf.UInt64Value")) { - m->well_known_type = UPB_WELLKNOWN_UINT64VALUE; + m->well_known_type = kUpb_WellKnown_UInt64Value; } else if (!strcmp(name, "google.protobuf.Int32Value")) { - m->well_known_type = UPB_WELLKNOWN_INT32VALUE; + m->well_known_type = kUpb_WellKnown_Int32Value; } else if (!strcmp(name, "google.protobuf.UInt32Value")) { - m->well_known_type = UPB_WELLKNOWN_UINT32VALUE; + m->well_known_type = kUpb_WellKnown_UInt32Value; } else if (!strcmp(name, "google.protobuf.BoolValue")) { - m->well_known_type = UPB_WELLKNOWN_BOOLVALUE; + m->well_known_type = kUpb_WellKnown_BoolValue; } else if (!strcmp(name, "google.protobuf.StringValue")) { - m->well_known_type = UPB_WELLKNOWN_STRINGVALUE; + m->well_known_type = kUpb_WellKnown_StringValue; } else if (!strcmp(name, "google.protobuf.BytesValue")) { - m->well_known_type = UPB_WELLKNOWN_BYTESVALUE; + m->well_known_type = kUpb_WellKnown_BytesValue; } else if (!strcmp(name, "google.protobuf.Value")) { - m->well_known_type = UPB_WELLKNOWN_VALUE; + m->well_known_type = kUpb_WellKnown_Value; } else if (!strcmp(name, "google.protobuf.ListValue")) { - m->well_known_type = UPB_WELLKNOWN_LISTVALUE; + m->well_known_type = kUpb_WellKnown_ListValue; } else if (!strcmp(name, "google.protobuf.Struct")) { - m->well_known_type = UPB_WELLKNOWN_STRUCT; + m->well_known_type = kUpb_WellKnown_Struct; } else { - m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; + m->well_known_type = kUpb_WellKnown_Unspecified; } } +/* upb_EnumDef ****************************************************************/ -/* upb_enumdef ****************************************************************/ +const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) { + return e->opts; +} -const char *upb_enumdef_fullname(const upb_enumdef *e) { - return e->full_name; +bool upb_EnumDef_HasOptions(const upb_EnumDef* e) { + return e->opts != (void*)opt_default; } -const char *upb_enumdef_name(const upb_enumdef *e) { +const char* upb_EnumDef_FullName(const upb_EnumDef* e) { return e->full_name; } + +const char* upb_EnumDef_Name(const upb_EnumDef* e) { return shortdefname(e->full_name); } -const upb_filedef *upb_enumdef_file(const upb_enumdef *e) { - return e->file; +const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e) { return e->file; } + +const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e) { + return e->containing_type; } -int32_t upb_enumdef_default(const upb_enumdef *e) { - UPB_ASSERT(upb_enumdef_lookupnum(e, e->defaultval)); +int32_t upb_EnumDef_Default(const upb_EnumDef* e) { + UPB_ASSERT(upb_EnumDef_FindValueByNumber(e, e->defaultval)); return e->defaultval; } -const upb_enumvaldef *upb_enumdef_lookupname(const upb_enumdef *def, - const char *name, size_t len) { +int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; } + +const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( + const upb_EnumDef* def, const char* name, size_t len) { upb_value v; return upb_strtable_lookup2(&def->ntoi, name, len, &v) ? upb_value_getconstptr(v) : NULL; } -const upb_enumvaldef *upb_enumdef_lookupnum(const upb_enumdef *def, int32_t num) { +const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* def, + int32_t num) { upb_value v; return upb_inttable_lookup(&def->iton, num, &v) ? upb_value_getconstptr(v) : NULL; } -const upb_enumvaldef *upb_enumdef_value(const upb_enumdef *e, int i) { +bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num) { + // We could use upb_EnumDef_FindValueByNumber(e, num) != NULL, but we expect + // this to be faster (especially for small numbers). + return upb_MiniTable_Enum_CheckValue(e->layout, num); +} + +const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) { UPB_ASSERT(0 <= i && i < e->value_count); return &e->values[i]; } -// Deprecated functions. +/* upb_EnumValueDef ***********************************************************/ -int upb_enumdef_numvals(const upb_enumdef *e) { - return (int)upb_strtable_count(&e->ntoi); +const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( + const upb_EnumValueDef* e) { + return e->opts; } -void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) { - /* We iterate over the ntoi table, to account for duplicate numbers. */ - upb_strtable_begin(i, &e->ntoi); +bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* e) { + return e->opts != (void*)opt_default; } -void upb_enum_next(upb_enum_iter *iter) { upb_strtable_next(iter); } -bool upb_enum_done(upb_enum_iter *iter) { return upb_strtable_done(iter); } - -const char *upb_enum_iter_name(upb_enum_iter *iter) { - return upb_strtable_iter_key(iter).data; +const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* ev) { + return ev->parent; } -int32_t upb_enum_iter_number(upb_enum_iter *iter) { - return upb_value_getint32(upb_strtable_iter_value(iter)); +const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* ev) { + return ev->full_name; } +const char* upb_EnumValueDef_Name(const upb_EnumValueDef* ev) { + return shortdefname(ev->full_name); +} -/* upb_enumvaldef *************************************************************/ +int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* ev) { + return ev->number; +} -const upb_enumdef *upb_enumvaldef_enum(const upb_enumvaldef *ev) { - return ev->enum_; +uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* ev) { + // Compute index in our parent's array. + return ev - ev->parent->values; } -const char *upb_enumvaldef_fullname(const upb_enumvaldef *ev) { - return ev->full_name; +/* upb_ExtensionRange + * ***************************************************************/ + +const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options( + const upb_ExtensionRange* r) { + return r->opts; } -const char *upb_enumvaldef_name(const upb_enumvaldef *ev) { - return shortdefname(ev->full_name); +bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r) { + return r->opts != (void*)opt_default; } -int32_t upb_enumvaldef_number(const upb_enumvaldef *ev) { - return ev->number; +int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* e) { + return e->start; } +int32_t upb_ExtensionRange_End(const upb_ExtensionRange* e) { return e->end; } + +/* upb_FieldDef ***************************************************************/ + +const google_protobuf_FieldOptions* upb_FieldDef_Options( + const upb_FieldDef* f) { + return f->opts; +} -/* upb_fielddef ***************************************************************/ +bool upb_FieldDef_HasOptions(const upb_FieldDef* f) { + return f->opts != (void*)opt_default; +} -const char *upb_fielddef_fullname(const upb_fielddef *f) { +const char* upb_FieldDef_FullName(const upb_FieldDef* f) { return f->full_name; } -upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f) { +upb_CType upb_FieldDef_CType(const upb_FieldDef* f) { switch (f->type_) { - case UPB_DESCRIPTOR_TYPE_DOUBLE: - return UPB_TYPE_DOUBLE; - case UPB_DESCRIPTOR_TYPE_FLOAT: - return UPB_TYPE_FLOAT; - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_SINT64: - case UPB_DESCRIPTOR_TYPE_SFIXED64: - return UPB_TYPE_INT64; - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - case UPB_DESCRIPTOR_TYPE_SINT32: - return UPB_TYPE_INT32; - case UPB_DESCRIPTOR_TYPE_UINT64: - case UPB_DESCRIPTOR_TYPE_FIXED64: - return UPB_TYPE_UINT64; - case UPB_DESCRIPTOR_TYPE_UINT32: - case UPB_DESCRIPTOR_TYPE_FIXED32: - return UPB_TYPE_UINT32; - case UPB_DESCRIPTOR_TYPE_ENUM: - return UPB_TYPE_ENUM; - case UPB_DESCRIPTOR_TYPE_BOOL: - return UPB_TYPE_BOOL; - case UPB_DESCRIPTOR_TYPE_STRING: - return UPB_TYPE_STRING; - case UPB_DESCRIPTOR_TYPE_BYTES: - return UPB_TYPE_BYTES; - case UPB_DESCRIPTOR_TYPE_GROUP: - case UPB_DESCRIPTOR_TYPE_MESSAGE: - return UPB_TYPE_MESSAGE; + case kUpb_FieldType_Double: + return kUpb_CType_Double; + case kUpb_FieldType_Float: + return kUpb_CType_Float; + case kUpb_FieldType_Int64: + case kUpb_FieldType_SInt64: + case kUpb_FieldType_SFixed64: + return kUpb_CType_Int64; + case kUpb_FieldType_Int32: + case kUpb_FieldType_SFixed32: + case kUpb_FieldType_SInt32: + return kUpb_CType_Int32; + case kUpb_FieldType_UInt64: + case kUpb_FieldType_Fixed64: + return kUpb_CType_UInt64; + case kUpb_FieldType_UInt32: + case kUpb_FieldType_Fixed32: + return kUpb_CType_UInt32; + case kUpb_FieldType_Enum: + return kUpb_CType_Enum; + case kUpb_FieldType_Bool: + return kUpb_CType_Bool; + case kUpb_FieldType_String: + return kUpb_CType_String; + case kUpb_FieldType_Bytes: + return kUpb_CType_Bytes; + case kUpb_FieldType_Group: + case kUpb_FieldType_Message: + return kUpb_CType_Message; } UPB_UNREACHABLE(); } -upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f) { - return f->type_; -} +upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f) { return f->type_; } -uint32_t upb_fielddef_index(const upb_fielddef *f) { - return f->index_; -} +uint32_t upb_FieldDef_Index(const upb_FieldDef* f) { return f->index_; } -upb_label_t upb_fielddef_label(const upb_fielddef *f) { - return f->label_; -} +upb_Label upb_FieldDef_Label(const upb_FieldDef* f) { return f->label_; } -uint32_t upb_fielddef_number(const upb_fielddef *f) { - return f->number_; -} +uint32_t upb_FieldDef_Number(const upb_FieldDef* f) { return f->number_; } -bool upb_fielddef_isextension(const upb_fielddef *f) { +bool upb_FieldDef_IsExtension(const upb_FieldDef* f) { return f->is_extension_; } -bool upb_fielddef_lazy(const upb_fielddef *f) { - return f->lazy_; -} - -bool upb_fielddef_packed(const upb_fielddef *f) { - return f->packed_; -} +bool upb_FieldDef_IsPacked(const upb_FieldDef* f) { return f->packed_; } -const char *upb_fielddef_name(const upb_fielddef *f) { +const char* upb_FieldDef_Name(const upb_FieldDef* f) { return shortdefname(f->full_name); } -const char *upb_fielddef_jsonname(const upb_fielddef *f) { +const char* upb_FieldDef_JsonName(const upb_FieldDef* f) { return f->json_name; } -const upb_filedef *upb_fielddef_file(const upb_fielddef *f) { - return f->file; +bool upb_FieldDef_HasJsonName(const upb_FieldDef* f) { + return f->has_json_name_; } -const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) { - return f->msgdef; -} +const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f) { return f->file; } -const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) { - return f->oneof; -} - -const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f) { - if (!f->oneof || upb_oneofdef_issynthetic(f->oneof)) return NULL; - return f->oneof; +const upb_MessageDef* upb_FieldDef_ContainingType(const upb_FieldDef* f) { + return f->msgdef; } -upb_msgval upb_fielddef_default(const upb_fielddef *f) { - UPB_ASSERT(!upb_fielddef_issubmsg(f)); - upb_msgval ret; - if (upb_fielddef_isstring(f)) { - str_t *str = f->defaultval.str; - if (str) { - ret.str_val.data = str->str; - ret.str_val.size = str->len; - } else { - ret.str_val.size = 0; +const upb_MessageDef* upb_FieldDef_ExtensionScope(const upb_FieldDef* f) { + return f->is_extension_ ? f->scope.extension_scope : NULL; +} + +const upb_OneofDef* upb_FieldDef_ContainingOneof(const upb_FieldDef* f) { + return f->is_extension_ ? NULL : f->scope.oneof; +} + +const upb_OneofDef* upb_FieldDef_RealContainingOneof(const upb_FieldDef* f) { + const upb_OneofDef* oneof = upb_FieldDef_ContainingOneof(f); + if (!oneof || upb_OneofDef_IsSynthetic(oneof)) return NULL; + return oneof; +} + +upb_MessageValue upb_FieldDef_Default(const upb_FieldDef* f) { + UPB_ASSERT(!upb_FieldDef_IsSubMessage(f)); + upb_MessageValue ret; + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + return (upb_MessageValue){.bool_val = f->defaultval.boolean}; + case kUpb_CType_Int64: + return (upb_MessageValue){.int64_val = f->defaultval.sint}; + case kUpb_CType_UInt64: + return (upb_MessageValue){.uint64_val = f->defaultval.uint}; + case kUpb_CType_Enum: + case kUpb_CType_Int32: + return (upb_MessageValue){.int32_val = (int32_t)f->defaultval.sint}; + case kUpb_CType_UInt32: + return (upb_MessageValue){.uint32_val = (uint32_t)f->defaultval.uint}; + case kUpb_CType_Float: + return (upb_MessageValue){.float_val = f->defaultval.flt}; + case kUpb_CType_Double: + return (upb_MessageValue){.double_val = f->defaultval.dbl}; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + str_t* str = f->defaultval.str; + if (str) { + return (upb_MessageValue){ + .str_val = (upb_StringView){.data = str->str, .size = str->len}}; + } else { + return (upb_MessageValue){ + .str_val = (upb_StringView){.data = NULL, .size = 0}}; + } } - } else { - memcpy(&ret, &f->defaultval, 8); + default: + UPB_UNREACHABLE(); } - return ret; -} - -static void chkdefaulttype(const upb_fielddef *f, int ctype) { - UPB_UNUSED(f); - UPB_UNUSED(ctype); -} -int64_t upb_fielddef_defaultint64(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_INT64); - return f->defaultval.sint; + return ret; } -int32_t upb_fielddef_defaultint32(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_INT32); - return (int32_t)f->defaultval.sint; +const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Message ? f->sub.msgdef : NULL; } -uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_UINT64); - return f->defaultval.uint; +const upb_EnumDef* upb_FieldDef_EnumSubDef(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Enum ? f->sub.enumdef : NULL; } -uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_UINT32); - return (uint32_t)f->defaultval.uint; +const upb_MiniTable_Field* upb_FieldDef_MiniTable(const upb_FieldDef* f) { + UPB_ASSERT(!upb_FieldDef_IsExtension(f)); + return &f->msgdef->layout->fields[f->layout_index]; } -bool upb_fielddef_defaultbool(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_BOOL); - return f->defaultval.boolean; +const upb_MiniTable_Extension* _upb_FieldDef_ExtensionMiniTable( + const upb_FieldDef* f) { + UPB_ASSERT(upb_FieldDef_IsExtension(f)); + return f->file->ext_layouts[f->layout_index]; } -float upb_fielddef_defaultfloat(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_FLOAT); - return f->defaultval.flt; +bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f) { + return f->proto3_optional_; } -double upb_fielddef_defaultdouble(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_DOUBLE); - return f->defaultval.dbl; +bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Message; } -const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) { - str_t *str = f->defaultval.str; - UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_STRING || - upb_fielddef_type(f) == UPB_TYPE_BYTES || - upb_fielddef_type(f) == UPB_TYPE_ENUM); - if (str) { - if (len) *len = str->len; - return str->str; - } else { - if (len) *len = 0; - return NULL; - } +bool upb_FieldDef_IsString(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_String || + upb_FieldDef_CType(f) == kUpb_CType_Bytes; } -const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) { - return upb_fielddef_type(f) == UPB_TYPE_MESSAGE ? f->sub.msgdef : NULL; +bool upb_FieldDef_IsRepeated(const upb_FieldDef* f) { + return upb_FieldDef_Label(f) == kUpb_Label_Repeated; } -const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) { - return upb_fielddef_type(f) == UPB_TYPE_ENUM ? f->sub.enumdef : NULL; +bool upb_FieldDef_IsPrimitive(const upb_FieldDef* f) { + return !upb_FieldDef_IsString(f) && !upb_FieldDef_IsSubMessage(f); } -const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f) { - UPB_ASSERT(!upb_fielddef_isextension(f)); - return &f->msgdef->layout->fields[f->layout_index]; +bool upb_FieldDef_IsMap(const upb_FieldDef* f) { + return upb_FieldDef_IsRepeated(f) && upb_FieldDef_IsSubMessage(f) && + upb_MessageDef_IsMapEntry(upb_FieldDef_MessageSubDef(f)); } -const upb_msglayout_ext *_upb_fielddef_extlayout(const upb_fielddef *f) { - UPB_ASSERT(upb_fielddef_isextension(f)); - return f->file->ext_layouts[f->layout_index]; -} - -bool upb_fielddef_issubmsg(const upb_fielddef *f) { - return upb_fielddef_type(f) == UPB_TYPE_MESSAGE; -} +bool upb_FieldDef_HasDefault(const upb_FieldDef* f) { return f->has_default; } -bool upb_fielddef_isstring(const upb_fielddef *f) { - return upb_fielddef_type(f) == UPB_TYPE_STRING || - upb_fielddef_type(f) == UPB_TYPE_BYTES; +bool upb_FieldDef_HasSubDef(const upb_FieldDef* f) { + return upb_FieldDef_IsSubMessage(f) || + upb_FieldDef_CType(f) == kUpb_CType_Enum; } -bool upb_fielddef_isseq(const upb_fielddef *f) { - return upb_fielddef_label(f) == UPB_LABEL_REPEATED; +bool upb_FieldDef_HasPresence(const upb_FieldDef* f) { + if (upb_FieldDef_IsRepeated(f)) return false; + return upb_FieldDef_IsSubMessage(f) || upb_FieldDef_ContainingOneof(f) || + f->file->syntax == kUpb_Syntax_Proto2; } -bool upb_fielddef_isprimitive(const upb_fielddef *f) { - return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f); +static bool between(int32_t x, int32_t low, int32_t high) { + return x >= low && x <= high; } -bool upb_fielddef_ismap(const upb_fielddef *f) { - return upb_fielddef_isseq(f) && upb_fielddef_issubmsg(f) && - upb_msgdef_mapentry(upb_fielddef_msgsubdef(f)); -} +bool upb_FieldDef_checklabel(int32_t label) { return between(label, 1, 3); } +bool upb_FieldDef_checktype(int32_t type) { return between(type, 1, 11); } +bool upb_FieldDef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); } -bool upb_fielddef_hassubdef(const upb_fielddef *f) { - return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM; +bool upb_FieldDef_checkdescriptortype(int32_t type) { + return between(type, 1, 18); } -bool upb_fielddef_haspresence(const upb_fielddef *f) { - if (upb_fielddef_isseq(f)) return false; - return upb_fielddef_issubmsg(f) || upb_fielddef_containingoneof(f) || - f->file->syntax == UPB_SYNTAX_PROTO2; -} +/* upb_MessageDef + * *****************************************************************/ -static bool between(int32_t x, int32_t low, int32_t high) { - return x >= low && x <= high; +const google_protobuf_MessageOptions* upb_MessageDef_Options( + const upb_MessageDef* m) { + return m->opts; } -bool upb_fielddef_checklabel(int32_t label) { return between(label, 1, 3); } -bool upb_fielddef_checktype(int32_t type) { return between(type, 1, 11); } -bool upb_fielddef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); } - -bool upb_fielddef_checkdescriptortype(int32_t type) { - return between(type, 1, 18); +bool upb_MessageDef_HasOptions(const upb_MessageDef* m) { + return m->opts != (void*)opt_default; } -/* upb_msgdef *****************************************************************/ - -const char *upb_msgdef_fullname(const upb_msgdef *m) { +const char* upb_MessageDef_FullName(const upb_MessageDef* m) { return m->full_name; } -const upb_filedef *upb_msgdef_file(const upb_msgdef *m) { +const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m) { return m->file; } -const char *upb_msgdef_name(const upb_msgdef *m) { +const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m) { + return m->containing_type; +} + +const char* upb_MessageDef_Name(const upb_MessageDef* m) { return shortdefname(m->full_name); } -upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) { +upb_Syntax upb_MessageDef_Syntax(const upb_MessageDef* m) { return m->file->syntax; } -const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) { +const upb_FieldDef* upb_MessageDef_FindFieldByNumber(const upb_MessageDef* m, + uint32_t i) { upb_value val; return upb_inttable_lookup(&m->itof, i, &val) ? upb_value_getconstptr(val) : NULL; } -const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, - size_t len) { +const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize( + const upb_MessageDef* m, const char* name, size_t len) { upb_value val; if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { @@ -628,8 +709,8 @@ const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, return unpack_def(val, UPB_DEFTYPE_FIELD); } -const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, - size_t len) { +const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize( + const upb_MessageDef* m, const char* name, size_t len) { upb_value val; if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { @@ -639,23 +720,27 @@ const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, return unpack_def(val, UPB_DEFTYPE_ONEOF); } -bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, - const upb_fielddef **f, const upb_oneofdef **o) { +bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m, + const char* name, size_t len, + const upb_FieldDef** out_f, + const upb_OneofDef** out_o) { upb_value val; if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { return false; } - *o = unpack_def(val, UPB_DEFTYPE_ONEOF); - *f = unpack_def(val, UPB_DEFTYPE_FIELD); - return *o || *f; /* False if this was a JSON name. */ + const upb_FieldDef* f = unpack_def(val, UPB_DEFTYPE_FIELD); + const upb_OneofDef* o = unpack_def(val, UPB_DEFTYPE_ONEOF); + if (out_f) *out_f = f; + if (out_o) *out_o = o; + return f || o; /* False if this was a JSON name. */ } -const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, - const char *name, size_t len) { +const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize( + const upb_MessageDef* m, const char* name, size_t len) { upb_value val; - const upb_fielddef* f; + const upb_FieldDef* f; if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { return NULL; @@ -667,257 +752,316 @@ const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, return f; } -int upb_msgdef_numfields(const upb_msgdef *m) { - return m->field_count; -} +int upb_MessageDef_numfields(const upb_MessageDef* m) { return m->field_count; } -int upb_msgdef_numoneofs(const upb_msgdef *m) { - return m->oneof_count; -} +int upb_MessageDef_numoneofs(const upb_MessageDef* m) { return m->oneof_count; } -int upb_msgdef_numrealoneofs(const upb_msgdef *m) { +int upb_MessageDef_numrealoneofs(const upb_MessageDef* m) { return m->real_oneof_count; } -int upb_msgdef_extrangecount(const upb_msgdef *m) { +int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m) { return m->ext_range_count; } -int upb_msgdef_fieldcount(const upb_msgdef *m) { +int upb_MessageDef_FieldCount(const upb_MessageDef* m) { return m->field_count; } -int upb_msgdef_oneofcount(const upb_msgdef *m) { +int upb_MessageDef_OneofCount(const upb_MessageDef* m) { return m->oneof_count; } -int upb_msgdef_realoneofcount(const upb_msgdef *m) { +int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m) { + return m->nested_msg_count; +} + +int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m) { + return m->nested_enum_count; +} + +int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m) { + return m->nested_ext_count; +} + +int upb_MessageDef_realoneofcount(const upb_MessageDef* m) { return m->real_oneof_count; } -const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) { +const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m) { return m->layout; } -const upb_extrange *upb_msgdef_extrange(const upb_msgdef *m, int i) { - UPB_ASSERT(i >= 0 && i < m->ext_range_count); +const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->ext_range_count); return &m->ext_ranges[i]; } -const upb_fielddef *upb_msgdef_field(const upb_msgdef *m, int i) { - UPB_ASSERT(i >= 0 && i < m->field_count); +const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->field_count); return &m->fields[i]; } -const upb_oneofdef *upb_msgdef_oneof(const upb_msgdef *m, int i) { - UPB_ASSERT(i >= 0 && i < m->oneof_count); +const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->oneof_count); return &m->oneofs[i]; } -bool upb_msgdef_mapentry(const upb_msgdef *m) { - return m->map_entry; +const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->nested_msg_count); + return &m->nested_msgs[i]; } -upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m) { - return m->well_known_type; +const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->nested_enum_count); + return &m->nested_enums[i]; } -bool upb_msgdef_isnumberwrapper(const upb_msgdef *m) { - upb_wellknowntype_t type = upb_msgdef_wellknowntype(m); - return type >= UPB_WELLKNOWN_DOUBLEVALUE && - type <= UPB_WELLKNOWN_UINT32VALUE; +const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->nested_ext_count); + return &m->nested_exts[i]; } -bool upb_msgdef_iswrapper(const upb_msgdef *m) { - upb_wellknowntype_t type = upb_msgdef_wellknowntype(m); - return type >= UPB_WELLKNOWN_DOUBLEVALUE && - type <= UPB_WELLKNOWN_BOOLVALUE; +upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m) { + return m->well_known_type; } -void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) { - upb_inttable_begin(iter, &m->itof); +/* upb_OneofDef ***************************************************************/ + +const google_protobuf_OneofOptions* upb_OneofDef_Options( + const upb_OneofDef* o) { + return o->opts; } -void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); } +bool upb_OneofDef_HasOptions(const upb_OneofDef* o) { + return o->opts != (void*)opt_default; +} -bool upb_msg_field_done(const upb_msg_field_iter *iter) { - return upb_inttable_done(iter); +const char* upb_OneofDef_Name(const upb_OneofDef* o) { + return shortdefname(o->full_name); } -upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) { - return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); +const upb_MessageDef* upb_OneofDef_ContainingType(const upb_OneofDef* o) { + return o->parent; } -void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) { - upb_inttable_iter_setdone(iter); +int upb_OneofDef_FieldCount(const upb_OneofDef* o) { return o->field_count; } + +const upb_FieldDef* upb_OneofDef_Field(const upb_OneofDef* o, int i) { + UPB_ASSERT(i < o->field_count); + return o->fields[i]; } -bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1, - const upb_msg_field_iter * iter2) { - return upb_inttable_iter_isequal(iter1, iter2); +int upb_OneofDef_numfields(const upb_OneofDef* o) { return o->field_count; } + +uint32_t upb_OneofDef_Index(const upb_OneofDef* o) { + // Compute index in our parent's array. + return o - o->parent->oneofs; } -void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) { - upb_strtable_begin(iter, &m->ntof); - /* We need to skip past any initial fields. */ - while (!upb_strtable_done(iter) && - !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)) { - upb_strtable_next(iter); - } +bool upb_OneofDef_IsSynthetic(const upb_OneofDef* o) { return o->synthetic; } + +const upb_FieldDef* upb_OneofDef_LookupNameWithSize(const upb_OneofDef* o, + const char* name, + size_t length) { + upb_value val; + return upb_strtable_lookup2(&o->ntof, name, length, &val) + ? upb_value_getptr(val) + : NULL; } -void upb_msg_oneof_next(upb_msg_oneof_iter *iter) { - /* We need to skip past fields to return only oneofs. */ - do { - upb_strtable_next(iter); - } while (!upb_strtable_done(iter) && - !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)); +const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, + uint32_t num) { + upb_value val; + return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val) + : NULL; } -bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { - return upb_strtable_done(iter); +/* upb_FileDef ****************************************************************/ + +const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f) { + return f->opts; } -const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { - return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF); +bool upb_FileDef_HasOptions(const upb_FileDef* f) { + return f->opts != (void*)opt_default; } -void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { - upb_strtable_iter_setdone(iter); +const char* upb_FileDef_Name(const upb_FileDef* f) { return f->name; } + +const char* upb_FileDef_Package(const upb_FileDef* f) { return f->package; } + +upb_Syntax upb_FileDef_Syntax(const upb_FileDef* f) { return f->syntax; } + +int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f) { + return f->top_lvl_msg_count; } -bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, - const upb_msg_oneof_iter *iter2) { - return upb_strtable_iter_isequal(iter1, iter2); +int upb_FileDef_DependencyCount(const upb_FileDef* f) { return f->dep_count; } + +int upb_FileDef_PublicDependencyCount(const upb_FileDef* f) { + return f->public_dep_count; } -/* upb_oneofdef ***************************************************************/ +int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) { + return f->weak_dep_count; +} -const char *upb_oneofdef_name(const upb_oneofdef *o) { - return shortdefname(o->full_name); +const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) { + return f->public_deps; } -const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { - return o->parent; +const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f) { + return f->weak_deps; } -int upb_oneofdef_fieldcount(const upb_oneofdef *o) { - return o->field_count; +int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) { + return f->top_lvl_enum_count; } -const upb_fielddef *upb_oneofdef_field(const upb_oneofdef *o, int i) { - UPB_ASSERT(i < o->field_count); - return o->fields[i]; +int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f) { + return f->top_lvl_ext_count; } -int upb_oneofdef_numfields(const upb_oneofdef *o) { - return o->field_count; +int upb_FileDef_ServiceCount(const upb_FileDef* f) { return f->service_count; } + +const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->dep_count); + return f->deps[i]; } -uint32_t upb_oneofdef_index(const upb_oneofdef *o) { - return o - o->parent->oneofs; +const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->public_dep_count); + return f->deps[f->public_deps[i]]; } -bool upb_oneofdef_issynthetic(const upb_oneofdef *o) { - return o->synthetic; +const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->public_dep_count); + return f->deps[f->weak_deps[i]]; } -const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, - const char *name, size_t length) { - upb_value val; - return upb_strtable_lookup2(&o->ntof, name, length, &val) ? - upb_value_getptr(val) : NULL; +const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_msg_count); + return &f->top_lvl_msgs[i]; } -const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) { - upb_value val; - return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val) - : NULL; +const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_enum_count); + return &f->top_lvl_enums[i]; } -void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) { - upb_inttable_begin(iter, &o->itof); +const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_ext_count); + return &f->top_lvl_exts[i]; } -void upb_oneof_next(upb_oneof_iter *iter) { - upb_inttable_next(iter); +const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->service_count); + return &f->services[i]; } -bool upb_oneof_done(upb_oneof_iter *iter) { - return upb_inttable_done(iter); +const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f) { return f->symtab; } + +/* upb_MethodDef **************************************************************/ + +const google_protobuf_MethodOptions* upb_MethodDef_Options( + const upb_MethodDef* m) { + return m->opts; } -upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) { - return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); +bool upb_MethodDef_HasOptions(const upb_MethodDef* m) { + return m->opts != (void*)opt_default; } -void upb_oneof_iter_setdone(upb_oneof_iter *iter) { - upb_inttable_iter_setdone(iter); +const char* upb_MethodDef_FullName(const upb_MethodDef* m) { + return m->full_name; } -/* upb_filedef ****************************************************************/ +const char* upb_MethodDef_Name(const upb_MethodDef* m) { + return shortdefname(m->full_name); +} -const char *upb_filedef_name(const upb_filedef *f) { - return f->name; +const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m) { + return m->service; } -const char *upb_filedef_package(const upb_filedef *f) { - return f->package; +const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m) { + return m->input_type; } -const char *upb_filedef_phpprefix(const upb_filedef *f) { - return f->phpprefix; +const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m) { + return m->output_type; } -const char *upb_filedef_phpnamespace(const upb_filedef *f) { - return f->phpnamespace; +bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m) { + return m->client_streaming; } -upb_syntax_t upb_filedef_syntax(const upb_filedef *f) { - return f->syntax; +bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m) { + return m->server_streaming; } -int upb_filedef_msgcount(const upb_filedef *f) { - return f->msg_count; +/* upb_ServiceDef *************************************************************/ + +const google_protobuf_ServiceOptions* upb_ServiceDef_Options( + const upb_ServiceDef* s) { + return s->opts; } -int upb_filedef_depcount(const upb_filedef *f) { - return f->dep_count; +bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s) { + return s->opts != (void*)opt_default; } -int upb_filedef_enumcount(const upb_filedef *f) { - return f->enum_count; +const char* upb_ServiceDef_FullName(const upb_ServiceDef* s) { + return s->full_name; } -const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) { - return i < 0 || i >= f->dep_count ? NULL : f->deps[i]; +const char* upb_ServiceDef_Name(const upb_ServiceDef* s) { + return shortdefname(s->full_name); } -const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) { - return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i]; +int upb_ServiceDef_Index(const upb_ServiceDef* s) { return s->index; } + +const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s) { + return s->file; } -const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) { - return i < 0 || i >= f->enum_count ? NULL : &f->enums[i]; +int upb_ServiceDef_MethodCount(const upb_ServiceDef* s) { + return s->method_count; } -const upb_symtab *upb_filedef_symtab(const upb_filedef *f) { - return f->symtab; +const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i) { + return i < 0 || i >= s->method_count ? NULL : &s->methods[i]; +} + +const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, + const char* name) { + for (int i = 0; i < s->method_count; i++) { + if (strcmp(name, upb_MethodDef_Name(&s->methods[i])) == 0) { + return &s->methods[i]; + } + } + return NULL; } -void upb_symtab_free(upb_symtab *s) { - upb_arena_free(s->arena); +/* upb_DefPool ****************************************************************/ + +void upb_DefPool_Free(upb_DefPool* s) { + upb_Arena_Free(s->arena); upb_gfree(s); } -upb_symtab *upb_symtab_new(void) { - upb_symtab *s = upb_gmalloc(sizeof(*s)); +upb_DefPool* upb_DefPool_New(void) { + upb_DefPool* s = upb_gmalloc(sizeof(*s)); if (!s) { return NULL; } - s->arena = upb_arena_new(); + s->arena = upb_Arena_New(); s->bytes_loaded = 0; if (!upb_strtable_init(&s->syms, 32, s->arena) || @@ -926,50 +1070,68 @@ upb_symtab *upb_symtab_new(void) { goto err; } - s->extreg = upb_extreg_new(s->arena); + s->extreg = upb_ExtensionRegistry_New(s->arena); if (!s->extreg) goto err; return s; err: - upb_arena_free(s->arena); + upb_Arena_Free(s->arena); upb_gfree(s); return NULL; } -const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) { +static const void* symtab_lookup(const upb_DefPool* s, const char* sym, + upb_deftype_t type) { upb_value v; - return upb_strtable_lookup(&s->syms, sym, &v) ? - unpack_def(v, UPB_DEFTYPE_MSG) : NULL; + return upb_strtable_lookup(&s->syms, sym, &v) ? unpack_def(v, type) : NULL; } -static const void *symtab_lookup2(const upb_symtab *s, const char *sym, +static const void* symtab_lookup2(const upb_DefPool* s, const char* sym, size_t size, upb_deftype_t type) { upb_value v; return upb_strtable_lookup2(&s->syms, sym, size, &v) ? unpack_def(v, type) : NULL; } -const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym, - size_t len) { +const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s, + const char* sym) { + return symtab_lookup(s, sym, UPB_DEFTYPE_MSG); +} + +const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len) { return symtab_lookup2(s, sym, len, UPB_DEFTYPE_MSG); } -const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) { +const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s, + const char* sym) { + return symtab_lookup(s, sym, UPB_DEFTYPE_ENUM); +} + +const upb_EnumValueDef* upb_DefPool_FindEnumByNameval(const upb_DefPool* s, + const char* sym) { + return symtab_lookup(s, sym, UPB_DEFTYPE_ENUMVAL); +} + +const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s, + const char* name) { upb_value v; - return upb_strtable_lookup(&s->syms, sym, &v) ? - unpack_def(v, UPB_DEFTYPE_ENUM) : NULL; + return upb_strtable_lookup(&s->files, name, &v) + ? unpack_def(v, UPB_DEFTYPE_FILE) + : NULL; } -const upb_enumvaldef *upb_symtab_lookupenumval(const upb_symtab *s, - const char *sym) { +const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, + const char* name, + size_t len) { upb_value v; - return upb_strtable_lookup(&s->syms, sym, &v) - ? unpack_def(v, UPB_DEFTYPE_ENUMVAL) + return upb_strtable_lookup2(&s->files, name, len, &v) + ? unpack_def(v, UPB_DEFTYPE_FILE) : NULL; } -const upb_fielddef *upb_symtab_lookupext2(const upb_symtab *s, const char *name, - size_t size) { +const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( + const upb_DefPool* s, const char* name, size_t size) { upb_value v; if (!upb_strtable_lookup2(&s->syms, name, size, &v)) return NULL; @@ -977,8 +1139,8 @@ const upb_fielddef *upb_symtab_lookupext2(const upb_symtab *s, const char *name, case UPB_DEFTYPE_FIELD: return unpack_def(v, UPB_DEFTYPE_FIELD); case UPB_DEFTYPE_MSG: { - const upb_msgdef *m = unpack_def(v, UPB_DEFTYPE_MSG); - return m->message_set_ext; /* May be NULL if not in MessageeSet. */ + const upb_MessageDef* m = unpack_def(v, UPB_DEFTYPE_MSG); + return m->in_message_set ? &m->nested_exts[0] : NULL; } default: break; @@ -987,25 +1149,66 @@ const upb_fielddef *upb_symtab_lookupext2(const upb_symtab *s, const char *name, return NULL; } -const upb_fielddef *upb_symtab_lookupext(const upb_symtab *s, const char *sym) { - return upb_symtab_lookupext2(s, sym, strlen(sym)); +const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, + const char* sym) { + return upb_DefPool_FindExtensionByNameWithSize(s, sym, strlen(sym)); } -const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) { - upb_value v; - return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v) - : NULL; +const upb_ServiceDef* upb_DefPool_FindServiceByName(const upb_DefPool* s, + const char* name) { + return symtab_lookup(s, name, UPB_DEFTYPE_SERVICE); } -const upb_filedef *upb_symtab_lookupfile2( - const upb_symtab *s, const char *name, size_t len) { - upb_value v; - return upb_strtable_lookup2(&s->files, name, len, &v) ? - upb_value_getconstptr(v) : NULL; +const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize( + const upb_DefPool* s, const char* name, size_t size) { + return symtab_lookup2(s, name, size, UPB_DEFTYPE_SERVICE); } -int upb_symtab_filecount(const upb_symtab *s) { - return (int)upb_strtable_count(&s->files); +const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, + const char* name) { + upb_value v; + // TODO(haberman): non-extension fields and oneofs. + if (upb_strtable_lookup(&s->syms, name, &v)) { + switch (deftype(v)) { + case UPB_DEFTYPE_EXT: { + const upb_FieldDef* f = unpack_def(v, UPB_DEFTYPE_EXT); + return upb_FieldDef_File(f); + } + case UPB_DEFTYPE_MSG: { + const upb_MessageDef* m = unpack_def(v, UPB_DEFTYPE_MSG); + return upb_MessageDef_File(m); + } + case UPB_DEFTYPE_ENUM: { + const upb_EnumDef* e = unpack_def(v, UPB_DEFTYPE_ENUM); + return upb_EnumDef_File(e); + } + case UPB_DEFTYPE_ENUMVAL: { + const upb_EnumValueDef* ev = unpack_def(v, UPB_DEFTYPE_ENUMVAL); + return upb_EnumDef_File(upb_EnumValueDef_Enum(ev)); + } + case UPB_DEFTYPE_SERVICE: { + const upb_ServiceDef* service = unpack_def(v, UPB_DEFTYPE_SERVICE); + return upb_ServiceDef_File(service); + } + default: + UPB_UNREACHABLE(); + } + } + + const char* last_dot = strrchr(name, '.'); + if (last_dot) { + const upb_MessageDef* parent = + upb_DefPool_FindMessageByNameWithSize(s, name, last_dot - name); + if (parent) { + const char* shortname = last_dot + 1; + if (upb_MessageDef_FindByNameWithSize(parent, shortname, + strlen(shortname), NULL, NULL)) { + return upb_MessageDef_File(parent); + } + } + } + + return NULL; } /* Code to build defs from descriptor protos. *********************************/ @@ -1015,43 +1218,61 @@ int upb_symtab_filecount(const upb_symtab *s) { * this code is used to directly build defs from Ruby (for example) we do need * to validate important constraints like uniqueness of names and numbers. */ -#define CHK_OOM(x) if (!(x)) { symtab_oomerr(ctx); } +#define CHK_OOM(x) \ + if (!(x)) { \ + symtab_oomerr(ctx); \ + } typedef struct { - upb_symtab *symtab; - upb_filedef *file; /* File we are building. */ - upb_arena *arena; /* Allocate defs here. */ - const upb_msglayout_file *layout; /* NULL if we should build layouts. */ - int enum_count; /* Count of enums built so far. */ - int msg_count; /* Count of messages built so far. */ - int ext_count; /* Count of extensions built so far. */ - upb_status *status; /* Record errors here. */ - jmp_buf err; /* longjmp() on error. */ + upb_DefPool* symtab; + upb_FileDef* file; /* File we are building. */ + upb_Arena* arena; /* Allocate defs here. */ + upb_Arena* tmp_arena; /* For temporary allocations. */ + const upb_MiniTable_File* layout; /* NULL if we should build layouts. */ + int enum_count; /* Count of enums built so far. */ + int msg_count; /* Count of messages built so far. */ + int ext_count; /* Count of extensions built so far. */ + upb_Status* status; /* Record errors here. */ + jmp_buf err; /* longjmp() on error. */ } symtab_addctx; -UPB_NORETURN UPB_NOINLINE UPB_PRINTF(2, 3) -static void symtab_errf(symtab_addctx *ctx, const char *fmt, ...) { +UPB_NORETURN UPB_NOINLINE UPB_PRINTF(2, 3) static void symtab_errf( + symtab_addctx* ctx, const char* fmt, ...) { va_list argp; va_start(argp, fmt); - upb_status_vseterrf(ctx->status, fmt, argp); + upb_Status_VSetErrorFormat(ctx->status, fmt, argp); va_end(argp); UPB_LONGJMP(ctx->err, 1); } -UPB_NORETURN UPB_NOINLINE -static void symtab_oomerr(symtab_addctx *ctx) { - upb_status_setoom(ctx->status); +UPB_NORETURN UPB_NOINLINE static void symtab_oomerr(symtab_addctx* ctx) { + upb_Status_setoom(ctx->status); UPB_LONGJMP(ctx->err, 1); } -void *symtab_alloc(symtab_addctx *ctx, size_t bytes) { - void *ret = upb_arena_malloc(ctx->arena, bytes); +void* symtab_alloc(symtab_addctx* ctx, size_t bytes) { + if (bytes == 0) return NULL; + void* ret = upb_Arena_Malloc(ctx->arena, bytes); if (!ret) symtab_oomerr(ctx); return ret; } -static void check_ident(symtab_addctx *ctx, upb_strview name, bool full) { - const char *str = name.data; +// We want to copy the options verbatim into the destination options proto. +// We use serialize+parse as our deep copy. +#define SET_OPTIONS(target, desc_type, options_type, proto) \ + if (google_protobuf_##desc_type##_has_options(proto)) { \ + size_t size; \ + char* pb = google_protobuf_##options_type##_serialize( \ + google_protobuf_##desc_type##_options(proto), ctx->tmp_arena, &size); \ + CHK_OOM(pb); \ + target = google_protobuf_##options_type##_parse(pb, size, ctx->arena); \ + CHK_OOM(target); \ + } else { \ + target = (const google_protobuf_##options_type*)opt_default; \ + } + +static void check_ident(symtab_addctx* ctx, upb_StringView name, bool full) { + const char* str = name.data; size_t len = name.size; bool start = true; size_t i; @@ -1082,144 +1303,159 @@ static void check_ident(symtab_addctx *ctx, upb_strview name, bool full) { } } -static size_t div_round_up(size_t n, size_t d) { - return (n + d - 1) / d; -} +static size_t div_round_up(size_t n, size_t d) { return (n + d - 1) / d; } -static size_t upb_msgval_sizeof(upb_fieldtype_t type) { +static size_t upb_MessageValue_sizeof(upb_CType type) { switch (type) { - case UPB_TYPE_DOUBLE: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: return 8; - case UPB_TYPE_ENUM: - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_FLOAT: + case kUpb_CType_Enum: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Float: return 4; - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: return 1; - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: return sizeof(void*); - case UPB_TYPE_BYTES: - case UPB_TYPE_STRING: - return sizeof(upb_strview); + case kUpb_CType_Bytes: + case kUpb_CType_String: + return sizeof(upb_StringView); } UPB_UNREACHABLE(); } -static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) { - if (upb_msgdef_mapentry(upb_fielddef_containingtype(f))) { - upb_map_entry ent; +static uint8_t upb_msg_fielddefsize(const upb_FieldDef* f) { + if (upb_MessageDef_IsMapEntry(upb_FieldDef_ContainingType(f))) { + upb_MapEntry ent; UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v)); return sizeof(ent.k); - } else if (upb_fielddef_isseq(f)) { + } else if (upb_FieldDef_IsRepeated(f)) { return sizeof(void*); } else { - return upb_msgval_sizeof(upb_fielddef_type(f)); + return upb_MessageValue_sizeof(upb_FieldDef_CType(f)); } } -static uint32_t upb_msglayout_place(upb_msglayout *l, size_t size) { - uint32_t ret; +static uint32_t upb_MiniTable_place(symtab_addctx* ctx, upb_MiniTable* l, + size_t size, const upb_MessageDef* m) { + size_t ofs = UPB_ALIGN_UP(l->size, size); + size_t next = ofs + size; - l->size = UPB_ALIGN_UP(l->size, size); - ret = l->size; - l->size += size; - return ret; + if (next > UINT16_MAX) { + symtab_errf(ctx, "size of message %s exceeded max size of %zu bytes", + upb_MessageDef_FullName(m), (size_t)UINT16_MAX); + } + + l->size = next; + return ofs; } -static int field_number_cmp(const void *p1, const void *p2) { - const upb_msglayout_field *f1 = p1; - const upb_msglayout_field *f2 = p2; +static int field_number_cmp(const void* p1, const void* p2) { + const upb_MiniTable_Field* f1 = p1; + const upb_MiniTable_Field* f2 = p2; return f1->number - f2->number; } -static void assign_layout_indices(const upb_msgdef *m, upb_msglayout *l, - upb_msglayout_field *fields) { +static void assign_layout_indices(const upb_MessageDef* m, upb_MiniTable* l, + upb_MiniTable_Field* fields) { int i; - int n = upb_msgdef_numfields(m); + int n = upb_MessageDef_numfields(m); int dense_below = 0; for (i = 0; i < n; i++) { - upb_fielddef *f = (upb_fielddef*)upb_msgdef_itof(m, fields[i].number); + upb_FieldDef* f = + (upb_FieldDef*)upb_MessageDef_FindFieldByNumber(m, fields[i].number); UPB_ASSERT(f); f->layout_index = i; if (i < UINT8_MAX && fields[i].number == i + 1 && - (i == 0 || fields[i-1].number == i)) { + (i == 0 || fields[i - 1].number == i)) { dense_below = i + 1; } } l->dense_below = dense_below; } -static void fill_fieldlayout(upb_msglayout_field *field, const upb_fielddef *f) { - field->number = upb_fielddef_number(f); - field->descriptortype = upb_fielddef_descriptortype(f); - - if (field->descriptortype == UPB_DTYPE_STRING && - f->file->syntax == UPB_SYNTAX_PROTO2) { - /* See TableDescriptorType() in upbc/generator.cc for details and - * rationale. */ - field->descriptortype = UPB_DTYPE_BYTES; +static uint8_t map_descriptortype(const upb_FieldDef* f) { + uint8_t type = upb_FieldDef_Type(f); + /* See TableDescriptorType() in upbc/generator.cc for details and + * rationale of these exceptions. */ + if (type == kUpb_FieldType_String && f->file->syntax == kUpb_Syntax_Proto2) { + return kUpb_FieldType_Bytes; + } else if (type == kUpb_FieldType_Enum && + f->sub.enumdef->file->syntax == kUpb_Syntax_Proto3) { + return kUpb_FieldType_Int32; } + return type; +} - if (upb_fielddef_ismap(f)) { - field->mode = _UPB_MODE_MAP | (_UPB_REP_PTR << _UPB_REP_SHIFT); - } else if (upb_fielddef_isseq(f)) { - field->mode = _UPB_MODE_ARRAY | (_UPB_REP_PTR << _UPB_REP_SHIFT); +static void fill_fieldlayout(upb_MiniTable_Field* field, + const upb_FieldDef* f) { + field->number = upb_FieldDef_Number(f); + field->descriptortype = map_descriptortype(f); + + if (upb_FieldDef_IsMap(f)) { + field->mode = + kUpb_FieldMode_Map | (upb_FieldRep_Pointer << upb_FieldRep_Shift); + } else if (upb_FieldDef_IsRepeated(f)) { + field->mode = + kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift); } else { /* Maps descriptor type -> elem_size_lg2. */ static const uint8_t sizes[] = { - -1, /* invalid descriptor type */ - _UPB_REP_8BYTE, /* DOUBLE */ - _UPB_REP_4BYTE, /* FLOAT */ - _UPB_REP_8BYTE, /* INT64 */ - _UPB_REP_8BYTE, /* UINT64 */ - _UPB_REP_4BYTE, /* INT32 */ - _UPB_REP_8BYTE, /* FIXED64 */ - _UPB_REP_4BYTE, /* FIXED32 */ - _UPB_REP_1BYTE, /* BOOL */ - _UPB_REP_STRVIEW, /* STRING */ - _UPB_REP_PTR, /* GROUP */ - _UPB_REP_PTR, /* MESSAGE */ - _UPB_REP_STRVIEW, /* BYTES */ - _UPB_REP_4BYTE, /* UINT32 */ - _UPB_REP_4BYTE, /* ENUM */ - _UPB_REP_4BYTE, /* SFIXED32 */ - _UPB_REP_8BYTE, /* SFIXED64 */ - _UPB_REP_4BYTE, /* SINT32 */ - _UPB_REP_8BYTE, /* SINT64 */ + -1, /* invalid descriptor type */ + upb_FieldRep_8Byte, /* DOUBLE */ + upb_FieldRep_4Byte, /* FLOAT */ + upb_FieldRep_8Byte, /* INT64 */ + upb_FieldRep_8Byte, /* UINT64 */ + upb_FieldRep_4Byte, /* INT32 */ + upb_FieldRep_8Byte, /* FIXED64 */ + upb_FieldRep_4Byte, /* FIXED32 */ + upb_FieldRep_1Byte, /* BOOL */ + upb_FieldRep_StringView, /* STRING */ + upb_FieldRep_Pointer, /* GROUP */ + upb_FieldRep_Pointer, /* MESSAGE */ + upb_FieldRep_StringView, /* BYTES */ + upb_FieldRep_4Byte, /* UINT32 */ + upb_FieldRep_4Byte, /* ENUM */ + upb_FieldRep_4Byte, /* SFIXED32 */ + upb_FieldRep_8Byte, /* SFIXED64 */ + upb_FieldRep_4Byte, /* SINT32 */ + upb_FieldRep_8Byte, /* SINT64 */ }; - field->mode = - _UPB_MODE_SCALAR | (sizes[field->descriptortype] << _UPB_REP_SHIFT); + field->mode = kUpb_FieldMode_Scalar | + (sizes[field->descriptortype] << upb_FieldRep_Shift); } - if (upb_fielddef_packed(f)) { - field->mode |= _UPB_MODE_IS_PACKED; + if (upb_FieldDef_IsPacked(f)) { + field->mode |= upb_LabelFlags_IsPacked; } - if (upb_fielddef_isextension(f)) { - field->mode |= _UPB_MODE_IS_EXTENSION; + if (upb_FieldDef_IsExtension(f)) { + field->mode |= upb_LabelFlags_IsExtension; } } /* This function is the dynamic equivalent of message_layout.{cc,h} in upbc. * It computes a dynamic layout for all of the fields in |m|. */ -static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { - upb_msglayout *l = (upb_msglayout*)m->layout; - upb_msg_field_iter it; - upb_msg_oneof_iter oit; - size_t hasbit; - size_t field_count = upb_msgdef_numfields(m); +static void make_layout(symtab_addctx* ctx, const upb_MessageDef* m) { + upb_MiniTable* l = (upb_MiniTable*)m->layout; + size_t field_count = upb_MessageDef_numfields(m); size_t sublayout_count = 0; - upb_msglayout_sub *subs; - upb_msglayout_field *fields; + upb_MiniTable_Sub* subs; + upb_MiniTable_Field* fields; - memset(l, 0, sizeof(*l) + sizeof(_upb_fasttable_entry)); + memset(l, 0, sizeof(*l) + sizeof(_upb_FastTable_Entry)); /* Count sub-messages. */ for (size_t i = 0; i < field_count; i++) { - if (upb_fielddef_issubmsg(&m->fields[i])) { + const upb_FieldDef* f = &m->fields[i]; + if (upb_FieldDef_IsSubMessage(f)) { + sublayout_count++; + } + if (upb_FieldDef_CType(f) == kUpb_CType_Enum && + f->sub.enumdef->file->syntax == kUpb_Syntax_Proto2) { sublayout_count++; } } @@ -1227,19 +1463,20 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { fields = symtab_alloc(ctx, field_count * sizeof(*fields)); subs = symtab_alloc(ctx, sublayout_count * sizeof(*subs)); - l->field_count = upb_msgdef_numfields(m); + l->field_count = upb_MessageDef_numfields(m); l->fields = fields; l->subs = subs; l->table_mask = 0; + l->required_count = 0; - if (upb_msgdef_extrangecount(m) > 0) { - if (m->is_message_set) { - l->ext = _UPB_MSGEXT_MSGSET; + if (upb_MessageDef_ExtensionRangeCount(m) > 0) { + if (google_protobuf_MessageOptions_message_set_wire_format(m->opts)) { + l->ext = upb_ExtMode_IsMessageSet; } else { - l->ext = _UPB_MSGEXT_EXTENDABLE; + l->ext = upb_ExtMode_Extendable; } } else { - l->ext = _UPB_MSGEXT_NONE; + l->ext = upb_ExtMode_NonExtendable; } /* TODO(haberman): initialize fast tables so that reflection-based parsing @@ -1247,30 +1484,37 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { l->fasttable[0].field_parser = &fastdecode_generic; l->fasttable[0].field_data = 0; - if (upb_msgdef_mapentry(m)) { + if (upb_MessageDef_IsMapEntry(m)) { /* TODO(haberman): refactor this method so this special case is more * elegant. */ - const upb_fielddef *key = upb_msgdef_itof(m, 1); - const upb_fielddef *val = upb_msgdef_itof(m, 2); + const upb_FieldDef* key = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_FieldDef* val = upb_MessageDef_FindFieldByNumber(m, 2); fields[0].number = 1; fields[1].number = 2; - fields[0].mode = _UPB_MODE_SCALAR; - fields[1].mode = _UPB_MODE_SCALAR; + fields[0].mode = kUpb_FieldMode_Scalar; + fields[1].mode = kUpb_FieldMode_Scalar; fields[0].presence = 0; fields[1].presence = 0; - fields[0].descriptortype = upb_fielddef_descriptortype(key); - fields[1].descriptortype = upb_fielddef_descriptortype(val); + fields[0].descriptortype = map_descriptortype(key); + fields[1].descriptortype = map_descriptortype(val); fields[0].offset = 0; - fields[1].offset = sizeof(upb_strview); + fields[1].offset = sizeof(upb_StringView); fields[1].submsg_index = 0; - if (upb_fielddef_type(val) == UPB_TYPE_MESSAGE) { - subs[0].submsg = upb_fielddef_msgsubdef(val)->layout; + if (upb_FieldDef_CType(val) == kUpb_CType_Message) { + subs[0].submsg = upb_FieldDef_MessageSubDef(val)->layout; } + upb_FieldDef* fielddefs = (upb_FieldDef*)&m->fields[0]; + UPB_ASSERT(fielddefs[0].number_ == 1); + UPB_ASSERT(fielddefs[1].number_ == 2); + fielddefs[0].layout_index = 0; + fielddefs[1].layout_index = 1; + l->field_count = 2; - l->size = 2 * sizeof(upb_strview); + l->size = 2 * sizeof(upb_StringView); l->size = UPB_ALIGN_UP(l->size, 8); + l->dense_below = 2; return; } @@ -1283,23 +1527,44 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { * OPT: There is a lot of room for optimization here to minimize the size. */ + /* Assign hasbits for required fields first. */ + size_t hasbit = 0; + + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = &m->fields[i]; + upb_MiniTable_Field* field = &fields[upb_FieldDef_Index(f)]; + if (upb_FieldDef_Label(f) == kUpb_Label_Required) { + field->presence = ++hasbit; + if (hasbit >= 63) { + symtab_errf(ctx, "Message with >=63 required fields: %s", + upb_MessageDef_FullName(m)); + } + l->required_count++; + } + } + /* Allocate hasbits and set basic field attributes. */ sublayout_count = 0; - for (upb_msg_field_begin(&it, m), hasbit = 0; - !upb_msg_field_done(&it); - upb_msg_field_next(&it)) { - upb_fielddef* f = upb_msg_iter_field(&it); - upb_msglayout_field *field = &fields[upb_fielddef_index(f)]; + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = &m->fields[i]; + upb_MiniTable_Field* field = &fields[upb_FieldDef_Index(f)]; fill_fieldlayout(field, f); - if (upb_fielddef_issubmsg(f)) { - const upb_msgdef *subm = upb_fielddef_msgsubdef(f); + if (upb_FieldDef_IsSubMessage(f)) { + field->submsg_index = sublayout_count++; + subs[field->submsg_index].submsg = upb_FieldDef_MessageSubDef(f)->layout; + } else if (upb_FieldDef_CType(f) == kUpb_CType_Enum && + f->file->syntax == kUpb_Syntax_Proto2) { field->submsg_index = sublayout_count++; - subs[field->submsg_index].submsg = subm->layout; + subs[field->submsg_index].subenum = upb_FieldDef_EnumSubDef(f)->layout; + UPB_ASSERT(subs[field->submsg_index].subenum); } - if (upb_fielddef_haspresence(f) && !upb_fielddef_realcontainingoneof(f)) { + if (upb_FieldDef_Label(f) == kUpb_Label_Required) { + /* Hasbit was already assigned. */ + } else if (upb_FieldDef_HasPresence(f) && + !upb_FieldDef_RealContainingOneof(f)) { /* We don't use hasbit 0, so that 0 can indicate "no presence" in the * table. This wastes one hasbit, but we don't worry about it for now. */ field->presence = ++hasbit; @@ -1309,55 +1574,47 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { } /* Account for space used by hasbits. */ - l->size = div_round_up(hasbit, 8); + l->size = hasbit ? div_round_up(hasbit + 1, 8) : 0; /* Allocate non-oneof fields. */ - for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it); - upb_msg_field_next(&it)) { - const upb_fielddef* f = upb_msg_iter_field(&it); + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = &m->fields[i]; size_t field_size = upb_msg_fielddefsize(f); - size_t index = upb_fielddef_index(f); + size_t index = upb_FieldDef_Index(f); - if (upb_fielddef_realcontainingoneof(f)) { + if (upb_FieldDef_RealContainingOneof(f)) { /* Oneofs are handled separately below. */ continue; } - fields[index].offset = upb_msglayout_place(l, field_size); + fields[index].offset = upb_MiniTable_place(ctx, l, field_size, m); } /* Allocate oneof fields. Each oneof field consists of a uint32 for the case * and space for the actual data. */ - for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit); - upb_msg_oneof_next(&oit)) { - const upb_oneofdef* o = upb_msg_iter_oneof(&oit); - upb_oneof_iter fit; - - size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */ + for (int i = 0; i < m->oneof_count; i++) { + const upb_OneofDef* o = &m->oneofs[i]; + size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */ size_t field_size = 0; uint32_t case_offset; uint32_t data_offset; - if (upb_oneofdef_issynthetic(o)) continue; + if (upb_OneofDef_IsSynthetic(o)) continue; /* Calculate field size: the max of all field sizes. */ - for (upb_oneof_begin(&fit, o); - !upb_oneof_done(&fit); - upb_oneof_next(&fit)) { - const upb_fielddef* f = upb_oneof_iter_field(&fit); + for (int j = 0; j < o->field_count; j++) { + const upb_FieldDef* f = o->fields[j]; field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f)); } /* Align and allocate case offset. */ - case_offset = upb_msglayout_place(l, case_size); - data_offset = upb_msglayout_place(l, field_size); + case_offset = upb_MiniTable_place(ctx, l, case_size, m); + data_offset = upb_MiniTable_place(ctx, l, field_size, m); - for (upb_oneof_begin(&fit, o); - !upb_oneof_done(&fit); - upb_oneof_next(&fit)) { - const upb_fielddef* f = upb_oneof_iter_field(&fit); - fields[upb_fielddef_index(f)].offset = data_offset; - fields[upb_fielddef_index(f)].presence = ~case_offset; + for (int i = 0; i < o->field_count; i++) { + const upb_FieldDef* f = o->fields[i]; + fields[upb_FieldDef_Index(f)].offset = data_offset; + fields[upb_FieldDef_Index(f)].presence = ~case_offset; } } @@ -1366,30 +1623,30 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { l->size = UPB_ALIGN_UP(l->size, 8); /* Sort fields by number. */ - qsort(fields, upb_msgdef_numfields(m), sizeof(*fields), field_number_cmp); + qsort(fields, upb_MessageDef_numfields(m), sizeof(*fields), field_number_cmp); assign_layout_indices(m, l, fields); } -static char *strviewdup(symtab_addctx *ctx, upb_strview view) { - char *ret = upb_strdup2(view.data, view.size, ctx->arena); +static char* strviewdup(symtab_addctx* ctx, upb_StringView view) { + char* ret = upb_strdup2(view.data, view.size, ctx->arena); CHK_OOM(ret); return ret; } -static bool streql2(const char *a, size_t n, const char *b) { +static bool streql2(const char* a, size_t n, const char* b) { return n == strlen(b) && memcmp(a, b, n) == 0; } -static bool streql_view(upb_strview view, const char *b) { +static bool streql_view(upb_StringView view, const char* b) { return streql2(view.data, view.size, b); } -static const char *makefullname(symtab_addctx *ctx, const char *prefix, - upb_strview name) { +static const char* makefullname(symtab_addctx* ctx, const char* prefix, + upb_StringView name) { if (prefix) { /* ret = prefix + '.' + name; */ size_t n = strlen(prefix); - char *ret = symtab_alloc(ctx, n + name.size + 2); + char* ret = symtab_alloc(ctx, n + name.size + 2); strcpy(ret, prefix); ret[n] = '.'; memcpy(&ret[n + 1], name.data, name.size); @@ -1400,33 +1657,33 @@ static const char *makefullname(symtab_addctx *ctx, const char *prefix, } } -static void finalize_oneofs(symtab_addctx *ctx, upb_msgdef *m) { +static void finalize_oneofs(symtab_addctx* ctx, upb_MessageDef* m) { int i; int synthetic_count = 0; - upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs; + upb_OneofDef* mutable_oneofs = (upb_OneofDef*)m->oneofs; for (i = 0; i < m->oneof_count; i++) { - upb_oneofdef *o = &mutable_oneofs[i]; + upb_OneofDef* o = &mutable_oneofs[i]; if (o->synthetic && o->field_count != 1) { symtab_errf(ctx, "Synthetic oneofs must have one field, not %d: %s", - o->field_count, upb_oneofdef_name(o)); + o->field_count, upb_OneofDef_Name(o)); } if (o->synthetic) { synthetic_count++; } else if (synthetic_count != 0) { symtab_errf(ctx, "Synthetic oneofs must be after all other oneofs: %s", - upb_oneofdef_name(o)); + upb_OneofDef_Name(o)); } - o->fields = symtab_alloc(ctx, sizeof(upb_fielddef *) * o->field_count); + o->fields = symtab_alloc(ctx, sizeof(upb_FieldDef*) * o->field_count); o->field_count = 0; } for (i = 0; i < m->field_count; i++) { - const upb_fielddef *f = &m->fields[i]; - upb_oneofdef *o = (upb_oneofdef*)f->oneof; + const upb_FieldDef* f = &m->fields[i]; + upb_OneofDef* o = (upb_OneofDef*)upb_FieldDef_ContainingOneof(f); if (o) { o->fields[o->field_count++] = f; } @@ -1435,14 +1692,16 @@ static void finalize_oneofs(symtab_addctx *ctx, upb_msgdef *m) { m->real_oneof_count = m->oneof_count - synthetic_count; } -size_t getjsonname(const char *name, char *buf, size_t len) { +size_t getjsonname(const char* name, char* buf, size_t len) { size_t src, dst = 0; bool ucase_next = false; -#define WRITE(byte) \ - ++dst; \ - if (dst < len) buf[dst - 1] = byte; \ - else if (dst == len) buf[dst - 1] = '\0' +#define WRITE(byte) \ + ++dst; \ + if (dst < len) \ + buf[dst - 1] = byte; \ + else if (dst == len) \ + buf[dst - 1] = '\0' if (!name) { WRITE('\0'); @@ -1473,14 +1732,17 @@ size_t getjsonname(const char *name, char *buf, size_t len) { #undef WRITE } -static char* makejsonname(symtab_addctx *ctx, const char* name) { +static char* makejsonname(symtab_addctx* ctx, const char* name) { size_t size = getjsonname(name, NULL, 0); char* json_name = symtab_alloc(ctx, size); getjsonname(name, json_name, size); return json_name; } -static void symtab_add(symtab_addctx *ctx, const char *name, upb_value v) { +/* Adds a symbol |v| to the symtab, which must be a def pointer previously + * packed with pack_def(). The def's pointer to upb_FileDef* must be set before + * adding, so we know which entries to remove if building this file fails. */ +static void symtab_add(symtab_addctx* ctx, const char* name, upb_value v) { // TODO: table should support an operation "tryinsert" to avoid the double // lookup. if (upb_strtable_lookup(&ctx->symtab->syms, name, NULL)) { @@ -1491,83 +1753,264 @@ static void symtab_add(symtab_addctx *ctx, const char *name, upb_value v) { ctx->symtab->arena)); } +static bool remove_component(char* base, size_t* len) { + if (*len == 0) return false; + + for (size_t i = *len - 1; i > 0; i--) { + if (base[i] == '.') { + *len = i; + return true; + } + } + + *len = 0; + return true; +} + /* Given a symbol and the base symbol inside which it is defined, find the * symbol's definition in t. */ -static const void *symtab_resolve(symtab_addctx *ctx, const upb_fielddef *f, - const char *base, upb_strview sym, - upb_deftype_t type) { - const upb_strtable *t = &ctx->symtab->syms; - if(sym.size == 0) goto notfound; - if(sym.data[0] == '.') { +static const void* symtab_resolveany(symtab_addctx* ctx, + const char* from_name_dbg, + const char* base, upb_StringView sym, + upb_deftype_t* type) { + const upb_strtable* t = &ctx->symtab->syms; + if (sym.size == 0) goto notfound; + upb_value v; + if (sym.data[0] == '.') { /* Symbols starting with '.' are absolute, so we do a single lookup. * Slice to omit the leading '.' */ - upb_value v; if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) { goto notfound; } - - const void *ret = unpack_def(v, type); - if (!ret) { - symtab_errf(ctx, "type mismatch when resolving field %s, name %s", - f->full_name, sym.data); - } - return ret; } else { - /* Remove components from base until we find an entry or run out. - * TODO: This branch is totally broken, but currently not used. */ - (void)base; - UPB_ASSERT(false); - goto notfound; + /* Remove components from base until we find an entry or run out. */ + size_t baselen = strlen(base); + char* tmp = malloc(sym.size + strlen(base) + 1); + while (1) { + char* p = tmp; + if (baselen) { + memcpy(p, base, baselen); + p[baselen] = '.'; + p += baselen + 1; + } + memcpy(p, sym.data, sym.size); + p += sym.size; + if (upb_strtable_lookup2(t, tmp, p - tmp, &v)) { + break; + } + if (!remove_component(tmp, &baselen)) { + free(tmp); + goto notfound; + } + } + free(tmp); } + *type = deftype(v); + return unpack_def(v, *type); + notfound: - symtab_errf(ctx, "couldn't resolve name '" UPB_STRVIEW_FORMAT "'", - UPB_STRVIEW_ARGS(sym)); + symtab_errf(ctx, "couldn't resolve name '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(sym)); +} + +static const void* symtab_resolve(symtab_addctx* ctx, const char* from_name_dbg, + const char* base, upb_StringView sym, + upb_deftype_t type) { + upb_deftype_t found_type; + const void* ret = + symtab_resolveany(ctx, from_name_dbg, base, sym, &found_type); + if (ret && found_type != type) { + symtab_errf( + ctx, + "type mismatch when resolving %s: couldn't find name %s with type=%d", + from_name_dbg, sym.data, (int)type); + } + return ret; } static void create_oneofdef( - symtab_addctx *ctx, upb_msgdef *m, - const google_protobuf_OneofDescriptorProto *oneof_proto) { - upb_oneofdef *o; - upb_strview name = google_protobuf_OneofDescriptorProto_name(oneof_proto); + symtab_addctx* ctx, upb_MessageDef* m, + const google_protobuf_OneofDescriptorProto* oneof_proto, + const upb_OneofDef* _o) { + upb_OneofDef* o = (upb_OneofDef*)_o; + upb_StringView name = google_protobuf_OneofDescriptorProto_name(oneof_proto); upb_value v; - o = (upb_oneofdef*)&m->oneofs[m->oneof_count++]; o->parent = m; o->full_name = makefullname(ctx, m->full_name, name); o->field_count = 0; o->synthetic = false; + SET_OPTIONS(o->opts, OneofDescriptorProto, OneofOptions, oneof_proto); + v = pack_def(o, UPB_DEFTYPE_ONEOF); - symtab_add(ctx, o->full_name, v); CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, v, ctx->arena)); CHK_OOM(upb_inttable_init(&o->itof, ctx->arena)); CHK_OOM(upb_strtable_init(&o->ntof, 4, ctx->arena)); } -static str_t *newstr(symtab_addctx *ctx, const char *data, size_t len) { - str_t *ret = symtab_alloc(ctx, sizeof(*ret) + len); - if (!ret) return NULL; +static str_t* newstr(symtab_addctx* ctx, const char* data, size_t len) { + str_t* ret = symtab_alloc(ctx, sizeof(*ret) + len); + CHK_OOM(ret); ret->len = len; if (len) memcpy(ret->str, data, len); ret->str[len] = '\0'; return ret; } -static void parse_default(symtab_addctx *ctx, const char *str, size_t len, - upb_fielddef *f) { - char *end; +static bool upb_DefPool_TryGetChar(const char** src, const char* end, + char* ch) { + if (*src == end) return false; + *ch = **src; + *src += 1; + return true; +} + +static char upb_DefPool_TryGetHexDigit(symtab_addctx* ctx, + const upb_FieldDef* f, const char** src, + const char* end) { + char ch; + if (!upb_DefPool_TryGetChar(src, end, &ch)) return -1; + if ('0' <= ch && ch <= '9') { + return ch - '0'; + } + ch = upb_ascii_lower(ch); + if ('a' <= ch && ch <= 'f') { + return ch - 'a' + 0xa; + } + *src -= 1; // Char wasn't actually a hex digit. + return -1; +} + +static char upb_DefPool_ParseHexEscape(symtab_addctx* ctx, + const upb_FieldDef* f, const char** src, + const char* end) { + char hex_digit = upb_DefPool_TryGetHexDigit(ctx, f, src, end); + if (hex_digit < 0) { + symtab_errf(ctx, + "\\x cannot be followed by non-hex digit in field '%s' default", + upb_FieldDef_FullName(f)); + return 0; + } + unsigned int ret = hex_digit; + while ((hex_digit = upb_DefPool_TryGetHexDigit(ctx, f, src, end)) >= 0) { + ret = (ret << 4) | hex_digit; + } + if (ret > 0xff) { + symtab_errf(ctx, "Value of hex escape in field %s exceeds 8 bits", + upb_FieldDef_FullName(f)); + return 0; + } + return ret; +} + +char upb_DefPool_TryGetOctalDigit(const char** src, const char* end) { + char ch; + if (!upb_DefPool_TryGetChar(src, end, &ch)) return -1; + if ('0' <= ch && ch <= '7') { + return ch - '0'; + } + *src -= 1; // Char wasn't actually an octal digit. + return -1; +} + +static char upb_DefPool_ParseOctalEscape(symtab_addctx* ctx, + const upb_FieldDef* f, + const char** src, const char* end) { + char ch = 0; + for (int i = 0; i < 3; i++) { + char digit; + if ((digit = upb_DefPool_TryGetOctalDigit(src, end)) >= 0) { + ch = (ch << 3) | digit; + } + } + return ch; +} + +static char upb_DefPool_ParseEscape(symtab_addctx* ctx, const upb_FieldDef* f, + const char** src, const char* end) { + char ch; + if (!upb_DefPool_TryGetChar(src, end, &ch)) { + symtab_errf(ctx, "unterminated escape sequence in field %s", + upb_FieldDef_FullName(f)); + return 0; + } + switch (ch) { + case 'a': + return '\a'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'v': + return '\v'; + case '\\': + return '\\'; + case '\'': + return '\''; + case '\"': + return '\"'; + case '?': + return '\?'; + case 'x': + case 'X': + return upb_DefPool_ParseHexEscape(ctx, f, src, end); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + *src -= 1; + return upb_DefPool_ParseOctalEscape(ctx, f, src, end); + } + symtab_errf(ctx, "Unknown escape sequence: \\%c", ch); +} + +static str_t* unescape(symtab_addctx* ctx, const upb_FieldDef* f, + const char* data, size_t len) { + // Size here is an upper bound; escape sequences could ultimately shrink it. + str_t* ret = symtab_alloc(ctx, sizeof(*ret) + len); + char* dst = &ret->str[0]; + const char* src = data; + const char* end = data + len; + + while (src < end) { + if (*src == '\\') { + src++; + *dst++ = upb_DefPool_ParseEscape(ctx, f, &src, end); + } else { + *dst++ = *src++; + } + } + + ret->len = dst - &ret->str[0]; + return ret; +} + +static void parse_default(symtab_addctx* ctx, const char* str, size_t len, + upb_FieldDef* f) { + char* end; char nullz[64]; errno = 0; - switch (upb_fielddef_type(f)) { - case UPB_TYPE_INT32: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT32: - case UPB_TYPE_UINT64: - case UPB_TYPE_DOUBLE: - case UPB_TYPE_FLOAT: + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: + case kUpb_CType_Int64: + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: + case kUpb_CType_Double: + case kUpb_CType_Float: /* Standard C number parsing functions expect null-terminated strings. */ if (len >= sizeof(nullz) - 1) { symtab_errf(ctx, "Default too long: %.*s", (int)len, str); @@ -1580,8 +2023,8 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, break; } - switch (upb_fielddef_type(f)) { - case UPB_TYPE_INT32: { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: { long val = strtol(str, &end, 0); if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) { goto invalid; @@ -1589,16 +2032,17 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, f->defaultval.sint = val; break; } - case UPB_TYPE_ENUM: { - const upb_enumdef *e = f->sub.enumdef; - const upb_enumvaldef *ev = upb_enumdef_lookupname(e, str, len); + case kUpb_CType_Enum: { + const upb_EnumDef* e = f->sub.enumdef; + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNameWithSize(e, str, len); if (!ev) { goto invalid; } f->defaultval.sint = ev->number; break; } - case UPB_TYPE_INT64: { + case kUpb_CType_Int64: { long long val = strtoll(str, &end, 0); if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) { goto invalid; @@ -1606,7 +2050,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, f->defaultval.sint = val; break; } - case UPB_TYPE_UINT32: { + case kUpb_CType_UInt32: { unsigned long val = strtoul(str, &end, 0); if (val > UINT32_MAX || errno == ERANGE || *end) { goto invalid; @@ -1614,7 +2058,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, f->defaultval.uint = val; break; } - case UPB_TYPE_UINT64: { + case kUpb_CType_UInt64: { unsigned long long val = strtoull(str, &end, 0); if (val > UINT64_MAX || errno == ERANGE || *end) { goto invalid; @@ -1622,7 +2066,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, f->defaultval.uint = val; break; } - case UPB_TYPE_DOUBLE: { + case kUpb_CType_Double: { double val = strtod(str, &end); if (errno == ERANGE || *end) { goto invalid; @@ -1630,7 +2074,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, f->defaultval.dbl = val; break; } - case UPB_TYPE_FLOAT: { + case kUpb_CType_Float: { float val = strtof(str, &end); if (errno == ERANGE || *end) { goto invalid; @@ -1638,75 +2082,78 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len, f->defaultval.flt = val; break; } - case UPB_TYPE_BOOL: { + case kUpb_CType_Bool: { if (streql2(str, len, "false")) { f->defaultval.boolean = false; } else if (streql2(str, len, "true")) { f->defaultval.boolean = true; } else { + goto invalid; } break; } - case UPB_TYPE_STRING: + case kUpb_CType_String: f->defaultval.str = newstr(ctx, str, len); break; - case UPB_TYPE_BYTES: - /* XXX: need to interpret the C-escaped value. */ - f->defaultval.str = newstr(ctx, str, len); + case kUpb_CType_Bytes: + f->defaultval.str = unescape(ctx, f, str, len); break; - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: /* Should not have a default value. */ symtab_errf(ctx, "Message should not have a default (%s)", - upb_fielddef_fullname(f)); + upb_FieldDef_FullName(f)); } return; invalid: - symtab_errf(ctx, "Invalid default '%.*s' for field %s", (int)len, str, - upb_fielddef_fullname(f)); + symtab_errf(ctx, "Invalid default '%.*s' for field %s of type %d", (int)len, + str, upb_FieldDef_FullName(f), (int)upb_FieldDef_Type(f)); } -static void set_default_default(symtab_addctx *ctx, upb_fielddef *f) { - switch (upb_fielddef_type(f)) { - case UPB_TYPE_INT32: - case UPB_TYPE_INT64: - case UPB_TYPE_ENUM: +static void set_default_default(symtab_addctx* ctx, upb_FieldDef* f) { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: + case kUpb_CType_Int64: f->defaultval.sint = 0; break; - case UPB_TYPE_UINT64: - case UPB_TYPE_UINT32: + case kUpb_CType_UInt64: + case kUpb_CType_UInt32: f->defaultval.uint = 0; break; - case UPB_TYPE_DOUBLE: - case UPB_TYPE_FLOAT: + case kUpb_CType_Double: + case kUpb_CType_Float: f->defaultval.dbl = 0; break; - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: + case kUpb_CType_String: + case kUpb_CType_Bytes: f->defaultval.str = newstr(ctx, NULL, 0); break; - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: f->defaultval.boolean = false; break; - case UPB_TYPE_MESSAGE: + case kUpb_CType_Enum: + f->defaultval.sint = f->sub.enumdef->values[0].number; + case kUpb_CType_Message: break; } } static void create_fielddef( - symtab_addctx *ctx, const char *prefix, upb_msgdef *m, - const google_protobuf_FieldDescriptorProto *field_proto) { - upb_fielddef *f; - const google_protobuf_FieldOptions *options; - upb_strview name; - const char *full_name; - const char *json_name; - const char *shortname; - uint32_t field_number; + symtab_addctx* ctx, const char* prefix, upb_MessageDef* m, + const google_protobuf_FieldDescriptorProto* field_proto, + const upb_FieldDef* _f, bool is_extension) { + upb_FieldDef* f = (upb_FieldDef*)_f; + upb_StringView name; + const char* full_name; + const char* json_name; + const char* shortname; + int32_t field_number; + + f->file = ctx->file; /* Must happen prior to symtab_add(). */ if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) { - symtab_errf(ctx, "field has no name (%s)", upb_msgdef_fullname(m)); + symtab_errf(ctx, "field has no name (%s)", upb_MessageDef_FullName(m)); } name = google_protobuf_FieldDescriptorProto_name(field_proto); @@ -1717,53 +2164,91 @@ static void create_fielddef( if (google_protobuf_FieldDescriptorProto_has_json_name(field_proto)) { json_name = strviewdup( ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto)); + f->has_json_name_ = true; } else { json_name = makejsonname(ctx, shortname); + f->has_json_name_ = false; } field_number = google_protobuf_FieldDescriptorProto_number(field_proto); - if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) { - symtab_errf(ctx, "invalid field number (%u)", field_number); - } + f->full_name = full_name; + f->json_name = json_name; + f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto); + f->number_ = field_number; + f->scope.oneof = NULL; + f->proto3_optional_ = + google_protobuf_FieldDescriptorProto_proto3_optional(field_proto); - if (m) { - /* direct message field. */ - upb_value v, field_v, json_v; - size_t json_size; + bool has_type = google_protobuf_FieldDescriptorProto_has_type(field_proto); + bool has_type_name = + google_protobuf_FieldDescriptorProto_has_type_name(field_proto); - f = (upb_fielddef*)&m->fields[m->field_count]; - f->index_ = m->field_count++; - f->msgdef = m; - f->is_extension_ = false; + f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto); - if (upb_strtable_lookup(&m->ntof, shortname, NULL)) { - symtab_errf(ctx, "duplicate field name (%s)", shortname); + if (has_type) { + switch (f->type_) { + case kUpb_FieldType_Message: + case kUpb_FieldType_Group: + case kUpb_FieldType_Enum: + if (!has_type_name) { + symtab_errf(ctx, "field of type %d requires type name (%s)", + (int)f->type_, full_name); + } + break; + default: + if (has_type_name) { + symtab_errf(ctx, "invalid type for field with type_name set (%s, %d)", + full_name, (int)f->type_); + } } + } else if (has_type_name) { + f->type_ = + FIELD_TYPE_UNSPECIFIED; // We'll fill this in in resolve_fielddef(). + } - if (upb_strtable_lookup(&m->ntof, json_name, NULL)) { - symtab_errf(ctx, "duplicate json_name (%s)", json_name); - } + if (!is_extension) { + /* direct message field. */ + upb_value v, field_v, json_v, existing_v; + size_t json_size; - if (upb_inttable_lookup(&m->itof, field_number, NULL)) { - symtab_errf(ctx, "duplicate field number (%u)", field_number); + if (field_number <= 0 || field_number > kUpb_MaxFieldNumber) { + symtab_errf(ctx, "invalid field number (%u)", field_number); } + f->index_ = f - m->fields; + f->msgdef = m; + f->is_extension_ = false; + field_v = pack_def(f, UPB_DEFTYPE_FIELD); json_v = pack_def(f, UPB_DEFTYPE_FIELD_JSONNAME); v = upb_value_constptr(f); json_size = strlen(json_name); + if (upb_strtable_lookup(&m->ntof, shortname, &existing_v)) { + symtab_errf(ctx, "duplicate field name (%s)", shortname); + } + CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, field_v, ctx->arena)); - CHK_OOM(upb_inttable_insert(&m->itof, field_number, v, ctx->arena)); if (strcmp(shortname, json_name) != 0) { - upb_strtable_insert(&m->ntof, json_name, json_size, json_v, ctx->arena); + if (upb_strtable_lookup(&m->ntof, json_name, &v)) { + symtab_errf(ctx, "duplicate json_name (%s)", json_name); + } else { + CHK_OOM(upb_strtable_insert(&m->ntof, json_name, json_size, json_v, + ctx->arena)); + } + } + + if (upb_inttable_lookup(&m->itof, field_number, NULL)) { + symtab_errf(ctx, "duplicate field number (%u)", field_number); } + CHK_OOM(upb_inttable_insert(&m->itof, field_number, v, ctx->arena)); + if (ctx->layout) { - const upb_msglayout_field *fields = m->layout->fields; + const upb_MiniTable_Field* fields = m->layout->fields; int count = m->layout->field_count; bool found = false; for (int i = 0; i < count; i++) { @@ -1777,43 +2262,42 @@ static void create_fielddef( } } else { /* extension field. */ - uint16_t layout_index = ctx->ext_count++; - f = (upb_fielddef*)&ctx->file->exts[layout_index]; - f->layout_index = layout_index; f->is_extension_ = true; - symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD)); + f->scope.extension_scope = m; + symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_EXT)); + f->layout_index = ctx->ext_count++; if (ctx->layout) { UPB_ASSERT(ctx->file->ext_layouts[f->layout_index]->field.number == field_number); } } - f->full_name = full_name; - f->json_name = json_name; - f->file = ctx->file; - f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto); - f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto); - f->number_ = field_number; - f->oneof = NULL; - f->proto3_optional_ = - google_protobuf_FieldDescriptorProto_proto3_optional(field_proto); + if (f->type_ < kUpb_FieldType_Double || f->type_ > kUpb_FieldType_SInt64) { + symtab_errf(ctx, "invalid type for field %s (%d)", f->full_name, f->type_); + } + + if (f->label_ < kUpb_Label_Optional || f->label_ > kUpb_Label_Repeated) { + symtab_errf(ctx, "invalid label for field %s (%d)", f->full_name, + f->label_); + } /* We can't resolve the subdef or (in the case of extensions) the containing * message yet, because it may not have been defined yet. We stash a pointer * to the field_proto until later when we can properly resolve it. */ f->sub.unresolved = field_proto; - if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) { + if (f->label_ == kUpb_Label_Required && + f->file->syntax == kUpb_Syntax_Proto3) { symtab_errf(ctx, "proto3 fields cannot be required (%s)", f->full_name); } if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { int oneof_index = google_protobuf_FieldDescriptorProto_oneof_index(field_proto); - upb_oneofdef *oneof; + upb_OneofDef* oneof; upb_value v = upb_value_constptr(f); - if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) { + if (upb_FieldDef_Label(f) != kUpb_Label_Optional) { symtab_errf(ctx, "fields in oneof must have OPTIONAL label (%s)", f->full_name); } @@ -1827,8 +2311,8 @@ static void create_fielddef( symtab_errf(ctx, "oneof_index out of range (%s)", f->full_name); } - oneof = (upb_oneofdef *)&m->oneofs[oneof_index]; - f->oneof = oneof; + oneof = (upb_OneofDef*)&m->oneofs[oneof_index]; + f->scope.oneof = oneof; oneof->field_count++; if (f->proto3_optional_) { @@ -1838,43 +2322,166 @@ static void create_fielddef( CHK_OOM( upb_strtable_insert(&oneof->ntof, name.data, name.size, v, ctx->arena)); } else { - f->oneof = NULL; if (f->proto3_optional_) { symtab_errf(ctx, "field with proto3_optional was not in a oneof (%s)", f->full_name); } } - options = google_protobuf_FieldDescriptorProto_has_options(field_proto) ? - google_protobuf_FieldDescriptorProto_options(field_proto) : NULL; + SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto); - if (options && google_protobuf_FieldOptions_has_packed(options)) { - f->packed_ = google_protobuf_FieldOptions_packed(options); + if (google_protobuf_FieldOptions_has_packed(f->opts)) { + f->packed_ = google_protobuf_FieldOptions_packed(f->opts); } else { /* Repeated fields default to packed for proto3 only. */ - f->packed_ = upb_fielddef_isprimitive(f) && - f->label_ == UPB_LABEL_REPEATED && f->file->syntax == UPB_SYNTAX_PROTO3; + f->packed_ = upb_FieldDef_IsPrimitive(f) && + f->label_ == kUpb_Label_Repeated && + f->file->syntax == kUpb_Syntax_Proto3; } +} - if (options) { - f->lazy_ = google_protobuf_FieldOptions_lazy(options); - } else { - f->lazy_ = false; +static void create_service( + symtab_addctx* ctx, const google_protobuf_ServiceDescriptorProto* svc_proto, + const upb_ServiceDef* _s) { + upb_ServiceDef* s = (upb_ServiceDef*)_s; + upb_StringView name; + const google_protobuf_MethodDescriptorProto* const* methods; + size_t i, n; + + s->file = ctx->file; /* Must happen prior to symtab_add. */ + + name = google_protobuf_ServiceDescriptorProto_name(svc_proto); + check_ident(ctx, name, false); + s->full_name = makefullname(ctx, ctx->file->package, name); + symtab_add(ctx, s->full_name, pack_def(s, UPB_DEFTYPE_SERVICE)); + + methods = google_protobuf_ServiceDescriptorProto_method(svc_proto, &n); + + s->method_count = n; + s->methods = symtab_alloc(ctx, sizeof(*s->methods) * n); + + SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions, svc_proto); + + for (i = 0; i < n; i++) { + const google_protobuf_MethodDescriptorProto* method_proto = methods[i]; + upb_MethodDef* m = (upb_MethodDef*)&s->methods[i]; + upb_StringView name = + google_protobuf_MethodDescriptorProto_name(method_proto); + + m->service = s; + m->full_name = makefullname(ctx, s->full_name, name); + m->client_streaming = + google_protobuf_MethodDescriptorProto_client_streaming(method_proto); + m->server_streaming = + google_protobuf_MethodDescriptorProto_server_streaming(method_proto); + m->input_type = symtab_resolve( + ctx, m->full_name, m->full_name, + google_protobuf_MethodDescriptorProto_input_type(method_proto), + UPB_DEFTYPE_MSG); + m->output_type = symtab_resolve( + ctx, m->full_name, m->full_name, + google_protobuf_MethodDescriptorProto_output_type(method_proto), + UPB_DEFTYPE_MSG); + + SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions, method_proto); + } +} + +static int count_bits_debug(uint64_t x) { + // For assertions only, speed does not matter. + int n = 0; + while (x) { + if (x & 1) n++; + x >>= 1; + } + return n; +} + +upb_MiniTable_Enum* create_enumlayout(symtab_addctx* ctx, + const upb_EnumDef* e) { + int n = 0; + uint64_t mask = 0; + + for (int i = 0; i < e->value_count; i++) { + uint32_t val = (uint32_t)e->values[i].number; + if (val < 64) { + mask |= 1 << val; + } else { + n++; + } + } + + int32_t* values = symtab_alloc(ctx, sizeof(*values) * n); + + if (n) { + int32_t* p = values; + + // Add values outside the bitmask range to the list, as described in the + // comments for upb_MiniTable_Enum. + for (int i = 0; i < e->value_count; i++) { + int32_t val = e->values[i].number; + if ((uint32_t)val >= 64) { + *p++ = val; + } + } + UPB_ASSERT(p == values + n); + } + + UPB_ASSERT(upb_inttable_count(&e->iton) == n + count_bits_debug(mask)); + + upb_MiniTable_Enum* layout = symtab_alloc(ctx, sizeof(*layout)); + layout->value_count = n; + layout->mask = mask; + layout->values = values; + + return layout; +} + +static void create_enumvaldef( + symtab_addctx* ctx, const char* prefix, + const google_protobuf_EnumValueDescriptorProto* val_proto, upb_EnumDef* e, + int i) { + upb_EnumValueDef* val = (upb_EnumValueDef*)&e->values[i]; + upb_StringView name = + google_protobuf_EnumValueDescriptorProto_name(val_proto); + upb_value v = upb_value_constptr(val); + + val->parent = e; /* Must happen prior to symtab_add(). */ + val->full_name = makefullname(ctx, prefix, name); + val->number = google_protobuf_EnumValueDescriptorProto_number(val_proto); + symtab_add(ctx, val->full_name, pack_def(val, UPB_DEFTYPE_ENUMVAL)); + + SET_OPTIONS(val->opts, EnumValueDescriptorProto, EnumValueOptions, val_proto); + + if (i == 0 && e->file->syntax == kUpb_Syntax_Proto3 && val->number != 0) { + symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)", + e->full_name); + } + + CHK_OOM(upb_strtable_insert(&e->ntoi, name.data, name.size, v, ctx->arena)); + + // Multiple enumerators can have the same number, first one wins. + if (!upb_inttable_lookup(&e->iton, val->number, NULL)) { + CHK_OOM(upb_inttable_insert(&e->iton, val->number, v, ctx->arena)); } } static void create_enumdef( - symtab_addctx *ctx, const char *prefix, - const google_protobuf_EnumDescriptorProto *enum_proto) { - upb_enumdef *e; - const google_protobuf_EnumValueDescriptorProto *const *values; - upb_strview name; + symtab_addctx* ctx, const char* prefix, + const google_protobuf_EnumDescriptorProto* enum_proto, + const upb_MessageDef* containing_type, const upb_EnumDef* _e) { + upb_EnumDef* e = (upb_EnumDef*)_e; + ; + const google_protobuf_EnumValueDescriptorProto* const* values; + upb_StringView name; size_t i, n; + e->file = ctx->file; /* Must happen prior to symtab_add() */ + e->containing_type = containing_type; + name = google_protobuf_EnumDescriptorProto_name(enum_proto); check_ident(ctx, name, false); - e = (upb_enumdef*)&ctx->file->enums[ctx->enum_count++]; e->full_name = makefullname(ctx, prefix, name); symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM)); @@ -1882,7 +2489,6 @@ static void create_enumdef( CHK_OOM(upb_strtable_init(&e->ntoi, n, ctx->arena)); CHK_OOM(upb_inttable_init(&e->iton, ctx->arena)); - e->file = ctx->file; e->defaultval = 0; e->value_count = n; e->values = symtab_alloc(ctx, sizeof(*e->values) * n); @@ -1892,52 +2498,50 @@ static void create_enumdef( e->full_name); } - for (i = 0; i < n; i++) { - const google_protobuf_EnumValueDescriptorProto *val_proto = values[i]; - upb_enumvaldef *val = (upb_enumvaldef*)&e->values[i]; - upb_strview name = google_protobuf_EnumValueDescriptorProto_name(val_proto); - upb_value v = upb_value_constptr(val); - - val->enum_ = e; - val->full_name = makefullname(ctx, prefix, name); - val->number = google_protobuf_EnumValueDescriptorProto_number(val_proto); - symtab_add(ctx, val->full_name, pack_def(val, UPB_DEFTYPE_ENUMVAL)); + SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto); - if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && val->number != 0) { - symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)", - e->full_name); - } + for (i = 0; i < n; i++) { + create_enumvaldef(ctx, prefix, values[i], e, i); + } - CHK_OOM(upb_strtable_insert(&e->ntoi, name.data, name.size, v, ctx->arena)); + upb_inttable_compact(&e->iton, ctx->arena); - // Multiple enumerators can have the same number, first one wins. - if (!upb_inttable_lookup(&e->iton, val->number, NULL)) { - CHK_OOM(upb_inttable_insert(&e->iton, val->number, v, ctx->arena)); + if (e->file->syntax == kUpb_Syntax_Proto2) { + if (ctx->layout) { + UPB_ASSERT(ctx->enum_count < ctx->layout->enum_count); + e->layout = ctx->layout->enums[ctx->enum_count++]; + UPB_ASSERT(n == + e->layout->value_count + count_bits_debug(e->layout->mask)); + } else { + e->layout = create_enumlayout(ctx, e); } + } else { + e->layout = NULL; } - - upb_inttable_compact(&e->iton, ctx->arena); } -static void create_msgdef(symtab_addctx *ctx, const char *prefix, - const google_protobuf_DescriptorProto *msg_proto) { - upb_msgdef *m; - const google_protobuf_MessageOptions *options; - const google_protobuf_OneofDescriptorProto *const *oneofs; - const google_protobuf_FieldDescriptorProto *const *fields; - const google_protobuf_EnumDescriptorProto *const *enums; - const google_protobuf_DescriptorProto *const *msgs; - const google_protobuf_DescriptorProto_ExtensionRange *const *ext_ranges; - size_t i, n_oneof, n_field, n_ext_range, n; - upb_strview name; +static void msgdef_create_nested( + symtab_addctx* ctx, const google_protobuf_DescriptorProto* msg_proto, + upb_MessageDef* m); + +static void create_msgdef(symtab_addctx* ctx, const char* prefix, + const google_protobuf_DescriptorProto* msg_proto, + const upb_MessageDef* containing_type, + const upb_MessageDef* _m) { + upb_MessageDef* m = (upb_MessageDef*)_m; + const google_protobuf_OneofDescriptorProto* const* oneofs; + const google_protobuf_FieldDescriptorProto* const* fields; + const google_protobuf_DescriptorProto_ExtensionRange* const* ext_ranges; + size_t i, n_oneof, n_field, n_ext_range; + upb_StringView name; + + m->file = ctx->file; /* Must happen prior to symtab_add(). */ + m->containing_type = containing_type; name = google_protobuf_DescriptorProto_name(msg_proto); check_ident(ctx, name, false); - int msg_index = ctx->msg_count; - m = (upb_msgdef*)&ctx->file->msgs[msg_index]; m->full_name = makefullname(ctx, prefix, name); - ctx->msg_count++; symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG)); oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof); @@ -1948,206 +2552,293 @@ static void create_msgdef(symtab_addctx *ctx, const char *prefix, CHK_OOM(upb_inttable_init(&m->itof, ctx->arena)); CHK_OOM(upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena)); - m->file = ctx->file; - m->map_entry = false; - m->is_message_set = false; - m->message_set_ext = NULL; - - options = google_protobuf_DescriptorProto_options(msg_proto); - - if (options) { - m->map_entry = google_protobuf_MessageOptions_map_entry(options); - m->is_message_set = - google_protobuf_MessageOptions_message_set_wire_format(options); - } - if (ctx->layout) { /* create_fielddef() below depends on this being set. */ - m->layout = ctx->layout->msgs[msg_index]; + UPB_ASSERT(ctx->msg_count < ctx->layout->msg_count); + m->layout = ctx->layout->msgs[ctx->msg_count++]; UPB_ASSERT(n_field == m->layout->field_count); } else { /* Allocate now (to allow cross-linking), populate later. */ - m->layout = symtab_alloc( - ctx, sizeof(*m->layout) + sizeof(_upb_fasttable_entry)); + m->layout = + symtab_alloc(ctx, sizeof(*m->layout) + sizeof(_upb_FastTable_Entry)); } - m->oneof_count = 0; + SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto); + + m->oneof_count = n_oneof; m->oneofs = symtab_alloc(ctx, sizeof(*m->oneofs) * n_oneof); for (i = 0; i < n_oneof; i++) { - create_oneofdef(ctx, m, oneofs[i]); + create_oneofdef(ctx, m, oneofs[i], &m->oneofs[i]); } - m->field_count = 0; + m->field_count = n_field; m->fields = symtab_alloc(ctx, sizeof(*m->fields) * n_field); for (i = 0; i < n_field; i++) { - create_fielddef(ctx, m->full_name, m, fields[i]); + create_fielddef(ctx, m->full_name, m, fields[i], &m->fields[i], + /* is_extension= */ false); } m->ext_range_count = n_ext_range; m->ext_ranges = symtab_alloc(ctx, sizeof(*m->ext_ranges) * n_ext_range); for (i = 0; i < n_ext_range; i++) { - const google_protobuf_DescriptorProto_ExtensionRange *r = ext_ranges[i]; - upb_extrange *r_def = (upb_extrange*)&m->ext_ranges[i]; - r_def->start = google_protobuf_DescriptorProto_ExtensionRange_start(r); - r_def->end = google_protobuf_DescriptorProto_ExtensionRange_end(r); + const google_protobuf_DescriptorProto_ExtensionRange* r = ext_ranges[i]; + upb_ExtensionRange* r_def = (upb_ExtensionRange*)&m->ext_ranges[i]; + int32_t start = google_protobuf_DescriptorProto_ExtensionRange_start(r); + int32_t end = google_protobuf_DescriptorProto_ExtensionRange_end(r); + int32_t max = + google_protobuf_MessageOptions_message_set_wire_format(m->opts) + ? INT32_MAX + : kUpb_MaxFieldNumber + 1; + + // A full validation would also check that each range is disjoint, and that + // none of the fields overlap with the extension ranges, but we are just + // sanity checking here. + if (start < 1 || end <= start || end > max) { + symtab_errf(ctx, "Extension range (%d, %d) is invalid, message=%s\n", + (int)start, (int)end, m->full_name); + } + + r_def->start = start; + r_def->end = end; + SET_OPTIONS(r_def->opts, DescriptorProto_ExtensionRange, + ExtensionRangeOptions, r); } finalize_oneofs(ctx, m); assign_msg_wellknowntype(m); upb_inttable_compact(&m->itof, ctx->arena); - - /* This message is built. Now build nested messages and enums. */ - - enums = google_protobuf_DescriptorProto_enum_type(msg_proto, &n); - for (i = 0; i < n; i++) { - create_enumdef(ctx, m->full_name, enums[i]); - } - - fields = google_protobuf_DescriptorProto_extension(msg_proto, &n); - for (i = 0; i < n; i++) { - create_fielddef(ctx, m->full_name, NULL, fields[i]); - } - - msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); - for (i = 0; i < n; i++) { - create_msgdef(ctx, m->full_name, msgs[i]); + msgdef_create_nested(ctx, msg_proto, m); +} + +static void msgdef_create_nested( + symtab_addctx* ctx, const google_protobuf_DescriptorProto* msg_proto, + upb_MessageDef* m) { + size_t n; + + const google_protobuf_EnumDescriptorProto* const* enums = + google_protobuf_DescriptorProto_enum_type(msg_proto, &n); + m->nested_enum_count = n; + m->nested_enums = symtab_alloc(ctx, sizeof(*m->nested_enums) * n); + for (size_t i = 0; i < n; i++) { + m->nested_enum_count = i + 1; + create_enumdef(ctx, m->full_name, enums[i], m, &m->nested_enums[i]); + } + + const google_protobuf_FieldDescriptorProto* const* exts = + google_protobuf_DescriptorProto_extension(msg_proto, &n); + m->nested_ext_count = n; + m->nested_exts = symtab_alloc(ctx, sizeof(*m->nested_exts) * n); + for (size_t i = 0; i < n; i++) { + create_fielddef(ctx, m->full_name, m, exts[i], &m->nested_exts[i], + /* is_extension= */ true); + ((upb_FieldDef*)&m->nested_exts[i])->index_ = i; + } + + const google_protobuf_DescriptorProto* const* msgs = + google_protobuf_DescriptorProto_nested_type(msg_proto, &n); + m->nested_msg_count = n; + m->nested_msgs = symtab_alloc(ctx, sizeof(*m->nested_msgs) * n); + for (size_t i = 0; i < n; i++) { + create_msgdef(ctx, m->full_name, msgs[i], m, &m->nested_msgs[i]); + } +} + +static void resolve_subdef(symtab_addctx* ctx, const char* prefix, + upb_FieldDef* f) { + const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved; + upb_StringView name = + google_protobuf_FieldDescriptorProto_type_name(field_proto); + bool has_name = + google_protobuf_FieldDescriptorProto_has_type_name(field_proto); + switch ((int)f->type_) { + case FIELD_TYPE_UNSPECIFIED: { + // Type was not specified and must be inferred. + UPB_ASSERT(has_name); + upb_deftype_t type; + const void* def = + symtab_resolveany(ctx, f->full_name, prefix, name, &type); + switch (type) { + case UPB_DEFTYPE_ENUM: + f->sub.enumdef = def; + f->type_ = kUpb_FieldType_Enum; + break; + case UPB_DEFTYPE_MSG: + f->sub.msgdef = def; + f->type_ = kUpb_FieldType_Message; // It appears there is no way of + // this being a group. + break; + default: + symtab_errf(ctx, "Couldn't resolve type name for field %s", + f->full_name); + } + } + case kUpb_FieldType_Message: + case kUpb_FieldType_Group: + UPB_ASSERT(has_name); + f->sub.msgdef = + symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_MSG); + break; + case kUpb_FieldType_Enum: + UPB_ASSERT(has_name); + f->sub.enumdef = + symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_ENUM); + break; + default: + // No resolution necessary. + break; } } -static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto, - upb_filedef *file) { - const google_protobuf_DescriptorProto *const *msgs; - size_t i, n; - - file->msg_count++; - - msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); - for (i = 0; i < n; i++) { - count_types_in_msg(msgs[i], file); +static void resolve_extension( + symtab_addctx* ctx, const char* prefix, upb_FieldDef* f, + const google_protobuf_FieldDescriptorProto* field_proto) { + if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) { + symtab_errf(ctx, "extension for field '%s' had no extendee", f->full_name); } - google_protobuf_DescriptorProto_enum_type(msg_proto, &n); - file->enum_count += n; + upb_StringView name = + google_protobuf_FieldDescriptorProto_extendee(field_proto); + const upb_MessageDef* m = + symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_MSG); + f->msgdef = m; - google_protobuf_DescriptorProto_extension(msg_proto, &n); - file->ext_count += n; -} + bool found = false; -static void count_types_in_file( - const google_protobuf_FileDescriptorProto *file_proto, - upb_filedef *file) { - const google_protobuf_DescriptorProto *const *msgs; - size_t i, n; + for (int i = 0, n = m->ext_range_count; i < n; i++) { + const upb_ExtensionRange* r = &m->ext_ranges[i]; + if (r->start <= f->number_ && f->number_ < r->end) { + found = true; + break; + } + } - msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); - for (i = 0; i < n; i++) { - count_types_in_msg(msgs[i], file); + if (!found) { + symtab_errf(ctx, + "field number %u in extension %s has no extension range in " + "message %s", + (unsigned)f->number_, f->full_name, f->msgdef->full_name); } - google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); - file->enum_count += n; + const upb_MiniTable_Extension* ext = ctx->file->ext_layouts[f->layout_index]; + if (ctx->layout) { + UPB_ASSERT(upb_FieldDef_Number(f) == ext->field.number); + } else { + upb_MiniTable_Extension* mut_ext = (upb_MiniTable_Extension*)ext; + fill_fieldlayout(&mut_ext->field, f); + mut_ext->field.presence = 0; + mut_ext->field.offset = 0; + mut_ext->field.submsg_index = 0; + mut_ext->extendee = f->msgdef->layout; + mut_ext->sub.submsg = f->sub.msgdef->layout; + } - google_protobuf_FileDescriptorProto_extension(file_proto, &n); - file->ext_count += n; + CHK_OOM(upb_inttable_insert(&ctx->symtab->exts, (uintptr_t)ext, + upb_value_constptr(f), ctx->arena)); } -static void resolve_fielddef(symtab_addctx *ctx, const char *prefix, - upb_fielddef *f) { - upb_strview name; - const google_protobuf_FieldDescriptorProto *field_proto = f->sub.unresolved; +static void resolve_default( + symtab_addctx* ctx, upb_FieldDef* f, + const google_protobuf_FieldDescriptorProto* field_proto) { + // Have to delay resolving of the default value until now because of the enum + // case, since enum defaults are specified with a label. + if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) { + upb_StringView defaultval = + google_protobuf_FieldDescriptorProto_default_value(field_proto); - if (f->is_extension_) { - if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) { - symtab_errf(ctx, "extension for field '%s' had no extendee", + if (f->file->syntax == kUpb_Syntax_Proto3) { + symtab_errf(ctx, "proto3 fields cannot have explicit defaults (%s)", f->full_name); } - name = google_protobuf_FieldDescriptorProto_extendee(field_proto); - f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); - - const upb_msglayout_ext *ext = ctx->file->ext_layouts[f->layout_index]; - if (ctx->layout) { - UPB_ASSERT(upb_fielddef_number(f) == ext->field.number); - } else { - upb_msglayout_ext *mut_ext = (upb_msglayout_ext*)ext; - fill_fieldlayout(&mut_ext->field, f); - mut_ext->field.presence = 0; - mut_ext->field.offset = 0; - mut_ext->field.submsg_index = 0; - mut_ext->extendee = f->msgdef->layout; - mut_ext->sub.submsg = f->sub.msgdef->layout; + if (upb_FieldDef_IsSubMessage(f)) { + symtab_errf(ctx, "message fields cannot have explicit defaults (%s)", + f->full_name); } - CHK_OOM(upb_inttable_insert(&ctx->symtab->exts, (uintptr_t)ext, - upb_value_constptr(f), ctx->arena)); + parse_default(ctx, defaultval.data, defaultval.size, f); + f->has_default = true; + } else { + set_default_default(ctx, f); + f->has_default = false; } +} - if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) && - !google_protobuf_FieldDescriptorProto_has_type_name(field_proto)) { - symtab_errf(ctx, "field '%s' is missing type name", f->full_name); +static void resolve_fielddef(symtab_addctx* ctx, const char* prefix, + upb_FieldDef* f) { + // We have to stash this away since resolve_subdef() may overwrite it. + const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved; + + resolve_subdef(ctx, prefix, f); + resolve_default(ctx, f, field_proto); + + if (f->is_extension_) { + resolve_extension(ctx, prefix, f, field_proto); } +} - name = google_protobuf_FieldDescriptorProto_type_name(field_proto); +static void resolve_msgdef(symtab_addctx* ctx, upb_MessageDef* m) { + for (int i = 0; i < m->field_count; i++) { + resolve_fielddef(ctx, m->full_name, (upb_FieldDef*)&m->fields[i]); + } - if (upb_fielddef_issubmsg(f)) { - f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); - if (f->is_extension_ && f->msgdef->is_message_set && - f->file == f->msgdef->file) { - // TODO: When defs are restructured to follow message nesting, we can make - // this check more robust. The actual rules for what make something - // qualify as a MessageSet item are more strict. - ((upb_msgdef*)f->sub.msgdef)->message_set_ext = f; - } - } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) { - f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM); + for (int i = 0; i < m->nested_ext_count; i++) { + resolve_fielddef(ctx, m->full_name, (upb_FieldDef*)&m->nested_exts[i]); } - /* Have to delay resolving of the default value until now because of the enum - * case, since enum defaults are specified with a label. */ - if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) { - upb_strview defaultval = - google_protobuf_FieldDescriptorProto_default_value(field_proto); + if (!ctx->layout) make_layout(ctx, m); - if (f->file->syntax == UPB_SYNTAX_PROTO3) { - symtab_errf(ctx, "proto3 fields cannot have explicit defaults (%s)", - f->full_name); + m->in_message_set = false; + if (m->nested_ext_count == 1) { + const upb_FieldDef* ext = &m->nested_exts[0]; + if (ext->type_ == kUpb_FieldType_Message && + ext->label_ == kUpb_Label_Optional && ext->sub.msgdef == m && + google_protobuf_MessageOptions_message_set_wire_format( + ext->msgdef->opts)) { + m->in_message_set = true; } + } - if (upb_fielddef_issubmsg(f)) { - symtab_errf(ctx, "message fields cannot have explicit defaults (%s)", - f->full_name); - } + for (int i = 0; i < m->nested_msg_count; i++) { + resolve_msgdef(ctx, (upb_MessageDef*)&m->nested_msgs[i]); + } +} - parse_default(ctx, defaultval.data, defaultval.size, f); - } else { - set_default_default(ctx, f); +static int count_exts_in_msg(const google_protobuf_DescriptorProto* msg_proto) { + size_t n; + google_protobuf_DescriptorProto_extension(msg_proto, &n); + int ext_count = n; + + const google_protobuf_DescriptorProto* const* nested_msgs = + google_protobuf_DescriptorProto_nested_type(msg_proto, &n); + for (size_t i = 0; i < n; i++) { + ext_count += count_exts_in_msg(nested_msgs[i]); } + + return ext_count; } static void build_filedef( - symtab_addctx *ctx, upb_filedef *file, - const google_protobuf_FileDescriptorProto *file_proto) { - const google_protobuf_FileOptions *file_options_proto; - const google_protobuf_DescriptorProto *const *msgs; - const google_protobuf_EnumDescriptorProto *const *enums; - const google_protobuf_FieldDescriptorProto *const *exts; - const upb_strview* strs; + symtab_addctx* ctx, upb_FileDef* file, + const google_protobuf_FileDescriptorProto* file_proto) { + const google_protobuf_DescriptorProto* const* msgs; + const google_protobuf_EnumDescriptorProto* const* enums; + const google_protobuf_FieldDescriptorProto* const* exts; + const google_protobuf_ServiceDescriptorProto* const* services; + const upb_StringView* strs; + const int32_t* public_deps; + const int32_t* weak_deps; size_t i, n; file->symtab = ctx->symtab; - /* One pass to count and allocate. */ - file->msg_count = 0; - file->enum_count = 0; - file->ext_count = 0; - count_types_in_file(file_proto, file); - file->msgs = symtab_alloc(ctx, sizeof(*file->msgs) * file->msg_count); - file->enums = symtab_alloc(ctx, sizeof(*file->enums) * file->enum_count); - file->exts = symtab_alloc(ctx, sizeof(*file->exts) * file->ext_count); - - ctx->msg_count = 0; - ctx->enum_count = 0; - ctx->ext_count = 0; + /* Count all extensions in the file, to build a flat array of layouts. */ + google_protobuf_FileDescriptorProto_extension(file_proto, &n); + int ext_count = n; + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + for (int i = 0; i < n; i++) { + ext_count += count_exts_in_msg(msgs[i]); + } + file->ext_count = ext_count; if (ctx->layout) { /* We are using the ext layouts that were passed in. */ @@ -2160,7 +2851,8 @@ static void build_filedef( /* We are building ext layouts from scratch. */ file->ext_layouts = symtab_alloc(ctx, sizeof(*file->ext_layouts) * file->ext_count); - upb_msglayout_ext *ext = symtab_alloc(ctx, sizeof(*ext) * file->ext_count); + upb_MiniTable_Extension* ext = + symtab_alloc(ctx, sizeof(*ext) * file->ext_count); for (int i = 0; i < file->ext_count; i++) { file->ext_layouts[i] = &ext[i]; } @@ -2172,11 +2864,9 @@ static void build_filedef( file->name = strviewdup(ctx, google_protobuf_FileDescriptorProto_name(file_proto)); - file->phpprefix = NULL; - file->phpnamespace = NULL; if (google_protobuf_FileDescriptorProto_has_package(file_proto)) { - upb_strview package = + upb_StringView package = google_protobuf_FileDescriptorProto_package(file_proto); check_ident(ctx, package, true); file->package = strviewdup(ctx, package); @@ -2185,190 +2875,243 @@ static void build_filedef( } if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) { - upb_strview syntax = + upb_StringView syntax = google_protobuf_FileDescriptorProto_syntax(file_proto); if (streql_view(syntax, "proto2")) { - file->syntax = UPB_SYNTAX_PROTO2; + file->syntax = kUpb_Syntax_Proto2; } else if (streql_view(syntax, "proto3")) { - file->syntax = UPB_SYNTAX_PROTO3; + file->syntax = kUpb_Syntax_Proto3; } else { - symtab_errf(ctx, "Invalid syntax '" UPB_STRVIEW_FORMAT "'", - UPB_STRVIEW_ARGS(syntax)); + symtab_errf(ctx, "Invalid syntax '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(syntax)); } } else { - file->syntax = UPB_SYNTAX_PROTO2; + file->syntax = kUpb_Syntax_Proto2; } /* Read options. */ - file_options_proto = google_protobuf_FileDescriptorProto_options(file_proto); - if (file_options_proto) { - if (google_protobuf_FileOptions_has_php_class_prefix(file_options_proto)) { - file->phpprefix = strviewdup( - ctx, - google_protobuf_FileOptions_php_class_prefix(file_options_proto)); - } - if (google_protobuf_FileOptions_has_php_namespace(file_options_proto)) { - file->phpnamespace = strviewdup( - ctx, google_protobuf_FileOptions_php_namespace(file_options_proto)); - } - } + SET_OPTIONS(file->opts, FileDescriptorProto, FileOptions, file_proto); /* Verify dependencies. */ strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n); + file->dep_count = n; file->deps = symtab_alloc(ctx, sizeof(*file->deps) * n); for (i = 0; i < n; i++) { - upb_strview dep_name = strs[i]; - upb_value v; - if (!upb_strtable_lookup2(&ctx->symtab->files, dep_name.data, - dep_name.size, &v)) { + upb_StringView str = strs[i]; + file->deps[i] = + upb_DefPool_FindFileByNameWithSize(ctx->symtab, str.data, str.size); + if (!file->deps[i]) { symtab_errf(ctx, - "Depends on file '" UPB_STRVIEW_FORMAT + "Depends on file '" UPB_STRINGVIEW_FORMAT "', but it has not been loaded", - UPB_STRVIEW_ARGS(dep_name)); + UPB_STRINGVIEW_ARGS(str)); } - file->deps[i] = upb_value_getconstptr(v); } - /* Create messages. */ - msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + public_deps = + google_protobuf_FileDescriptorProto_public_dependency(file_proto, &n); + file->public_dep_count = n; + file->public_deps = symtab_alloc(ctx, sizeof(*file->public_deps) * n); + int32_t* mutable_public_deps = (int32_t*)file->public_deps; for (i = 0; i < n; i++) { - create_msgdef(ctx, file->package, msgs[i]); + if (public_deps[i] >= file->dep_count) { + symtab_errf(ctx, "public_dep %d is out of range", (int)public_deps[i]); + } + mutable_public_deps[i] = public_deps[i]; + } + + weak_deps = + google_protobuf_FileDescriptorProto_weak_dependency(file_proto, &n); + file->weak_dep_count = n; + file->weak_deps = symtab_alloc(ctx, sizeof(*file->weak_deps) * n); + int32_t* mutable_weak_deps = (int32_t*)file->weak_deps; + for (i = 0; i < n; i++) { + if (weak_deps[i] >= file->dep_count) { + symtab_errf(ctx, "public_dep %d is out of range", (int)public_deps[i]); + } + mutable_weak_deps[i] = weak_deps[i]; } /* Create enums. */ enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); + file->top_lvl_enum_count = n; + file->top_lvl_enums = symtab_alloc(ctx, sizeof(*file->top_lvl_enums) * n); for (i = 0; i < n; i++) { - create_enumdef(ctx, file->package, enums[i]); + create_enumdef(ctx, file->package, enums[i], NULL, &file->top_lvl_enums[i]); } /* Create extensions. */ exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n); + file->top_lvl_ext_count = n; + file->top_lvl_exts = symtab_alloc(ctx, sizeof(*file->top_lvl_exts) * n); + for (i = 0; i < n; i++) { + create_fielddef(ctx, file->package, NULL, exts[i], &file->top_lvl_exts[i], + /* is_extension= */ true); + ((upb_FieldDef*)&file->top_lvl_exts[i])->index_ = i; + } + + /* Create messages. */ + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + file->top_lvl_msg_count = n; + file->top_lvl_msgs = symtab_alloc(ctx, sizeof(*file->top_lvl_msgs) * n); for (i = 0; i < n; i++) { - create_fielddef(ctx, file->package, NULL, exts[i]); + create_msgdef(ctx, file->package, msgs[i], NULL, &file->top_lvl_msgs[i]); } - UPB_ASSERT(ctx->ext_count == file->ext_count); + /* Create services. */ + services = google_protobuf_FileDescriptorProto_service(file_proto, &n); + file->service_count = n; + file->services = symtab_alloc(ctx, sizeof(*file->services) * n); + for (i = 0; i < n; i++) { + create_service(ctx, services[i], &file->services[i]); + ((upb_ServiceDef*)&file->services[i])->index = i; + } /* Now that all names are in the table, build layouts and resolve refs. */ - for (i = 0; i < (size_t)file->ext_count; i++) { - resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]); + for (i = 0; i < (size_t)file->top_lvl_ext_count; i++) { + resolve_fielddef(ctx, file->package, (upb_FieldDef*)&file->top_lvl_exts[i]); } - for (i = 0; i < (size_t)file->msg_count; i++) { - const upb_msgdef *m = &file->msgs[i]; - int j; - for (j = 0; j < m->field_count; j++) { - resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j]); - } + for (i = 0; i < (size_t)file->top_lvl_msg_count; i++) { + resolve_msgdef(ctx, (upb_MessageDef*)&file->top_lvl_msgs[i]); } - if (!ctx->layout) { - for (i = 0; i < (size_t)file->msg_count; i++) { - const upb_msgdef *m = &file->msgs[i]; - make_layout(ctx, m); - } + if (file->ext_count) { + CHK_OOM(_upb_extreg_add(ctx->symtab->extreg, file->ext_layouts, + file->ext_count)); } - - CHK_OOM( - _upb_extreg_add(ctx->symtab->extreg, file->ext_layouts, file->ext_count)); } -static void remove_filedef(symtab_addctx *ctx, upb_symtab *s, upb_filedef *file) { - int i; - for (i = 0; i < ctx->msg_count; i++) { - const char *name = file->msgs[i].full_name; - upb_strtable_remove(&s->syms, name, strlen(name), NULL); - } - for (i = 0; i < ctx->enum_count; i++) { - const char *name = file->enums[i].full_name; - upb_strtable_remove(&s->syms, name, strlen(name), NULL); - } - for (i = 0; i < ctx->ext_count; i++) { - const char *name = file->exts[i].full_name; - upb_strtable_remove(&s->syms, name, strlen(name), NULL); +static void remove_filedef(upb_DefPool* s, upb_FileDef* file) { + intptr_t iter = UPB_INTTABLE_BEGIN; + upb_StringView key; + upb_value val; + while (upb_strtable_next2(&s->syms, &key, &val, &iter)) { + const upb_FileDef* f; + switch (deftype(val)) { + case UPB_DEFTYPE_EXT: + f = upb_FieldDef_File(unpack_def(val, UPB_DEFTYPE_EXT)); + break; + case UPB_DEFTYPE_MSG: + f = upb_MessageDef_File(unpack_def(val, UPB_DEFTYPE_MSG)); + break; + case UPB_DEFTYPE_ENUM: + f = upb_EnumDef_File(unpack_def(val, UPB_DEFTYPE_ENUM)); + break; + case UPB_DEFTYPE_ENUMVAL: + f = upb_EnumDef_File( + upb_EnumValueDef_Enum(unpack_def(val, UPB_DEFTYPE_ENUMVAL))); + break; + case UPB_DEFTYPE_SERVICE: + f = upb_ServiceDef_File(unpack_def(val, UPB_DEFTYPE_SERVICE)); + break; + default: + UPB_UNREACHABLE(); + } + + if (f == file) upb_strtable_removeiter(&s->syms, &iter); } } -static const upb_filedef *_upb_symtab_addfile( - upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, - const upb_msglayout_file *layout, upb_status *status) { +static const upb_FileDef* _upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, + const upb_MiniTable_File* layout, upb_Status* status) { symtab_addctx ctx; - upb_strview name = google_protobuf_FileDescriptorProto_name(file_proto); + upb_StringView name = google_protobuf_FileDescriptorProto_name(file_proto); + upb_value v; - if (upb_strtable_lookup2(&s->files, name.data, name.size, NULL)) { - upb_status_seterrf(status, "duplicate file name (%.*s)", - UPB_STRVIEW_ARGS(name)); - return NULL; + if (upb_strtable_lookup2(&s->files, name.data, name.size, &v)) { + if (unpack_def(v, UPB_DEFTYPE_FILE)) { + upb_Status_SetErrorFormat(status, "duplicate file name (%.*s)", + UPB_STRINGVIEW_ARGS(name)); + return NULL; + } + const upb_MiniTable_File* registered = unpack_def(v, UPB_DEFTYPE_LAYOUT); + UPB_ASSERT(registered); + if (layout && layout != registered) { + upb_Status_SetErrorFormat( + status, "tried to build with a different layout (filename=%.*s)", + UPB_STRINGVIEW_ARGS(name)); + return NULL; + } + layout = registered; } ctx.symtab = s; ctx.layout = layout; + ctx.msg_count = 0; + ctx.enum_count = 0; + ctx.ext_count = 0; ctx.status = status; ctx.file = NULL; - ctx.arena = upb_arena_new(); + ctx.arena = upb_Arena_New(); + ctx.tmp_arena = upb_Arena_New(); - if (!ctx.arena) { - upb_status_setoom(status); + if (!ctx.arena || !ctx.tmp_arena) { + if (ctx.arena) upb_Arena_Free(ctx.arena); + if (ctx.tmp_arena) upb_Arena_Free(ctx.tmp_arena); + upb_Status_setoom(status); return NULL; } if (UPB_UNLIKELY(UPB_SETJMP(ctx.err))) { - UPB_ASSERT(!upb_ok(status)); + UPB_ASSERT(!upb_Status_IsOk(status)); if (ctx.file) { - remove_filedef(&ctx, s, ctx.file); + remove_filedef(s, ctx.file); ctx.file = NULL; } } else { ctx.file = symtab_alloc(&ctx, sizeof(*ctx.file)); build_filedef(&ctx, ctx.file, file_proto); upb_strtable_insert(&s->files, name.data, name.size, - upb_value_constptr(ctx.file), ctx.arena); - UPB_ASSERT(upb_ok(status)); - upb_arena_fuse(s->arena, ctx.arena); + pack_def(ctx.file, UPB_DEFTYPE_FILE), ctx.arena); + UPB_ASSERT(upb_Status_IsOk(status)); + upb_Arena_Fuse(s->arena, ctx.arena); } - upb_arena_free(ctx.arena); + upb_Arena_Free(ctx.arena); + upb_Arena_Free(ctx.tmp_arena); return ctx.file; } -const upb_filedef *upb_symtab_addfile( - upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, - upb_status *status) { - return _upb_symtab_addfile(s, file_proto, NULL, status); +const upb_FileDef* upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, + upb_Status* status) { + return _upb_DefPool_AddFile(s, file_proto, NULL, status); } /* Include here since we want most of this file to be stdio-free. */ #include <stdio.h> -bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { +bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init) { /* Since this function should never fail (it would indicate a bug in upb) we * print errors to stderr instead of returning error status to the user. */ - upb_def_init **deps = init->deps; - google_protobuf_FileDescriptorProto *file; - upb_arena *arena; - upb_status status; + _upb_DefPool_Init** deps = init->deps; + google_protobuf_FileDescriptorProto* file; + upb_Arena* arena; + upb_Status status; - upb_status_clear(&status); + upb_Status_Clear(&status); - if (upb_strtable_lookup(&s->files, init->filename, NULL)) { + if (upb_DefPool_FindFileByName(s, init->filename)) { return true; } - arena = upb_arena_new(); + arena = upb_Arena_New(); for (; *deps; deps++) { - if (!_upb_symtab_loaddefinit(s, *deps)) goto err; + if (!_upb_DefPool_LoadDefInit(s, *deps)) goto err; } file = google_protobuf_FileDescriptorProto_parse_ex( - init->descriptor.data, init->descriptor.size, NULL, UPB_DECODE_ALIAS, - arena); + init->descriptor.data, init->descriptor.size, NULL, + kUpb_DecodeOption_AliasString, arena); s->bytes_loaded += init->descriptor.size; if (!file) { - upb_status_seterrf( + upb_Status_SetErrorFormat( &status, "Failed to parse compiled-in descriptor for file '%s'. This should " "never happen.", @@ -2376,38 +3119,80 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { goto err; } - if (!_upb_symtab_addfile(s, file, init->layout, &status)) goto err; + if (!_upb_DefPool_AddFile(s, file, init->layout, &status)) { + goto err; + } - upb_arena_free(arena); + upb_Arena_Free(arena); return true; err: fprintf(stderr, "Error loading compiled-in descriptor for file '%s' (this should " "never happen): %s\n", - init->filename, upb_status_errmsg(&status)); - upb_arena_free(arena); + init->filename, upb_Status_ErrorMessage(&status)); + upb_Arena_Free(arena); return false; } -size_t _upb_symtab_bytesloaded(const upb_symtab *s) { +size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s) { return s->bytes_loaded; } -upb_arena *_upb_symtab_arena(const upb_symtab *s) { - return s->arena; -} +upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s) { return s->arena; } -const upb_fielddef *_upb_symtab_lookupextfield(const upb_symtab *s, - const upb_msglayout_ext *ext) { +const upb_FieldDef* _upb_DefPool_FindExtensionByMiniTable( + const upb_DefPool* s, const upb_MiniTable_Extension* ext) { upb_value v; bool ok = upb_inttable_lookup(&s->exts, (uintptr_t)ext, &v); UPB_ASSERT(ok); return upb_value_getconstptr(v); } -const upb_extreg *upb_symtab_extreg(const upb_symtab *s) { +const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s, + const upb_MessageDef* m, + int32_t fieldnum) { + const upb_MiniTable* l = upb_MessageDef_MiniTable(m); + const upb_MiniTable_Extension* ext = _upb_extreg_get(s->extreg, l, fieldnum); + return ext ? _upb_DefPool_FindExtensionByMiniTable(s, ext) : NULL; +} + +bool _upb_DefPool_registerlayout(upb_DefPool* s, const char* filename, + const upb_MiniTable_File* file) { + if (upb_DefPool_FindFileByName(s, filename)) return false; + upb_value v = pack_def(file, UPB_DEFTYPE_LAYOUT); + return upb_strtable_insert(&s->files, filename, strlen(filename), v, + s->arena); +} + +const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( + const upb_DefPool* s) { return s->extreg; } +const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, + const upb_MessageDef* m, + size_t* count) { + size_t n = 0; + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t key; + upb_value val; + // This is O(all exts) instead of O(exts for m). If we need this to be + // efficient we may need to make extreg into a two-level table, or have a + // second per-message index. + while (upb_inttable_next2(&s->exts, &key, &val, &iter)) { + const upb_FieldDef* f = upb_value_getconstptr(val); + if (upb_FieldDef_ContainingType(f) == m) n++; + } + const upb_FieldDef** exts = malloc(n * sizeof(*exts)); + iter = UPB_INTTABLE_BEGIN; + size_t i = 0; + while (upb_inttable_next2(&s->exts, &key, &val, &iter)) { + const upb_FieldDef* f = upb_value_getconstptr(val); + if (upb_FieldDef_ContainingType(f) == m) exts[i++] = f; + } + *count = n; + return exts; +} + #undef CHK_OOM diff --git a/contrib/libs/grpc/third_party/upb/upb/def.h b/contrib/libs/grpc/third_party/upb/upb/def.h index b548e2b360..8b64a53c1d 100644 --- a/contrib/libs/grpc/third_party/upb/upb/def.h +++ b/contrib/libs/grpc/third_party/upb/upb/def.h @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -25,344 +25,376 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * Defs are upb's internal representation of the constructs that can appear - * in a .proto file: - * - * - upb_msgdef: describes a "message" construct. - * - upb_fielddef: describes a message field. - * - upb_filedef: describes a .proto file and its defs. - * - upb_enumdef: describes an enum. - * - upb_oneofdef: describes a oneof. - * - * TODO: definitions of services. - */ - #ifndef UPB_DEF_H_ #define UPB_DEF_H_ -#include "upb/upb.h" -#include "upb/table_internal.h" #include "google/protobuf/descriptor.upb.h" +#include "upb/table_internal.h" +#include "upb/upb.h" /* Must be last. */ #include "upb/port_def.inc" #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ - -struct upb_enumdef; -typedef struct upb_enumdef upb_enumdef; -struct upb_enumvaldef; -typedef struct upb_enumvaldef upb_enumvaldef; -struct upb_extrange; -typedef struct upb_extrange upb_extrange; -struct upb_fielddef; -typedef struct upb_fielddef upb_fielddef; -struct upb_filedef; -typedef struct upb_filedef upb_filedef; -struct upb_msgdef; -typedef struct upb_msgdef upb_msgdef; -struct upb_oneofdef; -typedef struct upb_oneofdef upb_oneofdef; -struct upb_symtab; -typedef struct upb_symtab upb_symtab; - -typedef enum { - UPB_SYNTAX_PROTO2 = 2, - UPB_SYNTAX_PROTO3 = 3 -} upb_syntax_t; +#endif /* __cplusplus */ + +struct upb_EnumDef; +typedef struct upb_EnumDef upb_EnumDef; +struct upb_EnumValueDef; +typedef struct upb_EnumValueDef upb_EnumValueDef; +struct upb_ExtensionRange; +typedef struct upb_ExtensionRange upb_ExtensionRange; +struct upb_FieldDef; +typedef struct upb_FieldDef upb_FieldDef; +struct upb_FileDef; +typedef struct upb_FileDef upb_FileDef; +struct upb_MethodDef; +typedef struct upb_MethodDef upb_MethodDef; +struct upb_MessageDef; +typedef struct upb_MessageDef upb_MessageDef; +struct upb_OneofDef; +typedef struct upb_OneofDef upb_OneofDef; +struct upb_ServiceDef; +typedef struct upb_ServiceDef upb_ServiceDef; +struct upb_streamdef; +typedef struct upb_streamdef upb_streamdef; +struct upb_DefPool; +typedef struct upb_DefPool upb_DefPool; + +typedef enum { kUpb_Syntax_Proto2 = 2, kUpb_Syntax_Proto3 = 3 } upb_Syntax; /* All the different kind of well known type messages. For simplicity of check, * number wrappers and string wrappers are grouped together. Make sure the * order and merber of these groups are not changed. */ typedef enum { - UPB_WELLKNOWN_UNSPECIFIED, - UPB_WELLKNOWN_ANY, - UPB_WELLKNOWN_FIELDMASK, - UPB_WELLKNOWN_DURATION, - UPB_WELLKNOWN_TIMESTAMP, + kUpb_WellKnown_Unspecified, + kUpb_WellKnown_Any, + kUpb_WellKnown_FieldMask, + kUpb_WellKnown_Duration, + kUpb_WellKnown_Timestamp, /* number wrappers */ - UPB_WELLKNOWN_DOUBLEVALUE, - UPB_WELLKNOWN_FLOATVALUE, - UPB_WELLKNOWN_INT64VALUE, - UPB_WELLKNOWN_UINT64VALUE, - UPB_WELLKNOWN_INT32VALUE, - UPB_WELLKNOWN_UINT32VALUE, + kUpb_WellKnown_DoubleValue, + kUpb_WellKnown_FloatValue, + kUpb_WellKnown_Int64Value, + kUpb_WellKnown_UInt64Value, + kUpb_WellKnown_Int32Value, + kUpb_WellKnown_UInt32Value, /* string wrappers */ - UPB_WELLKNOWN_STRINGVALUE, - UPB_WELLKNOWN_BYTESVALUE, - UPB_WELLKNOWN_BOOLVALUE, - UPB_WELLKNOWN_VALUE, - UPB_WELLKNOWN_LISTVALUE, - UPB_WELLKNOWN_STRUCT -} upb_wellknowntype_t; + kUpb_WellKnown_StringValue, + kUpb_WellKnown_BytesValue, + kUpb_WellKnown_BoolValue, + kUpb_WellKnown_Value, + kUpb_WellKnown_ListValue, + kUpb_WellKnown_Struct +} upb_WellKnown; -/* upb_fielddef ***************************************************************/ +/* upb_FieldDef ***************************************************************/ /* Maximum field number allowed for FieldDefs. This is an inherent limit of the * protobuf wire format. */ -#define UPB_MAX_FIELDNUMBER ((1 << 29) - 1) - -const char *upb_fielddef_fullname(const upb_fielddef *f); -upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f); -upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f); -upb_label_t upb_fielddef_label(const upb_fielddef *f); -uint32_t upb_fielddef_number(const upb_fielddef *f); -const char *upb_fielddef_name(const upb_fielddef *f); -const char *upb_fielddef_jsonname(const upb_fielddef *f); -bool upb_fielddef_isextension(const upb_fielddef *f); -bool upb_fielddef_lazy(const upb_fielddef *f); -bool upb_fielddef_packed(const upb_fielddef *f); -const upb_filedef *upb_fielddef_file(const upb_fielddef *f); -const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f); -const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f); -const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f); -uint32_t upb_fielddef_index(const upb_fielddef *f); -bool upb_fielddef_issubmsg(const upb_fielddef *f); -bool upb_fielddef_isstring(const upb_fielddef *f); -bool upb_fielddef_isseq(const upb_fielddef *f); -bool upb_fielddef_isprimitive(const upb_fielddef *f); -bool upb_fielddef_ismap(const upb_fielddef *f); -int64_t upb_fielddef_defaultint64(const upb_fielddef *f); -int32_t upb_fielddef_defaultint32(const upb_fielddef *f); -uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f); -uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f); -bool upb_fielddef_defaultbool(const upb_fielddef *f); -float upb_fielddef_defaultfloat(const upb_fielddef *f); -double upb_fielddef_defaultdouble(const upb_fielddef *f); -const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len); -bool upb_fielddef_hassubdef(const upb_fielddef *f); -bool upb_fielddef_haspresence(const upb_fielddef *f); -const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f); -const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f); -const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f); -const upb_msglayout_ext *_upb_fielddef_extlayout(const upb_fielddef *f); - -/* upb_oneofdef ***************************************************************/ - -typedef upb_inttable_iter upb_oneof_iter; - -const char *upb_oneofdef_name(const upb_oneofdef *o); -const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o); -uint32_t upb_oneofdef_index(const upb_oneofdef *o); -bool upb_oneofdef_issynthetic(const upb_oneofdef *o); -int upb_oneofdef_fieldcount(const upb_oneofdef *o); -const upb_fielddef *upb_oneofdef_field(const upb_oneofdef *o, int i); +#define kUpb_MaxFieldNumber ((1 << 29) - 1) + +const google_protobuf_FieldOptions* upb_FieldDef_Options(const upb_FieldDef* f); +bool upb_FieldDef_HasOptions(const upb_FieldDef* f); +const char* upb_FieldDef_FullName(const upb_FieldDef* f); +upb_CType upb_FieldDef_CType(const upb_FieldDef* f); +upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f); +upb_Label upb_FieldDef_Label(const upb_FieldDef* f); +uint32_t upb_FieldDef_Number(const upb_FieldDef* f); +const char* upb_FieldDef_Name(const upb_FieldDef* f); +const char* upb_FieldDef_JsonName(const upb_FieldDef* f); +bool upb_FieldDef_HasJsonName(const upb_FieldDef* f); +bool upb_FieldDef_IsExtension(const upb_FieldDef* f); +bool upb_FieldDef_IsPacked(const upb_FieldDef* f); +const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f); +const upb_MessageDef* upb_FieldDef_ContainingType(const upb_FieldDef* f); +const upb_MessageDef* upb_FieldDef_ExtensionScope(const upb_FieldDef* f); +const upb_OneofDef* upb_FieldDef_ContainingOneof(const upb_FieldDef* f); +const upb_OneofDef* upb_FieldDef_RealContainingOneof(const upb_FieldDef* f); +uint32_t upb_FieldDef_Index(const upb_FieldDef* f); +bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f); +bool upb_FieldDef_IsString(const upb_FieldDef* f); +bool upb_FieldDef_IsRepeated(const upb_FieldDef* f); +bool upb_FieldDef_IsPrimitive(const upb_FieldDef* f); +bool upb_FieldDef_IsMap(const upb_FieldDef* f); +bool upb_FieldDef_HasDefault(const upb_FieldDef* f); +bool upb_FieldDef_HasSubDef(const upb_FieldDef* f); +bool upb_FieldDef_HasPresence(const upb_FieldDef* f); +const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f); +const upb_EnumDef* upb_FieldDef_EnumSubDef(const upb_FieldDef* f); +const upb_MiniTable_Field* upb_FieldDef_MiniTable(const upb_FieldDef* f); +const upb_MiniTable_Extension* _upb_FieldDef_ExtensionMiniTable( + const upb_FieldDef* f); +bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f); + +/* upb_OneofDef ***************************************************************/ + +const google_protobuf_OneofOptions* upb_OneofDef_Options(const upb_OneofDef* o); +bool upb_OneofDef_HasOptions(const upb_OneofDef* o); +const char* upb_OneofDef_Name(const upb_OneofDef* o); +const upb_MessageDef* upb_OneofDef_ContainingType(const upb_OneofDef* o); +uint32_t upb_OneofDef_Index(const upb_OneofDef* o); +bool upb_OneofDef_IsSynthetic(const upb_OneofDef* o); +int upb_OneofDef_FieldCount(const upb_OneofDef* o); +const upb_FieldDef* upb_OneofDef_Field(const upb_OneofDef* o, int i); /* Oneof lookups: * - ntof: look up a field by name. * - ntofz: look up a field by name (as a null-terminated string). * - itof: look up a field by number. */ -const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, - const char *name, size_t length); -UPB_INLINE const upb_fielddef *upb_oneofdef_ntofz(const upb_oneofdef *o, - const char *name) { - return upb_oneofdef_ntof(o, name, strlen(name)); +const upb_FieldDef* upb_OneofDef_LookupNameWithSize(const upb_OneofDef* o, + const char* name, + size_t length); +UPB_INLINE const upb_FieldDef* upb_OneofDef_LookupName(const upb_OneofDef* o, + const char* name) { + return upb_OneofDef_LookupNameWithSize(o, name, strlen(name)); } -const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num); - -/* DEPRECATED, slated for removal. */ -int upb_oneofdef_numfields(const upb_oneofdef *o); -void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o); -void upb_oneof_next(upb_oneof_iter *iter); -bool upb_oneof_done(upb_oneof_iter *iter); -upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter); -void upb_oneof_iter_setdone(upb_oneof_iter *iter); -bool upb_oneof_iter_isequal(const upb_oneof_iter *iter1, - const upb_oneof_iter *iter2); -/* END DEPRECATED */ +const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, + uint32_t num); -/* upb_msgdef *****************************************************************/ - -typedef upb_inttable_iter upb_msg_field_iter; -typedef upb_strtable_iter upb_msg_oneof_iter; +/* upb_MessageDef *************************************************************/ /* Well-known field tag numbers for map-entry messages. */ -#define UPB_MAPENTRY_KEY 1 -#define UPB_MAPENTRY_VALUE 2 +#define kUpb_MapEntry_KeyFieldNumber 1 +#define kUpb_MapEntry_ValueFieldNumber 2 /* Well-known field tag numbers for Any messages. */ -#define UPB_ANY_TYPE 1 -#define UPB_ANY_VALUE 2 +#define kUpb_Any_TypeFieldNumber 1 +#define kUpb_Any_ValueFieldNumber 2 /* Well-known field tag numbers for timestamp messages. */ -#define UPB_DURATION_SECONDS 1 -#define UPB_DURATION_NANOS 2 +#define kUpb_Duration_SecondsFieldNumber 1 +#define kUpb_Duration_NanosFieldNumber 2 /* Well-known field tag numbers for duration messages. */ -#define UPB_TIMESTAMP_SECONDS 1 -#define UPB_TIMESTAMP_NANOS 2 - -const char *upb_msgdef_fullname(const upb_msgdef *m); -const upb_filedef *upb_msgdef_file(const upb_msgdef *m); -const char *upb_msgdef_name(const upb_msgdef *m); -upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m); -bool upb_msgdef_mapentry(const upb_msgdef *m); -upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m); -bool upb_msgdef_iswrapper(const upb_msgdef *m); -bool upb_msgdef_isnumberwrapper(const upb_msgdef *m); -int upb_msgdef_extrangecount(const upb_msgdef *m); -int upb_msgdef_fieldcount(const upb_msgdef *m); -int upb_msgdef_oneofcount(const upb_msgdef *m); -const upb_extrange *upb_msgdef_extrange(const upb_msgdef *m, int i); -const upb_fielddef *upb_msgdef_field(const upb_msgdef *m, int i); -const upb_oneofdef *upb_msgdef_oneof(const upb_msgdef *m, int i); -const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i); -const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, - size_t len); -const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, - size_t len); -const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m); - -UPB_INLINE const upb_oneofdef *upb_msgdef_ntooz(const upb_msgdef *m, - const char *name) { - return upb_msgdef_ntoo(m, name, strlen(name)); +#define kUpb_Timestamp_SecondsFieldNumber 1 +#define kUpb_Timestamp_NanosFieldNumber 2 + +const google_protobuf_MessageOptions* upb_MessageDef_Options( + const upb_MessageDef* m); +bool upb_MessageDef_HasOptions(const upb_MessageDef* m); +const char* upb_MessageDef_FullName(const upb_MessageDef* m); +const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m); +const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m); +const char* upb_MessageDef_Name(const upb_MessageDef* m); +upb_Syntax upb_MessageDef_Syntax(const upb_MessageDef* m); +upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m); +int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m); +int upb_MessageDef_FieldCount(const upb_MessageDef* m); +int upb_MessageDef_OneofCount(const upb_MessageDef* m); +const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m, + int i); +const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, int i); +const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, int i); +const upb_FieldDef* upb_MessageDef_FindFieldByNumber(const upb_MessageDef* m, + uint32_t i); +const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize( + const upb_MessageDef* m, const char* name, size_t len); +const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize( + const upb_MessageDef* m, const char* name, size_t len); +const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m); + +UPB_INLINE const upb_OneofDef* upb_MessageDef_FindOneofByName( + const upb_MessageDef* m, const char* name) { + return upb_MessageDef_FindOneofByNameWithSize(m, name, strlen(name)); +} + +UPB_INLINE const upb_FieldDef* upb_MessageDef_FindFieldByName( + const upb_MessageDef* m, const char* name) { + return upb_MessageDef_FindFieldByNameWithSize(m, name, strlen(name)); } -UPB_INLINE const upb_fielddef *upb_msgdef_ntofz(const upb_msgdef *m, - const char *name) { - return upb_msgdef_ntof(m, name, strlen(name)); +UPB_INLINE bool upb_MessageDef_IsMapEntry(const upb_MessageDef* m) { + return google_protobuf_MessageOptions_map_entry(upb_MessageDef_Options(m)); } +/* Nested entities. */ +int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m); +int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m); +int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m); +const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m, + int i); +const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i); +const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m, + int i); + /* Lookup of either field or oneof by name. Returns whether either was found. * If the return is true, then the found def will be set, and the non-found * one set to NULL. */ -bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, - const upb_fielddef **f, const upb_oneofdef **o); - -UPB_INLINE bool upb_msgdef_lookupnamez(const upb_msgdef *m, const char *name, - const upb_fielddef **f, - const upb_oneofdef **o) { - return upb_msgdef_lookupname(m, name, strlen(name), f, o); +bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m, + const char* name, size_t len, + const upb_FieldDef** f, + const upb_OneofDef** o); + +UPB_INLINE bool upb_MessageDef_FindByName(const upb_MessageDef* m, + const char* name, + const upb_FieldDef** f, + const upb_OneofDef** o) { + return upb_MessageDef_FindByNameWithSize(m, name, strlen(name), f, o); } /* Returns a field by either JSON name or regular proto name. */ -const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, - const char *name, size_t len); - -/* DEPRECATED, slated for removal */ -int upb_msgdef_numfields(const upb_msgdef *m); -int upb_msgdef_numoneofs(const upb_msgdef *m); -int upb_msgdef_numrealoneofs(const upb_msgdef *m); -void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m); -void upb_msg_field_next(upb_msg_field_iter *iter); -bool upb_msg_field_done(const upb_msg_field_iter *iter); -upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter); -void upb_msg_field_iter_setdone(upb_msg_field_iter *iter); -bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1, - const upb_msg_field_iter * iter2); -void upb_msg_oneof_begin(upb_msg_oneof_iter * iter, const upb_msgdef *m); -void upb_msg_oneof_next(upb_msg_oneof_iter * iter); -bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter); -const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter); -void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter * iter); -bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, - const upb_msg_oneof_iter *iter2); -/* END DEPRECATED */ - -/* upb_extrange ***************************************************************/ - -const google_protobuf_ExtensionRangeOptions *upb_extrange_options( - const upb_extrange *r); -bool upb_extrange_hasoptions(const upb_extrange *r); -int32_t upb_extrange_start(const upb_extrange *r); -int32_t upb_extrange_end(const upb_extrange *r); - -/* upb_enumdef ****************************************************************/ - -typedef upb_strtable_iter upb_enum_iter; - -const char *upb_enumdef_fullname(const upb_enumdef *e); -const char *upb_enumdef_name(const upb_enumdef *e); -const upb_filedef *upb_enumdef_file(const upb_enumdef *e); -int32_t upb_enumdef_default(const upb_enumdef *e); -int upb_enumdef_valuecount(const upb_enumdef *e); -const upb_enumvaldef *upb_enumdef_value(const upb_enumdef *e, int i); - -const upb_enumvaldef *upb_enumdef_lookupname(const upb_enumdef *e, - const char *name, size_t len); -const upb_enumvaldef *upb_enumdef_lookupnum(const upb_enumdef *e, int32_t num); - -/* DEPRECATED, slated for removal */ -int upb_enumdef_numvals(const upb_enumdef *e); -void upb_enum_begin(upb_enum_iter *iter, const upb_enumdef *e); -void upb_enum_next(upb_enum_iter *iter); -bool upb_enum_done(upb_enum_iter *iter); -const char *upb_enum_iter_name(upb_enum_iter *iter); -int32_t upb_enum_iter_number(upb_enum_iter *iter); -/* END DEPRECATED */ +const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize( + const upb_MessageDef* m, const char* name, size_t len); +UPB_INLINE const upb_FieldDef* upb_MessageDef_FindByJsonName( + const upb_MessageDef* m, const char* name) { + return upb_MessageDef_FindByJsonNameWithSize(m, name, strlen(name)); +} + +/* upb_ExtensionRange *********************************************************/ + +const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options( + const upb_ExtensionRange* r); +bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r); +int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* r); +int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r); + +/* upb_EnumDef ****************************************************************/ + +const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e); +bool upb_EnumDef_HasOptions(const upb_EnumDef* e); +const char* upb_EnumDef_FullName(const upb_EnumDef* e); +const char* upb_EnumDef_Name(const upb_EnumDef* e); +const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e); +const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e); +int32_t upb_EnumDef_Default(const upb_EnumDef* e); +int upb_EnumDef_ValueCount(const upb_EnumDef* e); +const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i); + +const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( + const upb_EnumDef* e, const char* name, size_t len); +const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e, + int32_t num); +bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num); // Convenience wrapper. -UPB_INLINE const upb_enumvaldef *upb_enumdef_lookupnamez(const upb_enumdef *e, - const char *name) { - return upb_enumdef_lookupname(e, name, strlen(name)); +UPB_INLINE const upb_EnumValueDef* upb_EnumDef_FindValueByName( + const upb_EnumDef* e, const char* name) { + return upb_EnumDef_FindValueByNameWithSize(e, name, strlen(name)); } -/* upb_enumvaldef *************************************************************/ - -const char *upb_enumvaldef_fullname(const upb_enumvaldef *e); -const char *upb_enumvaldef_name(const upb_enumvaldef *e); -int32_t upb_enumvaldef_number(const upb_enumvaldef *e); -const upb_enumdef *upb_enumvaldef_enum(const upb_enumvaldef *e); - -/* upb_filedef ****************************************************************/ - -const char *upb_filedef_name(const upb_filedef *f); -const char *upb_filedef_package(const upb_filedef *f); -const char *upb_filedef_phpprefix(const upb_filedef *f); -const char *upb_filedef_phpnamespace(const upb_filedef *f); -upb_syntax_t upb_filedef_syntax(const upb_filedef *f); -int upb_filedef_depcount(const upb_filedef *f); -int upb_filedef_msgcount(const upb_filedef *f); -int upb_filedef_enumcount(const upb_filedef *f); -const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i); -const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i); -const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i); -const upb_symtab *upb_filedef_symtab(const upb_filedef *f); - -/* upb_symtab *****************************************************************/ - -upb_symtab *upb_symtab_new(void); -void upb_symtab_free(upb_symtab* s); -const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym); -const upb_msgdef *upb_symtab_lookupmsg2( - const upb_symtab *s, const char *sym, size_t len); -const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym); -const upb_enumvaldef *upb_symtab_lookupenumval(const upb_symtab *s, - const char *sym); -const upb_fielddef *upb_symtab_lookupext(const upb_symtab *s, const char *sym); -const upb_fielddef *upb_symtab_lookupext2(const upb_symtab *s, const char *sym, - size_t len); -const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name); -const upb_filedef *upb_symtab_lookupfile2( - const upb_symtab *s, const char *name, size_t len); -int upb_symtab_filecount(const upb_symtab *s); -const upb_filedef *upb_symtab_addfile( - upb_symtab *s, const google_protobuf_FileDescriptorProto *file, - upb_status *status); -size_t _upb_symtab_bytesloaded(const upb_symtab *s); -upb_arena *_upb_symtab_arena(const upb_symtab *s); -const upb_fielddef *_upb_symtab_lookupextfield(const upb_symtab *s, - const upb_msglayout_ext *ext); -const upb_extreg *upb_symtab_extreg(const upb_symtab *s); +/* upb_EnumValueDef ***********************************************************/ + +const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( + const upb_EnumValueDef* e); +bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* e); +const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* e); +const char* upb_EnumValueDef_Name(const upb_EnumValueDef* e); +int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* e); +uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* e); +const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* e); + +/* upb_FileDef ****************************************************************/ + +const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f); +bool upb_FileDef_HasOptions(const upb_FileDef* f); +const char* upb_FileDef_Name(const upb_FileDef* f); +const char* upb_FileDef_Package(const upb_FileDef* f); +upb_Syntax upb_FileDef_Syntax(const upb_FileDef* f); +int upb_FileDef_DependencyCount(const upb_FileDef* f); +int upb_FileDef_PublicDependencyCount(const upb_FileDef* f); +int upb_FileDef_WeakDependencyCount(const upb_FileDef* f); +int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f); +int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f); +int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f); +int upb_FileDef_ServiceCount(const upb_FileDef* f); +const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i); +const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i); +const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i); +const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i); +const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i); +const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i); +const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i); +const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f); +const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f); +const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f); + +/* upb_MethodDef **************************************************************/ + +const google_protobuf_MethodOptions* upb_MethodDef_Options( + const upb_MethodDef* m); +bool upb_MethodDef_HasOptions(const upb_MethodDef* m); +const char* upb_MethodDef_FullName(const upb_MethodDef* m); +const char* upb_MethodDef_Name(const upb_MethodDef* m); +const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m); +const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m); +const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m); +bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m); +bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m); + +/* upb_ServiceDef *************************************************************/ + +const google_protobuf_ServiceOptions* upb_ServiceDef_Options( + const upb_ServiceDef* s); +bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s); +const char* upb_ServiceDef_FullName(const upb_ServiceDef* s); +const char* upb_ServiceDef_Name(const upb_ServiceDef* s); +int upb_ServiceDef_Index(const upb_ServiceDef* s); +const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s); +int upb_ServiceDef_MethodCount(const upb_ServiceDef* s); +const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i); +const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, + const char* name); + +/* upb_DefPool ****************************************************************/ + +upb_DefPool* upb_DefPool_New(void); +void upb_DefPool_Free(upb_DefPool* s); +const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s, + const char* sym); +const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len); +const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s, + const char* sym); +const upb_EnumValueDef* upb_DefPool_FindEnumByNameval(const upb_DefPool* s, + const char* sym); +const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, + const char* sym); +const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len); +const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s, + const char* name); +const upb_ServiceDef* upb_DefPool_FindServiceByName(const upb_DefPool* s, + const char* name); +const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize( + const upb_DefPool* s, const char* name, size_t size); +const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, + const char* name); +const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, + const char* name, + size_t len); +const upb_FileDef* upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file, + upb_Status* status); +size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s); +upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s); +const upb_FieldDef* _upb_DefPool_FindExtensionByMiniTable( + const upb_DefPool* s, const upb_MiniTable_Extension* ext); +const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s, + const upb_MessageDef* m, + int32_t fieldnum); +const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( + const upb_DefPool* s); +const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, + const upb_MessageDef* m, + size_t* count); /* For generated code only: loads a generated descriptor. */ -typedef struct upb_def_init { - struct upb_def_init **deps; /* Dependencies of this file. */ - const upb_msglayout_file *layout; - const char *filename; - upb_strview descriptor; /* Serialized descriptor. */ -} upb_def_init; +typedef struct _upb_DefPool_Init { + struct _upb_DefPool_Init** deps; /* Dependencies of this file. */ + const upb_MiniTable_File* layout; + const char* filename; + upb_StringView descriptor; /* Serialized descriptor. */ +} _upb_DefPool_Init; -bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init); +bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init); #include "upb/port_undef.inc" #ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ +} /* extern "C" */ +#endif /* __cplusplus */ #endif /* UPB_DEF_H_ */ diff --git a/contrib/libs/grpc/third_party/upb/upb/def.hpp b/contrib/libs/grpc/third_party/upb/upb/def.hpp index e18828e9ec..d179721d1f 100644 --- a/contrib/libs/grpc/third_party/upb/upb/def.hpp +++ b/contrib/libs/grpc/third_party/upb/upb/def.hpp @@ -12,11 +12,11 @@ // names of its contributors may be used to endorse or promote products // derived from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -38,57 +38,49 @@ namespace upb { -typedef upb_msgval MessageValue; +typedef upb_MessageValue MessageValue; class EnumDefPtr; +class FileDefPtr; class MessageDefPtr; class OneofDefPtr; // A upb::FieldDefPtr describes a single field in a message. It is most often -// found as a part of a upb_msgdef, but can also stand alone to represent +// found as a part of a upb_MessageDef, but can also stand alone to represent // an extension. class FieldDefPtr { public: FieldDefPtr() : ptr_(nullptr) {} - explicit FieldDefPtr(const upb_fielddef* ptr) : ptr_(ptr) {} + explicit FieldDefPtr(const upb_FieldDef* ptr) : ptr_(ptr) {} - const upb_fielddef* ptr() const { return ptr_; } + const upb_FieldDef* ptr() const { return ptr_; } explicit operator bool() const { return ptr_ != nullptr; } - typedef upb_fieldtype_t Type; - typedef upb_label_t Label; - typedef upb_descriptortype_t DescriptorType; + typedef upb_CType Type; + typedef upb_Label Label; + typedef upb_FieldType DescriptorType; - const char* full_name() const { return upb_fielddef_fullname(ptr_); } + const char* full_name() const { return upb_FieldDef_FullName(ptr_); } - Type type() const { return upb_fielddef_type(ptr_); } - Label label() const { return upb_fielddef_label(ptr_); } - const char* name() const { return upb_fielddef_name(ptr_); } - const char* json_name() const { return upb_fielddef_jsonname(ptr_); } - uint32_t number() const { return upb_fielddef_number(ptr_); } - bool is_extension() const { return upb_fielddef_isextension(ptr_); } - - // For UPB_TYPE_MESSAGE fields only where is_tag_delimited() == false, - // indicates whether this field should have lazy parsing handlers that yield - // the unparsed string for the submessage. - // - // TODO(haberman): I think we want to move this into a FieldOptions container - // when we add support for custom options (the FieldOptions struct will - // contain both regular FieldOptions like "lazy" *and* custom options). - bool lazy() const { return upb_fielddef_lazy(ptr_); } + Type type() const { return upb_FieldDef_CType(ptr_); } + Label label() const { return upb_FieldDef_Label(ptr_); } + const char* name() const { return upb_FieldDef_Name(ptr_); } + const char* json_name() const { return upb_FieldDef_JsonName(ptr_); } + uint32_t number() const { return upb_FieldDef_Number(ptr_); } + bool is_extension() const { return upb_FieldDef_IsExtension(ptr_); } // For non-string, non-submessage fields, this indicates whether binary // protobufs are encoded in packed or non-packed format. // - // TODO(haberman): see note above about putting options like this into a - // FieldOptions container. - bool packed() const { return upb_fielddef_packed(ptr_); } + // Note: this accessor reflects the fact that "packed" has different defaults + // depending on whether the proto is proto2 or proto3. + bool packed() const { return upb_FieldDef_IsPacked(ptr_); } // An integer that can be used as an index into an array of fields for // whatever message this field belongs to. Guaranteed to be less than // f->containing_type()->field_count(). May only be accessed once the def has // been finalized. - uint32_t index() const { return upb_fielddef_index(ptr_); } + uint32_t index() const { return upb_FieldDef_Index(ptr_); } // The MessageDef to which this field belongs. // @@ -109,74 +101,54 @@ class FieldDefPtr { // INT32 and SINT32, whereas our "type" enum does not. This return of // descriptor_type() is a function of type(), integer_format(), and // is_tag_delimited(). - DescriptorType descriptor_type() const { - return upb_fielddef_descriptortype(ptr_); - } + DescriptorType descriptor_type() const { return upb_FieldDef_Type(ptr_); } // Convenient field type tests. - bool IsSubMessage() const { return upb_fielddef_issubmsg(ptr_); } - bool IsString() const { return upb_fielddef_isstring(ptr_); } - bool IsSequence() const { return upb_fielddef_isseq(ptr_); } - bool IsPrimitive() const { return upb_fielddef_isprimitive(ptr_); } - bool IsMap() const { return upb_fielddef_ismap(ptr_); } - - // Returns the non-string default value for this fielddef, which may either - // be something the client set explicitly or the "default default" (0 for - // numbers, empty for strings). The field's type indicates the type of the - // returned value, except for enum fields that are still mutable. - // - // Requires that the given function matches the field's current type. - int64_t default_int64() const { return upb_fielddef_defaultint64(ptr_); } - int32_t default_int32() const { return upb_fielddef_defaultint32(ptr_); } - uint64_t default_uint64() const { return upb_fielddef_defaultuint64(ptr_); } - uint32_t default_uint32() const { return upb_fielddef_defaultuint32(ptr_); } - bool default_bool() const { return upb_fielddef_defaultbool(ptr_); } - float default_float() const { return upb_fielddef_defaultfloat(ptr_); } - double default_double() const { return upb_fielddef_defaultdouble(ptr_); } - - MessageValue default_value() const { return upb_fielddef_default(ptr_); } - - // The resulting string is always NULL-terminated. If non-NULL, the length - // will be stored in *len. - const char* default_string(size_t* len) const { - return upb_fielddef_defaultstr(ptr_, len); - } + bool IsSubMessage() const { return upb_FieldDef_IsSubMessage(ptr_); } + bool IsString() const { return upb_FieldDef_IsString(ptr_); } + bool IsSequence() const { return upb_FieldDef_IsRepeated(ptr_); } + bool IsPrimitive() const { return upb_FieldDef_IsPrimitive(ptr_); } + bool IsMap() const { return upb_FieldDef_IsMap(ptr_); } + + MessageValue default_value() const { return upb_FieldDef_Default(ptr_); } // Returns the enum or submessage def for this field, if any. The field's // type must match (ie. you may only call enum_subdef() for fields where - // type() == UPB_TYPE_ENUM). + // type() == kUpb_CType_Enum). EnumDefPtr enum_subdef() const; MessageDefPtr message_subdef() const; private: - const upb_fielddef* ptr_; + const upb_FieldDef* ptr_; }; // Class that represents a oneof. class OneofDefPtr { public: OneofDefPtr() : ptr_(nullptr) {} - explicit OneofDefPtr(const upb_oneofdef* ptr) : ptr_(ptr) {} + explicit OneofDefPtr(const upb_OneofDef* ptr) : ptr_(ptr) {} - const upb_oneofdef* ptr() const { return ptr_; } + const upb_OneofDef* ptr() const { return ptr_; } explicit operator bool() const { return ptr_ != nullptr; } // Returns the MessageDef that contains this OneofDef. MessageDefPtr containing_type() const; // Returns the name of this oneof. - const char* name() const { return upb_oneofdef_name(ptr_); } + const char* name() const { return upb_OneofDef_Name(ptr_); } // Returns the number of fields in the oneof. - int field_count() const { return upb_oneofdef_numfields(ptr_); } - FieldDefPtr field(int i) const { return FieldDefPtr(upb_oneofdef_field(ptr_, i)); } + int field_count() const { return upb_OneofDef_FieldCount(ptr_); } + FieldDefPtr field(int i) const { + return FieldDefPtr(upb_OneofDef_Field(ptr_, i)); + } // Looks up by name. FieldDefPtr FindFieldByName(const char* name, size_t len) const { - return FieldDefPtr(upb_oneofdef_ntof(ptr_, name, len)); + return FieldDefPtr(upb_OneofDef_LookupNameWithSize(ptr_, name, len)); } FieldDefPtr FindFieldByName(const char* name) const { - return FieldDefPtr(upb_oneofdef_ntofz(ptr_, name)); + return FieldDefPtr(upb_OneofDef_LookupName(ptr_, name)); } template <class T> @@ -186,44 +158,50 @@ class OneofDefPtr { // Looks up by tag number. FieldDefPtr FindFieldByNumber(uint32_t num) const { - return FieldDefPtr(upb_oneofdef_itof(ptr_, num)); + return FieldDefPtr(upb_OneofDef_LookupNumber(ptr_, num)); } private: - const upb_oneofdef* ptr_; + const upb_OneofDef* ptr_; }; // Structure that describes a single .proto message type. class MessageDefPtr { public: MessageDefPtr() : ptr_(nullptr) {} - explicit MessageDefPtr(const upb_msgdef* ptr) : ptr_(ptr) {} + explicit MessageDefPtr(const upb_MessageDef* ptr) : ptr_(ptr) {} - const upb_msgdef* ptr() const { return ptr_; } + const upb_MessageDef* ptr() const { return ptr_; } explicit operator bool() const { return ptr_ != nullptr; } - const char* full_name() const { return upb_msgdef_fullname(ptr_); } - const char* name() const { return upb_msgdef_name(ptr_); } + FileDefPtr file() const; + + const char* full_name() const { return upb_MessageDef_FullName(ptr_); } + const char* name() const { return upb_MessageDef_Name(ptr_); } // The number of fields that belong to the MessageDef. - int field_count() const { return upb_msgdef_numfields(ptr_); } - FieldDefPtr field(int i) const { return FieldDefPtr(upb_msgdef_field(ptr_, i)); } + int field_count() const { return upb_MessageDef_FieldCount(ptr_); } + FieldDefPtr field(int i) const { + return FieldDefPtr(upb_MessageDef_Field(ptr_, i)); + } // The number of oneofs that belong to the MessageDef. - int oneof_count() const { return upb_msgdef_numoneofs(ptr_); } - OneofDefPtr oneof(int i) const { return OneofDefPtr(upb_msgdef_oneof(ptr_, i)); } + int oneof_count() const { return upb_MessageDef_OneofCount(ptr_); } + OneofDefPtr oneof(int i) const { + return OneofDefPtr(upb_MessageDef_Oneof(ptr_, i)); + } - upb_syntax_t syntax() const { return upb_msgdef_syntax(ptr_); } + upb_Syntax syntax() const { return upb_MessageDef_Syntax(ptr_); } // These return null pointers if the field is not found. FieldDefPtr FindFieldByNumber(uint32_t number) const { - return FieldDefPtr(upb_msgdef_itof(ptr_, number)); + return FieldDefPtr(upb_MessageDef_FindFieldByNumber(ptr_, number)); } FieldDefPtr FindFieldByName(const char* name, size_t len) const { - return FieldDefPtr(upb_msgdef_ntof(ptr_, name, len)); + return FieldDefPtr(upb_MessageDef_FindFieldByNameWithSize(ptr_, name, len)); } FieldDefPtr FindFieldByName(const char* name) const { - return FieldDefPtr(upb_msgdef_ntofz(ptr_, name)); + return FieldDefPtr(upb_MessageDef_FindFieldByName(ptr_, name)); } template <class T> @@ -232,11 +210,11 @@ class MessageDefPtr { } OneofDefPtr FindOneofByName(const char* name, size_t len) const { - return OneofDefPtr(upb_msgdef_ntoo(ptr_, name, len)); + return OneofDefPtr(upb_MessageDef_FindOneofByNameWithSize(ptr_, name, len)); } OneofDefPtr FindOneofByName(const char* name) const { - return OneofDefPtr(upb_msgdef_ntooz(ptr_, name)); + return OneofDefPtr(upb_MessageDef_FindOneofByName(ptr_, name)); } template <class T> @@ -245,64 +223,65 @@ class MessageDefPtr { } // Is this message a map entry? - bool mapentry() const { return upb_msgdef_mapentry(ptr_); } + bool mapentry() const { return upb_MessageDef_IsMapEntry(ptr_); } - // Return the type of well known type message. UPB_WELLKNOWN_UNSPECIFIED for + // Return the type of well known type message. kUpb_WellKnown_Unspecified for // non-well-known message. - upb_wellknowntype_t wellknowntype() const { - return upb_msgdef_wellknowntype(ptr_); + upb_WellKnown wellknowntype() const { + return upb_MessageDef_WellKnownType(ptr_); } - // Whether is a number wrapper. - bool isnumberwrapper() const { return upb_msgdef_isnumberwrapper(ptr_); } - private: class FieldIter { public: - explicit FieldIter(const upb_msgdef *m, int i) : m_(m), i_(i) {} + explicit FieldIter(const upb_MessageDef* m, int i) : m_(m), i_(i) {} void operator++() { i_++; } - FieldDefPtr operator*() { return FieldDefPtr(upb_msgdef_field(m_, i_)); } + FieldDefPtr operator*() { + return FieldDefPtr(upb_MessageDef_Field(m_, i_)); + } bool operator!=(const FieldIter& other) { return i_ != other.i_; } bool operator==(const FieldIter& other) { return i_ == other.i_; } private: - const upb_msgdef *m_; + const upb_MessageDef* m_; int i_; }; class FieldAccessor { public: - explicit FieldAccessor(const upb_msgdef* md) : md_(md) {} + explicit FieldAccessor(const upb_MessageDef* md) : md_(md) {} FieldIter begin() { return FieldIter(md_, 0); } - FieldIter end() { return FieldIter(md_, upb_msgdef_fieldcount(md_)); } + FieldIter end() { return FieldIter(md_, upb_MessageDef_FieldCount(md_)); } private: - const upb_msgdef* md_; + const upb_MessageDef* md_; }; class OneofIter { public: - explicit OneofIter(const upb_msgdef *m, int i) : m_(m), i_(i) {} + explicit OneofIter(const upb_MessageDef* m, int i) : m_(m), i_(i) {} void operator++() { i_++; } - OneofDefPtr operator*() { return OneofDefPtr(upb_msgdef_oneof(m_, i_)); } + OneofDefPtr operator*() { + return OneofDefPtr(upb_MessageDef_Oneof(m_, i_)); + } bool operator!=(const OneofIter& other) { return i_ != other.i_; } bool operator==(const OneofIter& other) { return i_ == other.i_; } private: - const upb_msgdef *m_; + const upb_MessageDef* m_; int i_; }; class OneofAccessor { public: - explicit OneofAccessor(const upb_msgdef* md) : md_(md) {} + explicit OneofAccessor(const upb_MessageDef* md) : md_(md) {} OneofIter begin() { return OneofIter(md_, 0); } - OneofIter end() { return OneofIter(md_, upb_msgdef_oneofcount(md_)); } + OneofIter end() { return OneofIter(md_, upb_MessageDef_OneofCount(md_)); } private: - const upb_msgdef* md_; + const upb_MessageDef* md_; }; public: @@ -310,75 +289,58 @@ class MessageDefPtr { OneofAccessor oneofs() const { return OneofAccessor(ptr()); } private: - const upb_msgdef* ptr_; + const upb_MessageDef* ptr_; }; class EnumValDefPtr { public: EnumValDefPtr() : ptr_(nullptr) {} - explicit EnumValDefPtr(const upb_enumvaldef* ptr) : ptr_(ptr) {} + explicit EnumValDefPtr(const upb_EnumValueDef* ptr) : ptr_(ptr) {} - int32_t number() const { return upb_enumvaldef_number(ptr_); } - const char *full_name() const { return upb_enumvaldef_fullname(ptr_); } - const char *name() const { return upb_enumvaldef_name(ptr_); } + int32_t number() const { return upb_EnumValueDef_Number(ptr_); } + const char* full_name() const { return upb_EnumValueDef_FullName(ptr_); } + const char* name() const { return upb_EnumValueDef_Name(ptr_); } private: - const upb_enumvaldef* ptr_; + const upb_EnumValueDef* ptr_; }; class EnumDefPtr { public: EnumDefPtr() : ptr_(nullptr) {} - explicit EnumDefPtr(const upb_enumdef* ptr) : ptr_(ptr) {} + explicit EnumDefPtr(const upb_EnumDef* ptr) : ptr_(ptr) {} - const upb_enumdef* ptr() const { return ptr_; } + const upb_EnumDef* ptr() const { return ptr_; } explicit operator bool() const { return ptr_ != nullptr; } - const char* full_name() const { return upb_enumdef_fullname(ptr_); } - const char* name() const { return upb_enumdef_name(ptr_); } + const char* full_name() const { return upb_EnumDef_FullName(ptr_); } + const char* name() const { return upb_EnumDef_Name(ptr_); } // The value that is used as the default when no field default is specified. // If not set explicitly, the first value that was added will be used. // The default value must be a member of the enum. // Requires that value_count() > 0. - int32_t default_value() const { return upb_enumdef_default(ptr_); } + int32_t default_value() const { return upb_EnumDef_Default(ptr_); } // Returns the number of values currently defined in the enum. Note that // multiple names can refer to the same number, so this may be greater than // the total number of unique numbers. - int value_count() const { return upb_enumdef_numvals(ptr_); } + int value_count() const { return upb_EnumDef_ValueCount(ptr_); } // Lookups from name to integer, returning true if found. EnumValDefPtr FindValueByName(const char* name) const { - return EnumValDefPtr(upb_enumdef_lookupnamez(ptr_, name)); + return EnumValDefPtr(upb_EnumDef_FindValueByName(ptr_, name)); } // Finds the name corresponding to the given number, or NULL if none was // found. If more than one name corresponds to this number, returns the // first one that was added. EnumValDefPtr FindValueByNumber(int32_t num) const { - return EnumValDefPtr(upb_enumdef_lookupnum(ptr_, num)); + return EnumValDefPtr(upb_EnumDef_FindValueByNumber(ptr_, num)); } - // Iteration over name/value pairs. The order is undefined. - // Adding an enum val invalidates any iterators. - // - // TODO: make compatible with range-for, with elements as pairs? - class Iterator { - public: - explicit Iterator(EnumDefPtr e) { upb_enum_begin(&iter_, e.ptr()); } - - int32_t number() { return upb_enum_iter_number(&iter_); } - const char* name() { return upb_enum_iter_name(&iter_); } - bool Done() { return upb_enum_done(&iter_); } - void Next() { return upb_enum_next(&iter_); } - - private: - upb_enum_iter iter_; - }; - private: - const upb_enumdef* ptr_; + const upb_EnumDef* ptr_; }; // Class that represents a .proto file with some things defined in it. @@ -387,61 +349,52 @@ class EnumDefPtr { // read the values of file-level options. class FileDefPtr { public: - explicit FileDefPtr(const upb_filedef* ptr) : ptr_(ptr) {} + explicit FileDefPtr(const upb_FileDef* ptr) : ptr_(ptr) {} - const upb_filedef* ptr() const { return ptr_; } + const upb_FileDef* ptr() const { return ptr_; } explicit operator bool() const { return ptr_ != nullptr; } // Get/set name of the file (eg. "foo/bar.proto"). - const char* name() const { return upb_filedef_name(ptr_); } + const char* name() const { return upb_FileDef_Name(ptr_); } // Package name for definitions inside the file (eg. "foo.bar"). - const char* package() const { return upb_filedef_package(ptr_); } - - // Sets the php class prefix which is prepended to all php generated classes - // from this .proto. Default is empty. - const char* phpprefix() const { return upb_filedef_phpprefix(ptr_); } - - // Use this option to change the namespace of php generated classes. Default - // is empty. When this option is empty, the package name will be used for - // determining the namespace. - const char* phpnamespace() const { return upb_filedef_phpnamespace(ptr_); } + const char* package() const { return upb_FileDef_Package(ptr_); } // Syntax for the file. Defaults to proto2. - upb_syntax_t syntax() const { return upb_filedef_syntax(ptr_); } + upb_Syntax syntax() const { return upb_FileDef_Syntax(ptr_); } // Get the list of dependencies from the file. These are returned in the // order that they were added to the FileDefPtr. - int dependency_count() const { return upb_filedef_depcount(ptr_); } + int dependency_count() const { return upb_FileDef_DependencyCount(ptr_); } const FileDefPtr dependency(int index) const { - return FileDefPtr(upb_filedef_dep(ptr_, index)); + return FileDefPtr(upb_FileDef_Dependency(ptr_, index)); } private: - const upb_filedef* ptr_; + const upb_FileDef* ptr_; }; // Non-const methods in upb::SymbolTable are NOT thread-safe. class SymbolTable { public: - SymbolTable() : ptr_(upb_symtab_new(), upb_symtab_free) {} - explicit SymbolTable(upb_symtab* s) : ptr_(s, upb_symtab_free) {} + SymbolTable() : ptr_(upb_DefPool_New(), upb_DefPool_Free) {} + explicit SymbolTable(upb_DefPool* s) : ptr_(s, upb_DefPool_Free) {} - const upb_symtab* ptr() const { return ptr_.get(); } - upb_symtab* ptr() { return ptr_.get(); } + const upb_DefPool* ptr() const { return ptr_.get(); } + upb_DefPool* ptr() { return ptr_.get(); } // Finds an entry in the symbol table with this exact name. If not found, // returns NULL. - MessageDefPtr LookupMessage(const char* sym) const { - return MessageDefPtr(upb_symtab_lookupmsg(ptr_.get(), sym)); + MessageDefPtr FindMessageByName(const char* sym) const { + return MessageDefPtr(upb_DefPool_FindMessageByName(ptr_.get(), sym)); } - EnumDefPtr LookupEnum(const char* sym) const { - return EnumDefPtr(upb_symtab_lookupenum(ptr_.get(), sym)); + EnumDefPtr FindEnumByName(const char* sym) const { + return EnumDefPtr(upb_DefPool_FindEnumByName(ptr_.get(), sym)); } - FileDefPtr LookupFile(const char* name) const { - return FileDefPtr(upb_symtab_lookupfile(ptr_.get(), name)); + FileDefPtr FindFileByName(const char* name) const { + return FileDefPtr(upb_DefPool_FindFileByName(ptr_.get(), name)); } // TODO: iteration? @@ -450,31 +403,35 @@ class SymbolTable { FileDefPtr AddFile(const google_protobuf_FileDescriptorProto* file_proto, Status* status) { return FileDefPtr( - upb_symtab_addfile(ptr_.get(), file_proto, status->ptr())); + upb_DefPool_AddFile(ptr_.get(), file_proto, status->ptr())); } private: - std::unique_ptr<upb_symtab, decltype(&upb_symtab_free)> ptr_; + std::unique_ptr<upb_DefPool, decltype(&upb_DefPool_Free)> ptr_; }; +inline FileDefPtr MessageDefPtr::file() const { + return FileDefPtr(upb_MessageDef_File(ptr_)); +} + inline MessageDefPtr FieldDefPtr::message_subdef() const { - return MessageDefPtr(upb_fielddef_msgsubdef(ptr_)); + return MessageDefPtr(upb_FieldDef_MessageSubDef(ptr_)); } inline MessageDefPtr FieldDefPtr::containing_type() const { - return MessageDefPtr(upb_fielddef_containingtype(ptr_)); + return MessageDefPtr(upb_FieldDef_ContainingType(ptr_)); } inline MessageDefPtr OneofDefPtr::containing_type() const { - return MessageDefPtr(upb_oneofdef_containingtype(ptr_)); + return MessageDefPtr(upb_OneofDef_ContainingType(ptr_)); } inline OneofDefPtr FieldDefPtr::containing_oneof() const { - return OneofDefPtr(upb_fielddef_containingoneof(ptr_)); + return OneofDefPtr(upb_FieldDef_ContainingOneof(ptr_)); } inline EnumDefPtr FieldDefPtr::enum_subdef() const { - return EnumDefPtr(upb_fielddef_enumsubdef(ptr_)); + return EnumDefPtr(upb_FieldDef_EnumSubDef(ptr_)); } } // namespace upb diff --git a/contrib/libs/grpc/third_party/upb/upb/encode.c b/contrib/libs/grpc/third_party/upb/upb/encode.c index 71a4ba07fa..c339c9d81e 100644 --- a/contrib/libs/grpc/third_party/upb/upb/encode.c +++ b/contrib/libs/grpc/third_party/upb/upb/encode.c @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -41,7 +41,7 @@ #define UPB_PB_VARINT_MAX_LEN 10 UPB_NOINLINE -static size_t encode_varint64(uint64_t val, char *buf) { +static size_t encode_varint64(uint64_t val, char* buf) { size_t i = 0; do { uint8_t byte = val & 0x7fU; @@ -52,12 +52,16 @@ static size_t encode_varint64(uint64_t val, char *buf) { return i; } -static uint32_t encode_zz32(int32_t n) { return ((uint32_t)n << 1) ^ (n >> 31); } -static uint64_t encode_zz64(int64_t n) { return ((uint64_t)n << 1) ^ (n >> 63); } +static uint32_t encode_zz32(int32_t n) { + return ((uint32_t)n << 1) ^ (n >> 31); +} +static uint64_t encode_zz64(int64_t n) { + return ((uint64_t)n << 1) ^ (n >> 63); +} typedef struct { jmp_buf err; - upb_alloc *alloc; + upb_alloc* alloc; char *buf, *ptr, *limit; int options; int depth; @@ -72,15 +76,13 @@ static size_t upb_roundup_pow2(size_t bytes) { return ret; } -UPB_NORETURN static void encode_err(upb_encstate *e) { - UPB_LONGJMP(e->err, 1); -} +UPB_NORETURN static void encode_err(upb_encstate* e) { UPB_LONGJMP(e->err, 1); } UPB_NOINLINE -static void encode_growbuffer(upb_encstate *e, size_t bytes) { +static void encode_growbuffer(upb_encstate* e, size_t bytes) { size_t old_size = e->limit - e->buf; size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr)); - char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size); + char* new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size); if (!new_buf) encode_err(e); @@ -99,7 +101,7 @@ static void encode_growbuffer(upb_encstate *e, size_t bytes) { /* Call to ensure that at least "bytes" bytes are available for writing at * e->ptr. Returns false if the bytes could not be allocated. */ UPB_FORCEINLINE -static void encode_reserve(upb_encstate *e, size_t bytes) { +static void encode_reserve(upb_encstate* e, size_t bytes) { if ((size_t)(e->ptr - e->buf) < bytes) { encode_growbuffer(e, bytes); return; @@ -109,26 +111,26 @@ static void encode_reserve(upb_encstate *e, size_t bytes) { } /* Writes the given bytes to the buffer, handling reserve/advance. */ -static void encode_bytes(upb_encstate *e, const void *data, size_t len) { - if (len == 0) return; /* memcpy() with zero size is UB */ +static void encode_bytes(upb_encstate* e, const void* data, size_t len) { + if (len == 0) return; /* memcpy() with zero size is UB */ encode_reserve(e, len); memcpy(e->ptr, data, len); } -static void encode_fixed64(upb_encstate *e, uint64_t val) { - val = _upb_be_swap64(val); +static void encode_fixed64(upb_encstate* e, uint64_t val) { + val = _upb_BigEndian_Swap64(val); encode_bytes(e, &val, sizeof(uint64_t)); } -static void encode_fixed32(upb_encstate *e, uint32_t val) { - val = _upb_be_swap32(val); +static void encode_fixed32(upb_encstate* e, uint32_t val) { + val = _upb_BigEndian_Swap32(val); encode_bytes(e, &val, sizeof(uint32_t)); } UPB_NOINLINE -static void encode_longvarint(upb_encstate *e, uint64_t val) { +static void encode_longvarint(upb_encstate* e, uint64_t val) { size_t len; - char *start; + char* start; encode_reserve(e, UPB_PB_VARINT_MAX_LEN); len = encode_varint64(val, e->ptr); @@ -138,7 +140,7 @@ static void encode_longvarint(upb_encstate *e, uint64_t val) { } UPB_FORCEINLINE -static void encode_varint(upb_encstate *e, uint64_t val) { +static void encode_varint(upb_encstate* e, uint64_t val) { if (val < 128 && e->ptr != e->buf) { --e->ptr; *e->ptr = val; @@ -147,34 +149,47 @@ static void encode_varint(upb_encstate *e, uint64_t val) { } } -static void encode_double(upb_encstate *e, double d) { +static void encode_double(upb_encstate* e, double d) { uint64_t u64; UPB_ASSERT(sizeof(double) == sizeof(uint64_t)); memcpy(&u64, &d, sizeof(uint64_t)); encode_fixed64(e, u64); } -static void encode_float(upb_encstate *e, float d) { +static void encode_float(upb_encstate* e, float d) { uint32_t u32; UPB_ASSERT(sizeof(float) == sizeof(uint32_t)); memcpy(&u32, &d, sizeof(uint32_t)); encode_fixed32(e, u32); } -static void encode_tag(upb_encstate *e, uint32_t field_number, +static void encode_tag(upb_encstate* e, uint32_t field_number, uint8_t wire_type) { encode_varint(e, (field_number << 3) | wire_type); } -static void encode_fixedarray(upb_encstate *e, const upb_array *arr, - size_t elem_size, uint32_t tag) { +static void encode_fixedarray(upb_encstate* e, const upb_Array* arr, + size_t elem_size, uint32_t tag) { size_t bytes = arr->len * elem_size; const char* data = _upb_array_constptr(arr); const char* ptr = data + bytes - elem_size; - if (tag) { + + if (tag || !_upb_IsLittleEndian()) { while (true) { - encode_bytes(e, ptr, elem_size); - encode_varint(e, tag); + if (elem_size == 4) { + uint32_t val; + memcpy(&val, ptr, sizeof(val)); + val = _upb_BigEndian_Swap32(val); + encode_bytes(e, &val, elem_size); + } else { + UPB_ASSERT(elem_size == 8); + uint64_t val; + memcpy(&val, ptr, sizeof(val)); + val = _upb_BigEndian_Swap64(val); + encode_bytes(e, &val, elem_size); + } + + if (tag) encode_varint(e, tag); if (ptr == data) break; ptr -= elem_size; } @@ -183,81 +198,81 @@ static void encode_fixedarray(upb_encstate *e, const upb_array *arr, } } -static void encode_message(upb_encstate *e, const upb_msg *msg, - const upb_msglayout *m, size_t *size); +static void encode_message(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable* m, size_t* size); -static void encode_scalar(upb_encstate *e, const void *_field_mem, - const upb_msglayout_sub *subs, - const upb_msglayout_field *f) { - const char *field_mem = _field_mem; +static void encode_scalar(upb_encstate* e, const void* _field_mem, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* f) { + const char* field_mem = _field_mem; int wire_type; #define CASE(ctype, type, wtype, encodeval) \ { \ - ctype val = *(ctype *)field_mem; \ + ctype val = *(ctype*)field_mem; \ encode_##type(e, encodeval); \ wire_type = wtype; \ break; \ } switch (f->descriptortype) { - case UPB_DESCRIPTOR_TYPE_DOUBLE: - CASE(double, double, UPB_WIRE_TYPE_64BIT, val); - case UPB_DESCRIPTOR_TYPE_FLOAT: - CASE(float, float, UPB_WIRE_TYPE_32BIT, val); - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_UINT64: - CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val); - case UPB_DESCRIPTOR_TYPE_UINT32: - CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val); - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_ENUM: - CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val); - case UPB_DESCRIPTOR_TYPE_SFIXED64: - case UPB_DESCRIPTOR_TYPE_FIXED64: - CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val); - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val); - case UPB_DESCRIPTOR_TYPE_BOOL: - CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val); - case UPB_DESCRIPTOR_TYPE_SINT32: - CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, encode_zz32(val)); - case UPB_DESCRIPTOR_TYPE_SINT64: - CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, encode_zz64(val)); - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview view = *(upb_strview*)field_mem; + case kUpb_FieldType_Double: + CASE(double, double, kUpb_WireType_64Bit, val); + case kUpb_FieldType_Float: + CASE(float, float, kUpb_WireType_32Bit, val); + case kUpb_FieldType_Int64: + case kUpb_FieldType_UInt64: + CASE(uint64_t, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_UInt32: + CASE(uint32_t, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_Int32: + case kUpb_FieldType_Enum: + CASE(int32_t, varint, kUpb_WireType_Varint, (int64_t)val); + case kUpb_FieldType_SFixed64: + case kUpb_FieldType_Fixed64: + CASE(uint64_t, fixed64, kUpb_WireType_64Bit, val); + case kUpb_FieldType_Fixed32: + case kUpb_FieldType_SFixed32: + CASE(uint32_t, fixed32, kUpb_WireType_32Bit, val); + case kUpb_FieldType_Bool: + CASE(bool, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_SInt32: + CASE(int32_t, varint, kUpb_WireType_Varint, encode_zz32(val)); + case kUpb_FieldType_SInt64: + CASE(int64_t, varint, kUpb_WireType_Varint, encode_zz64(val)); + case kUpb_FieldType_String: + case kUpb_FieldType_Bytes: { + upb_StringView view = *(upb_StringView*)field_mem; encode_bytes(e, view.data, view.size); encode_varint(e, view.size); - wire_type = UPB_WIRE_TYPE_DELIMITED; + wire_type = kUpb_WireType_Delimited; break; } - case UPB_DESCRIPTOR_TYPE_GROUP: { + case kUpb_FieldType_Group: { size_t size; - void *submsg = *(void **)field_mem; - const upb_msglayout *subm = subs[f->submsg_index].submsg; + void* submsg = *(void**)field_mem; + const upb_MiniTable* subm = subs[f->submsg_index].submsg; if (submsg == NULL) { return; } if (--e->depth == 0) encode_err(e); - encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP); + encode_tag(e, f->number, kUpb_WireType_EndGroup); encode_message(e, submsg, subm, &size); - wire_type = UPB_WIRE_TYPE_START_GROUP; + wire_type = kUpb_WireType_StartGroup; e->depth++; break; } - case UPB_DESCRIPTOR_TYPE_MESSAGE: { + case kUpb_FieldType_Message: { size_t size; - void *submsg = *(void **)field_mem; - const upb_msglayout *subm = subs[f->submsg_index].submsg; + void* submsg = *(void**)field_mem; + const upb_MiniTable* subm = subs[f->submsg_index].submsg; if (submsg == NULL) { return; } if (--e->depth == 0) encode_err(e); encode_message(e, submsg, subm, &size); encode_varint(e, size); - wire_type = UPB_WIRE_TYPE_DELIMITED; + wire_type = kUpb_WireType_Delimited; e->depth++; break; } @@ -269,11 +284,11 @@ static void encode_scalar(upb_encstate *e, const void *_field_mem, encode_tag(e, f->number, wire_type); } -static void encode_array(upb_encstate *e, const upb_msg *msg, - const upb_msglayout_sub *subs, - const upb_msglayout_field *f) { - const upb_array *arr = *UPB_PTR_AT(msg, f->offset, upb_array*); - bool packed = f->mode & _UPB_MODE_IS_PACKED; +static void encode_array(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* f) { + const upb_Array* arr = *UPB_PTR_AT(msg, f->offset, upb_Array*); + bool packed = f->mode & upb_LabelFlags_IsPacked; size_t pre_len = e->limit - e->ptr; if (arr == NULL || arr->len == 0) { @@ -282,9 +297,9 @@ static void encode_array(upb_encstate *e, const upb_msg *msg, #define VARINT_CASE(ctype, encode) \ { \ - const ctype *start = _upb_array_constptr(arr); \ - const ctype *ptr = start + arr->len; \ - uint32_t tag = packed ? 0 : (f->number << 3) | UPB_WIRE_TYPE_VARINT; \ + const ctype* start = _upb_array_constptr(arr); \ + const ctype* ptr = start + arr->len; \ + uint32_t tag = packed ? 0 : (f->number << 3) | kUpb_WireType_Varint; \ do { \ ptr--; \ encode_varint(e, encode); \ @@ -296,72 +311,72 @@ static void encode_array(upb_encstate *e, const upb_msg *msg, #define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type)) switch (f->descriptortype) { - case UPB_DESCRIPTOR_TYPE_DOUBLE: - encode_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT)); + case kUpb_FieldType_Double: + encode_fixedarray(e, arr, sizeof(double), TAG(kUpb_WireType_64Bit)); break; - case UPB_DESCRIPTOR_TYPE_FLOAT: - encode_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT)); + case kUpb_FieldType_Float: + encode_fixedarray(e, arr, sizeof(float), TAG(kUpb_WireType_32Bit)); break; - case UPB_DESCRIPTOR_TYPE_SFIXED64: - case UPB_DESCRIPTOR_TYPE_FIXED64: - encode_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT)); + case kUpb_FieldType_SFixed64: + case kUpb_FieldType_Fixed64: + encode_fixedarray(e, arr, sizeof(uint64_t), TAG(kUpb_WireType_64Bit)); break; - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - encode_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT)); + case kUpb_FieldType_Fixed32: + case kUpb_FieldType_SFixed32: + encode_fixedarray(e, arr, sizeof(uint32_t), TAG(kUpb_WireType_32Bit)); break; - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_UINT64: + case kUpb_FieldType_Int64: + case kUpb_FieldType_UInt64: VARINT_CASE(uint64_t, *ptr); - case UPB_DESCRIPTOR_TYPE_UINT32: + case kUpb_FieldType_UInt32: VARINT_CASE(uint32_t, *ptr); - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_ENUM: + case kUpb_FieldType_Int32: + case kUpb_FieldType_Enum: VARINT_CASE(int32_t, (int64_t)*ptr); - case UPB_DESCRIPTOR_TYPE_BOOL: + case kUpb_FieldType_Bool: VARINT_CASE(bool, *ptr); - case UPB_DESCRIPTOR_TYPE_SINT32: + case kUpb_FieldType_SInt32: VARINT_CASE(int32_t, encode_zz32(*ptr)); - case UPB_DESCRIPTOR_TYPE_SINT64: + case kUpb_FieldType_SInt64: VARINT_CASE(int64_t, encode_zz64(*ptr)); - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: { - const upb_strview *start = _upb_array_constptr(arr); - const upb_strview *ptr = start + arr->len; + case kUpb_FieldType_String: + case kUpb_FieldType_Bytes: { + const upb_StringView* start = _upb_array_constptr(arr); + const upb_StringView* ptr = start + arr->len; do { ptr--; encode_bytes(e, ptr->data, ptr->size); encode_varint(e, ptr->size); - encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + encode_tag(e, f->number, kUpb_WireType_Delimited); } while (ptr != start); return; } - case UPB_DESCRIPTOR_TYPE_GROUP: { - const void *const*start = _upb_array_constptr(arr); - const void *const*ptr = start + arr->len; - const upb_msglayout *subm = subs[f->submsg_index].submsg; + case kUpb_FieldType_Group: { + const void* const* start = _upb_array_constptr(arr); + const void* const* ptr = start + arr->len; + const upb_MiniTable* subm = subs[f->submsg_index].submsg; if (--e->depth == 0) encode_err(e); do { size_t size; ptr--; - encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP); + encode_tag(e, f->number, kUpb_WireType_EndGroup); encode_message(e, *ptr, subm, &size); - encode_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP); + encode_tag(e, f->number, kUpb_WireType_StartGroup); } while (ptr != start); e->depth++; return; } - case UPB_DESCRIPTOR_TYPE_MESSAGE: { - const void *const*start = _upb_array_constptr(arr); - const void *const*ptr = start + arr->len; - const upb_msglayout *subm = subs[f->submsg_index].submsg; + case kUpb_FieldType_Message: { + const void* const* start = _upb_array_constptr(arr); + const void* const* ptr = start + arr->len; + const upb_MiniTable* subm = subs[f->submsg_index].submsg; if (--e->depth == 0) encode_err(e); do { size_t size; ptr--; encode_message(e, *ptr, subm, &size); encode_varint(e, size); - encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + encode_tag(e, f->number, kUpb_WireType_Delimited); } while (ptr != start); e->depth++; return; @@ -371,38 +386,38 @@ static void encode_array(upb_encstate *e, const upb_msg *msg, if (packed) { encode_varint(e, e->limit - e->ptr - pre_len); - encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + encode_tag(e, f->number, kUpb_WireType_Delimited); } } -static void encode_mapentry(upb_encstate *e, uint32_t number, - const upb_msglayout *layout, - const upb_map_entry *ent) { - const upb_msglayout_field *key_field = &layout->fields[0]; - const upb_msglayout_field *val_field = &layout->fields[1]; +static void encode_mapentry(upb_encstate* e, uint32_t number, + const upb_MiniTable* layout, + const upb_MapEntry* ent) { + const upb_MiniTable_Field* key_field = &layout->fields[0]; + const upb_MiniTable_Field* val_field = &layout->fields[1]; size_t pre_len = e->limit - e->ptr; size_t size; encode_scalar(e, &ent->v, layout->subs, val_field); encode_scalar(e, &ent->k, layout->subs, key_field); size = (e->limit - e->ptr) - pre_len; encode_varint(e, size); - encode_tag(e, number, UPB_WIRE_TYPE_DELIMITED); + encode_tag(e, number, kUpb_WireType_Delimited); } -static void encode_map(upb_encstate *e, const upb_msg *msg, - const upb_msglayout_sub *subs, - const upb_msglayout_field *f) { - const upb_map *map = *UPB_PTR_AT(msg, f->offset, const upb_map*); - const upb_msglayout *layout = subs[f->submsg_index].submsg; +static void encode_map(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* f) { + const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*); + const upb_MiniTable* layout = subs[f->submsg_index].submsg; UPB_ASSERT(layout->field_count == 2); if (map == NULL) return; - if (e->options & UPB_ENCODE_DETERMINISTIC) { + if (e->options & kUpb_Encode_Deterministic) { _upb_sortedmap sorted; _upb_mapsorter_pushmap(&e->sorter, layout->fields[0].descriptortype, map, &sorted); - upb_map_entry ent; + upb_MapEntry ent; while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) { encode_mapentry(e, f->number, layout, &ent); } @@ -410,10 +425,10 @@ static void encode_map(upb_encstate *e, const upb_msg *msg, } else { upb_strtable_iter i; upb_strtable_begin(&i, &map->table); - for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { - upb_strview key = upb_strtable_iter_key(&i); + for (; !upb_strtable_done(&i); upb_strtable_next(&i)) { + upb_StringView key = upb_strtable_iter_key(&i); const upb_value val = upb_strtable_iter_value(&i); - upb_map_entry ent; + upb_MapEntry ent; _upb_map_fromkey(key, &ent.k, map->key_size); _upb_map_fromvalue(val, &ent.v, map->val_size); encode_mapentry(e, f->number, layout, &ent); @@ -421,30 +436,30 @@ static void encode_map(upb_encstate *e, const upb_msg *msg, } } -static bool encode_shouldencode(upb_encstate *e, const upb_msg *msg, - const upb_msglayout_sub *subs, - const upb_msglayout_field *f) { +static bool encode_shouldencode(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* f) { if (f->presence == 0) { /* Proto3 presence or map/array. */ - const void *mem = UPB_PTR_AT(msg, f->offset, void); - switch (f->mode >> _UPB_REP_SHIFT) { - case _UPB_REP_1BYTE: { + const void* mem = UPB_PTR_AT(msg, f->offset, void); + switch (f->mode >> upb_FieldRep_Shift) { + case upb_FieldRep_1Byte: { char ch; memcpy(&ch, mem, 1); return ch != 0; } - case _UPB_REP_4BYTE: { + case upb_FieldRep_4Byte: { uint32_t u32; memcpy(&u32, mem, 4); return u32 != 0; } - case _UPB_REP_8BYTE: { + case upb_FieldRep_8Byte: { uint64_t u64; memcpy(&u64, mem, 8); return u64 != 0; } - case _UPB_REP_STRVIEW: { - const upb_strview *str = (const upb_strview*)mem; + case upb_FieldRep_StringView: { + const upb_StringView* str = (const upb_StringView*)mem; return str->size != 0; } default: @@ -459,17 +474,17 @@ static bool encode_shouldencode(upb_encstate *e, const upb_msg *msg, } } -static void encode_field(upb_encstate *e, const upb_msg *msg, - const upb_msglayout_sub *subs, - const upb_msglayout_field *field) { - switch (_upb_getmode(field)) { - case _UPB_MODE_ARRAY: +static void encode_field(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable_Sub* subs, + const upb_MiniTable_Field* field) { + switch (upb_FieldMode_Get(field)) { + case kUpb_FieldMode_Array: encode_array(e, msg, subs, field); break; - case _UPB_MODE_MAP: + case kUpb_FieldMode_Map: encode_map(e, msg, subs, field); break; - case _UPB_MODE_SCALAR: + case kUpb_FieldMode_Scalar: encode_scalar(e, UPB_PTR_AT(msg, field->offset, void), subs, field); break; default: @@ -483,40 +498,50 @@ static void encode_field(upb_encstate *e, const upb_msg *msg, * required string message = 3; * } * } */ -static void encode_msgset_item(upb_encstate *e, const upb_msg_ext *ext) { +static void encode_msgset_item(upb_encstate* e, + const upb_Message_Extension* ext) { size_t size; - encode_tag(e, 1, UPB_WIRE_TYPE_END_GROUP); + encode_tag(e, 1, kUpb_WireType_EndGroup); encode_message(e, ext->data.ptr, ext->ext->sub.submsg, &size); encode_varint(e, size); - encode_tag(e, 3, UPB_WIRE_TYPE_DELIMITED); + encode_tag(e, 3, kUpb_WireType_Delimited); encode_varint(e, ext->ext->field.number); - encode_tag(e, 2, UPB_WIRE_TYPE_VARINT); - encode_tag(e, 1, UPB_WIRE_TYPE_START_GROUP); + encode_tag(e, 2, kUpb_WireType_Varint); + encode_tag(e, 1, kUpb_WireType_StartGroup); } -static void encode_message(upb_encstate *e, const upb_msg *msg, - const upb_msglayout *m, size_t *size) { +static void encode_message(upb_encstate* e, const upb_Message* msg, + const upb_MiniTable* m, size_t* size) { size_t pre_len = e->limit - e->ptr; - if ((e->options & UPB_ENCODE_SKIPUNKNOWN) == 0) { + if ((e->options & kUpb_Encode_CheckRequired) && m->required_count) { + uint64_t msg_head; + memcpy(&msg_head, msg, 8); + msg_head = _upb_BigEndian_Swap64(msg_head); + if (upb_MiniTable_requiredmask(m) & ~msg_head) { + encode_err(e); + } + } + + if ((e->options & kUpb_Encode_SkipUnknown) == 0) { size_t unknown_size; - const char *unknown = upb_msg_getunknown(msg, &unknown_size); + const char* unknown = upb_Message_GetUnknown(msg, &unknown_size); if (unknown) { encode_bytes(e, unknown, unknown_size); } } - if (m->ext != _UPB_MSGEXT_NONE) { + if (m->ext != upb_ExtMode_NonExtendable) { /* Encode all extensions together. Unlike C++, we do not attempt to keep * these in field number order relative to normal fields or even to each * other. */ size_t ext_count; - const upb_msg_ext *ext = _upb_msg_getexts(msg, &ext_count); - const upb_msg_ext *end = ext + ext_count; + const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &ext_count); if (ext_count) { + const upb_Message_Extension* end = ext + ext_count; for (; ext != end; ext++) { - if (UPB_UNLIKELY(m->ext == _UPB_MSGEXT_MSGSET)) { + if (UPB_UNLIKELY(m->ext == upb_ExtMode_IsMessageSet)) { encode_msgset_item(e, ext); } else { encode_field(e, &ext->data, &ext->ext->sub, &ext->ext->field); @@ -525,31 +550,33 @@ static void encode_message(upb_encstate *e, const upb_msg *msg, } } - const upb_msglayout_field *f = &m->fields[m->field_count]; - const upb_msglayout_field *first = &m->fields[0]; - while (f != first) { - f--; - if (encode_shouldencode(e, msg, m->subs, f)) { - encode_field(e, msg, m->subs, f); + if (m->field_count) { + const upb_MiniTable_Field* f = &m->fields[m->field_count]; + const upb_MiniTable_Field* first = &m->fields[0]; + while (f != first) { + f--; + if (encode_shouldencode(e, msg, m->subs, f)) { + encode_field(e, msg, m->subs, f); + } } } *size = (e->limit - e->ptr) - pre_len; } -char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options, - upb_arena *arena, size_t *size) { +char* upb_Encode(const void* msg, const upb_MiniTable* l, int options, + upb_Arena* arena, size_t* size) { upb_encstate e; unsigned depth = (unsigned)options >> 16; - e.alloc = upb_arena_alloc(arena); + e.alloc = upb_Arena_Alloc(arena); e.buf = NULL; e.limit = NULL; e.ptr = NULL; e.depth = depth ? depth : 64; e.options = options; _upb_mapsorter_init(&e.sorter); - char *ret = NULL; + char* ret = NULL; if (UPB_SETJMP(e.err)) { *size = 0; diff --git a/contrib/libs/grpc/third_party/upb/upb/encode.h b/contrib/libs/grpc/third_party/upb/upb/encode.h index 3ea2003d2d..906b6f0c35 100644 --- a/contrib/libs/grpc/third_party/upb/upb/encode.h +++ b/contrib/libs/grpc/third_party/upb/upb/encode.h @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -26,7 +26,7 @@ */ /* - * upb_encode: parsing into a upb_msg using a upb_msglayout. + * upb_Encode: parsing into a upb_Message using a upb_MiniTable. */ #ifndef UPB_ENCODE_H_ @@ -48,26 +48,24 @@ enum { * * If your proto contains maps, the encoder will need to malloc()/free() * memory during encode. */ - UPB_ENCODE_DETERMINISTIC = 1, + kUpb_Encode_Deterministic = 1, /* When set, unknown fields are not printed. */ - UPB_ENCODE_SKIPUNKNOWN = 2, + kUpb_Encode_SkipUnknown = 2, + + /* When set, the encode will fail if any required fields are missing. */ + kUpb_Encode_CheckRequired = 4, }; #define UPB_ENCODE_MAXDEPTH(depth) ((depth) << 16) -char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options, - upb_arena *arena, size_t *size); - -UPB_INLINE char *upb_encode(const void *msg, const upb_msglayout *l, - upb_arena *arena, size_t *size) { - return upb_encode_ex(msg, l, 0, arena, size); -} +char* upb_Encode(const void* msg, const upb_MiniTable* l, int options, + upb_Arena* arena, size_t* size); #include "upb/port_undef.inc" #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif -#endif /* UPB_ENCODE_H_ */ +#endif /* UPB_ENCODE_H_ */ diff --git a/contrib/libs/grpc/third_party/upb/upb/msg.c b/contrib/libs/grpc/third_party/upb/upb/msg.c index 54426ec721..3734fc5491 100644 --- a/contrib/libs/grpc/third_party/upb/upb/msg.c +++ b/contrib/libs/grpc/third_party/upb/upb/msg.c @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -31,30 +31,32 @@ #include "upb/port_def.inc" #include "upb/table_internal.h" -/** upb_msg *******************************************************************/ +/** upb_Message + * *******************************************************************/ -static const size_t overhead = sizeof(upb_msg_internaldata); +static const size_t overhead = sizeof(upb_Message_InternalData); -static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) { - ptrdiff_t size = sizeof(upb_msg_internal); - return (upb_msg_internal*)((char*)msg - size); +static const upb_Message_Internal* upb_Message_Getinternal_const( + const upb_Message* msg) { + ptrdiff_t size = sizeof(upb_Message_Internal); + return (upb_Message_Internal*)((char*)msg - size); } -upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) { - return _upb_msg_new_inl(l, a); +upb_Message* _upb_Message_New(const upb_MiniTable* l, upb_Arena* a) { + return _upb_Message_New_inl(l, a); } -void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l) { - void *mem = UPB_PTR_AT(msg, -sizeof(upb_msg_internal), char); +void _upb_Message_Clear(upb_Message* msg, const upb_MiniTable* l) { + void* mem = UPB_PTR_AT(msg, -sizeof(upb_Message_Internal), char); memset(mem, 0, upb_msg_sizeof(l)); } -static bool realloc_internal(upb_msg *msg, size_t need, upb_arena *arena) { - upb_msg_internal *in = upb_msg_getinternal(msg); +static bool realloc_internal(upb_Message* msg, size_t need, upb_Arena* arena) { + upb_Message_Internal* in = upb_Message_Getinternal(msg); if (!in->internal) { /* No internal data, allocate from scratch. */ - size_t size = UPB_MAX(128, _upb_lg2ceilsize(need + overhead)); - upb_msg_internaldata *internal = upb_arena_malloc(arena, size); + size_t size = UPB_MAX(128, _upb_Log2Ceilingsize(need + overhead)); + upb_Message_InternalData* internal = upb_Arena_Malloc(arena, size); if (!internal) return false; internal->size = size; internal->unknown_end = overhead; @@ -62,15 +64,15 @@ static bool realloc_internal(upb_msg *msg, size_t need, upb_arena *arena) { in->internal = internal; } else if (in->internal->ext_begin - in->internal->unknown_end < need) { /* Internal data is too small, reallocate. */ - size_t new_size = _upb_lg2ceilsize(in->internal->size + need); + size_t new_size = _upb_Log2Ceilingsize(in->internal->size + need); size_t ext_bytes = in->internal->size - in->internal->ext_begin; size_t new_ext_begin = new_size - ext_bytes; - upb_msg_internaldata *internal = - upb_arena_realloc(arena, in->internal, in->internal->size, new_size); + upb_Message_InternalData* internal = + upb_Arena_Realloc(arena, in->internal, in->internal->size, new_size); if (!internal) return false; if (ext_bytes) { /* Need to move extension data to the end. */ - char *ptr = (char*)internal; + char* ptr = (char*)internal; memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes); } internal->ext_begin = new_ext_begin; @@ -81,24 +83,24 @@ static bool realloc_internal(upb_msg *msg, size_t need, upb_arena *arena) { return true; } -bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, - upb_arena *arena) { +bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, + upb_Arena* arena) { if (!realloc_internal(msg, len, arena)) return false; - upb_msg_internal *in = upb_msg_getinternal(msg); + upb_Message_Internal* in = upb_Message_Getinternal(msg); memcpy(UPB_PTR_AT(in->internal, in->internal->unknown_end, char), data, len); in->internal->unknown_end += len; return true; } -void _upb_msg_discardunknown_shallow(upb_msg *msg) { - upb_msg_internal *in = upb_msg_getinternal(msg); +void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { + upb_Message_Internal* in = upb_Message_Getinternal(msg); if (in->internal) { in->internal->unknown_end = overhead; } } -const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) { - const upb_msg_internal *in = upb_msg_getinternal_const(msg); +const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len) { + const upb_Message_Internal* in = upb_Message_Getinternal_const(msg); if (in->internal) { *len = in->internal->unknown_end - overhead; return (char*)(in->internal + 1); @@ -108,11 +110,12 @@ const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) { } } -const upb_msg_ext *_upb_msg_getexts(const upb_msg *msg, size_t *count) { - const upb_msg_internal *in = upb_msg_getinternal_const(msg); +const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg, + size_t* count) { + const upb_Message_Internal* in = upb_Message_Getinternal_const(msg); if (in->internal) { - *count = - (in->internal->size - in->internal->ext_begin) / sizeof(upb_msg_ext); + *count = (in->internal->size - in->internal->ext_begin) / + sizeof(upb_Message_Extension); return UPB_PTR_AT(in->internal, in->internal->ext_begin, void); } else { *count = 0; @@ -120,10 +123,10 @@ const upb_msg_ext *_upb_msg_getexts(const upb_msg *msg, size_t *count) { } } -const upb_msg_ext *_upb_msg_getext(const upb_msg *msg, - const upb_msglayout_ext *e) { +const upb_Message_Extension* _upb_Message_Getext( + const upb_Message* msg, const upb_MiniTable_Extension* e) { size_t n; - const upb_msg_ext *ext = _upb_msg_getexts(msg, &n); + const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &n); /* For now we use linear search exclusively to find extensions. If this * becomes an issue due to messages with lots of extensions, we can introduce @@ -137,34 +140,43 @@ const upb_msg_ext *_upb_msg_getext(const upb_msg *msg, return NULL; } -void _upb_msg_clearext(upb_msg *msg, const upb_msglayout_ext *ext_l) { - upb_msg_internal *in = upb_msg_getinternal(msg); +void _upb_Message_Clearext(upb_Message* msg, + const upb_MiniTable_Extension* ext_l) { + upb_Message_Internal* in = upb_Message_Getinternal(msg); if (!in->internal) return; - const upb_msg_ext *base = + const upb_Message_Extension* base = UPB_PTR_AT(in->internal, in->internal->ext_begin, void); - upb_msg_ext *ext = (upb_msg_ext*)_upb_msg_getext(msg, ext_l); + upb_Message_Extension* ext = + (upb_Message_Extension*)_upb_Message_Getext(msg, ext_l); if (ext) { *ext = *base; - in->internal->ext_begin += sizeof(upb_msg_ext); + in->internal->ext_begin += sizeof(upb_Message_Extension); } } -upb_msg_ext *_upb_msg_getorcreateext(upb_msg *msg, const upb_msglayout_ext *e, - upb_arena *arena) { - upb_msg_ext *ext = (upb_msg_ext*)_upb_msg_getext(msg, e); +upb_Message_Extension* _upb_Message_Getorcreateext( + upb_Message* msg, const upb_MiniTable_Extension* e, upb_Arena* arena) { + upb_Message_Extension* ext = + (upb_Message_Extension*)_upb_Message_Getext(msg, e); if (ext) return ext; - if (!realloc_internal(msg, sizeof(upb_msg_ext), arena)) return NULL; - upb_msg_internal *in = upb_msg_getinternal(msg); - in->internal->ext_begin -= sizeof(upb_msg_ext); + if (!realloc_internal(msg, sizeof(upb_Message_Extension), arena)) return NULL; + upb_Message_Internal* in = upb_Message_Getinternal(msg); + in->internal->ext_begin -= sizeof(upb_Message_Extension); ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void); - memset(ext, 0, sizeof(upb_msg_ext)); + memset(ext, 0, sizeof(upb_Message_Extension)); ext->ext = e; return ext; } -/** upb_array *****************************************************************/ +size_t upb_Message_ExtensionCount(const upb_Message* msg) { + size_t count; + _upb_Message_Getexts(msg, &count); + return count; +} + +/** upb_Array *****************************************************************/ -bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { +bool _upb_array_realloc(upb_Array* arr, size_t min_size, upb_Arena* arena) { size_t new_size = UPB_MAX(arr->size, 4); int elem_size_lg2 = arr->data & 7; size_t old_bytes = arr->size << elem_size_lg2; @@ -175,7 +187,7 @@ bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { while (new_size < min_size) new_size *= 2; new_bytes = new_size << elem_size_lg2; - ptr = upb_arena_realloc(arena, ptr, old_bytes, new_bytes); + ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes); if (!ptr) { return false; @@ -186,44 +198,44 @@ bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { return true; } -static upb_array *getorcreate_array(upb_array **arr_ptr, int elem_size_lg2, - upb_arena *arena) { - upb_array *arr = *arr_ptr; +static upb_Array* getorcreate_array(upb_Array** arr_ptr, int elem_size_lg2, + upb_Arena* arena) { + upb_Array* arr = *arr_ptr; if (!arr) { - arr = _upb_array_new(arena, 4, elem_size_lg2); + arr = _upb_Array_New(arena, 4, elem_size_lg2); if (!arr) return NULL; *arr_ptr = arr; } return arr; } -void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, - int elem_size_lg2, upb_arena *arena) { - upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena); - return arr && _upb_array_resize(arr, size, arena) ? _upb_array_ptr(arr) +void* _upb_Array_Resize_fallback(upb_Array** arr_ptr, size_t size, + int elem_size_lg2, upb_Arena* arena) { + upb_Array* arr = getorcreate_array(arr_ptr, elem_size_lg2, arena); + return arr && _upb_Array_Resize(arr, size, arena) ? _upb_array_ptr(arr) : NULL; } -bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value, - int elem_size_lg2, upb_arena *arena) { - upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena); +bool _upb_Array_Append_fallback(upb_Array** arr_ptr, const void* value, + int elem_size_lg2, upb_Arena* arena) { + upb_Array* arr = getorcreate_array(arr_ptr, elem_size_lg2, arena); if (!arr) return false; size_t elems = arr->len; - if (!_upb_array_resize(arr, elems + 1, arena)) { + if (!_upb_Array_Resize(arr, elems + 1, arena)) { return false; } - char *data = _upb_array_ptr(arr); + char* data = _upb_array_ptr(arr); memcpy(data + (elems << elem_size_lg2), value, 1 << elem_size_lg2); return true; } -/** upb_map *******************************************************************/ +/** upb_Map *******************************************************************/ -upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) { - upb_map *map = upb_arena_malloc(a, sizeof(upb_map)); +upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) { + upb_Map* map = upb_Arena_Malloc(a, sizeof(upb_Map)); if (!map) { return NULL; @@ -236,65 +248,69 @@ upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) { return map; } -static void _upb_mapsorter_getkeys(const void *_a, const void *_b, void *a_key, - void *b_key, size_t size) { - const upb_tabent *const*a = _a; - const upb_tabent *const*b = _b; - upb_strview a_tabkey = upb_tabstrview((*a)->key); - upb_strview b_tabkey = upb_tabstrview((*b)->key); +static void _upb_mapsorter_getkeys(const void* _a, const void* _b, void* a_key, + void* b_key, size_t size) { + const upb_tabent* const* a = _a; + const upb_tabent* const* b = _b; + upb_StringView a_tabkey = upb_tabstrview((*a)->key); + upb_StringView b_tabkey = upb_tabstrview((*b)->key); _upb_map_fromkey(a_tabkey, a_key, size); _upb_map_fromkey(b_tabkey, b_key, size); } -static int _upb_mapsorter_cmpi64(const void *_a, const void *_b) { +#define UPB_COMPARE_INTEGERS(a, b) ((a) < (b) ? -1 : ((a) == (b) ? 0 : 1)) + +static int _upb_mapsorter_cmpi64(const void* _a, const void* _b) { int64_t a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, 8); - return a - b; + return UPB_COMPARE_INTEGERS(a, b); } -static int _upb_mapsorter_cmpu64(const void *_a, const void *_b) { +static int _upb_mapsorter_cmpu64(const void* _a, const void* _b) { uint64_t a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, 8); - return a - b; + return UPB_COMPARE_INTEGERS(a, b); } -static int _upb_mapsorter_cmpi32(const void *_a, const void *_b) { +static int _upb_mapsorter_cmpi32(const void* _a, const void* _b) { int32_t a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, 4); - return a - b; + return UPB_COMPARE_INTEGERS(a, b); } -static int _upb_mapsorter_cmpu32(const void *_a, const void *_b) { +static int _upb_mapsorter_cmpu32(const void* _a, const void* _b) { uint32_t a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, 4); - return a - b; + return UPB_COMPARE_INTEGERS(a, b); } -static int _upb_mapsorter_cmpbool(const void *_a, const void *_b) { +static int _upb_mapsorter_cmpbool(const void* _a, const void* _b) { bool a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, 1); - return a - b; + return UPB_COMPARE_INTEGERS(a, b); } -static int _upb_mapsorter_cmpstr(const void *_a, const void *_b) { - upb_strview a, b; +static int _upb_mapsorter_cmpstr(const void* _a, const void* _b) { + upb_StringView a, b; _upb_mapsorter_getkeys(_a, _b, &a, &b, UPB_MAPTYPE_STRING); size_t common_size = UPB_MIN(a.size, b.size); int cmp = memcmp(a.data, b.data, common_size); - if (cmp) return cmp; - return a.size - b.size; + if (cmp) return -cmp; + return UPB_COMPARE_INTEGERS(a.size, b.size); } -bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, - const upb_map *map, _upb_sortedmap *sorted) { - int map_size = _upb_map_size(map); +#undef UPB_COMPARE_INTEGERS + +bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, + const upb_Map* map, _upb_sortedmap* sorted) { + int map_size = _upb_Map_Size(map); sorted->start = s->size; sorted->pos = sorted->start; sorted->end = sorted->start + map_size; /* Grow s->entries if necessary. */ if (sorted->end > s->cap) { - s->cap = _upb_lg2ceilsize(sorted->end); + s->cap = _upb_Log2Ceilingsize(sorted->end); s->entries = realloc(s->entries, s->cap * sizeof(*s->entries)); if (!s->entries) return false; } @@ -302,9 +318,9 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, s->size = sorted->end; /* Copy non-empty entries from the table to s->entries. */ - upb_tabent const**dst = &s->entries[sorted->start]; - const upb_tabent *src = map->table.t.entries; - const upb_tabent *end = src + upb_table_size(&map->table.t); + upb_tabent const** dst = &s->entries[sorted->start]; + const upb_tabent* src = map->table.t.entries; + const upb_tabent* end = src + upb_table_size(&map->table.t); for (; src < end; src++) { if (!upb_tabent_isempty(src)) { *dst = src; @@ -315,32 +331,33 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, /* Sort entries according to the key type. */ - int (*compar)(const void *, const void *); + int (*compar)(const void*, const void*); switch (key_type) { - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_SFIXED64: - case UPB_DESCRIPTOR_TYPE_SINT64: + case kUpb_FieldType_Int64: + case kUpb_FieldType_SFixed64: + case kUpb_FieldType_SInt64: compar = _upb_mapsorter_cmpi64; break; - case UPB_DESCRIPTOR_TYPE_UINT64: - case UPB_DESCRIPTOR_TYPE_FIXED64: + case kUpb_FieldType_UInt64: + case kUpb_FieldType_Fixed64: compar = _upb_mapsorter_cmpu64; break; - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_SINT32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - case UPB_DESCRIPTOR_TYPE_ENUM: + case kUpb_FieldType_Int32: + case kUpb_FieldType_SInt32: + case kUpb_FieldType_SFixed32: + case kUpb_FieldType_Enum: compar = _upb_mapsorter_cmpi32; break; - case UPB_DESCRIPTOR_TYPE_UINT32: - case UPB_DESCRIPTOR_TYPE_FIXED32: + case kUpb_FieldType_UInt32: + case kUpb_FieldType_Fixed32: compar = _upb_mapsorter_cmpu32; break; - case UPB_DESCRIPTOR_TYPE_BOOL: + case kUpb_FieldType_Bool: compar = _upb_mapsorter_cmpbool; break; - case UPB_DESCRIPTOR_TYPE_STRING: + case kUpb_FieldType_String: + case kUpb_FieldType_Bytes: compar = _upb_mapsorter_cmpstr; break; default: @@ -351,34 +368,36 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, return true; } -/** upb_extreg ****************************************************************/ +/** upb_ExtensionRegistry + * ****************************************************************/ -struct upb_extreg { - upb_arena *arena; - upb_strtable exts; /* Key is upb_msglayout* concatenated with fieldnum. */ +struct upb_ExtensionRegistry { + upb_Arena* arena; + upb_strtable exts; /* Key is upb_MiniTable* concatenated with fieldnum. */ }; -#define EXTREG_KEY_SIZE (sizeof(upb_msglayout*) + sizeof(uint32_t)) +#define EXTREG_KEY_SIZE (sizeof(upb_MiniTable*) + sizeof(uint32_t)) -static void extreg_key(char *buf, const upb_msglayout *l, uint32_t fieldnum) { +static void extreg_key(char* buf, const upb_MiniTable* l, uint32_t fieldnum) { memcpy(buf, &l, sizeof(l)); memcpy(buf + sizeof(l), &fieldnum, sizeof(fieldnum)); } -upb_extreg *upb_extreg_new(upb_arena *arena) { - upb_extreg *r = upb_arena_malloc(arena, sizeof(*r)); +upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) { + upb_ExtensionRegistry* r = upb_Arena_Malloc(arena, sizeof(*r)); if (!r) return NULL; r->arena = arena; if (!upb_strtable_init(&r->exts, 8, arena)) return NULL; return r; } -bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext **e, size_t count) { +bool _upb_extreg_add(upb_ExtensionRegistry* r, + const upb_MiniTable_Extension** e, size_t count) { char buf[EXTREG_KEY_SIZE]; - const upb_msglayout_ext **start = e; - const upb_msglayout_ext **end = e + count; + const upb_MiniTable_Extension** start = e; + const upb_MiniTable_Extension** end = UPB_PTRADD(e, count); for (; e < end; e++) { - const upb_msglayout_ext *ext = *e; + const upb_MiniTable_Extension* ext = *e; extreg_key(buf, ext->extendee, ext->field.number); if (!upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE, upb_value_constptr(ext), r->arena)) { @@ -390,15 +409,16 @@ bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext **e, size_t count) { failure: /* Back out the entries previously added. */ for (end = e, e = start; e < end; e++) { - const upb_msglayout_ext *ext = *e; + const upb_MiniTable_Extension* ext = *e; extreg_key(buf, ext->extendee, ext->field.number); - upb_strtable_remove(&r->exts, buf, EXTREG_KEY_SIZE, NULL); + upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL); } return false; } -const upb_msglayout_ext *_upb_extreg_get(const upb_extreg *r, - const upb_msglayout *l, uint32_t num) { +const upb_MiniTable_Extension* _upb_extreg_get(const upb_ExtensionRegistry* r, + const upb_MiniTable* l, + uint32_t num) { char buf[EXTREG_KEY_SIZE]; upb_value v; extreg_key(buf, l, num); diff --git a/contrib/libs/grpc/third_party/upb/upb/msg.h b/contrib/libs/grpc/third_party/upb/upb/msg.h index 497bd82b01..99928393ae 100644 --- a/contrib/libs/grpc/third_party/upb/upb/msg.h +++ b/contrib/libs/grpc/third_party/upb/upb/msg.h @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -44,39 +44,46 @@ extern "C" { #endif -typedef void upb_msg; +/** upb_Message + * *******************************************************************/ -/* For users these are opaque. They can be obtained from upb_msgdef_layout() - * but users cannot access any of the members. */ -struct upb_msglayout; -typedef struct upb_msglayout upb_msglayout; +typedef void upb_Message; + +/* For users these are opaque. They can be obtained from + * upb_MessageDef_MiniTable() but users cannot access any of the members. */ +struct upb_MiniTable; +typedef struct upb_MiniTable upb_MiniTable; /* Adds unknown data (serialized protobuf data) to the given message. The data * is copied into the message instance. */ -void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, - upb_arena *arena); +void upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, + upb_Arena* arena); /* Returns a reference to the message's unknown data. */ -const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); +const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len); + +/* Returns the number of extensions present in this message. */ +size_t upb_Message_ExtensionCount(const upb_Message* msg); -/** upb_extreg *******************************************************************/ +/** upb_ExtensionRegistry *****************************************************/ /* Extension registry: a dynamic data structure that stores a map of: - * (upb_msglayout, number) -> extension info + * (upb_MiniTable, number) -> extension info * - * upb_decode() uses upb_extreg to look up extensions while parsing binary - * format. + * upb_decode() uses upb_ExtensionRegistry to look up extensions while parsing + * binary format. * - * upb_extreg is part of the mini-table (msglayout) family of objects. Like all - * mini-table objects, it is suitable for reflection-less builds that do not - * want to expose names into the binary. + * upb_ExtensionRegistry is part of the mini-table (msglayout) family of + * objects. Like all mini-table objects, it is suitable for reflection-less + * builds that do not want to expose names into the binary. * - * Unlike most mini-table types, upb_extreg requires dynamic memory allocation - * and dynamic initialization: - * * If reflection is being used, then upb_symtab will construct an appropriate - * upb_extreg automatically. + * Unlike most mini-table types, upb_ExtensionRegistry requires dynamic memory + * allocation and dynamic initialization: + * * If reflection is being used, then upb_DefPool will construct an appropriate + * upb_ExtensionRegistry automatically. * * For a mini-table only build, the user must manually construct the - * upb_extreg and populate it with all of the extensions the user cares about. + * upb_ExtensionRegistry and populate it with all of the extensions the user + * cares about. * * A third alternative is to manually unpack relevant extensions after the * main parse is complete, similar to how Any works. This is perhaps the * nicest solution from the perspective of reducing dependencies, avoiding @@ -90,19 +97,19 @@ const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); * extensions from a generated module and pass the extension registry to the * binary decoder. * - * A upb_symtab provides a upb_extreg, so any users who use reflection do not - * need to populate a upb_extreg directly. + * A upb_DefPool provides a upb_ExtensionRegistry, so any users who use + * reflection do not need to populate a upb_ExtensionRegistry directly. */ -struct upb_extreg; -typedef struct upb_extreg upb_extreg; +struct upb_ExtensionRegistry; +typedef struct upb_ExtensionRegistry upb_ExtensionRegistry; -/* Creates a upb_extreg in the given arena. The arena must outlive any use of - * the extreg. */ -upb_extreg *upb_extreg_new(upb_arena *arena); +/* Creates a upb_ExtensionRegistry in the given arena. The arena must outlive + * any use of the extreg. */ +upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif #endif /* UPB_MSG_INT_H_ */ diff --git a/contrib/libs/grpc/third_party/upb/upb/msg_internal.h b/contrib/libs/grpc/third_party/upb/upb/msg_internal.h index 7d024f7beb..88c17108f1 100644 --- a/contrib/libs/grpc/third_party/upb/upb/msg_internal.h +++ b/contrib/libs/grpc/third_party/upb/upb/msg_internal.h @@ -50,97 +50,110 @@ extern "C" { #endif -/** upb_msglayout *************************************************************/ +/** upb_MiniTable *************************************************************/ -/* upb_msglayout represents the memory layout of a given upb_msgdef. The +/* upb_MiniTable represents the memory layout of a given upb_MessageDef. The * members are public so generated code can initialize them, but users MUST NOT * read or write any of its members. */ -/* These aren't real labels according to descriptor.proto, but in the table we - * use these for map/packed fields instead of UPB_LABEL_REPEATED. */ -enum { - _UPB_LABEL_MAP = 4, - _UPB_LABEL_PACKED = 7 /* Low 3 bits are common with UPB_LABEL_REPEATED. */ -}; - typedef struct { uint32_t number; uint16_t offset; - int16_t presence; /* If >0, hasbit_index. If <0, ~oneof_index. */ - uint16_t submsg_index; /* undefined if descriptortype != MESSAGE or GROUP. */ + int16_t presence; // If >0, hasbit_index. If <0, ~oneof_index + uint16_t submsg_index; // undefined if descriptortype != MESSAGE/GROUP/ENUM uint8_t descriptortype; - uint8_t mode; /* upb_fieldmode | upb_labelflags | - (upb_rep << _UPB_REP_SHIFT) */ -} upb_msglayout_field; + uint8_t mode; /* upb_FieldMode | upb_LabelFlags | + (upb_FieldRep << upb_FieldRep_Shift) */ +} upb_MiniTable_Field; typedef enum { - _UPB_MODE_MAP = 0, - _UPB_MODE_ARRAY = 1, - _UPB_MODE_SCALAR = 2, + kUpb_FieldMode_Map = 0, + kUpb_FieldMode_Array = 1, + kUpb_FieldMode_Scalar = 2, - _UPB_MODE_MASK = 3, /* Mask to isolate the mode from upb_rep. */ -} upb_fieldmode; + kUpb_FieldMode_Mask = 3, /* Mask to isolate the mode from upb_FieldRep. */ +} upb_FieldMode; /* Extra flags on the mode field. */ -enum upb_labelflags { - _UPB_MODE_IS_PACKED = 4, - _UPB_MODE_IS_EXTENSION = 8, +enum upb_LabelFlags { + upb_LabelFlags_IsPacked = 4, + upb_LabelFlags_IsExtension = 8, }; /* Representation in the message. Derivable from descriptortype and mode, but * fast access helps the serializer. */ -enum upb_rep { - _UPB_REP_1BYTE = 0, - _UPB_REP_4BYTE = 1, - _UPB_REP_8BYTE = 2, - _UPB_REP_STRVIEW = 3, +enum upb_FieldRep { + upb_FieldRep_1Byte = 0, + upb_FieldRep_4Byte = 1, + upb_FieldRep_8Byte = 2, + upb_FieldRep_StringView = 3, #if UINTPTR_MAX == 0xffffffff - _UPB_REP_PTR = _UPB_REP_4BYTE, + upb_FieldRep_Pointer = upb_FieldRep_4Byte, #else - _UPB_REP_PTR = _UPB_REP_8BYTE, + upb_FieldRep_Pointer = upb_FieldRep_8Byte, #endif - _UPB_REP_SHIFT = 6, /* Bit offset of the rep in upb_msglayout_field.mode */ + upb_FieldRep_Shift = + 6, /* Bit offset of the rep in upb_MiniTable_Field.mode */ }; -UPB_INLINE upb_fieldmode _upb_getmode(const upb_msglayout_field *field) { - return (upb_fieldmode)(field->mode & 3); +UPB_INLINE upb_FieldMode upb_FieldMode_Get(const upb_MiniTable_Field* field) { + return (upb_FieldMode)(field->mode & 3); } -UPB_INLINE bool _upb_repeated_or_map(const upb_msglayout_field *field) { - /* This works because upb_fieldmode has no value 3. */ - return !(field->mode & _UPB_MODE_SCALAR); +UPB_INLINE bool upb_IsRepeatedOrMap(const upb_MiniTable_Field* field) { + /* This works because upb_FieldMode has no value 3. */ + return !(field->mode & kUpb_FieldMode_Scalar); } -UPB_INLINE bool _upb_issubmsg(const upb_msglayout_field *field) { - return field->descriptortype == UPB_DTYPE_MESSAGE || - field->descriptortype == UPB_DTYPE_GROUP; +UPB_INLINE bool upb_IsSubMessage(const upb_MiniTable_Field* field) { + return field->descriptortype == kUpb_FieldType_Message || + field->descriptortype == kUpb_FieldType_Group; } -struct upb_decstate; -struct upb_msglayout; +struct upb_Decoder; +struct upb_MiniTable; -typedef const char *_upb_field_parser(struct upb_decstate *d, const char *ptr, - upb_msg *msg, intptr_t table, - uint64_t hasbits, uint64_t data); +typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data); typedef struct { uint64_t field_data; - _upb_field_parser *field_parser; -} _upb_fasttable_entry; + _upb_FieldParser* field_parser; +} _upb_FastTable_Entry; + +typedef struct { + const int32_t* values; // List of values <0 or >63 + uint64_t mask; // Bits are set for acceptable value 0 <= x < 64 + int value_count; +} upb_MiniTable_Enum; + +UPB_INLINE bool upb_MiniTable_Enum_CheckValue(const upb_MiniTable_Enum* e, + int32_t val) { + uint32_t uval = (uint32_t)val; + if (uval < 64) return e->mask & (1 << uval); + // OPT: binary search long lists? + int n = e->value_count; + for (int i = 0; i < n; i++) { + if (e->values[i] == val) return true; + } + return false; +} typedef union { - const struct upb_msglayout *submsg; - // TODO: const upb_enumlayout *subenum; -} upb_msglayout_sub; + const struct upb_MiniTable* submsg; + const upb_MiniTable_Enum* subenum; +} upb_MiniTable_Sub; typedef enum { - _UPB_MSGEXT_NONE = 0, // Non-extendable message. - _UPB_MSGEXT_EXTENDABLE = 1, // Normal extendable message. - _UPB_MSGEXT_MSGSET = 2, // MessageSet message. - _UPB_MSGEXT_MSGSET_ITEM = 3, // MessageSet item (temporary only, see decode.c) -} upb_msgext_mode; + upb_ExtMode_NonExtendable = 0, // Non-extendable message. + upb_ExtMode_Extendable = 1, // Normal extendable message. + upb_ExtMode_IsMessageSet = 2, // MessageSet message. + upb_ExtMode_IsMessageSet_ITEM = + 3, // MessageSet item (temporary only, see decode.c) +} upb_ExtMode; /* MessageSet wire format is: * message MessageSet { @@ -156,57 +169,77 @@ typedef enum { _UPB_MSGSET_MESSAGE = 3, } upb_msgext_fieldnum; -struct upb_msglayout { - const upb_msglayout_sub *subs; - const upb_msglayout_field *fields; +struct upb_MiniTable { + const upb_MiniTable_Sub* subs; + const upb_MiniTable_Field* fields; /* Must be aligned to sizeof(void*). Doesn't include internal members like * unknown fields, extension dict, pointer to msglayout, etc. */ uint16_t size; uint16_t field_count; - uint8_t ext; // upb_msgext_mode, declared as uint8_t so sizeof(ext) == 1 + uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1 uint8_t dense_below; uint8_t table_mask; - /* To constant-initialize the tables of variable length, we need a flexible - * array member, and we need to compile in C99 mode. */ - _upb_fasttable_entry fasttable[]; + uint8_t required_count; // Required fields have the lowest hasbits. + /* To statically initialize the tables of variable length, we need a flexible + * array member, and we need to compile in gnu99 mode (constant initialization + * of flexible array members is a GNU extension, not in C99 unfortunately. */ + _upb_FastTable_Entry fasttable[]; }; typedef struct { - upb_msglayout_field field; - const upb_msglayout *extendee; - upb_msglayout_sub sub; /* NULL unless submessage or proto2 enum */ -} upb_msglayout_ext; + upb_MiniTable_Field field; + const upb_MiniTable* extendee; + upb_MiniTable_Sub sub; /* NULL unless submessage or proto2 enum */ +} upb_MiniTable_Extension; typedef struct { - const upb_msglayout **msgs; - const upb_msglayout_ext **exts; + const upb_MiniTable** msgs; + const upb_MiniTable_Enum** enums; + const upb_MiniTable_Extension** exts; int msg_count; + int enum_count; int ext_count; -} upb_msglayout_file; +} upb_MiniTable_File; -/** upb_extreg ****************************************************************/ +// Computes a bitmask in which the |l->required_count| lowest bits are set, +// except that we skip the lowest bit (because upb never uses hasbit 0). +// +// Sample output: +// requiredmask(1) => 0b10 (0x2) +// requiredmask(5) => 0b111110 (0x3e) +UPB_INLINE uint64_t upb_MiniTable_requiredmask(const upb_MiniTable* l) { + int n = l->required_count; + assert(0 < n && n <= 63); + return ((1ULL << n) - 1) << 1; +} + +/** upb_ExtensionRegistry + * ****************************************************************/ /* Adds the given extension info for message type |l| and field number |num| * into the registry. Returns false if this message type and field number were * already in the map, or if memory allocation fails. */ -bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext **e, size_t count); +bool _upb_extreg_add(upb_ExtensionRegistry* r, + const upb_MiniTable_Extension** e, size_t count); /* Looks up the extension (if any) defined for message type |l| and field * number |num|. If an extension was found, copies the field info into |*ext| * and returns true. Otherwise returns false. */ -const upb_msglayout_ext *_upb_extreg_get(const upb_extreg *r, - const upb_msglayout *l, uint32_t num); +const upb_MiniTable_Extension* _upb_extreg_get(const upb_ExtensionRegistry* r, + const upb_MiniTable* l, + uint32_t num); -/** upb_msg *******************************************************************/ +/** upb_Message + * *******************************************************************/ -/* Internal members of a upb_msg that track unknown fields and/or extensions. - * We can change this without breaking binary compatibility. We put these - * before the user's data. The user's upb_msg* points after the - * upb_msg_internal. */ +/* Internal members of a upb_Message that track unknown fields and/or + * extensions. We can change this without breaking binary compatibility. We put + * these before the user's data. The user's upb_Message* points after the + * upb_Message_Internal. */ typedef struct { /* Total size of this structure, including the data that follows. - * Must be aligned to 8, which is alignof(upb_msg_ext) */ + * Must be aligned to 8, which is alignof(upb_Message_Extension) */ uint32_t size; /* Offsets relative to the beginning of this structure. @@ -216,162 +249,176 @@ typedef struct { * When the two meet, we're out of data and have to realloc. * * If we imagine that the final member of this struct is: - * char data[size - overhead]; // overhead = sizeof(upb_msg_internaldata) - * + * char data[size - overhead]; // overhead = + * sizeof(upb_Message_InternalData) + * * Then we have: * unknown data: data[0 .. (unknown_end - overhead)] * extensions data: data[(ext_begin - overhead) .. (size - overhead)] */ uint32_t unknown_end; uint32_t ext_begin; /* Data follows, as if there were an array: - * char data[size - sizeof(upb_msg_internaldata)]; */ -} upb_msg_internaldata; + * char data[size - sizeof(upb_Message_InternalData)]; */ +} upb_Message_InternalData; typedef struct { - upb_msg_internaldata *internal; -} upb_msg_internal; + upb_Message_InternalData* internal; + /* Message data follows. */ +} upb_Message_Internal; -/* Maps upb_fieldtype_t -> memory size. */ -extern char _upb_fieldtype_to_size[12]; +/* Maps upb_CType -> memory size. */ +extern char _upb_CTypeo_size[12]; -UPB_INLINE size_t upb_msg_sizeof(const upb_msglayout *l) { - return l->size + sizeof(upb_msg_internal); +UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* l) { + return l->size + sizeof(upb_Message_Internal); } -UPB_INLINE upb_msg *_upb_msg_new_inl(const upb_msglayout *l, upb_arena *a) { +UPB_INLINE upb_Message* _upb_Message_New_inl(const upb_MiniTable* l, + upb_Arena* a) { size_t size = upb_msg_sizeof(l); - void *mem = upb_arena_malloc(a, size); - upb_msg *msg; + void* mem = upb_Arena_Malloc(a, size); + upb_Message* msg; if (UPB_UNLIKELY(!mem)) return NULL; - msg = UPB_PTR_AT(mem, sizeof(upb_msg_internal), upb_msg); + msg = UPB_PTR_AT(mem, sizeof(upb_Message_Internal), upb_Message); memset(mem, 0, size); return msg; } /* Creates a new messages with the given layout on the given arena. */ -upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a); +upb_Message* _upb_Message_New(const upb_MiniTable* l, upb_Arena* a); -UPB_INLINE upb_msg_internal *upb_msg_getinternal(upb_msg *msg) { - ptrdiff_t size = sizeof(upb_msg_internal); - return (upb_msg_internal*)((char*)msg - size); +UPB_INLINE upb_Message_Internal* upb_Message_Getinternal(upb_Message* msg) { + ptrdiff_t size = sizeof(upb_Message_Internal); + return (upb_Message_Internal*)((char*)msg - size); } /* Clears the given message. */ -void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l); +void _upb_Message_Clear(upb_Message* msg, const upb_MiniTable* l); /* Discards the unknown fields for this message only. */ -void _upb_msg_discardunknown_shallow(upb_msg *msg); +void _upb_Message_DiscardUnknown_shallow(upb_Message* msg); /* Adds unknown data (serialized protobuf data) to the given message. The data * is copied into the message instance. */ -bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, - upb_arena *arena); +bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, + upb_Arena* arena); -/** upb_msg_ext ***************************************************************/ +/** upb_Message_Extension + * ***************************************************************/ /* The internal representation of an extension is self-describing: it contains * enough information that we can serialize it to binary format without needing - * to look it up in a registry. */ + * to look it up in a upb_ExtensionRegistry. + * + * This representation allocates 16 bytes to data on 64-bit platforms. This is + * rather wasteful for scalars (in the extreme case of bool, it wastes 15 + * bytes). We accept this because we expect messages to be the most common + * extension type. */ typedef struct { - const upb_msglayout_ext *ext; + const upb_MiniTable_Extension* ext; union { - upb_strview str; - void *ptr; - double dbl; + upb_StringView str; + void* ptr; char scalar_data[8]; } data; -} upb_msg_ext; +} upb_Message_Extension; -/* Adds the given extension data to the given message. The returned extension will - * have its "ext" member initialized according to |ext|. */ -upb_msg_ext *_upb_msg_getorcreateext(upb_msg *msg, const upb_msglayout_ext *ext, - upb_arena *arena); +/* Adds the given extension data to the given message. |ext| is copied into the + * message instance. This logically replaces any previously-added extension with + * this number */ +upb_Message_Extension* _upb_Message_Getorcreateext( + upb_Message* msg, const upb_MiniTable_Extension* ext, upb_Arena* arena); /* Returns an array of extensions for this message. Note: the array is * ordered in reverse relative to the order of creation. */ -const upb_msg_ext *_upb_msg_getexts(const upb_msg *msg, size_t *count); +const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg, + size_t* count); /* Returns an extension for the given field number, or NULL if no extension * exists for this field number. */ -const upb_msg_ext *_upb_msg_getext(const upb_msg *msg, - const upb_msglayout_ext *ext); +const upb_Message_Extension* _upb_Message_Getext( + const upb_Message* msg, const upb_MiniTable_Extension* ext); + +void _upb_Message_Clearext(upb_Message* msg, + const upb_MiniTable_Extension* ext); -void _upb_msg_clearext(upb_msg *msg, const upb_msglayout_ext *ext); +void _upb_Message_Clearext(upb_Message* msg, + const upb_MiniTable_Extension* ext); /** Hasbit access *************************************************************/ -UPB_INLINE bool _upb_hasbit(const upb_msg *msg, size_t idx) { +UPB_INLINE bool _upb_hasbit(const upb_Message* msg, size_t idx) { return (*UPB_PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0; } -UPB_INLINE void _upb_sethas(const upb_msg *msg, size_t idx) { +UPB_INLINE void _upb_sethas(const upb_Message* msg, size_t idx) { (*UPB_PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8)); } -UPB_INLINE void _upb_clearhas(const upb_msg *msg, size_t idx) { +UPB_INLINE void _upb_clearhas(const upb_Message* msg, size_t idx) { (*UPB_PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8))); } -UPB_INLINE size_t _upb_msg_hasidx(const upb_msglayout_field *f) { +UPB_INLINE size_t _upb_Message_Hasidx(const upb_MiniTable_Field* f) { UPB_ASSERT(f->presence > 0); return f->presence; } -UPB_INLINE bool _upb_hasbit_field(const upb_msg *msg, - const upb_msglayout_field *f) { - return _upb_hasbit(msg, _upb_msg_hasidx(f)); +UPB_INLINE bool _upb_hasbit_field(const upb_Message* msg, + const upb_MiniTable_Field* f) { + return _upb_hasbit(msg, _upb_Message_Hasidx(f)); } -UPB_INLINE void _upb_sethas_field(const upb_msg *msg, - const upb_msglayout_field *f) { - _upb_sethas(msg, _upb_msg_hasidx(f)); +UPB_INLINE void _upb_sethas_field(const upb_Message* msg, + const upb_MiniTable_Field* f) { + _upb_sethas(msg, _upb_Message_Hasidx(f)); } -UPB_INLINE void _upb_clearhas_field(const upb_msg *msg, - const upb_msglayout_field *f) { - _upb_clearhas(msg, _upb_msg_hasidx(f)); +UPB_INLINE void _upb_clearhas_field(const upb_Message* msg, + const upb_MiniTable_Field* f) { + _upb_clearhas(msg, _upb_Message_Hasidx(f)); } /** Oneof case access *********************************************************/ -UPB_INLINE uint32_t *_upb_oneofcase(upb_msg *msg, size_t case_ofs) { +UPB_INLINE uint32_t* _upb_oneofcase(upb_Message* msg, size_t case_ofs) { return UPB_PTR_AT(msg, case_ofs, uint32_t); } -UPB_INLINE uint32_t _upb_getoneofcase(const void *msg, size_t case_ofs) { +UPB_INLINE uint32_t _upb_getoneofcase(const void* msg, size_t case_ofs) { return *UPB_PTR_AT(msg, case_ofs, uint32_t); } -UPB_INLINE size_t _upb_oneofcase_ofs(const upb_msglayout_field *f) { +UPB_INLINE size_t _upb_oneofcase_ofs(const upb_MiniTable_Field* f) { UPB_ASSERT(f->presence < 0); return ~(ptrdiff_t)f->presence; } -UPB_INLINE uint32_t *_upb_oneofcase_field(upb_msg *msg, - const upb_msglayout_field *f) { +UPB_INLINE uint32_t* _upb_oneofcase_field(upb_Message* msg, + const upb_MiniTable_Field* f) { return _upb_oneofcase(msg, _upb_oneofcase_ofs(f)); } -UPB_INLINE uint32_t _upb_getoneofcase_field(const upb_msg *msg, - const upb_msglayout_field *f) { +UPB_INLINE uint32_t _upb_getoneofcase_field(const upb_Message* msg, + const upb_MiniTable_Field* f) { return _upb_getoneofcase(msg, _upb_oneofcase_ofs(f)); } -UPB_INLINE bool _upb_has_submsg_nohasbit(const upb_msg *msg, size_t ofs) { - return *UPB_PTR_AT(msg, ofs, const upb_msg*) != NULL; +UPB_INLINE bool _upb_has_submsg_nohasbit(const upb_Message* msg, size_t ofs) { + return *UPB_PTR_AT(msg, ofs, const upb_Message*) != NULL; } -/** upb_array *****************************************************************/ +/** upb_Array *****************************************************************/ /* Our internal representation for repeated fields. */ typedef struct { - uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */ - size_t len; /* Measured in elements. */ - size_t size; /* Measured in elements. */ + uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */ + size_t len; /* Measured in elements. */ + size_t size; /* Measured in elements. */ uint64_t junk; -} upb_array; +} upb_Array; -UPB_INLINE const void *_upb_array_constptr(const upb_array *arr) { +UPB_INLINE const void* _upb_array_constptr(const upb_Array* arr) { UPB_ASSERT((arr->data & 7) <= 4); return (void*)(arr->data & ~(uintptr_t)7); } @@ -381,7 +428,7 @@ UPB_INLINE uintptr_t _upb_array_tagptr(void* ptr, int elem_size_lg2) { return (uintptr_t)ptr | elem_size_lg2; } -UPB_INLINE void *_upb_array_ptr(upb_array *arr) { +UPB_INLINE void* _upb_array_ptr(upb_Array* arr) { return (void*)_upb_array_constptr(arr); } @@ -391,11 +438,11 @@ UPB_INLINE uintptr_t _upb_tag_arrptr(void* ptr, int elem_size_lg2) { return (uintptr_t)ptr | (unsigned)elem_size_lg2; } -UPB_INLINE upb_array *_upb_array_new(upb_arena *a, size_t init_size, +UPB_INLINE upb_Array* _upb_Array_New(upb_Arena* a, size_t init_size, int elem_size_lg2) { - const size_t arr_size = UPB_ALIGN_UP(sizeof(upb_array), 8); - const size_t bytes = sizeof(upb_array) + (init_size << elem_size_lg2); - upb_array *arr = (upb_array*)upb_arena_malloc(a, bytes); + const size_t arr_size = UPB_ALIGN_UP(sizeof(upb_Array), 8); + const size_t bytes = sizeof(upb_Array) + (init_size << elem_size_lg2); + upb_Array* arr = (upb_Array*)upb_Arena_Malloc(a, bytes); if (!arr) return NULL; arr->data = _upb_tag_arrptr(UPB_PTR_AT(arr, arr_size, void), elem_size_lg2); arr->len = 0; @@ -404,30 +451,30 @@ UPB_INLINE upb_array *_upb_array_new(upb_arena *a, size_t init_size, } /* Resizes the capacity of the array to be at least min_size. */ -bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena); +bool _upb_array_realloc(upb_Array* arr, size_t min_size, upb_Arena* arena); /* Fallback functions for when the accessors require a resize. */ -void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, - int elem_size_lg2, upb_arena *arena); -bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value, - int elem_size_lg2, upb_arena *arena); +void* _upb_Array_Resize_fallback(upb_Array** arr_ptr, size_t size, + int elem_size_lg2, upb_Arena* arena); +bool _upb_Array_Append_fallback(upb_Array** arr_ptr, const void* value, + int elem_size_lg2, upb_Arena* arena); -UPB_INLINE bool _upb_array_reserve(upb_array *arr, size_t size, - upb_arena *arena) { +UPB_INLINE bool _upb_array_reserve(upb_Array* arr, size_t size, + upb_Arena* arena) { if (arr->size < size) return _upb_array_realloc(arr, size, arena); return true; } -UPB_INLINE bool _upb_array_resize(upb_array *arr, size_t size, - upb_arena *arena) { +UPB_INLINE bool _upb_Array_Resize(upb_Array* arr, size_t size, + upb_Arena* arena) { if (!_upb_array_reserve(arr, size, arena)) return false; arr->len = size; return true; } -UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs, - size_t *size) { - const upb_array *arr = *UPB_PTR_AT(msg, ofs, const upb_array*); +UPB_INLINE const void* _upb_array_accessor(const void* msg, size_t ofs, + size_t* size) { + const upb_Array* arr = *UPB_PTR_AT(msg, ofs, const upb_Array*); if (arr) { if (size) *size = arr->len; return _upb_array_constptr(arr); @@ -437,9 +484,9 @@ UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs, } } -UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs, - size_t *size) { - upb_array *arr = *UPB_PTR_AT(msg, ofs, upb_array*); +UPB_INLINE void* _upb_array_mutable_accessor(void* msg, size_t ofs, + size_t* size) { + upb_Array* arr = *UPB_PTR_AT(msg, ofs, upb_Array*); if (arr) { if (size) *size = arr->len; return _upb_array_ptr(arr); @@ -449,28 +496,28 @@ UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs, } } -UPB_INLINE void *_upb_array_resize_accessor2(void *msg, size_t ofs, size_t size, +UPB_INLINE void* _upb_Array_Resize_accessor2(void* msg, size_t ofs, size_t size, int elem_size_lg2, - upb_arena *arena) { - upb_array **arr_ptr = UPB_PTR_AT(msg, ofs, upb_array *); - upb_array *arr = *arr_ptr; + upb_Arena* arena) { + upb_Array** arr_ptr = UPB_PTR_AT(msg, ofs, upb_Array*); + upb_Array* arr = *arr_ptr; if (!arr || arr->size < size) { - return _upb_array_resize_fallback(arr_ptr, size, elem_size_lg2, arena); + return _upb_Array_Resize_fallback(arr_ptr, size, elem_size_lg2, arena); } arr->len = size; return _upb_array_ptr(arr); } -UPB_INLINE bool _upb_array_append_accessor2(void *msg, size_t ofs, +UPB_INLINE bool _upb_Array_Append_accessor2(void* msg, size_t ofs, int elem_size_lg2, - const void *value, - upb_arena *arena) { - upb_array **arr_ptr = UPB_PTR_AT(msg, ofs, upb_array *); + const void* value, + upb_Arena* arena) { + upb_Array** arr_ptr = UPB_PTR_AT(msg, ofs, upb_Array*); size_t elem_size = 1 << elem_size_lg2; - upb_array *arr = *arr_ptr; - void *ptr; + upb_Array* arr = *arr_ptr; + void* ptr; if (!arr || arr->len == arr->size) { - return _upb_array_append_fallback(arr_ptr, value, elem_size_lg2, arena); + return _upb_Array_Append_fallback(arr_ptr, value, elem_size_lg2, arena); } ptr = _upb_array_ptr(arr); memcpy(UPB_PTR_AT(ptr, arr->len * elem_size, char), value, elem_size); @@ -479,42 +526,41 @@ UPB_INLINE bool _upb_array_append_accessor2(void *msg, size_t ofs, } /* Used by old generated code, remove once all code has been regenerated. */ -UPB_INLINE int _upb_sizelg2(upb_fieldtype_t type) { +UPB_INLINE int _upb_sizelg2(upb_CType type) { switch (type) { - case UPB_TYPE_BOOL: + case kUpb_CType_Bool: return 0; - case UPB_TYPE_FLOAT: - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_ENUM: + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: return 2; - case UPB_TYPE_MESSAGE: + case kUpb_CType_Message: return UPB_SIZE(2, 3); - case UPB_TYPE_DOUBLE: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: return 3; - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: + case kUpb_CType_String: + case kUpb_CType_Bytes: return UPB_SIZE(3, 4); } UPB_UNREACHABLE(); } -UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size, - upb_fieldtype_t type, - upb_arena *arena) { - return _upb_array_resize_accessor2(msg, ofs, size, _upb_sizelg2(type), arena); +UPB_INLINE void* _upb_Array_Resize_accessor(void* msg, size_t ofs, size_t size, + upb_CType type, upb_Arena* arena) { + return _upb_Array_Resize_accessor2(msg, ofs, size, _upb_sizelg2(type), arena); } -UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs, - size_t elem_size, upb_fieldtype_t type, - const void *value, - upb_arena *arena) { +UPB_INLINE bool _upb_Array_Append_accessor(void* msg, size_t ofs, + size_t elem_size, upb_CType type, + const void* value, + upb_Arena* arena) { (void)elem_size; - return _upb_array_append_accessor2(msg, ofs, _upb_sizelg2(type), value, + return _upb_Array_Append_accessor2(msg, ofs, _upb_sizelg2(type), value, arena); } -/** upb_map *******************************************************************/ +/** upb_Map *******************************************************************/ /* Right now we use strmaps for everything. We'll likely want to use * integer-specific maps for integer-keyed maps.*/ @@ -525,25 +571,25 @@ typedef struct { char val_size; upb_strtable table; -} upb_map; +} upb_Map; /* Map entries aren't actually stored, they are only used during parsing. For * parsing, it helps a lot if all map entry messages have the same layout. * The compiler and def.c must ensure that all map entries have this layout. */ typedef struct { - upb_msg_internal internal; + upb_Message_Internal internal; union { - upb_strview str; /* For str/bytes. */ - upb_value val; /* For all other types. */ + upb_StringView str; /* For str/bytes. */ + upb_value val; /* For all other types. */ } k; union { - upb_strview str; /* For str/bytes. */ - upb_value val; /* For all other types. */ + upb_StringView str; /* For str/bytes. */ + upb_value val; /* For all other types. */ } v; -} upb_map_entry; +} upb_MapEntry; /* Creates a new map on the given arena with this key/value type. */ -upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size); +upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size); /* Converting between internal table representation and user values. * @@ -554,15 +600,15 @@ upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size); * from other types when stored in a map. */ -UPB_INLINE upb_strview _upb_map_tokey(const void *key, size_t size) { +UPB_INLINE upb_StringView _upb_map_tokey(const void* key, size_t size) { if (size == UPB_MAPTYPE_STRING) { - return *(upb_strview*)key; + return *(upb_StringView*)key; } else { - return upb_strview_make((const char*)key, size); + return upb_StringView_FromDataAndSize((const char*)key, size); } } -UPB_INLINE void _upb_map_fromkey(upb_strview key, void* out, size_t size) { +UPB_INLINE void _upb_map_fromkey(upb_StringView key, void* out, size_t size) { if (size == UPB_MAPTYPE_STRING) { memcpy(out, &key, sizeof(key)); } else { @@ -570,12 +616,12 @@ UPB_INLINE void _upb_map_fromkey(upb_strview key, void* out, size_t size) { } } -UPB_INLINE bool _upb_map_tovalue(const void *val, size_t size, upb_value *msgval, - upb_arena *a) { +UPB_INLINE bool _upb_map_tovalue(const void* val, size_t size, + upb_value* msgval, upb_Arena* a) { if (size == UPB_MAPTYPE_STRING) { - upb_strview *strp = (upb_strview*)upb_arena_malloc(a, sizeof(*strp)); + upb_StringView* strp = (upb_StringView*)upb_Arena_Malloc(a, sizeof(*strp)); if (!strp) return false; - *strp = *(upb_strview*)val; + *strp = *(upb_StringView*)val; *msgval = upb_value_ptr(strp); } else { memcpy(msgval, val, size); @@ -585,8 +631,8 @@ UPB_INLINE bool _upb_map_tovalue(const void *val, size_t size, upb_value *msgval UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) { if (size == UPB_MAPTYPE_STRING) { - const upb_strview *strp = (const upb_strview*)upb_value_getptr(val); - memcpy(out, strp, sizeof(upb_strview)); + const upb_StringView* strp = (const upb_StringView*)upb_value_getptr(val); + memcpy(out, strp, sizeof(upb_StringView)); } else { memcpy(out, &val, size); } @@ -594,14 +640,14 @@ UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) { /* Map operations, shared by reflection and generated code. */ -UPB_INLINE size_t _upb_map_size(const upb_map *map) { +UPB_INLINE size_t _upb_Map_Size(const upb_Map* map) { return map->table.t.count; } -UPB_INLINE bool _upb_map_get(const upb_map *map, const void *key, - size_t key_size, void *val, size_t val_size) { +UPB_INLINE bool _upb_Map_Get(const upb_Map* map, const void* key, + size_t key_size, void* val, size_t val_size) { upb_value tabval; - upb_strview k = _upb_map_tokey(key, key_size); + upb_StringView k = _upb_map_tokey(key, key_size); bool ret = upb_strtable_lookup2(&map->table, k.data, k.size, &tabval); if (ret && val) { _upb_map_fromvalue(tabval, val, val_size); @@ -609,7 +655,7 @@ UPB_INLINE bool _upb_map_get(const upb_map *map, const void *key, return ret; } -UPB_INLINE void* _upb_map_next(const upb_map *map, size_t *iter) { +UPB_INLINE void* _upb_map_next(const upb_Map* map, size_t* iter) { upb_strtable_iter it; it.t = &map->table; it.index = *iter; @@ -619,108 +665,111 @@ UPB_INLINE void* _upb_map_next(const upb_map *map, size_t *iter) { return (void*)str_tabent(&it); } -UPB_INLINE bool _upb_map_set(upb_map *map, const void *key, size_t key_size, - void *val, size_t val_size, upb_arena *a) { - upb_strview strkey = _upb_map_tokey(key, key_size); +UPB_INLINE bool _upb_Map_Set(upb_Map* map, const void* key, size_t key_size, + void* val, size_t val_size, upb_Arena* a) { + upb_StringView strkey = _upb_map_tokey(key, key_size); upb_value tabval = {0}; if (!_upb_map_tovalue(val, val_size, &tabval, a)) return false; /* TODO(haberman): add overwrite operation to minimize number of lookups. */ - upb_strtable_remove(&map->table, strkey.data, strkey.size, NULL); + upb_strtable_remove2(&map->table, strkey.data, strkey.size, NULL); return upb_strtable_insert(&map->table, strkey.data, strkey.size, tabval, a); } -UPB_INLINE bool _upb_map_delete(upb_map *map, const void *key, size_t key_size) { - upb_strview k = _upb_map_tokey(key, key_size); - return upb_strtable_remove(&map->table, k.data, k.size, NULL); +UPB_INLINE bool _upb_Map_Delete(upb_Map* map, const void* key, + size_t key_size) { + upb_StringView k = _upb_map_tokey(key, key_size); + return upb_strtable_remove2(&map->table, k.data, k.size, NULL); } -UPB_INLINE void _upb_map_clear(upb_map *map) { +UPB_INLINE void _upb_Map_Clear(upb_Map* map) { upb_strtable_clear(&map->table); } /* Message map operations, these get the map from the message first. */ -UPB_INLINE size_t _upb_msg_map_size(const upb_msg *msg, size_t ofs) { - upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); - return map ? _upb_map_size(map) : 0; +UPB_INLINE size_t _upb_msg_map_size(const upb_Message* msg, size_t ofs) { + upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); + return map ? _upb_Map_Size(map) : 0; } -UPB_INLINE bool _upb_msg_map_get(const upb_msg *msg, size_t ofs, - const void *key, size_t key_size, void *val, +UPB_INLINE bool _upb_msg_map_get(const upb_Message* msg, size_t ofs, + const void* key, size_t key_size, void* val, size_t val_size) { - upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); if (!map) return false; - return _upb_map_get(map, key, key_size, val, val_size); + return _upb_Map_Get(map, key, key_size, val, val_size); } -UPB_INLINE void *_upb_msg_map_next(const upb_msg *msg, size_t ofs, - size_t *iter) { - upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); +UPB_INLINE void* _upb_msg_map_next(const upb_Message* msg, size_t ofs, + size_t* iter) { + upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); if (!map) return NULL; return _upb_map_next(map, iter); } -UPB_INLINE bool _upb_msg_map_set(upb_msg *msg, size_t ofs, const void *key, - size_t key_size, void *val, size_t val_size, - upb_arena *arena) { - upb_map **map = UPB_PTR_AT(msg, ofs, upb_map *); +UPB_INLINE bool _upb_msg_map_set(upb_Message* msg, size_t ofs, const void* key, + size_t key_size, void* val, size_t val_size, + upb_Arena* arena) { + upb_Map** map = UPB_PTR_AT(msg, ofs, upb_Map*); if (!*map) { - *map = _upb_map_new(arena, key_size, val_size); + *map = _upb_Map_New(arena, key_size, val_size); } - return _upb_map_set(*map, key, key_size, val, val_size, arena); + return _upb_Map_Set(*map, key, key_size, val, val_size, arena); } -UPB_INLINE bool _upb_msg_map_delete(upb_msg *msg, size_t ofs, const void *key, - size_t key_size) { - upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); +UPB_INLINE bool _upb_msg_map_delete(upb_Message* msg, size_t ofs, + const void* key, size_t key_size) { + upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); if (!map) return false; - return _upb_map_delete(map, key, key_size); + return _upb_Map_Delete(map, key, key_size); } -UPB_INLINE void _upb_msg_map_clear(upb_msg *msg, size_t ofs) { - upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); +UPB_INLINE void _upb_msg_map_clear(upb_Message* msg, size_t ofs) { + upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); if (!map) return; - _upb_map_clear(map); + _upb_Map_Clear(map); } /* Accessing map key/value from a pointer, used by generated code only. */ UPB_INLINE void _upb_msg_map_key(const void* msg, void* key, size_t size) { - const upb_tabent *ent = (const upb_tabent*)msg; + const upb_tabent* ent = (const upb_tabent*)msg; uint32_t u32len; - upb_strview k; + upb_StringView k; k.data = upb_tabstr(ent->key, &u32len); k.size = u32len; _upb_map_fromkey(k, key, size); } UPB_INLINE void _upb_msg_map_value(const void* msg, void* val, size_t size) { - const upb_tabent *ent = (const upb_tabent*)msg; + const upb_tabent* ent = (const upb_tabent*)msg; upb_value v = {ent->val.val}; _upb_map_fromvalue(v, val, size); } -UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, size_t size) { - upb_tabent *ent = (upb_tabent*)msg; +UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, + size_t size) { + upb_tabent* ent = (upb_tabent*)msg; /* This is like _upb_map_tovalue() except the entry already exists so we can - * reuse the allocated upb_strview for string fields. */ + * reuse the allocated upb_StringView for string fields. */ if (size == UPB_MAPTYPE_STRING) { - upb_strview *strp = (upb_strview*)(uintptr_t)ent->val.val; + upb_StringView* strp = (upb_StringView*)(uintptr_t)ent->val.val; memcpy(strp, val, sizeof(*strp)); } else { memcpy(&ent->val.val, val, size); } } -/** _upb_mapsorter *************************************************************/ +/** _upb_mapsorter + * *************************************************************/ /* _upb_mapsorter sorts maps and provides ordered iteration over the entries. - * Since maps can be recursive (map values can be messages which contain other maps). - * _upb_mapsorter can contain a stack of maps. */ + * Since maps can be recursive (map values can be messages which contain other + * maps). _upb_mapsorter can contain a stack of maps. */ typedef struct { - upb_tabent const**entries; + upb_tabent const** entries; int size; int cap; } _upb_mapsorter; @@ -731,29 +780,29 @@ typedef struct { int end; } _upb_sortedmap; -UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter *s) { +UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter* s) { s->entries = NULL; s->size = 0; s->cap = 0; } -UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter *s) { +UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter* s) { if (s->entries) free(s->entries); } -bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, - const upb_map *map, _upb_sortedmap *sorted); +bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, + const upb_Map* map, _upb_sortedmap* sorted); -UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter *s, _upb_sortedmap *sorted) { +UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter* s, + _upb_sortedmap* sorted) { s->size = sorted->start; } -UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter *s, const upb_map *map, - _upb_sortedmap *sorted, - upb_map_entry *ent) { +UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter* s, const upb_Map* map, + _upb_sortedmap* sorted, upb_MapEntry* ent) { if (sorted->pos == sorted->end) return false; - const upb_tabent *tabent = s->entries[sorted->pos++]; - upb_strview key = upb_tabstrview(tabent->key); + const upb_tabent* tabent = s->entries[sorted->pos++]; + upb_StringView key = upb_tabstrview(tabent->key); _upb_map_fromkey(key, &ent->k, map->key_size); upb_value val = {tabent->val.val}; _upb_map_fromvalue(val, &ent->v, map->val_size); @@ -761,7 +810,7 @@ UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter *s, const upb_map *map, } #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif #include "upb/port_undef.inc" diff --git a/contrib/libs/grpc/third_party/upb/upb/reflection.c b/contrib/libs/grpc/third_party/upb/upb/reflection.c index 2c3e7e8eea..a3a64d2780 100644 --- a/contrib/libs/grpc/third_party/upb/upb/reflection.c +++ b/contrib/libs/grpc/third_party/upb/upb/reflection.c @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -28,178 +28,187 @@ #include "upb/reflection.h" #include <string.h> -#include "upb/table_internal.h" -#include "upb/msg.h" +#include "upb/msg.h" #include "upb/port_def.inc" +#include "upb/table_internal.h" -static size_t get_field_size(const upb_msglayout_field *f) { +static size_t get_field_size(const upb_MiniTable_Field* f) { static unsigned char sizes[] = { - 0,/* 0 */ - 8, /* UPB_DESCRIPTOR_TYPE_DOUBLE */ - 4, /* UPB_DESCRIPTOR_TYPE_FLOAT */ - 8, /* UPB_DESCRIPTOR_TYPE_INT64 */ - 8, /* UPB_DESCRIPTOR_TYPE_UINT64 */ - 4, /* UPB_DESCRIPTOR_TYPE_INT32 */ - 8, /* UPB_DESCRIPTOR_TYPE_FIXED64 */ - 4, /* UPB_DESCRIPTOR_TYPE_FIXED32 */ - 1, /* UPB_DESCRIPTOR_TYPE_BOOL */ - sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING */ - sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP */ - sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE */ - sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES */ - 4, /* UPB_DESCRIPTOR_TYPE_UINT32 */ - 4, /* UPB_DESCRIPTOR_TYPE_ENUM */ - 4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 */ - 8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 */ - 4, /* UPB_DESCRIPTOR_TYPE_SINT32 */ - 8, /* UPB_DESCRIPTOR_TYPE_SINT64 */ + 0, /* 0 */ + 8, /* kUpb_FieldType_Double */ + 4, /* kUpb_FieldType_Float */ + 8, /* kUpb_FieldType_Int64 */ + 8, /* kUpb_FieldType_UInt64 */ + 4, /* kUpb_FieldType_Int32 */ + 8, /* kUpb_FieldType_Fixed64 */ + 4, /* kUpb_FieldType_Fixed32 */ + 1, /* kUpb_FieldType_Bool */ + sizeof(upb_StringView), /* kUpb_FieldType_String */ + sizeof(void*), /* kUpb_FieldType_Group */ + sizeof(void*), /* kUpb_FieldType_Message */ + sizeof(upb_StringView), /* kUpb_FieldType_Bytes */ + 4, /* kUpb_FieldType_UInt32 */ + 4, /* kUpb_FieldType_Enum */ + 4, /* kUpb_FieldType_SFixed32 */ + 8, /* kUpb_FieldType_SFixed64 */ + 4, /* kUpb_FieldType_SInt32 */ + 8, /* kUpb_FieldType_SInt64 */ }; - return _upb_repeated_or_map(f) ? sizeof(void *) : sizes[f->descriptortype]; + return upb_IsRepeatedOrMap(f) ? sizeof(void*) : sizes[f->descriptortype]; } /* Strings/bytes are special-cased in maps. */ -static char _upb_fieldtype_to_mapsize[12] = { - 0, - 1, /* UPB_TYPE_BOOL */ - 4, /* UPB_TYPE_FLOAT */ - 4, /* UPB_TYPE_INT32 */ - 4, /* UPB_TYPE_UINT32 */ - 4, /* UPB_TYPE_ENUM */ - sizeof(void*), /* UPB_TYPE_MESSAGE */ - 8, /* UPB_TYPE_DOUBLE */ - 8, /* UPB_TYPE_INT64 */ - 8, /* UPB_TYPE_UINT64 */ - 0, /* UPB_TYPE_STRING */ - 0, /* UPB_TYPE_BYTES */ +static char _upb_CTypeo_mapsize[12] = { + 0, + 1, /* kUpb_CType_Bool */ + 4, /* kUpb_CType_Float */ + 4, /* kUpb_CType_Int32 */ + 4, /* kUpb_CType_UInt32 */ + 4, /* kUpb_CType_Enum */ + sizeof(void*), /* kUpb_CType_Message */ + 8, /* kUpb_CType_Double */ + 8, /* kUpb_CType_Int64 */ + 8, /* kUpb_CType_UInt64 */ + 0, /* kUpb_CType_String */ + 0, /* kUpb_CType_Bytes */ }; -static const char _upb_fieldtype_to_sizelg2[12] = { - 0, - 0, /* UPB_TYPE_BOOL */ - 2, /* UPB_TYPE_FLOAT */ - 2, /* UPB_TYPE_INT32 */ - 2, /* UPB_TYPE_UINT32 */ - 2, /* UPB_TYPE_ENUM */ - UPB_SIZE(2, 3), /* UPB_TYPE_MESSAGE */ - 3, /* UPB_TYPE_DOUBLE */ - 3, /* UPB_TYPE_INT64 */ - 3, /* UPB_TYPE_UINT64 */ - UPB_SIZE(3, 4), /* UPB_TYPE_STRING */ - UPB_SIZE(3, 4), /* UPB_TYPE_BYTES */ +static const char _upb_CTypeo_sizelg2[12] = { + 0, + 0, /* kUpb_CType_Bool */ + 2, /* kUpb_CType_Float */ + 2, /* kUpb_CType_Int32 */ + 2, /* kUpb_CType_UInt32 */ + 2, /* kUpb_CType_Enum */ + UPB_SIZE(2, 3), /* kUpb_CType_Message */ + 3, /* kUpb_CType_Double */ + 3, /* kUpb_CType_Int64 */ + 3, /* kUpb_CType_UInt64 */ + UPB_SIZE(3, 4), /* kUpb_CType_String */ + UPB_SIZE(3, 4), /* kUpb_CType_Bytes */ }; -/** upb_msg *******************************************************************/ +/** upb_Message + * *******************************************************************/ -upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) { - return _upb_msg_new(upb_msgdef_layout(m), a); +upb_Message* upb_Message_New(const upb_MessageDef* m, upb_Arena* a) { + return _upb_Message_New(upb_MessageDef_MiniTable(m), a); } -static bool in_oneof(const upb_msglayout_field *field) { +static bool in_oneof(const upb_MiniTable_Field* field) { return field->presence < 0; } -static upb_msgval _upb_msg_getraw(const upb_msg *msg, const upb_fielddef *f) { - const upb_msglayout_field *field = upb_fielddef_layout(f); - const char *mem = UPB_PTR_AT(msg, field->offset, char); - upb_msgval val = {0}; +static upb_MessageValue _upb_Message_Getraw(const upb_Message* msg, + const upb_FieldDef* f) { + const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f); + const char* mem = UPB_PTR_AT(msg, field->offset, char); + upb_MessageValue val = {0}; memcpy(&val, mem, get_field_size(field)); return val; } -bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) { - if (upb_fielddef_isextension(f)) { - const upb_msglayout_ext *ext = _upb_fielddef_extlayout(f); - return _upb_msg_getext(msg, ext) != NULL; +bool upb_Message_Has(const upb_Message* msg, const upb_FieldDef* f) { + assert(upb_FieldDef_HasPresence(f)); + if (upb_FieldDef_IsExtension(f)) { + const upb_MiniTable_Extension* ext = _upb_FieldDef_ExtensionMiniTable(f); + return _upb_Message_Getext(msg, ext) != NULL; } else { - const upb_msglayout_field *field = upb_fielddef_layout(f); + const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f); if (in_oneof(field)) { return _upb_getoneofcase_field(msg, field) == field->number; } else if (field->presence > 0) { return _upb_hasbit_field(msg, field); } else { - UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE || - field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP); - return _upb_msg_getraw(msg, f).msg_val != NULL; + UPB_ASSERT(field->descriptortype == kUpb_FieldType_Message || + field->descriptortype == kUpb_FieldType_Group); + return _upb_Message_Getraw(msg, f).msg_val != NULL; } } } -const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg, - const upb_oneofdef *o) { - const upb_fielddef *f = upb_oneofdef_field(o, 0); - if (upb_oneofdef_issynthetic(o)) { - UPB_ASSERT(upb_oneofdef_fieldcount(o) == 1); - return upb_msg_has(msg, f) ? f : NULL; +const upb_FieldDef* upb_Message_WhichOneof(const upb_Message* msg, + const upb_OneofDef* o) { + const upb_FieldDef* f = upb_OneofDef_Field(o, 0); + if (upb_OneofDef_IsSynthetic(o)) { + UPB_ASSERT(upb_OneofDef_FieldCount(o) == 1); + return upb_Message_Has(msg, f) ? f : NULL; } else { - const upb_msglayout_field *field = upb_fielddef_layout(f); + const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f); uint32_t oneof_case = _upb_getoneofcase_field(msg, field); - f = oneof_case ? upb_oneofdef_itof(o, oneof_case) : NULL; + f = oneof_case ? upb_OneofDef_LookupNumber(o, oneof_case) : NULL; UPB_ASSERT((f != NULL) == (oneof_case != 0)); return f; } } -upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) { - if (upb_fielddef_isextension(f)) { - const upb_msg_ext *ext = _upb_msg_getext(msg, _upb_fielddef_extlayout(f)); +upb_MessageValue upb_Message_Get(const upb_Message* msg, + const upb_FieldDef* f) { + if (upb_FieldDef_IsExtension(f)) { + const upb_Message_Extension* ext = + _upb_Message_Getext(msg, _upb_FieldDef_ExtensionMiniTable(f)); if (ext) { - upb_msgval val; + upb_MessageValue val; memcpy(&val, &ext->data, sizeof(val)); return val; - } else if (upb_fielddef_isseq(f)) { - return (upb_msgval){.array_val = NULL}; + } else if (upb_FieldDef_IsRepeated(f)) { + return (upb_MessageValue){.array_val = NULL}; } - } else if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) { - return _upb_msg_getraw(msg, f); + } else if (!upb_FieldDef_HasPresence(f) || upb_Message_Has(msg, f)) { + return _upb_Message_Getraw(msg, f); } - return upb_fielddef_default(f); + return upb_FieldDef_Default(f); } -upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f, - upb_arena *a) { - UPB_ASSERT(upb_fielddef_issubmsg(f) || upb_fielddef_isseq(f)); - if (upb_fielddef_haspresence(f) && !upb_msg_has(msg, f)) { - // We need to skip the upb_msg_get() call in this case. +upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, + const upb_FieldDef* f, + upb_Arena* a) { + UPB_ASSERT(upb_FieldDef_IsSubMessage(f) || upb_FieldDef_IsRepeated(f)); + if (upb_FieldDef_HasPresence(f) && !upb_Message_Has(msg, f)) { + // We need to skip the upb_Message_Get() call in this case. goto make; } - upb_msgval val = upb_msg_get(msg, f); + upb_MessageValue val = upb_Message_Get(msg, f); if (val.array_val) { - return (upb_mutmsgval){.array = (upb_array*)val.array_val}; + return (upb_MutableMessageValue){.array = (upb_Array*)val.array_val}; } - upb_mutmsgval ret; + upb_MutableMessageValue ret; make: - if (!a) return (upb_mutmsgval){.array = NULL}; - if (upb_fielddef_ismap(f)) { - const upb_msgdef *entry = upb_fielddef_msgsubdef(f); - const upb_fielddef *key = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY); - const upb_fielddef *value = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE); - ret.map = upb_map_new(a, upb_fielddef_type(key), upb_fielddef_type(value)); - } else if (upb_fielddef_isseq(f)) { - ret.array = upb_array_new(a, upb_fielddef_type(f)); + if (!a) return (upb_MutableMessageValue){.array = NULL}; + if (upb_FieldDef_IsMap(f)) { + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key = + upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_KeyFieldNumber); + const upb_FieldDef* value = + upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_ValueFieldNumber); + ret.map = + upb_Map_New(a, upb_FieldDef_CType(key), upb_FieldDef_CType(value)); + } else if (upb_FieldDef_IsRepeated(f)) { + ret.array = upb_Array_New(a, upb_FieldDef_CType(f)); } else { - UPB_ASSERT(upb_fielddef_issubmsg(f)); - ret.msg = upb_msg_new(upb_fielddef_msgsubdef(f), a); + UPB_ASSERT(upb_FieldDef_IsSubMessage(f)); + ret.msg = upb_Message_New(upb_FieldDef_MessageSubDef(f), a); } val.array_val = ret.array; - upb_msg_set(msg, f, val, a); + upb_Message_Set(msg, f, val, a); return ret; } -bool upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val, - upb_arena *a) { - if (upb_fielddef_isextension(f)) { - upb_msg_ext *ext = - _upb_msg_getorcreateext(msg, _upb_fielddef_extlayout(f), a); +bool upb_Message_Set(upb_Message* msg, const upb_FieldDef* f, + upb_MessageValue val, upb_Arena* a) { + if (upb_FieldDef_IsExtension(f)) { + upb_Message_Extension* ext = _upb_Message_Getorcreateext( + msg, _upb_FieldDef_ExtensionMiniTable(f), a); if (!ext) return false; memcpy(&ext->data, &val, sizeof(val)); } else { - const upb_msglayout_field *field = upb_fielddef_layout(f); - char *mem = UPB_PTR_AT(msg, field->offset, char); + const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f); + char* mem = UPB_PTR_AT(msg, field->offset, char); memcpy(mem, &val, get_field_size(field)); if (field->presence > 0) { _upb_sethas_field(msg, field); @@ -210,17 +219,17 @@ bool upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val, return true; } -void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f) { - if (upb_fielddef_isextension(f)) { - _upb_msg_clearext(msg, _upb_fielddef_extlayout(f)); +void upb_Message_ClearField(upb_Message* msg, const upb_FieldDef* f) { + if (upb_FieldDef_IsExtension(f)) { + _upb_Message_Clearext(msg, _upb_FieldDef_ExtensionMiniTable(f)); } else { - const upb_msglayout_field *field = upb_fielddef_layout(f); - char *mem = UPB_PTR_AT(msg, field->offset, char); + const upb_MiniTable_Field* field = upb_FieldDef_MiniTable(f); + char* mem = UPB_PTR_AT(msg, field->offset, char); if (field->presence > 0) { _upb_clearhas_field(msg, field); } else if (in_oneof(field)) { - uint32_t *oneof_case = _upb_oneofcase_field(msg, field); + uint32_t* oneof_case = _upb_oneofcase_field(msg, field); if (*oneof_case != field->number) return; *oneof_case = 0; } @@ -229,29 +238,29 @@ void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f) { } } -void upb_msg_clear(upb_msg *msg, const upb_msgdef *m) { - _upb_msg_clear(msg, upb_msgdef_layout(m)); +void upb_Message_Clear(upb_Message* msg, const upb_MessageDef* m) { + _upb_Message_Clear(msg, upb_MessageDef_MiniTable(m)); } -bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, - const upb_symtab *ext_pool, const upb_fielddef **out_f, - upb_msgval *out_val, size_t *iter) { +bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, const upb_FieldDef** out_f, + upb_MessageValue* out_val, size_t* iter) { size_t i = *iter; - size_t n = upb_msgdef_fieldcount(m); - const upb_msgval zero = {0}; + size_t n = upb_MessageDef_FieldCount(m); + const upb_MessageValue zero = {0}; UPB_UNUSED(ext_pool); /* Iterate over normal fields, returning the first one that is set. */ while (++i < n) { - const upb_fielddef *f = upb_msgdef_field(m, i); - upb_msgval val = _upb_msg_getraw(msg, f); + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + upb_MessageValue val = _upb_Message_Getraw(msg, f); /* Skip field if unset or empty. */ - if (upb_fielddef_haspresence(f)) { - if (!upb_msg_has(msg, f)) continue; + if (upb_FieldDef_HasPresence(f)) { + if (!upb_Message_Has(msg, f)) continue; } else { - upb_msgval test = val; - if (upb_fielddef_isstring(f) && !upb_fielddef_isseq(f)) { + upb_MessageValue test = val; + if (upb_FieldDef_IsString(f) && !upb_FieldDef_IsRepeated(f)) { /* Clear string pointer, only size matters (ptr could be non-NULL). */ test.str_val.data = NULL; } @@ -259,10 +268,10 @@ bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, if (memcmp(&test, &zero, sizeof(test)) == 0) continue; /* Continue on empty array or map. */ - if (upb_fielddef_ismap(f)) { - if (upb_map_size(test.map_val) == 0) continue; - } else if (upb_fielddef_isseq(f)) { - if (upb_array_size(test.array_val) == 0) continue; + if (upb_FieldDef_IsMap(f)) { + if (upb_Map_Size(test.map_val) == 0) continue; + } else if (upb_FieldDef_IsRepeated(f)) { + if (upb_Array_Size(test.array_val) == 0) continue; } } @@ -275,11 +284,11 @@ bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, if (ext_pool) { /* Return any extensions that are set. */ size_t count; - const upb_msg_ext *ext = _upb_msg_getexts(msg, &count); + const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &count); if (i - n < count) { ext += count - 1 - (i - n); memcpy(out_val, &ext->data, sizeof(*out_val)); - *out_f = _upb_symtab_lookupextfield(ext_pool, ext->ext); + *out_f = _upb_DefPool_FindExtensionByMiniTable(ext_pool, ext->ext); *iter = i; return true; } @@ -289,44 +298,48 @@ bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, return false; } -bool _upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int depth) { - size_t iter = UPB_MSG_BEGIN; - const upb_fielddef *f; - upb_msgval val; +bool _upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, + int depth) { + size_t iter = kUpb_Message_Begin; + const upb_FieldDef* f; + upb_MessageValue val; bool ret = true; if (--depth == 0) return false; - _upb_msg_discardunknown_shallow(msg); + _upb_Message_DiscardUnknown_shallow(msg); - while (upb_msg_next(msg, m, NULL /*ext_pool*/, &f, &val, &iter)) { - const upb_msgdef *subm = upb_fielddef_msgsubdef(f); + while (upb_Message_Next(msg, m, NULL /*ext_pool*/, &f, &val, &iter)) { + const upb_MessageDef* subm = upb_FieldDef_MessageSubDef(f); if (!subm) continue; - if (upb_fielddef_ismap(f)) { - const upb_fielddef *val_f = upb_msgdef_itof(subm, 2); - const upb_msgdef *val_m = upb_fielddef_msgsubdef(val_f); - upb_map *map = (upb_map*)val.map_val; - size_t iter = UPB_MAP_BEGIN; + if (upb_FieldDef_IsMap(f)) { + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(subm, 2); + const upb_MessageDef* val_m = upb_FieldDef_MessageSubDef(val_f); + upb_Map* map = (upb_Map*)val.map_val; + size_t iter = kUpb_Map_Begin; if (!val_m) continue; - while (upb_mapiter_next(map, &iter)) { - upb_msgval map_val = upb_mapiter_value(map, iter); - if (!_upb_msg_discardunknown((upb_msg*)map_val.msg_val, val_m, depth)) { + while (upb_MapIterator_Next(map, &iter)) { + upb_MessageValue map_val = upb_MapIterator_Value(map, iter); + if (!_upb_Message_DiscardUnknown((upb_Message*)map_val.msg_val, val_m, + depth)) { ret = false; } } - } else if (upb_fielddef_isseq(f)) { - const upb_array *arr = val.array_val; - size_t i, n = upb_array_size(arr); + } else if (upb_FieldDef_IsRepeated(f)) { + const upb_Array* arr = val.array_val; + size_t i, n = upb_Array_Size(arr); for (i = 0; i < n; i++) { - upb_msgval elem = upb_array_get(arr, i); - if (!_upb_msg_discardunknown((upb_msg*)elem.msg_val, subm, depth)) { + upb_MessageValue elem = upb_Array_Get(arr, i); + if (!_upb_Message_DiscardUnknown((upb_Message*)elem.msg_val, subm, + depth)) { ret = false; } } } else { - if (!_upb_msg_discardunknown((upb_msg*)val.msg_val, subm, depth)) { + if (!_upb_Message_DiscardUnknown((upb_Message*)val.msg_val, subm, + depth)) { ret = false; } } @@ -335,22 +348,21 @@ bool _upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int depth) { return ret; } -bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth) { - return _upb_msg_discardunknown(msg, m, maxdepth); +bool upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, + int maxdepth) { + return _upb_Message_DiscardUnknown(msg, m, maxdepth); } -/** upb_array *****************************************************************/ +/** upb_Array *****************************************************************/ -upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type) { - return _upb_array_new(a, 4, _upb_fieldtype_to_sizelg2[type]); +upb_Array* upb_Array_New(upb_Arena* a, upb_CType type) { + return _upb_Array_New(a, 4, _upb_CTypeo_sizelg2[type]); } -size_t upb_array_size(const upb_array *arr) { - return arr->len; -} +size_t upb_Array_Size(const upb_Array* arr) { return arr->len; } -upb_msgval upb_array_get(const upb_array *arr, size_t i) { - upb_msgval ret; +upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i) { + upb_MessageValue ret; const char* data = _upb_array_constptr(arr); int lg2 = arr->data & 7; UPB_ASSERT(i < arr->len); @@ -358,83 +370,111 @@ upb_msgval upb_array_get(const upb_array *arr, size_t i) { return ret; } -void upb_array_set(upb_array *arr, size_t i, upb_msgval val) { +void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue val) { char* data = _upb_array_ptr(arr); int lg2 = arr->data & 7; UPB_ASSERT(i < arr->len); memcpy(data + (i << lg2), &val, 1 << lg2); } -bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) { - if (!upb_array_resize(arr, arr->len + 1, arena)) { +bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) { + if (!upb_Array_Resize(arr, arr->len + 1, arena)) { return false; } - upb_array_set(arr, arr->len - 1, val); + upb_Array_Set(arr, arr->len - 1, val); return true; } -bool upb_array_resize(upb_array *arr, size_t size, upb_arena *arena) { - return _upb_array_resize(arr, size, arena); +void upb_Array_Move(upb_Array* arr, size_t dst_idx, size_t src_idx, + size_t count) { + char* data = _upb_array_ptr(arr); + int lg2 = arr->data & 7; + memmove(&data[dst_idx << lg2], &data[src_idx << lg2], count << lg2); } -/** upb_map *******************************************************************/ +bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count, + upb_Arena* arena) { + UPB_ASSERT(i <= arr->len); + UPB_ASSERT(count + arr->len >= count); + size_t oldsize = arr->len; + if (!upb_Array_Resize(arr, arr->len + count, arena)) { + return false; + } + upb_Array_Move(arr, i + count, i, oldsize - i); + return true; +} -upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type, - upb_fieldtype_t value_type) { - return _upb_map_new(a, _upb_fieldtype_to_mapsize[key_type], - _upb_fieldtype_to_mapsize[value_type]); +/* + * i end arr->len + * |------------|XXXXXXXX|--------| + */ +void upb_Array_Delete(upb_Array* arr, size_t i, size_t count) { + size_t end = i + count; + UPB_ASSERT(i <= end); + UPB_ASSERT(end <= arr->len); + upb_Array_Move(arr, i, end, arr->len - end); + arr->len -= count; } -size_t upb_map_size(const upb_map *map) { - return _upb_map_size(map); +bool upb_Array_Resize(upb_Array* arr, size_t size, upb_Arena* arena) { + return _upb_Array_Resize(arr, size, arena); } -bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) { - return _upb_map_get(map, &key, map->key_size, val, map->val_size); +/** upb_Map *******************************************************************/ + +upb_Map* upb_Map_New(upb_Arena* a, upb_CType key_type, upb_CType value_type) { + return _upb_Map_New(a, _upb_CTypeo_mapsize[key_type], + _upb_CTypeo_mapsize[value_type]); } -void upb_map_clear(upb_map *map) { - _upb_map_clear(map); +size_t upb_Map_Size(const upb_Map* map) { return _upb_Map_Size(map); } + +bool upb_Map_Get(const upb_Map* map, upb_MessageValue key, + upb_MessageValue* val) { + return _upb_Map_Get(map, &key, map->key_size, val, map->val_size); } -bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val, - upb_arena *arena) { - return _upb_map_set(map, &key, map->key_size, &val, map->val_size, arena); +void upb_Map_Clear(upb_Map* map) { _upb_Map_Clear(map); } + +bool upb_Map_Set(upb_Map* map, upb_MessageValue key, upb_MessageValue val, + upb_Arena* arena) { + return _upb_Map_Set(map, &key, map->key_size, &val, map->val_size, arena); } -bool upb_map_delete(upb_map *map, upb_msgval key) { - return _upb_map_delete(map, &key, map->key_size); +bool upb_Map_Delete(upb_Map* map, upb_MessageValue key) { + return _upb_Map_Delete(map, &key, map->key_size); } -bool upb_mapiter_next(const upb_map *map, size_t *iter) { +bool upb_MapIterator_Next(const upb_Map* map, size_t* iter) { return _upb_map_next(map, iter); } -bool upb_mapiter_done(const upb_map *map, size_t iter) { +bool upb_MapIterator_Done(const upb_Map* map, size_t iter) { upb_strtable_iter i; - UPB_ASSERT(iter != UPB_MAP_BEGIN); + UPB_ASSERT(iter != kUpb_Map_Begin); i.t = &map->table; i.index = iter; return upb_strtable_done(&i); } /* Returns the key and value for this entry of the map. */ -upb_msgval upb_mapiter_key(const upb_map *map, size_t iter) { +upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter) { upb_strtable_iter i; - upb_msgval ret; + upb_MessageValue ret; i.t = &map->table; i.index = iter; _upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size); return ret; } -upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) { +upb_MessageValue upb_MapIterator_Value(const upb_Map* map, size_t iter) { upb_strtable_iter i; - upb_msgval ret; + upb_MessageValue ret; i.t = &map->table; i.index = iter; _upb_map_fromvalue(upb_strtable_iter_value(&i), &ret, map->val_size); return ret; } -/* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */ +/* void upb_MapIterator_SetValue(upb_Map *map, size_t iter, upb_MessageValue + * value); */ diff --git a/contrib/libs/grpc/third_party/upb/upb/reflection.h b/contrib/libs/grpc/third_party/upb/upb/reflection.h index 3c99ff1c4b..b892f66bfb 100644 --- a/contrib/libs/grpc/third_party/upb/upb/reflection.h +++ b/contrib/libs/grpc/third_party/upb/upb/reflection.h @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -30,9 +30,8 @@ #include "upb/def.h" #include "upb/msg.h" -#include "upb/upb.h" - #include "upb/port_def.inc" +#include "upb/upb.h" #ifdef __cplusplus extern "C" { @@ -46,61 +45,63 @@ typedef union { int64_t int64_val; uint32_t uint32_val; uint64_t uint64_val; - const upb_map* map_val; - const upb_msg* msg_val; - const upb_array* array_val; - upb_strview str_val; -} upb_msgval; + const upb_Map* map_val; + const upb_Message* msg_val; + const upb_Array* array_val; + upb_StringView str_val; +} upb_MessageValue; typedef union { - upb_map* map; - upb_msg* msg; - upb_array* array; -} upb_mutmsgval; + upb_Map* map; + upb_Message* msg; + upb_Array* array; +} upb_MutableMessageValue; -upb_msgval upb_fielddef_default(const upb_fielddef *f); +upb_MessageValue upb_FieldDef_Default(const upb_FieldDef* f); -/** upb_msg *******************************************************************/ +/** upb_Message + * *******************************************************************/ /* Creates a new message of the given type in the given arena. */ -upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a); +upb_Message* upb_Message_New(const upb_MessageDef* m, upb_Arena* a); /* Returns the value associated with this field. */ -upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f); +upb_MessageValue upb_Message_Get(const upb_Message* msg, const upb_FieldDef* f); /* Returns a mutable pointer to a map, array, or submessage value. If the given * arena is non-NULL this will construct a new object if it was not previously * present. May not be called for primitive fields. */ -upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f, upb_arena *a); +upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, + const upb_FieldDef* f, + upb_Arena* a); -/* May only be called for fields where upb_fielddef_haspresence(f) == true. */ -bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f); +/* May only be called for fields where upb_FieldDef_HasPresence(f) == true. */ +bool upb_Message_Has(const upb_Message* msg, const upb_FieldDef* f); /* Returns the field that is set in the oneof, or NULL if none are set. */ -const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg, - const upb_oneofdef *o); +const upb_FieldDef* upb_Message_WhichOneof(const upb_Message* msg, + const upb_OneofDef* o); /* Sets the given field to the given value. For a msg/array/map/string, the * caller must ensure that the target data outlives |msg| (by living either in * the same arena or a different arena that outlives it). * * Returns false if allocation fails. */ -bool upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val, - upb_arena *a); - +bool upb_Message_Set(upb_Message* msg, const upb_FieldDef* f, + upb_MessageValue val, upb_Arena* a); /* Clears any field presence and sets the value back to its default. */ -void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f); +void upb_Message_ClearField(upb_Message* msg, const upb_FieldDef* f); /* Clear all data and unknown fields. */ -void upb_msg_clear(upb_msg *msg, const upb_msgdef *m); +void upb_Message_Clear(upb_Message* msg, const upb_MessageDef* m); /* Iterate over present fields. * - * size_t iter = UPB_MSG_BEGIN; - * const upb_fielddef *f; - * upb_msgval val; - * while (upb_msg_next(msg, m, ext_pool, &f, &val, &iter)) { + * size_t iter = kUpb_Message_Begin; + * const upb_FieldDef *f; + * upb_MessageValue val; + * while (upb_Message_Next(msg, m, ext_pool, &f, &val, &iter)) { * process_field(f, val); * } * @@ -109,90 +110,109 @@ void upb_msg_clear(upb_msg *msg, const upb_msgdef *m); * will be skipped. */ -#define UPB_MSG_BEGIN -1 -bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, - const upb_symtab *ext_pool, const upb_fielddef **f, - upb_msgval *val, size_t *iter); +#define kUpb_Message_Begin -1 +bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, const upb_FieldDef** f, + upb_MessageValue* val, size_t* iter); /* Clears all unknown field data from this message and all submessages. */ -bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth); +bool upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, + int maxdepth); -/** upb_array *****************************************************************/ +/** upb_Array *****************************************************************/ /* Creates a new array on the given arena that holds elements of this type. */ -upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type); +upb_Array* upb_Array_New(upb_Arena* a, upb_CType type); /* Returns the size of the array. */ -size_t upb_array_size(const upb_array *arr); +size_t upb_Array_Size(const upb_Array* arr); /* Returns the given element, which must be within the array's current size. */ -upb_msgval upb_array_get(const upb_array *arr, size_t i); +upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i); /* Sets the given element, which must be within the array's current size. */ -void upb_array_set(upb_array *arr, size_t i, upb_msgval val); +void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue val); /* Appends an element to the array. Returns false on allocation failure. */ -bool upb_array_append(upb_array *array, upb_msgval val, upb_arena *arena); +bool upb_Array_Append(upb_Array* array, upb_MessageValue val, upb_Arena* arena); + +/* Moves elements within the array using memmove(). Like memmove(), the source + * and destination elements may be overlapping. */ +void upb_Array_Move(upb_Array* array, size_t dst_idx, size_t src_idx, + size_t count); + +/* Inserts one or more empty elements into the array. Existing elements are + * shifted right. The new elements have undefined state and must be set with + * `upb_Array_Set()`. + * REQUIRES: `i <= upb_Array_Size(arr)` */ +bool upb_Array_Insert(upb_Array* array, size_t i, size_t count, + upb_Arena* arena); + +/* Deletes one or more elements from the array. Existing elements are shifted + * left. + * REQUIRES: `i + count <= upb_Array_Size(arr)` */ +void upb_Array_Delete(upb_Array* array, size_t i, size_t count); /* Changes the size of a vector. New elements are initialized to empty/0. * Returns false on allocation failure. */ -bool upb_array_resize(upb_array *array, size_t size, upb_arena *arena); +bool upb_Array_Resize(upb_Array* array, size_t size, upb_Arena* arena); -/** upb_map *******************************************************************/ +/** upb_Map *******************************************************************/ /* Creates a new map on the given arena with the given key/value size. */ -upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type, - upb_fieldtype_t value_type); +upb_Map* upb_Map_New(upb_Arena* a, upb_CType key_type, upb_CType value_type); /* Returns the number of entries in the map. */ -size_t upb_map_size(const upb_map *map); +size_t upb_Map_Size(const upb_Map* map); /* Stores a value for the given key into |*val| (or the zero value if the key is * not present). Returns whether the key was present. The |val| pointer may be * NULL, in which case the function tests whether the given key is present. */ -bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val); +bool upb_Map_Get(const upb_Map* map, upb_MessageValue key, + upb_MessageValue* val); /* Removes all entries in the map. */ -void upb_map_clear(upb_map *map); +void upb_Map_Clear(upb_Map* map); /* Sets the given key to the given value. Returns true if this was a new key in * the map, or false if an existing key was replaced. */ -bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val, - upb_arena *arena); +bool upb_Map_Set(upb_Map* map, upb_MessageValue key, upb_MessageValue val, + upb_Arena* arena); /* Deletes this key from the table. Returns true if the key was present. */ -bool upb_map_delete(upb_map *map, upb_msgval key); +bool upb_Map_Delete(upb_Map* map, upb_MessageValue key); /* Map iteration: * - * size_t iter = UPB_MAP_BEGIN; - * while (upb_mapiter_next(map, &iter)) { - * upb_msgval key = upb_mapiter_key(map, iter); - * upb_msgval val = upb_mapiter_value(map, iter); + * size_t iter = kUpb_Map_Begin; + * while (upb_MapIterator_Next(map, &iter)) { + * upb_MessageValue key = upb_MapIterator_Key(map, iter); + * upb_MessageValue val = upb_MapIterator_Value(map, iter); * * // If mutating is desired. - * upb_mapiter_setvalue(map, iter, value2); + * upb_MapIterator_SetValue(map, iter, value2); * } */ /* Advances to the next entry. Returns false if no more entries are present. */ -bool upb_mapiter_next(const upb_map *map, size_t *iter); +bool upb_MapIterator_Next(const upb_Map* map, size_t* iter); /* Returns true if the iterator still points to a valid entry, or false if the * iterator is past the last element. It is an error to call this function with - * UPB_MAP_BEGIN (you must call next() at least once first). */ -bool upb_mapiter_done(const upb_map *map, size_t iter); + * kUpb_Map_Begin (you must call next() at least once first). */ +bool upb_MapIterator_Done(const upb_Map* map, size_t iter); /* Returns the key and value for this entry of the map. */ -upb_msgval upb_mapiter_key(const upb_map *map, size_t iter); -upb_msgval upb_mapiter_value(const upb_map *map, size_t iter); +upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter); +upb_MessageValue upb_MapIterator_Value(const upb_Map* map, size_t iter); /* Sets the value for this entry. The iterator must not be done, and the * iterator must not have been initialized const. */ -void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); +void upb_MapIterator_SetValue(upb_Map* map, size_t iter, + upb_MessageValue value); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif #include "upb/port_undef.inc" diff --git a/contrib/libs/grpc/third_party/upb/upb/table.c b/contrib/libs/grpc/third_party/upb/upb/table.c index 21e42ac816..33b3a9dc6e 100644 --- a/contrib/libs/grpc/third_party/upb/upb/table.c +++ b/contrib/libs/grpc/third_party/upb/upb/table.c @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -38,11 +38,11 @@ /* Must be last. */ #include "upb/port_def.inc" -#define UPB_MAXARRSIZE 16 /* 64k. */ +#define UPB_MAXARRSIZE 16 /* 64k. */ /* From Chromium. */ #define ARRAY_SIZE(x) \ - ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) + ((sizeof(x) / sizeof(0 [x])) / ((size_t)(!(sizeof(x) % sizeof(0 [x]))))) static const double MAX_LOAD = 0.85; @@ -63,20 +63,20 @@ static int log2ceil(uint64_t v) { int ret = 0; bool pow2 = is_pow2(v); while (v >>= 1) ret++; - ret = pow2 ? ret : ret + 1; /* Ceiling. */ + ret = pow2 ? ret : ret + 1; /* Ceiling. */ return UPB_MIN(UPB_MAXARRSIZE, ret); } -char *upb_strdup2(const char *s, size_t len, upb_arena *a) { +char* upb_strdup2(const char* s, size_t len, upb_Arena* a) { size_t n; - char *p; + char* p; /* Prevent overflow errors. */ if (len == SIZE_MAX) return NULL; /* Always null-terminate, even if binary data; but don't rely on the input to * have a null-terminating byte since it may be a raw binary buffer. */ n = len + 1; - p = upb_arena_malloc(a, n); + p = upb_Arena_Malloc(a, n); if (p) { memcpy(p, s, len); p[len] = 0; @@ -88,12 +88,12 @@ char *upb_strdup2(const char *s, size_t len, upb_arena *a) { typedef union { uintptr_t num; struct { - const char *str; + const char* str; size_t len; } str; } lookupkey_t; -static lookupkey_t strkey2(const char *str, size_t len) { +static lookupkey_t strkey2(const char* str, size_t len) { lookupkey_t k; k.str.str = str; k.str.len = len; @@ -111,24 +111,17 @@ typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2); /* Base table (shared code) ***************************************************/ -static uint32_t upb_inthash(uintptr_t key) { - return (uint32_t)key; -} +static uint32_t upb_inthash(uintptr_t key) { return (uint32_t)key; } -static const upb_tabent *upb_getentry(const upb_table *t, uint32_t hash) { +static const upb_tabent* upb_getentry(const upb_table* t, uint32_t hash) { return t->entries + (hash & t->mask); } -static bool upb_arrhas(upb_tabval key) { - return key.val != (uint64_t)-1; -} - +static bool upb_arrhas(upb_tabval key) { return key.val != (uint64_t)-1; } -static bool isfull(upb_table *t) { - return t->count == t->max_count; -} +static bool isfull(upb_table* t) { return t->count == t->max_count; } -static bool init(upb_table *t, uint8_t size_lg2, upb_arena *a) { +static bool init(upb_table* t, uint8_t size_lg2, upb_Arena* a) { size_t bytes; t->count = 0; @@ -137,7 +130,7 @@ static bool init(upb_table *t, uint8_t size_lg2, upb_arena *a) { t->max_count = upb_table_size(t) * MAX_LOAD; bytes = upb_table_size(t) * sizeof(upb_tabent); if (bytes > 0) { - t->entries = upb_arena_malloc(a, bytes); + t->entries = upb_Arena_Malloc(a, bytes); if (!t->entries) return false; memset(t->entries, 0, bytes); } else { @@ -146,9 +139,9 @@ static bool init(upb_table *t, uint8_t size_lg2, upb_arena *a) { return true; } -static upb_tabent *emptyent(upb_table *t, upb_tabent *e) { - upb_tabent *begin = t->entries; - upb_tabent *end = begin + upb_table_size(t); +static upb_tabent* emptyent(upb_table* t, upb_tabent* e) { + upb_tabent* begin = t->entries; + upb_tabent* end = begin + upb_table_size(t); for (e = e + 1; e < end; e++) { if (upb_tabent_isempty(e)) return e; } @@ -159,13 +152,13 @@ static upb_tabent *emptyent(upb_table *t, upb_tabent *e) { return NULL; } -static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) { +static upb_tabent* getentry_mutable(upb_table* t, uint32_t hash) { return (upb_tabent*)upb_getentry(t, hash); } -static const upb_tabent *findentry(const upb_table *t, lookupkey_t key, - uint32_t hash, eqlfunc_t *eql) { - const upb_tabent *e; +static const upb_tabent* findentry(const upb_table* t, lookupkey_t key, + uint32_t hash, eqlfunc_t* eql) { + const upb_tabent* e; if (t->size_lg2 == 0) return NULL; e = upb_getentry(t, hash); @@ -176,14 +169,14 @@ static const upb_tabent *findentry(const upb_table *t, lookupkey_t key, } } -static upb_tabent *findentry_mutable(upb_table *t, lookupkey_t key, - uint32_t hash, eqlfunc_t *eql) { +static upb_tabent* findentry_mutable(upb_table* t, lookupkey_t key, + uint32_t hash, eqlfunc_t* eql) { return (upb_tabent*)findentry(t, key, hash, eql); } -static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v, - uint32_t hash, eqlfunc_t *eql) { - const upb_tabent *e = findentry(t, key, hash, eql); +static bool lookup(const upb_table* t, lookupkey_t key, upb_value* v, + uint32_t hash, eqlfunc_t* eql) { + const upb_tabent* e = findentry(t, key, hash, eql); if (e) { if (v) { _upb_value_setval(v, e->val.val); @@ -195,11 +188,11 @@ static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v, } /* The given key must not already exist in the table. */ -static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, - upb_value val, uint32_t hash, - hashfunc_t *hashfunc, eqlfunc_t *eql) { - upb_tabent *mainpos_e; - upb_tabent *our_e; +static void insert(upb_table* t, lookupkey_t key, upb_tabkey tabkey, + upb_value val, uint32_t hash, hashfunc_t* hashfunc, + eqlfunc_t* eql) { + upb_tabent* mainpos_e; + upb_tabent* our_e; UPB_ASSERT(findentry(t, key, hash, eql) == NULL); @@ -212,12 +205,13 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, our_e->next = NULL; } else { /* Collision. */ - upb_tabent *new_e = emptyent(t, mainpos_e); + upb_tabent* new_e = emptyent(t, mainpos_e); /* Head of collider's chain. */ - upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key)); + upb_tabent* chain = getentry_mutable(t, hashfunc(mainpos_e->key)); if (chain == mainpos_e) { /* Existing ent is in its main position (it has the same hash as us, and - * is the head of our chain). Insert to new ent and append to this chain. */ + * is the head of our chain). Insert to new ent and append to this chain. + */ new_e->next = mainpos_e->next; mainpos_e->next = new_e; our_e = new_e; @@ -225,7 +219,7 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, /* Existing ent is not in its main position (it is a node in some other * chain). This implies that no existing ent in the table has our hash. * Evict it (updating its chain) and use its ent for head of our chain. */ - *new_e = *mainpos_e; /* copies next. */ + *new_e = *mainpos_e; /* copies next. */ while (chain->next != mainpos_e) { chain = (upb_tabent*)chain->next; UPB_ASSERT(chain); @@ -240,9 +234,9 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, UPB_ASSERT(findentry(t, key, hash, eql) == our_e); } -static bool rm(upb_table *t, lookupkey_t key, upb_value *val, - upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql) { - upb_tabent *chain = getentry_mutable(t, hash); +static bool rm(upb_table* t, lookupkey_t key, upb_value* val, + upb_tabkey* removed, uint32_t hash, eqlfunc_t* eql) { + upb_tabent* chain = getentry_mutable(t, hash); if (upb_tabent_isempty(chain)) return false; if (eql(chain->key, key)) { /* Element to remove is at the head of its chain. */ @@ -250,11 +244,11 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val, if (val) _upb_value_setval(val, chain->val.val); if (removed) *removed = chain->key; if (chain->next) { - upb_tabent *move = (upb_tabent*)chain->next; + upb_tabent* move = (upb_tabent*)chain->next; *chain = *move; - move->key = 0; /* Make the slot empty. */ + move->key = 0; /* Make the slot empty. */ } else { - chain->key = 0; /* Make the slot empty. */ + chain->key = 0; /* Make the slot empty. */ } return true; } else { @@ -265,11 +259,11 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val, } if (chain->next) { /* Found element to remove. */ - upb_tabent *rm = (upb_tabent*)chain->next; + upb_tabent* rm = (upb_tabent*)chain->next; t->count--; if (val) _upb_value_setval(val, chain->next->val.val); if (removed) *removed = rm->key; - rm->key = 0; /* Make the slot empty. */ + rm->key = 0; /* Make the slot empty. */ chain->next = rm->next; return true; } else { @@ -279,27 +273,24 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val, } } -static size_t next(const upb_table *t, size_t i) { +static size_t next(const upb_table* t, size_t i) { do { - if (++i >= upb_table_size(t)) - return SIZE_MAX - 1; /* Distinct from -1. */ - } while(upb_tabent_isempty(&t->entries[i])); + if (++i >= upb_table_size(t)) return SIZE_MAX - 1; /* Distinct from -1. */ + } while (upb_tabent_isempty(&t->entries[i])); return i; } -static size_t begin(const upb_table *t) { - return next(t, -1); -} - +static size_t begin(const upb_table* t) { return next(t, -1); } /* upb_strtable ***************************************************************/ -/* A simple "subclass" of upb_table that only adds a hash function for strings. */ +/* A simple "subclass" of upb_table that only adds a hash function for strings. + */ -static upb_tabkey strcopy(lookupkey_t k2, upb_arena *a) { - uint32_t len = (uint32_t) k2.str.len; - char *str = upb_arena_malloc(a, k2.str.len + sizeof(uint32_t) + 1); +static upb_tabkey strcopy(lookupkey_t k2, upb_Arena* a) { + uint32_t len = (uint32_t)k2.str.len; + char* str = upb_Arena_Malloc(a, k2.str.len + sizeof(uint32_t) + 1); if (str == NULL) return 0; memcpy(str, &len, sizeof(uint32_t)); if (k2.str.len) memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len); @@ -309,13 +300,13 @@ static upb_tabkey strcopy(lookupkey_t k2, upb_arena *a) { /* Adapted from ABSL's wyhash. */ -static uint64_t UnalignedLoad64(const void *p) { +static uint64_t UnalignedLoad64(const void* p) { uint64_t val; memcpy(&val, p, 8); return val; } -static uint32_t UnalignedLoad32(const void *p) { +static uint32_t UnalignedLoad32(const void* p) { uint32_t val; memcpy(&val, p, 4); return val; @@ -358,7 +349,7 @@ static uint64_t WyhashMix(uint64_t v0, uint64_t v1) { return low ^ high; } -static uint64_t Wyhash(const void *data, size_t len, uint64_t seed, +static uint64_t Wyhash(const void* data, size_t len, uint64_t seed, const uint64_t salt[]) { const uint8_t* ptr = (const uint8_t*)data; uint64_t starting_length = (uint64_t)len; @@ -442,45 +433,45 @@ const uint64_t kWyhashSalt[5] = { 0x082EFA98EC4E6C89ULL, 0x452821E638D01377ULL, }; -static uint32_t table_hash(const char *p, size_t n) { +static uint32_t table_hash(const char* p, size_t n) { return Wyhash(p, n, 0, kWyhashSalt); } static uint32_t strhash(upb_tabkey key) { uint32_t len; - char *str = upb_tabstr(key, &len); + char* str = upb_tabstr(key, &len); return table_hash(str, len); } static bool streql(upb_tabkey k1, lookupkey_t k2) { uint32_t len; - char *str = upb_tabstr(k1, &len); + char* str = upb_tabstr(k1, &len); return len == k2.str.len && (len == 0 || memcmp(str, k2.str.str, len) == 0); } -bool upb_strtable_init(upb_strtable *t, size_t expected_size, upb_arena *a) { - // Multiply by approximate reciprocal of MAX_LOAD (0.85), with pow2 denominator. +bool upb_strtable_init(upb_strtable* t, size_t expected_size, upb_Arena* a) { + // Multiply by approximate reciprocal of MAX_LOAD (0.85), with pow2 + // denominator. size_t need_entries = (expected_size + 1) * 1204 / 1024; UPB_ASSERT(need_entries >= expected_size * 0.85); - int size_lg2 = _upb_lg2ceil(need_entries); + int size_lg2 = _upb_Log2Ceiling(need_entries); return init(&t->t, size_lg2, a); } -void upb_strtable_clear(upb_strtable *t) { +void upb_strtable_clear(upb_strtable* t) { size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent); t->t.count = 0; memset((char*)t->t.entries, 0, bytes); } -bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a) { +bool upb_strtable_resize(upb_strtable* t, size_t size_lg2, upb_Arena* a) { upb_strtable new_table; upb_strtable_iter i; - if (!init(&new_table.t, size_lg2, a)) - return false; + if (!init(&new_table.t, size_lg2, a)) return false; upb_strtable_begin(&i, t); - for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) { - upb_strview key = upb_strtable_iter_key(&i); + for (; !upb_strtable_done(&i); upb_strtable_next(&i)) { + upb_StringView key = upb_strtable_iter_key(&i); upb_strtable_insert(&new_table, key.data, key.size, upb_strtable_iter_value(&i), a); } @@ -488,8 +479,8 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a) { return true; } -bool upb_strtable_insert(upb_strtable *t, const char *k, size_t len, - upb_value v, upb_arena *a) { +bool upb_strtable_insert(upb_strtable* t, const char* k, size_t len, + upb_value v, upb_Arena* a) { lookupkey_t key; upb_tabkey tabkey; uint32_t hash; @@ -510,14 +501,14 @@ bool upb_strtable_insert(upb_strtable *t, const char *k, size_t len, return true; } -bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, - upb_value *v) { +bool upb_strtable_lookup2(const upb_strtable* t, const char* key, size_t len, + upb_value* v) { uint32_t hash = table_hash(key, len); return lookup(&t->t, strkey2(key, len), v, hash, &streql); } -bool upb_strtable_remove(upb_strtable *t, const char *key, size_t len, - upb_value *val) { +bool upb_strtable_remove2(upb_strtable* t, const char* key, size_t len, + upb_value* val) { uint32_t hash = table_hash(key, len); upb_tabkey tabkey; return rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql); @@ -525,23 +516,23 @@ bool upb_strtable_remove(upb_strtable *t, const char *key, size_t len, /* Iteration */ -void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) { +void upb_strtable_begin(upb_strtable_iter* i, const upb_strtable* t) { i->t = t; i->index = begin(&t->t); } -void upb_strtable_next(upb_strtable_iter *i) { +void upb_strtable_next(upb_strtable_iter* i) { i->index = next(&i->t->t, i->index); } -bool upb_strtable_done(const upb_strtable_iter *i) { +bool upb_strtable_done(const upb_strtable_iter* i) { if (!i->t) return true; return i->index >= upb_table_size(&i->t->t) || upb_tabent_isempty(str_tabent(i)); } -upb_strview upb_strtable_iter_key(const upb_strtable_iter *i) { - upb_strview key; +upb_StringView upb_strtable_iter_key(const upb_strtable_iter* i) { + upb_StringView key; uint32_t len; UPB_ASSERT(!upb_strtable_done(i)); key.data = upb_tabstr(str_tabent(i)->key, &len); @@ -549,24 +540,22 @@ upb_strview upb_strtable_iter_key(const upb_strtable_iter *i) { return key; } -upb_value upb_strtable_iter_value(const upb_strtable_iter *i) { +upb_value upb_strtable_iter_value(const upb_strtable_iter* i) { UPB_ASSERT(!upb_strtable_done(i)); return _upb_value_val(str_tabent(i)->val.val); } -void upb_strtable_iter_setdone(upb_strtable_iter *i) { +void upb_strtable_iter_setdone(upb_strtable_iter* i) { i->t = NULL; i->index = SIZE_MAX; } -bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, - const upb_strtable_iter *i2) { - if (upb_strtable_done(i1) && upb_strtable_done(i2)) - return true; +bool upb_strtable_iter_isequal(const upb_strtable_iter* i1, + const upb_strtable_iter* i2) { + if (upb_strtable_done(i1) && upb_strtable_done(i2)) return true; return i1->t == i2->t && i1->index == i2->index; } - /* upb_inttable ***************************************************************/ /* For inttables we use a hybrid structure where small keys are kept in an @@ -574,34 +563,32 @@ bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, static uint32_t inthash(upb_tabkey key) { return upb_inthash(key); } -static bool inteql(upb_tabkey k1, lookupkey_t k2) { - return k1 == k2.num; -} +static bool inteql(upb_tabkey k1, lookupkey_t k2) { return k1 == k2.num; } -static upb_tabval *mutable_array(upb_inttable *t) { +static upb_tabval* mutable_array(upb_inttable* t) { return (upb_tabval*)t->array; } -static upb_tabval *inttable_val(upb_inttable *t, uintptr_t key) { +static upb_tabval* inttable_val(upb_inttable* t, uintptr_t key) { if (key < t->array_size) { return upb_arrhas(t->array[key]) ? &(mutable_array(t)[key]) : NULL; } else { - upb_tabent *e = + upb_tabent* e = findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql); return e ? &e->val : NULL; } } -static const upb_tabval *inttable_val_const(const upb_inttable *t, +static const upb_tabval* inttable_val_const(const upb_inttable* t, uintptr_t key) { return inttable_val((upb_inttable*)t, key); } -size_t upb_inttable_count(const upb_inttable *t) { +size_t upb_inttable_count(const upb_inttable* t) { return t->t.count + t->array_count; } -static void check(upb_inttable *t) { +static void check(upb_inttable* t) { UPB_UNUSED(t); #if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG) { @@ -609,7 +596,7 @@ static void check(upb_inttable *t) { size_t count = 0; upb_inttable_iter i; upb_inttable_begin(&i, t); - for(; !upb_inttable_done(&i); upb_inttable_next(&i), count++) { + for (; !upb_inttable_done(&i); upb_inttable_next(&i), count++) { UPB_ASSERT(upb_inttable_lookup(t, upb_inttable_iter_key(&i), NULL)); } UPB_ASSERT(count == upb_inttable_count(t)); @@ -617,8 +604,8 @@ static void check(upb_inttable *t) { #endif } -bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2, - upb_arena *a) { +bool upb_inttable_sizedinit(upb_inttable* t, size_t asize, int hsize_lg2, + upb_Arena* a) { size_t array_bytes; if (!init(&t->t, hsize_lg2, a)) return false; @@ -627,7 +614,7 @@ bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2, t->array_size = UPB_MAX(1, asize); t->array_count = 0; array_bytes = t->array_size * sizeof(upb_value); - t->array = upb_arena_malloc(a, array_bytes); + t->array = upb_Arena_Malloc(a, array_bytes); if (!t->array) { return false; } @@ -636,15 +623,16 @@ bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2, return true; } -bool upb_inttable_init(upb_inttable *t, upb_arena *a) { +bool upb_inttable_init(upb_inttable* t, upb_Arena* a) { return upb_inttable_sizedinit(t, 0, 4, a); } -bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val, - upb_arena *a) { +bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val, + upb_Arena* a) { upb_tabval tabval; tabval.val = val.val; - UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */ + UPB_ASSERT( + upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */ if (key < t->array_size) { UPB_ASSERT(!upb_arrhas(t->array[key])); @@ -661,7 +649,7 @@ bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val, } for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) { - const upb_tabent *e = &t->t.entries[i]; + const upb_tabent* e = &t->t.entries[i]; uint32_t hash; upb_value v; @@ -680,21 +668,21 @@ bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val, return true; } -bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) { - const upb_tabval *table_v = inttable_val_const(t, key); +bool upb_inttable_lookup(const upb_inttable* t, uintptr_t key, upb_value* v) { + const upb_tabval* table_v = inttable_val_const(t, key); if (!table_v) return false; if (v) _upb_value_setval(v, table_v->val); return true; } -bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val) { - upb_tabval *table_v = inttable_val(t, key); +bool upb_inttable_replace(upb_inttable* t, uintptr_t key, upb_value val) { + upb_tabval* table_v = inttable_val(t, key); if (!table_v) return false; table_v->val = val.val; return true; } -bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) { +bool upb_inttable_remove(upb_inttable* t, uintptr_t key, upb_value* val) { bool success; if (key < t->array_size) { if (upb_arrhas(t->array[key])) { @@ -715,7 +703,7 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) { return success; } -void upb_inttable_compact(upb_inttable *t, upb_arena *a) { +void upb_inttable_compact(upb_inttable* t, upb_Arena* a) { /* A power-of-two histogram of the table keys. */ size_t counts[UPB_MAXARRSIZE + 1] = {0}; @@ -754,7 +742,7 @@ void upb_inttable_compact(upb_inttable *t, upb_arena *a) { { /* Insert all elements into new, perfectly-sized table. */ - size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */ + size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */ size_t hash_count = upb_inttable_count(t) - arr_count; size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0; int hashsize_lg2 = log2ceil(hash_size); @@ -773,25 +761,25 @@ void upb_inttable_compact(upb_inttable *t, upb_arena *a) { /* Iteration. */ -static const upb_tabent *int_tabent(const upb_inttable_iter *i) { +static const upb_tabent* int_tabent(const upb_inttable_iter* i) { UPB_ASSERT(!i->array_part); return &i->t->t.entries[i->index]; } -static upb_tabval int_arrent(const upb_inttable_iter *i) { +static upb_tabval int_arrent(const upb_inttable_iter* i) { UPB_ASSERT(i->array_part); return i->t->array[i->index]; } -void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t) { +void upb_inttable_begin(upb_inttable_iter* i, const upb_inttable* t) { i->t = t; i->index = -1; i->array_part = true; upb_inttable_next(i); } -void upb_inttable_next(upb_inttable_iter *iter) { - const upb_inttable *t = iter->t; +void upb_inttable_next(upb_inttable_iter* iter) { + const upb_inttable* t = iter->t; if (iter->array_part) { while (++iter->index < t->array_size) { if (upb_arrhas(int_arrent(iter))) { @@ -805,38 +793,130 @@ void upb_inttable_next(upb_inttable_iter *iter) { } } -bool upb_inttable_done(const upb_inttable_iter *i) { +bool upb_inttable_next2(const upb_inttable* t, uintptr_t* key, upb_value* val, + intptr_t* iter) { + intptr_t i = *iter; + if (i < t->array_size) { + while (++i < t->array_size) { + upb_tabval ent = t->array[i]; + if (upb_arrhas(ent)) { + *key = i; + *val = _upb_value_val(ent.val); + *iter = i; + return true; + } + } + } + + size_t tab_idx = next(&t->t, i == -1 ? -1 : i - t->array_size); + if (tab_idx < upb_table_size(&t->t)) { + upb_tabent* ent = &t->t.entries[tab_idx]; + *key = ent->key; + *val = _upb_value_val(ent->val.val); + *iter = tab_idx + t->array_size; + return true; + } + + return false; +} + +void upb_inttable_removeiter(upb_inttable* t, intptr_t* iter) { + intptr_t i = *iter; + if (i < t->array_size) { + t->array_count--; + mutable_array(t)[i].val = -1; + } else { + upb_tabent* ent = &t->t.entries[i - t->array_size]; + upb_tabent* prev = NULL; + + // Linear search, not great. + upb_tabent* end = &t->t.entries[upb_table_size(&t->t)]; + for (upb_tabent* e = t->t.entries; e != end; e++) { + if (e->next == ent) { + prev = e; + break; + } + } + + if (prev) { + prev->next = ent->next; + } + + t->t.count--; + ent->key = 0; + ent->next = NULL; + } +} + +bool upb_strtable_next2(const upb_strtable* t, upb_StringView* key, + upb_value* val, intptr_t* iter) { + size_t tab_idx = next(&t->t, *iter); + if (tab_idx < upb_table_size(&t->t)) { + upb_tabent* ent = &t->t.entries[tab_idx]; + uint32_t len; + key->data = upb_tabstr(ent->key, &len); + key->size = len; + *val = _upb_value_val(ent->val.val); + *iter = tab_idx; + return true; + } + + return false; +} + +void upb_strtable_removeiter(upb_strtable* t, intptr_t* iter) { + intptr_t i = *iter; + upb_tabent* ent = &t->t.entries[i]; + upb_tabent* prev = NULL; + + // Linear search, not great. + upb_tabent* end = &t->t.entries[upb_table_size(&t->t)]; + for (upb_tabent* e = t->t.entries; e != end; e++) { + if (e->next == ent) { + prev = e; + break; + } + } + + if (prev) { + prev->next = ent->next; + } + + t->t.count--; + ent->key = 0; + ent->next = NULL; +} + +bool upb_inttable_done(const upb_inttable_iter* i) { if (!i->t) return true; if (i->array_part) { - return i->index >= i->t->array_size || - !upb_arrhas(int_arrent(i)); + return i->index >= i->t->array_size || !upb_arrhas(int_arrent(i)); } else { return i->index >= upb_table_size(&i->t->t) || upb_tabent_isempty(int_tabent(i)); } } -uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) { +uintptr_t upb_inttable_iter_key(const upb_inttable_iter* i) { UPB_ASSERT(!upb_inttable_done(i)); return i->array_part ? i->index : int_tabent(i)->key; } -upb_value upb_inttable_iter_value(const upb_inttable_iter *i) { +upb_value upb_inttable_iter_value(const upb_inttable_iter* i) { UPB_ASSERT(!upb_inttable_done(i)); - return _upb_value_val( - i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val); + return _upb_value_val(i->array_part ? i->t->array[i->index].val + : int_tabent(i)->val.val); } -void upb_inttable_iter_setdone(upb_inttable_iter *i) { +void upb_inttable_iter_setdone(upb_inttable_iter* i) { i->t = NULL; i->index = SIZE_MAX; i->array_part = false; } -bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, - const upb_inttable_iter *i2) { - if (upb_inttable_done(i1) && upb_inttable_done(i2)) - return true; +bool upb_inttable_iter_isequal(const upb_inttable_iter* i1, + const upb_inttable_iter* i2) { + if (upb_inttable_done(i1) && upb_inttable_done(i2)) return true; return i1->t == i2->t && i1->index == i2->index && i1->array_part == i2->array_part; } diff --git a/contrib/libs/grpc/third_party/upb/upb/table_internal.h b/contrib/libs/grpc/third_party/upb/upb/table_internal.h index 1313686848..9fb2d238cd 100644 --- a/contrib/libs/grpc/third_party/upb/upb/table_internal.h +++ b/contrib/libs/grpc/third_party/upb/upb/table_internal.h @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -49,15 +49,16 @@ #include <stdint.h> #include <string.h> + #include "upb/upb.h" +// Must be last. #include "upb/port_def.inc" #ifdef __cplusplus extern "C" { #endif - /* upb_value ******************************************************************/ typedef struct { @@ -66,11 +67,9 @@ typedef struct { /* Variant that works with a length-delimited rather than NULL-delimited string, * as supported by strtable. */ -char *upb_strdup2(const char *s, size_t len, upb_arena *a); +char* upb_strdup2(const char* s, size_t len, upb_Arena* a); -UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val) { - v->val = val; -} +UPB_INLINE void _upb_value_setval(upb_value* v, uint64_t val) { v->val = val; } /* For each value ctype, define the following set of functions: * @@ -80,36 +79,35 @@ UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val) { * * // Construct a new upb_value from an int32. * upb_value upb_value_int32(int32_t val); */ -#define FUNCS(name, membername, type_t, converter, proto_type) \ - UPB_INLINE void upb_value_set ## name(upb_value *val, type_t cval) { \ - val->val = (converter)cval; \ - } \ - UPB_INLINE upb_value upb_value_ ## name(type_t val) { \ - upb_value ret; \ - upb_value_set ## name(&ret, val); \ - return ret; \ - } \ - UPB_INLINE type_t upb_value_get ## name(upb_value val) { \ - return (type_t)(converter)val.val; \ +#define FUNCS(name, membername, type_t, converter, proto_type) \ + UPB_INLINE void upb_value_set##name(upb_value* val, type_t cval) { \ + val->val = (converter)cval; \ + } \ + UPB_INLINE upb_value upb_value_##name(type_t val) { \ + upb_value ret; \ + upb_value_set##name(&ret, val); \ + return ret; \ + } \ + UPB_INLINE type_t upb_value_get##name(upb_value val) { \ + return (type_t)(converter)val.val; \ } -FUNCS(int32, int32, int32_t, int32_t, UPB_CTYPE_INT32) -FUNCS(int64, int64, int64_t, int64_t, UPB_CTYPE_INT64) -FUNCS(uint32, uint32, uint32_t, uint32_t, UPB_CTYPE_UINT32) -FUNCS(uint64, uint64, uint64_t, uint64_t, UPB_CTYPE_UINT64) -FUNCS(bool, _bool, bool, bool, UPB_CTYPE_BOOL) -FUNCS(cstr, cstr, char*, uintptr_t, UPB_CTYPE_CSTR) -FUNCS(ptr, ptr, void*, uintptr_t, UPB_CTYPE_PTR) -FUNCS(constptr, constptr, const void*, uintptr_t, UPB_CTYPE_CONSTPTR) -FUNCS(fptr, fptr, upb_func*, uintptr_t, UPB_CTYPE_FPTR) +FUNCS(int32, int32, int32_t, int32_t, UPB_CTYPE_INT32) +FUNCS(int64, int64, int64_t, int64_t, UPB_CTYPE_INT64) +FUNCS(uint32, uint32, uint32_t, uint32_t, UPB_CTYPE_UINT32) +FUNCS(uint64, uint64, uint64_t, uint64_t, UPB_CTYPE_UINT64) +FUNCS(bool, _bool, bool, bool, UPB_CTYPE_BOOL) +FUNCS(cstr, cstr, char*, uintptr_t, UPB_CTYPE_CSTR) +FUNCS(ptr, ptr, void*, uintptr_t, UPB_CTYPE_PTR) +FUNCS(constptr, constptr, const void*, uintptr_t, UPB_CTYPE_CONSTPTR) #undef FUNCS -UPB_INLINE void upb_value_setfloat(upb_value *val, float cval) { +UPB_INLINE void upb_value_setfloat(upb_value* val, float cval) { memcpy(&val->val, &cval, sizeof(cval)); } -UPB_INLINE void upb_value_setdouble(upb_value *val, double cval) { +UPB_INLINE void upb_value_setdouble(upb_value* val, double cval) { memcpy(&val->val, &cval, sizeof(cval)); } @@ -127,7 +125,6 @@ UPB_INLINE upb_value upb_value_double(double cval) { #undef SET_TYPE - /* upb_tabkey *****************************************************************/ /* Either: @@ -139,14 +136,14 @@ UPB_INLINE upb_value upb_value_double(double cval) { * initializing a non-first union member. */ typedef uintptr_t upb_tabkey; -UPB_INLINE char *upb_tabstr(upb_tabkey key, uint32_t *len) { +UPB_INLINE char* upb_tabstr(upb_tabkey key, uint32_t* len) { char* mem = (char*)key; if (len) memcpy(len, mem, sizeof(*len)); return mem + sizeof(*len); } -UPB_INLINE upb_strview upb_tabstrview(upb_tabkey key) { - upb_strview ret; +UPB_INLINE upb_StringView upb_tabstrview(upb_tabkey key) { + upb_StringView ret; uint32_t len; ret.data = upb_tabstr(key, &len); ret.size = len; @@ -159,7 +156,8 @@ typedef struct upb_tabval { uint64_t val; } upb_tabval; -#define UPB_TABVALUE_EMPTY_INIT {-1} +#define UPB_TABVALUE_EMPTY_INIT \ + { -1 } /* upb_table ******************************************************************/ @@ -171,15 +169,15 @@ typedef struct _upb_tabent { * tables. We cast away const sometimes, but *only* when the containing * upb_table is known to be non-const. This requires a bit of care, but * the subtlety is confined to table.c. */ - const struct _upb_tabent *next; + const struct _upb_tabent* next; } upb_tabent; typedef struct { - size_t count; /* Number of entries in the hash part. */ - uint32_t mask; /* Mask to turn hash value -> bucket. */ - uint32_t max_count; /* Max count before we hit our load limit. */ - uint8_t size_lg2; /* Size of the hashtable part is 2^size_lg2 entries. */ - upb_tabent *entries; + size_t count; /* Number of entries in the hash part. */ + uint32_t mask; /* Mask to turn hash value -> bucket. */ + uint32_t max_count; /* Max count before we hit our load limit. */ + uint8_t size_lg2; /* Size of the hashtable part is 2^size_lg2 entries. */ + upb_tabent* entries; } upb_table; typedef struct { @@ -187,13 +185,13 @@ typedef struct { } upb_strtable; typedef struct { - upb_table t; /* For entries that don't fit in the array part. */ - const upb_tabval *array; /* Array part of the table. See const note above. */ - size_t array_size; /* Array part size. */ - size_t array_count; /* Array part number of elements. */ + upb_table t; /* For entries that don't fit in the array part. */ + const upb_tabval* array; /* Array part of the table. See const note above. */ + size_t array_size; /* Array part size. */ + size_t array_count; /* Array part number of elements. */ } upb_inttable; -UPB_INLINE size_t upb_table_size(const upb_table *t) { +UPB_INLINE size_t upb_table_size(const upb_table* t) { if (t->size_lg2 == 0) return 0; else @@ -201,22 +199,20 @@ UPB_INLINE size_t upb_table_size(const upb_table *t) { } /* Internal-only functions, in .h file only out of necessity. */ -UPB_INLINE bool upb_tabent_isempty(const upb_tabent *e) { - return e->key == 0; -} +UPB_INLINE bool upb_tabent_isempty(const upb_tabent* e) { return e->key == 0; } /* Initialize and uninitialize a table, respectively. If memory allocation * failed, false is returned that the table is uninitialized. */ -bool upb_inttable_init(upb_inttable *table, upb_arena *a); -bool upb_strtable_init(upb_strtable *table, size_t expected_size, upb_arena *a); +bool upb_inttable_init(upb_inttable* table, upb_Arena* a); +bool upb_strtable_init(upb_strtable* table, size_t expected_size, upb_Arena* a); /* Returns the number of values in the table. */ -size_t upb_inttable_count(const upb_inttable *t); -UPB_INLINE size_t upb_strtable_count(const upb_strtable *t) { +size_t upb_inttable_count(const upb_inttable* t); +UPB_INLINE size_t upb_strtable_count(const upb_strtable* t) { return t->t.count; } -void upb_strtable_clear(upb_strtable *t); +void upb_strtable_clear(upb_strtable* t); /* Inserts the given key into the hashtable with the given value. The key must * not already exist in the hash table. For string tables, the key must be @@ -225,45 +221,84 @@ void upb_strtable_clear(upb_strtable *t); * * If a table resize was required but memory allocation failed, false is * returned and the table is unchanged. */ -bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val, - upb_arena *a); -bool upb_strtable_insert(upb_strtable *t, const char *key, size_t len, - upb_value val, upb_arena *a); +bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val, + upb_Arena* a); +bool upb_strtable_insert(upb_strtable* t, const char* key, size_t len, + upb_value val, upb_Arena* a); /* Looks up key in this table, returning "true" if the key was found. * If v is non-NULL, copies the value for this key into *v. */ -bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v); -bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, - upb_value *v); +bool upb_inttable_lookup(const upb_inttable* t, uintptr_t key, upb_value* v); +bool upb_strtable_lookup2(const upb_strtable* t, const char* key, size_t len, + upb_value* v); /* For NULL-terminated strings. */ -UPB_INLINE bool upb_strtable_lookup(const upb_strtable *t, const char *key, - upb_value *v) { +UPB_INLINE bool upb_strtable_lookup(const upb_strtable* t, const char* key, + upb_value* v) { return upb_strtable_lookup2(t, key, strlen(key), v); } /* Removes an item from the table. Returns true if the remove was successful, * and stores the removed item in *val if non-NULL. */ -bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val); -bool upb_strtable_remove(upb_strtable *t, const char *key, size_t len, - upb_value *val); +bool upb_inttable_remove(upb_inttable* t, uintptr_t key, upb_value* val); +bool upb_strtable_remove2(upb_strtable* t, const char* key, size_t len, + upb_value* val); + +UPB_INLINE bool upb_strtable_remove(upb_strtable* t, const char* key, + upb_value* v) { + return upb_strtable_remove2(t, key, strlen(key), v); +} /* Updates an existing entry in an inttable. If the entry does not exist, * returns false and does nothing. Unlike insert/remove, this does not * invalidate iterators. */ -bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val); +bool upb_inttable_replace(upb_inttable* t, uintptr_t key, upb_value val); /* Optimizes the table for the current set of entries, for both memory use and * lookup time. Client should call this after all entries have been inserted; * inserting more entries is legal, but will likely require a table resize. */ -void upb_inttable_compact(upb_inttable *t, upb_arena *a); +void upb_inttable_compact(upb_inttable* t, upb_Arena* a); /* Exposed for testing only. */ -bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a); +bool upb_strtable_resize(upb_strtable* t, size_t size_lg2, upb_Arena* a); /* Iterators ******************************************************************/ -/* Iterators for int and string tables. We are subject to some kind of unusual +/* Iteration over inttable. + * + * intptr_t iter = UPB_INTTABLE_BEGIN; + * uintptr_t key; + * upb_value val; + * while (upb_inttable_next2(t, &key, &val, &iter)) { + * // ... + * } + */ + +#define UPB_INTTABLE_BEGIN -1 + +bool upb_inttable_next2(const upb_inttable* t, uintptr_t* key, upb_value* val, + intptr_t* iter); +void upb_inttable_removeiter(upb_inttable* t, intptr_t* iter); + +/* Iteration over strtable. + * + * intptr_t iter = UPB_INTTABLE_BEGIN; + * upb_StringView key; + * upb_value val; + * while (upb_strtable_next2(t, &key, &val, &iter)) { + * // ... + * } + */ + +#define UPB_STRTABLE_BEGIN -1 + +bool upb_strtable_next2(const upb_strtable* t, upb_StringView* key, + upb_value* val, intptr_t* iter); +void upb_strtable_removeiter(upb_strtable* t, intptr_t* iter); + +/* DEPRECATED iterators, slated for removal. + * + * Iterators for int and string tables. We are subject to some kind of unusual * design constraints: * * For high-level languages: @@ -284,7 +319,6 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a); * guaranteed not to crash and to return real table elements (except when done() * is true). */ - /* upb_strtable_iter **********************************************************/ /* upb_strtable_iter i; @@ -297,19 +331,18 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a); */ typedef struct { - const upb_strtable *t; + const upb_strtable* t; size_t index; } upb_strtable_iter; -void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t); -void upb_strtable_next(upb_strtable_iter *i); -bool upb_strtable_done(const upb_strtable_iter *i); -upb_strview upb_strtable_iter_key(const upb_strtable_iter *i); -upb_value upb_strtable_iter_value(const upb_strtable_iter *i); -void upb_strtable_iter_setdone(upb_strtable_iter *i); -bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, - const upb_strtable_iter *i2); - +void upb_strtable_begin(upb_strtable_iter* i, const upb_strtable* t); +void upb_strtable_next(upb_strtable_iter* i); +bool upb_strtable_done(const upb_strtable_iter* i); +upb_StringView upb_strtable_iter_key(const upb_strtable_iter* i); +upb_value upb_strtable_iter_value(const upb_strtable_iter* i); +void upb_strtable_iter_setdone(upb_strtable_iter* i); +bool upb_strtable_iter_isequal(const upb_strtable_iter* i1, + const upb_strtable_iter* i2); /* upb_inttable_iter **********************************************************/ @@ -323,29 +356,28 @@ bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, */ typedef struct { - const upb_inttable *t; + const upb_inttable* t; size_t index; bool array_part; } upb_inttable_iter; -UPB_INLINE const upb_tabent *str_tabent(const upb_strtable_iter *i) { +UPB_INLINE const upb_tabent* str_tabent(const upb_strtable_iter* i) { return &i->t->t.entries[i->index]; } -void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t); -void upb_inttable_next(upb_inttable_iter *i); -bool upb_inttable_done(const upb_inttable_iter *i); -uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i); -upb_value upb_inttable_iter_value(const upb_inttable_iter *i); -void upb_inttable_iter_setdone(upb_inttable_iter *i); -bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, - const upb_inttable_iter *i2); - +void upb_inttable_begin(upb_inttable_iter* i, const upb_inttable* t); +void upb_inttable_next(upb_inttable_iter* i); +bool upb_inttable_done(const upb_inttable_iter* i); +uintptr_t upb_inttable_iter_key(const upb_inttable_iter* i); +upb_value upb_inttable_iter_value(const upb_inttable_iter* i); +void upb_inttable_iter_setdone(upb_inttable_iter* i); +bool upb_inttable_iter_isequal(const upb_inttable_iter* i1, + const upb_inttable_iter* i2); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif #include "upb/port_undef.inc" -#endif /* UPB_TABLE_H_ */ +#endif /* UPB_TABLE_H_ */ diff --git a/contrib/libs/grpc/third_party/upb/upb/text_encode.c b/contrib/libs/grpc/third_party/upb/upb/text_encode.c index 12840c0fae..9612375dba 100644 --- a/contrib/libs/grpc/third_party/upb/upb/text_encode.c +++ b/contrib/libs/grpc/third_party/upb/upb/text_encode.c @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -35,6 +35,9 @@ #include <string.h> #include "upb/reflection.h" +#include "upb/upb_internal.h" + +// Must be last. #include "upb/port_def.inc" typedef struct { @@ -42,13 +45,14 @@ typedef struct { size_t overflow; int indent_depth; int options; - const upb_symtab *ext_pool; + const upb_DefPool* ext_pool; _upb_mapsorter sorter; } txtenc; -static void txtenc_msg(txtenc *e, const upb_msg *msg, const upb_msgdef *m); +static void txtenc_msg(txtenc* e, const upb_Message* msg, + const upb_MessageDef* m); -static void txtenc_putbytes(txtenc *e, const void *data, size_t len) { +static void txtenc_putbytes(txtenc* e, const void* data, size_t len) { size_t have = e->end - e->ptr; if (UPB_LIKELY(have >= len)) { memcpy(e->ptr, data, len); @@ -62,11 +66,11 @@ static void txtenc_putbytes(txtenc *e, const void *data, size_t len) { } } -static void txtenc_putstr(txtenc *e, const char *str) { +static void txtenc_putstr(txtenc* e, const char* str) { txtenc_putbytes(e, str, strlen(str)); } -static void txtenc_printf(txtenc *e, const char *fmt, ...) { +static void txtenc_printf(txtenc* e, const char* fmt, ...) { size_t n; size_t have = e->end - e->ptr; va_list args; @@ -83,7 +87,7 @@ static void txtenc_printf(txtenc *e, const char *fmt, ...) { } } -static void txtenc_indent(txtenc *e) { +static void txtenc_indent(txtenc* e) { if ((e->options & UPB_TXTENC_SINGLELINE) == 0) { int i = e->indent_depth; while (i-- > 0) { @@ -92,7 +96,7 @@ static void txtenc_indent(txtenc *e) { } } -static void txtenc_endfield(txtenc *e) { +static void txtenc_endfield(txtenc* e) { if (e->options & UPB_TXTENC_SINGLELINE) { txtenc_putstr(e, " "); } else { @@ -100,20 +104,20 @@ static void txtenc_endfield(txtenc *e) { } } -static void txtenc_enum(int32_t val, const upb_fielddef *f, txtenc *e) { - const upb_enumdef *e_def = upb_fielddef_enumsubdef(f); - const upb_enumvaldef *ev = upb_enumdef_lookupnum(e_def, val); +static void txtenc_enum(int32_t val, const upb_FieldDef* f, txtenc* e) { + const upb_EnumDef* e_def = upb_FieldDef_EnumSubDef(f); + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(e_def, val); if (ev) { - txtenc_printf(e, "%s", upb_enumvaldef_name(ev)); + txtenc_printf(e, "%s", upb_EnumValueDef_Name(ev)); } else { txtenc_printf(e, "%" PRId32, val); } } -static void txtenc_string(txtenc *e, upb_strview str, bool bytes) { - const char *ptr = str.data; - const char *end = ptr + str.size; +static void txtenc_string(txtenc* e, upb_StringView str, bool bytes) { + const char* ptr = str.data; + const char* end = ptr + str.size; txtenc_putstr(e, "\""); while (ptr < end) { @@ -150,50 +154,65 @@ static void txtenc_string(txtenc *e, upb_strview str, bool bytes) { txtenc_putstr(e, "\""); } -static void txtenc_field(txtenc *e, upb_msgval val, const upb_fielddef *f) { +static void txtenc_field(txtenc* e, upb_MessageValue val, + const upb_FieldDef* f) { txtenc_indent(e); - txtenc_printf(e, "%s: ", upb_fielddef_name(f)); + upb_CType type = upb_FieldDef_CType(f); + const char* name = upb_FieldDef_Name(f); + + if (type == kUpb_CType_Message) { + txtenc_printf(e, "%s {", name); + txtenc_endfield(e); + e->indent_depth++; + txtenc_msg(e, val.msg_val, upb_FieldDef_MessageSubDef(f)); + e->indent_depth--; + txtenc_indent(e); + txtenc_putstr(e, "}"); + txtenc_endfield(e); + return; + } + + txtenc_printf(e, "%s: ", name); - switch (upb_fielddef_type(f)) { - case UPB_TYPE_BOOL: + switch (type) { + case kUpb_CType_Bool: txtenc_putstr(e, val.bool_val ? "true" : "false"); break; - case UPB_TYPE_FLOAT: - txtenc_printf(e, "%f", val.float_val); + case kUpb_CType_Float: { + char buf[32]; + _upb_EncodeRoundTripFloat(val.float_val, buf, sizeof(buf)); + txtenc_putstr(e, buf); break; - case UPB_TYPE_DOUBLE: - txtenc_printf(e, "%f", val.double_val); + } + case kUpb_CType_Double: { + char buf[32]; + _upb_EncodeRoundTripDouble(val.double_val, buf, sizeof(buf)); + txtenc_putstr(e, buf); break; - case UPB_TYPE_INT32: + } + case kUpb_CType_Int32: txtenc_printf(e, "%" PRId32, val.int32_val); break; - case UPB_TYPE_UINT32: + case kUpb_CType_UInt32: txtenc_printf(e, "%" PRIu32, val.uint32_val); break; - case UPB_TYPE_INT64: + case kUpb_CType_Int64: txtenc_printf(e, "%" PRId64, val.int64_val); break; - case UPB_TYPE_UINT64: + case kUpb_CType_UInt64: txtenc_printf(e, "%" PRIu64, val.uint64_val); break; - case UPB_TYPE_STRING: + case kUpb_CType_String: txtenc_string(e, val.str_val, false); break; - case UPB_TYPE_BYTES: + case kUpb_CType_Bytes: txtenc_string(e, val.str_val, true); break; - case UPB_TYPE_ENUM: + case kUpb_CType_Enum: txtenc_enum(val.int32_val, f, e); break; - case UPB_TYPE_MESSAGE: - txtenc_putstr(e, "{"); - txtenc_endfield(e); - e->indent_depth++; - txtenc_msg(e, val.msg_val, upb_fielddef_msgsubdef(f)); - e->indent_depth--; - txtenc_indent(e); - txtenc_putstr(e, "}"); - break; + default: + UPB_UNREACHABLE(); } txtenc_endfield(e); @@ -206,23 +225,23 @@ static void txtenc_field(txtenc *e, upb_msgval val, const upb_fielddef *f) { * foo_field: 2 * foo_field: 3 */ -static void txtenc_array(txtenc *e, const upb_array *arr, - const upb_fielddef *f) { +static void txtenc_array(txtenc* e, const upb_Array* arr, + const upb_FieldDef* f) { size_t i; - size_t size = upb_array_size(arr); + size_t size = upb_Array_Size(arr); for (i = 0; i < size; i++) { - txtenc_field(e, upb_array_get(arr, i), f); + txtenc_field(e, upb_Array_Get(arr, i), f); } } -static void txtenc_mapentry(txtenc *e, upb_msgval key, upb_msgval val, - const upb_fielddef *f) { - const upb_msgdef *entry = upb_fielddef_msgsubdef(f); - const upb_fielddef *key_f = upb_msgdef_field(entry, 0); - const upb_fielddef *val_f = upb_msgdef_field(entry, 1); +static void txtenc_mapentry(txtenc* e, upb_MessageValue key, + upb_MessageValue val, const upb_FieldDef* f) { + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key_f = upb_MessageDef_Field(entry, 0); + const upb_FieldDef* val_f = upb_MessageDef_Field(entry, 1); txtenc_indent(e); - txtenc_printf(e, "%s: {", upb_fielddef_name(f)); + txtenc_printf(e, "%s {", upb_FieldDef_Name(f)); txtenc_endfield(e); e->indent_depth++; @@ -247,24 +266,23 @@ static void txtenc_mapentry(txtenc *e, upb_msgval key, upb_msgval val, * value: 456 * } */ -static void txtenc_map(txtenc *e, const upb_map *map, const upb_fielddef *f) { +static void txtenc_map(txtenc* e, const upb_Map* map, const upb_FieldDef* f) { if (e->options & UPB_TXTENC_NOSORT) { - size_t iter = UPB_MAP_BEGIN; - while (upb_mapiter_next(map, &iter)) { - upb_msgval key = upb_mapiter_key(map, iter); - upb_msgval val = upb_mapiter_value(map, iter); + size_t iter = kUpb_Map_Begin; + while (upb_MapIterator_Next(map, &iter)) { + upb_MessageValue key = upb_MapIterator_Key(map, iter); + upb_MessageValue val = upb_MapIterator_Value(map, iter); txtenc_mapentry(e, key, val, f); } } else { - const upb_msgdef *entry = upb_fielddef_msgsubdef(f); - const upb_fielddef *key_f = upb_msgdef_field(entry, 0); + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key_f = upb_MessageDef_Field(entry, 0); _upb_sortedmap sorted; - upb_map_entry ent; + upb_MapEntry ent; - _upb_mapsorter_pushmap(&e->sorter, upb_fielddef_descriptortype(key_f), map, - &sorted); + _upb_mapsorter_pushmap(&e->sorter, upb_FieldDef_Type(key_f), map, &sorted); while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) { - upb_msgval key, val; + upb_MessageValue key, val; memcpy(&key, &ent.k, sizeof(key)); memcpy(&val, &ent.v, sizeof(val)); txtenc_mapentry(e, key, val, f); @@ -273,10 +291,15 @@ static void txtenc_map(txtenc *e, const upb_map *map, const upb_fielddef *f) { } } -#define CHK(x) do { if (!(x)) { return false; } } while(0) +#define CHK(x) \ + do { \ + if (!(x)) { \ + return false; \ + } \ + } while (0) -static const char *txtenc_parsevarint(const char *ptr, const char *limit, - uint64_t *val) { +static const char* txtenc_parsevarint(const char* ptr, const char* limit, + uint64_t* val) { uint8_t byte; int bitpos = 0; *val = 0; @@ -302,7 +325,7 @@ static const char *txtenc_parsevarint(const char *ptr, const char *limit, * 1: 111 * } */ -static const char *txtenc_unknown(txtenc *e, const char *ptr, const char *end, +static const char* txtenc_unknown(txtenc* e, const char* ptr, const char* end, int groupnum) { while (ptr < end) { uint64_t tag_64; @@ -311,7 +334,7 @@ static const char *txtenc_unknown(txtenc *e, const char *ptr, const char *end, CHK(tag_64 < UINT32_MAX); tag = (uint32_t)tag_64; - if ((tag & 7) == UPB_WIRE_TYPE_END_GROUP) { + if ((tag & 7) == kUpb_WireType_EndGroup) { CHK((tag >> 3) == (uint32_t)groupnum); return ptr; } @@ -320,13 +343,13 @@ static const char *txtenc_unknown(txtenc *e, const char *ptr, const char *end, txtenc_printf(e, "%d: ", (int)(tag >> 3)); switch (tag & 7) { - case UPB_WIRE_TYPE_VARINT: { + case kUpb_WireType_Varint: { uint64_t val; CHK(ptr = txtenc_parsevarint(ptr, end, &val)); txtenc_printf(e, "%" PRIu64, val); break; } - case UPB_WIRE_TYPE_32BIT: { + case kUpb_WireType_32Bit: { uint32_t val; CHK(end - ptr >= 4); memcpy(&val, ptr, 4); @@ -334,7 +357,7 @@ static const char *txtenc_unknown(txtenc *e, const char *ptr, const char *end, txtenc_printf(e, "0x%08" PRIu32, val); break; } - case UPB_WIRE_TYPE_64BIT: { + case kUpb_WireType_64Bit: { uint64_t val; CHK(end - ptr >= 8); memcpy(&val, ptr, 8); @@ -342,10 +365,10 @@ static const char *txtenc_unknown(txtenc *e, const char *ptr, const char *end, txtenc_printf(e, "0x%016" PRIu64, val); break; } - case UPB_WIRE_TYPE_DELIMITED: { + case kUpb_WireType_Delimited: { uint64_t len; size_t avail = end - ptr; - char *start = e->ptr; + char* start = e->ptr; size_t start_overflow = e->overflow; CHK(ptr = txtenc_parsevarint(ptr, end, &len)); CHK(avail >= len); @@ -360,7 +383,7 @@ static const char *txtenc_unknown(txtenc *e, const char *ptr, const char *end, txtenc_putstr(e, "}"); } else { /* Didn't work out, print as raw bytes. */ - upb_strview str; + upb_StringView str; e->indent_depth--; e->ptr = start; e->overflow = start_overflow; @@ -371,7 +394,7 @@ static const char *txtenc_unknown(txtenc *e, const char *ptr, const char *end, ptr += len; break; } - case UPB_WIRE_TYPE_START_GROUP: + case kUpb_WireType_StartGroup: txtenc_putstr(e, "{"); txtenc_endfield(e); e->indent_depth++; @@ -389,16 +412,16 @@ static const char *txtenc_unknown(txtenc *e, const char *ptr, const char *end, #undef CHK -static void txtenc_msg(txtenc *e, const upb_msg *msg, - const upb_msgdef *m) { - size_t iter = UPB_MSG_BEGIN; - const upb_fielddef *f; - upb_msgval val; +static void txtenc_msg(txtenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + size_t iter = kUpb_Message_Begin; + const upb_FieldDef* f; + upb_MessageValue val; - while (upb_msg_next(msg, m, e->ext_pool, &f, &val, &iter)) { - if (upb_fielddef_ismap(f)) { + while (upb_Message_Next(msg, m, e->ext_pool, &f, &val, &iter)) { + if (upb_FieldDef_IsMap(f)) { txtenc_map(e, val.map_val, f); - } else if (upb_fielddef_isseq(f)) { + } else if (upb_FieldDef_IsRepeated(f)) { txtenc_array(e, val.array_val, f); } else { txtenc_field(e, val, f); @@ -407,8 +430,8 @@ static void txtenc_msg(txtenc *e, const upb_msg *msg, if ((e->options & UPB_TXTENC_SKIPUNKNOWN) == 0) { size_t len; - const char *ptr = upb_msg_getunknown(msg, &len); - char *start = e->ptr; + const char* ptr = upb_Message_GetUnknown(msg, &len); + char* start = e->ptr; if (ptr) { if (!txtenc_unknown(e, ptr, ptr + len, -1)) { /* Unknown failed to parse, back up and don't print it at all. */ @@ -418,7 +441,7 @@ static void txtenc_msg(txtenc *e, const upb_msg *msg, } } -size_t txtenc_nullz(txtenc *e, size_t size) { +size_t txtenc_nullz(txtenc* e, size_t size) { size_t ret = e->ptr - e->buf + e->overflow; if (size > 0) { @@ -429,9 +452,9 @@ size_t txtenc_nullz(txtenc *e, size_t size) { return ret; } -size_t upb_text_encode(const upb_msg *msg, const upb_msgdef *m, - const upb_symtab *ext_pool, int options, char *buf, - size_t size) { +size_t upb_TextEncode(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int options, char* buf, + size_t size) { txtenc e; e.buf = buf; diff --git a/contrib/libs/grpc/third_party/upb/upb/text_encode.h b/contrib/libs/grpc/third_party/upb/upb/text_encode.h index 9456082a38..2e817a3e50 100644 --- a/contrib/libs/grpc/third_party/upb/upb/text_encode.h +++ b/contrib/libs/grpc/third_party/upb/upb/text_encode.h @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -53,12 +53,12 @@ enum { * size (excluding NULL) is returned. This means that a return value >= |size| * implies that the output was truncated. (These are the same semantics as * snprintf()). */ -size_t upb_text_encode(const upb_msg *msg, const upb_msgdef *m, - const upb_symtab *ext_pool, int options, char *buf, - size_t size); +size_t upb_TextEncode(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int options, char* buf, + size_t size); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif -#endif /* UPB_TEXTENCODE_H_ */ +#endif /* UPB_TEXTENCODE_H_ */ diff --git a/contrib/libs/grpc/third_party/upb/upb/upb.c b/contrib/libs/grpc/third_party/upb/upb/upb.c index 48621b9f6e..55730bbe82 100644 --- a/contrib/libs/grpc/third_party/upb/upb/upb.c +++ b/contrib/libs/grpc/third_party/upb/upb/upb.c @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -25,9 +25,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "upb/upb_internal.h" - #include <errno.h> +#include <float.h> #include <stdarg.h> #include <stddef.h> #include <stdint.h> @@ -35,53 +34,60 @@ #include <stdlib.h> #include <string.h> +#include "upb/upb_internal.h" + +// Must be last. #include "upb/port_def.inc" -/* upb_status *****************************************************************/ +/* upb_Status *****************************************************************/ -void upb_status_clear(upb_status *status) { +void upb_Status_Clear(upb_Status* status) { if (!status) return; status->ok = true; status->msg[0] = '\0'; } -bool upb_ok(const upb_status *status) { return status->ok; } +bool upb_Status_IsOk(const upb_Status* status) { return status->ok; } -const char *upb_status_errmsg(const upb_status *status) { return status->msg; } +const char* upb_Status_ErrorMessage(const upb_Status* status) { + return status->msg; +} -void upb_status_seterrmsg(upb_status *status, const char *msg) { +void upb_Status_SetErrorMessage(upb_Status* status, const char* msg) { if (!status) return; status->ok = false; - strncpy(status->msg, msg, UPB_STATUS_MAX_MESSAGE - 1); - status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; + strncpy(status->msg, msg, _kUpb_Status_MaxMessage - 1); + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; } -void upb_status_seterrf(upb_status *status, const char *fmt, ...) { +void upb_Status_SetErrorFormat(upb_Status* status, const char* fmt, ...) { va_list args; va_start(args, fmt); - upb_status_vseterrf(status, fmt, args); + upb_Status_VSetErrorFormat(status, fmt, args); va_end(args); } -void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) { +void upb_Status_VSetErrorFormat(upb_Status* status, const char* fmt, + va_list args) { if (!status) return; status->ok = false; vsnprintf(status->msg, sizeof(status->msg), fmt, args); - status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; } -void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args) { +void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, + va_list args) { size_t len; if (!status) return; status->ok = false; len = strlen(status->msg); vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args); - status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; } /* upb_alloc ******************************************************************/ -static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, +static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize, size_t size) { UPB_UNUSED(alloc); UPB_UNUSED(oldsize); @@ -93,53 +99,53 @@ static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, } } -static uint32_t *upb_cleanup_pointer(uintptr_t cleanup_metadata) { - return (uint32_t *)(cleanup_metadata & ~0x1); +static uint32_t* upb_cleanup_pointer(uintptr_t cleanup_metadata) { + return (uint32_t*)(cleanup_metadata & ~0x1); } static bool upb_cleanup_has_initial_block(uintptr_t cleanup_metadata) { return cleanup_metadata & 0x1; } -static uintptr_t upb_cleanup_metadata(uint32_t *cleanup, +static uintptr_t upb_cleanup_metadata(uint32_t* cleanup, bool has_initial_block) { return (uintptr_t)cleanup | has_initial_block; } upb_alloc upb_alloc_global = {&upb_global_allocfunc}; -/* upb_arena ******************************************************************/ +/* upb_Arena ******************************************************************/ /* Be conservative and choose 16 in case anyone is using SSE. */ struct mem_block { - struct mem_block *next; + struct mem_block* next; uint32_t size; uint32_t cleanups; /* Data follows. */ }; typedef struct cleanup_ent { - upb_cleanup_func *cleanup; - void *ud; + upb_CleanupFunc* cleanup; + void* ud; } cleanup_ent; static const size_t memblock_reserve = UPB_ALIGN_UP(sizeof(mem_block), 16); -static upb_arena *arena_findroot(upb_arena *a) { +static upb_Arena* arena_findroot(upb_Arena* a) { /* Path splitting keeps time complexity down, see: * https://en.wikipedia.org/wiki/Disjoint-set_data_structure */ while (a->parent != a) { - upb_arena *next = a->parent; + upb_Arena* next = a->parent; a->parent = next->parent; a = next; } return a; } -static void upb_arena_addblock(upb_arena *a, upb_arena *root, void *ptr, +static void upb_Arena_addblock(upb_Arena* a, upb_Arena* root, void* ptr, size_t size) { - mem_block *block = ptr; + mem_block* block = ptr; /* The block is for arena |a|, but should appear in the freelist of |root|. */ block->next = root->freelist; @@ -157,33 +163,33 @@ static void upb_arena_addblock(upb_arena *a, upb_arena *root, void *ptr, UPB_POISON_MEMORY_REGION(a->head.ptr, a->head.end - a->head.ptr); } -static bool upb_arena_allocblock(upb_arena *a, size_t size) { - upb_arena *root = arena_findroot(a); +static bool upb_Arena_Allocblock(upb_Arena* a, size_t size) { + upb_Arena* root = arena_findroot(a); size_t block_size = UPB_MAX(size, a->last_size * 2) + memblock_reserve; - mem_block *block = upb_malloc(root->block_alloc, block_size); + mem_block* block = upb_malloc(root->block_alloc, block_size); if (!block) return false; - upb_arena_addblock(a, root, block, block_size); + upb_Arena_addblock(a, root, block, block_size); return true; } -void *_upb_arena_slowmalloc(upb_arena *a, size_t size) { - if (!upb_arena_allocblock(a, size)) return NULL; /* Out of memory. */ - UPB_ASSERT(_upb_arenahas(a) >= size); - return upb_arena_malloc(a, size); +void* _upb_Arena_SlowMalloc(upb_Arena* a, size_t size) { + if (!upb_Arena_Allocblock(a, size)) return NULL; /* Out of memory. */ + UPB_ASSERT(_upb_ArenaHas(a) >= size); + return upb_Arena_Malloc(a, size); } -static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize, +static void* upb_Arena_doalloc(upb_alloc* alloc, void* ptr, size_t oldsize, size_t size) { - upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */ - return upb_arena_realloc(a, ptr, oldsize, size); + upb_Arena* a = (upb_Arena*)alloc; /* upb_alloc is initial member. */ + return upb_Arena_Realloc(a, ptr, oldsize, size); } /* Public Arena API ***********************************************************/ -upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) { - const size_t first_block_overhead = sizeof(upb_arena) + memblock_reserve; - upb_arena *a; +upb_Arena* arena_initslow(void* mem, size_t n, upb_alloc* alloc) { + const size_t first_block_overhead = sizeof(upb_Arena) + memblock_reserve; + upb_Arena* a; /* We need to malloc the initial block. */ n = first_block_overhead + 256; @@ -191,10 +197,10 @@ upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) { return NULL; } - a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena); + a = UPB_PTR_AT(mem, n - sizeof(*a), upb_Arena); n -= sizeof(*a); - a->head.alloc.func = &upb_arena_doalloc; + a->head.alloc.func = &upb_Arena_doalloc; a->block_alloc = alloc; a->parent = a; a->refcount = 1; @@ -202,17 +208,17 @@ upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) { a->freelist_tail = NULL; a->cleanup_metadata = upb_cleanup_metadata(NULL, false); - upb_arena_addblock(a, a, mem, n); + upb_Arena_addblock(a, a, mem, n); return a; } -upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { - upb_arena *a; +upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc) { + upb_Arena* a; if (n) { /* Align initial pointer up so that we return properly-aligned pointers. */ - void *aligned = (void*)UPB_ALIGN_UP((uintptr_t)mem, 16); + void* aligned = (void*)UPB_ALIGN_UP((uintptr_t)mem, 16); size_t delta = (uintptr_t)aligned - (uintptr_t)mem; n = delta <= n ? n - delta : 0; mem = aligned; @@ -220,15 +226,15 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { /* Round block size down to alignof(*a) since we will allocate the arena * itself at the end. */ - n = UPB_ALIGN_DOWN(n, UPB_ALIGN_OF(upb_arena)); + n = UPB_ALIGN_DOWN(n, UPB_ALIGN_OF(upb_Arena)); - if (UPB_UNLIKELY(n < sizeof(upb_arena))) { + if (UPB_UNLIKELY(n < sizeof(upb_Arena))) { return arena_initslow(mem, n, alloc); } - a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena); + a = UPB_PTR_AT(mem, n - sizeof(*a), upb_Arena); - a->head.alloc.func = &upb_arena_doalloc; + a->head.alloc.func = &upb_Arena_doalloc; a->block_alloc = alloc; a->parent = a; a->refcount = 1; @@ -241,18 +247,18 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { return a; } -static void arena_dofree(upb_arena *a) { - mem_block *block = a->freelist; +static void arena_dofree(upb_Arena* a) { + mem_block* block = a->freelist; UPB_ASSERT(a->parent == a); UPB_ASSERT(a->refcount == 0); while (block) { /* Load first since we are deleting block. */ - mem_block *next = block->next; + mem_block* next = block->next; if (block->cleanups > 0) { - cleanup_ent *end = UPB_PTR_AT(block, block->size, void); - cleanup_ent *ptr = end - block->cleanups; + cleanup_ent* end = UPB_PTR_AT(block, block->size, void); + cleanup_ent* ptr = end - block->cleanups; for (; ptr < end; ptr++) { ptr->cleanup(ptr->ud); @@ -264,18 +270,18 @@ static void arena_dofree(upb_arena *a) { } } -void upb_arena_free(upb_arena *a) { +void upb_Arena_Free(upb_Arena* a) { a = arena_findroot(a); if (--a->refcount == 0) arena_dofree(a); } -bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) { - cleanup_ent *ent; +bool upb_Arena_AddCleanup(upb_Arena* a, void* ud, upb_CleanupFunc* func) { + cleanup_ent* ent; uint32_t* cleanups = upb_cleanup_pointer(a->cleanup_metadata); - if (!cleanups || _upb_arenahas(a) < sizeof(cleanup_ent)) { - if (!upb_arena_allocblock(a, 128)) return false; /* Out of memory. */ - UPB_ASSERT(_upb_arenahas(a) >= sizeof(cleanup_ent)); + if (!cleanups || _upb_ArenaHas(a) < sizeof(cleanup_ent)) { + if (!upb_Arena_Allocblock(a, 128)) return false; /* Out of memory. */ + UPB_ASSERT(_upb_ArenaHas(a) >= sizeof(cleanup_ent)); cleanups = upb_cleanup_pointer(a->cleanup_metadata); } @@ -290,11 +296,11 @@ bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) { return true; } -bool upb_arena_fuse(upb_arena *a1, upb_arena *a2) { - upb_arena *r1 = arena_findroot(a1); - upb_arena *r2 = arena_findroot(a2); +bool upb_Arena_Fuse(upb_Arena* a1, upb_Arena* a2) { + upb_Arena* r1 = arena_findroot(a1); + upb_Arena* r2 = arena_findroot(a2); - if (r1 == r2) return true; /* Already fused. */ + if (r1 == r2) return true; /* Already fused. */ /* Do not fuse initial blocks since we cannot lifetime extend them. */ if (upb_cleanup_has_initial_block(r1->cleanup_metadata)) return false; @@ -306,7 +312,7 @@ bool upb_arena_fuse(upb_arena *a1, upb_arena *a2) { /* We want to join the smaller tree to the larger tree. * So swap first if they are backwards. */ if (r1->refcount < r2->refcount) { - upb_arena *tmp = r1; + upb_Arena* tmp = r1; r1 = r2; r2 = tmp; } @@ -321,3 +327,36 @@ bool upb_arena_fuse(upb_arena *a1, upb_arena *a2) { r2->parent = r1; return true; } + +/* Miscellaneous utilities ****************************************************/ + +static void upb_FixLocale(char* p) { + /* printf() is dependent on locales; sadly there is no easy and portable way + * to avoid this. This little post-processing step will translate 1,2 -> 1.2 + * since JSON needs the latter. Arguably a hack, but it is simple and the + * alternatives are far more complicated, platform-dependent, and/or larger + * in code size. */ + for (; *p; p++) { + if (*p == ',') *p = '.'; + } +} + +void _upb_EncodeRoundTripDouble(double val, char* buf, size_t size) { + assert(size >= kUpb_RoundTripBufferSize); + snprintf(buf, size, "%.*g", DBL_DIG, val); + if (strtod(buf, NULL) != val) { + snprintf(buf, size, "%.*g", DBL_DIG + 2, val); + assert(strtod(buf, NULL) == val); + } + upb_FixLocale(buf); +} + +void _upb_EncodeRoundTripFloat(float val, char* buf, size_t size) { + assert(size >= kUpb_RoundTripBufferSize); + snprintf(buf, size, "%.*g", FLT_DIG, val); + if (strtof(buf, NULL) != val) { + snprintf(buf, size, "%.*g", FLT_DIG + 3, val); + assert(strtof(buf, NULL) == val); + } + upb_FixLocale(buf); +} diff --git a/contrib/libs/grpc/third_party/upb/upb/upb.h b/contrib/libs/grpc/third_party/upb/upb/upb.h index bc0edf9dc1..12aecb46cb 100644 --- a/contrib/libs/grpc/third_party/upb/upb/upb.h +++ b/contrib/libs/grpc/third_party/upb/upb/upb.h @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -45,54 +45,56 @@ extern "C" { #endif -/* upb_status *****************************************************************/ +/* upb_Status *****************************************************************/ -#define UPB_STATUS_MAX_MESSAGE 127 +#define _kUpb_Status_MaxMessage 127 typedef struct { bool ok; - char msg[UPB_STATUS_MAX_MESSAGE]; /* Error message; NULL-terminated. */ -} upb_status; + char msg[_kUpb_Status_MaxMessage]; /* Error message; NULL-terminated. */ +} upb_Status; -const char *upb_status_errmsg(const upb_status *status); -bool upb_ok(const upb_status *status); +const char* upb_Status_ErrorMessage(const upb_Status* status); +bool upb_Status_IsOk(const upb_Status* status); /* These are no-op if |status| is NULL. */ -void upb_status_clear(upb_status *status); -void upb_status_seterrmsg(upb_status *status, const char *msg); -void upb_status_seterrf(upb_status *status, const char *fmt, ...) +void upb_Status_Clear(upb_Status* status); +void upb_Status_SetErrorMessage(upb_Status* status, const char* msg); +void upb_Status_SetErrorFormat(upb_Status* status, const char* fmt, ...) UPB_PRINTF(2, 3); -void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) - UPB_PRINTF(2, 0); -void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args) - UPB_PRINTF(2, 0); +void upb_Status_VSetErrorFormat(upb_Status* status, const char* fmt, + va_list args) UPB_PRINTF(2, 0); +void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, + va_list args) UPB_PRINTF(2, 0); -/** upb_strview ************************************************************/ +/** upb_StringView ************************************************************/ typedef struct { - const char *data; + const char* data; size_t size; -} upb_strview; +} upb_StringView; -UPB_INLINE upb_strview upb_strview_make(const char *data, size_t size) { - upb_strview ret; +UPB_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, + size_t size) { + upb_StringView ret; ret.data = data; ret.size = size; return ret; } -UPB_INLINE upb_strview upb_strview_makez(const char *data) { - return upb_strview_make(data, strlen(data)); +UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { + return upb_StringView_FromDataAndSize(data, strlen(data)); } -UPB_INLINE bool upb_strview_eql(upb_strview a, upb_strview b) { +UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; } -#define UPB_STRVIEW_INIT(ptr, len) {ptr, len} +#define UPB_STRINGVIEW_INIT(ptr, len) \ + { ptr, len } -#define UPB_STRVIEW_FORMAT "%.*s" -#define UPB_STRVIEW_ARGS(view) (int)(view).size, (view).data +#define UPB_STRINGVIEW_FORMAT "%.*s" +#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data /** upb_alloc *****************************************************************/ @@ -108,25 +110,25 @@ typedef struct upb_alloc upb_alloc; /* A malloc()/free() function. * If "size" is 0 then the function acts like free(), otherwise it acts like * realloc(). Only "oldsize" bytes from a previous allocation are preserved. */ -typedef void *upb_alloc_func(upb_alloc *alloc, void *ptr, size_t oldsize, +typedef void* upb_alloc_func(upb_alloc* alloc, void* ptr, size_t oldsize, size_t size); struct upb_alloc { - upb_alloc_func *func; + upb_alloc_func* func; }; -UPB_INLINE void *upb_malloc(upb_alloc *alloc, size_t size) { +UPB_INLINE void* upb_malloc(upb_alloc* alloc, size_t size) { UPB_ASSERT(alloc); return alloc->func(alloc, NULL, 0, size); } -UPB_INLINE void *upb_realloc(upb_alloc *alloc, void *ptr, size_t oldsize, +UPB_INLINE void* upb_realloc(upb_alloc* alloc, void* ptr, size_t oldsize, size_t size) { UPB_ASSERT(alloc); return alloc->func(alloc, ptr, oldsize, size); } -UPB_INLINE void upb_free(upb_alloc *alloc, void *ptr) { +UPB_INLINE void upb_free(upb_alloc* alloc, void* ptr) { assert(alloc); alloc->func(alloc, ptr, 0, 0); } @@ -140,69 +142,67 @@ extern upb_alloc upb_alloc_global; * We still get benefit because we can put custom logic into our global * allocator, like injecting out-of-memory faults in debug/testing builds. */ -UPB_INLINE void *upb_gmalloc(size_t size) { +UPB_INLINE void* upb_gmalloc(size_t size) { return upb_malloc(&upb_alloc_global, size); } -UPB_INLINE void *upb_grealloc(void *ptr, size_t oldsize, size_t size) { +UPB_INLINE void* upb_grealloc(void* ptr, size_t oldsize, size_t size) { return upb_realloc(&upb_alloc_global, ptr, oldsize, size); } -UPB_INLINE void upb_gfree(void *ptr) { - upb_free(&upb_alloc_global, ptr); -} +UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); } -/* upb_arena ******************************************************************/ +/* upb_Arena ******************************************************************/ -/* upb_arena is a specific allocator implementation that uses arena allocation. +/* upb_Arena is a specific allocator implementation that uses arena allocation. * The user provides an allocator that will be used to allocate the underlying * arena blocks. Arenas by nature do not require the individual allocations * to be freed. However the Arena does allow users to register cleanup * functions that will run when the arena is destroyed. * - * A upb_arena is *not* thread-safe. + * A upb_Arena is *not* thread-safe. * * You could write a thread-safe arena allocator that satisfies the * upb_alloc interface, but it would not be as efficient for the * single-threaded case. */ -typedef void upb_cleanup_func(void *ud); +typedef void upb_CleanupFunc(void* ud); -struct upb_arena; -typedef struct upb_arena upb_arena; +struct upb_Arena; +typedef struct upb_Arena upb_Arena; typedef struct { /* We implement the allocator interface. - * This must be the first member of upb_arena! + * This must be the first member of upb_Arena! * TODO(haberman): remove once handlers are gone. */ upb_alloc alloc; char *ptr, *end; -} _upb_arena_head; +} _upb_ArenaHead; /* Creates an arena from the given initial block (if any -- n may be 0). * Additional blocks will be allocated from |alloc|. If |alloc| is NULL, this * is a fixed-size arena and cannot grow. */ -upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc); -void upb_arena_free(upb_arena *a); -bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func); -bool upb_arena_fuse(upb_arena *a, upb_arena *b); -void *_upb_arena_slowmalloc(upb_arena *a, size_t size); +upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc); +void upb_Arena_Free(upb_Arena* a); +bool upb_Arena_AddCleanup(upb_Arena* a, void* ud, upb_CleanupFunc* func); +bool upb_Arena_Fuse(upb_Arena* a, upb_Arena* b); +void* _upb_Arena_SlowMalloc(upb_Arena* a, size_t size); -UPB_INLINE upb_alloc *upb_arena_alloc(upb_arena *a) { return (upb_alloc*)a; } +UPB_INLINE upb_alloc* upb_Arena_Alloc(upb_Arena* a) { return (upb_alloc*)a; } -UPB_INLINE size_t _upb_arenahas(upb_arena *a) { - _upb_arena_head *h = (_upb_arena_head*)a; +UPB_INLINE size_t _upb_ArenaHas(upb_Arena* a) { + _upb_ArenaHead* h = (_upb_ArenaHead*)a; return (size_t)(h->end - h->ptr); } -UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { - _upb_arena_head *h = (_upb_arena_head*)a; +UPB_INLINE void* upb_Arena_Malloc(upb_Arena* a, size_t size) { + _upb_ArenaHead* h = (_upb_ArenaHead*)a; void* ret; size = UPB_ALIGN_MALLOC(size); - if (UPB_UNLIKELY(_upb_arenahas(a) < size)) { - return _upb_arena_slowmalloc(a, size); + if (UPB_UNLIKELY(_upb_ArenaHas(a) < size)) { + return _upb_Arena_SlowMalloc(a, size); } ret = h->ptr; @@ -212,7 +212,7 @@ UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { #if UPB_ASAN { size_t guard_size = 32; - if (_upb_arenahas(a) >= guard_size) { + if (_upb_ArenaHas(a) >= guard_size) { h->ptr += guard_size; } else { h->ptr = h->end; @@ -223,9 +223,9 @@ UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { return ret; } -UPB_INLINE void *upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize, +UPB_INLINE void* upb_Arena_Realloc(upb_Arena* a, void* ptr, size_t oldsize, size_t size) { - void *ret = upb_arena_malloc(a, size); + void* ret = upb_Arena_Malloc(a, size); if (ret && oldsize > 0) { memcpy(ret, ptr, oldsize); @@ -234,100 +234,77 @@ UPB_INLINE void *upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize, return ret; } -UPB_INLINE upb_arena *upb_arena_new(void) { - return upb_arena_init(NULL, 0, &upb_alloc_global); +UPB_INLINE upb_Arena* upb_Arena_New(void) { + return upb_Arena_Init(NULL, 0, &upb_alloc_global); } /* Constants ******************************************************************/ -/* Generic function type. */ -typedef void upb_func(void); - /* A list of types as they are encoded on-the-wire. */ typedef enum { - UPB_WIRE_TYPE_VARINT = 0, - UPB_WIRE_TYPE_64BIT = 1, - UPB_WIRE_TYPE_DELIMITED = 2, - UPB_WIRE_TYPE_START_GROUP = 3, - UPB_WIRE_TYPE_END_GROUP = 4, - UPB_WIRE_TYPE_32BIT = 5 -} upb_wiretype_t; + kUpb_WireType_Varint = 0, + kUpb_WireType_64Bit = 1, + kUpb_WireType_Delimited = 2, + kUpb_WireType_StartGroup = 3, + kUpb_WireType_EndGroup = 4, + kUpb_WireType_32Bit = 5 +} upb_WireType; /* The types a field can have. Note that this list is not identical to the * types defined in descriptor.proto, which gives INT32 and SINT32 separate * types (we distinguish the two with the "integer encoding" enum below). */ typedef enum { - UPB_TYPE_BOOL = 1, - UPB_TYPE_FLOAT = 2, - UPB_TYPE_INT32 = 3, - UPB_TYPE_UINT32 = 4, - UPB_TYPE_ENUM = 5, /* Enum values are int32. */ - UPB_TYPE_MESSAGE = 6, - UPB_TYPE_DOUBLE = 7, - UPB_TYPE_INT64 = 8, - UPB_TYPE_UINT64 = 9, - UPB_TYPE_STRING = 10, - UPB_TYPE_BYTES = 11 -} upb_fieldtype_t; + kUpb_CType_Bool = 1, + kUpb_CType_Float = 2, + kUpb_CType_Int32 = 3, + kUpb_CType_UInt32 = 4, + kUpb_CType_Enum = 5, /* Enum values are int32. */ + kUpb_CType_Message = 6, + kUpb_CType_Double = 7, + kUpb_CType_Int64 = 8, + kUpb_CType_UInt64 = 9, + kUpb_CType_String = 10, + kUpb_CType_Bytes = 11 +} upb_CType; /* The repeated-ness of each field; this matches descriptor.proto. */ typedef enum { - UPB_LABEL_OPTIONAL = 1, - UPB_LABEL_REQUIRED = 2, - UPB_LABEL_REPEATED = 3 -} upb_label_t; + kUpb_Label_Optional = 1, + kUpb_Label_Required = 2, + kUpb_Label_Repeated = 3 +} upb_Label; /* Descriptor types, as defined in descriptor.proto. */ typedef enum { - /* Old (long) names. TODO(haberman): remove */ - UPB_DESCRIPTOR_TYPE_DOUBLE = 1, - UPB_DESCRIPTOR_TYPE_FLOAT = 2, - UPB_DESCRIPTOR_TYPE_INT64 = 3, - UPB_DESCRIPTOR_TYPE_UINT64 = 4, - UPB_DESCRIPTOR_TYPE_INT32 = 5, - UPB_DESCRIPTOR_TYPE_FIXED64 = 6, - UPB_DESCRIPTOR_TYPE_FIXED32 = 7, - UPB_DESCRIPTOR_TYPE_BOOL = 8, - UPB_DESCRIPTOR_TYPE_STRING = 9, - UPB_DESCRIPTOR_TYPE_GROUP = 10, - UPB_DESCRIPTOR_TYPE_MESSAGE = 11, - UPB_DESCRIPTOR_TYPE_BYTES = 12, - UPB_DESCRIPTOR_TYPE_UINT32 = 13, - UPB_DESCRIPTOR_TYPE_ENUM = 14, - UPB_DESCRIPTOR_TYPE_SFIXED32 = 15, - UPB_DESCRIPTOR_TYPE_SFIXED64 = 16, - UPB_DESCRIPTOR_TYPE_SINT32 = 17, - UPB_DESCRIPTOR_TYPE_SINT64 = 18, - - UPB_DTYPE_DOUBLE = 1, - UPB_DTYPE_FLOAT = 2, - UPB_DTYPE_INT64 = 3, - UPB_DTYPE_UINT64 = 4, - UPB_DTYPE_INT32 = 5, - UPB_DTYPE_FIXED64 = 6, - UPB_DTYPE_FIXED32 = 7, - UPB_DTYPE_BOOL = 8, - UPB_DTYPE_STRING = 9, - UPB_DTYPE_GROUP = 10, - UPB_DTYPE_MESSAGE = 11, - UPB_DTYPE_BYTES = 12, - UPB_DTYPE_UINT32 = 13, - UPB_DTYPE_ENUM = 14, - UPB_DTYPE_SFIXED32 = 15, - UPB_DTYPE_SFIXED64 = 16, - UPB_DTYPE_SINT32 = 17, - UPB_DTYPE_SINT64 = 18 -} upb_descriptortype_t; - -#define UPB_MAP_BEGIN ((size_t)-1) - -UPB_INLINE bool _upb_isle(void) { + kUpb_FieldType_Double = 1, + kUpb_FieldType_Float = 2, + kUpb_FieldType_Int64 = 3, + kUpb_FieldType_UInt64 = 4, + kUpb_FieldType_Int32 = 5, + kUpb_FieldType_Fixed64 = 6, + kUpb_FieldType_Fixed32 = 7, + kUpb_FieldType_Bool = 8, + kUpb_FieldType_String = 9, + kUpb_FieldType_Group = 10, + kUpb_FieldType_Message = 11, + kUpb_FieldType_Bytes = 12, + kUpb_FieldType_UInt32 = 13, + kUpb_FieldType_Enum = 14, + kUpb_FieldType_SFixed32 = 15, + kUpb_FieldType_SFixed64 = 16, + kUpb_FieldType_SInt32 = 17, + kUpb_FieldType_SInt64 = 18 +} upb_FieldType; + +#define kUpb_Map_Begin ((size_t)-1) + +UPB_INLINE bool _upb_IsLittleEndian(void) { int x = 1; return *(char*)&x == 1; } -UPB_INLINE uint32_t _upb_be_swap32(uint32_t val) { - if (_upb_isle()) { +UPB_INLINE uint32_t _upb_BigEndian_Swap32(uint32_t val) { + if (_upb_IsLittleEndian()) { return val; } else { return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | @@ -335,15 +312,16 @@ UPB_INLINE uint32_t _upb_be_swap32(uint32_t val) { } } -UPB_INLINE uint64_t _upb_be_swap64(uint64_t val) { - if (_upb_isle()) { +UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) { + if (_upb_IsLittleEndian()) { return val; } else { - return ((uint64_t)_upb_be_swap32(val) << 32) | _upb_be_swap32(val >> 32); + return ((uint64_t)_upb_BigEndian_Swap32(val) << 32) | + _upb_BigEndian_Swap32(val >> 32); } } -UPB_INLINE int _upb_lg2ceil(int x) { +UPB_INLINE int _upb_Log2Ceiling(int x) { if (x <= 1) return 0; #ifdef __GNUC__ return 32 - __builtin_clz(x - 1); @@ -354,14 +332,12 @@ UPB_INLINE int _upb_lg2ceil(int x) { #endif } -UPB_INLINE int _upb_lg2ceilsize(int x) { - return 1 << _upb_lg2ceil(x); -} +UPB_INLINE int _upb_Log2Ceilingsize(int x) { return 1 << _upb_Log2Ceiling(x); } #include "upb/port_undef.inc" #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif -#endif /* UPB_H_ */ +#endif /* UPB_H_ */ diff --git a/contrib/libs/grpc/third_party/upb/upb/upb.hpp b/contrib/libs/grpc/third_party/upb/upb/upb.hpp index 361053745a..2e4a21beac 100644 --- a/contrib/libs/grpc/third_party/upb/upb/upb.hpp +++ b/contrib/libs/grpc/third_party/upb/upb/upb.hpp @@ -12,11 +12,11 @@ // names of its contributors may be used to endorse or promote products // derived from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -34,63 +34,66 @@ namespace upb { class Status { public: - Status() { upb_status_clear(&status_); } + Status() { upb_Status_Clear(&status_); } - upb_status* ptr() { return &status_; } + upb_Status* ptr() { return &status_; } // Returns true if there is no error. - bool ok() const { return upb_ok(&status_); } + bool ok() const { return upb_Status_IsOk(&status_); } // Guaranteed to be NULL-terminated. - const char *error_message() const { return upb_status_errmsg(&status_); } + const char* error_message() const { + return upb_Status_ErrorMessage(&status_); + } // The error message will be truncated if it is longer than - // UPB_STATUS_MAX_MESSAGE-4. - void SetErrorMessage(const char *msg) { upb_status_seterrmsg(&status_, msg); } - void SetFormattedErrorMessage(const char *fmt, ...) { + // _kUpb_Status_MaxMessage-4. + void SetErrorMessage(const char* msg) { + upb_Status_SetErrorMessage(&status_, msg); + } + void SetFormattedErrorMessage(const char* fmt, ...) { va_list args; va_start(args, fmt); - upb_status_vseterrf(&status_, fmt, args); + upb_Status_VSetErrorFormat(&status_, fmt, args); va_end(args); } // Resets the status to a successful state with no message. - void Clear() { upb_status_clear(&status_); } + void Clear() { upb_Status_Clear(&status_); } private: - upb_status status_; + upb_Status status_; }; class Arena { public: // A simple arena with no initial memory block and the default allocator. - Arena() : ptr_(upb_arena_new(), upb_arena_free) {} - Arena(char *initial_block, size_t size) - : ptr_(upb_arena_init(initial_block, size, &upb_alloc_global), - upb_arena_free) {} + Arena() : ptr_(upb_Arena_New(), upb_Arena_Free) {} + Arena(char* initial_block, size_t size) + : ptr_(upb_Arena_Init(initial_block, size, &upb_alloc_global), + upb_Arena_Free) {} - upb_arena* ptr() { return ptr_.get(); } + upb_Arena* ptr() { return ptr_.get(); } // Allows this arena to be used as a generic allocator. // // The arena does not need free() calls so when using Arena as an allocator // it is safe to skip them. However they are no-ops so there is no harm in // calling free() either. - upb_alloc *allocator() { return upb_arena_alloc(ptr_.get()); } + upb_alloc* allocator() { return upb_Arena_Alloc(ptr_.get()); } // Add a cleanup function to run when the arena is destroyed. // Returns false on out-of-memory. template <class T> - bool Own(T *obj) { - return upb_arena_addcleanup(ptr_.get(), obj, [](void* obj) { - delete static_cast<T*>(obj); - }); + bool Own(T* obj) { + return upb_Arena_AddCleanup(ptr_.get(), obj, + [](void* obj) { delete static_cast<T*>(obj); }); } - void Fuse(Arena& other) { upb_arena_fuse(ptr(), other.ptr()); } + void Fuse(Arena& other) { upb_Arena_Fuse(ptr(), other.ptr()); } private: - std::unique_ptr<upb_arena, decltype(&upb_arena_free)> ptr_; + std::unique_ptr<upb_Arena, decltype(&upb_Arena_Free)> ptr_; }; // InlinedArena seeds the arenas with a predefined amount of memory. No @@ -109,4 +112,4 @@ class InlinedArena : public Arena { } // namespace upb -#endif // UPB_HPP_ +#endif // UPB_HPP_ diff --git a/contrib/libs/grpc/third_party/upb/upb/upb_internal.h b/contrib/libs/grpc/third_party/upb/upb/upb_internal.h index ae50678b5f..1eb166f7d3 100644 --- a/contrib/libs/grpc/third_party/upb/upb/upb_internal.h +++ b/contrib/libs/grpc/third_party/upb/upb/upb_internal.h @@ -13,11 +13,11 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -33,8 +33,8 @@ struct mem_block; typedef struct mem_block mem_block; -struct upb_arena { - _upb_arena_head head; +struct upb_Arena { + _upb_ArenaHead head; /* Stores cleanup metadata for this arena. * - a pointer to the current cleanup counter. * - a boolean indicating if there is an unowned initial block. */ @@ -42,17 +42,27 @@ struct upb_arena { /* Allocator to allocate arena blocks. We are responsible for freeing these * when we are destroyed. */ - upb_alloc *block_alloc; + upb_alloc* block_alloc; uint32_t last_size; /* When multiple arenas are fused together, each arena points to a parent * arena (root points to itself). The root tracks how many live arenas * reference it. */ - uint32_t refcount; /* Only used when a->parent == a */ - struct upb_arena *parent; + uint32_t refcount; /* Only used when a->parent == a */ + struct upb_Arena* parent; /* Linked list of blocks to free/cleanup. */ mem_block *freelist, *freelist_tail; }; -#endif /* UPB_INT_H_ */ +// Encodes a float or double that is round-trippable, but as short as possible. +// These routines are not fully optimal (not guaranteed to be shortest), but are +// short-ish and match the implementation that has been used in protobuf since +// the beginning. +// +// The given buffer size must be at least kUpb_RoundTripBufferSize. +enum { kUpb_RoundTripBufferSize = 32 }; +void _upb_EncodeRoundTripDouble(double val, char* buf, size_t size); +void _upb_EncodeRoundTripFloat(float val, char* buf, size_t size); + +#endif /* UPB_INT_H_ */ diff --git a/contrib/libs/grpc/third_party/upb/ya.make b/contrib/libs/grpc/third_party/upb/ya.make index 524296fc96..9ee160fe32 100644 --- a/contrib/libs/grpc/third_party/upb/ya.make +++ b/contrib/libs/grpc/third_party/upb/ya.make @@ -2,7 +2,10 @@ LIBRARY() -LICENSE(BSD-3-Clause) +LICENSE( + BSD-3-Clause AND + MIT +) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) @@ -29,6 +32,9 @@ ENDIF() SRCS( src/core/ext/upb-generated/google/protobuf/descriptor.upb.c src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c + third_party/upb/third_party/utf8_range/naive.c + third_party/upb/third_party/utf8_range/range2-neon.c + third_party/upb/third_party/utf8_range/range2-sse.c third_party/upb/upb/decode.c third_party/upb/upb/decode_fast.c third_party/upb/upb/def.c |