diff options
author | Joshua Haberman <joshua@reverberate.org> | 2011-01-10 09:43:28 -0800 |
---|---|---|
committer | Joshua Haberman <joshua@reverberate.org> | 2011-01-10 09:43:28 -0800 |
commit | 45599180905d45a882970f6ca8b6007436ac3f97 (patch) | |
tree | f0ca31d70cf6df80b21dad231dc3095f95bbe76a | |
parent | db512df98e0fac208a716c7807d037f0b0d309f1 (diff) |
More work on upb_src.
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | core/upb.h | 43 | ||||
-rw-r--r-- | core/upb_def.c | 445 | ||||
-rw-r--r-- | core/upb_stream.h | 6 |
4 files changed, 302 insertions, 196 deletions
@@ -28,7 +28,7 @@ CC=gcc CXX=g++ CFLAGS=-std=c99 INCLUDE=-Idescriptor -Icore -Itests -Istream -I. -CPPFLAGS=-Wall -Wextra -g $(INCLUDE) $(strip $(shell test -f perf-cppflags && cat perf-cppflags)) +CPPFLAGS=-Wall -Wextra -Wno-missing-field-initializers -g $(INCLUDE) $(strip $(shell test -f perf-cppflags && cat perf-cppflags)) LDLIBS=-lpthread core/libupb.a ifeq ($(shell uname), Darwin) CPPFLAGS += -I/usr/include/lua5.1 @@ -61,7 +61,7 @@ SRC=core/upb.c \ core/upb_table.c \ core/upb_string.c \ descriptor/descriptor.c \ -# core/upb_def.c \ + core/upb_def.c \ # core/upb_msg.c \ # stream/upb_decoder.c \ # stream/upb_stdio.c \ @@ -12,6 +12,7 @@ #include <stdbool.h> #include <stdint.h> #include <stdio.h> // only for size_t. +#include <assert.h> #include "descriptor_const.h" #include "upb_atomic.h" @@ -128,6 +129,11 @@ typedef struct _upb_msg upb_msg; typedef uint32_t upb_strlen_t; +// The type of a upb_value. This is like a upb_fieldtype_t, but adds the +// constant UPB_VALUETYPE_ARRAY to represent an array. +typedef uint8_t upb_valuetype_t; +#define UPB_VALUETYPE_ARRAY 32 + // A single .proto value. The owner must have an out-of-band way of knowing // the type, so that it knows which union member to use. typedef struct { @@ -153,14 +159,20 @@ typedef struct { #endif } upb_value; +#ifdef NDEBUG +#define SET_TYPE(dest, val) +#else +#define SET_TYPE(dest, val) dest = val +#endif + #define UPB_VALUE_ACCESSORS(name, membername, ctype, proto_type) \ ctype upb_value_get ## name(upb_value val) { \ assert(val.type == UPB_TYPE(proto_type)); \ - return val.membername; \ + return val.val.membername; \ } \ void upb_value_ ## name(upb_value *val, ctype cval) { \ - val.type = UPB_TYPE(proto_type); \ - val.membername = cval; \ + SET_TYPE(val->type, UPB_TYPE(proto_type)); \ + val->val.membername = cval; \ } UPB_VALUE_ACCESSORS(double, _double, double, DOUBLE); UPB_VALUE_ACCESSORS(float, _float, float, FLOAT); @@ -169,6 +181,7 @@ UPB_VALUE_ACCESSORS(int64, int64, int64_t, INT64); UPB_VALUE_ACCESSORS(uint32, uint32, uint32_t, UINT32); UPB_VALUE_ACCESSORS(uint64, uint64, uint64_t, UINT64); UPB_VALUE_ACCESSORS(bool, _bool, bool, BOOL); +UPB_VALUE_ACCESSORS(str, str, upb_string*, STRING); // A pointer to a .proto value. The owner must have an out-of-band way of // knowing the type, so it knows which union member to use. @@ -187,24 +200,23 @@ typedef union { void *_void; } upb_valueptr; -// The type of a upb_value. This is like a upb_fieldtype_t, but adds the -// constant UPB_VALUETYPE_ARRAY to represent an array. -typedef uint8_t upb_valuetype_t; -#define UPB_VALUETYPE_ARRAY 32 - INLINE upb_valueptr upb_value_addrof(upb_value *val) { - upb_valueptr ptr = {&val->_double}; + upb_valueptr ptr = {&val->val._double}; return ptr; } -// Converts upb_value_ptr -> upb_value by reading from the pointer. We need to -// know the value type to perform this operation, because we need to know how -// much memory to copy. +// Reads or writes a upb_value from an address represented by a upb_value_ptr. +// We need to know the value type to perform this operation, because we need to +// know how much memory to copy (and for big-endian machines, we need to know +// where in the upb_value the data goes). +// +// For little endian-machines where we didn't mind overreading, we could make +// upb_value_read simply use memcpy(). INLINE upb_value upb_value_read(upb_valueptr ptr, upb_fieldtype_t ft) { upb_value val; #define CASE(t, member_name) \ - case UPB_TYPE(t): val.member_name = *ptr.member_name; break; + case UPB_TYPE(t): val.val.member_name = *ptr.member_name; break; switch(ft) { CASE(DOUBLE, _double) @@ -232,13 +244,10 @@ INLINE upb_value upb_value_read(upb_valueptr ptr, upb_fieldtype_t ft) { #undef CASE } -// Writes a upb_value to a upb_value_ptr location. We need to know the value -// type to perform this operation, because we need to know how much memory to -// copy. INLINE void upb_value_write(upb_valueptr ptr, upb_value val, upb_fieldtype_t ft) { #define CASE(t, member_name) \ - case UPB_TYPE(t): *ptr.member_name = val.member_name; break; + case UPB_TYPE(t): *ptr.member_name = val.val.member_name; break; switch(ft) { CASE(DOUBLE, _double) diff --git a/core/upb_def.c b/core/upb_def.c index cc771dc..4320fb6 100644 --- a/core/upb_def.c +++ b/core/upb_def.c @@ -9,9 +9,6 @@ #include "descriptor.h" #include "upb_def.h" -#define CHECKSRC(x) if(!(x)) goto src_err -#define CHECK(x) if(!(x)) goto err - /* Rounds p up to the next multiple of t. */ static size_t upb_align_up(size_t val, size_t align) { return val % align == 0 ? val : val + align - (val % align); @@ -184,6 +181,188 @@ static void upb_def_uninit(upb_def *def) { } +/* upb_defbuilder ************************************************************/ + +// A upb_defbuilder builds a list of defs by handling a parse of a protobuf in +// the format defined in descriptor.proto. The output of a upb_defbuilder is +// a list of upb_def* that possibly contain unresolved references. +// +// We use a separate object (upb_defbuilder) instead of having the defs handle +// the parse themselves because we need to store state that is only necessary +// during the building process itself. + +// When we are bootstrapping descriptor.proto, we must help the bare decoder out +// by telling it when to descend into a submessage, because with the wire format +// alone we cannot tell the difference between a submessage and a string. +// +// TODO: In the long-term, we should bootstrap from a serialization format that +// contains this information, so we can remove this special-case code. This +// would involve defining a serialization format very similar to the existing +// protobuf format, but that contains more information about the wire type. +#define BEGIN_SUBMSG 100 + +// upb_deflist: A little dynamic array for storing a growing list of upb_defs. +typedef struct { + upb_def **defs; + uint32_t len; + uint32_t size; +} upb_deflist; + +static void upb_deflist_init(upb_deflist *l) { + l->size = 8; + l->defs = malloc(l->size * sizeof(void*)); + l->len = 0; +} + +static void upb_deflist_uninit(upb_deflist *l) { + for(uint32_t i = 0; i < l->len; i++) + if(l->defs[i]) upb_def_unref(l->defs[i]); + free(l->defs); +} + +static void upb_deflist_push(upb_deflist *l, upb_def *d) { + if(l->len == l->size) { + l->size *= 2; + l->defs = realloc(l->defs, l->size * sizeof(void*)); + } + l->defs[l->len++] = d; +} + +// Qualify the defname for all defs starting with offset "start" with "str". +static void upb_deflist_qualify(upb_deflist *l, upb_string *str, int32_t start) { + for(uint32_t i = start; i < l->len; i++) { + upb_def *def = l->defs[i]; + upb_string *name = def->fqname; + def->fqname = upb_join(str, name); + upb_string_unref(name); + } +} + +typedef struct { + upb_string *name; + int start; +} upb_defbuilder_frame; + +struct _upb_defbuilder { + upb_deflist defs; + upb_defbuilder_frame stack[UPB_MAX_TYPE_DEPTH]; + int stack_len; + + uint32_t number; + upb_string *name; +}; +typedef struct _upb_defbuilder upb_defbuilder; + +// Forward declares for top-level file descriptors. +static void upb_msgdef_register_DescriptorProto(upb_defbuilder *b, upb_handlers *h); +static void upb_enumdef_register_EnumDescriptorProto(upb_defbuilder *b, + upb_handlers *h); + + +// Start/end handlers for FileDescriptorProto and DescriptorProto (the two +// entities that have names and can contain sub-definitions. +void upb_defbuilder_startcontainer(upb_defbuilder *b) { + upb_defbuilder_frame *f = &b->stack[b->stack_len++]; + f->start = b->defs.len; + f->name = NULL; +} + +void upb_defbuilder_endcontainer(upb_defbuilder *b) { + upb_defbuilder_frame *f = &b->stack[--b->stack_len]; + upb_deflist_qualify(&b->defs, f->name, f->start); + upb_string_unref(f->name); +} + +void upb_defbuilder_setscopename(upb_defbuilder *b, upb_string *str) { + upb_defbuilder_frame *f = &b->stack[b->stack_len-1]; + upb_string_unref(f->name); + f->name = upb_string_getref(str); +} + +// Handlers for google.protobuf.FileDescriptorProto. +static upb_flow_t upb_defbuilder_FileDescriptorProto_value(void *_b, + upb_fielddef *f, + upb_value val) { + upb_defbuilder *b = _b; + switch(f->number) { + case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_FIELDNUM: + upb_defbuilder_setscopename(b, upb_value_getstr(val)); + break; + case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_FIELDNUM: + case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_FIELDNUM: + return BEGIN_SUBMSG; + default: + return UPB_SKIP; + } +} + +static upb_flow_t upb_defbuilder_FileDescriptorProto_startsubmsg( + void *_b, upb_fielddef *f, upb_handlers *h) { + upb_defbuilder *b = _b; + switch(f->number) { + case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_FIELDNUM: + upb_msgdef_register_DescriptorProto(b, h); + return UPB_DELEGATE; + case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_FIELDNUM: + upb_enumdef_register_EnumDescriptorProto(b, h); + return UPB_DELEGATE; + default: + // TODO: services and extensions. + return UPB_SKIP; + } +} + +static void upb_defbuilder_register_FileDescriptorProto(upb_defbuilder *b, + upb_handlers *h) { + static upb_handlerset upb_defbuilder_FileDescriptorProto_handlers = { + NULL, // startmsg + NULL, // endmsg + &upb_defbuilder_FileDescriptorProto_value, + &upb_defbuilder_FileDescriptorProto_startsubmsg, + }; + upb_register_handlerset(h, &upb_defbuilder_FileDescriptorProto_handlers); + upb_set_handler_closure(h, b); +} + +// Handlers for google.protobuf.FileDescriptorSet. +static upb_flow_t upb_defbuilder_FileDescriptorSet_value(void *b, + upb_fielddef *f, + upb_value val) { + (void)b; + (void)val; + switch(f->number) { + case GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNUM: + return BEGIN_SUBMSG; + default: + return UPB_SKIP; + } +} + +static upb_flow_t upb_defbuilder_FileDescriptorSet_startsubmsg( + void *_b, upb_fielddef *f, upb_handlers *h) { + upb_defbuilder *b = _b; + switch(f->number) { + case GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNUM: + upb_defbuilder_register_FileDescriptorProto(b, h); + return UPB_DELEGATE; + default: + return UPB_SKIP; + } +} + +static void upb_defbuilder_register_FileDescriptorSet( + upb_defbuilder *b, upb_handlers *h) { + static upb_handlerset upb_defbuilder_FileDescriptorSet_handlers = { + NULL, // startmsg + NULL, // endmsg + &upb_defbuilder_FileDescriptorSet_value, + &upb_defbuilder_FileDescriptorSet_startsubmsg, + }; + upb_register_handlerset(h, &upb_defbuilder_FileDescriptorSet_handlers); + upb_set_handler_closure(h, b); +} + + /* upb_unresolveddef **********************************************************/ // Unresolved defs are used as temporary placeholders for a def whose name has @@ -227,28 +406,30 @@ static void upb_enumdef_free(upb_enumdef *e) { } // google.protobuf.EnumValueDescriptorProto. -static void upb_enumdef_startmsg(upb_defbuilder *b) { +static void upb_enumdef_EnumValueDescriptorProto_startmsg(upb_defbuilder *b) { b->number = -1; - name = NULL; + b->name = NULL; } -static upb_flow_t upb_enumdef_value(upb_defbuilder *b, upb_fielddef *f, upb_value val) { +static upb_flow_t upb_enumdef_EnumValueDescriptorProto_value(upb_defbuilder *b, + upb_fielddef *f, + upb_value val) { switch(f->number) { case GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_FIELDNUM: - name = upb_string_tryrecycle(name); + b->name = upb_string_tryrecycle(name); CHECKSRC(upb_src_getstr(src, name)); break; case GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER_FIELDNUM: - CHECKSRC(upb_src_getint32(src, &number)); + b->number = upb_value_getint32(val); break; default: - CHECKSRC(upb_src_skipval(src)); break; } + return UPB_CONTINUE; } -static void upb_enumdef_endmsg(upb_defbuilder *b) { - if(name == NULL || number == -1) { +static void upb_enumdef_EnumValueDescriptorProto_endmsg(upb_defbuilder *b) { + if(b->name == NULL || b->number == -1) { upb_seterr(status, UPB_STATUS_ERROR, "Enum value missing name or number."); goto err; } @@ -262,7 +443,66 @@ static void upb_enumdef_endmsg(upb_defbuilder *b) { return UPB_CONTINUE; } -upb_enum_iter upb_enum_begin(upb_enumdef *e) { +static void upb_enumdef_register_EnumValueDescriptorProto(upb_defbuilder *b, + upb_handlers *h) { + static upb_handlerset upb_enumdef_EnumValueDescriptorProto_handlers = { + &upb_enumdef_EnumValueDescriptorProto_startmsg, + &upb_enumdef_EnumValueDescriptorProto_endmsg, + &upb_enumdef_EnumValueDescriptorProto_value, + } + upb_register_handlerset(h, &upb_enumdef_EnumValueDescriptorProto_handlers); + upb_set_handler_closure(h, b); +} + +// google.protobuf.EnumDescriptorProto. +void upb_enumdef_EnumDescriptorProto_startmsg(upb_defbuilder *b) { + upb_enumdef *e = malloc(sizeof(*e)); + upb_def_init(&e->base, UPB_DEF_ENUM); + upb_strtable_init(&e->ntoi, 0, sizeof(upb_ntoi_ent)); + upb_inttable_init(&e->iton, 0, sizeof(upb_iton_ent)); + upb_deflist_push(&b->defs, UPB_UPCAST(e)); +} + +void upb_enumdef_EnumDescriptorProto_endmsg(upb_defbuilder *b) { + assert(e->base.fqname); +} + +static upb_flow_t upb_enumdef_EnumDescriptorProto_value(upb_defbuilder *b, + upb_fielddef *f, + upb_value val) { + switch(f->number) { + case GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_FIELDNUM: + upb_string_unref(e->base.fqname); + e->base.fqname = upb_value_getstr(val); + case GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_FIELDNUM: + return BEGIN_SUBMSG; + } + return UPB_CONTINUE; +} + +static upb_flow_t upb_enumdef_EnumDescriptorProto_startsubmsg(upb_defbuilder *b, + upb_fielddef *f, + upb_handlers *h) { + switch(f->number) { + case GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_FIELDNUM: + upb_enumdef_register_EnumValueDescriptorProto(b, h); + return UPB_DELEGATE; + } + return UPB_SKIP; +} + +static void upb_enumdef_register_EnumDescriptorProto(upb_defbuilder *b, + upb_handlers *h) { + static upb_handlerset upb_enumdef_EnumDescriptorProto_handlers = { + &upb_enumdef_EnumDescriptorProto_startmsg, + &upb_enumdef_EnumDescriptorProto_endmsg, + &upb_enumdef_EnumDescriptorProto_value, + } + upb_register_handlerset(h, &upb_enumdef_EnumDescriptorProto_handlers); + upb_set_handler_closure(h, b); +} + +upb_enum_iter upb_enum_begin(upb_enumdef *e) { // We could iterate over either table here; the choice is arbitrary. return upb_inttable_begin(&e->iton); } @@ -355,7 +595,7 @@ static int upb_compare_fields(const void *f1, const void *f2) { return upb_compare_typed_fields(*(void**)f1, *(void**)f2); } -// Processes a google.protobuf.DescriptorProto, adding defs to "defs." +// google.protobuf.DescriptorProto. static void upb_msgdef_startmsg(upb_defbuilder *b) { upb_msgdef *m = malloc(sizeof(*m)); upb_def_init(&m->base, UPB_DEF_MSG); @@ -417,9 +657,6 @@ static void upb_msgdef_endmsg(upb_defbuilder *b) { static bool upb_msgdef_value(upb_defbuilder *b, upb_fielddef *f, upb_value val) { switch(f->number) { case GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_FIELDNUM: - // XXX - m->base.fqname = upb_string_tryrecycle(m->base.fqname); - m->base.fqname = upb_value_getstr(val); upb_defbuilder_setscopename(upb_value_getstr(val)); break; case GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_FIELDNUM: @@ -432,13 +669,14 @@ static bool upb_msgdef_value(upb_defbuilder *b, upb_fielddef *f, upb_value val) } } -static upb_flow_t upb_msgdef_startsubmsg(upb_defbuilder *b, upb_fielddef *f, upb_handlers *h) { +static upb_flow_t upb_msgdef_startsubmsg(upb_defbuilder *b, upb_fielddef *f, + upb_handlers *h) { switch(f->number) { case GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_FIELDNUM: upb_register_FieldDescriptorProto(b, h); return UPB_DELEGATE; case GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_FIELDNUM: - upb_register_DescriptorProto(b, h); + upb_msgdef_register_DescriptorProto(b, h); return UPB_DELEGATE; case GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_FIELDNUM: upb_register_EnumDescriptorProto(b, h); @@ -449,6 +687,18 @@ static upb_flow_t upb_msgdef_startsubmsg(upb_defbuilder *b, upb_fielddef *f, upb } } +static void upb_msgdef_register_DescriptorProto(upb_defbuilder *b, + upb_handlers *h) { + static upb_handlerset upb_msgdef_DescriptorProto_handlers = { + &upb_msgdef_startmsg, + &upb_msgdef_endmsg, + &upb_msgdef_value, + &upb_msgdef_startsubmsg, + } + upb_register_handlerset(h, &upb_msgdef_DescriptorProto_handlers); + upb_set_handler_closure(h, b); +} + static void upb_msgdef_free(upb_msgdef *m) { upb_msg_iter i; @@ -477,165 +727,6 @@ upb_msg_iter upb_msg_next(upb_msgdef *m, upb_msg_iter iter) { return upb_inttable_next(&m->itof, &iter->e); } -/* upb_defbuilder ************************************************************/ - -// A upb_defbuilder builds a list of defs by handling a parse of a protobuf in -// the format defined in descriptor.proto. The output of a upb_defbuilder is -// a list of upb_def* that possibly contain unresolved references. -// -// We use a separate object (upb_defbuilder) instead of having the defs handle -// the parse themselves because we need to store state that is only necessary -// during the building process itself. - -// When we are bootstrapping descriptor.proto, we must help the bare decoder out -// by telling it when to descend into a submessage, because with the wire format -// alone we cannot tell the difference between a submessage and a string. -#define BEGIN_SUBMSG 100 - -// upb_deflist: A little dynamic array for storing a growing list of upb_defs. -typedef struct { - upb_def **defs; - uint32_t len; - uint32_t size; -} upb_deflist; - -static void upb_deflist_init(upb_deflist *l) { - l->size = 8; - l->defs = malloc(l->size * sizeof(void*)); - l->len = 0; -} - -static void upb_deflist_uninit(upb_deflist *l) { - for(uint32_t i = 0; i < l->len; i++) - if(l->defs[i]) upb_def_unref(l->defs[i]); - free(l->defs); -} - -static void upb_deflist_push(upb_deflist *l, upb_def *d) { - if(l->len == l->size) { - l->size *= 2; - l->defs = realloc(l->defs, l->size * sizeof(void*)); - } - l->defs[l->len++] = d; -} - -// Qualify the defname for all defs starting with offset "start" with "str". -static void upb_deflist_qualify(upb_deflist *l, upb_string *str, int32_t start) { - for(uint32_t i = start; i < l->len; i++) { - upb_def *def = l->defs[i]; - upb_string *name = def->fqname; - def->fqname = upb_join(str, name); - upb_string_unref(name); - } -} - -typedef struct { - upb_deflist defs; - struct { - upb_string *name; - int start; - } upb_defbuilder_frame; - upb_defbuilder_frame stack[UPB_MAX_TYPE_DEPTH]; - int stack_len; -} upb_defbuilder; - -// Start/end handlers for FileDescriptorProto and DescriptorProto (the two -// entities that have names and can contain sub-definitions. -upb_defbuilder_startcontainer(upb_defbuilder *b) { - upb_defbuilder_frame *f = b->stack[b->stack_len++]; - f->start = b->defs.len; - f->name = NULL; -} - -upb_defbuilder_endcontainer(upb_defbuilder *b) { - upb_defbuilder_frame *f = b->stack[--b->stack_len]; - upb_deflist_qualify(&b->defs, f->name, f->start); - upb_string_unref(f->name); -} - -upb_defbuilder_setscopename(upb_defbuilder *b, upb_string *str) { -} - -// Handlers for google.protobuf.FileDescriptorProto. -static bool upb_defbuilder_FileDescriptorProto_value(upb_defbuilder *b, - upb_fielddef *f, - upb_value val) { - switch(f->number) { - case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_FIELDNUM: - upb_defbuilder_setscopename(b, val.str); - break; - case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_FIELDNUM: - case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_FIELDNUM: - return BEGIN_SUBMSG; - default: - return UPB_SKIP; - } -} - -static bool upb_defbuilder_FileDescriptorProto_startsubmsg(upb_defbuilder *b, - upb_fielddef *f, - upb_handlers *h) { - switch(f->number) { - case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_FIELDNUM: - upb_defbuilder_register_DescriptorProto(b, h); - return UPB_DELEGATE; - case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_FIELDNUM: - upb_defbuilder_register_EnumDescriptorProto(b, h); - return UPB_DELEGATE; - default: - // TODO: services and extensions. - return UPB_SKIP; - } -} - -static upb_handlers upb_defbuilder_FileDescriptorProto_handlers = { - NULL, // startmsg - NULL, // endmsg - &upb_defbuilder_FileDescriptorProto_value, - &upb_defbuilder_FileDescriptorProto_startsubmsg, -} - -upb_defbuilder_register_FileDescriptorProto(upb_defbuilder *b, upb_handlers *h) { - upb_register_handlerset(h, &upb_defbuilder_FileDescriptorProto_handlers); - upb_set_handler_closure(h, b); -} - -// Handlers for google.protobuf.FileDescriptorSet. -upb_defbuilder_FileDescriptorSet_value(upb_defbuilder *b, upb_fielddef *f, - upb_value val) { - switch(f->number) { - case GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNUM: - return BEGIN_SUBMSG; - default: - return UPB_SKIP; - } -} - -upb_defbuilder_FileDescriptorSet_startsubmsg(upb_defbuilder *b, - upb_fielddef *f, upb_handlers *h) { - switch(f->number) { - case GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNUM: - upb_defbuilder_register_FileDescriptorProto(b, h); - return UPB_DELEGATE; - default: - return UPB_SKIP; - } -} - -static upb_handlers upb_defbuilder_FileDescriptorSet_handlers = { - NULL, // startmsg - NULL, // endmsg - &upb_defbuilder_FileDescriptorSet_value, - &upb_defbuilder_FileDescriptorSet_startsubmsg, -} - -upb_defbuilder_register_FileDescriptorSet(upb_defbuilder *b, upb_handlers *h) { - upb_register_handlerset(h, &upb_defbuilder_FileDescriptorSet_handlers); - upb_set_handler_closure(h, b); -} - - - /* upb_symtab adding defs *****************************************************/ // This is a self-contained group of functions that, given a list of upb_defs diff --git a/core/upb_stream.h b/core/upb_stream.h index 1eb111e..c96c544 100644 --- a/core/upb_stream.h +++ b/core/upb_stream.h @@ -135,6 +135,12 @@ INLINE upb_flow_t upb_dispatch_unknownval(upb_dispatcher *d, upb_field_number_t fieldnum, upb_value val); +/* upb_src ********************************************************************/ + +struct _upb_src; +typedef struct _upb_src upb_src; + + /* upb_bytesrc ****************************************************************/ struct _upb_bytesrc; |