diff --git a/build_defs.bzl b/build_defs.bzl index 825101433e..7445fce136 100644 --- a/build_defs.bzl +++ b/build_defs.bzl @@ -182,13 +182,14 @@ _file_list_aspect = aspect( ) def _upb_amalgamation(ctx): + inputs = [] srcs = [] - hdrs = [] for lib in ctx.attr.libs: - srcs += lib[SrcList].srcs - hdrs += lib[SrcList].hdrs + inputs += lib[SrcList].srcs + inputs += lib[SrcList].hdrs + srcs += [src for src in lib[SrcList].srcs if src.path.endswith("c")] ctx.actions.run( - inputs = srcs + hdrs, + inputs = inputs, outputs = ctx.outputs.outs, arguments = ["", ctx.bin_dir.path + "/"] + [f.path for f in srcs], progress_message = "Making amalgamation", diff --git a/kokoro/ubuntu/build.sh b/kokoro/ubuntu/build.sh index 70a81592a5..3550a34ed4 100644 --- a/kokoro/ubuntu/build.sh +++ b/kokoro/ubuntu/build.sh @@ -8,4 +8,4 @@ which bazel bazel version cd $(dirname $0)/../.. -bazel test :all +bazel test --test_output=errors :all diff --git a/tools/dump_cinit.lua b/tools/dump_cinit.lua index 93ee12e57f..34d9dd1ec6 100644 --- a/tools/dump_cinit.lua +++ b/tools/dump_cinit.lua @@ -350,6 +350,7 @@ end local function well_known_type(m) local type_map = {} + type_map["google.protobuf.Any"] = "UPB_WELLKNOWN_ANY" type_map["google.protobuf.Duration"] = "UPB_WELLKNOWN_DURATION" type_map["google.protobuf.Timestamp"] = "UPB_WELLKNOWN_TIMESTAMP" type_map["google.protobuf.Value"] = "UPB_WELLKNOWN_VALUE" diff --git a/upb/def.h b/upb/def.h index c9ed1cf6e9..98b458ab0c 100644 --- a/upb/def.h +++ b/upb/def.h @@ -689,6 +689,10 @@ typedef upb_strtable_iter upb_msg_oneof_iter; #define UPB_MAPENTRY_KEY 1 #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. */ #define UPB_DURATION_SECONDS 1 #define UPB_DURATION_NANOS 2 diff --git a/upb/json/parser.c b/upb/json/parser.c index 83590a1fa2..08056d39af 100644 --- a/upb/json/parser.c +++ b/upb/json/parser.c @@ -1301,15 +1301,15 @@ static bool end_stringval_nontop(upb_json_parser *p) { return true; } - if (p->top->is_any) { - return end_any_stringval(p); - } - if (p->top->f == NULL) { multipart_end(p); return true; } + if (p->top->is_any) { + return end_any_stringval(p); + } + switch (upb_fielddef_type(p->top->f)) { case UPB_TYPE_BYTES: if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING), diff --git a/upb/json/parser.rl b/upb/json/parser.rl index a7bdb3fe5d..e5845153a8 100644 --- a/upb/json/parser.rl +++ b/upb/json/parser.rl @@ -1299,15 +1299,15 @@ static bool end_stringval_nontop(upb_json_parser *p) { return true; } - if (p->top->is_any) { - return end_any_stringval(p); - } - if (p->top->f == NULL) { multipart_end(p); return true; } + if (p->top->is_any) { + return end_any_stringval(p); + } + switch (upb_fielddef_type(p->top->f)) { case UPB_TYPE_BYTES: if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING), diff --git a/upb/json/printer.c b/upb/json/printer.c index fe306d45ac..5ed79a0f3d 100644 --- a/upb/json/printer.c +++ b/upb/json/printer.c @@ -69,6 +69,15 @@ strpc *newstrpc(upb_handlers *h, const upb_fielddef *f, return ret; } +/* Convert a null-terminated const char* to a string piece. */ +strpc *newstrpc_str(upb_handlers *h, const char * str) { + strpc * ret = upb_gmalloc(sizeof(*ret)); + ret->ptr = upb_gstrdup(str); + ret->len = strlen(str); + upb_handlers_addcleanup(h, ret, freestrpc); + return ret; +} + /* ------------ JSON string printing: values, maps, arrays ------------------ */ static void print_data( @@ -920,6 +929,49 @@ static bool printer_endmsg_noframe( 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 = newstrpc_str(h, "@type"); + strpc *value_json_name = newstrpc_str(h, "value"); + + upb_handlerattr_sethandlerdata(&type_name_attr, type_url_json_name); + 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); + + /* This is not the full and correct JSON encoding for the Any value field. It + * requires further processing by the wrapper code based on the type URL. + */ + upb_handlers_setstartstr(h, value_field, scalar_startstr_onlykey, + &value_name_attr); + + UPB_UNUSED(closure); +} + /* Set up handlers for a duration submessage. */ void printer_sethandlers_duration(const void *closure, upb_handlers *h) { const upb_msgdef *md = upb_handlers_msgdef(h); @@ -1074,7 +1126,8 @@ void printer_sethandlers(const void *closure, upb_handlers *h) { case UPB_WELLKNOWN_UNSPECIFIED: break; case UPB_WELLKNOWN_ANY: - break; + printer_sethandlers_any(closure, h); + return; case UPB_WELLKNOWN_DURATION: printer_sethandlers_duration(closure, h); return;