Add support for encoding Any in json

pull/13171/head
Bo Yang 6 years ago
parent 13c59cb051
commit b39dbb9d40
  1. 1
      tools/dump_cinit.lua
  2. 4
      upb/def.h
  3. 32
      upb/json/parser.c
  4. 8
      upb/json/parser.rl
  5. 56
      upb/json/printer.c

@ -350,6 +350,7 @@ end
local function well_known_type(m) local function well_known_type(m)
local type_map = {} local type_map = {}
type_map["google.protobuf.Any"] = "UPB_WELLKNOWN_ANY"
type_map["google.protobuf.Duration"] = "UPB_WELLKNOWN_DURATION" type_map["google.protobuf.Duration"] = "UPB_WELLKNOWN_DURATION"
type_map["google.protobuf.Timestamp"] = "UPB_WELLKNOWN_TIMESTAMP" type_map["google.protobuf.Timestamp"] = "UPB_WELLKNOWN_TIMESTAMP"
type_map["google.protobuf.Value"] = "UPB_WELLKNOWN_VALUE" type_map["google.protobuf.Value"] = "UPB_WELLKNOWN_VALUE"

@ -689,6 +689,10 @@ typedef upb_strtable_iter upb_msg_oneof_iter;
#define UPB_MAPENTRY_KEY 1 #define UPB_MAPENTRY_KEY 1
#define UPB_MAPENTRY_VALUE 2 #define UPB_MAPENTRY_VALUE 2
/* Well-known field tag numbers for Any messages. */
#define UPB_ANY_TYPE 1
#define UPB_ANY_VALUE 2
/* Well-known field tag numbers for timestamp messages. */ /* Well-known field tag numbers for timestamp messages. */
#define UPB_DURATION_SECONDS 1 #define UPB_DURATION_SECONDS 1
#define UPB_DURATION_NANOS 2 #define UPB_DURATION_NANOS 2

@ -1301,15 +1301,15 @@ static bool end_stringval_nontop(upb_json_parser *p) {
return true; return true;
} }
if (p->top->is_any) {
return end_any_stringval(p);
}
if (p->top->f == NULL) { if (p->top->f == NULL) {
multipart_end(p); multipart_end(p);
return true; return true;
} }
if (p->top->is_any) {
return end_any_stringval(p);
}
switch (upb_fielddef_type(p->top->f)) { switch (upb_fielddef_type(p->top->f)) {
case UPB_TYPE_BYTES: case UPB_TYPE_BYTES:
if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING), if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING),
@ -2768,7 +2768,7 @@ _match:
break; break;
case 2: case 2:
#line 2429 "upb/json/parser.rl" #line 2429 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 23;goto _again;} } { p--; {stack[top++] = cs; cs = 23; goto _again;} }
break; break;
case 3: case 3:
#line 2433 "upb/json/parser.rl" #line 2433 "upb/json/parser.rl"
@ -2842,17 +2842,17 @@ _match:
#line 2488 "upb/json/parser.rl" #line 2488 "upb/json/parser.rl"
{ {
if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) { if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) {
{stack[top++] = cs; cs = 47;goto _again;} {stack[top++] = cs; cs = 47; goto _again;}
} else if (is_wellknown_msg(parser, UPB_WELLKNOWN_DURATION)) { } else if (is_wellknown_msg(parser, UPB_WELLKNOWN_DURATION)) {
{stack[top++] = cs; cs = 40;goto _again;} {stack[top++] = cs; cs = 40; goto _again;}
} else { } else {
{stack[top++] = cs; cs = 32;goto _again;} {stack[top++] = cs; cs = 32; goto _again;}
} }
} }
break; break;
case 21: case 21:
#line 2499 "upb/json/parser.rl" #line 2499 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 75;goto _again;} } { p--; {stack[top++] = cs; cs = 75; goto _again;} }
break; break;
case 22: case 22:
#line 2504 "upb/json/parser.rl" #line 2504 "upb/json/parser.rl"
@ -2964,9 +2964,7 @@ _again:
switch ( *__acts++ ) { switch ( *__acts++ ) {
case 0: case 0:
#line 2425 "upb/json/parser.rl" #line 2425 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; if ( p == pe ) { p--; {cs = stack[--top]; goto _again;} }
goto _test_eof;
goto _again;} }
break; break;
case 30: case 30:
#line 2556 "upb/json/parser.rl" #line 2556 "upb/json/parser.rl"
@ -2988,7 +2986,7 @@ goto _again;} }
#line 2568 "upb/json/parser.rl" #line 2568 "upb/json/parser.rl"
{ end_subobject_full(parser); } { end_subobject_full(parser); }
break; break;
#line 2992 "upb/json/parser.c" #line 2990 "upb/json/parser.c"
} }
} }
} }
@ -3027,7 +3025,11 @@ static bool end(void *closure, const void *hd) {
parse(parser, hd, &eof_ch, 0, NULL); parse(parser, hd, &eof_ch, 0, NULL);
return parser->current_state >= 103; return parser->current_state >=
#line 3030 "upb/json/parser.c"
103
#line 2631 "upb/json/parser.rl"
;
} }
static void json_parser_reset(upb_json_parser *p) { static void json_parser_reset(upb_json_parser *p) {
@ -3044,7 +3046,7 @@ static void json_parser_reset(upb_json_parser *p) {
/* Emit Ragel initialization of the parser. */ /* Emit Ragel initialization of the parser. */
#line 3048 "upb/json/parser.c" #line 3050 "upb/json/parser.c"
{ {
cs = json_start; cs = json_start;
top = 0; top = 0;

@ -1299,15 +1299,15 @@ static bool end_stringval_nontop(upb_json_parser *p) {
return true; return true;
} }
if (p->top->is_any) {
return end_any_stringval(p);
}
if (p->top->f == NULL) { if (p->top->f == NULL) {
multipart_end(p); multipart_end(p);
return true; return true;
} }
if (p->top->is_any) {
return end_any_stringval(p);
}
switch (upb_fielddef_type(p->top->f)) { switch (upb_fielddef_type(p->top->f)) {
case UPB_TYPE_BYTES: case UPB_TYPE_BYTES:
if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING), if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING),

@ -692,6 +692,14 @@ void printer_sethandlers_mapentry(const void *closure, bool preserve_fieldnames,
upb_handlerattr_uninit(&empty_attr); upb_handlerattr_uninit(&empty_attr);
} }
static void *scalar_startstr_any_typeurl(void *closure, const void *handler_data,
size_t size_hint) {
upb_json_printer *p = closure;
UPB_UNUSED(handler_data);
UPB_UNUSED(size_hint);
return p;
}
static bool putseconds(void *closure, const void *handler_data, static bool putseconds(void *closure, const void *handler_data,
int64_t seconds) { int64_t seconds) {
upb_json_printer *p = closure; upb_json_printer *p = closure;
@ -920,6 +928,51 @@ static bool printer_endmsg_noframe(
return true; return true;
} }
static void *scalar_startstr_onlykey(
void *closure, const void *handler_data, size_t size_hint) {
upb_json_printer *p = closure;
UPB_UNUSED(size_hint);
CHK(putkey(closure, handler_data));
return p;
}
/* Set up handlers for an Any submessage. */
void printer_sethandlers_any(const void *closure, upb_handlers *h) {
const upb_msgdef *md = upb_handlers_msgdef(h);
const upb_fielddef* type_field = upb_msgdef_itof(md, UPB_ANY_TYPE);
const upb_fielddef* value_field = upb_msgdef_itof(md, UPB_ANY_VALUE);
upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
/* type_url's json name is "@type" */
upb_handlerattr type_name_attr = UPB_HANDLERATTR_INITIALIZER;
upb_handlerattr value_name_attr = UPB_HANDLERATTR_INITIALIZER;
strpc *type_url_json_name = upb_gmalloc(sizeof(*type_url_json_name));
strpc *value_json_name = upb_gmalloc(sizeof(*type_url_json_name));
type_url_json_name->ptr = upb_gstrdup("@type");
type_url_json_name->len = strlen(type_url_json_name->ptr);
upb_handlers_addcleanup(h, type_url_json_name, freestrpc);
upb_handlerattr_sethandlerdata(&type_name_attr, type_url_json_name);
value_json_name->ptr = upb_gstrdup("value");
value_json_name->len = strlen(value_json_name->ptr);
upb_handlers_addcleanup(h, value_json_name, freestrpc);
upb_handlerattr_sethandlerdata(&value_name_attr, value_json_name);
/* Set up handlers. */
upb_handlers_setstartmsg(h, printer_startmsg, &empty_attr);
upb_handlers_setendmsg(h, printer_endmsg, &empty_attr);
upb_handlers_setstartstr(h, type_field, scalar_startstr, &type_name_attr);
upb_handlers_setstring(h, type_field, scalar_str, &empty_attr);
upb_handlers_setendstr(h, type_field, scalar_endstr, &empty_attr);
upb_handlers_setstartstr(h, value_field, scalar_startstr_onlykey,
&value_name_attr);
}
/* Set up handlers for a duration submessage. */ /* Set up handlers for a duration submessage. */
void printer_sethandlers_duration(const void *closure, upb_handlers *h) { void printer_sethandlers_duration(const void *closure, upb_handlers *h) {
const upb_msgdef *md = upb_handlers_msgdef(h); const upb_msgdef *md = upb_handlers_msgdef(h);
@ -1074,7 +1127,8 @@ void printer_sethandlers(const void *closure, upb_handlers *h) {
case UPB_WELLKNOWN_UNSPECIFIED: case UPB_WELLKNOWN_UNSPECIFIED:
break; break;
case UPB_WELLKNOWN_ANY: case UPB_WELLKNOWN_ANY:
break; printer_sethandlers_any(closure, h);
return;
case UPB_WELLKNOWN_DURATION: case UPB_WELLKNOWN_DURATION:
printer_sethandlers_duration(closure, h); printer_sethandlers_duration(closure, h);
return; return;

Loading…
Cancel
Save