diff --git a/tools/upbc.c b/tools/upbc.c index fa264d7eda..b22b9587d7 100644 --- a/tools/upbc.c +++ b/tools/upbc.c @@ -221,6 +221,7 @@ int compare_entries(const void *_e1, const void *_e2) static void write_c(struct upb_symtab_entry *entries[], int num_entries, char *hfile_name, char *outfile_name, FILE *stream) { + (void)outfile_name; fputs("/* This file was generated by upbc (the upb compiler). " "Do not edit. */\n\n", stream), fprintf(stream, "#include \"%s\"\n\n", hfile_name); @@ -236,7 +237,6 @@ static void write_c(struct upb_symtab_entry *entries[], int num_entries, upb_strtable_init(&t, 16, sizeof(struct strtable_entry)); for(int i = 0; i < num_entries; i++) { - //addident(entries[i].key); struct strtable_entry e = {.e = {.key = entries[i]->e.key}}; if(upb_strtable_lookup(&t, &e.e.key) == NULL) upb_strtable_insert(&t, &e.e); switch(entries[i]->type) { @@ -296,9 +296,60 @@ static void write_c(struct upb_symtab_entry *entries[], int num_entries, fputs("static struct upb_string strings[] = {\n", stream); for(int i = 0; i < size; i++) { struct strtable_entry *e = str_entries[i]; - fprintf(stream, " {.ptr = &strdata[%d], .byte_len=%d}", e->offset, e->e.key.byte_len); - if(i+1 != size) fputc(',', stream); - fputc('\n', stream); + fprintf(stream, " {.ptr = &strdata[%d], .byte_len=%d},\n", e->offset, e->e.key.byte_len); + } + fputs("};\n\n", stream); + + /* Emit fields. */ + fputs("static google_protobuf_FieldDescriptorProto fields[] = {\n", stream); + int total = 0; + for(int i = 0; i < num_entries; i++) { + if(entries[i]->type != UPB_SYM_MESSAGE) continue; + struct upb_msg *m = entries[i]->ref.msg; + for(uint32_t j = 0; j < m->num_fields; j++) { + struct google_protobuf_FieldDescriptorProto *fd = m->field_descriptors[j]; + struct strtable_entry *e = upb_strtable_lookup(&t, fd->name); + fprintf(stream, " {.set_flags = {.bytes={0x%02hhx}}, .name=&strings[%3d], .number=%d, .label=%d, .type=%2d, .type_name=NULL},\n", + fd->set_flags.bytes[0], e->num, fd->number, fd->label, fd->type); + total ++; + } + } + fputs("};\n\n", stream); + + fputs("static google_protobuf_FieldDescriptorProto *field_pointers[] = {\n", stream); + for(int i = 0; i < total; i++) { + fprintf(stream, " &fields[%d],\n", i); + } + fputs("};\n\n", stream); + + offset = 0; + fputs("static UPB_MSG_ARRAY(google_protobuf_FieldDescriptorProto) field_arrays[] = {\n", stream); + for(int i = 0; i < num_entries; i++) { + if(entries[i]->type != UPB_SYM_MESSAGE) continue; + struct upb_msg *m = entries[i]->ref.msg; + fprintf(stream, " {.elements=&field_pointers[%d], .len=%d},\n", offset, m->num_fields); + offset += m->num_fields; + } + fputs("};\n\n", stream); + + /* Emit messages. */ + fputs("static google_protobuf_DescriptorProto messages[] = {\n", stream); + offset = 0; + for(int i = 0; i < num_entries; i++) { + if(entries[i]->type != UPB_SYM_MESSAGE) continue; + struct upb_msg *m = entries[i]->ref.msg; + struct google_protobuf_DescriptorProto *d = m->descriptor; + struct strtable_entry *e = upb_strtable_lookup(&t, d->name); + fprintf(stream, " {.set_flags = {.bytes={0x%02hhx}}, .name=&strings[%3d], .field=&field_arrays[%d]},\n", + d->set_flags.bytes[0], e->num, offset); + } + fputs("};\n\n", stream); + + fputs("static google_protobuf_DescriptorProto *message_pointers[] = {\n", stream); + offset = 0; + for(int i = 0; i < num_entries; i++) { + if(entries[i]->type != UPB_SYM_MESSAGE) continue; + fprintf(stream, " &messages[%d],\n", offset); } fputs("};\n\n", stream); }