Skip to content

Commit 76eec5f

Browse files
committed
do not omit empty message in oneof
1 parent bd82f66 commit 76eec5f

File tree

3 files changed

+56
-34
lines changed

3 files changed

+56
-34
lines changed

pb.c

+14-15
Original file line numberDiff line numberDiff line change
@@ -1167,7 +1167,6 @@ static int lpb_pushtype(lua_State *L, pb_Type *t) {
11671167
}
11681168

11691169
static int lpb_pushfield(lua_State *L, pb_Type *t, pb_Field *f) {
1170-
pb_OneofEntry *e;
11711170
if (f == NULL) return 0;
11721171
lua_pushstring(L, (char*)f->name);
11731172
lua_pushinteger(L, f->number);
@@ -1176,10 +1175,9 @@ static int lpb_pushfield(lua_State *L, pb_Type *t, pb_Field *f) {
11761175
lua_pushstring(L, (char*)f->default_value);
11771176
lua_pushstring(L, f->packed ? "packed" :
11781177
f->repeated ? "repeated" : "optional");
1179-
e = (pb_OneofEntry*)pb_gettable(&t->oneof_index, (pb_Key)f);
1180-
if (e) {
1181-
lua_pushstring(L, (const char*)e->name);
1182-
lua_pushinteger(L, e->index-1);
1178+
if (f->oneof_idx > 0) {
1179+
lua_pushstring(L, (const char*)pb_oneofname(t, f->oneof_idx));
1180+
lua_pushinteger(L, f->oneof_idx-1);
11831181
return 7;
11841182
}
11851183
return 5;
@@ -1244,7 +1242,7 @@ static int Lpb_enum(lua_State *L) {
12441242
}
12451243

12461244
static int lpb_pushdefault(lua_State *L, lpb_State *LS, pb_Field *f, int is_proto3) {
1247-
pb_Type *type = f->type;
1245+
pb_Type *type = f->type;
12481246
int ret = 0;
12491247
char *end;
12501248
if (f == NULL) return 0;
@@ -1389,7 +1387,7 @@ static void lpbE_field(lpb_Env *e, pb_Field *f, size_t *plen) {
13891387
pb_Buffer *b = e->b;
13901388
size_t len;
13911389
int ltype;
1392-
if (plen) *plen = 0;
1390+
if (plen) *plen = 0;
13931391
switch (f->type_id) {
13941392
case PB_Tenum:
13951393
lpbE_enum(e, f);
@@ -1476,8 +1474,8 @@ static void lpb_encode(lpb_Env *e, pb_Type *t) {
14761474
lpbE_map(e, f);
14771475
else if (f->repeated)
14781476
lpbE_repeated(e, f);
1479-
else if (!f->type || f->type->field_count != 0) {
1480-
size_t ignoredlen;
1477+
else if (!f->type || (f->type->field_count != 0 || f->oneof_idx > 0)) {
1478+
size_t ignoredlen;
14811479
lpbE_tagfield(e, f, &ignoredlen);
14821480
if (t->is_proto3) e->b->size -= ignoredlen;
14831481
}
@@ -1574,7 +1572,8 @@ static void lpbD_field(lpb_Env *e, pb_Field *f, uint32_t tag) {
15741572

15751573
case PB_Tmessage:
15761574
lpb_readbytes(L, s, &sv);
1577-
if (f->type == NULL || f->type->field_count == 0)
1575+
if (f->type == NULL
1576+
|| (f->type->field_count == 0 && f->oneof_idx == 0))
15781577
lua_pushnil(L);
15791578
else {
15801579
lpb_pushtypetable(L, e->LS, f->type);
@@ -1650,11 +1649,11 @@ static int lpb_decode(lpb_Env *e, pb_Type *t) {
16501649
lpbD_map(e, f);
16511650
else if (f->repeated)
16521651
lpbD_repeated(e, f, tag);
1653-
else {
1654-
lua_pushstring(L, (char*)f->name);
1655-
lpbD_field(e, f, tag);
1656-
lua_rawset(L, -3);
1657-
}
1652+
else {
1653+
lua_pushstring(L, (char*)f->name);
1654+
lpbD_field(e, f, tag);
1655+
lua_rawset(L, -3);
1656+
}
16581657
}
16591658
return 1;
16601659
}

pb.h

+19-19
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ PB_API pb_Type *pb_type (pb_State *S, pb_Name *tname);
217217
PB_API pb_Field *pb_fname (pb_Type *t, pb_Name *tname);
218218
PB_API pb_Field *pb_field (pb_Type *t, int32_t number);
219219

220+
PB_API pb_Name *pb_oneofname (pb_Type *t, int oneof_index);
221+
220222
PB_API int pb_nexttype (pb_State *S, pb_Type **ptype);
221223
PB_API int pb_nextfield (pb_Type *t, pb_Field **pfield);
222224

@@ -293,10 +295,11 @@ struct pb_Field {
293295
pb_Type *type;
294296
pb_Name *default_value;
295297
int32_t number;
296-
unsigned type_id : 29; /* PB_T* enum */
297-
unsigned repeated : 1;
298-
unsigned packed : 1;
299-
unsigned scalar : 1;
298+
unsigned oneof_idx : 24;
299+
unsigned type_id : 5; /* PB_T* enum */
300+
unsigned repeated : 1;
301+
unsigned packed : 1;
302+
unsigned scalar : 1;
300303
};
301304

302305
struct pb_Type {
@@ -1110,6 +1113,12 @@ PB_API pb_Field *pb_field(pb_Type *t, int32_t number) {
11101113
return fe ? fe->value : NULL;
11111114
}
11121115

1116+
PB_API pb_Name *pb_oneofname(pb_Type *t, int idx) {
1117+
pb_OneofEntry *oe = NULL;
1118+
if (t != NULL) oe = (pb_OneofEntry*)pb_gettable(&t->oneof_index, idx);
1119+
return oe ? oe->name : NULL;
1120+
}
1121+
11131122
PB_API int pb_nexttype(pb_State *S, pb_Type **ptype) {
11141123
pb_TypeEntry *e = NULL;
11151124
if (S != NULL) {
@@ -1564,22 +1573,13 @@ static void pbL_loadField(pb_State *S, pbL_FieldInfo *info, pb_Loader *L, pb_Typ
15641573
if (!(f = pb_newfield(S, t, pb_newname(S, info->name), info->number)))
15651574
return;
15661575
f->default_value = pb_newname(S, info->default_value);
1567-
f->type = ft;
1568-
f->type_id = info->type;
1569-
f->repeated = info->label == 3; /* repeated */
1570-
f->packed = info->packed >= 0 ? info->packed : L->is_proto3;
1576+
f->type = ft;
1577+
f->oneof_idx = info->oneof_index;
1578+
f->type_id = info->type;
1579+
f->repeated = info->label == 3; /* repeated */
1580+
f->packed = info->packed >= 0 ? info->packed : L->is_proto3;
15711581
if (f->type_id >= 9 && f->type_id <= 12) f->packed = 0;
1572-
f->scalar = f->type == NULL;
1573-
if (info->oneof_index != 0) {
1574-
pb_OneofEntry *fe, *e = (pb_OneofEntry*)pb_gettable(&t->oneof_index,
1575-
info->oneof_index), saved;
1576-
if (e != NULL) {
1577-
saved = *e;
1578-
fe = (pb_OneofEntry*)pb_settable(&t->oneof_index, (pb_Key)f);
1579-
fe->name = pb_usename(saved.name);
1580-
fe->index = saved.index;
1581-
}
1582-
}
1582+
f->scalar = (f->type == NULL);
15831583
}
15841584

15851585
static void pbL_loadType(pb_State *S, pbL_TypeInfo *info, pb_Loader *L) {

test.lua

+23
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,29 @@ function _G.test_map()
615615
end
616616

617617
function _G.test_oneof()
618+
check_load [[
619+
syntax = "proto3";
620+
message TO_M1 {
621+
}
622+
message TO_M2 {
623+
}
624+
message TO_M3 {
625+
int32 value = 1;
626+
}
627+
message TestOneof {
628+
oneof body_oneof {
629+
TO_M1 m1 = 100;
630+
TO_M2 m2 = 200;
631+
TO_M3 m3 = 300;
632+
}
633+
} ]]
634+
check_msg("TestOneof", {})
635+
check_msg("TestOneof", { m1 = {} })
636+
check_msg("TestOneof", { m2 = {} })
637+
check_msg("TestOneof", { m3 = { value = 0 } })
638+
check_msg("TestOneof", { m3 = { value = 10 } })
639+
pb.clear "TestOneof"
640+
618641
check_load [[
619642
syntax = "proto3";
620643
message TestOneof {

0 commit comments

Comments
 (0)