@@ -11,6 +11,7 @@ import (
1111 "go/parser"
1212 "go/token"
1313 "math"
14+ "path"
1415 "strconv"
1516 "strings"
1617 "unicode"
@@ -80,6 +81,8 @@ func setToOpaque(msg *protogen.Message) {
8081 }
8182}
8283
84+ const gamedataPackageName = "gamedata"
85+
8386// GenerateFile generates the contents of a .pb.go file.
8487//
8588// With the Hybrid API, multiple files are generated (_protoopaque.pb.go variant),
@@ -413,6 +416,9 @@ func genMessage(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
413416 leadingComments := appendDeprecationSuffix (m .Comments .Leading ,
414417 m .Desc .ParentFile (),
415418 m .Desc .Options ().(* descriptorpb.MessageOptions ).GetDeprecated ())
419+ if path .Base (string (m .GoIdent .GoImportPath )) == gamedataPackageName {
420+ g .P ("type " , m .GoIdent , "List []*" , m .GoIdent )
421+ }
416422 g .P (leadingComments ,
417423 "type " , m .GoIdent , " struct {" )
418424 genMessageFields (g , f , m )
@@ -485,6 +491,10 @@ func genMessageField(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, fie
485491 if pointer {
486492 goType = "*" + goType
487493 }
494+ // make gamedata list for findById
495+ if goType [:3 ] == "[]*" && path .Base (string (field .Message .GoIdent .GoImportPath )) == gamedataPackageName {
496+ goType = goType [3 :] + "List"
497+ }
488498 tags := structTags {
489499 {"protobuf" , fieldProtobufTagValue (field )},
490500 {"json" , fieldJSONTagValue (field )},
@@ -653,6 +663,26 @@ func genMessageGetterMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageI
653663 g .P ("return " , defaultValue )
654664 g .P ("}" )
655665 default :
666+ if field .GoName == "Id" && path .Base (string (m .GoIdent .GoImportPath )) == gamedataPackageName {
667+ g .P (leadingComments , "func (x " , m .GoIdent , "List) FindById (id " , goType , ") (*" , m .GoIdent , ", bool) {" )
668+ g .P ("for _, xx := range x {" )
669+ g .P ("if xx.Id == id {" )
670+ g .P ("return xx, true" )
671+ g .P ("}" )
672+ g .P ("}" )
673+ g .P ("return nil, false" )
674+ g .P ("}" )
675+ g .P ()
676+
677+ g .P (leadingComments , "func (x " , m .GoIdent , "List) Get (id " , goType , ") *" , m .GoIdent , "{" )
678+ g .P ("xx, ok := x.FindById(id)" )
679+ g .P ("if ok {" )
680+ g .P ("return xx" )
681+ g .P ("}" )
682+ g .P ("panic(\" Not exist: " , m .GoIdent , "\" )" )
683+ g .P ("}" )
684+ g .P ()
685+ }
656686 g .P (leadingComments , "func (x *" , m .GoIdent , ") Get" , field .GoName , "() " , goType , " {" )
657687 if ! field .Desc .HasPresence () || defaultValue == "nil" {
658688 g .P ("if x != nil {" )
@@ -833,11 +863,25 @@ func genMessageOneofWrapperTypes(g *protogen.GeneratedFile, f *fileInfo, m *mess
833863 if oneof .Desc .IsSynthetic () {
834864 continue
835865 }
866+
867+ typedTypeName := oneof .GoIdent .GoName + "Type"
868+ g .P ("type " , typedTypeName , " string" )
869+ g .P ()
870+
836871 ifName := oneofInterfaceName (oneof )
837872 g .P ("type " , ifName , " interface {" )
838873 g .P (ifName , "()" )
874+ g .P ("Type() " , typedTypeName )
839875 g .P ("}" )
840876 g .P ()
877+
878+ g .P ("const (" )
879+ for _ , field := range oneof .Fields {
880+ g .P (fmt .Sprintf ("%s_%s %s = \" %s\" " , typedTypeName , field .GoName , typedTypeName , field .GoIdent .GoName ))
881+ }
882+ g .P (")" )
883+ g .P ("" )
884+
841885 for _ , field := range oneof .Fields {
842886 g .AnnotateSymbol (field .GoIdent .GoName , protogen.Annotation {Location : field .Location })
843887 g .AnnotateSymbol (field .GoIdent .GoName + "." + field .GoName , protogen.Annotation {Location : field .Location })
@@ -857,10 +901,52 @@ func genMessageOneofWrapperTypes(g *protogen.GeneratedFile, f *fileInfo, m *mess
857901 trailingComment (field .Comments .Trailing ))
858902 g .P ("}" )
859903 g .P ()
904+
905+ ty , _ := fieldGoType (g , f , field )
906+ ty = strings .ReplaceAll (ty , "*" , "" )
907+ if field .Message != nil {
908+ params := make ([]string , len (field .Message .Fields ))
909+ noGen := false
910+ for i := 0 ; i < len (field .Message .Fields ); i ++ {
911+ curField := field .Message .Fields [i ]
912+ if curField .Oneof != nil {
913+ noGen = true
914+ break
915+ }
916+ params [i ] = makeParam (g , f , curField )
917+ }
918+ if noGen {
919+ continue
920+ }
921+ g .P (fmt .Sprintf ("func New%s%s (%s) *%s {" , m .GoIdent .GoName , field .GoName , strings .Join (params , "," ), m .GoIdent .GoName ))
922+ g .P (fmt .Sprintf ("return &%s {" , m .GoIdent .GoName ))
923+ g .P (fmt .Sprintf ("%s: &%s {" , field .Oneof .GoName , field .GoIdent .GoName ))
924+ g .P (fmt .Sprintf ("%s: &%s {" , field .GoName , ty ))
925+ for i := 0 ; i < len (field .Message .Fields ); i ++ {
926+ f := field .Message .Fields [i ]
927+ g .P (fmt .Sprintf ("%s: p%s," , f .GoName , f .GoName ))
928+ }
929+ g .P ("}," )
930+ g .P ("}," )
931+ g .P ("}" )
932+ g .P ("}" )
933+ } else {
934+ g .P (fmt .Sprintf ("func New%s%s (p %s) *%s {" , m .GoIdent .GoName , field .GoName , ty , m .GoIdent .GoName ))
935+ g .P (fmt .Sprintf ("return &%s {" , m .GoIdent .GoName ))
936+ g .P (fmt .Sprintf ("%s: &%s {" , field .Oneof .GoName , field .GoIdent .GoName ))
937+ g .P (fmt .Sprintf ("%s: p," , field .GoName ))
938+ g .P ("}," )
939+ g .P ("}" )
940+ g .P ("}" )
941+ }
942+ g .P ()
860943 }
861944 for _ , field := range oneof .Fields {
862945 g .P ("func (*" , field .GoIdent , ") " , ifName , "() {}" )
863946 g .P ()
947+
948+ g .P (fmt .Sprintf ("func (*%s) Type() %s { return \" %s\" }" , field .GoIdent .GoName , typedTypeName , field .GoIdent .GoName ))
949+ g .P ()
864950 }
865951 }
866952}
@@ -930,3 +1016,12 @@ func (c trailingComment) String() string {
9301016 }
9311017 return s
9321018}
1019+
1020+ func makeParam (g * protogen.GeneratedFile , f * fileInfo , field * protogen.Field ) string {
1021+ ty , isPtr := fieldGoType (g , f , field )
1022+ format := "p%s %s"
1023+ if isPtr {
1024+ format = "p%s *%s"
1025+ }
1026+ return fmt .Sprintf (format , field .GoName , ty )
1027+ }
0 commit comments