From 706ffdbc658e00fdf0d03715c8306eb7e7b7e963 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Tue, 18 Sep 2018 09:53:38 -0700 Subject: Fix json encoding for wrappers, ListValue, Struct and Value. (#126) * Fix json encoding for wrappers, ListValue, Struct and Value. * Add well_known_type field in upb_msgdef to specify type of well known messages. * Remove comma at end of enum definition. * Group number wrappers * Fix comments * Refactoring to use is_wellknown_{msg/field} --- upb/json/parser.rl | 256 ++++++++++++----------------------------------------- 1 file changed, 55 insertions(+), 201 deletions(-) (limited to 'upb/json/parser.rl') diff --git a/upb/json/parser.rl b/upb/json/parser.rl index 0ac49a5..217caef 100644 --- a/upb/json/parser.rl +++ b/upb/json/parser.rl @@ -37,16 +37,6 @@ #define UPB_JSON_MAX_DEPTH 64 -static const char *kDoubleValueFullMessageName = "google.protobuf.DoubleValue"; -static const char *kFloatValueFullMessageName = "google.protobuf.FloatValue"; -static const char *kInt64ValueFullMessageName = "google.protobuf.Int64Value"; -static const char *kUInt64ValueFullMessageName = "google.protobuf.UInt64Value"; -static const char *kInt32ValueFullMessageName = "google.protobuf.Int32Value"; -static const char *kUInt32ValueFullMessageName = "google.protobuf.UInt32Value"; -static const char *kBoolValueFullMessageName = "google.protobuf.BoolValue"; -static const char *kStringValueFullMessageName = "google.protobuf.StringValue"; -static const char *kBytesValueFullMessageName = "google.protobuf.BytesValue"; - /* Type of value message */ enum { VALUE_NULLVALUE = 0, @@ -59,6 +49,8 @@ enum { /* Forward declare */ static bool is_top_level(upb_json_parser *p); +static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type); +static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type); static bool is_number_wrapper_object(upb_json_parser *p); static bool does_number_wrapper_start(upb_json_parser *p); @@ -68,30 +60,6 @@ static bool is_string_wrapper_object(upb_json_parser *p); static bool does_string_wrapper_start(upb_json_parser *p); static bool does_string_wrapper_end(upb_json_parser *p); -static bool is_boolean_wrapper_object(upb_json_parser *p); -static bool does_boolean_wrapper_start(upb_json_parser *p); -static bool does_boolean_wrapper_end(upb_json_parser *p); - -static bool is_duration_object(upb_json_parser *p); -static bool does_duration_start(upb_json_parser *p); -static bool does_duration_end(upb_json_parser *p); - -static bool is_timestamp_object(upb_json_parser *p); -static bool does_timestamp_start(upb_json_parser *p); -static bool does_timestamp_end(upb_json_parser *p); - -static bool is_value_object(upb_json_parser *p); -static bool does_value_start(upb_json_parser *p); -static bool does_value_end(upb_json_parser *p); - -static bool is_listvalue_object(upb_json_parser *p); -static bool does_listvalue_start(upb_json_parser *p); -static bool does_listvalue_end(upb_json_parser *p); - -static bool is_structvalue_object(upb_json_parser *p); -static bool does_structvalue_start(upb_json_parser *p); -static bool does_structvalue_end(upb_json_parser *p); - static void start_wrapper_object(upb_json_parser *p); static void end_wrapper_object(upb_json_parser *p); @@ -699,7 +667,7 @@ static bool start_number(upb_json_parser *p, const char *ptr) { if (is_top_level(p)) { if (is_number_wrapper_object(p)) { start_wrapper_object(p); - } else if (is_value_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_NUMBERVALUE); } else { return false; @@ -709,7 +677,7 @@ static bool start_number(upb_json_parser *p, const char *ptr) { return false; } start_wrapper_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } @@ -749,7 +717,7 @@ static bool end_number(upb_json_parser *p, const char *ptr) { return true; } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -929,19 +897,19 @@ static bool parser_putbool(upb_json_parser *p, bool val) { static bool end_bool(upb_json_parser *p, bool val) { if (is_top_level(p)) { - if (is_boolean_wrapper_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) { start_wrapper_object(p); - } else if (is_value_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_BOOLVALUE); } else { return false; } - } else if (does_boolean_wrapper_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_BOOLVALUE)) { if (!start_subobject(p)) { return false; } start_wrapper_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } @@ -952,7 +920,7 @@ static bool end_bool(upb_json_parser *p, bool val) { return false; } - if (does_boolean_wrapper_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) { end_wrapper_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -960,7 +928,7 @@ static bool end_bool(upb_json_parser *p, bool val) { return true; } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -975,12 +943,12 @@ static bool end_null(upb_json_parser *p) { const char *zero_ptr = "0"; if (is_top_level(p)) { - if (is_value_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_NULLVALUE); } else { return true; } - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } @@ -1007,9 +975,10 @@ static bool start_stringval(upb_json_parser *p) { if (is_top_level(p)) { if (is_string_wrapper_object(p)) { start_wrapper_object(p); - } else if (is_timestamp_object(p) || is_duration_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) { start_object(p); - } else if (is_value_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_STRINGVALUE); } else { return false; @@ -1019,12 +988,13 @@ static bool start_stringval(upb_json_parser *p) { return false; } start_wrapper_object(p); - } else if (does_timestamp_start(p) || does_duration_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_field(p, UPB_WELLKNOWN_DURATION)) { if (!start_subobject(p)) { return false; } start_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) { return false; } @@ -1085,7 +1055,8 @@ static bool start_stringval(upb_json_parser *p) { static bool end_stringval_nontop(upb_json_parser *p) { bool ok = true; - if (is_timestamp_object(p) || is_duration_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) { multipart_end(p); return true; } @@ -1167,7 +1138,7 @@ static bool end_stringval(upb_json_parser *p) { return true; } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1175,7 +1146,8 @@ static bool end_stringval(upb_json_parser *p) { return true; } - if (does_timestamp_end(p) || does_duration_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) || + is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) { end_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1677,19 +1649,19 @@ static bool start_subobject(upb_json_parser *p) { static bool start_subobject_full(upb_json_parser *p) { if (is_top_level(p)) { - if (is_value_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_STRUCTVALUE); if (!start_subobject(p)) return false; start_structvalue_object(p); - } else if (is_structvalue_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) { start_structvalue_object(p); } else { return true; } - } else if (does_structvalue_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_STRUCT)) { if (!start_subobject(p)) return false; start_structvalue_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) return false; start_value_object(p, VALUE_STRUCTVALUE); if (!start_subobject(p)) return false; @@ -1723,14 +1695,14 @@ static void end_subobject(upb_json_parser *p) { static void end_subobject_full(upb_json_parser *p) { end_subobject(p); - if (does_structvalue_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) { end_structvalue_object(p); if (!is_top_level(p)) { end_subobject(p); } } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1743,19 +1715,19 @@ static bool start_array(upb_json_parser *p) { upb_selector_t sel; if (is_top_level(p)) { - if (is_value_object(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { start_value_object(p, VALUE_LISTVALUE); if (!start_subobject(p)) return false; start_listvalue_object(p); - } else if (is_listvalue_object(p)) { + } else if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) { start_listvalue_object(p); } else { return false; } - } else if (does_listvalue_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_LISTVALUE)) { if (!start_subobject(p)) return false; start_listvalue_object(p); - } else if (does_value_start(p)) { + } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) { if (!start_subobject(p)) return false; start_value_object(p, VALUE_LISTVALUE); if (!start_subobject(p)) return false; @@ -1796,14 +1768,14 @@ static void end_array(upb_json_parser *p) { sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ); upb_sink_endseq(&p->top->sink, sel); - if (does_listvalue_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) { end_listvalue_object(p); if (!is_top_level(p)) { end_subobject(p); } } - if (does_value_end(p)) { + if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) { end_value_object(p); if (!is_top_level(p)) { end_subobject(p); @@ -1828,54 +1800,10 @@ static void end_object(upb_json_parser *p) { } } -static bool is_double_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kDoubleValueFullMessageName) == 0; -} - -static bool is_float_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kFloatValueFullMessageName) == 0; -} - -static bool is_int64_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kInt64ValueFullMessageName) == 0; -} - -static bool is_uint64_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kUInt64ValueFullMessageName) == 0; -} - -static bool is_int32_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kInt32ValueFullMessageName) == 0; -} - -static bool is_uint32_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kUInt32ValueFullMessageName) == 0; -} - -static bool is_bool_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kBoolValueFullMessageName) == 0; -} - -static bool is_string_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kStringValueFullMessageName) == 0; -} - -static bool is_bytes_value(const upb_msgdef *m) { - return strcmp(upb_msgdef_fullname(m), kBytesValueFullMessageName) == 0; -} - -static bool is_number_wrapper(const upb_msgdef *m) { - return is_double_value(m) || - is_float_value(m) || - is_int64_value(m) || - is_uint64_value(m) || - is_int32_value(m) || - is_uint32_value(m); -} - static bool is_string_wrapper(const upb_msgdef *m) { - return is_string_value(m) || - is_bytes_value(m); + upb_wellknowntype_t type = upb_msgdef_wellknowntype(m); + return type == UPB_WELLKNOWN_STRINGVALUE || + type == UPB_WELLKNOWN_BYTESVALUE; } static void start_wrapper_object(upb_json_parser *p) { @@ -1977,18 +1905,29 @@ static bool is_top_level(upb_json_parser *p) { return p->top == p->stack && p->top->f == NULL; } +static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type) { + return p->top->m != NULL && upb_msgdef_wellknowntype(p->top->m) == type; +} + +static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type) { + return p->top->f != NULL && + upb_fielddef_issubmsg(p->top->f) && + (upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(p->top->f)) + == type); +} + static bool does_number_wrapper_start(upb_json_parser *p) { return p->top->f != NULL && upb_fielddef_issubmsg(p->top->f) && - is_number_wrapper(upb_fielddef_msgsubdef(p->top->f)); + upb_msgdef_isnumberwrapper(upb_fielddef_msgsubdef(p->top->f)); } static bool does_number_wrapper_end(upb_json_parser *p) { - return p->top->m != NULL && is_number_wrapper(p->top->m); + return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m); } static bool is_number_wrapper_object(upb_json_parser *p) { - return p->top->m != NULL && is_number_wrapper(p->top->m); + return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m); } static bool does_string_wrapper_start(upb_json_parser *p) { @@ -2005,91 +1944,6 @@ static bool is_string_wrapper_object(upb_json_parser *p) { return p->top->m != NULL && is_string_wrapper(p->top->m); } -static bool does_boolean_wrapper_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - is_bool_value(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_boolean_wrapper_end(upb_json_parser *p) { - return p->top->m != NULL && is_bool_value(p->top->m); -} - -static bool is_boolean_wrapper_object(upb_json_parser *p) { - return p->top->m != NULL && is_bool_value(p->top->m); -} - -static bool does_duration_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_duration(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_duration_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_duration(p->top->m); -} - -static bool is_duration_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_duration(p->top->m); -} - -static bool does_timestamp_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_timestamp(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_timestamp_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_timestamp(p->top->m); -} - -static bool is_timestamp_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_timestamp(p->top->m); -} - -static bool does_value_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_value(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_value_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_value(p->top->m); -} - -static bool is_value_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_value(p->top->m); -} - -static bool does_listvalue_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_listvalue(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_listvalue_end(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_listvalue(p->top->m); -} - -static bool is_listvalue_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_listvalue(p->top->m); -} - -static bool does_structvalue_start(upb_json_parser *p) { - return p->top->f != NULL && - upb_fielddef_issubmsg(p->top->f) && - upb_msgdef_structvalue(upb_fielddef_msgsubdef(p->top->f)); -} - -static bool does_structvalue_end(upb_json_parser *p) { - /* return p->top != p->stack && upb_msgdef_structvalue((p->top - 1)->m); */ - return p->top->m != NULL && upb_msgdef_structvalue(p->top->m); -} - -static bool is_structvalue_object(upb_json_parser *p) { - return p->top->m != NULL && upb_msgdef_structvalue(p->top->m); -} - #define CHECK_RETURN_TOP(x) if (!(x)) goto error @@ -2185,9 +2039,9 @@ static bool is_structvalue_object(upb_json_parser *p) { string = '"' @{ - if (is_timestamp_object(parser)) { + if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) { fcall timestamp_machine; - } else if (is_duration_object(parser)) { + } else if (is_wellknown_msg(parser, UPB_WELLKNOWN_DURATION)) { fcall duration_machine; } else { fcall string_machine; -- cgit v1.2.3