Auto-generate files after cl/594280505

pull/15214/head
Protobuf Team Bot 1 year ago
parent 0eac807f3b
commit c2c01b6166
  1. 834
      php/ext/google/protobuf/php-upb.c
  2. 166
      php/ext/google/protobuf/php-upb.h
  3. 834
      ruby/ext/google/protobuf_c/ruby-upb.c
  4. 166
      ruby/ext/google/protobuf_c/ruby-upb.h

@ -8026,457 +8026,127 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables,
}
const char _kUpb_ToBase92[] = {
' ', '!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
'>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
'Z', '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '{', '|', '}', '~',
};
const int8_t _kUpb_FromBase92[] = {
0, 1, -1, 2, 3, 4, 5, -1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, -1, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
};
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
// Must be last.
typedef struct {
uint64_t present_values_mask;
uint32_t last_written_value;
} upb_MtDataEncoderInternal_EnumState;
typedef struct {
uint64_t msg_modifiers;
uint32_t last_field_num;
enum {
kUpb_OneofState_NotStarted,
kUpb_OneofState_StartedOneof,
kUpb_OneofState_EmittedOneofField,
} oneof_state;
} upb_MtDataEncoderInternal_MsgState;
#define EXTREG_KEY_SIZE (sizeof(upb_MiniTable*) + sizeof(uint32_t))
typedef struct {
char* buf_start; // Only for checking kUpb_MtDataEncoder_MinSize.
union {
upb_MtDataEncoderInternal_EnumState enum_state;
upb_MtDataEncoderInternal_MsgState msg_state;
} state;
} upb_MtDataEncoderInternal;
struct upb_ExtensionRegistry {
upb_Arena* arena;
upb_strtable exts; // Key is upb_MiniTable* concatenated with fieldnum.
};
static upb_MtDataEncoderInternal* upb_MtDataEncoder_GetInternal(
upb_MtDataEncoder* e, char* buf_start) {
UPB_ASSERT(sizeof(upb_MtDataEncoderInternal) <= sizeof(e->internal));
upb_MtDataEncoderInternal* ret = (upb_MtDataEncoderInternal*)e->internal;
ret->buf_start = buf_start;
return ret;
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));
}
static char* upb_MtDataEncoder_PutRaw(upb_MtDataEncoder* e, char* ptr,
char ch) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
UPB_ASSERT(ptr - in->buf_start < kUpb_MtDataEncoder_MinSize);
if (ptr == e->end) return NULL;
*ptr++ = ch;
return ptr;
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;
}
static char* upb_MtDataEncoder_Put(upb_MtDataEncoder* e, char* ptr, char ch) {
return upb_MtDataEncoder_PutRaw(e, ptr, _upb_ToBase92(ch));
UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r,
const upb_MiniTableExtension* e) {
char buf[EXTREG_KEY_SIZE];
extreg_key(buf, e->UPB_PRIVATE(extendee), upb_MiniTableExtension_Number(e));
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) return false;
return upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE,
upb_value_constptr(e), r->arena);
}
static char* upb_MtDataEncoder_PutBase92Varint(upb_MtDataEncoder* e, char* ptr,
uint32_t val, int min, int max) {
int shift = upb_Log2Ceiling(_upb_FromBase92(max) - _upb_FromBase92(min) + 1);
UPB_ASSERT(shift <= 6);
uint32_t mask = (1 << shift) - 1;
do {
uint32_t bits = val & mask;
ptr = upb_MtDataEncoder_Put(e, ptr, bits + _upb_FromBase92(min));
if (!ptr) return NULL;
val >>= shift;
} while (val);
return ptr;
bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r,
const upb_MiniTableExtension** e,
size_t count) {
const upb_MiniTableExtension** start = e;
const upb_MiniTableExtension** end = UPB_PTRADD(e, count);
for (; e < end; e++) {
if (!upb_ExtensionRegistry_Add(r, *e)) goto failure;
}
return true;
char* upb_MtDataEncoder_PutModifier(upb_MtDataEncoder* e, char* ptr,
uint64_t mod) {
if (mod) {
ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, mod,
kUpb_EncodedValue_MinModifier,
kUpb_EncodedValue_MaxModifier);
failure:
// Back out the entries previously added.
for (end = e, e = start; e < end; e++) {
const upb_MiniTableExtension* ext = *e;
char buf[EXTREG_KEY_SIZE];
extreg_key(buf, ext->UPB_PRIVATE(extendee),
upb_MiniTableExtension_Number(ext));
upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
}
return ptr;
return false;
}
char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = 0;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup(
const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num) {
char buf[EXTREG_KEY_SIZE];
upb_value v;
extreg_key(buf, t, num);
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
return upb_value_getconstptr(v);
} else {
return NULL;
}
}
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_ExtensionV1);
if (!ptr) return NULL;
return upb_MtDataEncoder_PutField(e, ptr, type, field_num, field_mod);
}
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr,
upb_FieldType key_type,
upb_FieldType value_type, uint64_t key_mod,
uint64_t value_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = 0;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MapV1);
if (!ptr) return NULL;
// Must be last.
ptr = upb_MtDataEncoder_PutField(e, ptr, key_type, 1, key_mod);
if (!ptr) return NULL;
const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
const upb_MiniTable* m, uint32_t number) {
const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX
return upb_MtDataEncoder_PutField(e, ptr, value_type, 2, value_mod);
// Ideal case: index into dense fields
if (i < m->UPB_PRIVATE(dense_below)) {
UPB_ASSERT(m->UPB_PRIVATE(fields)[i].UPB_PRIVATE(number) == number);
return &m->UPB_PRIVATE(fields)[i];
}
char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr) {
(void)upb_MtDataEncoder_GetInternal(e, ptr);
return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageSetV1);
// Slow case: binary search
int lo = m->UPB_PRIVATE(dense_below);
int hi = m->UPB_PRIVATE(field_count) - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
uint32_t num = m->UPB_PRIVATE(fields)[mid].UPB_PRIVATE(number);
if (num < number) {
lo = mid + 1;
continue;
}
char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr,
uint64_t msg_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = msg_mod;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageV1);
if (!ptr) return NULL;
return upb_MtDataEncoder_PutModifier(e, ptr, msg_mod);
if (num > number) {
hi = mid - 1;
continue;
}
static char* _upb_MtDataEncoder_MaybePutFieldSkip(upb_MtDataEncoder* e,
char* ptr,
uint32_t field_num) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
if (field_num <= in->state.msg_state.last_field_num) return NULL;
if (in->state.msg_state.last_field_num + 1 != field_num) {
// Put skip.
UPB_ASSERT(field_num > in->state.msg_state.last_field_num);
uint32_t skip = field_num - in->state.msg_state.last_field_num;
ptr = upb_MtDataEncoder_PutBase92Varint(
e, ptr, skip, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
if (!ptr) return NULL;
return &m->UPB_PRIVATE(fields)[mid];
}
in->state.msg_state.last_field_num = field_num;
return ptr;
return NULL;
}
static char* _upb_MtDataEncoder_PutFieldType(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type,
uint64_t field_mod) {
static const char kUpb_TypeToEncoded[] = {
[kUpb_FieldType_Double] = kUpb_EncodedType_Double,
[kUpb_FieldType_Float] = kUpb_EncodedType_Float,
[kUpb_FieldType_Int64] = kUpb_EncodedType_Int64,
[kUpb_FieldType_UInt64] = kUpb_EncodedType_UInt64,
[kUpb_FieldType_Int32] = kUpb_EncodedType_Int32,
[kUpb_FieldType_Fixed64] = kUpb_EncodedType_Fixed64,
[kUpb_FieldType_Fixed32] = kUpb_EncodedType_Fixed32,
[kUpb_FieldType_Bool] = kUpb_EncodedType_Bool,
[kUpb_FieldType_String] = kUpb_EncodedType_String,
[kUpb_FieldType_Group] = kUpb_EncodedType_Group,
[kUpb_FieldType_Message] = kUpb_EncodedType_Message,
[kUpb_FieldType_Bytes] = kUpb_EncodedType_Bytes,
[kUpb_FieldType_UInt32] = kUpb_EncodedType_UInt32,
[kUpb_FieldType_Enum] = kUpb_EncodedType_OpenEnum,
[kUpb_FieldType_SFixed32] = kUpb_EncodedType_SFixed32,
[kUpb_FieldType_SFixed64] = kUpb_EncodedType_SFixed64,
[kUpb_FieldType_SInt32] = kUpb_EncodedType_SInt32,
[kUpb_FieldType_SInt64] = kUpb_EncodedType_SInt64,
};
int encoded_type = kUpb_TypeToEncoded[type];
if (field_mod & kUpb_FieldModifier_IsClosedEnum) {
UPB_ASSERT(type == kUpb_FieldType_Enum);
encoded_type = kUpb_EncodedType_ClosedEnum;
const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
const upb_MiniTableField* f) {
if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) {
return NULL;
}
if (field_mod & kUpb_FieldModifier_IsRepeated) {
// Repeated fields shift the type number up (unlike other modifiers which
// are bit flags).
encoded_type += kUpb_EncodedType_RepeatedBase;
const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* end =
&m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
for (; ptr < end; ptr++) {
if (ptr->presence == (*f).presence) {
return ptr;
}
return upb_MtDataEncoder_Put(e, ptr, encoded_type);
}
static char* _upb_MtDataEncoder_MaybePutModifiers(upb_MtDataEncoder* e,
char* ptr, upb_FieldType type,
uint64_t field_mod) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
uint32_t encoded_modifiers = 0;
if ((field_mod & kUpb_FieldModifier_IsRepeated) &&
upb_FieldType_IsPackable(type)) {
bool field_is_packed = field_mod & kUpb_FieldModifier_IsPacked;
bool default_is_packed = in->state.msg_state.msg_modifiers &
kUpb_MessageModifier_DefaultIsPacked;
if (field_is_packed != default_is_packed) {
encoded_modifiers |= kUpb_EncodedFieldModifier_FlipPacked;
}
}
if (type == kUpb_FieldType_String) {
bool field_validates_utf8 = field_mod & kUpb_FieldModifier_ValidateUtf8;
bool message_validates_utf8 =
in->state.msg_state.msg_modifiers & kUpb_MessageModifier_ValidateUtf8;
if (field_validates_utf8 != message_validates_utf8) {
// Old binaries do not recognize the field modifier. We need the failure
// mode to be too lax rather than too strict. Our caller should have
// handled this (see _upb_MessageDef_ValidateUtf8()).
assert(!message_validates_utf8);
encoded_modifiers |= kUpb_EncodedFieldModifier_FlipValidateUtf8;
}
}
if (field_mod & kUpb_FieldModifier_IsProto3Singular) {
encoded_modifiers |= kUpb_EncodedFieldModifier_IsProto3Singular;
}
if (field_mod & kUpb_FieldModifier_IsRequired) {
encoded_modifiers |= kUpb_EncodedFieldModifier_IsRequired;
}
return upb_MtDataEncoder_PutModifier(e, ptr, encoded_modifiers);
}
char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod) {
upb_MtDataEncoder_GetInternal(e, ptr);
ptr = _upb_MtDataEncoder_MaybePutFieldSkip(e, ptr, field_num);
if (!ptr) return NULL;
ptr = _upb_MtDataEncoder_PutFieldType(e, ptr, type, field_mod);
if (!ptr) return NULL;
return _upb_MtDataEncoder_MaybePutModifiers(e, ptr, type, field_mod);
}
char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (in->state.msg_state.oneof_state == kUpb_OneofState_NotStarted) {
ptr = upb_MtDataEncoder_Put(e, ptr, _upb_FromBase92(kUpb_EncodedValue_End));
} else {
ptr = upb_MtDataEncoder_Put(
e, ptr, _upb_FromBase92(kUpb_EncodedValue_OneofSeparator));
}
in->state.msg_state.oneof_state = kUpb_OneofState_StartedOneof;
return ptr;
}
char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
uint32_t field_num) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (in->state.msg_state.oneof_state == kUpb_OneofState_EmittedOneofField) {
ptr = upb_MtDataEncoder_Put(
e, ptr, _upb_FromBase92(kUpb_EncodedValue_FieldSeparator));
if (!ptr) return NULL;
}
ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, field_num, _upb_ToBase92(0),
_upb_ToBase92(63));
in->state.msg_state.oneof_state = kUpb_OneofState_EmittedOneofField;
return ptr;
}
char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.enum_state.present_values_mask = 0;
in->state.enum_state.last_written_value = 0;
return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_EnumV1);
}
static char* upb_MtDataEncoder_FlushDenseEnumMask(upb_MtDataEncoder* e,
char* ptr) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
ptr = upb_MtDataEncoder_Put(e, ptr, in->state.enum_state.present_values_mask);
in->state.enum_state.present_values_mask = 0;
in->state.enum_state.last_written_value += 5;
return ptr;
}
char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
uint32_t val) {
// TODO: optimize this encoding.
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
UPB_ASSERT(val >= in->state.enum_state.last_written_value);
uint32_t delta = val - in->state.enum_state.last_written_value;
if (delta >= 5 && in->state.enum_state.present_values_mask) {
ptr = upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
if (!ptr) {
return NULL;
}
delta -= 5;
}
if (delta >= 5) {
ptr = upb_MtDataEncoder_PutBase92Varint(
e, ptr, delta, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
in->state.enum_state.last_written_value += delta;
delta = 0;
}
UPB_ASSERT((in->state.enum_state.present_values_mask >> delta) == 0);
in->state.enum_state.present_values_mask |= 1ULL << delta;
return ptr;
}
char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (!in->state.enum_state.present_values_mask) return ptr;
return upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
}
#include <stddef.h>
#include <stdint.h>
#include <string.h>
// Must be last.
#define EXTREG_KEY_SIZE (sizeof(upb_MiniTable*) + sizeof(uint32_t))
struct upb_ExtensionRegistry {
upb_Arena* arena;
upb_strtable exts; // Key is upb_MiniTable* concatenated with 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_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;
}
UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r,
const upb_MiniTableExtension* e) {
char buf[EXTREG_KEY_SIZE];
extreg_key(buf, e->UPB_PRIVATE(extendee), upb_MiniTableExtension_Number(e));
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) return false;
return upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE,
upb_value_constptr(e), r->arena);
}
bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r,
const upb_MiniTableExtension** e,
size_t count) {
const upb_MiniTableExtension** start = e;
const upb_MiniTableExtension** end = UPB_PTRADD(e, count);
for (; e < end; e++) {
if (!upb_ExtensionRegistry_Add(r, *e)) goto failure;
}
return true;
failure:
// Back out the entries previously added.
for (end = e, e = start; e < end; e++) {
const upb_MiniTableExtension* ext = *e;
char buf[EXTREG_KEY_SIZE];
extreg_key(buf, ext->UPB_PRIVATE(extendee),
upb_MiniTableExtension_Number(ext));
upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
}
return false;
}
const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup(
const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num) {
char buf[EXTREG_KEY_SIZE];
upb_value v;
extreg_key(buf, t, num);
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
return upb_value_getconstptr(v);
} else {
return NULL;
}
}
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
// Must be last.
const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
const upb_MiniTable* m, uint32_t number) {
const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX
// Ideal case: index into dense fields
if (i < m->UPB_PRIVATE(dense_below)) {
UPB_ASSERT(m->UPB_PRIVATE(fields)[i].UPB_PRIVATE(number) == number);
return &m->UPB_PRIVATE(fields)[i];
}
// Slow case: binary search
int lo = m->UPB_PRIVATE(dense_below);
int hi = m->UPB_PRIVATE(field_count) - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
uint32_t num = m->UPB_PRIVATE(fields)[mid].UPB_PRIVATE(number);
if (num < number) {
lo = mid + 1;
continue;
}
if (num > number) {
hi = mid - 1;
continue;
}
return &m->UPB_PRIVATE(fields)[mid];
}
return NULL;
}
const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
const upb_MiniTableField* f) {
if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) {
return NULL;
}
const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* end =
&m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
for (; ptr < end; ptr++) {
if (ptr->presence == (*f).presence) {
return ptr;
}
}
return NULL;
}
return NULL;
}
bool upb_MiniTable_NextOneofField(const upb_MiniTable* m,
@ -15883,6 +15553,336 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
}
const char _kUpb_ToBase92[] = {
' ', '!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
'>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
'Z', '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '{', '|', '}', '~',
};
const int8_t _kUpb_FromBase92[] = {
0, 1, -1, 2, 3, 4, 5, -1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, -1, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
};
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
// Must be last.
typedef struct {
uint64_t present_values_mask;
uint32_t last_written_value;
} upb_MtDataEncoderInternal_EnumState;
typedef struct {
uint64_t msg_modifiers;
uint32_t last_field_num;
enum {
kUpb_OneofState_NotStarted,
kUpb_OneofState_StartedOneof,
kUpb_OneofState_EmittedOneofField,
} oneof_state;
} upb_MtDataEncoderInternal_MsgState;
typedef struct {
char* buf_start; // Only for checking kUpb_MtDataEncoder_MinSize.
union {
upb_MtDataEncoderInternal_EnumState enum_state;
upb_MtDataEncoderInternal_MsgState msg_state;
} state;
} upb_MtDataEncoderInternal;
static upb_MtDataEncoderInternal* upb_MtDataEncoder_GetInternal(
upb_MtDataEncoder* e, char* buf_start) {
UPB_ASSERT(sizeof(upb_MtDataEncoderInternal) <= sizeof(e->internal));
upb_MtDataEncoderInternal* ret = (upb_MtDataEncoderInternal*)e->internal;
ret->buf_start = buf_start;
return ret;
}
static char* upb_MtDataEncoder_PutRaw(upb_MtDataEncoder* e, char* ptr,
char ch) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
UPB_ASSERT(ptr - in->buf_start < kUpb_MtDataEncoder_MinSize);
if (ptr == e->end) return NULL;
*ptr++ = ch;
return ptr;
}
static char* upb_MtDataEncoder_Put(upb_MtDataEncoder* e, char* ptr, char ch) {
return upb_MtDataEncoder_PutRaw(e, ptr, _upb_ToBase92(ch));
}
static char* upb_MtDataEncoder_PutBase92Varint(upb_MtDataEncoder* e, char* ptr,
uint32_t val, int min, int max) {
int shift = upb_Log2Ceiling(_upb_FromBase92(max) - _upb_FromBase92(min) + 1);
UPB_ASSERT(shift <= 6);
uint32_t mask = (1 << shift) - 1;
do {
uint32_t bits = val & mask;
ptr = upb_MtDataEncoder_Put(e, ptr, bits + _upb_FromBase92(min));
if (!ptr) return NULL;
val >>= shift;
} while (val);
return ptr;
}
char* upb_MtDataEncoder_PutModifier(upb_MtDataEncoder* e, char* ptr,
uint64_t mod) {
if (mod) {
ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, mod,
kUpb_EncodedValue_MinModifier,
kUpb_EncodedValue_MaxModifier);
}
return ptr;
}
char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = 0;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_ExtensionV1);
if (!ptr) return NULL;
return upb_MtDataEncoder_PutField(e, ptr, type, field_num, field_mod);
}
char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr,
upb_FieldType key_type,
upb_FieldType value_type, uint64_t key_mod,
uint64_t value_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = 0;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MapV1);
if (!ptr) return NULL;
ptr = upb_MtDataEncoder_PutField(e, ptr, key_type, 1, key_mod);
if (!ptr) return NULL;
return upb_MtDataEncoder_PutField(e, ptr, value_type, 2, value_mod);
}
char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr) {
(void)upb_MtDataEncoder_GetInternal(e, ptr);
return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageSetV1);
}
char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr,
uint64_t msg_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = msg_mod;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageV1);
if (!ptr) return NULL;
return upb_MtDataEncoder_PutModifier(e, ptr, msg_mod);
}
static char* _upb_MtDataEncoder_MaybePutFieldSkip(upb_MtDataEncoder* e,
char* ptr,
uint32_t field_num) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
if (field_num <= in->state.msg_state.last_field_num) return NULL;
if (in->state.msg_state.last_field_num + 1 != field_num) {
// Put skip.
UPB_ASSERT(field_num > in->state.msg_state.last_field_num);
uint32_t skip = field_num - in->state.msg_state.last_field_num;
ptr = upb_MtDataEncoder_PutBase92Varint(
e, ptr, skip, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
if (!ptr) return NULL;
}
in->state.msg_state.last_field_num = field_num;
return ptr;
}
static char* _upb_MtDataEncoder_PutFieldType(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type,
uint64_t field_mod) {
static const char kUpb_TypeToEncoded[] = {
[kUpb_FieldType_Double] = kUpb_EncodedType_Double,
[kUpb_FieldType_Float] = kUpb_EncodedType_Float,
[kUpb_FieldType_Int64] = kUpb_EncodedType_Int64,
[kUpb_FieldType_UInt64] = kUpb_EncodedType_UInt64,
[kUpb_FieldType_Int32] = kUpb_EncodedType_Int32,
[kUpb_FieldType_Fixed64] = kUpb_EncodedType_Fixed64,
[kUpb_FieldType_Fixed32] = kUpb_EncodedType_Fixed32,
[kUpb_FieldType_Bool] = kUpb_EncodedType_Bool,
[kUpb_FieldType_String] = kUpb_EncodedType_String,
[kUpb_FieldType_Group] = kUpb_EncodedType_Group,
[kUpb_FieldType_Message] = kUpb_EncodedType_Message,
[kUpb_FieldType_Bytes] = kUpb_EncodedType_Bytes,
[kUpb_FieldType_UInt32] = kUpb_EncodedType_UInt32,
[kUpb_FieldType_Enum] = kUpb_EncodedType_OpenEnum,
[kUpb_FieldType_SFixed32] = kUpb_EncodedType_SFixed32,
[kUpb_FieldType_SFixed64] = kUpb_EncodedType_SFixed64,
[kUpb_FieldType_SInt32] = kUpb_EncodedType_SInt32,
[kUpb_FieldType_SInt64] = kUpb_EncodedType_SInt64,
};
int encoded_type = kUpb_TypeToEncoded[type];
if (field_mod & kUpb_FieldModifier_IsClosedEnum) {
UPB_ASSERT(type == kUpb_FieldType_Enum);
encoded_type = kUpb_EncodedType_ClosedEnum;
}
if (field_mod & kUpb_FieldModifier_IsRepeated) {
// Repeated fields shift the type number up (unlike other modifiers which
// are bit flags).
encoded_type += kUpb_EncodedType_RepeatedBase;
}
return upb_MtDataEncoder_Put(e, ptr, encoded_type);
}
static char* _upb_MtDataEncoder_MaybePutModifiers(upb_MtDataEncoder* e,
char* ptr, upb_FieldType type,
uint64_t field_mod) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
uint32_t encoded_modifiers = 0;
if ((field_mod & kUpb_FieldModifier_IsRepeated) &&
upb_FieldType_IsPackable(type)) {
bool field_is_packed = field_mod & kUpb_FieldModifier_IsPacked;
bool default_is_packed = in->state.msg_state.msg_modifiers &
kUpb_MessageModifier_DefaultIsPacked;
if (field_is_packed != default_is_packed) {
encoded_modifiers |= kUpb_EncodedFieldModifier_FlipPacked;
}
}
if (type == kUpb_FieldType_String) {
bool field_validates_utf8 = field_mod & kUpb_FieldModifier_ValidateUtf8;
bool message_validates_utf8 =
in->state.msg_state.msg_modifiers & kUpb_MessageModifier_ValidateUtf8;
if (field_validates_utf8 != message_validates_utf8) {
// Old binaries do not recognize the field modifier. We need the failure
// mode to be too lax rather than too strict. Our caller should have
// handled this (see _upb_MessageDef_ValidateUtf8()).
assert(!message_validates_utf8);
encoded_modifiers |= kUpb_EncodedFieldModifier_FlipValidateUtf8;
}
}
if (field_mod & kUpb_FieldModifier_IsProto3Singular) {
encoded_modifiers |= kUpb_EncodedFieldModifier_IsProto3Singular;
}
if (field_mod & kUpb_FieldModifier_IsRequired) {
encoded_modifiers |= kUpb_EncodedFieldModifier_IsRequired;
}
return upb_MtDataEncoder_PutModifier(e, ptr, encoded_modifiers);
}
char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod) {
upb_MtDataEncoder_GetInternal(e, ptr);
ptr = _upb_MtDataEncoder_MaybePutFieldSkip(e, ptr, field_num);
if (!ptr) return NULL;
ptr = _upb_MtDataEncoder_PutFieldType(e, ptr, type, field_mod);
if (!ptr) return NULL;
return _upb_MtDataEncoder_MaybePutModifiers(e, ptr, type, field_mod);
}
char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (in->state.msg_state.oneof_state == kUpb_OneofState_NotStarted) {
ptr = upb_MtDataEncoder_Put(e, ptr, _upb_FromBase92(kUpb_EncodedValue_End));
} else {
ptr = upb_MtDataEncoder_Put(
e, ptr, _upb_FromBase92(kUpb_EncodedValue_OneofSeparator));
}
in->state.msg_state.oneof_state = kUpb_OneofState_StartedOneof;
return ptr;
}
char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
uint32_t field_num) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (in->state.msg_state.oneof_state == kUpb_OneofState_EmittedOneofField) {
ptr = upb_MtDataEncoder_Put(
e, ptr, _upb_FromBase92(kUpb_EncodedValue_FieldSeparator));
if (!ptr) return NULL;
}
ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, field_num, _upb_ToBase92(0),
_upb_ToBase92(63));
in->state.msg_state.oneof_state = kUpb_OneofState_EmittedOneofField;
return ptr;
}
char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.enum_state.present_values_mask = 0;
in->state.enum_state.last_written_value = 0;
return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_EnumV1);
}
static char* upb_MtDataEncoder_FlushDenseEnumMask(upb_MtDataEncoder* e,
char* ptr) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
ptr = upb_MtDataEncoder_Put(e, ptr, in->state.enum_state.present_values_mask);
in->state.enum_state.present_values_mask = 0;
in->state.enum_state.last_written_value += 5;
return ptr;
}
char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
uint32_t val) {
// TODO: optimize this encoding.
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
UPB_ASSERT(val >= in->state.enum_state.last_written_value);
uint32_t delta = val - in->state.enum_state.last_written_value;
if (delta >= 5 && in->state.enum_state.present_values_mask) {
ptr = upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
if (!ptr) {
return NULL;
}
delta -= 5;
}
if (delta >= 5) {
ptr = upb_MtDataEncoder_PutBase92Varint(
e, ptr, delta, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
in->state.enum_state.last_written_value += delta;
delta = 0;
}
UPB_ASSERT((in->state.enum_state.present_values_mask >> delta) == 0);
in->state.enum_state.present_values_mask |= 1ULL << delta;
return ptr;
}
char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (!in->state.enum_state.present_values_mask) return ptr;
return upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
}
#include <stddef.h>
// Must be last.

@ -12926,89 +12926,6 @@ typedef enum {
#endif // UPB_MINI_DESCRIPTOR_INTERNAL_MODIFIERS_H_
#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_
#define UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_
#include <stdint.h>
// Must be last.
// If the input buffer has at least this many bytes available, the encoder call
// is guaranteed to succeed (as long as field number order is maintained).
#define kUpb_MtDataEncoder_MinSize 16
typedef struct {
char* end; // Limit of the buffer passed as a parameter.
// Aliased to internal-only members in .cc.
char internal[32];
} upb_MtDataEncoder;
#ifdef __cplusplus
extern "C" {
#endif
// Encodes field/oneof information for a given message. The sequence of calls
// should look like:
//
// upb_MtDataEncoder e;
// char buf[256];
// char* ptr = buf;
// e.end = ptr + sizeof(buf);
// unit64_t msg_mod = ...; // bitwise & of kUpb_MessageModifiers or zero
// ptr = upb_MtDataEncoder_StartMessage(&e, ptr, msg_mod);
// // Fields *must* be in field number order.
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
//
// // If oneofs are present. Oneofs must be encoded after regular fields.
// ptr = upb_MiniTable_StartOneof(&e, ptr)
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
//
// ptr = upb_MiniTable_StartOneof(&e, ptr);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
//
// Oneofs must be encoded after all regular fields.
char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr,
uint64_t msg_mod);
char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod);
char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr);
char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
uint32_t field_num);
// Encodes the set of values for a given enum. The values must be given in
// order (after casting to uint32_t), and repeats are not allowed.
char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr);
char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
uint32_t val);
char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr);
// Encodes an entire mini descriptor for an extension.
char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod);
// Encodes an entire mini descriptor for a map.
char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr,
upb_FieldType key_type,
upb_FieldType value_type, uint64_t key_mod,
uint64_t value_mod);
// Encodes an entire mini descriptor for a message set.
char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_ */
#ifndef UPB_MINI_TABLE_COMPAT_H_
#define UPB_MINI_TABLE_COMPAT_H_
@ -13410,6 +13327,89 @@ upb_ServiceDef* _upb_ServiceDefs_New(upb_DefBuilder* ctx, int n,
#define UPB_REFLECTION_DESC_STATE_INTERNAL_H_
#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_
#define UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_
#include <stdint.h>
// Must be last.
// If the input buffer has at least this many bytes available, the encoder call
// is guaranteed to succeed (as long as field number order is maintained).
#define kUpb_MtDataEncoder_MinSize 16
typedef struct {
char* end; // Limit of the buffer passed as a parameter.
// Aliased to internal-only members in .cc.
char internal[32];
} upb_MtDataEncoder;
#ifdef __cplusplus
extern "C" {
#endif
// Encodes field/oneof information for a given message. The sequence of calls
// should look like:
//
// upb_MtDataEncoder e;
// char buf[256];
// char* ptr = buf;
// e.end = ptr + sizeof(buf);
// unit64_t msg_mod = ...; // bitwise & of kUpb_MessageModifiers or zero
// ptr = upb_MtDataEncoder_StartMessage(&e, ptr, msg_mod);
// // Fields *must* be in field number order.
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
//
// // If oneofs are present. Oneofs must be encoded after regular fields.
// ptr = upb_MiniTable_StartOneof(&e, ptr)
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
//
// ptr = upb_MiniTable_StartOneof(&e, ptr);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
//
// Oneofs must be encoded after all regular fields.
char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr,
uint64_t msg_mod);
char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod);
char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr);
char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
uint32_t field_num);
// Encodes the set of values for a given enum. The values must be given in
// order (after casting to uint32_t), and repeats are not allowed.
char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr);
char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
uint32_t val);
char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr);
// Encodes an entire mini descriptor for an extension.
char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod);
// Encodes an entire mini descriptor for a map.
char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr,
upb_FieldType key_type,
upb_FieldType value_type, uint64_t key_mod,
uint64_t value_mod);
// Encodes an entire mini descriptor for a message set.
char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_ */
// Must be last.
// Manages the storage for mini descriptor strings as they are being encoded.

@ -7542,457 +7542,127 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables,
}
const char _kUpb_ToBase92[] = {
' ', '!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
'>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
'Z', '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '{', '|', '}', '~',
};
const int8_t _kUpb_FromBase92[] = {
0, 1, -1, 2, 3, 4, 5, -1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, -1, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
};
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
// Must be last.
typedef struct {
uint64_t present_values_mask;
uint32_t last_written_value;
} upb_MtDataEncoderInternal_EnumState;
typedef struct {
uint64_t msg_modifiers;
uint32_t last_field_num;
enum {
kUpb_OneofState_NotStarted,
kUpb_OneofState_StartedOneof,
kUpb_OneofState_EmittedOneofField,
} oneof_state;
} upb_MtDataEncoderInternal_MsgState;
#define EXTREG_KEY_SIZE (sizeof(upb_MiniTable*) + sizeof(uint32_t))
typedef struct {
char* buf_start; // Only for checking kUpb_MtDataEncoder_MinSize.
union {
upb_MtDataEncoderInternal_EnumState enum_state;
upb_MtDataEncoderInternal_MsgState msg_state;
} state;
} upb_MtDataEncoderInternal;
struct upb_ExtensionRegistry {
upb_Arena* arena;
upb_strtable exts; // Key is upb_MiniTable* concatenated with fieldnum.
};
static upb_MtDataEncoderInternal* upb_MtDataEncoder_GetInternal(
upb_MtDataEncoder* e, char* buf_start) {
UPB_ASSERT(sizeof(upb_MtDataEncoderInternal) <= sizeof(e->internal));
upb_MtDataEncoderInternal* ret = (upb_MtDataEncoderInternal*)e->internal;
ret->buf_start = buf_start;
return ret;
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));
}
static char* upb_MtDataEncoder_PutRaw(upb_MtDataEncoder* e, char* ptr,
char ch) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
UPB_ASSERT(ptr - in->buf_start < kUpb_MtDataEncoder_MinSize);
if (ptr == e->end) return NULL;
*ptr++ = ch;
return ptr;
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;
}
static char* upb_MtDataEncoder_Put(upb_MtDataEncoder* e, char* ptr, char ch) {
return upb_MtDataEncoder_PutRaw(e, ptr, _upb_ToBase92(ch));
UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r,
const upb_MiniTableExtension* e) {
char buf[EXTREG_KEY_SIZE];
extreg_key(buf, e->UPB_PRIVATE(extendee), upb_MiniTableExtension_Number(e));
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) return false;
return upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE,
upb_value_constptr(e), r->arena);
}
static char* upb_MtDataEncoder_PutBase92Varint(upb_MtDataEncoder* e, char* ptr,
uint32_t val, int min, int max) {
int shift = upb_Log2Ceiling(_upb_FromBase92(max) - _upb_FromBase92(min) + 1);
UPB_ASSERT(shift <= 6);
uint32_t mask = (1 << shift) - 1;
do {
uint32_t bits = val & mask;
ptr = upb_MtDataEncoder_Put(e, ptr, bits + _upb_FromBase92(min));
if (!ptr) return NULL;
val >>= shift;
} while (val);
return ptr;
bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r,
const upb_MiniTableExtension** e,
size_t count) {
const upb_MiniTableExtension** start = e;
const upb_MiniTableExtension** end = UPB_PTRADD(e, count);
for (; e < end; e++) {
if (!upb_ExtensionRegistry_Add(r, *e)) goto failure;
}
return true;
char* upb_MtDataEncoder_PutModifier(upb_MtDataEncoder* e, char* ptr,
uint64_t mod) {
if (mod) {
ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, mod,
kUpb_EncodedValue_MinModifier,
kUpb_EncodedValue_MaxModifier);
failure:
// Back out the entries previously added.
for (end = e, e = start; e < end; e++) {
const upb_MiniTableExtension* ext = *e;
char buf[EXTREG_KEY_SIZE];
extreg_key(buf, ext->UPB_PRIVATE(extendee),
upb_MiniTableExtension_Number(ext));
upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
}
return ptr;
return false;
}
char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = 0;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup(
const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num) {
char buf[EXTREG_KEY_SIZE];
upb_value v;
extreg_key(buf, t, num);
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
return upb_value_getconstptr(v);
} else {
return NULL;
}
}
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_ExtensionV1);
if (!ptr) return NULL;
return upb_MtDataEncoder_PutField(e, ptr, type, field_num, field_mod);
}
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr,
upb_FieldType key_type,
upb_FieldType value_type, uint64_t key_mod,
uint64_t value_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = 0;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MapV1);
if (!ptr) return NULL;
// Must be last.
ptr = upb_MtDataEncoder_PutField(e, ptr, key_type, 1, key_mod);
if (!ptr) return NULL;
const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
const upb_MiniTable* m, uint32_t number) {
const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX
return upb_MtDataEncoder_PutField(e, ptr, value_type, 2, value_mod);
// Ideal case: index into dense fields
if (i < m->UPB_PRIVATE(dense_below)) {
UPB_ASSERT(m->UPB_PRIVATE(fields)[i].UPB_PRIVATE(number) == number);
return &m->UPB_PRIVATE(fields)[i];
}
char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr) {
(void)upb_MtDataEncoder_GetInternal(e, ptr);
return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageSetV1);
// Slow case: binary search
int lo = m->UPB_PRIVATE(dense_below);
int hi = m->UPB_PRIVATE(field_count) - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
uint32_t num = m->UPB_PRIVATE(fields)[mid].UPB_PRIVATE(number);
if (num < number) {
lo = mid + 1;
continue;
}
char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr,
uint64_t msg_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = msg_mod;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageV1);
if (!ptr) return NULL;
return upb_MtDataEncoder_PutModifier(e, ptr, msg_mod);
if (num > number) {
hi = mid - 1;
continue;
}
static char* _upb_MtDataEncoder_MaybePutFieldSkip(upb_MtDataEncoder* e,
char* ptr,
uint32_t field_num) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
if (field_num <= in->state.msg_state.last_field_num) return NULL;
if (in->state.msg_state.last_field_num + 1 != field_num) {
// Put skip.
UPB_ASSERT(field_num > in->state.msg_state.last_field_num);
uint32_t skip = field_num - in->state.msg_state.last_field_num;
ptr = upb_MtDataEncoder_PutBase92Varint(
e, ptr, skip, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
if (!ptr) return NULL;
return &m->UPB_PRIVATE(fields)[mid];
}
in->state.msg_state.last_field_num = field_num;
return ptr;
return NULL;
}
static char* _upb_MtDataEncoder_PutFieldType(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type,
uint64_t field_mod) {
static const char kUpb_TypeToEncoded[] = {
[kUpb_FieldType_Double] = kUpb_EncodedType_Double,
[kUpb_FieldType_Float] = kUpb_EncodedType_Float,
[kUpb_FieldType_Int64] = kUpb_EncodedType_Int64,
[kUpb_FieldType_UInt64] = kUpb_EncodedType_UInt64,
[kUpb_FieldType_Int32] = kUpb_EncodedType_Int32,
[kUpb_FieldType_Fixed64] = kUpb_EncodedType_Fixed64,
[kUpb_FieldType_Fixed32] = kUpb_EncodedType_Fixed32,
[kUpb_FieldType_Bool] = kUpb_EncodedType_Bool,
[kUpb_FieldType_String] = kUpb_EncodedType_String,
[kUpb_FieldType_Group] = kUpb_EncodedType_Group,
[kUpb_FieldType_Message] = kUpb_EncodedType_Message,
[kUpb_FieldType_Bytes] = kUpb_EncodedType_Bytes,
[kUpb_FieldType_UInt32] = kUpb_EncodedType_UInt32,
[kUpb_FieldType_Enum] = kUpb_EncodedType_OpenEnum,
[kUpb_FieldType_SFixed32] = kUpb_EncodedType_SFixed32,
[kUpb_FieldType_SFixed64] = kUpb_EncodedType_SFixed64,
[kUpb_FieldType_SInt32] = kUpb_EncodedType_SInt32,
[kUpb_FieldType_SInt64] = kUpb_EncodedType_SInt64,
};
int encoded_type = kUpb_TypeToEncoded[type];
if (field_mod & kUpb_FieldModifier_IsClosedEnum) {
UPB_ASSERT(type == kUpb_FieldType_Enum);
encoded_type = kUpb_EncodedType_ClosedEnum;
const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
const upb_MiniTableField* f) {
if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) {
return NULL;
}
if (field_mod & kUpb_FieldModifier_IsRepeated) {
// Repeated fields shift the type number up (unlike other modifiers which
// are bit flags).
encoded_type += kUpb_EncodedType_RepeatedBase;
const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* end =
&m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
for (; ptr < end; ptr++) {
if (ptr->presence == (*f).presence) {
return ptr;
}
return upb_MtDataEncoder_Put(e, ptr, encoded_type);
}
static char* _upb_MtDataEncoder_MaybePutModifiers(upb_MtDataEncoder* e,
char* ptr, upb_FieldType type,
uint64_t field_mod) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
uint32_t encoded_modifiers = 0;
if ((field_mod & kUpb_FieldModifier_IsRepeated) &&
upb_FieldType_IsPackable(type)) {
bool field_is_packed = field_mod & kUpb_FieldModifier_IsPacked;
bool default_is_packed = in->state.msg_state.msg_modifiers &
kUpb_MessageModifier_DefaultIsPacked;
if (field_is_packed != default_is_packed) {
encoded_modifiers |= kUpb_EncodedFieldModifier_FlipPacked;
}
}
if (type == kUpb_FieldType_String) {
bool field_validates_utf8 = field_mod & kUpb_FieldModifier_ValidateUtf8;
bool message_validates_utf8 =
in->state.msg_state.msg_modifiers & kUpb_MessageModifier_ValidateUtf8;
if (field_validates_utf8 != message_validates_utf8) {
// Old binaries do not recognize the field modifier. We need the failure
// mode to be too lax rather than too strict. Our caller should have
// handled this (see _upb_MessageDef_ValidateUtf8()).
assert(!message_validates_utf8);
encoded_modifiers |= kUpb_EncodedFieldModifier_FlipValidateUtf8;
}
}
if (field_mod & kUpb_FieldModifier_IsProto3Singular) {
encoded_modifiers |= kUpb_EncodedFieldModifier_IsProto3Singular;
}
if (field_mod & kUpb_FieldModifier_IsRequired) {
encoded_modifiers |= kUpb_EncodedFieldModifier_IsRequired;
}
return upb_MtDataEncoder_PutModifier(e, ptr, encoded_modifiers);
}
char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod) {
upb_MtDataEncoder_GetInternal(e, ptr);
ptr = _upb_MtDataEncoder_MaybePutFieldSkip(e, ptr, field_num);
if (!ptr) return NULL;
ptr = _upb_MtDataEncoder_PutFieldType(e, ptr, type, field_mod);
if (!ptr) return NULL;
return _upb_MtDataEncoder_MaybePutModifiers(e, ptr, type, field_mod);
}
char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (in->state.msg_state.oneof_state == kUpb_OneofState_NotStarted) {
ptr = upb_MtDataEncoder_Put(e, ptr, _upb_FromBase92(kUpb_EncodedValue_End));
} else {
ptr = upb_MtDataEncoder_Put(
e, ptr, _upb_FromBase92(kUpb_EncodedValue_OneofSeparator));
}
in->state.msg_state.oneof_state = kUpb_OneofState_StartedOneof;
return ptr;
}
char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
uint32_t field_num) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (in->state.msg_state.oneof_state == kUpb_OneofState_EmittedOneofField) {
ptr = upb_MtDataEncoder_Put(
e, ptr, _upb_FromBase92(kUpb_EncodedValue_FieldSeparator));
if (!ptr) return NULL;
}
ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, field_num, _upb_ToBase92(0),
_upb_ToBase92(63));
in->state.msg_state.oneof_state = kUpb_OneofState_EmittedOneofField;
return ptr;
}
char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.enum_state.present_values_mask = 0;
in->state.enum_state.last_written_value = 0;
return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_EnumV1);
}
static char* upb_MtDataEncoder_FlushDenseEnumMask(upb_MtDataEncoder* e,
char* ptr) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
ptr = upb_MtDataEncoder_Put(e, ptr, in->state.enum_state.present_values_mask);
in->state.enum_state.present_values_mask = 0;
in->state.enum_state.last_written_value += 5;
return ptr;
}
char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
uint32_t val) {
// TODO: optimize this encoding.
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
UPB_ASSERT(val >= in->state.enum_state.last_written_value);
uint32_t delta = val - in->state.enum_state.last_written_value;
if (delta >= 5 && in->state.enum_state.present_values_mask) {
ptr = upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
if (!ptr) {
return NULL;
}
delta -= 5;
}
if (delta >= 5) {
ptr = upb_MtDataEncoder_PutBase92Varint(
e, ptr, delta, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
in->state.enum_state.last_written_value += delta;
delta = 0;
}
UPB_ASSERT((in->state.enum_state.present_values_mask >> delta) == 0);
in->state.enum_state.present_values_mask |= 1ULL << delta;
return ptr;
}
char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (!in->state.enum_state.present_values_mask) return ptr;
return upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
}
#include <stddef.h>
#include <stdint.h>
#include <string.h>
// Must be last.
#define EXTREG_KEY_SIZE (sizeof(upb_MiniTable*) + sizeof(uint32_t))
struct upb_ExtensionRegistry {
upb_Arena* arena;
upb_strtable exts; // Key is upb_MiniTable* concatenated with 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_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;
}
UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r,
const upb_MiniTableExtension* e) {
char buf[EXTREG_KEY_SIZE];
extreg_key(buf, e->UPB_PRIVATE(extendee), upb_MiniTableExtension_Number(e));
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) return false;
return upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE,
upb_value_constptr(e), r->arena);
}
bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r,
const upb_MiniTableExtension** e,
size_t count) {
const upb_MiniTableExtension** start = e;
const upb_MiniTableExtension** end = UPB_PTRADD(e, count);
for (; e < end; e++) {
if (!upb_ExtensionRegistry_Add(r, *e)) goto failure;
}
return true;
failure:
// Back out the entries previously added.
for (end = e, e = start; e < end; e++) {
const upb_MiniTableExtension* ext = *e;
char buf[EXTREG_KEY_SIZE];
extreg_key(buf, ext->UPB_PRIVATE(extendee),
upb_MiniTableExtension_Number(ext));
upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
}
return false;
}
const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup(
const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num) {
char buf[EXTREG_KEY_SIZE];
upb_value v;
extreg_key(buf, t, num);
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
return upb_value_getconstptr(v);
} else {
return NULL;
}
}
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
// Must be last.
const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
const upb_MiniTable* m, uint32_t number) {
const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX
// Ideal case: index into dense fields
if (i < m->UPB_PRIVATE(dense_below)) {
UPB_ASSERT(m->UPB_PRIVATE(fields)[i].UPB_PRIVATE(number) == number);
return &m->UPB_PRIVATE(fields)[i];
}
// Slow case: binary search
int lo = m->UPB_PRIVATE(dense_below);
int hi = m->UPB_PRIVATE(field_count) - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
uint32_t num = m->UPB_PRIVATE(fields)[mid].UPB_PRIVATE(number);
if (num < number) {
lo = mid + 1;
continue;
}
if (num > number) {
hi = mid - 1;
continue;
}
return &m->UPB_PRIVATE(fields)[mid];
}
return NULL;
}
const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
const upb_MiniTableField* f) {
if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) {
return NULL;
}
const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* end =
&m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
for (; ptr < end; ptr++) {
if (ptr->presence == (*f).presence) {
return ptr;
}
}
return NULL;
}
return NULL;
}
bool upb_MiniTable_NextOneofField(const upb_MiniTable* m,
@ -15399,6 +15069,336 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
}
const char _kUpb_ToBase92[] = {
' ', '!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
'>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
'Z', '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '{', '|', '}', '~',
};
const int8_t _kUpb_FromBase92[] = {
0, 1, -1, 2, 3, 4, 5, -1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, -1, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
};
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
// Must be last.
typedef struct {
uint64_t present_values_mask;
uint32_t last_written_value;
} upb_MtDataEncoderInternal_EnumState;
typedef struct {
uint64_t msg_modifiers;
uint32_t last_field_num;
enum {
kUpb_OneofState_NotStarted,
kUpb_OneofState_StartedOneof,
kUpb_OneofState_EmittedOneofField,
} oneof_state;
} upb_MtDataEncoderInternal_MsgState;
typedef struct {
char* buf_start; // Only for checking kUpb_MtDataEncoder_MinSize.
union {
upb_MtDataEncoderInternal_EnumState enum_state;
upb_MtDataEncoderInternal_MsgState msg_state;
} state;
} upb_MtDataEncoderInternal;
static upb_MtDataEncoderInternal* upb_MtDataEncoder_GetInternal(
upb_MtDataEncoder* e, char* buf_start) {
UPB_ASSERT(sizeof(upb_MtDataEncoderInternal) <= sizeof(e->internal));
upb_MtDataEncoderInternal* ret = (upb_MtDataEncoderInternal*)e->internal;
ret->buf_start = buf_start;
return ret;
}
static char* upb_MtDataEncoder_PutRaw(upb_MtDataEncoder* e, char* ptr,
char ch) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
UPB_ASSERT(ptr - in->buf_start < kUpb_MtDataEncoder_MinSize);
if (ptr == e->end) return NULL;
*ptr++ = ch;
return ptr;
}
static char* upb_MtDataEncoder_Put(upb_MtDataEncoder* e, char* ptr, char ch) {
return upb_MtDataEncoder_PutRaw(e, ptr, _upb_ToBase92(ch));
}
static char* upb_MtDataEncoder_PutBase92Varint(upb_MtDataEncoder* e, char* ptr,
uint32_t val, int min, int max) {
int shift = upb_Log2Ceiling(_upb_FromBase92(max) - _upb_FromBase92(min) + 1);
UPB_ASSERT(shift <= 6);
uint32_t mask = (1 << shift) - 1;
do {
uint32_t bits = val & mask;
ptr = upb_MtDataEncoder_Put(e, ptr, bits + _upb_FromBase92(min));
if (!ptr) return NULL;
val >>= shift;
} while (val);
return ptr;
}
char* upb_MtDataEncoder_PutModifier(upb_MtDataEncoder* e, char* ptr,
uint64_t mod) {
if (mod) {
ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, mod,
kUpb_EncodedValue_MinModifier,
kUpb_EncodedValue_MaxModifier);
}
return ptr;
}
char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = 0;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_ExtensionV1);
if (!ptr) return NULL;
return upb_MtDataEncoder_PutField(e, ptr, type, field_num, field_mod);
}
char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr,
upb_FieldType key_type,
upb_FieldType value_type, uint64_t key_mod,
uint64_t value_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = 0;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MapV1);
if (!ptr) return NULL;
ptr = upb_MtDataEncoder_PutField(e, ptr, key_type, 1, key_mod);
if (!ptr) return NULL;
return upb_MtDataEncoder_PutField(e, ptr, value_type, 2, value_mod);
}
char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr) {
(void)upb_MtDataEncoder_GetInternal(e, ptr);
return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageSetV1);
}
char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr,
uint64_t msg_mod) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.msg_state.msg_modifiers = msg_mod;
in->state.msg_state.last_field_num = 0;
in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageV1);
if (!ptr) return NULL;
return upb_MtDataEncoder_PutModifier(e, ptr, msg_mod);
}
static char* _upb_MtDataEncoder_MaybePutFieldSkip(upb_MtDataEncoder* e,
char* ptr,
uint32_t field_num) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
if (field_num <= in->state.msg_state.last_field_num) return NULL;
if (in->state.msg_state.last_field_num + 1 != field_num) {
// Put skip.
UPB_ASSERT(field_num > in->state.msg_state.last_field_num);
uint32_t skip = field_num - in->state.msg_state.last_field_num;
ptr = upb_MtDataEncoder_PutBase92Varint(
e, ptr, skip, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
if (!ptr) return NULL;
}
in->state.msg_state.last_field_num = field_num;
return ptr;
}
static char* _upb_MtDataEncoder_PutFieldType(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type,
uint64_t field_mod) {
static const char kUpb_TypeToEncoded[] = {
[kUpb_FieldType_Double] = kUpb_EncodedType_Double,
[kUpb_FieldType_Float] = kUpb_EncodedType_Float,
[kUpb_FieldType_Int64] = kUpb_EncodedType_Int64,
[kUpb_FieldType_UInt64] = kUpb_EncodedType_UInt64,
[kUpb_FieldType_Int32] = kUpb_EncodedType_Int32,
[kUpb_FieldType_Fixed64] = kUpb_EncodedType_Fixed64,
[kUpb_FieldType_Fixed32] = kUpb_EncodedType_Fixed32,
[kUpb_FieldType_Bool] = kUpb_EncodedType_Bool,
[kUpb_FieldType_String] = kUpb_EncodedType_String,
[kUpb_FieldType_Group] = kUpb_EncodedType_Group,
[kUpb_FieldType_Message] = kUpb_EncodedType_Message,
[kUpb_FieldType_Bytes] = kUpb_EncodedType_Bytes,
[kUpb_FieldType_UInt32] = kUpb_EncodedType_UInt32,
[kUpb_FieldType_Enum] = kUpb_EncodedType_OpenEnum,
[kUpb_FieldType_SFixed32] = kUpb_EncodedType_SFixed32,
[kUpb_FieldType_SFixed64] = kUpb_EncodedType_SFixed64,
[kUpb_FieldType_SInt32] = kUpb_EncodedType_SInt32,
[kUpb_FieldType_SInt64] = kUpb_EncodedType_SInt64,
};
int encoded_type = kUpb_TypeToEncoded[type];
if (field_mod & kUpb_FieldModifier_IsClosedEnum) {
UPB_ASSERT(type == kUpb_FieldType_Enum);
encoded_type = kUpb_EncodedType_ClosedEnum;
}
if (field_mod & kUpb_FieldModifier_IsRepeated) {
// Repeated fields shift the type number up (unlike other modifiers which
// are bit flags).
encoded_type += kUpb_EncodedType_RepeatedBase;
}
return upb_MtDataEncoder_Put(e, ptr, encoded_type);
}
static char* _upb_MtDataEncoder_MaybePutModifiers(upb_MtDataEncoder* e,
char* ptr, upb_FieldType type,
uint64_t field_mod) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
uint32_t encoded_modifiers = 0;
if ((field_mod & kUpb_FieldModifier_IsRepeated) &&
upb_FieldType_IsPackable(type)) {
bool field_is_packed = field_mod & kUpb_FieldModifier_IsPacked;
bool default_is_packed = in->state.msg_state.msg_modifiers &
kUpb_MessageModifier_DefaultIsPacked;
if (field_is_packed != default_is_packed) {
encoded_modifiers |= kUpb_EncodedFieldModifier_FlipPacked;
}
}
if (type == kUpb_FieldType_String) {
bool field_validates_utf8 = field_mod & kUpb_FieldModifier_ValidateUtf8;
bool message_validates_utf8 =
in->state.msg_state.msg_modifiers & kUpb_MessageModifier_ValidateUtf8;
if (field_validates_utf8 != message_validates_utf8) {
// Old binaries do not recognize the field modifier. We need the failure
// mode to be too lax rather than too strict. Our caller should have
// handled this (see _upb_MessageDef_ValidateUtf8()).
assert(!message_validates_utf8);
encoded_modifiers |= kUpb_EncodedFieldModifier_FlipValidateUtf8;
}
}
if (field_mod & kUpb_FieldModifier_IsProto3Singular) {
encoded_modifiers |= kUpb_EncodedFieldModifier_IsProto3Singular;
}
if (field_mod & kUpb_FieldModifier_IsRequired) {
encoded_modifiers |= kUpb_EncodedFieldModifier_IsRequired;
}
return upb_MtDataEncoder_PutModifier(e, ptr, encoded_modifiers);
}
char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod) {
upb_MtDataEncoder_GetInternal(e, ptr);
ptr = _upb_MtDataEncoder_MaybePutFieldSkip(e, ptr, field_num);
if (!ptr) return NULL;
ptr = _upb_MtDataEncoder_PutFieldType(e, ptr, type, field_mod);
if (!ptr) return NULL;
return _upb_MtDataEncoder_MaybePutModifiers(e, ptr, type, field_mod);
}
char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (in->state.msg_state.oneof_state == kUpb_OneofState_NotStarted) {
ptr = upb_MtDataEncoder_Put(e, ptr, _upb_FromBase92(kUpb_EncodedValue_End));
} else {
ptr = upb_MtDataEncoder_Put(
e, ptr, _upb_FromBase92(kUpb_EncodedValue_OneofSeparator));
}
in->state.msg_state.oneof_state = kUpb_OneofState_StartedOneof;
return ptr;
}
char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
uint32_t field_num) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (in->state.msg_state.oneof_state == kUpb_OneofState_EmittedOneofField) {
ptr = upb_MtDataEncoder_Put(
e, ptr, _upb_FromBase92(kUpb_EncodedValue_FieldSeparator));
if (!ptr) return NULL;
}
ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, field_num, _upb_ToBase92(0),
_upb_ToBase92(63));
in->state.msg_state.oneof_state = kUpb_OneofState_EmittedOneofField;
return ptr;
}
char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
in->state.enum_state.present_values_mask = 0;
in->state.enum_state.last_written_value = 0;
return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_EnumV1);
}
static char* upb_MtDataEncoder_FlushDenseEnumMask(upb_MtDataEncoder* e,
char* ptr) {
upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
ptr = upb_MtDataEncoder_Put(e, ptr, in->state.enum_state.present_values_mask);
in->state.enum_state.present_values_mask = 0;
in->state.enum_state.last_written_value += 5;
return ptr;
}
char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
uint32_t val) {
// TODO: optimize this encoding.
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
UPB_ASSERT(val >= in->state.enum_state.last_written_value);
uint32_t delta = val - in->state.enum_state.last_written_value;
if (delta >= 5 && in->state.enum_state.present_values_mask) {
ptr = upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
if (!ptr) {
return NULL;
}
delta -= 5;
}
if (delta >= 5) {
ptr = upb_MtDataEncoder_PutBase92Varint(
e, ptr, delta, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
in->state.enum_state.last_written_value += delta;
delta = 0;
}
UPB_ASSERT((in->state.enum_state.present_values_mask >> delta) == 0);
in->state.enum_state.present_values_mask |= 1ULL << delta;
return ptr;
}
char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) {
upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
if (!in->state.enum_state.present_values_mask) return ptr;
return upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
}
#include <stddef.h>
// Must be last.

@ -12698,89 +12698,6 @@ typedef enum {
#endif // UPB_MINI_DESCRIPTOR_INTERNAL_MODIFIERS_H_
#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_
#define UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_
#include <stdint.h>
// Must be last.
// If the input buffer has at least this many bytes available, the encoder call
// is guaranteed to succeed (as long as field number order is maintained).
#define kUpb_MtDataEncoder_MinSize 16
typedef struct {
char* end; // Limit of the buffer passed as a parameter.
// Aliased to internal-only members in .cc.
char internal[32];
} upb_MtDataEncoder;
#ifdef __cplusplus
extern "C" {
#endif
// Encodes field/oneof information for a given message. The sequence of calls
// should look like:
//
// upb_MtDataEncoder e;
// char buf[256];
// char* ptr = buf;
// e.end = ptr + sizeof(buf);
// unit64_t msg_mod = ...; // bitwise & of kUpb_MessageModifiers or zero
// ptr = upb_MtDataEncoder_StartMessage(&e, ptr, msg_mod);
// // Fields *must* be in field number order.
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
//
// // If oneofs are present. Oneofs must be encoded after regular fields.
// ptr = upb_MiniTable_StartOneof(&e, ptr)
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
//
// ptr = upb_MiniTable_StartOneof(&e, ptr);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
//
// Oneofs must be encoded after all regular fields.
char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr,
uint64_t msg_mod);
char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod);
char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr);
char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
uint32_t field_num);
// Encodes the set of values for a given enum. The values must be given in
// order (after casting to uint32_t), and repeats are not allowed.
char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr);
char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
uint32_t val);
char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr);
// Encodes an entire mini descriptor for an extension.
char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod);
// Encodes an entire mini descriptor for a map.
char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr,
upb_FieldType key_type,
upb_FieldType value_type, uint64_t key_mod,
uint64_t value_mod);
// Encodes an entire mini descriptor for a message set.
char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_ */
#ifndef UPB_MINI_TABLE_COMPAT_H_
#define UPB_MINI_TABLE_COMPAT_H_
@ -13229,6 +13146,89 @@ upb_ServiceDef* _upb_ServiceDefs_New(upb_DefBuilder* ctx, int n,
#define UPB_REFLECTION_DESC_STATE_INTERNAL_H_
#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_
#define UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_
#include <stdint.h>
// Must be last.
// If the input buffer has at least this many bytes available, the encoder call
// is guaranteed to succeed (as long as field number order is maintained).
#define kUpb_MtDataEncoder_MinSize 16
typedef struct {
char* end; // Limit of the buffer passed as a parameter.
// Aliased to internal-only members in .cc.
char internal[32];
} upb_MtDataEncoder;
#ifdef __cplusplus
extern "C" {
#endif
// Encodes field/oneof information for a given message. The sequence of calls
// should look like:
//
// upb_MtDataEncoder e;
// char buf[256];
// char* ptr = buf;
// e.end = ptr + sizeof(buf);
// unit64_t msg_mod = ...; // bitwise & of kUpb_MessageModifiers or zero
// ptr = upb_MtDataEncoder_StartMessage(&e, ptr, msg_mod);
// // Fields *must* be in field number order.
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
//
// // If oneofs are present. Oneofs must be encoded after regular fields.
// ptr = upb_MiniTable_StartOneof(&e, ptr)
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
//
// ptr = upb_MiniTable_StartOneof(&e, ptr);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
//
// Oneofs must be encoded after all regular fields.
char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr,
uint64_t msg_mod);
char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod);
char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr);
char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
uint32_t field_num);
// Encodes the set of values for a given enum. The values must be given in
// order (after casting to uint32_t), and repeats are not allowed.
char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr);
char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
uint32_t val);
char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr);
// Encodes an entire mini descriptor for an extension.
char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr,
upb_FieldType type, uint32_t field_num,
uint64_t field_mod);
// Encodes an entire mini descriptor for a map.
char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr,
upb_FieldType key_type,
upb_FieldType value_type, uint64_t key_mod,
uint64_t value_mod);
// Encodes an entire mini descriptor for a message set.
char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_ */
// Must be last.
// Manages the storage for mini descriptor strings as they are being encoded.

Loading…
Cancel
Save