Addressed PR comments.

pull/13171/head
Joshua Haberman 3 years ago
parent 1618e1b9a6
commit 58c1dbc11f
  1. 653
      cmake/google/protobuf/descriptor.upb.h
  2. 6
      upb/bindings/lua/msg.c
  3. 27
      upb/decode.c
  4. 3
      upb/decode_internal.h
  5. 3
      upb/json_encode.c
  6. 21
      upbc/common.h
  7. 66
      upbc/protoc-gen-upb.cc

File diff suppressed because it is too large Load Diff

@ -955,15 +955,15 @@ static int lupb_decode(lua_State *L) {
upb_msg *msg = lupb_msg_pushnew(L, 1);
upb_arena *arena = lupb_arenaget(L, -1);
char *buf;
bool ok;
/* Copy input data to arena, message will reference it. */
buf = upb_arena_malloc(arena, len);
memcpy(buf, pb, len);
ok = _upb_decode(buf, len, msg, layout, NULL, kUpb_DecodeOption_AliasString, arena) == 0;
upb_DecodeStatus status = _upb_decode(buf, len, msg, layout, NULL,
kUpb_DecodeOption_AliasString, arena);
if (!ok) {
if (status != kUpb_DecodeStatus_Ok) {
lua_pushstring(L, "Error decoding protobuf.");
return lua_error(L);
}

@ -190,10 +190,12 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
const upb_msglayout *layout);
UPB_NORETURN static void *decode_err(upb_decstate *d, upb_DecodeStatus status) {
assert(status != kUpb_DecodeStatus_Ok);
UPB_LONGJMP(d->err, status);
}
const char *fastdecode_err(upb_decstate *d, int status) {
assert(status != kUpb_DecodeStatus_Ok);
UPB_LONGJMP(d->err, status);
return NULL;
}
@ -257,7 +259,7 @@ static const char *decode_tag(upb_decstate *d, const char *ptr, uint32_t *val) {
decode_vret res = decode_longvarint64(ptr, byte);
ptr = res.ptr;
*val = res.val;
if (!ptr || *val > UINT32_MAX || ptr - start > 5) {
if (!ptr || res.val > UINT32_MAX || ptr - start > 5) {
return decode_err(d, kUpb_DecodeStatus_Malformed);
}
return ptr;
@ -660,6 +662,17 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
return ptr;
}
// Computes a bitmask in which the |n| lowest bits are set, except that we
// skip the lowest bit (because upb never uses hasbit 0).
//
// Sample output:
// decode_requiredmask(1) => 0b10 (0x2)
// decode_requiredmask(5) => 0b111110 (0x3e)
uint64_t decode_requiredmask(int n) {
assert(0 < n && n < 63);
return ((1 << n) - 1) << 1;
}
UPB_NOINLINE
const char *decode_checkrequired(upb_decstate *d, const char *ptr,
const upb_msg *msg, const upb_msglayout *l) {
@ -667,11 +680,10 @@ const char *decode_checkrequired(upb_decstate *d, const char *ptr,
if (UPB_LIKELY((d->options & kUpb_DecodeOption_CheckRequired) == 0)) {
return ptr;
}
uint64_t required_mask = ((1 << l->required_count) - 1) << 1;
uint64_t msg_head;
memcpy(&msg_head, msg, 8);
msg_head = _upb_be_swap64(msg_head);
if (required_mask & ~msg_head) {
if (decode_requiredmask(l->required_count) & ~msg_head) {
d->missing_required = true;
}
return ptr;
@ -867,8 +879,8 @@ static const char *decode_known(upb_decstate *d, const char *ptr, upb_msg *msg,
}
}
static const char *decode_reverse_skip_varint(const char *ptr, uint64_t val) {
uint64_t seen = 0;
static const char *decode_reverse_skip_varint(const char *ptr, uint32_t val) {
uint32_t seen = 0;
do {
ptr--;
seen <<= 7;
@ -907,7 +919,8 @@ static const char *decode_unknown(upb_decstate *d, const char *ptr,
}
assert(start == d->debug_valstart);
start = decode_reverse_skip_varint(start, (field_number << 3) | wire_type);
uint32_t tag = (field_number << 3) | wire_type;
start = decode_reverse_skip_varint(start, tag);
assert(start == d->debug_tagstart);
if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
@ -1047,7 +1060,7 @@ upb_DecodeStatus _upb_decode(const char *buf, size_t size, void *msg,
state.arena.parent = arena;
upb_DecodeStatus status = UPB_SETJMP(state.err);
if (UPB_LIKELY(status == 0)) {
if (UPB_LIKELY(status == kUpb_DecodeStatus_Ok)) {
status = decode_top(&state, buf, msg, l);
}

@ -101,6 +101,9 @@ bool decode_verifyutf8_inl(const char *ptr, int len) {
return utf8_range2((const unsigned char *)ptr, end - ptr) == 0;
}
const char *decode_checkrequired(upb_decstate *d, const char *ptr,
const upb_msg *msg, const upb_msglayout *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) {

@ -374,7 +374,8 @@ static void jsonenc_any(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
upb_arena *arena = jsonenc_arena(e);
upb_msg *any = upb_msg_new(any_m, arena);
if (upb_decode(value.data, value.size, any, any_layout, arena)) {
if (upb_decode(value.data, value.size, any, any_layout, arena) !=
kUpb_DecodeStatus_Ok) {
jsonenc_err(e, "Error decoding message in Any");
}

@ -30,6 +30,7 @@
#include <vector>
#include "absl/strings/str_replace.h"
#include "absl/strings/substitute.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/io/zero_copy_stream.h"
@ -49,6 +50,26 @@ class Output {
private:
void Write(absl::string_view data) {
std::string stripped;
if (absl::StartsWith(data, "\n ")) {
size_t indent = data.substr(1).find_first_not_of(' ');
if (indent != absl::string_view::npos) {
// Remove indentation from all lines.
auto line_prefix = data.substr(0, indent + 1);
// The final line has an extra newline and is indented two less, eg.
// R"cc(
// UPB_INLINE $0 $1_$2(const $1 *msg) {
// return $1_has_$2(msg) ? *UPB_PTR_AT(msg, $3, $0) : $4;
// }
// )cc",
std::string last_line_prefix = std::string(line_prefix);
last_line_prefix.resize(last_line_prefix.size() - 2);
data.remove_prefix(line_prefix.size());
stripped = absl::StrReplaceAll(
data, {{line_prefix, "\n"}, {last_line_prefix, "\n"}});
data = stripped;
}
}
while (!data.empty()) {
RefreshOutput();
size_t to_write = std::min(data.size(), size_);

@ -418,31 +418,33 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
if (!message->options().map_entry()) {
output(
"UPB_INLINE $0 *$0_new(upb_arena *arena) {\n"
" return ($0 *)_upb_msg_new(&$1, arena);\n"
"}\n"
"UPB_INLINE $0 *$0_parse(const char *buf, size_t size,\n"
" upb_arena *arena) {\n"
" $0 *ret = $0_new(arena);\n"
" if (!ret) return NULL;\n"
" if (upb_decode(buf, size, ret, &$1, arena)) return NULL;\n"
" return ret;\n"
"}\n"
"UPB_INLINE $0 *$0_parse_ex(const char *buf, size_t size,\n"
" const upb_extreg *extreg, int options,\n"
" upb_arena *arena) {\n"
" $0 *ret = $0_new(arena);\n"
" if (!ret) return NULL;\n"
" if (_upb_decode(buf, size, ret, &$1, extreg, options, arena)) {\n"
" return NULL;\n"
" }\n"
" return ret;\n"
"}\n"
"UPB_INLINE char *$0_serialize(const $0 *msg, upb_arena *arena, size_t "
"*len) {\n"
" return upb_encode(msg, &$1, arena, len);\n"
"}\n"
"\n",
R"cc(
UPB_INLINE $0 *$0_new(upb_arena *arena) {
return ($0 *)_upb_msg_new(&$1, arena);
}
UPB_INLINE $0 *$0_parse(const char *buf, size_t size, upb_arena *arena) {
$0 *ret = $0_new(arena);
if (!ret) return NULL;
if (upb_decode(buf, size, ret, &$1, arena) != kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE $0 *$0_parse_ex(const char *buf, size_t size,
const upb_extreg *extreg, int options,
upb_arena *arena) {
$0 *ret = $0_new(arena);
if (!ret) return NULL;
if (_upb_decode(buf, size, ret, &$1, extreg, options, arena) !=
kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE char *$0_serialize(const $0 *msg, upb_arena *arena, size_t *len) {
return upb_encode(msg, &$1, arena, len);
}
)cc",
MessageName(message), MessageInit(message));
}
@ -543,14 +545,20 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
} else {
if (HasNonZeroDefault(field)) {
output(
"UPB_INLINE $0 $1_$2(const $1 *msg) { "
"return $1_has_$2(msg) ? *UPB_PTR_AT(msg, $3, $0) : $4; }\n",
R"cc(
UPB_INLINE $0 $1_$2(const $1 *msg) {
return $1_has_$2(msg) ? *UPB_PTR_AT(msg, $3, $0) : $4;
}
)cc",
CTypeConst(field), msg_name, field->name(),
GetSizeInit(layout.GetFieldOffset(field)), FieldDefault(field));
} else {
output(
"UPB_INLINE $0 $1_$2(const $1 *msg) { "
"return *UPB_PTR_AT(msg, $3, $0); }\n",
R"cc(
UPB_INLINE $0 $1_$2(const $1 *msg) {
return *UPB_PTR_AT(msg, $3, $0);
}
)cc",
CTypeConst(field), msg_name, field->name(),
GetSizeInit(layout.GetFieldOffset(field)));
}

Loading…
Cancel
Save