Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/confgen/document_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ func (p *documentParser) parseUnionField(field *Field, msg protoreflect.Message,
}

if field.opts.Span == tableaupb.Span_SPAN_INNER_CELL {
present, err = p.parseIncellUnion(structValue, node.ScalarValue(), field.opts.GetProp().GetForm())
present, err = p.parseIncellUnion(field, structValue, node.ScalarValue())
} else {
present, err = p.parseUnionMessage(field, structValue.Message(), node.StructNode(), cardPrefix)
}
Expand Down
21 changes: 16 additions & 5 deletions internal/confgen/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,8 @@ func (p *sheetParser) parseIncellMap(field *Field, reflectMap protoreflect.Map,
// - map<int32, EnumType>
func (p *sheetParser) parseIncellMapWithSimpleKV(field *Field, reflectMap protoreflect.Map, cellData string) (err error) {
if cellData == "" {
return nil
// check presence
return fieldprop.CheckPresence(field.opts.Prop, false)
}
// If s does not contain sep and sep is not empty, Split returns a
// slice of length 1 whose only element is s.
Expand Down Expand Up @@ -480,7 +481,8 @@ func (p *sheetParser) parseIncellMapWithSimpleKV(field *Field, reflectMap protor
// }
func (p *sheetParser) parseIncellMapWithValueAsSimpleKVMessage(field *Field, reflectMap protoreflect.Map, cellData string) (err error) {
if cellData == "" {
return nil
// check presence
return fieldprop.CheckPresence(field.opts.Prop, false)
}
// If s does not contain sep and sep is not empty, Split returns a
// slice of length 1 whose only element is s.
Expand Down Expand Up @@ -753,6 +755,13 @@ func (p *sheetParser) checkSubFieldProp(field *Field, cardPrefix string, newValu
}

func (p *sheetParser) parseIncellList(field *Field, list protoreflect.List, cardPrefix string, elemData string) (present bool, err error) {
if elemData == "" {
if err := fieldprop.CheckPresence(field.opts.Prop, false); err != nil {
return false, err
}
// For fixed size list, an empty cell means an empty list element,
// So here we should continue to parse, but not return.
}
splits := strings.Split(elemData, field.sep)
return p.parseListElems(field, list, cardPrefix, field.subsep, splits)
}
Expand Down Expand Up @@ -823,7 +832,8 @@ func (p *sheetParser) parseListElems(field *Field, list protoreflect.List, cardP

func (p *sheetParser) parseIncellStruct(field *Field, structValue protoreflect.Value, cellData string, sep string) (present bool, err error) {
if cellData == "" {
return false, nil
// check presence
return false, fieldprop.CheckPresence(field.opts.Prop, false)
}
switch field.opts.GetProp().GetForm() {
case tableaupb.Form_FORM_TEXT:
Expand Down Expand Up @@ -915,10 +925,11 @@ func (p *sheetParser) parseUnionMessageField(field *Field, msg protoreflect.Mess
return nil
}

func (p *sheetParser) parseIncellUnion(structValue protoreflect.Value, cellData string, form tableaupb.Form) (present bool, err error) {
func (p *sheetParser) parseIncellUnion(field *Field, structValue protoreflect.Value, cellData string) (present bool, err error) {
if cellData == "" {
return false, nil
return false, fieldprop.CheckPresence(field.opts.Prop, false)
}
form := field.opts.GetProp().GetForm()
switch form {
case tableaupb.Form_FORM_TEXT:
if err := prototext.Unmarshal([]byte(cellData), structValue.Message().Interface()); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/confgen/table_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ func (p *tableParser) parseUnionField(field *Field, msg protoreflect.Message, r
if field.opts.Span == tableaupb.Span_SPAN_INNER_CELL {
// incell union
if cell, err = r.Cell(newPrefix, p.IsFieldOptional(field)); err == nil {
present, err = p.parseIncellUnion(structValue, cell.Data, field.opts.GetProp().GetForm())
present, err = p.parseIncellUnion(field, structValue, cell.Data)
}
} else {
// cross-cell union
Expand Down
108 changes: 108 additions & 0 deletions internal/confgen/table_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1009,3 +1009,111 @@ func TestTableParser_parseVerticalSequenceFieldKeyedList(t *testing.T) {
})
}
}

func TestTableParser_parseFieldPresentMap(t *testing.T) {
type args struct {
sheet *book.Sheet
}
tests := []struct {
name string
parser *sheetParser
args args
wantErr bool
err error
}{
{
name: "all fields present",
parser: newTableParserForTest(),
args: args{
sheet: book.NewTableSheet(
"FieldPresentMap",
[][]string{
{"ID", "WeaponName", "WeaponRarity", "Info", "Hero", "Attr", "Target"},
{"1", "sword", "2", "1,10", "1,2,3", "hp:10,atk:20,def:30", "type:TYPE_PVP pvp:{type:1 damage:2}"},
}),
},
wantErr: false,
},
{
name: "first field of horizontal struct not present",
parser: newTableParserForTest(),
args: args{
sheet: book.NewTableSheet(
"FieldPresentMap",
[][]string{
{"ID", "WeaponName", "WeaponRarity", "Info", "Hero", "Attr", "Target"},
{"1", "", "2", "1,10", "1,2,3", "hp:10,atk:20,def:30", "type:TYPE_PVP pvp:{type:1 damage:2}"},
}),
},
wantErr: true,
err: xerrors.ErrE2011,
},
{
name: "incell struct field not present",
parser: newTableParserForTest(),
args: args{
sheet: book.NewTableSheet(
"FieldPresentMap",
[][]string{
{"ID", "WeaponName", "WeaponRarity", "Info", "Hero", "Attr", "Target"},
{"1", "sword", "2", "", "1,2,3", "hp:10,atk:20,def:30", "type:TYPE_PVP pvp:{type:1 damage:2}"},
}),
},
wantErr: true,
err: xerrors.ErrE2011,
},
{
name: "incell list field not present",
parser: newTableParserForTest(),
args: args{
sheet: book.NewTableSheet(
"FieldPresentMap",
[][]string{
{"ID", "WeaponName", "WeaponRarity", "Info", "Hero", "Attr", "Target"},
{"1", "sword", "2", "1,10", "", "hp:10,atk:20,def:30", "type:TYPE_PVP pvp:{type:1 damage:2}"},
}),
},
wantErr: true,
err: xerrors.ErrE2011,
},
{
name: "incell map field not present",
parser: newTableParserForTest(),
args: args{
sheet: book.NewTableSheet(
"FieldPresentMap",
[][]string{
{"ID", "WeaponName", "WeaponRarity", "Info", "Hero", "Attr", "Target"},
{"1", "sword", "2", "1,10", "1,2,3", "", "type:TYPE_PVP pvp:{type:1 damage:2}"},
}),
},
wantErr: true,
err: xerrors.ErrE2011,
},
{
name: "incell union field not present",
parser: newTableParserForTest(),
args: args{
sheet: book.NewTableSheet(
"FieldPresentMap",
[][]string{
{"ID", "WeaponName", "WeaponRarity", "Info", "Hero", "Attr", "Target"},
{"1", "sword", "2", "1,10", "1,2,3", "hp:10,atk:20,def:30", ""},
}),
},
wantErr: true,
err: xerrors.ErrE2011,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.parser.Parse(&unittestpb.FieldPresentMap{}, tt.args.sheet)
if (err != nil) != tt.wantErr {
t.Errorf("sheetParser.Parse() error = %v, wantErr %v", err, tt.wantErr)
}
if err != nil {
require.ErrorIs(t, err, tt.err)
}
})
}
}
22 changes: 22 additions & 0 deletions proto/tableau/protobuf/unittest/unittest.proto
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,26 @@ message Transpose {
int32 id = 1 [(tableau.field) = {name:"ID"}];
string name = 2 [(tableau.field) = {name:"Name"}];
}
}

message FieldPresentMap {
option (tableau.worksheet) = {name:"FieldPresentMap"};

map<int32, Player> player_map = 1 [(tableau.field) = {key:"ID" layout:LAYOUT_VERTICAL}];
message Player {
int32 id = 1 [(tableau.field) = {name:"ID"}];
Weapon weapon = 2 [(tableau.field) = {name:"Weapon" prop:{present:true}}];
message Weapon {
string name = 1 [(tableau.field) = {name:"Name" prop:{present:true}}];
int32 rarity = 2 [(tableau.field) = {name:"Rarity"}];
}
Info info = 3 [(tableau.field) = {name:"Info" span:SPAN_INNER_CELL prop:{present:true}}];
message Info {
int32 level = 1 [(tableau.field) = {name:"Level"}];
int32 exp = 2 [(tableau.field) = {name:"Exp"}];
}
repeated int32 hero_list = 4 [(tableau.field) = {name:"Hero" layout:LAYOUT_INCELL prop:{present:true}}];
map<string, int32> attr_map = 5 [(tableau.field) = {name:"Attr" layout:LAYOUT_INCELL prop:{present:true}}];
unittest.Target target = 6 [(tableau.field) = {name:"Target" span:SPAN_INNER_CELL prop:{form:FORM_TEXT present:true}}];
}
}
Loading
Loading