upb is fully self-hosting (except for text->descriptor)!

pull/13171/head
Joshua Haberman 16 years ago
parent d8c93dc1a2
commit e58c871c19
  1. 3
      src/upb_context.c
  2. 21
      src/upb_msg.c
  3. 9
      src/upb_msg.h
  4. 1
      tests/tests.c
  5. 18
      tools/upbc.c

@ -27,7 +27,8 @@ bool upb_context_init(struct upb_context *c)
upb_strtable_init(&c->symtab, 16, sizeof(struct upb_symtab_entry));
upb_strtable_init(&c->psymtab, 16, sizeof(struct upb_symtab_entry));
/* Add all the types in descriptor.proto so we can parse descriptors. */
if(!addfd(&c->psymtab, &c->symtab, &google_protobuf_filedescriptor, false)) {
if(!addfd(&c->psymtab, &c->symtab, upb_file_descriptor_set->file->elements[0], false)) {
//if(!addfd(&c->psymtab, &c->symtab, &google_protobuf_filedescriptor, false)) {
assert(false);
return false; /* Indicates that upb is buggy or corrupt. */
}

@ -34,7 +34,12 @@ static int compare_fields(const void *e1, const void *e2) {
}
}
bool upb_msg_init(struct upb_msg *m, struct google_protobuf_DescriptorProto *d,
void upb_msg_sortfds(google_protobuf_FieldDescriptorProto **fds, size_t num)
{
qsort(fds, num, sizeof(void*), compare_fields);
}
bool upb_msg_init(struct upb_msg *m, google_protobuf_DescriptorProto *d,
struct upb_string fqname, bool sort)
{
/* TODO: more complete validation.
@ -60,8 +65,7 @@ bool upb_msg_init(struct upb_msg *m, struct google_protobuf_DescriptorProto *d,
/* We count on the caller to keep this pointer alive. */
m->field_descriptors[i] = d->field->elements[i];
}
if(sort)
qsort(m->field_descriptors, m->num_fields, sizeof(void*), compare_fields);
if(sort) upb_msg_sortfds(m->field_descriptors, m->num_fields);
size_t max_align = 0;
for(unsigned int i = 0; i < m->num_fields; i++) {
@ -284,13 +288,12 @@ static upb_status_t value_cb(void *udata, uint8_t *buf, uint8_t *end,
struct upb_msg_field *f = user_field_desc;
union upb_value_ptr p = get_value_ptr(s->top->data, f);
UPB_CHECK(upb_parse_value(buf, end, f->type, p, outbuf));
//google_protobuf_FieldDescriptorProto *fd = upb_msg_field_descriptor(f, s->top->m);
//upb_text_printfield(&s->p, *fd->name, f->type, p, stdout);
google_protobuf_FieldDescriptorProto *fd = upb_msg_field_descriptor(f, s->top->m);
//upb_text_printfield(&s->p, *fd->name, f->type, upb_deref(p, f->type), stdout);
return UPB_STATUS_OK;
}
static void str_cb(void *udata, struct upb_string *str,
void *user_field_desc)
static void str_cb(void *udata, struct upb_string *str, void *user_field_desc)
{
struct upb_msg_parse_state *s = udata;
struct upb_msg_field *f = user_field_desc;
@ -303,7 +306,7 @@ static void str_cb(void *udata, struct upb_string *str,
upb_strcpy(*p.str, str);
}
//google_protobuf_FieldDescriptorProto *fd = upb_msg_field_descriptor(f, s->top->m);
//upb_text_printfield(&s->p, *fd->name, f->type, p, stdout);
//upb_text_printfield(&s->p, *fd->name, f->type, upb_deref(p, fd->type), stdout);
}
static void submsg_start_cb(void *udata, void *user_field_desc)
@ -331,7 +334,7 @@ void upb_msg_parse_reset(struct upb_msg_parse_state *s, void *msg,
struct upb_msg *m, bool merge, bool byref)
{
upb_parse_reset(&s->s, s);
//upb_text_printer_init(&s->p, false);
upb_text_printer_init(&s->p, false);
s->merge = merge;
s->byref = byref;
if(!merge && msg == NULL) msg = upb_msgdata_new(m);

@ -175,6 +175,11 @@ bool upb_msg_init(struct upb_msg *m, struct google_protobuf_DescriptorProto *d,
struct upb_string fqname, bool sort);
void upb_msg_free(struct upb_msg *m);
/* Sort the given field descriptors in-place, according to what we think is an
* optimal ordering of fields. This can change from upb release to upb release.
* This is meant for internal use. */
void upb_msg_sortfds(google_protobuf_FieldDescriptorProto **fds, size_t num);
/* Clients use this function on a previously initialized upb_msg to resolve the
* "ref" field in the upb_msg_field. Since messages can refer to each other in
* mutually-recursive ways, this step must be separated from initialization. */
@ -309,14 +314,14 @@ struct upb_msg_parse_frame {
void *data;
};
//#include "upb_text.h"
#include "upb_text.h"
struct upb_msg_parse_state {
struct upb_parse_state s;
bool merge;
bool byref;
struct upb_msg *m;
struct upb_msg_parse_frame stack[UPB_MAX_NESTING], *top;
//struct upb_text_printer p;
struct upb_text_printer p;
};
/* Initializes/frees a message parser. The parser will write the data to the

@ -9,6 +9,7 @@
#include "upb_context.c"
#include "upb_msg.c"
#include "upb_table.c"
#include "upb_text.c"
int num_assertions = 0;
#define ASSERT(expr) do { \

@ -571,6 +571,14 @@ void error(char *err)
exit(1);
}
void sort_fields_in_descriptor(google_protobuf_DescriptorProto *d)
{
if(d->set_flags.has.field) upb_msg_sortfds(d->field->elements, d->field->len);
if(d->set_flags.has.nested_type)
for(uint32_t i = 0; i < d->nested_type->len; i++)
sort_fields_in_descriptor(d->nested_type->elements[i]);
}
int main(int argc, char *argv[])
{
/* Parse arguments. */
@ -612,6 +620,16 @@ int main(int argc, char *argv[])
if(!upb_context_addfds(&c, fds))
error("Failed to resolve symbols in descriptor.\n");
/* We need to sort the fields of all the descriptors. They will already be
* sorted in the upb_msgs that we base our header file output on, so we must
* sort here to match. */
for(uint32_t i = 0; i < fds->file->len; i++) {
google_protobuf_FileDescriptorProto *fd = fds->file->elements[i];
if(!fd->set_flags.has.message_type) continue;
for(uint32_t j = 0; j < fd->message_type->len; j++)
sort_fields_in_descriptor(fd->message_type->elements[j]);
}
/* Emit output files. */
const int maxsize = 256;
char h_filename[maxsize], c_filename[maxsize];

Loading…
Cancel
Save