Const invasion: large parts of upb made const-correct.

pull/13171/head
Joshua Haberman 13 years ago
parent 8f2758dda2
commit 621c0cdcb5
  1. 10
      Makefile
  2. 6
      benchmarks/parsestream.upb.c
  3. 18
      benchmarks/parsetoproto2.upb.cc
  4. 6
      benchmarks/parsetostruct.upb.c
  5. 17
      bindings/cpp/upb/def.hpp
  6. 3
      bindings/cpp/upb/handlers.hpp
  7. 44
      bindings/lua/upb.c
  8. 26
      bindings/python/upb.c
  9. 2
      tests/test_cpp.cc
  10. 6
      tests/test_decoder.c
  11. 2
      tests/test_def.c
  12. 14
      tests/test_vs_proto2.cc
  13. 20
      tests/tests.c
  14. 12
      tools/upbc.c
  15. 20
      upb/atomic.h
  16. 11
      upb/bytestream.c
  17. 10
      upb/bytestream.h
  18. 71
      upb/def.c
  19. 172
      upb/def.h
  20. 4
      upb/handlers.c
  21. 14
      upb/handlers.h
  22. 31
      upb/msg.c
  23. 24
      upb/msg.h
  24. 4
      upb/pb/decoder_x86.dasc
  25. 21
      upb/pb/glue.c
  26. 21
      upb/pb/glue.h
  27. 14
      upb/pb/textprinter.c
  28. 2
      upb/pb/textprinter.h
  29. 27
      upb/table.c
  30. 24
      upb/table.h
  31. 5
      upb/upb.c
  32. 13
      upb/upb.h

@ -23,7 +23,11 @@
.PHONY: clean_leave_profile
# Default rule: just build libupb.
all: lib
default: lib
# All: build absolutely everything
all: lib tests benchmarks tools/upbc lua python
testall: test pythontest
# User-specified CFLAGS.
USER_CFLAGS=$(strip $(shell test -f perf-cppflags && cat perf-cppflags))
@ -46,6 +50,7 @@ endif
CC=gcc
CXX=g++
CFLAGS=-std=gnu99
CXXFLAGS=-Ibindings/cpp
INCLUDE=-Itests -I.
CPPFLAGS=$(INCLUDE) -Wall -Wextra $(USER_CFLAGS)
LDLIBS=-lpthread upb/libupb.a
@ -200,7 +205,8 @@ INTERACTIVE_TESTS= \
SIMPLE_CXX_TESTS= \
tests/test_table
tests/test_table \
tests/test_cpp \
VARIADIC_TESTS= \
tests/t.test_vs_proto2.googlemessage1 \

@ -9,7 +9,7 @@
static char *input_str;
static size_t input_len;
static upb_msgdef *def;
static const upb_msgdef *def;
static upb_decoder decoder;
static upb_stringsrc stringsrc;
@ -31,14 +31,14 @@ static bool initialize()
// Initialize upb state, decode descriptor.
upb_status status = UPB_STATUS_INIT;
upb_symtab *s = upb_symtab_new();
upb_read_descriptorfile(s, MESSAGE_DESCRIPTOR_FILE, &status);
upb_load_descriptor_file_into_symtab(s, MESSAGE_DESCRIPTOR_FILE, &status);
if(!upb_ok(&status)) {
fprintf(stderr, "Error reading descriptor: %s\n",
upb_status_getstr(&status));
return false;
}
def = upb_dyncast_msgdef(upb_symtab_lookup(s, MESSAGE_NAME));
def = upb_dyncast_msgdef_const(upb_symtab_lookup(s, MESSAGE_NAME));
if(!def) {
fprintf(stderr, "Error finding symbol '%s'.\n", MESSAGE_NAME);
return false;

@ -29,7 +29,7 @@ MESSAGE_CIDENT msg[NUM_MESSAGES];
MESSAGE_CIDENT msg2;
static upb_stringsrc strsrc;
static upb_decoder d;
upb_msgdef *def;
static const upb_msgdef *def;
#define PROTO2_APPEND(type, ctype) \
upb_flow_t proto2_append_ ## type(void *_r, upb_value fval, upb_value val) { \
@ -50,10 +50,10 @@ PROTO2_APPEND(bool, bool)
upb_flow_t proto2_setstr(void *m, upb_value fval, upb_value val) {
assert(m != NULL);
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
std::string **str = (std::string**)UPB_INDEX(m, f->offset, 1);
if (*str == f->default_ptr) *str = new std::string;
upb_strref *ref = upb_value_getstrref(val);
const upb_strref *ref = upb_value_getstrref(val);
// XXX: only supports contiguous strings atm.
(*str)->assign(ref->ptr, ref->len);
return UPB_CONTINUE;
@ -64,7 +64,7 @@ upb_flow_t proto2_append_str(void *_r, upb_value fval, upb_value val) {
typedef google::protobuf::RepeatedPtrField<std::string> R;
(void)fval;
R *r = (R*)_r;
upb_strref *ref = upb_value_getstrref(val);
const upb_strref *ref = upb_value_getstrref(val);
// XXX: only supports contiguous strings atm.
r->Add()->assign(ref->ptr, ref->len);
return UPB_CONTINUE;
@ -72,13 +72,13 @@ upb_flow_t proto2_append_str(void *_r, upb_value fval, upb_value val) {
upb_sflow_t proto2_startseq(void *m, upb_value fval) {
assert(m != NULL);
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
return UPB_CONTINUE_WITH(UPB_INDEX(m, f->offset, 1));
}
upb_sflow_t proto2_startsubmsg(void *m, upb_value fval) {
assert(m != NULL);
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
google::protobuf::Message *prototype = (google::protobuf::Message*)f->prototype;
void **subm = (void**)UPB_INDEX(m, f->offset, 1);
if (*subm == NULL || *subm == f->default_ptr)
@ -122,7 +122,7 @@ upb_sflow_t proto2_startsubmsg_r(void *_r, upb_value fval) {
public:
typedef void Type;
};
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
UpbRepeatedPtrField *r = (UpbRepeatedPtrField*)_r;
void *submsg = r->Add((google::protobuf::Message*)f->prototype);
assert(submsg != NULL);
@ -225,7 +225,7 @@ static bool initialize()
return false;
}
int n;
upb_def **defs = upb_load_descriptor(data, len, &n, &status);
upb_def **defs = upb_load_defs_from_descriptor(data, len, &n, &status);
free(data);
if(!upb_ok(&status)) {
fprintf(stderr, "Error reading descriptor: %s\n",
@ -257,7 +257,7 @@ static bool initialize()
for(int i = 0; i < n; i++) upb_def_unref(defs[i]);
free(defs);
def = upb_dyncast_msgdef(upb_symtab_lookup(s, MESSAGE_NAME));
def = upb_dyncast_msgdef_const(upb_symtab_lookup(s, MESSAGE_NAME));
if(!def) {
fprintf(stderr, "Error finding symbol '%s'.\n", MESSAGE_NAME);
return false;

@ -7,7 +7,7 @@
#include "upb/pb/decoder.h"
#include "upb/pb/glue.h"
static upb_msgdef *def;
static const upb_msgdef *def;
static size_t len;
static void *msg[NUM_MESSAGES];
static upb_stringsrc strsrc;
@ -18,14 +18,14 @@ static bool initialize()
// Initialize upb state, decode descriptor.
upb_status status = UPB_STATUS_INIT;
upb_symtab *s = upb_symtab_new();
upb_read_descriptorfile(s, MESSAGE_DESCRIPTOR_FILE, &status);
upb_load_descriptor_file_into_symtab(s, MESSAGE_DESCRIPTOR_FILE, &status);
if(!upb_ok(&status)) {
fprintf(stderr, "Error reading descriptor: %s\n",
upb_status_getstr(&status));
return false;
}
def = upb_dyncast_msgdef(upb_symtab_lookup(s, MESSAGE_NAME));
def = upb_dyncast_msgdef_const(upb_symtab_lookup(s, MESSAGE_NAME));
if(!def) {
fprintf(stderr, "Error finding symbol '%s'.\n", MESSAGE_NAME);
return false;

@ -17,9 +17,14 @@ namespace upb {
class MessageDef : public upb_msgdef {
public:
// Converting from C types to C++ wrapper types.
static MessageDef* Cast(upb_msgdef *md) { return (MessageDef*)md; }
static const MessageDef* Cast(const upb_msgdef *md) {
return (const MessageDef*)md;
}
void Unref() { return upb_msgdef_unref(this); }
void Ref() const { upb_msgdef_ref(this); }
void Unref() const { upb_msgdef_unref(this); }
private:
MessageDef();
@ -28,14 +33,20 @@ class MessageDef : public upb_msgdef {
class SymbolTable : public upb_symtab {
public:
// Converting from C types to C++ wrapper types.
static SymbolTable* Cast(upb_symtab *s) { return (SymbolTable*)s; }
static const SymbolTable* Cast(const upb_symtab *s) {
return (SymbolTable*)s;
}
static SymbolTable* New() { return Cast(upb_symtab_new()); }
void Unref() { return upb_symtab_unref(this); }
void Ref() const { upb_symtab_unref(this); }
void Unref() const { upb_symtab_unref(this); }
// If the given name refers to a message in this symbol table, returns a new
// ref to that MessageDef object, otherwise returns NULL.
MessageDef* LookupMessage(const char *name) {
const MessageDef* LookupMessage(const char *name) const {
return MessageDef::Cast(upb_symtab_lookupmsg(this, name));
}

@ -4,9 +4,6 @@
* Copyright (c) 2011 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* Note! This file is a proof-of-concept for C++ wrappers and does not
* yet build.
*
* upb::Handlers is a generic visitor-like interface for iterating over a
* stream of protobuf data. You can register function pointers that will be
* called for each message and/or field as the data is being parsed or iterated

@ -37,7 +37,7 @@ static uint32_t lupb_touint32(lua_State *L, int narg, const char *name) {
return n;
}
static void lupb_pushstring(lua_State *L, upb_strref *ref) {
static void lupb_pushstring(lua_State *L, const upb_strref *ref) {
if (ref->ptr) {
lua_pushlstring(L, ref->ptr, ref->len);
} else {
@ -146,15 +146,15 @@ static void lupb_typecheck(lua_State *L, int narg, upb_fielddef *f) {
//static void lupb_msg_getorcreate(lua_State *L, upb_msg *msg, upb_msgdef *md);
static void lupb_fielddef_getorcreate(lua_State *L, upb_fielddef *f);
static upb_msgdef *lupb_msgdef_check(lua_State *L, int narg);
static void lupb_msg_pushnew(lua_State *L, void *md);
static void lupb_msg_pushnew(lua_State *L, const void *md);
void lupb_checkstatus(lua_State *L, upb_status *s) {
if (!upb_ok(s)) {
upb_status_print(s, stderr);
// Need to copy the string to the stack, so we can free it and not leak
// it (since luaL_error() does not return).
char buf[strlen(s->str)+1];
strcpy(buf, s->str);
const char *str = upb_status_getstr(s);
char buf[strlen(str)+1];
strcpy(buf, str);
upb_status_uninit(s);
luaL_error(L, "%s", buf);
}
@ -226,14 +226,14 @@ static lupb_def *lupb_def_check(lua_State *L, int narg) {
return ldef;
}
static void lupb_def_getorcreate(lua_State *L, upb_def *def, int owned) {
static void lupb_def_getorcreate(lua_State *L, const upb_def *def, int owned) {
bool created = false;
switch(def->type) {
case UPB_DEF_MSG:
created = lupb_cache_getorcreate(L, def, "upb.msgdef");
created = lupb_cache_getorcreate(L, (void*)def, "upb.msgdef");
break;
case UPB_DEF_ENUM:
created = lupb_cache_getorcreate(L, def, "upb.enumdef");
created = lupb_cache_getorcreate(L, (void*)def, "upb.enumdef");
break;
default:
luaL_error(L, "unknown deftype %d", def->type);
@ -564,7 +564,7 @@ static int lupb_symtab_gc(lua_State *L) {
static int lupb_symtab_lookup(lua_State *L) {
lupb_symtab *s = lupb_symtab_check(L, 1);
for (int i = 2; i <= lua_gettop(L); i++) {
upb_def *def = upb_symtab_lookup(s->symtab, luaL_checkstring(L, i));
const upb_def *def = upb_symtab_lookup(s->symtab, luaL_checkstring(L, i));
if (def) {
lupb_def_getorcreate(L, def, true);
} else {
@ -579,12 +579,12 @@ static int lupb_symtab_getdefs(lua_State *L) {
lupb_symtab *s = lupb_symtab_check(L, 1);
upb_deftype_t type = luaL_checkint(L, 2);
int count;
upb_def **defs = upb_symtab_getdefs(s->symtab, &count, type);
const upb_def **defs = upb_symtab_getdefs(s->symtab, &count, type);
// Create the table in which we will return the defs.
lua_createtable(L, count, 0);
for (int i = 0; i < count; i++) {
upb_def *def = defs[i];
const upb_def *def = defs[i];
lupb_def_getorcreate(L, def, true);
lua_rawseti(L, -2, i + 1);
}
@ -616,7 +616,7 @@ static const struct luaL_Reg lupb_symtab_mm[] = {
// {msgdef, <string, submessage, and array fields>}
// Must pass a upb_fielddef as the pointer.
static void lupb_array_pushnew(lua_State *L, void *f);
static void lupb_array_pushnew(lua_State *L, const void *f);
static void *lupb_msg_check(lua_State *L, int narg, upb_msgdef **md) {
void *msg = luaL_checkudata(L, narg, "upb.msg");
@ -632,14 +632,14 @@ static void *lupb_msg_check(lua_State *L, int narg, upb_msgdef **md) {
return msg;
}
static void lupb_msg_pushnew(lua_State *L, void *md) {
static void lupb_msg_pushnew(lua_State *L, const void *md) {
void *msg = lua_newuserdata(L, upb_msgdef_size(md));
luaL_getmetatable(L, "upb.msg");
assert(!lua_isnil(L, -1)); // Should have been created by luaopen_upb.
lua_setmetatable(L, -2);
upb_msg_clear(msg, md);
lua_getfenv(L, -1);
lupb_cache_getorcreate(L, md, "upb.msgdef");
lupb_cache_getorcreate(L, (void*)md, "upb.msgdef");
lua_rawseti(L, -2, 1);
lua_pop(L, 1); // Pop the fenv.
}
@ -755,10 +755,10 @@ static int lupb_msgdef(lua_State *L) {
//
// - use thread-local storage. Convenient and efficient, but not portable.
typedef void createfunc_t(lua_State *L, void *param);
typedef void createfunc_t(lua_State *L, const void *param);
static upb_sflow_t lupb_msg_start(void *m, upb_fielddef *f, bool array,
createfunc_t *pushnew, void *param) {
static upb_sflow_t lupb_msg_start(void *m, const upb_fielddef *f, bool array,
createfunc_t *pushnew, const void *param) {
lua_State *L = *(lua_State**)m;
int offset = array ? lua_rawlen(L, -1) : f->offset;
if (!lua_checkstack(L, 3)) luaL_error(L, "stack full");
@ -778,7 +778,7 @@ static upb_sflow_t lupb_msg_start(void *m, upb_fielddef *f, bool array,
static upb_flow_t lupb_msg_string(void *m, upb_value fval, upb_value val,
bool array) {
// Could add lazy materialization of strings here.
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
lua_State *L = *(lua_State**)m;
int offset = array ? lua_rawlen(L, -1) : f->offset;
if (!lua_checkstack(L, 1)) luaL_error(L, "stack full");
@ -788,17 +788,17 @@ static upb_flow_t lupb_msg_string(void *m, upb_value fval, upb_value val,
}
static upb_sflow_t lupb_msg_startseq(void *m, upb_value fval) {
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
return lupb_msg_start(m, f, false, lupb_array_pushnew, f);
}
static upb_sflow_t lupb_msg_startsubmsg(void *m, upb_value fval) {
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
return lupb_msg_start(m, f, false, lupb_msg_pushnew, upb_fielddef_subdef(f));
}
static upb_sflow_t lupb_msg_startsubmsg_r(void *a, upb_value fval) {
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
return lupb_msg_start(a, f, true, lupb_msg_pushnew, upb_fielddef_subdef(f));
}
@ -877,7 +877,7 @@ static void lupb_array_check(lua_State *L, int narg) {
luaL_typerror(L, narg, "upb array");
}
static void lupb_array_pushnew(lua_State *L, void *f) {
static void lupb_array_pushnew(lua_State *L, const void *f) {
(void)L;
(void)f;
}

@ -36,8 +36,8 @@ static upb_accessor_vtbl *PyUpb_AccessorForField(upb_fielddef *f);
// For objects that are just wrappers around a C object pointer, we keep a
// cache mapping C pointer -> wrapper object. This allows us to consistently
// vend the same Python object given the same C object. This prevents us from
// creating too many Python objects unnecessarily. More importantly, it provides
// the expected semantics:
// creating too many Python objects unnecessarily. Just as importantly, it
// provides the expected semantics:
//
// if field.subdef is field.subdef:
// print "Sanity prevails."
@ -66,7 +66,7 @@ static PyObject *weakref_callback = NULL;
// Utility functions for manipulating Python dictionaries keyed by pointer.
static PyObject *PyUpb_StringForPointer(void *ptr) {
static PyObject *PyUpb_StringForPointer(const void *ptr) {
PyObject *o = PyString_FromStringAndSize((const char *)&ptr, sizeof(void*));
assert(o);
return o;
@ -86,7 +86,7 @@ static PyObject *PyUpb_ObjCacheDeleteCallback(PyObject *self, PyObject *ref) {
return Py_None;
}
static PyObject *PyUpb_ObjCacheGet(void *obj, PyTypeObject *type) {
static PyObject *PyUpb_ObjCacheGet(const void *obj, PyTypeObject *type) {
PyObject *kv = PyUpb_StringForPointer(obj);
PyObject *ref = PyDict_GetItem(obj_cache, kv);
PyObject *ret;
@ -96,7 +96,7 @@ static PyObject *PyUpb_ObjCacheGet(void *obj, PyTypeObject *type) {
Py_INCREF(ret);
} else {
PyUpb_ObjWrapper *wrapper = (PyUpb_ObjWrapper*)type->tp_alloc(type, 0);
wrapper->obj = obj;
wrapper->obj = (void*)obj;
wrapper->weakreflist = NULL;
ret = (PyObject*)wrapper;
ref = PyWeakref_NewRef(ret, weakref_callback);
@ -113,7 +113,7 @@ static PyObject *PyUpb_ObjCacheGet(void *obj, PyTypeObject *type) {
/* PyUpb_Def ******************************************************************/
static PyTypeObject *PyUpb_TypeForDef(upb_def *def);
static PyTypeObject *PyUpb_TypeForDef(const upb_def *def);
static void PyUpb_Def_dealloc(PyObject *obj) {
PyUpb_ObjWrapper *wrapper = (void*)obj;
@ -121,7 +121,7 @@ static void PyUpb_Def_dealloc(PyObject *obj) {
obj->ob_type->tp_free(obj);
}
PyObject *PyUpb_Def_GetOrCreate(upb_def *def) {
PyObject *PyUpb_Def_GetOrCreate(const upb_def *def) {
return def ? PyUpb_ObjCacheGet(def, PyUpb_TypeForDef(def)) : Py_None;
}
@ -142,7 +142,7 @@ static int PyUpb_FieldDef_setattro(PyObject *o, PyObject *key, PyObject *val);
} \
} while(0)
static PyObject *PyUpb_FieldDef_GetOrCreate(upb_fielddef *f) {
static PyObject *PyUpb_FieldDef_GetOrCreate(const upb_fielddef *f) {
return PyUpb_ObjCacheGet(f, &PyUpb_FieldDefType);
}
@ -424,7 +424,7 @@ static PyTypeObject PyUpb_MessageDefType = {
};
static PyTypeObject *PyUpb_TypeForDef(upb_def *def) {
static PyTypeObject *PyUpb_TypeForDef(const upb_def *def) {
switch(def->type) {
case UPB_DEF_MSG: return &PyUpb_MessageDefType;
default: return NULL;
@ -499,7 +499,7 @@ static PyObject *PyUpb_SymbolTable_add_def(PyObject *o, PyObject *def) {
static PyObject *PyUpb_SymbolTable_defs(PyObject *o, PyObject *none) {
upb_symtab *s = Check_SymbolTable(o, NULL);
int count;
upb_def **defs = upb_symtab_getdefs(s, &count, UPB_DEF_ANY);
const upb_def **defs = upb_symtab_getdefs(s, &count, UPB_DEF_ANY);
PyObject *ret = PyList_New(count);
int i;
for(i = 0; i < count; i++)
@ -510,7 +510,7 @@ static PyObject *PyUpb_SymbolTable_defs(PyObject *o, PyObject *none) {
static PyObject *PyUpb_SymbolTable_lookup(PyObject *o, PyObject *arg) {
upb_symtab *s = Check_SymbolTable(o, NULL);
const char *name = PyString_AsString(arg);
upb_def *def = upb_symtab_lookup(s, name);
const upb_def *def = upb_symtab_lookup(s, name);
return PyUpb_Def_GetOrCreate(def);
}
@ -581,7 +581,7 @@ typedef struct {
PyObject **PyUpb_Accessor_GetPtr(PyObject *_m, upb_value fval) {
PyUpb_Message *m = (PyUpb_Message*)_m;
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
return (PyObject**)&m->data[f->offset];
}
@ -611,7 +611,7 @@ static upb_sflow_t PyUpb_Message_StartRepeatedSubmessage(void *a, upb_value fval
static upb_flow_t PyUpb_Message_StringValue(void *m, upb_value fval, upb_value val) {
PyObject **str = PyUpb_Accessor_GetPtr(m, fval);
if (*str) Py_DECREF(*str);
if (*str) { Py_DECREF(*str); }
*str = PyString_FromStringAndSize(NULL, upb_value_getstrref(val)->len);
upb_strref_read(upb_value_getstrref(val), PyString_AsString(*str));
upb_stdmsg_sethas(m, fval);

@ -10,7 +10,7 @@ static void TestSymbolTable() {
std::cerr << "Couldn't load descriptor: " << status;
exit(1);
}
upb::MessageDef *md = s->LookupMessage("A");
const upb::MessageDef *md = s->LookupMessage("A");
assert(md);
s->Unref();

@ -20,20 +20,20 @@ int main(int argc, char *argv[]) {
}
upb_status status = UPB_STATUS_INIT;
upb_read_descriptor(symtab, desc, desc_len, &status);
upb_load_descriptor_into_symtab(symtab, desc, desc_len, &status);
if (!upb_ok(&status)) {
fprintf(stderr, "Error parsing descriptor: %s", upb_status_getstr(&status));
return 1;
}
free((void*)desc);
upb_def *md = upb_symtab_lookup(symtab, argv[2]);
const upb_def *md = upb_symtab_lookup(symtab, argv[2]);
if (!md) {
fprintf(stderr, "Descriptor did not contain message: %s\n", argv[2]);
return 1;
}
upb_msgdef *m = upb_dyncast_msgdef(md);
const upb_msgdef *m = upb_dyncast_msgdef_const(md);
if (!m) {
fprintf(stderr, "Def was not a msgdef.\n");
return 1;

@ -8,7 +8,7 @@ int main() {
// Will be empty atm since we haven't added anything to the symtab.
int count;
upb_def **defs = upb_symtab_getdefs(s, &count, UPB_DEF_ANY);
const upb_def **defs = upb_symtab_getdefs(s, &count, UPB_DEF_ANY);
for (int i = 0; i < count; i++) {
upb_def_unref(defs[i]);
}

@ -21,7 +21,7 @@
size_t string_size;
void compare(const google::protobuf::Message& proto2_msg,
void *upb_msg, upb_msgdef *upb_md);
void *upb_msg, const upb_msgdef *upb_md);
void compare_arrays(const google::protobuf::Reflection *r,
const google::protobuf::Message& proto2_msg,
@ -143,7 +143,7 @@ void compare_values(const google::protobuf::Reflection *r,
}
void compare(const google::protobuf::Message& proto2_msg,
void *upb_msg, upb_msgdef *upb_md)
void *upb_msg, const upb_msgdef *upb_md)
{
const google::protobuf::Reflection *r = proto2_msg.GetReflection();
const google::protobuf::Descriptor *d = proto2_msg.GetDescriptor();
@ -179,7 +179,7 @@ void compare(const google::protobuf::Message& proto2_msg,
}
void parse_and_compare(MESSAGE_CIDENT *proto2_msg,
void *upb_msg, upb_msgdef *upb_md,
void *upb_msg, const upb_msgdef *upb_md,
const char *str, size_t len)
{
// Parse to both proto2 and upb.
@ -223,7 +223,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "Couldn't read " MESSAGE_DESCRIPTOR_FILE ".\n");
return 1;
}
upb_read_descriptor(symtab, fds, fds_len, &status);
upb_load_descriptor_into_symtab(symtab, fds, fds_len, &status);
if(!upb_ok(&status)) {
fprintf(stderr, "Error importing " MESSAGE_DESCRIPTOR_FILE ": %s",
upb_status_getstr(&status));
@ -231,9 +231,9 @@ int main(int argc, char *argv[])
}
free((void*)fds);
upb_def *def = upb_symtab_lookup(symtab, MESSAGE_NAME);
upb_msgdef *msgdef;
if(!def || !(msgdef = upb_dyncast_msgdef(def))) {
const upb_def *def = upb_symtab_lookup(symtab, MESSAGE_NAME);
const upb_msgdef *msgdef;
if(!def || !(msgdef = upb_dyncast_msgdef_const(def))) {
fprintf(stderr, "Error finding symbol '%s'.\n", MESSAGE_NAME);
return 1;
}

@ -1,4 +1,5 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@ -11,17 +12,12 @@
static upb_symtab *load_test_proto() {
upb_symtab *s = upb_symtab_new();
ASSERT(s);
size_t len;
char *descriptor = upb_readfile("tests/test.proto.pb", &len);
if(!descriptor) {
fprintf(stderr, "Couldn't read input file tests/test.proto.pb\n");
upb_status status = UPB_STATUS_INIT;
if (!upb_load_descriptor_file_into_symtab(s, "tests/test.proto.pb", &status)) {
fprintf(stderr, "Error loading descriptor file: %s\n", upb_status_getstr(&status));
exit(1);
}
upb_status status = UPB_STATUS_INIT;
upb_read_descriptor(s, descriptor, len, &status);
ASSERT(upb_ok(&status));
upb_status_uninit(&status);
free(descriptor);
return s;
}
@ -34,12 +30,12 @@ static upb_flow_t upb_test_onvalue(void *closure, upb_value fval, upb_value val)
static void test_upb_jit() {
upb_symtab *s = load_test_proto();
upb_def *def = upb_symtab_lookup(s, "SimplePrimitives");
const upb_def *def = upb_symtab_lookup(s, "SimplePrimitives");
ASSERT(def);
upb_handlers *h = upb_handlers_new();
upb_handlerset hset = {NULL, NULL, &upb_test_onvalue, NULL, NULL, NULL, NULL};
upb_handlers_reghandlerset(h, upb_downcast_msgdef(def), &hset);
upb_handlers_reghandlerset(h, upb_downcast_msgdef_const(def), &hset);
upb_decoder d;
upb_decoder_init(&d, h);
upb_decoder_uninit(&d);
@ -53,10 +49,10 @@ static void test_upb_symtab() {
// Test cycle detection by making a cyclic def's main refcount go to zero
// and then be incremented to one again.
upb_def *def = upb_symtab_lookup(s, "A");
const upb_def *def = upb_symtab_lookup(s, "A");
ASSERT(def);
upb_symtab_unref(s);
upb_msgdef *m = upb_downcast_msgdef(def);
const upb_msgdef *m = upb_downcast_msgdef_const(def);
upb_msg_iter i = upb_msg_begin(m);
upb_fielddef *f = upb_msg_iter_field(i);
ASSERT(upb_hassubdef(f));

@ -36,8 +36,8 @@ static void to_preproc(char *str) {
/* The _const.h file defines the constants (enums) defined in the .proto
* file. */
static void write_const_h(upb_def *defs[], int num_entries, char *outfile_name,
FILE *stream) {
static void write_const_h(const upb_def *defs[], int num_entries,
char *outfile_name, FILE *stream) {
/* Header file prologue. */
char *include_guard_name = strdup(outfile_name);
to_preproc(include_guard_name);
@ -54,7 +54,7 @@ static void write_const_h(upb_def *defs[], int num_entries, char *outfile_name,
fprintf(stream, "/* Enums. */\n\n");
for(int i = 0; i < num_entries; i++) { /* Foreach enum */
if(defs[i]->type != UPB_DEF_ENUM) continue;
upb_enumdef *enumdef = upb_downcast_enumdef(defs[i]);
const upb_enumdef *enumdef = upb_downcast_enumdef_const(defs[i]);
char *enum_name = strdup(upb_def_fqname(UPB_UPCAST(enumdef)));
char *enum_val_prefix = strdup(enum_name);
to_cident(enum_name);
@ -83,7 +83,7 @@ static void write_const_h(upb_def *defs[], int num_entries, char *outfile_name,
/* Constants for field names and numbers. */
fprintf(stream, "/* Constants for field names and numbers. */\n\n");
for(int i = 0; i < num_entries; i++) { /* Foreach enum */
upb_msgdef *m = upb_dyncast_msgdef(defs[i]);
const upb_msgdef *m = upb_dyncast_msgdef_const(defs[i]);
if(!m) continue;
char *msg_name = strdup(upb_def_fqname(UPB_UPCAST(m)));
char *msg_val_prefix = strdup(msg_name);
@ -167,7 +167,7 @@ int main(int argc, char *argv[]) {
// importing descriptor.proto.
upb_symtab *s = upb_symtab_new();
upb_status status = UPB_STATUS_INIT;
upb_read_descriptor(s, descriptor, len, &status);
upb_load_descriptor_into_symtab(s, descriptor, len, &status);
if(!upb_ok(&status)) {
error("Failed to parse input file descriptor: %s\n",
upb_status_getstr(&status));
@ -184,7 +184,7 @@ int main(int argc, char *argv[]) {
if(!h_const_file) error("Failed to open _const.h output file\n");
int symcount;
upb_def **defs = upb_symtab_getdefs(s, &symcount, UPB_DEF_ANY);
const upb_def **defs = upb_symtab_getdefs(s, &symcount, UPB_DEF_ANY);
write_const_h(defs, symcount, h_const_filename, h_const_file);
for (int i = 0; i < symcount; i++) upb_def_unref(defs[i]);
free(defs);

@ -130,11 +130,11 @@ INLINE bool upb_atomic_only(upb_atomic_t *a) {
typedef struct {
} upb_rwlock_t;
INLINE void upb_rwlock_init(upb_rwlock_t *l) { (void)l; }
INLINE void upb_rwlock_destroy(upb_rwlock_t *l) { (void)l; }
INLINE void upb_rwlock_rdlock(upb_rwlock_t *l) { (void)l; }
INLINE void upb_rwlock_wrlock(upb_rwlock_t *l) { (void)l; }
INLINE void upb_rwlock_unlock(upb_rwlock_t *l) { (void)l; }
INLINE void upb_rwlock_init(const upb_rwlock_t *l) { (void)l; }
INLINE void upb_rwlock_destroy(const upb_rwlock_t *l) { (void)l; }
INLINE void upb_rwlock_rdlock(const upb_rwlock_t *l) { (void)l; }
INLINE void upb_rwlock_wrlock(const upb_rwlock_t *l) { (void)l; }
INLINE void upb_rwlock_unlock(const upb_rwlock_t *l) { (void)l; }
#elif defined(UPB_USE_PTHREADS)
@ -144,27 +144,27 @@ typedef struct {
pthread_rwlock_t lock;
} upb_rwlock_t;
INLINE void upb_rwlock_init(upb_rwlock_t *l) {
INLINE void upb_rwlock_init(const upb_rwlock_t *l) {
/* TODO: check return value. */
pthread_rwlock_init(&l->lock, NULL);
}
INLINE void upb_rwlock_destroy(upb_rwlock_t *l) {
INLINE void upb_rwlock_destroy(const upb_rwlock_t *l) {
/* TODO: check return value. */
pthread_rwlock_destroy(&l->lock);
}
INLINE void upb_rwlock_rdlock(upb_rwlock_t *l) {
INLINE void upb_rwlock_rdlock(const upb_rwlock_t *l) {
/* TODO: check return value. */
pthread_rwlock_rdlock(&l->lock);
}
INLINE void upb_rwlock_wrlock(upb_rwlock_t *l) {
INLINE void upb_rwlock_wrlock(const upb_rwlock_t *l) {
/* TODO: check return value. */
pthread_rwlock_wrlock(&l->lock);
}
INLINE void upb_rwlock_unlock(upb_rwlock_t *l) {
INLINE void upb_rwlock_unlock(const upb_rwlock_t *l) {
/* TODO: check return value. */
pthread_rwlock_unlock(&l->lock);
}

@ -14,7 +14,7 @@
// We can make this configurable if necessary.
#define BUF_SIZE 32768
char *upb_strref_dup(struct _upb_strref *r) {
char *upb_strref_dup(const struct _upb_strref *r) {
char *ret = (char*)malloc(r->len + 1);
upb_bytesrc_read(r->bytesrc, r->stream_offset, r->len, ret);
ret[r->len] = '\0';
@ -38,7 +38,7 @@ int upb_stdio_cmpbuf(const void *_key, const void *_elem) {
return (*ofs / BUF_SIZE) - (buf->ofs / BUF_SIZE);
}
static upb_stdio_buf *upb_stdio_findbuf(upb_stdio *s, uint64_t ofs) {
static upb_stdio_buf *upb_stdio_findbuf(const upb_stdio *s, uint64_t ofs) {
// TODO: it is probably faster to linear search short lists, and to
// special-case the last one or two bufs.
return bsearch(&ofs, s->bufs, s->nbuf, sizeof(*s->bufs), &upb_stdio_cmpbuf);
@ -86,7 +86,7 @@ size_t upb_stdio_fetch(void *src, uint64_t ofs, upb_status *s) {
return buf->ofs + buf->len;
}
void upb_stdio_read(void *src, uint64_t src_ofs, size_t len, char *dst) {
void upb_stdio_read(const void *src, uint64_t src_ofs, size_t len, char *dst) {
upb_stdio_buf *buf = upb_stdio_findbuf(src, src_ofs);
src_ofs -= buf->ofs;
memcpy(dst, &buf->data[src_ofs], BUF_SIZE - src_ofs);
@ -203,8 +203,9 @@ size_t upb_stringsrc_fetch(void *_src, uint64_t ofs, upb_status *s) {
return src->len - ofs;
}
void upb_stringsrc_read(void *_src, uint64_t src_ofs, size_t len, char *dst) {
upb_stringsrc *src = _src;
void upb_stringsrc_read(const void *_src, uint64_t src_ofs,
size_t len, char *dst) {
const upb_stringsrc *src = _src;
memcpy(dst, src->str + src_ofs, len);
}

@ -36,7 +36,7 @@ extern "C" {
// data around for later use, without requiring a copy out of the input
// buffers.
typedef size_t upb_bytesrc_fetch_func(void*, uint64_t, upb_status*);
typedef void upb_bytesrc_read_func(void*, uint64_t, size_t, char*);
typedef void upb_bytesrc_read_func(const void*, uint64_t, size_t, char*);
typedef const char *upb_bytesrc_getptr_func(void*, uint64_t, size_t*);
typedef void upb_bytesrc_refregion_func(void*, uint64_t, size_t);
typedef void upb_bytesrc_ref_func(void*);
@ -74,8 +74,8 @@ INLINE size_t upb_bytesrc_fetch(upb_bytesrc *src, uint64_t ofs, upb_status *s) {
// Copies "len" bytes of data from offset src_ofs to "dst", which must be at
// least "len" bytes long. The caller must own a ref on the given region.
INLINE void upb_bytesrc_read(upb_bytesrc *src, uint64_t src_ofs, size_t len,
char *dst) {
INLINE void upb_bytesrc_read(const upb_bytesrc *src, uint64_t src_ofs,
size_t len, char *dst) {
src->vtbl->read(src, src_ofs, len, dst);
}
@ -149,9 +149,9 @@ typedef struct _upb_strref {
// Copies the contents of the strref into a newly-allocated, NULL-terminated
// string.
char *upb_strref_dup(struct _upb_strref *r);
char *upb_strref_dup(const struct _upb_strref *r);
INLINE void upb_strref_read(struct _upb_strref *r, char *buf) {
INLINE void upb_strref_read(const struct _upb_strref *r, char *buf) {
if (r->ptr) {
memcpy(buf, r->ptr, r->len);
} else {

@ -38,7 +38,7 @@ static void upb_msgdef_free(upb_msgdef *m);
static void upb_enumdef_free(upb_enumdef *e);
static void upb_unresolveddef_free(struct _upb_unresolveddef *u);
bool upb_def_ismutable(upb_def *def) { return def->symtab == NULL; }
bool upb_def_ismutable(const upb_def *def) { return def->symtab == NULL; }
bool upb_def_setfqname(upb_def *def, const char *fqname) {
assert(upb_def_ismutable(def));
@ -58,10 +58,12 @@ static void upb_def_free(upb_def *def) {
}
}
upb_def *upb_def_dup(upb_def *def) {
upb_def *upb_def_dup(const upb_def *def) {
switch (def->type) {
case UPB_DEF_MSG: return UPB_UPCAST(upb_msgdef_dup(upb_downcast_msgdef(def)));
case UPB_DEF_ENUM: return UPB_UPCAST(upb_enumdef_dup(upb_downcast_enumdef(def)));
case UPB_DEF_MSG:
return UPB_UPCAST(upb_msgdef_dup(upb_downcast_msgdef_const(def)));
case UPB_DEF_ENUM:
return UPB_UPCAST(upb_enumdef_dup(upb_downcast_enumdef_const(def)));
default: assert(false); return NULL;
}
}
@ -70,7 +72,8 @@ upb_def *upb_def_dup(upb_def *def) {
// def itself. If the refcount falls to zero, the def is deleted. Once the
// def belongs to a symtab, the def is owned by the symtab and its refcount
// determines whether the def owns a ref on the symtab or not.
void upb_def_ref(upb_def *def) {
void upb_def_ref(const upb_def *_def) {
upb_def *def = (upb_def*)_def; // Need to modify refcount.
if (upb_atomic_ref(&def->refcount) && def->symtab)
upb_symtab_ref(def->symtab);
}
@ -83,7 +86,8 @@ static void upb_def_movetosymtab(upb_def *d, upb_symtab *s) {
if (m) upb_inttable_compact(&m->itof);
}
void upb_def_unref(upb_def *def) {
void upb_def_unref(const upb_def *_def) {
upb_def *def = (upb_def*)_def; // Need to modify refcount.
if (!def) return;
if (upb_atomic_unref(&def->refcount)) {
if (def->symtab) {
@ -152,7 +156,7 @@ static void upb_enumdef_free(upb_enumdef *e) {
free(e);
}
upb_enumdef *upb_enumdef_dup(upb_enumdef *e) {
upb_enumdef *upb_enumdef_dup(const upb_enumdef *e) {
upb_enumdef *new_e = upb_enumdef_new();
upb_enum_iter i;
for(i = upb_enum_begin(e); !upb_enum_done(i); i = upb_enum_next(e, i)) {
@ -176,12 +180,12 @@ void upb_enumdef_setdefault(upb_enumdef *e, int32_t val) {
e->defaultval = val;
}
upb_enum_iter upb_enum_begin(upb_enumdef *e) {
upb_enum_iter upb_enum_begin(const upb_enumdef *e) {
// We could iterate over either table here; the choice is arbitrary.
return upb_inttable_begin(&e->iton);
}
upb_enum_iter upb_enum_next(upb_enumdef *e, upb_enum_iter iter) {
upb_enum_iter upb_enum_next(const upb_enumdef *e, upb_enum_iter iter) {
return upb_inttable_next(&e->iton, iter);
}
@ -267,11 +271,11 @@ upb_fielddef *upb_fielddef_dup(upb_fielddef *f) {
return f;
}
bool upb_fielddef_ismutable(upb_fielddef *f) {
bool upb_fielddef_ismutable(const upb_fielddef *f) {
return !f->msgdef || upb_def_ismutable(UPB_UPCAST(f->msgdef));
}
upb_def *upb_fielddef_subdef(upb_fielddef *f) {
upb_def *upb_fielddef_subdef(const upb_fielddef *f) {
if (upb_hassubdef(f) && !upb_fielddef_ismutable(f))
return f->def;
else
@ -403,7 +407,7 @@ static void upb_msgdef_free(upb_msgdef *m) {
free(m);
}
upb_msgdef *upb_msgdef_dup(upb_msgdef *m) {
upb_msgdef *upb_msgdef_dup(const upb_msgdef *m) {
upb_msgdef *newm = upb_msgdef_new();
newm->size = m->size;
newm->hasbit_bytes = m->hasbit_bytes;
@ -512,31 +516,24 @@ void upb_msgdef_layout(upb_msgdef *m) {
free(sorted_fields);
}
upb_msg_iter upb_msg_begin(upb_msgdef *m) {
upb_msg_iter upb_msg_begin(const upb_msgdef *m) {
return upb_inttable_begin(&m->itof);
}
upb_msg_iter upb_msg_next(upb_msgdef *m, upb_msg_iter iter) {
upb_msg_iter upb_msg_next(const upb_msgdef *m, upb_msg_iter iter) {
return upb_inttable_next(&m->itof, iter);
}
/* upb_symtab *****************************************************************/
struct _upb_symtab {
upb_atomic_t refcount;
upb_rwlock_t lock; // Protects all members except the refcount.
upb_strtable symtab; // The symbol table.
upb_deflist olddefs;
};
typedef struct {
upb_def *def;
} upb_symtab_ent;
// Given a symbol and the base symbol inside which it is defined, find the
// symbol's definition in t.
static upb_symtab_ent *upb_resolve(upb_strtable *t,
static upb_symtab_ent *upb_resolve(const upb_strtable *t,
const char *base, const char *sym) {
if(strlen(sym) == 0) return NULL;
if(sym[0] == UPB_SYMBOL_SEPARATOR) {
@ -575,9 +572,13 @@ static void upb_symtab_free(upb_symtab *s) {
free(s);
}
void upb_symtab_ref(upb_symtab *s) { upb_atomic_ref(&s->refcount); }
void upb_symtab_ref(const upb_symtab *_s) {
upb_symtab *s = (upb_symtab*)_s;
upb_atomic_ref(&s->refcount);
}
void upb_symtab_unref(upb_symtab *s) {
void upb_symtab_unref(const upb_symtab *_s) {
upb_symtab *s = (upb_symtab*)_s;
if(s && upb_atomic_unref(&s->refcount)) {
upb_symtab_free(s);
}
@ -592,12 +593,13 @@ upb_symtab *upb_symtab_new() {
return s;
}
upb_def **upb_symtab_getdefs(upb_symtab *s, int *count, upb_deftype_t type) {
const upb_def **upb_symtab_getdefs(const upb_symtab *s, int *count,
upb_deftype_t type) {
upb_rwlock_rdlock(&s->lock);
int total = upb_strtable_count(&s->symtab);
// We may only use part of this, depending on how many symbols are of the
// correct type.
upb_def **defs = malloc(sizeof(*defs) * total);
const upb_def **defs = malloc(sizeof(*defs) * total);
upb_strtable_iter iter;
upb_strtable_begin(&iter, &s->symtab);
int i = 0;
@ -614,7 +616,7 @@ upb_def **upb_symtab_getdefs(upb_symtab *s, int *count, upb_deftype_t type) {
return defs;
}
upb_def *upb_symtab_lookup(upb_symtab *s, const char *sym) {
const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym) {
upb_rwlock_rdlock(&s->lock);
upb_symtab_ent *e = upb_strtable_lookup(&s->symtab, sym);
upb_def *ret = NULL;
@ -626,7 +628,20 @@ upb_def *upb_symtab_lookup(upb_symtab *s, const char *sym) {
return ret;
}
upb_def *upb_symtab_resolve(upb_symtab *s, const char *base, const char *sym) {
const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
upb_rwlock_rdlock(&s->lock);
upb_symtab_ent *e = upb_strtable_lookup(&s->symtab, sym);
upb_msgdef *ret = NULL;
if(e && e->def->type == UPB_DEF_MSG) {
ret = upb_downcast_msgdef(e->def);
upb_def_ref(UPB_UPCAST(ret));
}
upb_rwlock_unlock(&s->lock);
return ret;
}
const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
const char *sym) {
upb_rwlock_rdlock(&s->lock);
upb_symtab_ent *e = upb_resolve(&s->symtab, base, sym);
upb_def *ret = NULL;

@ -11,13 +11,36 @@
* - upb_enumdef: describes an enum.
* (TODO: definitions of services).
*
* These defs are mutable (and not thread-safe) when first created.
* Once they are added to a defbuilder (and later its symtab) they become
* immutable.
*
* TODO: consider making thread-safe even when first created by using mutexes
* internally. Would also have to change any methods returning pointers to
* return copies instead.
* Defs go through two distinct phases of life:
*
* 1. MUTABLE: when first created, the properties of the def can be set freely
* (for example a message's name, its list of fields, the name/number of
* fields, etc). During this phase the def is *not* thread-safe, and may
* not be used for any purpose except to set its properties (it can't be
* used to parse anything, create any messages in memory, etc).
*
* 2. IMMUTABLE: after being added to a symtab (which links the defs together)
* the defs become thread-safe and immutable. Programs may only access defs
* through a CONST POINTER during this stage -- upb_symtab will help you out
* with this requirement by only vending const pointers, but you need to
* make sure not to use any non-const pointers you still have sitting
* around. In practice this means that you may not call any setters on the
* defs (or functions that themselves call the setters). If you want to
* modify an existing immutable def, copy it with upb_*_dup(), modify the
* copy, and add the modified def to the symtab (replacing the existing
* def).
*
* You can test for which stage of life a def is in by calling
* upb_def_ismutable(). This is particularly useful for dynamic language
* bindings, which must properly guarantee that the dynamic language cannot
* break the rules laid out above.
*
* It would be possible to make the defs thread-safe during stage 1 by using
* mutexes internally and changing any methods returning pointers to return
* copies instead. This could be important if we are integrating with a VM or
* interpreter that does not naturally serialize access to wrapped objects (for
* example, in the case of Python this is not necessary because of the GIL).
*/
#ifndef UPB_DEF_H_
@ -58,13 +81,13 @@ typedef struct {
// until the def is in a symtab. While a def is in a symtab, everything
// reachable from that def (the symtab and all defs in the symtab) are
// guaranteed to be alive.
void upb_def_ref(upb_def *def);
void upb_def_unref(upb_def *def);
upb_def *upb_def_dup(upb_def *def);
void upb_def_ref(const upb_def *def);
void upb_def_unref(const upb_def *def);
upb_def *upb_def_dup(const upb_def *def);
// A def is mutable until it has been added to a symtab.
bool upb_def_ismutable(upb_def *def);
INLINE const char *upb_def_fqname(upb_def *def) { return def->fqname; }
bool upb_def_ismutable(const upb_def *def);
INLINE const char *upb_def_fqname(const upb_def *def) { return def->fqname; }
bool upb_def_setfqname(upb_def *def, const char *fqname); // Only if mutable.
#define UPB_UPCAST(ptr) (&(ptr)->base)
@ -103,7 +126,7 @@ void upb_fielddef_unref(upb_fielddef *f);
upb_fielddef *upb_fielddef_dup(upb_fielddef *f);
// A fielddef is mutable until its msgdef has been added to a symtab.
bool upb_fielddef_ismutable(upb_fielddef *f);
bool upb_fielddef_ismutable(const upb_fielddef *f);
// Read accessors. May be called any time.
INLINE uint8_t upb_fielddef_type(upb_fielddef *f) { return f->type; }
@ -127,7 +150,7 @@ INLINE const char *upb_fielddef_typename(upb_fielddef *f) {
// submessage, group, and enum fields (ie. when upb_hassubdef(f) is true).
// Since defs are not linked together until they are in a symtab, this
// will return NULL until the msgdef is in a symtab.
upb_def *upb_fielddef_subdef(upb_fielddef *f);
upb_def *upb_fielddef_subdef(const upb_fielddef *f);
// Write accessors. "Number" and "name" must be set before the fielddef is
// added to a msgdef. For the moment we do not allow these to be set once
@ -155,12 +178,12 @@ INLINE bool upb_isstringtype(upb_fieldtype_t type) {
INLINE bool upb_isprimitivetype(upb_fieldtype_t type) {
return !upb_issubmsgtype(type) && !upb_isstringtype(type);
}
INLINE bool upb_issubmsg(upb_fielddef *f) { return upb_issubmsgtype(f->type); }
INLINE bool upb_isstring(upb_fielddef *f) { return upb_isstringtype(f->type); }
INLINE bool upb_isseq(upb_fielddef *f) { return f->label == UPB_LABEL(REPEATED); }
INLINE bool upb_issubmsg(const upb_fielddef *f) { return upb_issubmsgtype(f->type); }
INLINE bool upb_isstring(const upb_fielddef *f) { return upb_isstringtype(f->type); }
INLINE bool upb_isseq(const upb_fielddef *f) { return f->label == UPB_LABEL(REPEATED); }
// Does the type of this field imply that it should contain an associated def?
INLINE bool upb_hassubdef(upb_fielddef *f) {
INLINE bool upb_hassubdef(const upb_fielddef *f) {
return upb_issubmsg(f) || f->type == UPB_TYPE(ENUM);
}
@ -192,22 +215,22 @@ typedef struct {
} upb_ntof_ent;
upb_msgdef *upb_msgdef_new(void);
INLINE void upb_msgdef_unref(upb_msgdef *md) { upb_def_unref(UPB_UPCAST(md)); }
INLINE void upb_msgdef_ref(upb_msgdef *md) { upb_def_ref(UPB_UPCAST(md)); }
INLINE void upb_msgdef_unref(const upb_msgdef *md) { upb_def_unref(UPB_UPCAST(md)); }
INLINE void upb_msgdef_ref(const upb_msgdef *md) { upb_def_ref(UPB_UPCAST(md)); }
// Returns a new msgdef that is a copy of the given msgdef (and a copy of all
// the fields) but with any references to submessages broken and replaced with
// just the name of the submessage. This can be put back into another symtab
// and the names will be re-resolved in the new context.
upb_msgdef *upb_msgdef_dup(upb_msgdef *m);
upb_msgdef *upb_msgdef_dup(const upb_msgdef *m);
// Read accessors. May be called at any time.
INLINE uint16_t upb_msgdef_size(upb_msgdef *m) { return m->size; }
INLINE uint8_t upb_msgdef_hasbit_bytes(upb_msgdef *m) {
INLINE uint16_t upb_msgdef_size(const upb_msgdef *m) { return m->size; }
INLINE uint8_t upb_msgdef_hasbit_bytes(const upb_msgdef *m) {
return m->hasbit_bytes;
}
INLINE uint32_t upb_msgdef_extstart(upb_msgdef *m) { return m->extstart; }
INLINE uint32_t upb_msgdef_extend(upb_msgdef *m) { return m->extend; }
INLINE uint32_t upb_msgdef_extstart(const upb_msgdef *m) { return m->extstart; }
INLINE uint32_t upb_msgdef_extend(const upb_msgdef *m) { return m->extend; }
// Write accessors. May only be called before the msgdef is in a symtab.
void upb_msgdef_setsize(upb_msgdef *m, uint16_t size);
@ -248,7 +271,7 @@ INLINE upb_fielddef *upb_msgdef_ntof(upb_msgdef *m, const char *name) {
return e ? e->f : NULL;
}
INLINE int upb_msgdef_numfields(upb_msgdef *m) {
INLINE int upb_msgdef_numfields(const upb_msgdef *m) {
return upb_strtable_count(&m->ntof);
}
@ -262,8 +285,8 @@ INLINE int upb_msgdef_numfields(upb_msgdef *m) {
// }
typedef upb_inttable_iter upb_msg_iter;
upb_msg_iter upb_msg_begin(upb_msgdef *m);
upb_msg_iter upb_msg_next(upb_msgdef *m, upb_msg_iter iter);
upb_msg_iter upb_msg_begin(const upb_msgdef *m);
upb_msg_iter upb_msg_next(const upb_msgdef *m, upb_msg_iter iter);
INLINE bool upb_msg_done(upb_msg_iter iter) { return upb_inttable_done(iter); }
// Iterator accessor.
@ -292,9 +315,9 @@ typedef struct {
} upb_iton_ent;
upb_enumdef *upb_enumdef_new(void);
INLINE void upb_enumdef_ref(upb_enumdef *e) { upb_def_ref(UPB_UPCAST(e)); }
INLINE void upb_enumdef_unref(upb_enumdef *e) { upb_def_unref(UPB_UPCAST(e)); }
upb_enumdef *upb_enumdef_dup(upb_enumdef *e);
INLINE void upb_enumdef_ref(const upb_enumdef *e) { upb_def_ref(UPB_UPCAST(e)); }
INLINE void upb_enumdef_unref(const upb_enumdef *e) { upb_def_unref(UPB_UPCAST(e)); }
upb_enumdef *upb_enumdef_dup(const upb_enumdef *e);
INLINE int32_t upb_enumdef_default(upb_enumdef *e) { return e->defaultval; }
@ -320,8 +343,8 @@ const char *upb_enumdef_iton(upb_enumdef *e, int32_t num);
// }
typedef upb_inttable_iter upb_enum_iter;
upb_enum_iter upb_enum_begin(upb_enumdef *e);
upb_enum_iter upb_enum_next(upb_enumdef *e, upb_enum_iter iter);
upb_enum_iter upb_enum_begin(const upb_enumdef *e);
upb_enum_iter upb_enum_next(const upb_enumdef *e, upb_enum_iter iter);
INLINE bool upb_enum_done(upb_enum_iter iter) { return upb_inttable_done(iter); }
// Iterator accessors.
@ -334,15 +357,36 @@ INLINE int32_t upb_enum_iter_number(upb_enum_iter iter) {
}
/* upb_deflist ****************************************************************/
// upb_deflist is an internal-only dynamic array for storing a growing list of
// upb_defs.
typedef struct {
upb_def **defs;
uint32_t len;
uint32_t size;
} upb_deflist;
void upb_deflist_init(upb_deflist *l);
void upb_deflist_uninit(upb_deflist *l);
void upb_deflist_push(upb_deflist *l, upb_def *d);
/* upb_symtab *****************************************************************/
// A symtab (symbol table) is where upb_defs live. It is empty when first
// constructed. Clients add definitions to the symtab (or replace existing
// definitions) by calling upb_symtab_add().
struct _upb_symtab {
upb_atomic_t refcount;
upb_rwlock_t lock; // Protects all members except the refcount.
upb_strtable symtab; // The symbol table.
upb_deflist olddefs;
};
upb_symtab *upb_symtab_new(void);
void upb_symtab_ref(upb_symtab *s);
void upb_symtab_unref(upb_symtab *s);
void upb_symtab_ref(const upb_symtab *s);
void upb_symtab_unref(const upb_symtab *s);
// Resolves the given symbol using the rules described in descriptor.proto,
// namely:
@ -354,20 +398,19 @@ void upb_symtab_unref(upb_symtab *s);
//
// If a def is found, the caller owns one ref on the returned def. Otherwise
// returns NULL.
// TODO: make return const
upb_def *upb_symtab_resolve(upb_symtab *s, const char *base, const char *sym);
const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
const char *sym);
// Find an entry in the symbol table with this exact name. If a def is found,
// the caller owns one ref on the returned def. Otherwise returns NULL.
// TODO: make return const
upb_def *upb_symtab_lookup(upb_symtab *s, const char *sym);
const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym);
const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym);
// Gets an array of pointers to all currently active defs in this symtab. The
// caller owns the returned array (which is of length *count) as well as a ref
// to each symbol inside. If type is UPB_DEF_ANY then defs of all types are
// returned, otherwise only defs of the required type are returned.
// TODO: make return const
upb_def **upb_symtab_getdefs(upb_symtab *s, int *n, upb_deftype_t type);
const upb_def **upb_symtab_getdefs(const upb_symtab *s, int *n, upb_deftype_t type);
// Adds the given defs to the symtab, resolving all symbols. Only one def per
// name may be in the list, but defs can replace existing defs in the symtab.
@ -385,46 +428,31 @@ void upb_symtab_gc(upb_symtab *s);
/* upb_def casts **************************************************************/
// Dynamic casts, for determining if a def is of a particular type at runtime.
#define UPB_DYNAMIC_CAST_DEF(lower, upper) \
// Downcasts, for when some wants to assert that a def is of a particular type.
// These are only checked if we are building debug.
#define UPB_DEF_CASTS(lower, upper) \
struct _upb_ ## lower; /* Forward-declare. */ \
INLINE struct _upb_ ## lower *upb_dyncast_ ## lower(upb_def *def) { \
if(def->type != UPB_DEF_ ## upper) return NULL; \
return (struct _upb_ ## lower*)def; \
}
UPB_DYNAMIC_CAST_DEF(msgdef, MSG);
UPB_DYNAMIC_CAST_DEF(enumdef, ENUM);
UPB_DYNAMIC_CAST_DEF(svcdef, SERVICE);
UPB_DYNAMIC_CAST_DEF(unresolveddef, UNRESOLVED);
#undef UPB_DYNAMIC_CAST_DEF
// Downcasts, for when some wants to assert that a def is of a particular type.
// These are only checked if we are building debug.
#define UPB_DOWNCAST_DEF(lower, upper) \
struct _upb_ ## lower; /* Forward-declare. */ \
} \
INLINE const struct _upb_ ## lower *upb_dyncast_ ## lower ## _const(const upb_def *def) { \
if(def->type != UPB_DEF_ ## upper) return NULL; \
return (const struct _upb_ ## lower*)def; \
} \
INLINE struct _upb_ ## lower *upb_downcast_ ## lower(upb_def *def) { \
assert(def->type == UPB_DEF_ ## upper); \
return (struct _upb_ ## lower*)def; \
} \
INLINE const struct _upb_ ## lower *upb_downcast_ ## lower ## _const(const upb_def *def) { \
assert(def->type == UPB_DEF_ ## upper); \
return (const struct _upb_ ## lower*)def; \
}
UPB_DOWNCAST_DEF(msgdef, MSG);
UPB_DOWNCAST_DEF(enumdef, ENUM);
UPB_DOWNCAST_DEF(svcdef, SERVICE);
UPB_DOWNCAST_DEF(unresolveddef, UNRESOLVED);
#undef UPB_DOWNCAST_DEF
/* upb_deflist ****************************************************************/
// upb_deflist is an internal-only dynamic array for storing a growing list of
// upb_defs.
typedef struct {
upb_def **defs;
uint32_t len;
uint32_t size;
} upb_deflist;
void upb_deflist_init(upb_deflist *l);
void upb_deflist_uninit(upb_deflist *l);
void upb_deflist_push(upb_deflist *l, upb_def *d);
UPB_DEF_CASTS(msgdef, MSG);
UPB_DEF_CASTS(enumdef, ENUM);
UPB_DEF_CASTS(svcdef, SERVICE);
UPB_DEF_CASTS(unresolveddef, UNRESOLVED);
#undef UPB_DEF_CASTS
#ifdef __cplusplus
} /* extern "C" */

@ -107,7 +107,7 @@ typedef struct {
upb_mhandlers *mh;
} upb_mtab_ent;
static upb_mhandlers *upb_regmsg_dfs(upb_handlers *h, upb_msgdef *m,
static upb_mhandlers *upb_regmsg_dfs(upb_handlers *h, const upb_msgdef *m,
upb_onmsgreg *msgreg_cb,
upb_onfieldreg *fieldreg_cb,
void *closure, upb_strtable *mtab) {
@ -139,7 +139,7 @@ static upb_mhandlers *upb_regmsg_dfs(upb_handlers *h, upb_msgdef *m,
return mh;
}
upb_mhandlers *upb_handlers_regmsgdef(upb_handlers *h, upb_msgdef *m,
upb_mhandlers *upb_handlers_regmsgdef(upb_handlers *h, const upb_msgdef *m,
upb_onmsgreg *msgreg_cb,
upb_onfieldreg *fieldreg_cb,
void *closure) {

@ -166,7 +166,7 @@ void upb_fhandlers_unref(upb_fhandlers *m);
// upb_fhandlers accessors
#define UPB_FHANDLERS_ACCESSORS(name, type) \
INLINE void upb_fhandlers_set ## name(upb_fhandlers *f, type v){f->name = v;} \
INLINE type upb_fhandlers_get ## name(upb_fhandlers *f) { return f->name; }
INLINE type upb_fhandlers_get ## name(const upb_fhandlers *f) { return f->name; }
UPB_FHANDLERS_ACCESSORS(fval, upb_value)
UPB_FHANDLERS_ACCESSORS(value, upb_value_handler*)
UPB_FHANDLERS_ACCESSORS(startsubmsg, upb_startfield_handler*)
@ -257,9 +257,9 @@ upb_mhandlers *upb_handlers_getmhandlers(upb_handlers *h, int index);
// with "fieldreg_cb"
//
// See upb_handlers_reghandlerset() below for an example.
typedef void upb_onmsgreg(void *closure, upb_mhandlers *mh, upb_msgdef *m);
typedef void upb_onfieldreg(void *closure, upb_fhandlers *mh, upb_fielddef *m);
upb_mhandlers *upb_handlers_regmsgdef(upb_handlers *h, upb_msgdef *m,
typedef void upb_onmsgreg(void *closure, upb_mhandlers *mh, const upb_msgdef *m);
typedef void upb_onfieldreg(void *closure, upb_fhandlers *mh, const upb_fielddef *m);
upb_mhandlers *upb_handlers_regmsgdef(upb_handlers *h, const upb_msgdef *m,
upb_onmsgreg *msgreg_cb,
upb_onfieldreg *fieldreg_cb,
void *closure);
@ -278,13 +278,13 @@ typedef struct {
upb_endfield_handler *endseq;
} upb_handlerset;
INLINE void upb_onmreg_hset(void *c, upb_mhandlers *mh, upb_msgdef *m) {
INLINE void upb_onmreg_hset(void *c, upb_mhandlers *mh, const upb_msgdef *m) {
(void)m;
upb_handlerset *hs = (upb_handlerset*)c;
if (hs->startmsg) upb_mhandlers_setstartmsg(mh, hs->startmsg);
if (hs->endmsg) upb_mhandlers_setendmsg(mh, hs->endmsg);
}
INLINE void upb_onfreg_hset(void *c, upb_fhandlers *fh, upb_fielddef *f) {
INLINE void upb_onfreg_hset(void *c, upb_fhandlers *fh, const upb_fielddef *f) {
upb_handlerset *hs = (upb_handlerset*)c;
if (hs->value) upb_fhandlers_setvalue(fh, hs->value);
if (hs->startsubmsg) upb_fhandlers_setstartsubmsg(fh, hs->startsubmsg);
@ -295,7 +295,7 @@ INLINE void upb_onfreg_hset(void *c, upb_fhandlers *fh, upb_fielddef *f) {
upb_value_setfielddef(&val, f);
upb_fhandlers_setfval(fh, val);
}
INLINE upb_mhandlers *upb_handlers_reghandlerset(upb_handlers *h, upb_msgdef *m,
INLINE upb_mhandlers *upb_handlers_reghandlerset(upb_handlers *h, const upb_msgdef *m,
upb_handlerset *hs) {
return upb_handlers_regmsgdef(h, m, &upb_onmreg_hset, &upb_onfreg_hset, hs);
}

@ -10,7 +10,7 @@
#include "upb/upb.h"
#include "upb/msg.h"
void upb_msg_clear(void *msg, upb_msgdef *md) {
void upb_msg_clear(void *msg, const upb_msgdef *md) {
assert(msg != NULL);
memset(msg, 0, md->hasbit_bytes);
// TODO: set primitive fields to defaults?
@ -85,14 +85,14 @@ void upb_msg_runhandlers(upb_msg *msg, upb_msgdef *md, upb_handlers *h,
void upb_stdmsg_sethas(void *_m, upb_value fval) {
assert(_m != NULL);
char *m = _m;
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
if (f->hasbit >= 0) m[f->hasbit / 8] |= (1 << (f->hasbit % 8));
}
bool upb_stdmsg_has(void *_m, upb_value fval) {
assert(_m != NULL);
char *m = _m;
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
return f->hasbit < 0 || (m[f->hasbit / 8] & (1 << (f->hasbit % 8)));
}
@ -100,7 +100,7 @@ bool upb_stdmsg_has(void *_m, upb_value fval) {
upb_flow_t upb_stdmsg_set ## type (void *_m, upb_value fval, \
upb_value val) { \
assert(_m != NULL); \
upb_fielddef *f = upb_value_getfielddef(fval); \
const upb_fielddef *f = upb_value_getfielddef(fval); \
uint8_t *m = _m; \
/* Hasbit is set automatically by the handlers. */ \
*(ctype*)&m[f->offset] = upb_value_get ## type(val); \
@ -119,7 +119,7 @@ bool upb_stdmsg_has(void *_m, upb_value fval) {
upb_value upb_stdmsg_get ## type(void *_m, upb_value fval) { \
assert(_m != NULL); \
uint8_t *m = _m; \
upb_fielddef *f = upb_value_getfielddef(fval); \
const upb_fielddef *f = upb_value_getfielddef(fval); \
upb_value ret; \
upb_value_set ## type(&ret, *(ctype*)&m[f->offset]); \
return ret; \
@ -151,7 +151,7 @@ static void _upb_stdmsg_setstr(void *_dst, upb_value src) {
*dstp = dst;
}
dst->len = 0;
upb_strref *ref = upb_value_getstrref(src);
const upb_strref *ref = upb_value_getstrref(src);
if (ref->len > dst->size) {
dst->size = ref->len;
dst->ptr = realloc(dst->ptr, dst->size);
@ -163,7 +163,7 @@ static void _upb_stdmsg_setstr(void *_dst, upb_value src) {
upb_flow_t upb_stdmsg_setstr(void *_m, upb_value fval, upb_value val) {
assert(_m != NULL);
char *m = _m;
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
// Hasbit automatically set by the handlers.
_upb_stdmsg_setstr(&m[f->offset], val);
return UPB_CONTINUE;
@ -186,7 +186,7 @@ upb_value upb_stdmsg_seqgetstr(void *i) {
return upb_stdmsg_seqgetptr(i);
}
void *upb_stdmsg_new(upb_msgdef *md) {
void *upb_stdmsg_new(const upb_msgdef *md) {
void *m = malloc(md->size);
memset(m, 0, md->size);
upb_msg_clear(m, md);
@ -211,7 +211,7 @@ void upb_stdseq_free(void *s, upb_fielddef *f) {
free(a);
}
void upb_stdmsg_free(void *m, upb_msgdef *md) {
void upb_stdmsg_free(void *m, const upb_msgdef *md) {
if (m == NULL) return;
upb_msg_iter i;
for(i = upb_msg_begin(md); !upb_msg_done(i); i = upb_msg_next(md, i)) {
@ -234,7 +234,7 @@ void upb_stdmsg_free(void *m, upb_msgdef *md) {
upb_sflow_t upb_stdmsg_startseq(void *_m, upb_value fval) {
char *m = _m;
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
upb_stdarray **arr = (void*)&m[f->offset];
if (!upb_stdmsg_has(_m, fval)) {
if (!*arr) {
@ -248,7 +248,7 @@ upb_sflow_t upb_stdmsg_startseq(void *_m, upb_value fval) {
return UPB_CONTINUE_WITH(*arr);
}
void upb_stdmsg_recycle(void **m, upb_msgdef *md) {
void upb_stdmsg_recycle(void **m, const upb_msgdef *md) {
if (*m)
upb_msg_clear(*m, md);
else
@ -258,7 +258,7 @@ void upb_stdmsg_recycle(void **m, upb_msgdef *md) {
upb_sflow_t upb_stdmsg_startsubmsg(void *_m, upb_value fval) {
assert(_m != NULL);
char *m = _m;
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
void **subm = (void*)&m[f->offset];
if (!upb_stdmsg_has(m, fval)) {
upb_stdmsg_recycle(subm, upb_downcast_msgdef(f->def));
@ -269,7 +269,7 @@ upb_sflow_t upb_stdmsg_startsubmsg(void *_m, upb_value fval) {
upb_sflow_t upb_stdmsg_startsubmsg_r(void *a, upb_value fval) {
assert(a != NULL);
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
void **subm = upb_stdarray_append((upb_stdarray*)a, sizeof(void*));
upb_stdmsg_recycle(subm, upb_downcast_msgdef(f->def));
return UPB_CONTINUE_WITH(*subm);
@ -329,7 +329,8 @@ upb_accessor_vtbl *upb_stdmsg_accessor(upb_fielddef *f) {
return NULL;
}
static void upb_accessors_onfreg(void *c, upb_fhandlers *fh, upb_fielddef *f) {
static void upb_accessors_onfreg(void *c, upb_fhandlers *fh,
const upb_fielddef *f) {
(void)c;
if (f->accessor) {
upb_fhandlers_setfval(fh, f->fval);
@ -345,6 +346,6 @@ static void upb_accessors_onfreg(void *c, upb_fhandlers *fh, upb_fielddef *f) {
}
}
upb_mhandlers *upb_accessors_reghandlers(upb_handlers *h, upb_msgdef *m) {
upb_mhandlers *upb_accessors_reghandlers(upb_handlers *h, const upb_msgdef *m) {
return upb_handlers_regmsgdef(h, m, NULL, &upb_accessors_onfreg, NULL);
}

@ -69,7 +69,7 @@ typedef struct _upb_accessor_vtbl {
} upb_accessor_vtbl;
// Registers handlers for writing into a message of the given type.
upb_mhandlers *upb_accessors_reghandlers(upb_handlers *h, upb_msgdef *m);
upb_mhandlers *upb_accessors_reghandlers(upb_handlers *h, const upb_msgdef *m);
// Returns an stdmsg accessor for the given fielddef.
upb_accessor_vtbl *upb_stdmsg_accessor(upb_fielddef *f);
@ -85,9 +85,9 @@ upb_accessor_vtbl *upb_stdmsg_accessor(upb_fielddef *f);
// Clears all hasbits.
// TODO: Add a separate function for setting primitive values back to their
// defaults (but not strings, submessages, or arrays).
void upb_msg_clear(void *msg, upb_msgdef *md);
void upb_msg_clear(void *msg, const upb_msgdef *md);
INLINE void upb_msg_clearbit(void *msg, upb_fielddef *f) {
INLINE void upb_msg_clearbit(void *msg, const upb_fielddef *f) {
((char*)msg)[f->hasbit / 8] &= ~(1 << (f->hasbit % 8));
}
@ -97,37 +97,37 @@ INLINE void upb_msg_clearbit(void *msg, upb_fielddef *f) {
// or arrays. Also this could be desired to provide proto2 operations on
// generated messages.
INLINE bool upb_msg_has(void *m, upb_fielddef *f) {
INLINE bool upb_msg_has(void *m, const upb_fielddef *f) {
return f->accessor && f->accessor->has(m, f->fval);
}
// May only be called for fields that have accessors.
INLINE upb_value upb_msg_get(void *m, upb_fielddef *f) {
INLINE upb_value upb_msg_get(void *m, const upb_fielddef *f) {
assert(f->accessor && !upb_isseq(f));
return f->accessor->get(m, f->fval);
}
// May only be called for fields that have accessors.
INLINE upb_value upb_msg_getseq(void *m, upb_fielddef *f) {
INLINE upb_value upb_msg_getseq(void *m, const upb_fielddef *f) {
assert(f->accessor && upb_isseq(f));
return f->accessor->getseq(m, f->fval);
}
INLINE void upb_msg_set(void *m, upb_fielddef *f, upb_value val) {
INLINE void upb_msg_set(void *m, const upb_fielddef *f, upb_value val) {
assert(f->accessor);
f->accessor->set(m, f->fval, val);
}
INLINE void *upb_seq_begin(void *s, upb_fielddef *f) {
INLINE void *upb_seq_begin(void *s, const upb_fielddef *f) {
assert(f->accessor);
return f->accessor->seqbegin(s);
}
INLINE void *upb_seq_next(void *s, void *iter, upb_fielddef *f) {
INLINE void *upb_seq_next(void *s, void *iter, const upb_fielddef *f) {
assert(f->accessor);
assert(!upb_seq_done(iter));
return f->accessor->seqnext(s, iter);
}
INLINE upb_value upb_seq_get(void *iter, upb_fielddef *f) {
INLINE upb_value upb_seq_get(void *iter, const upb_fielddef *f) {
assert(f->accessor);
assert(!upb_seq_done(iter));
return f->accessor->seqget(iter);
@ -175,10 +175,10 @@ void upb_msgvisitor_visit(upb_msgvisitor *v, upb_status *status);
/* Standard writers. **********************************************************/
// Allocates a new stdmsg.
void *upb_stdmsg_new(upb_msgdef *md);
void *upb_stdmsg_new(const upb_msgdef *md);
// Recursively frees any strings or submessages that the message refers to.
void upb_stdmsg_free(void *m, upb_msgdef *md);
void upb_stdmsg_free(void *m, const upb_msgdef *md);
void upb_stdmsg_sethas(void *_m, upb_value fval);

@ -413,7 +413,7 @@ static void upb_decoder_jit_doappend(upb_decoder *d, uint8_t size,
#endif
static void upb_decoder_jit_callcb(upb_decoder *d, upb_fhandlers *f) {
upb_fielddef *fd = upb_value_getfielddef(f->fval);
const upb_fielddef *fd = upb_value_getfielddef(f->fval);
// Call callbacks.
if (upb_issubmsgtype(f->type)) {
// Load closure and fval into arg registers.
@ -439,7 +439,7 @@ static void upb_decoder_jit_callcb(upb_decoder *d, upb_fhandlers *f) {
}
| pushframe f, rdx, esi, false
upb_mhandlers *sub_m = upb_fhandlers_getsubmsg(f);
const upb_mhandlers *sub_m = upb_fhandlers_getsubmsg(f);
if (sub_m->jit_parent_field_done_pclabel != UPB_MULTIPLE) {
| jmp =>sub_m->jit_startmsg_pclabel;
} else {

@ -12,7 +12,7 @@
#include "upb/pb/glue.h"
#include "upb/pb/textprinter.h"
void upb_strtomsg(const char *str, size_t len, void *msg, upb_msgdef *md,
void upb_strtomsg(const char *str, size_t len, void *msg, const upb_msgdef *md,
upb_status *status) {
upb_stringsrc strsrc;
upb_stringsrc_init(&strsrc);
@ -56,7 +56,7 @@ void upb_msgtotext(upb_string *str, upb_msg *msg, upb_msgdef *md,
#endif
// TODO: read->load.
upb_def **upb_load_descriptor(const char *str, size_t len, int *n,
upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
upb_status *status) {
upb_stringsrc strsrc;
upb_stringsrc_init(&strsrc);
@ -98,13 +98,15 @@ upb_def **upb_load_descriptor(const char *str, size_t len, int *n,
return defscopy;
}
void upb_read_descriptor(upb_symtab *s, const char *str, size_t len,
bool upb_load_descriptor_into_symtab(upb_symtab *s, const char *str, size_t len,
upb_status *status) {
int n;
upb_def **defs = upb_load_descriptor(str, len, &n, status);
if (upb_ok(status)) upb_symtab_add(s, defs, n, status);
upb_def **defs = upb_load_defs_from_descriptor(str, len, &n, status);
if (!defs) return false;
bool success = upb_symtab_add(s, defs, n, status);
for(int i = 0; i < n; i++) upb_def_unref(defs[i]);
free(defs);
return success;
}
char *upb_readfile(const char *filename, size_t *len) {
@ -125,14 +127,15 @@ error:
return NULL;
}
void upb_read_descriptorfile(upb_symtab *symtab, const char *fname,
bool upb_load_descriptor_file_into_symtab(upb_symtab *symtab, const char *fname,
upb_status *status) {
size_t len;
char *data = upb_readfile(fname, &len);
if (!data) {
upb_status_seterrf(status, "Couldn't read file: %s", fname);
return;
if (status) upb_status_seterrf(status, "Couldn't read file: %s", fname);
return false;
}
upb_read_descriptor(symtab, data, len, status);
bool success = upb_load_descriptor_into_symtab(symtab, data, len, status);
free(data);
return success;
}

@ -42,20 +42,29 @@ struct _upb_symtab;
// Decodes the given string, which must be in protobuf binary format, to the
// given upb_msg with msgdef "md", storing the status of the operation in "s".
void upb_strtomsg(const char *str, size_t len, void *msg,
struct _upb_msgdef *md, upb_status *s);
const struct _upb_msgdef *md, upb_status *s);
//void upb_msgtotext(struct _upb_string *str, void *msg,
// struct _upb_msgdef *md, bool single_line);
upb_def **upb_load_descriptor(const char *str, size_t len, int *n,
upb_status *status);
void upb_read_descriptor(struct _upb_symtab *symtab, const char *str, size_t len,
// Loads all defs from the given protobuf binary descriptor, setting default
// accessors and a default layout on all messages. The caller owns the
// returned array of defs, which will be of length *n. On error NULL is
// returned and status is set (if non-NULL).
upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
upb_status *status);
void upb_read_descriptorfile(struct _upb_symtab *symtab, const char *fname,
upb_status *status);
// Like the previous but also adds the loaded defs to the given symtab.
bool upb_load_descriptor_into_symtab(struct _upb_symtab *symtab, const char *str,
size_t len, upb_status *status);
// Like the previous but also reads the descriptor from the given filename.
bool upb_load_descriptor_file_into_symtab(struct _upb_symtab *symtab,
const char *fname, upb_status *status);
// Reads the given filename into a character string, returning NULL if there
// was an error.
char *upb_readfile(const char *filename, size_t *len);
#ifdef __cplusplus

@ -35,7 +35,7 @@ err:
return -1;
}
static int upb_textprinter_putescaped(upb_textprinter *p, upb_strref *strref,
static int upb_textprinter_putescaped(upb_textprinter *p, const upb_strref *strref,
bool preserve_utf8) {
// Based on CEscapeInternal() from Google's protobuf release.
// TODO; we could read directly from a bytesrc's buffer instead.
@ -90,7 +90,7 @@ err:
static upb_flow_t upb_textprinter_put ## member(void *_p, upb_value fval, \
upb_value val) { \
upb_textprinter *p = _p; \
upb_fielddef *f = upb_value_getfielddef(fval); \
const upb_fielddef *f = upb_value_getfielddef(fval); \
uint64_t start_ofs = upb_bytesink_getoffset(p->sink); \
CHECK(upb_textprinter_indent(p)); \
CHECK(upb_bytesink_writestr(p->sink, f->name)); \
@ -120,7 +120,7 @@ static upb_flow_t upb_textprinter_putenum(void *_p, upb_value fval,
upb_textprinter *p = _p;
uint64_t start_ofs = upb_bytesink_getoffset(p->sink);
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
upb_enumdef *enum_def = upb_downcast_enumdef(f->def);
const char *label = upb_enumdef_iton(enum_def, upb_value_getint32(val));
if (label) {
@ -138,7 +138,7 @@ static upb_flow_t upb_textprinter_putstr(void *_p, upb_value fval,
upb_value val) {
upb_textprinter *p = _p;
uint64_t start_ofs = upb_bytesink_getoffset(p->sink);
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
CHECK(upb_bytesink_putc(p->sink, '"'));
CHECK(upb_textprinter_putescaped(p, upb_value_getstrref(val),
f->type == UPB_TYPE(STRING)));
@ -152,7 +152,7 @@ err:
static upb_sflow_t upb_textprinter_startsubmsg(void *_p, upb_value fval) {
upb_textprinter *p = _p;
uint64_t start_ofs = upb_bytesink_getoffset(p->sink);
upb_fielddef *f = upb_value_getfielddef(fval);
const upb_fielddef *f = upb_value_getfielddef(fval);
CHECK(upb_textprinter_indent(p));
CHECK(upb_bytesink_printf(p->sink, "%s {", f->name));
if (!p->single_line)
@ -192,7 +192,7 @@ void upb_textprinter_reset(upb_textprinter *p, upb_bytesink *sink,
p->indent_depth = 0;
}
static void upb_textprinter_onfreg(void *c, upb_fhandlers *fh, upb_fielddef *f) {
static void upb_textprinter_onfreg(void *c, upb_fhandlers *fh, const upb_fielddef *f) {
(void)c;
upb_fhandlers_setstartsubmsg(fh, &upb_textprinter_startsubmsg);
upb_fhandlers_setendsubmsg(fh, &upb_textprinter_endsubmsg);
@ -207,7 +207,7 @@ static void upb_textprinter_onfreg(void *c, upb_fhandlers *fh, upb_fielddef *f)
upb_fhandlers_setfval(fh, fval);
}
upb_mhandlers *upb_textprinter_reghandlers(upb_handlers *h, upb_msgdef *m) {
upb_mhandlers *upb_textprinter_reghandlers(upb_handlers *h, const upb_msgdef *m) {
return upb_handlers_regmsgdef(
h, m, NULL, &upb_textprinter_onfreg, NULL);
}

@ -22,7 +22,7 @@ upb_textprinter *upb_textprinter_new();
void upb_textprinter_free(upb_textprinter *p);
void upb_textprinter_reset(upb_textprinter *p, upb_bytesink *sink,
bool single_line);
upb_mhandlers *upb_textprinter_reghandlers(upb_handlers *h, upb_msgdef *m);
upb_mhandlers *upb_textprinter_reghandlers(upb_handlers *h, const upb_msgdef *m);
#ifdef __cplusplus
} /* extern "C" */

@ -25,9 +25,9 @@ static uint32_t MurmurHash2(const void *key, size_t len, uint32_t seed);
/* Base table (shared code) ***************************************************/
static uint32_t upb_table_size(upb_table *t) { return 1 << t->size_lg2; }
static size_t upb_table_entrysize(upb_table *t) { return t->entry_size; }
static size_t upb_table_valuesize(upb_table *t) { return t->value_size; }
static uint32_t upb_table_size(const upb_table *t) { return 1 << t->size_lg2; }
static size_t upb_table_entrysize(const upb_table *t) { return t->entry_size; }
static size_t upb_table_valuesize(const upb_table *t) { return t->value_size; }
void upb_table_init(upb_table *t, uint32_t size, uint16_t entry_size) {
t->count = 0;
@ -43,12 +43,12 @@ void upb_table_free(upb_table *t) { free(t->entries); }
/* upb_inttable ***************************************************************/
static upb_inttable_entry *intent(upb_inttable *t, int32_t i) {
static upb_inttable_entry *intent(const upb_inttable *t, int32_t i) {
//printf("looking up int entry %d, size of entry: %d\n", i, t->t.entry_size);
return UPB_INDEX(t->t.entries, i, t->t.entry_size);
}
static uint32_t upb_inttable_hashtablesize(upb_inttable *t) {
static uint32_t upb_inttable_hashtablesize(const upb_inttable *t) {
return upb_table_size(&t->t);
}
@ -219,12 +219,13 @@ void upb_inttable_compact(upb_inttable *t) {
*t = new_table;
}
upb_inttable_iter upb_inttable_begin(upb_inttable *t) {
upb_inttable_iter upb_inttable_begin(const upb_inttable *t) {
upb_inttable_iter iter = {-1, NULL, true}; // -1 will overflow to 0 on the first iteration.
return upb_inttable_next(t, iter);
}
upb_inttable_iter upb_inttable_next(upb_inttable *t, upb_inttable_iter iter) {
upb_inttable_iter upb_inttable_next(const upb_inttable *t,
upb_inttable_iter iter) {
const size_t hdrsize = sizeof(upb_inttable_header);
const size_t entsize = upb_table_entrysize(&t->t);
if (iter.array_part) {
@ -259,13 +260,13 @@ upb_inttable_iter upb_inttable_next(upb_inttable *t, upb_inttable_iter iter) {
/* upb_strtable ***************************************************************/
static upb_strtable_entry *strent(upb_strtable *t, int32_t i) {
static upb_strtable_entry *strent(const upb_strtable *t, int32_t i) {
//fprintf(stderr, "i: %d, table_size: %d\n", i, upb_table_size(&t->t));
assert(i <= (int32_t)upb_table_size(&t->t));
return UPB_INDEX(t->t.entries, i, t->t.entry_size);
}
static uint32_t upb_strtable_size(upb_strtable *t) {
static uint32_t upb_strtable_size(const upb_strtable *t) {
return upb_table_size(&t->t);
}
@ -288,12 +289,12 @@ void upb_strtable_free(upb_strtable *t) {
upb_table_free(&t->t);
}
static uint32_t strtable_bucket(upb_strtable *t, const char *key) {
static uint32_t strtable_bucket(const upb_strtable *t, const char *key) {
uint32_t hash = MurmurHash2(key, strlen(key), 0);
return (hash & t->t.mask);
}
void *upb_strtable_lookup(upb_strtable *t, const char *key) {
void *upb_strtable_lookup(const upb_strtable *t, const char *key) {
uint32_t bucket = strtable_bucket(t, key);
upb_strtable_entry *e;
do {
@ -303,7 +304,7 @@ void *upb_strtable_lookup(upb_strtable *t, const char *key) {
return NULL;
}
void *upb_strtable_lookupl(upb_strtable *t, const char *key, size_t len) {
void *upb_strtable_lookupl(const upb_strtable *t, const char *key, size_t len) {
// TODO: improve.
char key2[len+1];
memcpy(key2, key, len);
@ -383,7 +384,7 @@ void upb_strtable_insert(upb_strtable *t, const char *key, const void *val) {
strinsert(t, key, val);
}
void upb_strtable_begin(upb_strtable_iter *i, upb_strtable *t) {
void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) {
i->e = strent(t, -1);
i->t = t;
upb_strtable_next(i);

@ -90,11 +90,11 @@ void upb_strtable_init(upb_strtable *table, uint32_t size, uint16_t value_size);
void upb_strtable_free(upb_strtable *table);
// Number of values in the hash table.
INLINE uint32_t upb_table_count(upb_table *t) { return t->count; }
INLINE uint32_t upb_inttable_count(upb_inttable *t) {
INLINE uint32_t upb_table_count(const upb_table *t) { return t->count; }
INLINE uint32_t upb_inttable_count(const upb_inttable *t) {
return t->array_count + upb_table_count(&t->t);
}
INLINE uint32_t upb_strtable_count(upb_strtable *t) {
INLINE uint32_t upb_strtable_count(const upb_strtable *t) {
return upb_table_count(&t->t);
}
@ -111,14 +111,14 @@ void upb_inttable_insert(upb_inttable *t, uint32_t key, const void *val);
void upb_strtable_insert(upb_strtable *t, const char *key, const void *val);
void upb_inttable_compact(upb_inttable *t);
INLINE uint32_t _upb_inttable_bucket(upb_inttable *t, uint32_t k) {
INLINE uint32_t _upb_inttable_bucket(const upb_inttable *t, uint32_t k) {
uint32_t bucket = k & t->t.mask; // Identity hash for ints.
assert(bucket != UPB_END_OF_CHAIN);
return bucket;
}
// Returns true if this key belongs in the array part of the table.
INLINE bool _upb_inttable_isarrkey(upb_inttable *t, uint32_t k) {
INLINE bool _upb_inttable_isarrkey(const upb_inttable *t, uint32_t k) {
return (k < t->array_size);
}
@ -126,7 +126,7 @@ INLINE bool _upb_inttable_isarrkey(upb_inttable *t, uint32_t k) {
// We have the caller specify the entry_size because fixing this as a literal
// (instead of reading table->entry_size) gives the compiler more ability to
// optimize.
INLINE void *_upb_inttable_fastlookup(upb_inttable *t, uint32_t key,
INLINE void *_upb_inttable_fastlookup(const upb_inttable *t, uint32_t key,
size_t entry_size, size_t value_size) {
upb_inttable_value *arrval =
(upb_inttable_value*)UPB_INDEX(t->array, key, value_size);
@ -158,8 +158,8 @@ INLINE void *upb_inttable_lookup(upb_inttable *t, uint32_t key) {
return _upb_inttable_fastlookup(t, key, t->t.entry_size, t->t.value_size);
}
void *upb_strtable_lookupl(upb_strtable *t, const char *key, size_t len);
void *upb_strtable_lookup(upb_strtable *t, const char *key);
void *upb_strtable_lookupl(const upb_strtable *t, const char *key, size_t len);
void *upb_strtable_lookup(const upb_strtable *t, const char *key);
/* upb_strtable_iter **********************************************************/
@ -172,11 +172,11 @@ void *upb_strtable_lookup(upb_strtable *t, const char *key);
// // ...
// }
typedef struct {
upb_strtable *t;
const upb_strtable *t;
upb_strtable_entry *e;
} upb_strtable_iter;
void upb_strtable_begin(upb_strtable_iter *i, upb_strtable *t);
void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t);
void upb_strtable_next(upb_strtable_iter *i);
INLINE bool upb_strtable_done(upb_strtable_iter *i) { return i->e == NULL; }
INLINE const char *upb_strtable_iter_key(upb_strtable_iter *i) {
@ -200,8 +200,8 @@ typedef struct {
bool array_part;
} upb_inttable_iter;
upb_inttable_iter upb_inttable_begin(upb_inttable *t);
upb_inttable_iter upb_inttable_next(upb_inttable *t, upb_inttable_iter iter);
upb_inttable_iter upb_inttable_begin(const upb_inttable *t);
upb_inttable_iter upb_inttable_next(const upb_inttable *t, upb_inttable_iter iter);
INLINE bool upb_inttable_done(upb_inttable_iter iter) { return iter.value == NULL; }
INLINE uint32_t upb_inttable_iter_key(upb_inttable_iter iter) {
return iter.key;

@ -87,7 +87,10 @@ void upb_status_copy(upb_status *to, upb_status *from) {
}
}
const char *upb_status_getstr(upb_status *status) {
const char *upb_status_getstr(const upb_status *_status) {
// Function is logically const but can modify internal state to materialize
// the string.
upb_status *status = (upb_status*)_status;
if (status->str == NULL && status->space && status->space->code_to_string) {
status->space->code_to_string(status->code, status->buf, status->bufsize);
status->str = status->buf;

@ -144,8 +144,8 @@ typedef struct {
int64_t int64;
uint32_t uint32;
bool _bool;
struct _upb_strref *strref;
struct _upb_fielddef *fielddef;
const struct _upb_strref *strref;
const struct _upb_fielddef *fielddef;
void *_void;
} val;
@ -178,10 +178,13 @@ UPB_VALUE_ACCESSORS(int64, int64, int64_t, UPB_TYPE(INT64));
UPB_VALUE_ACCESSORS(uint32, uint32, uint32_t, UPB_TYPE(UINT32));
UPB_VALUE_ACCESSORS(uint64, uint64, uint64_t, UPB_TYPE(UINT64));
UPB_VALUE_ACCESSORS(bool, _bool, bool, UPB_TYPE(BOOL));
UPB_VALUE_ACCESSORS(strref, strref, struct _upb_strref*, UPB_TYPE(STRING));
UPB_VALUE_ACCESSORS(fielddef, fielddef, struct _upb_fielddef*, UPB_VALUETYPE_FIELDDEF);
UPB_VALUE_ACCESSORS(ptr, _void, void*, UPB_VALUETYPE_PTR);
// upb_fielddef and upb_strref should never be modified from a callback
// (ie. when they're getting passed through a upb_value).
UPB_VALUE_ACCESSORS(strref, strref, const struct _upb_strref*, UPB_TYPE(STRING));
UPB_VALUE_ACCESSORS(fielddef, fielddef, const struct _upb_fielddef*, UPB_VALUETYPE_FIELDDEF);
extern upb_value UPB_NO_VALUE;
@ -223,7 +226,7 @@ void upb_status_seterrliteral(upb_status *status, const char *msg);
void upb_status_seterrf(upb_status *s, const char *msg, ...);
void upb_status_setcode(upb_status *s, upb_errorspace *space, int code);
// The returned string is invalidated by any other call into the status.
const char *upb_status_getstr(upb_status *s);
const char *upb_status_getstr(const upb_status *s);
void upb_status_copy(upb_status *to, upb_status *from);
extern upb_errorspace upb_posix_errorspace;

Loading…
Cancel
Save