diff options
author | Joshua Haberman <joshua@reverberate.org> | 2011-02-18 18:17:06 -0800 |
---|---|---|
committer | Joshua Haberman <joshua@reverberate.org> | 2011-02-18 18:17:06 -0800 |
commit | 61e5d367ff180a4fcd48dd06b9918a9d37edc766 (patch) | |
tree | db9b726919615984bc2bc4750340b90f58777cb2 /src/upb_def.c | |
parent | ff23340fe2983b1f034b0e156807b328417d2310 (diff) |
Change the API for getting the bootstrapped defs.
The symtab that contains them is now hidden, and
you can look them up by name but there is no access
to the symtab itself, so there is no risk of
mutating it (by extending it, adding other defs
to it, etc).
Diffstat (limited to 'src/upb_def.c')
-rw-r--r-- | src/upb_def.c | 87 |
1 files changed, 54 insertions, 33 deletions
diff --git a/src/upb_def.c b/src/upb_def.c index 6a1e543..0382610 100644 --- a/src/upb_def.c +++ b/src/upb_def.c @@ -859,6 +859,7 @@ static upb_symtab_ent *upb_resolve(upb_strtable *t, // TODO: This branch is totally broken, but currently not used. upb_string *sym_str = upb_string_new(); int baselen = upb_string_len(base); + upb_symtab_ent *ret = NULL; while(1) { // sym_str = base[0...base_len] + UPB_SYMBOL_SEPARATOR + sym upb_strlen_t len = baselen + upb_string_len(sym) + 1; @@ -868,11 +869,18 @@ static upb_symtab_ent *upb_resolve(upb_strtable *t, memcpy(buf + baselen + 1, upb_string_getrobuf(sym), upb_string_len(sym)); upb_symtab_ent *e = upb_strtable_lookup(t, sym_str); - if (e) return e; - else if(baselen == 0) return NULL; // No more scopes to try. - + if (e) { + ret = e; + break; + } else if(baselen == 0) { + // No more scopes to try. + ret = NULL; + break; + } baselen = my_memrchr(buf, UPB_SYMBOL_SEPARATOR, baselen); } + upb_string_unref(sym_str); + return ret; } } @@ -1307,38 +1315,51 @@ static upb_src *upb_baredecoder_src(upb_baredecoder *d) { return &d->src; } -void upb_symtab_add_descriptorproto(upb_symtab *symtab) { - // For the moment we silently decline to perform the operation if the symbols - // already exist in the symtab. Revisit this when we have a better story - // about whether syms in a table can be replaced. - if(symtab->fds_msgdef) return; - - static upb_string descriptor_str = - UPB_STATIC_STRING_ARRAY(descriptor_pb); - upb_baredecoder *decoder = upb_baredecoder_new(&descriptor_str); - upb_status status = UPB_STATUS_INIT; - upb_symtab_addfds(symtab, upb_baredecoder_src(decoder), &status); - upb_baredecoder_free(decoder); - - if(!upb_ok(&status)) { - // upb itself is corrupt. - upb_printerr(&status); - upb_clearerr(&status); - upb_symtab_unref(symtab); - abort(); +static upb_symtab *descriptor_symtab = NULL; + +static void upb_free_descriptor_symtab() { + if (descriptor_symtab) { + // There should be no way for anyone to acquire a ref on this symtab. + assert(upb_atomic_only(&descriptor_symtab->refcount)); + _upb_symtab_free(descriptor_symtab); + descriptor_symtab = NULL; } - upb_def *def = upb_symtab_lookup( - symtab, UPB_STRLIT("google.protobuf.FileDescriptorSet")); - if (!def || (symtab->fds_msgdef = upb_dyncast_msgdef(def)) == NULL) { - // upb itself is corrupt. - abort(); +} + +upb_def *upb_getdescriptordef(upb_string *str) { + // TODO: add locking. + if (descriptor_symtab == NULL) { + descriptor_symtab = upb_symtab_new(); + + static upb_string descriptor_str = + UPB_STATIC_STRING_ARRAY(descriptor_pb); + upb_baredecoder *decoder = upb_baredecoder_new(&descriptor_str); + upb_status status = UPB_STATUS_INIT; + upb_symtab_addfds(descriptor_symtab, upb_baredecoder_src(decoder), &status); + upb_baredecoder_free(decoder); + + if(!upb_ok(&status)) { + // upb itself is corrupt. + upb_printerr(&status); + upb_clearerr(&status); + abort(); + } + upb_status_uninit(&status); + + // As a sanity check, make sure that FileDescriptorSet was loaded. + upb_msgdef *def = upb_getfdsdef(); + if (!def) { + // upb itself is corrupt. + abort(); + } + upb_def_unref(UPB_UPCAST(def)); // The symtab already holds a ref on it. + atexit(upb_free_descriptor_symtab); } - upb_def_unref(def); // The symtab already holds a ref on it. - upb_status_uninit(&status); + return upb_symtab_resolve( + descriptor_symtab, UPB_STRLIT("google.protobuf"), str); } -upb_msgdef *upb_symtab_fds_def(upb_symtab *s) { - assert(s->fds_msgdef != NULL); - upb_def_ref(UPB_UPCAST(s->fds_msgdef)); - return s->fds_msgdef; +upb_msgdef *upb_getfdsdef() { + return upb_downcast_msgdef( + upb_getdescriptordef(UPB_STRLIT("FileDescriptorSet"))); } |