mirror of
https://github.com/vxcontrol/lualibs-protobuf.git
synced 2026-07-01 09:16:28 -04:00
add oneof field for actually written fields
This commit is contained in:
@@ -1685,7 +1685,7 @@ static void lpb_usedechooks(lua_State *L, lpb_State *LS, const pb_Type *t) {
|
||||
static void lpb_pushtypetable(lua_State *L, lpb_State *LS, const pb_Type *t) {
|
||||
const pb_Field *f = NULL;
|
||||
int mode = LS->default_mode;
|
||||
lua_createtable(L, 0, t->field_count - t->oneof_count);
|
||||
lua_createtable(L, 0, t->field_count - t->oneof_field + t->oneof_count*2);
|
||||
switch (t->is_proto3 && mode == LPB_DEFDEF ? LPB_COPYDEF : mode) {
|
||||
case LPB_COPYDEF:
|
||||
while (pb_nextfield(t, &f))
|
||||
@@ -1827,6 +1827,11 @@ static int lpbD_message(lpb_Env *e, const pb_Type *t) {
|
||||
lpbD_repeated(e, f, tag);
|
||||
else {
|
||||
lua_pushstring(L, (const char*)f->name);
|
||||
if (f->oneof_idx) {
|
||||
lua_pushstring(L, (const char*)pb_oneofname(t, f->oneof_idx));
|
||||
lua_pushvalue(L, -2);
|
||||
lua_rawset(L, -4);
|
||||
}
|
||||
lpbD_field(e, f, tag);
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
|
||||
@@ -338,6 +338,7 @@ struct pb_Type {
|
||||
pb_Table field_names;
|
||||
pb_Table oneof_index;
|
||||
unsigned oneof_count; /* extra field count from oneof entries */
|
||||
unsigned oneof_field; /* extra field in oneof declarations */
|
||||
unsigned field_count : 28;
|
||||
unsigned is_enum : 1;
|
||||
unsigned is_map : 1;
|
||||
@@ -1245,7 +1246,7 @@ PB_API void pb_deltype(pb_State *S, pb_Type *t) {
|
||||
pb_freetable(&t->field_tags);
|
||||
pb_freetable(&t->field_names);
|
||||
pb_freetable(&t->oneof_index);
|
||||
t->oneof_count = 0, t->field_count = 0;
|
||||
t->oneof_field = 0, t->field_count = 0;
|
||||
t->is_dead = 1;
|
||||
/*pb_delname(S, t->name); */
|
||||
/*pb_poolfree(&S->typepool, t); */
|
||||
@@ -1630,7 +1631,7 @@ static int pbL_loadField(pb_State *S, pbL_FieldInfo *info, pb_Loader *L, pb_Type
|
||||
pbCE(f = pb_newfield(S, t, pb_newname(S, info->name, NULL), info->number));
|
||||
f->default_value = pb_newname(S, info->default_value, NULL);
|
||||
f->type = ft;
|
||||
if ((f->oneof_idx = info->oneof_index)) ++t->oneof_count;
|
||||
if ((f->oneof_idx = info->oneof_index)) ++t->oneof_field;
|
||||
f->type_id = info->type;
|
||||
f->repeated = info->label == 3; /* repeated */
|
||||
f->packed = info->packed >= 0 ? info->packed : L->is_proto3 && f->repeated;
|
||||
@@ -1659,7 +1660,7 @@ static int pbL_loadType(pb_State *S, pbL_TypeInfo *info, pb_Loader *L) {
|
||||
pbC(pbL_loadEnum(S, &info->enum_type[i], L));
|
||||
for (i = 0, count = pbL_count(info->nested_type); i < count; ++i)
|
||||
pbC(pbL_loadType(S, &info->nested_type[i], L));
|
||||
t->oneof_count -= pbL_count(info->oneof_decl);
|
||||
t->oneof_count = pbL_count(info->oneof_decl);
|
||||
L->b.size = (unsigned)curr;
|
||||
return PB_OK;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ local protoc = require "protoc"
|
||||
local eq = lu.assertEquals
|
||||
local table_eq = lu.assertItemsEquals
|
||||
local fail = lu.assertErrorMsgContains
|
||||
local is_true = lu.assertIsTrue
|
||||
|
||||
local types = 0
|
||||
for _ in pb.types() do
|
||||
@@ -543,6 +544,9 @@ function _G.test_packed()
|
||||
fail("table expected at field 'packs', got boolean",
|
||||
function() pb.encode("TestPacked", { packs = true }) end)
|
||||
|
||||
local data = {packs = {}}
|
||||
check_msg(".TestPacked", data, {})
|
||||
|
||||
local hasEmpty
|
||||
for _, name in pb.types() do
|
||||
if name == "Empty" then
|
||||
@@ -684,10 +688,10 @@ function _G.test_oneof()
|
||||
}
|
||||
} ]]
|
||||
check_msg("TestOneof", {})
|
||||
check_msg("TestOneof", { m1 = {} })
|
||||
check_msg("TestOneof", { m2 = {} })
|
||||
check_msg("TestOneof", { m3 = { value = 0 } })
|
||||
check_msg("TestOneof", { m3 = { value = 10 } })
|
||||
check_msg("TestOneof", { m1 = {}, body_oneof = "m1" })
|
||||
check_msg("TestOneof", { m2 = {}, body_oneof = "m2" })
|
||||
check_msg("TestOneof", { m3 = { value = 0 }, body_oneof = "m3" })
|
||||
check_msg("TestOneof", { m3 = { value = 10 }, body_oneof = "m3" })
|
||||
pb.clear "TestOneof"
|
||||
|
||||
check_load [[
|
||||
@@ -702,12 +706,17 @@ function _G.test_oneof()
|
||||
TestOneof msg = 1;
|
||||
}
|
||||
]]
|
||||
check_msg("TestOneof", { foo = 0 })
|
||||
check_msg("TestOneof", { bar = "" })
|
||||
check_msg("TestOneof", { foo = 0, bar = "" })
|
||||
check_msg("Outter", { msg = { foo = 0 }})
|
||||
check_msg("Outter", { msg = { bar = "" }})
|
||||
check_msg("Outter", { msg = { foo = 0, bar = "" }})
|
||||
|
||||
check_msg("TestOneof", { foo = 0, body = "foo" })
|
||||
check_msg("TestOneof", { bar = "", body = "bar" })
|
||||
local chunk = pb.encode("TestOneof", { foo = 0, bar = "" })
|
||||
local data = pb.decode("TestOneof", chunk)
|
||||
is_true(data.body == "foo" or data.body == "bar")
|
||||
check_msg("Outter", { msg = { foo = 0, body = "foo" }})
|
||||
check_msg("Outter", { msg = { bar = "", body = "bar" }})
|
||||
local chunk = pb.encode("Outter", {msg = { foo = 0, bar = "" }})
|
||||
local data = pb.decode("Outter", chunk)
|
||||
is_true(data.msg.body == "foo" or data.msg.body == "bar")
|
||||
pb.clear "TestOneof"
|
||||
pb.clear "Outter"
|
||||
|
||||
@@ -720,12 +729,12 @@ function _G.test_oneof()
|
||||
}
|
||||
} ]]
|
||||
|
||||
check_msg("TestOneof", { name = "foo" })
|
||||
check_msg("TestOneof", { value = 0 })
|
||||
check_msg("TestOneof", { name = "foo", value = 0 })
|
||||
check_msg("TestOneof", { name = "foo", test_oneof = "name" })
|
||||
check_msg("TestOneof", { value = 0, test_oneof = "value" })
|
||||
local chunk = pb.encode("TestOneof", { name = "foo", value = 0 })
|
||||
local data = pb.decode("TestOneof", chunk)
|
||||
is_true(data.test_oneof == "name" or data.test_oneof == "value")
|
||||
|
||||
local data = { name = "foo", value = 5 }
|
||||
check_msg("TestOneof", data)
|
||||
eq(pb.field("TestOneof", "name"), "name")
|
||||
pb.clear("TestOneof", "name")
|
||||
eq(pb.field("TestOneof", "name"), nil)
|
||||
|
||||
Reference in New Issue
Block a user