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 { struct lupb_msgclass {
const upb_msglayout *layout; const upb_msglayout *layout;
const upb_msgdef *msgdef; const upb_msgdef *msgdef;
const lupb_msgfactory *lfactory;
}; };
/* Type-checks for assigning to a message field. */ /* 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; return lmsgclass->msgdef;
} }
upb_msgfactory *lupb_msgclass_getfactory(const lupb_msgclass *lmsgclass) {
return lmsgclass->lfactory->factory;
}
/** /**
* lupb_msgclass_typecheck() * 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); lupb_uservalseti(L, -1, LUPB_MSGCLASS_FACTORY, factory);
lmc->layout = upb_msgfactory_getlayout(lfactory->factory, md); lmc->layout = upb_msgfactory_getlayout(lfactory->factory, md);
lmc->lfactory = lfactory;
lmc->msgdef = md; lmc->msgdef = md;
return 1; return 1;
@ -493,13 +487,13 @@ static upb_msgval lupb_array_typecheck(lua_State *L, int narg, int msg,
const upb_fielddef *f) { const upb_fielddef *f) {
lupb_array *larray = lupb_array_check(L, narg); 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) { lupb_msg_getsubmsgclass(L, msg, f) != larray->lmsgclass) {
luaL_error(L, "Array had incorrect type (expected: %d, got: %d)", 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), lupb_msgclass_typecheck(L, lupb_msg_getsubmsgclass(L, msg, f),
larray->lmsgclass); larray->lmsgclass);
} }
@ -550,7 +544,7 @@ static int lupb_array_new(lua_State *L) {
static int lupb_array_newindex(lua_State *L) { static int lupb_array_newindex(lua_State *L) {
lupb_array *larray = lupb_array_check(L, 1); 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); uint32_t n = lupb_array_checkindex(L, 2, upb_array_size(larray->arr) + 1);
upb_msgval msgval = lupb_tomsgval(L, type, 3, larray->lmsgclass); 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); lupb_array *larray = lupb_array_check(L, 1);
upb_array *array = larray->arr; upb_array *array = larray->arr;
uint32_t n = lupb_array_checkindex(L, 2, upb_array_size(array)); 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)) { if (lupb_istypewrapped(type)) {
lupb_uservalgeti(L, 1, n); lupb_uservalgeti(L, 1, n);
} else { } else {
lupb_pushmsgval(L, upb_array_type(array), lupb_pushmsgval(L, type, upb_array_get(array, type, n));
upb_array_get(array, larray->type, n));
} }
return 1; 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 lupb_msgclass *lupb_msgclass_check(lua_State *L, int narg);
const upb_msglayout *lupb_msgclass_getlayout(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); 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); void lupb_msg_registertypes(lua_State *L);
#endif /* UPB_LUA_UPB_H_ */ #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); memcpy(p, &val, size);
} }
static size_t upb_msgval_sizeof(upb_fieldtype_t type) { static size_t upb_msgval_sizeof(upb_descriptortype_t type) {
switch (type) { static uint8_t sizes[] = {
case UPB_TYPE_DOUBLE: 0, /* none */
case UPB_TYPE_INT64: 8, /* UPB_DESCRIPTOR_TYPE_DOUBLE = 1 */
case UPB_TYPE_UINT64: 4, /* UPB_DESCRIPTOR_TYPE_FLOAT = 2 */
return 8; 8, /* UPB_DESCRIPTOR_TYPE_INT64 = 3 */
case UPB_TYPE_ENUM: 8, /* UPB_DESCRIPTOR_TYPE_UINT64 = 4 */
case UPB_TYPE_INT32: 4, /* UPB_DESCRIPTOR_TYPE_INT32 = 5 */
case UPB_TYPE_UINT32: 8, /* UPB_DESCRIPTOR_TYPE_FIXED64 = 6 */
case UPB_TYPE_FLOAT: 4, /* UPB_DESCRIPTOR_TYPE_FIXED32 = 7 */
return 4; 1, /* UPB_DESCRIPTOR_TYPE_BOOL = 8 */
case UPB_TYPE_BOOL: sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING = 9 */
return 1; sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP = 11 */
case UPB_TYPE_MESSAGE: sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE = 12 */
return sizeof(void*); sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES = 13 */
case UPB_TYPE_BYTES: 4, /* UPB_DESCRIPTOR_TYPE_UINT32 = 14 */
case UPB_TYPE_STRING: 4, /* UPB_DESCRIPTOR_TYPE_ENUM = 15 */
return sizeof(upb_strview); 4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 = 16 */
} 8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 = 17 */
UPB_UNREACHABLE(); 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) { static uint8_t upb_msg_fieldsize(const upb_msglayout_field *field) {
if (field->label == UPB_LABEL_REPEATED) { if (field->label == UPB_LABEL_REPEATED) {
return sizeof(void*); return sizeof(void*);
} else { } 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) { 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); UPB_ASSERT(i < arr->len);
return upb_msgval_read(arr->data, i * element_size, element_size); 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, bool upb_array_set(upb_array *arr, upb_fieldtype_t type, size_t i,
upb_msgval val, upb_arena *arena) { 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); UPB_ASSERT(i <= arr->len);
if (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 *******************************************************************/ /** 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) { const char **out_key, size_t *out_len) {
switch (type) { switch (type) {
case UPB_TYPE_STRING: case UPB_DESCRIPTOR_TYPE_BYTES:
case UPB_DESCRIPTOR_TYPE_STRING:
/* Point to string data of the input key. */ /* Point to string data of the input key. */
*out_key = key->str.data; *out_key = key->str.data;
*out_len = key->str.size; *out_len = key->str.size;
return; return;
case UPB_TYPE_BOOL: case UPB_DESCRIPTOR_TYPE_BOOL:
case UPB_TYPE_INT32: case UPB_DESCRIPTOR_TYPE_INT32:
case UPB_TYPE_UINT32: case UPB_DESCRIPTOR_TYPE_SINT32:
case UPB_TYPE_INT64: case UPB_DESCRIPTOR_TYPE_SFIXED32:
case UPB_TYPE_UINT64: 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. */ /* Point to the key itself. XXX: big-endian. */
*out_key = (const char*)key; *out_key = (const char*)key;
*out_len = upb_msgval_sizeof(type); *out_len = upb_msgval_sizeof(type);
return; return;
case UPB_TYPE_BYTES: case UPB_DESCRIPTOR_TYPE_DOUBLE:
case UPB_TYPE_DOUBLE: case UPB_DESCRIPTOR_TYPE_ENUM:
case UPB_TYPE_ENUM: case UPB_DESCRIPTOR_TYPE_FLOAT:
case UPB_TYPE_FLOAT: case UPB_DESCRIPTOR_TYPE_MESSAGE:
case UPB_TYPE_MESSAGE: case UPB_DESCRIPTOR_TYPE_GROUP:
break; /* Cannot be a map key. */ UPB_UNREACHABLE(); /* Cannot be a map key. */
} }
UPB_UNREACHABLE(); 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) { size_t len) {
switch (type) { switch (type) {
case UPB_TYPE_STRING: case UPB_DESCRIPTOR_TYPE_BYTES:
case UPB_DESCRIPTOR_TYPE_STRING:
return upb_msgval_makestr(key, len); return upb_msgval_makestr(key, len);
case UPB_TYPE_BOOL: case UPB_DESCRIPTOR_TYPE_BOOL:
case UPB_TYPE_INT32: case UPB_DESCRIPTOR_TYPE_INT32:
case UPB_TYPE_UINT32: case UPB_DESCRIPTOR_TYPE_SINT32:
case UPB_TYPE_INT64: case UPB_DESCRIPTOR_TYPE_SFIXED32:
case UPB_TYPE_UINT64: 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)); return upb_msgval_read(key, 0, upb_msgval_sizeof(type));
case UPB_TYPE_BYTES: case UPB_DESCRIPTOR_TYPE_DOUBLE:
case UPB_TYPE_DOUBLE: case UPB_DESCRIPTOR_TYPE_ENUM:
case UPB_TYPE_ENUM: case UPB_DESCRIPTOR_TYPE_FLOAT:
case UPB_TYPE_FLOAT: case UPB_DESCRIPTOR_TYPE_MESSAGE:
case UPB_TYPE_MESSAGE: case UPB_DESCRIPTOR_TYPE_GROUP:
break; /* Cannot be a map key. */ UPB_UNREACHABLE(); /* Cannot be a map key. */
} }
UPB_UNREACHABLE(); UPB_UNREACHABLE();
} }
bool upb_map_get(const upb_map *map, upb_fieldtype_t key_type, upb_msgval key, bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val,
upb_msgval *val) { const upb_msglayout *layout) {
const upb_strmap *map2 = (const upb_strmap*)map;
upb_value tabval; upb_value tabval;
const char *key_str; const char *key_str;
size_t key_len; size_t key_len;
bool ret; bool ret;
upb_map_tokey(key_type, &key, &key_str, &key_len); upb_map_tokey(layout->fields[0].descriptortype, &key, &key_str, &key_len);
ret = upb_strtable_lookup2(&map2->table, key_str, key_len, &tabval); ret = upb_strtable_lookup2(&map->table, key_str, key_len, &tabval);
if (ret) { if (ret) {
memcpy(val, &tabval, sizeof(tabval)); 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; return ret;
} }
bool upb_map_set(upb_map *map, upb_fieldtype_t key_type, upb_msgval key, bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
upb_msgval val, upb_msgval *removed, upb_arena *arena) { const upb_msglayout *layout, upb_arena *arena) {
upb_strmap *map2 = (upb_strmap*)map;
const char *key_str; const char *key_str;
size_t key_len; size_t key_len;
upb_value tabval = upb_toval(val); upb_value tabval = upb_toval(val);
upb_value removedtabval; upb_value removedtabval;
upb_alloc *a = upb_arena_alloc(arena); 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. */ /* TODO(haberman): add overwrite operation to minimize number of lookups. */
if (upb_strtable_lookup2(&map2->table, key_str, key_len, NULL)) { if (upb_strtable_lookup2(&map->table, key_str, key_len, NULL)) {
upb_strtable_remove3(&map2->table, key_str, key_len, &removedtabval, a); upb_strtable_remove3(&map->table, key_str, key_len, &removedtabval, a);
memcpy(&removed, &removedtabval, sizeof(removed));
} }
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_arena *arena) {
upb_strmap *map2 = (upb_strmap*)map;
const char *key_str; const char *key_str;
size_t key_len; size_t key_len;
upb_alloc *a = upb_arena_alloc(arena); 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);
return upb_strtable_remove3(&map2->table, key_str, key_len, NULL, a); return upb_strtable_remove3(&map->table, key_str, key_len, NULL, a);
} }
/** upb_mapiter ***************************************************************/ /** upb_mapiter ***************************************************************/
struct upb_mapiter { struct upb_mapiter {
upb_strtable_iter iter; upb_strtable_iter iter;
upb_fieldtype_t key_type; upb_descriptortype_t key_type;
}; };
size_t upb_mapiter_sizeof() { size_t upb_mapiter_sizeof() {
return sizeof(upb_mapiter); 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_map *map) {
const upb_strmap *map2 = (const upb_strmap*)map; upb_strtable_begin(&i->iter, &map->table);
upb_strtable_begin(&i->iter, &map2->table); i->key_type = layout->fields[0].descriptortype;
i->key_type = key_type;
} }
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_alloc *a) {
upb_mapiter *ret = upb_malloc(a, upb_mapiter_sizeof()); 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; return NULL;
} }
upb_mapiter_begin(ret, key_type, map); upb_mapiter_begin(ret, layout, map);
return ret; return ret;
} }

@ -10,11 +10,6 @@
struct upb_mapiter; struct upb_mapiter;
typedef struct upb_mapiter 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 ****************************************************************/ /** upb_msgval ****************************************************************/
/* A union representing all possible protobuf values. Used for generic get/set /* 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 * semantics are the same as upb_msg. A upb_array allocates dynamic
* memory internally for the array elements. */ * memory internally for the array elements. */
upb_fieldtype_t upb_array_type(const upb_array *arr);
/* Read-only interface. Safe for anyone to call. */ /* Read-only interface. Safe for anyone to call. */
size_t upb_array_size(const upb_array *arr); 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. */ /* Read-only interface. Safe for anyone to call. */
size_t upb_map_size(const upb_map *map); 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, bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val,
upb_msgval *val); const upb_msglayout *l);
/* Write interface. May only be called by the message's owner who can enforce /* Write interface. May only be called by the message's owner who can enforce
* its memory management invariants. */ * 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 /* Sets or overwrites an entry in the map. Return value indicates whether
* the operation succeeded or failed with OOM, and also whether an existing * the operation succeeded or failed with OOM, and also whether an existing
* key was replaced or not. */ * key was replaced or not. */
bool upb_map_set(upb_map *map, upb_fieldtype_t key_type, upb_msgval key, bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
upb_msgval val, upb_msgval *valremoved, upb_arena *arena); const upb_msglayout *l, upb_arena *arena);
/* Deletes an entry in the map. Returns true if the key was present. */ /* 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_arena *arena);
/** upb_mapiter ***************************************************************/ /** 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(); 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); 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); upb_alloc *a);
void upb_mapiter_free(upb_mapiter *i, upb_alloc *a); void upb_mapiter_free(upb_mapiter *i, upb_alloc *a);
void upb_mapiter_next(upb_mapiter *i); void upb_mapiter_next(upb_mapiter *i);

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

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

Loading…
Cancel
Save