diff --git a/_lab/go/go.mod b/_lab/go/go.mod index 14c6e694..e54d1dda 100644 --- a/_lab/go/go.mod +++ b/_lab/go/go.mod @@ -1,6 +1,6 @@ module github.com/tableauio/loader/_lab/go -go 1.17 +go 1.18 require ( github.com/pkg/errors v0.9.1 diff --git a/_lab/go/loader_test.go b/_lab/go/loader_test.go index f705ab74..12d1ea6b 100644 --- a/_lab/go/loader_test.go +++ b/_lab/go/loader_test.go @@ -3,16 +3,17 @@ package main import ( "testing" - "github.com/tableauio/tableau/options" + "github.com/tableauio/loader/_lab/go/tableau" + "github.com/tableauio/tableau/format" ) func Test_Loader(t *testing.T) { - err := GetHub().Load("../../testdata/", nil, options.JSON) + err := GetHub().Load("../../testdata/", nil, format.JSON) if err != nil { panic(err) } - conf := GetHub().GetActivityConf() + conf := Get[*tableau.ActivityConf]() if conf == nil { panic("ActivityConf is nil") } @@ -21,4 +22,4 @@ func Test_Loader(t *testing.T) { panic(err) } t.Logf("ActivityConf: %v", chapter) -} \ No newline at end of file +} diff --git a/_lab/go/main.go b/_lab/go/main.go index 34687f58..1ee7c66f 100644 --- a/_lab/go/main.go +++ b/_lab/go/main.go @@ -28,13 +28,17 @@ func GetHub() *MyHub { return hubSingleton } +func Get[T tableau.Messager]() T { + return tableau.Get[T](GetHub().Hub) +} + func main() { err := GetHub().Load("../../test/testdata/", nil, format.JSON, load.IgnoreUnknownFields(true)) if err != nil { panic(err) } - conf := GetHub().GetActivityConf() + conf := Get[*tableau.ActivityConf]() if conf == nil { panic("ActivityConf is nil") } @@ -59,7 +63,7 @@ func main() { } func debug() { - itemConf := GetHub().GetItemConf() + itemConf := Get[*tableau.ItemConf]() if itemConf == nil { panic("ItemConf is nil") } diff --git a/_lab/go/tableau/hub.pc.go b/_lab/go/tableau/hub.pc.go index b462c316..0458731f 100644 --- a/_lab/go/tableau/hub.pc.go +++ b/_lab/go/tableau/hub.pc.go @@ -87,24 +87,17 @@ func (h *Hub) Load(dir string, filter Filter, format format.Format, options ...l return nil } -// Auto-generated getters below - -func (h *Hub) GetActivityConf() *ActivityConf { - msger := h.messagerMap["ActivityConf"] - if msger != nil { - if conf, ok := msger.(*ActivityConf); ok { - return conf - } +func Get[T Messager](h *Hub) T { + var t T + if h == nil { + return t } - return nil -} - -func (h *Hub) GetItemConf() *ItemConf { - msger := h.messagerMap["ItemConf"] + msgers := h.messagerMap + msger := msgers[t.Name()] if msger != nil { - if conf, ok := msger.(*ItemConf); ok { - return conf + if t, ok := msger.(T); ok { + return t } } - return nil + return t } diff --git a/_lab/go/tableau/item_conf.pc.go b/_lab/go/tableau/item_conf.pc.go index 67893595..21eec2df 100644 --- a/_lab/go/tableau/item_conf.pc.go +++ b/_lab/go/tableau/item_conf.pc.go @@ -9,15 +9,18 @@ import ( ) type ItemConf struct { - data protoconf.ItemConf + data *protoconf.ItemConf } func (x *ItemConf) Name() string { - return string((&x.data).ProtoReflect().Descriptor().Name()) + return string(x.Data().ProtoReflect().Descriptor().Name()) } func (x *ItemConf) Data() *protoconf.ItemConf { - return &x.data + if x == nil { + return nil + } + return x.data } // Messager is used to implement Checker interface. @@ -31,11 +34,11 @@ func (x *ItemConf) Check(hub *Hub) error { } func (x *ItemConf) Load(dir string, format format.Format, options ...load.Option) error { - return load.Load(&x.data, dir, format, options...) + return load.Load(x.data, dir, format, options...) } func (x *ItemConf) Get1(key1 uint32) (*protoconf.ItemConf_Item, error) { - d := x.data.ItemMap + d := x.Data().GetItemMap() if d == nil { return nil, xerrors.Errorf(code.Nil, "ItemMap is nil") } @@ -48,6 +51,6 @@ func (x *ItemConf) Get1(key1 uint32) (*protoconf.ItemConf_Item, error) { func init() { register("ItemConf", func() Messager { - return &ItemConf{} + return &ItemConf{data: &protoconf.ItemConf{}} }) } diff --git a/_lab/go/tableau/test.pc.go b/_lab/go/tableau/test.pc.go index f40353bb..768bbeb0 100644 --- a/_lab/go/tableau/test.pc.go +++ b/_lab/go/tableau/test.pc.go @@ -11,15 +11,18 @@ import ( ) type ActivityConf struct { - data protoconf.ActivityConf + data *protoconf.ActivityConf } func (x *ActivityConf) Name() string { - return string((&x.data).ProtoReflect().Descriptor().Name()) + return string(x.Data().ProtoReflect().Descriptor().Name()) } func (x *ActivityConf) Data() *protoconf.ActivityConf { - return &x.data + if x == nil { + return nil + } + return x.data } // Messager is used to implement Checker interface. @@ -29,13 +32,13 @@ func (x *ActivityConf) Messager() Messager { // Check is used to implement Checker interface. func (x *ActivityConf) Check(hub *Hub) error { - conf := hub.GetItemConf() + conf := Get[*ItemConf](hub) if conf == nil { return fmt.Errorf("ItemConf is nil") } for _, val1 := range x.data.ActivityMap { for key2 := range val1.ChapterMap { - if _, ok := conf.Data().ItemMap[key2]; !ok { + if _, ok := conf.Data().GetItemMap()[key2]; !ok { return fmt.Errorf("refer: %v not found in ItemConf.ID", key2) } } @@ -44,7 +47,7 @@ func (x *ActivityConf) Check(hub *Hub) error { } func (x *ActivityConf) Load(dir string, fmt format.Format, options ...load.Option) error { - return load.Load(&x.data, dir, fmt, options...) + return load.Load(x.data, dir, fmt, options...) } func (x *ActivityConf) Get1(key1 uint64) (*protoconf.ActivityConf_Activity, error) { @@ -112,6 +115,6 @@ func (x *ActivityConf) Get4(key1 uint64, key2 uint32, key3 uint32, key4 uint32) func init() { register("ActivityConf", func() Messager { - return &ActivityConf{} + return &ActivityConf{data: &protoconf.ActivityConf{}} }) } diff --git a/cmd/protoc-gen-go-tableau-loader/hub.go b/cmd/protoc-gen-go-tableau-loader/hub.go index 896dd157..1d0b9a2a 100644 --- a/cmd/protoc-gen-go-tableau-loader/hub.go +++ b/cmd/protoc-gen-go-tableau-loader/hub.go @@ -16,19 +16,6 @@ func generateHub(gen *protogen.Plugin) { g.P() g.P(staticHubContent) g.P() - - for _, messager := range messagers { - g.P("func (h *Hub) Get", messager, "() *", messager, " {") - g.P(`msger := h.messagerMap["`, messager, `"]`) - g.P("if msger != nil {") - g.P("if conf, ok := msger.(*", messager, "); ok {") - g.P("return conf") - g.P("}") - g.P("}") - g.P("return nil") - g.P("}") - g.P() - } } const staticHubContent = `import ( @@ -118,4 +105,19 @@ func (h *Hub) Load(dir string, filter Filter, format format.Format, options ...l return nil } -// Auto-generated getters below` +func Get[T Messager](h *Hub) T { + var t T + if h == nil { + return t + } + msgers := h.messagerMap + msger := msgers[t.Name()] + if msger != nil { + if t, ok := msger.(T); ok { + return t + } + } + return t +} + +` diff --git a/cmd/protoc-gen-go-tableau-loader/messager.go b/cmd/protoc-gen-go-tableau-loader/messager.go index 03d15912..23bef3b2 100644 --- a/cmd/protoc-gen-go-tableau-loader/messager.go +++ b/cmd/protoc-gen-go-tableau-loader/messager.go @@ -55,15 +55,15 @@ func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen. } } messagers = append(messagers, fileMessagers...) - generateRegister(fileMessagers, g) + generateRegister(fileMessagers, g, file) } -func generateRegister(messagers []string, g *protogen.GeneratedFile) { +func generateRegister(messagers []string, g *protogen.GeneratedFile, file *protogen.File) { // register messagers g.P("func init() {") for _, messager := range messagers { g.P(`register("`, messager, `", func() Messager {`) - g.P("return &", messager, "{}") + g.P("return &", messager, "{data: &", file.GoImportPath.Ident(messager), "{}}") g.P("})") } g.P("}") @@ -75,18 +75,21 @@ func genMessage(gen *protogen.Plugin, file *protogen.File, g *protogen.Generated // messager definition g.P("type ", messagerName, " struct {") - g.P("data ", file.GoImportPath.Ident(messagerName)) + g.P("data *", file.GoImportPath.Ident(messagerName)) g.P("}") g.P() // messager methods g.P("func (x *", messagerName, ") Name() string {") - g.P("return string((&x.data).ProtoReflect().Descriptor().Name())") + g.P("return string(x.Data().ProtoReflect().Descriptor().Name())") g.P("}") g.P() g.P("func (x *", messagerName, ") Data() *", file.GoImportPath.Ident(messagerName), " {") - g.P("return &x.data") + g.P("if x == nil {") + g.P("return nil") + g.P("}") + g.P("return x.data") g.P("}") g.P() @@ -109,7 +112,7 @@ func genMessage(gen *protogen.Plugin, file *protogen.File, g *protogen.Generated g.P() g.P("func (x *", messagerName, ") Load(dir string, format ", formatPackage.Ident("Format"), " , options ...", loadPackage.Ident("Option"), ") error {") - g.P("return ", loadPackage.Ident("Load"), "(&x.data, dir, format, options...)") + g.P("return ", loadPackage.Ident("Load"), "(x.data, dir, format, options...)") g.P("}") g.P() @@ -173,7 +176,7 @@ func genMapGetters(depth int, params []string, messagerName string, file *protog var container string if depth == 1 { - container = "x.data" + container = "x.Data()" } else { container = "conf" var findParams []string @@ -188,7 +191,7 @@ func genMapGetters(depth int, params []string, messagerName string, file *protog g.P() } - g.P("d := ", container, ".", field.GoName) + g.P("d := ", container, ".Get", field.GoName, "()") g.P("if d == nil {") g.P(`return `, returnEmptyValue, `, `, errorsPackage.Ident("Errorf"), `(`, codePackage.Ident("Nil"), `, "`, field.GoName, ` is nil")`) g.P("}") diff --git a/go.mod b/go.mod index 682c9afd..c8136b74 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/tableauio/loader -go 1.17 +go 1.18 require ( github.com/iancoleman/strcase v0.2.0