pull/13171/head
Joshua Haberman 6 years ago
parent 0a07f2714b
commit 1461da5056
  1. 19
      upb/bindings/lua/msg.c
  2. 1
      upb/bindings/lua/upb.h
  3. 178
      upb/legacy_msg_reflection.c
  4. 21
      upb/legacy_msg_reflection.h
  5. 5
      upb/msg.c
  6. 16
      upb/msg.h
  7. 5
      upb/msgfactory.h

@ -276,7 +276,6 @@ static const struct luaL_Reg lupb_msgfactory_mm[] = {
struct lupb_msgclass {
const upb_msglayout *layout;
const upb_msgdef *msgdef;
const lupb_msgfactory *lfactory;
};
/* Type-checks for assigning to a message field. */
@ -301,10 +300,6 @@ const upb_msgdef *lupb_msgclass_getmsgdef(const lupb_msgclass *lmsgclass) {
return lmsgclass->msgdef;
}
upb_msgfactory *lupb_msgclass_getfactory(const lupb_msgclass *lmsgclass) {
return lmsgclass->lfactory->factory;
}
/**
* lupb_msgclass_typecheck()
*
@ -355,7 +350,6 @@ static int lupb_msgclass_pushnew(lua_State *L, int factory,
lupb_uservalseti(L, -1, LUPB_MSGCLASS_FACTORY, factory);
lmc->layout = upb_msgfactory_getlayout(lfactory->factory, md);
lmc->lfactory = lfactory;
lmc->msgdef = md;
return 1;
@ -493,13 +487,13 @@ static upb_msgval lupb_array_typecheck(lua_State *L, int narg, int msg,
const upb_fielddef *f) {
lupb_array *larray = lupb_array_check(L, narg);
if (upb_array_type(larray->arr) != upb_fielddef_type(f) ||
if (larray->type != upb_fielddef_type(f) ||
lupb_msg_getsubmsgclass(L, msg, f) != larray->lmsgclass) {
luaL_error(L, "Array had incorrect type (expected: %d, got: %d)",
(int)upb_fielddef_type(f), (int)upb_array_type(larray->arr));
(int)upb_fielddef_type(f), (int)larray->type);
}
if (upb_array_type(larray->arr) == UPB_TYPE_MESSAGE) {
if (larray->type == UPB_TYPE_MESSAGE) {
lupb_msgclass_typecheck(L, lupb_msg_getsubmsgclass(L, msg, f),
larray->lmsgclass);
}
@ -550,7 +544,7 @@ static int lupb_array_new(lua_State *L) {
static int lupb_array_newindex(lua_State *L) {
lupb_array *larray = lupb_array_check(L, 1);
upb_fieldtype_t type = upb_array_type(larray->arr);
upb_fieldtype_t type = larray->type;
uint32_t n = lupb_array_checkindex(L, 2, upb_array_size(larray->arr) + 1);
upb_msgval msgval = lupb_tomsgval(L, type, 3, larray->lmsgclass);
@ -567,13 +561,12 @@ static int lupb_array_index(lua_State *L) {
lupb_array *larray = lupb_array_check(L, 1);
upb_array *array = larray->arr;
uint32_t n = lupb_array_checkindex(L, 2, upb_array_size(array));
upb_fieldtype_t type = upb_array_type(array);
upb_fieldtype_t type = larray->type;
if (lupb_istypewrapped(type)) {
lupb_uservalgeti(L, 1, n);
} else {
lupb_pushmsgval(L, upb_array_type(array),
upb_array_get(array, larray->type, n));
lupb_pushmsgval(L, type, upb_array_get(array, type, n));
}
return 1;

@ -121,7 +121,6 @@ upb_msg *lupb_msg_checkmsg2(lua_State *L, int narg,
const lupb_msgclass *lupb_msgclass_check(lua_State *L, int narg);
const upb_msglayout *lupb_msgclass_getlayout(lua_State *L, int narg);
const upb_msgdef *lupb_msgclass_getmsgdef(const lupb_msgclass *lmsgclass);
upb_msgfactory *lupb_msgclass_getfactory(const lupb_msgclass *lmsgclass);
void lupb_msg_registertypes(lua_State *L);
#endif /* UPB_LUA_UPB_H_ */

@ -37,33 +37,56 @@ static void upb_msgval_write(void *p, size_t ofs, upb_msgval val,
memcpy(p, &val, size);
}
static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
switch (type) {
case UPB_TYPE_DOUBLE:
case UPB_TYPE_INT64:
case UPB_TYPE_UINT64:
return 8;
case UPB_TYPE_ENUM:
case UPB_TYPE_INT32:
case UPB_TYPE_UINT32:
case UPB_TYPE_FLOAT:
return 4;
case UPB_TYPE_BOOL:
return 1;
case UPB_TYPE_MESSAGE:
return sizeof(void*);
case UPB_TYPE_BYTES:
case UPB_TYPE_STRING:
return sizeof(upb_strview);
}
UPB_UNREACHABLE();
static size_t upb_msgval_sizeof(upb_descriptortype_t type) {
static uint8_t sizes[] = {
0, /* none */
8, /* UPB_DESCRIPTOR_TYPE_DOUBLE = 1 */
4, /* UPB_DESCRIPTOR_TYPE_FLOAT = 2 */
8, /* UPB_DESCRIPTOR_TYPE_INT64 = 3 */
8, /* UPB_DESCRIPTOR_TYPE_UINT64 = 4 */
4, /* UPB_DESCRIPTOR_TYPE_INT32 = 5 */
8, /* UPB_DESCRIPTOR_TYPE_FIXED64 = 6 */
4, /* UPB_DESCRIPTOR_TYPE_FIXED32 = 7 */
1, /* UPB_DESCRIPTOR_TYPE_BOOL = 8 */
sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING = 9 */
sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP = 11 */
sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE = 12 */
sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES = 13 */
4, /* UPB_DESCRIPTOR_TYPE_UINT32 = 14 */
4, /* UPB_DESCRIPTOR_TYPE_ENUM = 15 */
4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 = 16 */
8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 = 17 */
4, /* UPB_DESCRIPTOR_TYPE_SINT32 = 18 */
8, /* UPB_DESCRIPTOR_TYPE_SINT64 = 19 */
};
UPB_ASSERT(type < sizeof(sizes));
return sizes[type];
}
static size_t upb_msgval_sizeof2(upb_fieldtype_t type) {
static uint8_t sizes[] = {
0, /* none */
1, /* UPB_TYPE_BOOL = 1, */
4, /* UPB_TYPE_FLOAT = 2, */
4, /* UPB_TYPE_INT32 = 3, */
4, /* UPB_TYPE_UINT32 = 4, */
4, /* UPB_TYPE_ENUM = 5, */
sizeof(upb_strview), /* UPB_TYPE_STRING = 6, */
sizeof(upb_strview), /* UPB_TYPE_BYTES = 7, */
sizeof(void*), /* UPB_TYPE_MESSAGE = 8, */
8, /* UPB_TYPE_DOUBLE = 9, */
8, /* UPB_TYPE_INT64 = 10, */
8, /* UPB_TYPE_UINT64 = 11 */
};
UPB_ASSERT(type < sizeof(sizes));
return sizes[type];
}
static uint8_t upb_msg_fieldsize(const upb_msglayout_field *field) {
if (field->label == UPB_LABEL_REPEATED) {
return sizeof(void*);
} else {
return upb_msgval_sizeof(upb_desctype_to_fieldtype[field->descriptortype]);
return upb_msgval_sizeof(field->descriptortype);
}
}
@ -150,14 +173,14 @@ size_t upb_array_size(const upb_array *arr) {
}
upb_msgval upb_array_get(const upb_array *arr, upb_fieldtype_t type, size_t i) {
size_t element_size = upb_msgval_sizeof(type);
size_t element_size = upb_msgval_sizeof2(type);
UPB_ASSERT(i < arr->len);
return upb_msgval_read(arr->data, i * element_size, element_size);
}
bool upb_array_set(upb_array *arr, upb_fieldtype_t type, size_t i,
upb_msgval val, upb_arena *arena) {
size_t element_size = upb_msgval_sizeof(type);
size_t element_size = upb_msgval_sizeof2(type);
UPB_ASSERT(i <= arr->len);
if (i == arr->len) {
@ -189,64 +212,77 @@ bool upb_array_set(upb_array *arr, upb_fieldtype_t type, size_t i,
/** upb_map *******************************************************************/
static void upb_map_tokey(upb_fieldtype_t type, upb_msgval *key,
static void upb_map_tokey(upb_descriptortype_t type, upb_msgval *key,
const char **out_key, size_t *out_len) {
switch (type) {
case UPB_TYPE_STRING:
case UPB_DESCRIPTOR_TYPE_BYTES:
case UPB_DESCRIPTOR_TYPE_STRING:
/* Point to string data of the input key. */
*out_key = key->str.data;
*out_len = key->str.size;
return;
case UPB_TYPE_BOOL:
case UPB_TYPE_INT32:
case UPB_TYPE_UINT32:
case UPB_TYPE_INT64:
case UPB_TYPE_UINT64:
case UPB_DESCRIPTOR_TYPE_BOOL:
case UPB_DESCRIPTOR_TYPE_INT32:
case UPB_DESCRIPTOR_TYPE_SINT32:
case UPB_DESCRIPTOR_TYPE_SFIXED32:
case UPB_DESCRIPTOR_TYPE_FIXED32:
case UPB_DESCRIPTOR_TYPE_UINT32:
case UPB_DESCRIPTOR_TYPE_INT64:
case UPB_DESCRIPTOR_TYPE_SINT64:
case UPB_DESCRIPTOR_TYPE_SFIXED64:
case UPB_DESCRIPTOR_TYPE_FIXED64:
case UPB_DESCRIPTOR_TYPE_UINT64:
/* Point to the key itself. XXX: big-endian. */
*out_key = (const char*)key;
*out_len = upb_msgval_sizeof(type);
return;
case UPB_TYPE_BYTES:
case UPB_TYPE_DOUBLE:
case UPB_TYPE_ENUM:
case UPB_TYPE_FLOAT:
case UPB_TYPE_MESSAGE:
break; /* Cannot be a map key. */
case UPB_DESCRIPTOR_TYPE_DOUBLE:
case UPB_DESCRIPTOR_TYPE_ENUM:
case UPB_DESCRIPTOR_TYPE_FLOAT:
case UPB_DESCRIPTOR_TYPE_MESSAGE:
case UPB_DESCRIPTOR_TYPE_GROUP:
UPB_UNREACHABLE(); /* Cannot be a map key. */
}
UPB_UNREACHABLE();
}
static upb_msgval upb_map_fromkey(upb_fieldtype_t type, const char *key,
static upb_msgval upb_map_fromkey(upb_descriptortype_t type, const char *key,
size_t len) {
switch (type) {
case UPB_TYPE_STRING:
case UPB_DESCRIPTOR_TYPE_BYTES:
case UPB_DESCRIPTOR_TYPE_STRING:
return upb_msgval_makestr(key, len);
case UPB_TYPE_BOOL:
case UPB_TYPE_INT32:
case UPB_TYPE_UINT32:
case UPB_TYPE_INT64:
case UPB_TYPE_UINT64:
case UPB_DESCRIPTOR_TYPE_BOOL:
case UPB_DESCRIPTOR_TYPE_INT32:
case UPB_DESCRIPTOR_TYPE_SINT32:
case UPB_DESCRIPTOR_TYPE_SFIXED32:
case UPB_DESCRIPTOR_TYPE_FIXED32:
case UPB_DESCRIPTOR_TYPE_UINT32:
case UPB_DESCRIPTOR_TYPE_INT64:
case UPB_DESCRIPTOR_TYPE_SINT64:
case UPB_DESCRIPTOR_TYPE_SFIXED64:
case UPB_DESCRIPTOR_TYPE_FIXED64:
case UPB_DESCRIPTOR_TYPE_UINT64:
return upb_msgval_read(key, 0, upb_msgval_sizeof(type));
case UPB_TYPE_BYTES:
case UPB_TYPE_DOUBLE:
case UPB_TYPE_ENUM:
case UPB_TYPE_FLOAT:
case UPB_TYPE_MESSAGE:
break; /* Cannot be a map key. */
case UPB_DESCRIPTOR_TYPE_DOUBLE:
case UPB_DESCRIPTOR_TYPE_ENUM:
case UPB_DESCRIPTOR_TYPE_FLOAT:
case UPB_DESCRIPTOR_TYPE_MESSAGE:
case UPB_DESCRIPTOR_TYPE_GROUP:
UPB_UNREACHABLE(); /* Cannot be a map key. */
}
UPB_UNREACHABLE();
}
bool upb_map_get(const upb_map *map, upb_fieldtype_t key_type, upb_msgval key,
upb_msgval *val) {
const upb_strmap *map2 = (const upb_strmap*)map;
bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val,
const upb_msglayout *layout) {
upb_value tabval;
const char *key_str;
size_t key_len;
bool ret;
upb_map_tokey(key_type, &key, &key_str, &key_len);
ret = upb_strtable_lookup2(&map2->table, key_str, key_len, &tabval);
upb_map_tokey(layout->fields[0].descriptortype, &key, &key_str, &key_len);
ret = upb_strtable_lookup2(&map->table, key_str, key_len, &tabval);
if (ret) {
memcpy(val, &tabval, sizeof(tabval));
}
@ -254,56 +290,52 @@ bool upb_map_get(const upb_map *map, upb_fieldtype_t key_type, upb_msgval key,
return ret;
}
bool upb_map_set(upb_map *map, upb_fieldtype_t key_type, upb_msgval key,
upb_msgval val, upb_msgval *removed, upb_arena *arena) {
upb_strmap *map2 = (upb_strmap*)map;
bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
const upb_msglayout *layout, upb_arena *arena) {
const char *key_str;
size_t key_len;
upb_value tabval = upb_toval(val);
upb_value removedtabval;
upb_alloc *a = upb_arena_alloc(arena);
upb_map_tokey(key_type, &key, &key_str, &key_len);
upb_map_tokey(layout->fields[0].descriptortype, &key, &key_str, &key_len);
/* TODO(haberman): add overwrite operation to minimize number of lookups. */
if (upb_strtable_lookup2(&map2->table, key_str, key_len, NULL)) {
upb_strtable_remove3(&map2->table, key_str, key_len, &removedtabval, a);
memcpy(&removed, &removedtabval, sizeof(removed));
if (upb_strtable_lookup2(&map->table, key_str, key_len, NULL)) {
upb_strtable_remove3(&map->table, key_str, key_len, &removedtabval, a);
}
return upb_strtable_insert3(&map2->table, key_str, key_len, tabval, a);
return upb_strtable_insert3(&map->table, key_str, key_len, tabval, a);
}
bool upb_map_del(upb_map *map, upb_fieldtype_t key_type, upb_msgval key,
bool upb_map_del(upb_map *map, upb_msgval key, const upb_msglayout *layout,
upb_arena *arena) {
upb_strmap *map2 = (upb_strmap*)map;
const char *key_str;
size_t key_len;
upb_alloc *a = upb_arena_alloc(arena);
upb_map_tokey(key_type, &key, &key_str, &key_len);
return upb_strtable_remove3(&map2->table, key_str, key_len, NULL, a);
upb_map_tokey(layout->fields[0].descriptortype, &key, &key_str, &key_len);
return upb_strtable_remove3(&map->table, key_str, key_len, NULL, a);
}
/** upb_mapiter ***************************************************************/
struct upb_mapiter {
upb_strtable_iter iter;
upb_fieldtype_t key_type;
upb_descriptortype_t key_type;
};
size_t upb_mapiter_sizeof() {
return sizeof(upb_mapiter);
}
void upb_mapiter_begin(upb_mapiter *i, upb_fieldtype_t key_type,
void upb_mapiter_begin(upb_mapiter *i, const upb_msglayout *layout,
const upb_map *map) {
const upb_strmap *map2 = (const upb_strmap*)map;
upb_strtable_begin(&i->iter, &map2->table);
i->key_type = key_type;
upb_strtable_begin(&i->iter, &map->table);
i->key_type = layout->fields[0].descriptortype;
}
upb_mapiter *upb_mapiter_new(const upb_map *map, upb_fieldtype_t key_type,
upb_mapiter *upb_mapiter_new(const upb_map *map, const upb_msglayout *layout,
upb_alloc *a) {
upb_mapiter *ret = upb_malloc(a, upb_mapiter_sizeof());
@ -311,7 +343,7 @@ upb_mapiter *upb_mapiter_new(const upb_map *map, upb_fieldtype_t key_type,
return NULL;
}
upb_mapiter_begin(ret, key_type, map);
upb_mapiter_begin(ret, layout, map);
return ret;
}

@ -10,11 +10,6 @@
struct upb_mapiter;
typedef struct upb_mapiter upb_mapiter;
/* A distinct pointer type to represent all maps for reflection. */
typedef struct {
int x;
} upb_map;
/** upb_msgval ****************************************************************/
/* A union representing all possible protobuf values. Used for generic get/set
@ -123,8 +118,6 @@ bool upb_msg_clearfield(upb_msg *msg,
* semantics are the same as upb_msg. A upb_array allocates dynamic
* memory internally for the array elements. */
upb_fieldtype_t upb_array_type(const upb_array *arr);
/* Read-only interface. Safe for anyone to call. */
size_t upb_array_size(const upb_array *arr);
@ -147,8 +140,8 @@ bool upb_array_set(upb_array *arr, upb_fieldtype_t type, size_t i,
/* Read-only interface. Safe for anyone to call. */
size_t upb_map_size(const upb_map *map);
bool upb_map_get(const upb_map *map, upb_fieldtype_t key_type, upb_msgval key,
upb_msgval *val);
bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val,
const upb_msglayout *l);
/* Write interface. May only be called by the message's owner who can enforce
* its memory management invariants. */
@ -156,11 +149,11 @@ bool upb_map_get(const upb_map *map, upb_fieldtype_t key_type, upb_msgval key,
/* Sets or overwrites an entry in the map. Return value indicates whether
* the operation succeeded or failed with OOM, and also whether an existing
* key was replaced or not. */
bool upb_map_set(upb_map *map, upb_fieldtype_t key_type, upb_msgval key,
upb_msgval val, upb_msgval *valremoved, upb_arena *arena);
bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
const upb_msglayout *l, upb_arena *arena);
/* Deletes an entry in the map. Returns true if the key was present. */
bool upb_map_del(upb_map *map, upb_fieldtype_t key_type, upb_msgval key,
bool upb_map_del(upb_map *map, upb_msgval key, const upb_msglayout *l,
upb_arena *arena);
/** upb_mapiter ***************************************************************/
@ -173,9 +166,9 @@ bool upb_map_del(upb_map *map, upb_fieldtype_t key_type, upb_msgval key,
size_t upb_mapiter_sizeof();
void upb_mapiter_begin(upb_mapiter *i, upb_fieldtype_t key_type,
void upb_mapiter_begin(upb_mapiter *i, const upb_msglayout *layout,
const upb_map *t);
upb_mapiter *upb_mapiter_new(const upb_map *t, upb_fieldtype_t key_type,
upb_mapiter *upb_mapiter_new(const upb_map *t, const upb_msglayout *layout,
upb_alloc *a);
void upb_mapiter_free(upb_mapiter *i, upb_alloc *a);
void upb_mapiter_next(upb_mapiter *i);

@ -92,14 +92,13 @@ upb_array *upb_array_new(upb_arena *a) {
return arr;
}
upb_strmap *upb_strmap_new(upb_arena *a) {
upb_strmap *map = upb_arena_malloc(a, sizeof(upb_strmap));
upb_map *upb_map_new(upb_arena *a) {
upb_map *map = upb_arena_malloc(a, sizeof(upb_map));
if (!map) {
return NULL;
}
upb_array_init(&map->array);
upb_strtable_init(&map->table, UPB_CTYPE_INT32);
return map;

@ -55,20 +55,16 @@ typedef struct {
size_t size; /* Measured in elements. */
} upb_array;
/* Our internal representation for maps. They are arrays but also have a side
* index. These start with array so the parser can begin with a simple array
* path and do the table insert as a separate step.
*
* Right now we use strmaps for everything. We'll likely want to use
* integer-specific maps for integer-keyed maps.*/
/* Our internal representation for maps. Right now we use strmaps for
* everything. We'll likely want to use integer-specific maps for
* integer-keyed maps.*/
typedef struct {
upb_array array;
upb_strtable table; /* Values are indices into array. */
} upb_strmap;
upb_strtable table;
} upb_map;
upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a);
upb_array *upb_array_new(upb_arena *a);
upb_strmap *upb_map_new(upb_arena *a);
upb_map *upb_map_new(upb_arena *a);
void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
upb_arena *arena);

@ -41,6 +41,11 @@ const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f);
const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
const upb_msgdef *m);
const upb_msglayout *upb_msgfactory_getmaplayout(upb_msgfactory *f,
const upb_fieldtype_t keytype,
const upb_fieldtype_t valtype,
const upb_msgdef *valmsg);
#ifdef __cplusplus
} /* extern "C" */
#endif

Loading…
Cancel
Save