Documentation
¶
Index ¶
- Constants
- Variables
- func CodeGeneratorModelGong(modelPkg *models.ModelPkg, pkgName string, pkgPath string)
- func CodeGeneratorModelGongCoder(modelPkg *models.ModelPkg, pkgName string, pkgPath string)
- func CodeGeneratorModelGongEnum(modelPkg *models.ModelPkg, pkgName string, pkgPath string)
- func CodeGeneratorModelGongGraph(modelPkg *models.ModelPkg, pkgName string, pkgPath string)
- func CodeGeneratorModelGongMarshall(modelPkg *models.ModelPkg, pkgName string, pkgPath string)
- func CodeGeneratorModelGongSlice(modelPkg *models.ModelPkg, pkgName string, pkgPath string, pkgGoPath string)
- func CodeGeneratorModelGongWop(modelPkg *models.ModelPkg, pkgName string, pkgPath string)
- func GongAstGenerator(modelPkg *models.ModelPkg, pkgPath string)
- type GongFilePerStructSubTemplateId
- type GongGraphFilePerStructSubTemplateId
- type GongMarshallFilePerStructSubTemplateId
- type GongModelEnumValueSubTemplateId
- type GongSliceGongstructInsertionId
- type GongSliceSubTemplateId
- type GongWopSubSubTemplateInsertionsId
- type ModelGongAstFieldInsertionId
- type ModelGongAstStructInsertionId
- type ModelGongCallbacksStructInsertionId
- type ModelGongCoderFieldInsertionId
- type ModelGongCoderStructInsertionId
- type ModelGongEnumInsertionId
- type ModelGongGraphStructInsertionId
- type ModelGongMarshallStructInsertionId
- type ModelGongOrchestratorStructInsertionId
- type ModelGongSerializeStructInsertionId
- type ModelGongStructInsertionId
- type ModelGongWopStructInsertionId
Constants ¶
View Source
const DefaultModelDocsTemplate = `// Default generated models package docs
// (at least one file is necessary in a models package)
package models
`
View Source
const GongAstTemplate = `// generated code - do not edit package models import ( "bufio" "errors" "go/ast" "go/doc/comment" "go/parser" "go/token" "log" "os" "path/filepath" "regexp" "strconv" "strings" "time" ) var dummy_strconv_import strconv.NumError var dummy_time_import time.Time // swagger:ignore type GONG__ExpressionType string const ( GONG__STRUCT_INSTANCE GONG__ExpressionType = "STRUCT_INSTANCE" GONG__FIELD_OR_CONST_VALUE GONG__ExpressionType = "FIELD_OR_CONST_VALUE" GONG__FIELD_VALUE GONG__ExpressionType = "FIELD_VALUE" GONG__ENUM_CAST_INT GONG__ExpressionType = "ENUM_CAST_INT" GONG__ENUM_CAST_STRING GONG__ExpressionType = "ENUM_CAST_STRING" GONG__IDENTIFIER_CONST GONG__ExpressionType = "IDENTIFIER_CONST" ) // ParseAstFile Parse pathToFile and stages all instances // declared in the file func ParseAstFile(stage *StageStruct, pathToFile string) error { ReplaceOldDeclarationsInFile(pathToFile) fileOfInterest, err := filepath.Abs(pathToFile) if err != nil { return errors.New("Path does not exist %s ;" + fileOfInterest) } fset := token.NewFileSet() // startParser := time.Now() inFile, errParser := parser.ParseFile(fset, fileOfInterest, nil, parser.ParseComments) // log.Printf("Parser took %s", time.Since(startParser)) if errParser != nil { return errors.New("Unable to parser " + errParser.Error()) } return ParseAstFileFromAst(stage, inFile, fset) } // ParseAstFile Parse pathToFile and stages all instances // declared in the file func ParseAstFileFromAst(stage *StageStruct, inFile *ast.File, fset *token.FileSet) error { // if there is a meta package import, it is the third import if len(inFile.Imports) > 3 { log.Fatalln("Too many imports in file", inFile.Name) } if len(inFile.Imports) == 3 { stage.MetaPackageImportAlias = inFile.Imports[2].Name.Name stage.MetaPackageImportPath = inFile.Imports[2].Path.Value } // astCoordinate := "File " // log.Println(// astCoordinate) for _, decl := range inFile.Decls { switch decl := decl.(type) { case *ast.FuncDecl: funcDecl := decl // astCoordinate := // astCoordinate + "\tFunction " + funcDecl.Name.Name if name := funcDecl.Name; name != nil { isOfInterest := strings.Contains(funcDecl.Name.Name, "_") if !isOfInterest { continue } // log.Println(// astCoordinate) } if doc := funcDecl.Doc; doc != nil { // astCoordinate := // astCoordinate + "\tDoc" for _, comment := range doc.List { _ = comment // astCoordinate := // astCoordinate + "\tComment: " + comment.Text // log.Println(// astCoordinate) } } if body := funcDecl.Body; body != nil { // astCoordinate := // astCoordinate + "\tBody: " for _, stmt := range body.List { switch stmt := stmt.(type) { case *ast.ExprStmt: exprStmt := stmt // astCoordinate := // astCoordinate + "\tExprStmt: " switch expr := exprStmt.X.(type) { case *ast.CallExpr: // astCoordinate := // astCoordinate + "\tCallExpr: " callExpr := expr switch fun := callExpr.Fun.(type) { case *ast.Ident: ident := fun _ = ident // astCoordinate := // astCoordinate + "\tIdent: " + ident.Name // log.Println(// astCoordinate) } } case *ast.AssignStmt: // Create an ast.CommentMap from the ast.File's comments. // This helps keeping the association between comments // and AST nodes. cmap := ast.NewCommentMap(fset, inFile, inFile.Comments) astCoordinate := "\tAssignStmt: " // log.Println(// astCoordinate) assignStmt := stmt instance, id, gongstruct, fieldName := UnmarshallGongstructStaging( stage, &cmap, assignStmt, astCoordinate) _ = instance _ = id _ = gongstruct _ = fieldName } } } case *ast.GenDecl: genDecl := decl // log.Println("\tAST GenDecl: ") if doc := genDecl.Doc; doc != nil { for _, comment := range doc.List { _ = comment // log.Println("\tAST Comment: ", comment.Text) } } for _, spec := range genDecl.Specs { switch spec := spec.(type) { case *ast.ImportSpec: importSpec := spec if path := importSpec.Path; path != nil { // log.Println("\t\tAST Path: ", path.Value) } case *ast.ValueSpec: ident := spec.Names[0] _ = ident if !strings.HasPrefix(ident.Name, "_") { continue } // declaration of a variable without initial value if len(spec.Values) == 0 { continue } switch compLit := spec.Values[0].(type) { case *ast.CompositeLit: var key string _ = key var value string _ = value for _, elt := range compLit.Elts { // each elt is an expression for struct or for field such as // for struct // // "dummy.Dummy": &(dummy.Dummy{}) // // or, for field // // "dummy.Dummy.Name": (dummy.Dummy{}).Name, // // first node in the AST is a key value expression var ok bool var kve *ast.KeyValueExpr if kve, ok = elt.(*ast.KeyValueExpr); !ok { log.Fatal("Expression should be key value expression" + fset.Position(kve.Pos()).String()) } switch bl := kve.Key.(type) { case *ast.BasicLit: key = bl.Value // "\"dumm.Dummy\"" is the value // one remove the ambracing double quotes key = strings.TrimPrefix(key, "\"") key = strings.TrimSuffix(key, "\"") } var expressionType GONG__ExpressionType = GONG__STRUCT_INSTANCE var docLink GONG__Identifier var fieldName string var ue *ast.UnaryExpr if ue, ok = kve.Value.(*ast.UnaryExpr); !ok { expressionType = GONG__FIELD_OR_CONST_VALUE } var callExpr *ast.CallExpr if callExpr, ok = kve.Value.(*ast.CallExpr); ok { var se *ast.SelectorExpr if se, ok = callExpr.Fun.(*ast.SelectorExpr); !ok { log.Fatal("Expression should be a selector expression" + fset.Position(callExpr.Pos()).String()) } var id *ast.Ident if id, ok = se.X.(*ast.Ident); !ok { log.Fatal("Expression should be an ident" + fset.Position(se.Pos()).String()) } // check the arg type to select wether this is a int or a string enum var bl *ast.BasicLit if bl, ok = callExpr.Args[0].(*ast.BasicLit); ok { switch bl.Kind { case token.STRING: expressionType = GONG__ENUM_CAST_STRING case token.INT: expressionType = GONG__ENUM_CAST_INT } } else { log.Fatal("Expression should be a basic lit" + fset.Position(se.Pos()).String()) } docLink.Ident = id.Name + "." + se.Sel.Name _ = callExpr } var se2 *ast.SelectorExpr switch expressionType { case GONG__FIELD_OR_CONST_VALUE: if se2, ok = kve.Value.(*ast.SelectorExpr); ok { var ident *ast.Ident if _, ok = se2.X.(*ast.ParenExpr); ok { expressionType = GONG__FIELD_VALUE fieldName = se2.Sel.Name } else if ident, ok = se2.X.(*ast.Ident); ok { expressionType = GONG__IDENTIFIER_CONST docLink.Ident = ident.Name + "." + se2.Sel.Name } else { log.Fatal("Expression should be a selector expression or an ident" + fset.Position(kve.Pos()).String()) } } else { } } var pe *ast.ParenExpr switch expressionType { case GONG__STRUCT_INSTANCE: if pe, ok = ue.X.(*ast.ParenExpr); !ok { log.Fatal("Expression should be parenthese expression" + fset.Position(ue.Pos()).String()) } case GONG__FIELD_VALUE: if pe, ok = se2.X.(*ast.ParenExpr); !ok { log.Fatal("Expression should be parenthese expression" + fset.Position(ue.Pos()).String()) } } switch expressionType { case GONG__FIELD_VALUE, GONG__STRUCT_INSTANCE: // expect a Composite Litteral with no Element <type>{} var cl *ast.CompositeLit if cl, ok = pe.X.(*ast.CompositeLit); !ok { log.Fatal("Expression should be a composite lit" + fset.Position(pe.Pos()).String()) } var se *ast.SelectorExpr if se, ok = cl.Type.(*ast.SelectorExpr); !ok { log.Fatal("Expression should be a selector" + fset.Position(cl.Pos()).String()) } var id *ast.Ident if id, ok = se.X.(*ast.Ident); !ok { log.Fatal("Expression should be an ident" + fset.Position(se.Pos()).String()) } docLink.Ident = id.Name + "." + se.Sel.Name } switch expressionType { case GONG__FIELD_VALUE: docLink.Ident += "." + fieldName } // if map_DocLink_Identifier has the same ident, this means // that no renaming has occured since the last processing of the // file. But it is neccessary to keep it in memory for the // marshalling if docLink.Ident == key { // continue } // otherwise, one stores the new ident (after renaming) in the // renaming map docLink.Type = expressionType stage.Map_DocLink_Renaming[key] = docLink } } } } } } return nil } var __gong__map_Indentifiers_gongstructName = make(map[string]string) // insertion point for identifiers maps{{` + string(rune(ModelGongAstGenericMaps)) + `}} // Parser needs to be configured for having the [Name1.Name2] or [pkg.Name1] ... // to be recognized as a proper identifier. // While this was introduced in go 1.19, it is not yet implemented in // gopls (see [issue](https://github.com/golang/go/issues/57559) func lookupPackage(name string) (importPath string, ok bool) { return name, true } func lookupSym(recv, name string) (ok bool) { if recv == "" { return true } return false } // UnmarshallGoStaging unmarshall a go assign statement func UnmarshallGongstructStaging(stage *StageStruct, cmap *ast.CommentMap, assignStmt *ast.AssignStmt, astCoordinate_ string) ( instance any, identifier string, gongstructName string, fieldName string) { // used for debug purposes astCoordinate := "\tAssignStmt: " // // First parse all comment groups in the assignement // if a comment "//gong:ident [DocLink]" is met and is followed by a string assignement. // modify the following AST assignement to assigns the DocLink text to the string value // // get the comment group of the assigStmt commentGroups := (*cmap)[assignStmt] // get the the prefix var hasGongIdentDirective bool var commentText string var docLinkText string for _, commentGroup := range commentGroups { for _, comment := range commentGroup.List { if strings.HasPrefix(comment.Text, "//gong:ident") { hasGongIdentDirective = true commentText = comment.Text } } } if hasGongIdentDirective { // parser configured to find doclinks var docLinkFinder comment.Parser docLinkFinder.LookupPackage = lookupPackage docLinkFinder.LookupSym = lookupSym doc := docLinkFinder.Parse(commentText) for _, block := range doc.Content { switch paragraph := block.(type) { case *comment.Paragraph: _ = paragraph for _, text := range paragraph.Text { switch docLink := text.(type) { case *comment.DocLink: if docLink.Recv == "" { docLinkText = docLink.ImportPath + "." + docLink.Name } else { docLinkText = docLink.ImportPath + "." + docLink.Recv + "." + docLink.Name } // we check wether the doc link has been renamed // to be removed after fix of [issue](https://github.com/golang/go/issues/57559) if renamed, ok := (stage.Map_DocLink_Renaming)[docLinkText]; ok { docLinkText = renamed.Ident } } } } } } for rank, expr := range assignStmt.Lhs { if rank > 0 { continue } switch expr := expr.(type) { case *ast.Ident: // we are on a variable declaration ident := expr // astCoordinate := astCoordinate + "\tLhs" + "." + ident.Name // log.Println(astCoordinate) identifier = ident.Name case *ast.SelectorExpr: // we are on a variable assignement selectorExpr := expr // astCoordinate := astCoordinate + "\tLhs" + "." + selectorExpr.X.(*ast.Ident).Name + "." + selectorExpr.Sel.Name // log.Println(astCoordinate) identifier = selectorExpr.X.(*ast.Ident).Name fieldName = selectorExpr.Sel.Name } } for _, expr := range assignStmt.Rhs { // astCoordinate := astCoordinate + "\tRhs" switch expr := expr.(type) { case *ast.CallExpr: callExpr := expr // astCoordinate := astCoordinate + "\tFun" switch fun := callExpr.Fun.(type) { // the is Fun Expr // function expression xxx.Stage() case *ast.SelectorExpr: selectorExpr := fun // astCoordinate := astCoordinate + "\tSelectorExpr" switch x := selectorExpr.X.(type) { case *ast.ParenExpr: // A ParenExpr node represents a parenthesized expression. // the is the // { Name : "A1"} // astCoordinate := astCoordinate + "\tX" parenExpr := x switch x := parenExpr.X.(type) { case *ast.UnaryExpr: unaryExpr := x // astCoordinate := astCoordinate + "\tUnaryExpr" switch x := unaryExpr.X.(type) { case *ast.CompositeLit: instanceName := "NoName yet" compositeLit := x // astCoordinate := astCoordinate + "\tX(CompositeLit)" for _, elt := range compositeLit.Elts { // astCoordinate := astCoordinate + "\tElt" switch elt := elt.(type) { case *ast.KeyValueExpr: // This is expression // Name: "A1" keyValueExpr := elt // astCoordinate := astCoordinate + "\tKeyValueExpr" switch key := keyValueExpr.Key.(type) { case *ast.Ident: ident := key _ = ident // astCoordinate := astCoordinate + "\tKey" + "." + ident.Name // log.Println(astCoordinate) } switch value := keyValueExpr.Value.(type) { case *ast.BasicLit: basicLit := value // astCoordinate := astCoordinate + "\tBasicLit Value" + "." + basicLit.Value // log.Println(astCoordinate) instanceName = basicLit.Value // remove first and last char instanceName = instanceName[1 : len(instanceName)-1] } } } astCoordinate2 := astCoordinate + "\tType" _ = astCoordinate2 switch type_ := compositeLit.Type.(type) { case *ast.SelectorExpr: slcExpr := type_ // astCoordinate := astCoordinate2 + "\tSelectorExpr" switch X := slcExpr.X.(type) { case *ast.Ident: ident := X _ = ident // astCoordinate := astCoordinate + "\tX" + "." + ident.Name // log.Println(astCoordinate) } if Sel := slcExpr.Sel; Sel != nil { // astCoordinate := astCoordinate + "\tSel" + "." + Sel.Name // log.Println(astCoordinate) gongstructName = Sel.Name // this is the place where an instance is created switch gongstructName { // insertion point for identifiers{{` + string(rune(ModelGongAstStageProcessing)) + `}} } __gong__map_Indentifiers_gongstructName[identifier] = gongstructName return } } } } } if sel := selectorExpr.Sel; sel != nil { // astCoordinate := astCoordinate + "\tSel" + "." + sel.Name // log.Println(astCoordinate) } for iteration, arg := range callExpr.Args { // astCoordinate := astCoordinate + "\tArg" switch arg := arg.(type) { case *ast.BasicLit: basicLit := arg // astCoordinate := astCoordinate + "\tBasicLit" + "." + basicLit.Value // log.Println(astCoordinate) // first iteration should be ignored if iteration == 0 { continue } // remove first and last char date := basicLit.Value[1 : len(basicLit.Value)-1] _ = date var ok bool gongstructName, ok = __gong__map_Indentifiers_gongstructName[identifier] if !ok { log.Fatalln("gongstructName not found for identifier", identifier) } switch gongstructName { // insertion point for basic lit assignments{{` + string(rune(ModelGongAstDateAssignment)) + `}} } } } case *ast.Ident: // append function ident := fun _ = ident // astCoordinate := astCoordinate + "\tIdent" + "." + ident.Name // log.Println(astCoordinate) } for _, arg := range callExpr.Args { // astCoordinate := astCoordinate + "\tArg" switch arg := arg.(type) { case *ast.Ident: ident := arg _ = ident // astCoordinate := astCoordinate + "\tIdent" + "." + ident.Name // log.Println(astCoordinate) var ok bool gongstructName, ok = __gong__map_Indentifiers_gongstructName[identifier] if !ok { log.Fatalln("gongstructName not found for identifier", identifier) } switch gongstructName { // insertion point for slice of pointers assignments{{` + string(rune(ModelGongAstSliceOfPointersAssignment)) + `}} } case *ast.SelectorExpr: slcExpr := arg // astCoordinate := astCoordinate + "\tSelectorExpr" switch X := slcExpr.X.(type) { case *ast.Ident: ident := X _ = ident // astCoordinate := astCoordinate + "\tX" + "." + ident.Name // log.Println(astCoordinate) } if Sel := slcExpr.Sel; Sel != nil { // astCoordinate := astCoordinate + "\tSel" + "." + Sel.Name // log.Println(astCoordinate) } } } case *ast.BasicLit, *ast.UnaryExpr: var basicLit *ast.BasicLit var exprSign = 1.0 _ = exprSign // in case this is not used if bl, ok := expr.(*ast.BasicLit); ok { // expression is for instance ... = 18.000 basicLit = bl } else if ue, ok := expr.(*ast.UnaryExpr); ok { // expression is for instance ... = -18.000 // we want to extract a *ast.BasicLit from the *ast.UnaryExpr basicLit = ue.X.(*ast.BasicLit) exprSign = -1 } // astCoordinate := astCoordinate + "\tBasicLit" + "." + basicLit.Value // log.Println(astCoordinate) var ok bool gongstructName, ok = __gong__map_Indentifiers_gongstructName[identifier] if !ok { log.Fatalln("gongstructName not found for identifier", identifier) } // substitute the RHS part of the assignment if a //gong:ident directive is met if hasGongIdentDirective { basicLit.Value = "[" + docLinkText + "]" } switch gongstructName { // insertion point for basic lit assignments{{` + string(rune(ModelGongAstBasicLitAssignment)) + `}} } case *ast.Ident: // assignment to boolean field ? ident := expr _ = ident // astCoordinate := astCoordinate + "\tIdent" + "." + ident.Name // log.Println(astCoordinate) var ok bool gongstructName, ok = __gong__map_Indentifiers_gongstructName[identifier] if !ok { log.Fatalln("gongstructName not found for identifier", identifier) } switch gongstructName { // insertion point for bool & pointers assignments{{` + string(rune(ModelGongAstIdentBooleanAndPointerAssignment)) + `}} } case *ast.SelectorExpr: // assignment to enum field selectorExpr := expr // astCoordinate := astCoordinate + "\tSelectorExpr" switch X := selectorExpr.X.(type) { case *ast.Ident: ident := X _ = ident // astCoordinate := astCoordinate + "\tX" + "." + ident.Name // log.Println(astCoordinate) } if Sel := selectorExpr.Sel; Sel != nil { // astCoordinate := astCoordinate + "\tSel" + "." + Sel.Name // log.Println(astCoordinate) // enum field var ok bool gongstructName, ok = __gong__map_Indentifiers_gongstructName[identifier] if !ok { log.Fatalln("gongstructName not found for identifier", identifier) } // remove first and last char enumValue := Sel.Name _ = enumValue switch gongstructName { // insertion point for enums assignments{{` + string(rune(ModelGongAstIdentEnumAssignment)) + `}} } } } } return } // ReplaceOldDeclarationsInFile replaces specific text in a file at the given path. func ReplaceOldDeclarationsInFile(pathToFile string) error { // Open the file for reading. file, err := os.Open(pathToFile) if err != nil { return err } defer file.Close() // replacing function with Injection pattern := regexp.MustCompile(` + "`" + `\b\w*Injection\b` + "`" + `) pattern2 := regexp.MustCompile(` + "`" + `\bmap_DocLink_Identifier_\w*\b` + "`" + `) // Temporary slice to hold lines from the file. var lines []string scanner := bufio.NewScanner(file) for scanner.Scan() { // Replace the target text with the desired text. line := strings.Replace(scanner.Text(), "var ___dummy__Time_stage time.Time", "var _ time.Time", -1) line = pattern.ReplaceAllString(line, "_") line = pattern2.ReplaceAllString(line, "_") lines = append(lines, line) } if err := scanner.Err(); err != nil { return err } // Re-open the file for writing. file, err = os.Create(pathToFile) if err != nil { return err } defer file.Close() // Write the modified lines back to the file. writer := bufio.NewWriter(file) for _, line := range lines { _, err := writer.WriteString(line + "\n") if err != nil { return err } } return writer.Flush() } `
View Source
const GongSliceTemplate = `// generated code - do not edit package models // ComputeReverseMaps computes the reverse map, for all intances, for all slice to pointers field // Its complexity is in O(n)O(p) where p is the number of pointers func (stage *StageStruct) ComputeReverseMaps() { // insertion point per named struct{{` + string(rune(GongSliceReverseMapCompute)) + `}} } `
View Source
const ModelGongCallbacksFileTemplate = `// generated code - do not edit package models // AfterCreateFromFront is called after a create from front func AfterCreateFromFront[Type Gongstruct](stage *StageStruct, instance *Type) { switch target := any(instance).(type) { // insertion point{{` + string(rune(ModelGongCallbacksCreate)) + `}} default: _ = target } } // AfterUpdateFromFront is called after a update from front func AfterUpdateFromFront[Type Gongstruct](stage *StageStruct, old, new *Type) { switch oldTarget := any(old).(type) { // insertion point{{` + string(rune(ModelGongCallbacksUpdate)) + `}} default: _ = oldTarget } } // AfterDeleteFromFront is called after a delete from front func AfterDeleteFromFront[Type Gongstruct](stage *StageStruct, staged, front *Type) { switch front := any(front).(type) { // insertion point{{` + string(rune(ModelGongCallbacksDelete)) + `}} default: _ = front } } // AfterReadFromFront is called after a Read from front func AfterReadFromFront[Type Gongstruct](stage *StageStruct, instance *Type) { switch target := any(instance).(type) { // insertion point{{` + string(rune(ModelGongCallbacksRead)) + `}} default: _ = target } } // SetCallbackAfterUpdateFromFront is a function to set up callback that is robust to refactoring func SetCallbackAfterUpdateFromFront[Type Gongstruct](stage *StageStruct, callback OnAfterUpdateInterface[Type]) { var instance Type switch any(instance).(type) { // insertion point{{` + string(rune(ModelGongCallbacksSetFuncUpdate)) + `}} } } func SetCallbackAfterCreateFromFront[Type Gongstruct](stage *StageStruct, callback OnAfterCreateInterface[Type]) { var instance Type switch any(instance).(type) { // insertion point{{` + string(rune(ModelGongCallbacksSetFuncCreate)) + `}} } } func SetCallbackAfterDeleteFromFront[Type Gongstruct](stage *StageStruct, callback OnAfterDeleteInterface[Type]) { var instance Type switch any(instance).(type) { // insertion point{{` + string(rune(ModelGongCallbacksSetFuncDelete)) + `}} } } func SetCallbackAfterReadFromFront[Type Gongstruct](stage *StageStruct, callback OnAfterReadInterface[Type]) { var instance Type switch any(instance).(type) { // insertion point{{` + string(rune(ModelGongCallbacksSetFuncRead)) + `}} } } `
View Source
const ModelGongCoderFileTemplate = `// generated code - do not edit package models import "time" // GongfieldCoder return an instance of Type where each field // encodes the index of the field // // This allows for refactorable field names // func GongfieldCoder[Type Gongstruct]() Type { var t Type switch any(t).(type) { // insertion point for cases{{` + string(rune(ModelGongCoderGenericGongstructCoder)) + `}} default: return t } } type Gongfield interface { string | bool | int | float64 | time.Time | time.Duration{{` + string(rune(ModelGongCoderGenericGongstructTypes)) + `}} } // GongfieldName provides the name of the field by passing the instance of the coder to // the fonction. // // This allows for refactorable field name // // fieldCoder := models.GongfieldCoder[models.Astruct]() // log.Println( models.GongfieldName[*models.Astruct](fieldCoder.Name)) // log.Println( models.GongfieldName[*models.Astruct](fieldCoder.Booleanfield)) // log.Println( models.GongfieldName[*models.Astruct](fieldCoder.Intfield)) // log.Println( models.GongfieldName[*models.Astruct](fieldCoder.Floatfield)) // // limitations: // 1. cannot encode boolean fields // 2. for associations (pointer to gongstruct or slice of pointer to gongstruct, uses GetAssociationName) func GongfieldName[Type PointerToGongstruct, FieldType Gongfield](field FieldType) string { var t Type switch any(t).(type) { // insertion point for cases{{` + string(rune(ModelGongCoderGenericGongstructNamerString)) + `}} default: return "" } _ = field return "" } `
View Source
const ModelGongEnumFileTemplate = `// generated code - do not edit package models // insertion point of enum utility functions{{` + string(rune(ModelGongEnumUtilityFunctions)) + `}} // end of insertion point for enum utility functions type GongstructEnumStringField interface { Codes() []string CodeValues() []string ToString() string } type PointerToGongstructEnumStringField interface { FromCodeString(input string) (err error) } type GongstructEnumIntField interface { int{{` + string(rune(ModelGongStructInsertionGenericEnumIntTypes)) + `}} Codes() []string CodeValues() []int } type PointerToGongstructEnumIntField interface { {{` + string(rune(ModelGongStructInsertionGenericPointerToEnumIntTypes)) + `}} FromCodeString(input string) (err error) } // Last line of the template `
View Source
const ModelGongFileTemplate = `// generated code - do not edit package models import ( "cmp" "errors" "fmt" "math" "slices" "time" ) func __Gong__Abs(x int) int { if x < 0 { return -x } return x } // errUnkownEnum is returns when a value cannot match enum values var errUnkownEnum = errors.New("unkown enum") // needed to avoid when fmt package is not needed by generated code var __dummy__fmt_variable fmt.Scanner // idem for math package when not need by generated code var __dummy_math_variable = math.E // swagger:ignore type __void any // needed for creating set of instances in the stage var __member __void // GongStructInterface is the interface met by GongStructs // It allows runtime reflexion of instances (without the hassle of the "reflect" package) type GongStructInterface interface { GetName() (res string) // GetID() (res int) // GetFields() (res []string) // GetFieldStringValue(fieldName string) (res string) } // StageStruct enables storage of staged instances // swagger:ignore type StageStruct struct { path string // insertion point for definition of arrays registering instances{{` + string(rune(ModelGongStructInsertionArrayDefintion)) + `}} AllModelsStructCreateCallback AllModelsStructCreateInterface AllModelsStructDeleteCallback AllModelsStructDeleteInterface BackRepo BackRepoInterface // if set will be called before each commit to the back repo OnInitCommitCallback OnInitCommitInterface OnInitCommitFromFrontCallback OnInitCommitInterface OnInitCommitFromBackCallback OnInitCommitInterface // store the number of instance per gongstruct Map_GongStructName_InstancesNb map[string]int // store meta package import MetaPackageImportPath string MetaPackageImportAlias string // to be removed after fix of [issue](https://github.com/golang/go/issues/57559) // map to enable docLink renaming when an identifier is renamed Map_DocLink_Renaming map[string]GONG__Identifier // the to be removed stops here } func (stage *StageStruct) GetType() string { return "{{PkgPathRoot}}/models" } type GONG__Identifier struct { Ident string Type GONG__ExpressionType } type OnInitCommitInterface interface { BeforeCommit(stage *StageStruct) } // OnAfterCreateInterface callback when an instance is updated from the front type OnAfterCreateInterface[Type Gongstruct] interface { OnAfterCreate(stage *StageStruct, instance *Type) } // OnAfterReadInterface callback when an instance is updated from the front type OnAfterReadInterface[Type Gongstruct] interface { OnAfterRead(stage *StageStruct, instance *Type) } // OnAfterUpdateInterface callback when an instance is updated from the front type OnAfterUpdateInterface[Type Gongstruct] interface { OnAfterUpdate(stage *StageStruct, old, new *Type) } // OnAfterDeleteInterface callback when an instance is updated from the front type OnAfterDeleteInterface[Type Gongstruct] interface { OnAfterDelete(stage *StageStruct, staged, front *Type) } type BackRepoInterface interface { Commit(stage *StageStruct) Checkout(stage *StageStruct) Backup(stage *StageStruct, dirPath string) Restore(stage *StageStruct, dirPath string) BackupXL(stage *StageStruct, dirPath string) RestoreXL(stage *StageStruct, dirPath string) // insertion point for Commit and Checkout signatures{{` + string(rune(ModelGongStructInsertionCommitCheckout)) + `}} GetLastCommitFromBackNb() uint GetLastPushFromFrontNb() uint } func NewStage(path string) (stage *StageStruct) { stage = &StageStruct{ // insertion point for array initiatialisation{{` + string(rune(ModelGongStructInsertionArrayInitialisation)) + `}} // end of insertion point Map_GongStructName_InstancesNb: make(map[string]int), path: path, // to be removed after fix of [issue](https://github.com/golang/go/issues/57559) Map_DocLink_Renaming: make(map[string]GONG__Identifier), // the to be removed stops here } return } func (stage *StageStruct) GetPath() string { return stage.path } func (stage *StageStruct) CommitWithSuspendedCallbacks() { tmp := stage.OnInitCommitFromBackCallback stage.OnInitCommitFromBackCallback = nil stage.Commit() stage.OnInitCommitFromBackCallback = tmp } func (stage *StageStruct) Commit() { stage.ComputeReverseMaps() if stage.BackRepo != nil { stage.BackRepo.Commit(stage) } // insertion point for computing the map of number of instances per gongstruct{{` + string(rune(ModelGongStructInsertionComputeNbInstances)) + `}} } func (stage *StageStruct) Checkout() { if stage.BackRepo != nil { stage.BackRepo.Checkout(stage) } stage.ComputeReverseMaps() // insertion point for computing the map of number of instances per gongstruct{{` + string(rune(ModelGongStructInsertionComputeNbInstances)) + `}} } // backup generates backup files in the dirPath func (stage *StageStruct) Backup(dirPath string) { if stage.BackRepo != nil { stage.BackRepo.Backup(stage, dirPath) } } // Restore resets Stage & BackRepo and restores their content from the restore files in dirPath func (stage *StageStruct) Restore(dirPath string) { if stage.BackRepo != nil { stage.BackRepo.Restore(stage, dirPath) } } // backup generates backup files in the dirPath func (stage *StageStruct) BackupXL(dirPath string) { if stage.BackRepo != nil { stage.BackRepo.BackupXL(stage, dirPath) } } // Restore resets Stage & BackRepo and restores their content from the restore files in dirPath func (stage *StageStruct) RestoreXL(dirPath string) { if stage.BackRepo != nil { stage.BackRepo.RestoreXL(stage, dirPath) } } // insertion point for cumulative sub template with model space calls{{` + string(rune(ModelGongStructInsertionStageFunctions)) + `}} // swagger:ignore type AllModelsStructCreateInterface interface { // insertion point for Callbacks on creation{{` + string(rune(ModelGongStructInsertionCreateCallback)) + `}} } type AllModelsStructDeleteInterface interface { // insertion point for Callbacks on deletion{{` + string(rune(ModelGongStructInsertionDeleteCallback)) + `}} } func (stage *StageStruct) Reset() { // insertion point for array reset{{` + string(rune(ModelGongStructInsertionArrayReset)) + `}} } func (stage *StageStruct) Nil() { // insertion point for array nil{{` + string(rune(ModelGongStructInsertionArrayNil)) + `}} } func (stage *StageStruct) Unstage() { // insertion point for array nil{{` + string(rune(ModelGongStructInsertionArrayUnstage)) + `}} } // Gongstruct is the type parameter for generated generic function that allows // - access to staged instances // - navigation between staged instances by going backward association links between gongstruct // - full refactoring of Gongstruct identifiers / fields type Gongstruct interface { } type GongtructBasicField interface { int | float64 | bool | string | time.Time | time.Duration } // Gongstruct is the type parameter for generated generic function that allows // - access to staged instances // - navigation between staged instances by going backward association links between gongstruct // - full refactoring of Gongstruct identifiers / fields type PointerToGongstruct interface { GetName() string CommitVoid(*StageStruct) UnstageVoid(stage *StageStruct) comparable } func CompareGongstructByName[T PointerToGongstruct](a, b T) int { return cmp.Compare(a.GetName(), b.GetName()) } func SortGongstructSetByName[T PointerToGongstruct](set map[T]any) (sortedSlice []T) { for key := range set { sortedSlice = append(sortedSlice, key) } slices.SortFunc(sortedSlice, CompareGongstructByName) return } func GetGongstrucsSorted[T PointerToGongstruct](stage *StageStruct) (sortedSlice []T) { set := GetGongstructInstancesSetFromPointerType[T](stage) sortedSlice = SortGongstructSetByName(*set) return } type GongstructSet interface { map[any]any } type GongstructMapString interface { map[any]any } // GongGetSet returns the set staged GongstructType instances // it is usefull because it allows refactoring of gong struct identifier func GongGetSet[Type GongstructSet](stage *StageStruct) *Type { var ret Type switch any(ret).(type) { // insertion point for generic get functions{{` + string(rune(ModelGongStructInsertionGenericGetSetFunctions)) + `}} default: return nil } } // GongGetMap returns the map of staged GongstructType instances // it is usefull because it allows refactoring of gong struct identifier func GongGetMap[Type GongstructMapString](stage *StageStruct) *Type { var ret Type switch any(ret).(type) { // insertion point for generic get functions{{` + string(rune(ModelGongStructInsertionGenericGetMapFunctions)) + `}} default: return nil } } // GetGongstructInstancesSet returns the set staged GongstructType instances // it is usefull because it allows refactoring of gongstruct identifier func GetGongstructInstancesSet[Type Gongstruct](stage *StageStruct) *map[*Type]any { var ret Type switch any(ret).(type) { // insertion point for generic get functions{{` + string(rune(ModelGongStructInsertionGenericInstancesSetFunctions)) + `}} default: return nil } } // GetGongstructInstancesSetFromPointerType returns the set staged GongstructType instances // it is usefull because it allows refactoring of gongstruct identifier func GetGongstructInstancesSetFromPointerType[Type PointerToGongstruct](stage *StageStruct) {{mapReturnType}} { var ret Type switch any(ret).(type) { // insertion point for generic get functions{{` + string(rune(ModelGongStructInsertionGenericInstancesSetFromPointerTypeFunctions)) + `}} default: return nil } } // GetGongstructInstancesMap returns the map of staged GongstructType instances // it is usefull because it allows refactoring of gong struct identifier func GetGongstructInstancesMap[Type Gongstruct](stage *StageStruct) *map[string]*Type { var ret Type switch any(ret).(type) { // insertion point for generic get functions{{` + string(rune(ModelGongStructInsertionGenericInstancesMapFunctions)) + `}} default: return nil } } // GetAssociationName is a generic function that returns an instance of Type // where each association is filled with an instance whose name is the name of the association // // This function can be handy for generating navigation function that are refactorable func GetAssociationName[Type Gongstruct]() *Type { var ret Type switch any(ret).(type) { // insertion point for instance with special fields{{` + string(rune(ModelGongStructInsertionGenericGetAssociationNameFunctions)) + `}} default: return nil } } // GetPointerReverseMap allows backtrack navigation of any Start.Fieldname // associations (0..1) that is a pointer from one staged Gongstruct (type Start) // instances to another (type End) // // The function provides a map with keys as instances of End and values to arrays of *Start // the map is construed by iterating over all Start instances and populationg keys with End instances // and values with slice of Start instances func GetPointerReverseMap[Start, End Gongstruct](fieldname string, stage *StageStruct) map[*End][]*Start { var ret Start switch any(ret).(type) { // insertion point of functions that provide maps for reverse associations{{` + string(rune(ModelGongStructInsertionGenericReversePointerAssociationsMaps)) + `}} } return nil } // GetSliceOfPointersReverseMap allows backtrack navigation of any Start.Fieldname // associations (0..N) between one staged Gongstruct instances and many others // // The function provides a map with keys as instances of End and values to *Start instances // the map is construed by iterating over all Start instances and populating keys with End instances // and values with the Start instances func GetSliceOfPointersReverseMap[Start, End Gongstruct](fieldname string, stage *StageStruct) map[*End]*Start { var ret Start switch any(ret).(type) { // insertion point of functions that provide maps for reverse associations{{` + string(rune(ModelGongStructInsertionGenericReverseSliceOfPointersAssociationsMaps)) + `}} } return nil } // GetGongstructName returns the name of the Gongstruct // this can be usefull if one want program robust to refactoring func GetGongstructName[Type Gongstruct]() (res string) { var ret Type switch any(ret).(type) { // insertion point for generic get gongstruct name{{` + string(rune(ModelGongStructInsertionGenericGongstructName)) + `}} } return res } // GetPointerToGongstructName returns the name of the Gongstruct // this can be usefull if one want program robust to refactoring func GetPointerToGongstructName[Type PointerToGongstruct]() (res string) { var ret Type switch any(ret).(type) { // insertion point for generic get gongstruct name{{` + string(rune(ModelGongStructInsertionGenericPointerToGongstructName)) + `}} } return res } // GetFields return the array of the fields func GetFields[Type Gongstruct]() (res []string) { var ret Type switch any(ret).(type) { // insertion point for generic get gongstruct name{{` + string(rune(ModelGongStructInsertionGenericGetFields)) + `}} } return } type ReverseField struct { GongstructName string Fieldname string } func GetReverseFields[Type Gongstruct]() (res []ReverseField) { res = make([]ReverseField, 0) var ret Type switch any(ret).(type) { // insertion point for generic get gongstruct name{{` + string(rune(ModelGongStructInsertionGenericGetReverseFields)) + `}} } return } // GetFieldsFromPointer return the array of the fields func GetFieldsFromPointer[Type PointerToGongstruct]() (res []string) { var ret Type switch any(ret).(type) { // insertion point for generic get gongstruct name{{` + string(rune(ModelGongStructInsertionGenericGetFieldsFromPointer)) + `}} } return } type GongFieldValueType string const ( GongFieldValueTypeInt GongFieldValueType = "GongFieldValueTypeInt" GongFieldValueTypeFloat GongFieldValueType = "GongFieldValueTypeFloat" GongFieldValueTypeBool GongFieldValueType = "GongFieldValueTypeBool" GongFieldValueTypeOthers GongFieldValueType = "GongFieldValueTypeOthers" ) type GongFieldValue struct { valueString string GongFieldValueType valueInt int valueFloat float64 valueBool bool } func (gongValueField *GongFieldValue) GetValueString() string { return gongValueField.valueString } func (gongValueField *GongFieldValue) GetValueInt() int { return gongValueField.valueInt } func (gongValueField *GongFieldValue) GetValueFloat() float64 { return gongValueField.valueFloat } func (gongValueField *GongFieldValue) GetValueBool() bool { return gongValueField.valueBool } func GetFieldStringValueFromPointer(instance any, fieldName string) (res GongFieldValue) { switch inferedInstance := any(instance).(type) { // insertion point for generic get gongstruct field value{{` + string(rune(ModelGongStructInsertionGenericGetFieldValuesFromPointer)) + `}} default: _ = inferedInstance } return } func GetFieldStringValue(instance any, fieldName string) (res GongFieldValue) { switch inferedInstance := any(instance).(type) { // insertion point for generic get gongstruct field value{{` + string(rune(ModelGongStructInsertionGenericGetFieldValues)) + `}} default: _ = inferedInstance } return } // Last line of the template `
View Source
const ModelGongGraphFileTemplate = `// generated code - do not edit package models func IsStaged[Type Gongstruct](stage *StageStruct, instance *Type) (ok bool) { switch target := any(instance).(type) { // insertion point for stage{{` + string(rune(ModelGongGraphStructInsertionIsStaged)) + `}} default: _ = target } return } // insertion point for stage per struct{{` + string(rune(ModelGongGraphStructInsertionIsStagedPerStruct)) + `}} // StageBranch stages instance and apply StageBranch on all gongstruct instances that are // referenced by pointers or slices of pointers of the instance // // the algorithm stops along the course of graph if a vertex is already staged func StageBranch[Type Gongstruct](stage *StageStruct, instance *Type) { switch target := any(instance).(type) { // insertion point for stage branch{{` + string(rune(ModelGongGraphStructInsertionStageBranch)) + `}} default: _ = target } } // insertion point for stage branch per struct{{` + string(rune(ModelGongGraphStructInsertionStageBranchPerStruct)) + `}} // CopyBranch stages instance and apply CopyBranch on all gongstruct instances that are // referenced by pointers or slices of pointers of the instance // // the algorithm stops along the course of graph if a vertex is already staged func CopyBranch[Type Gongstruct](from *Type) (to *Type) { mapOrigCopy := make(map[any]any) _ = mapOrigCopy switch fromT := any(from).(type) { // insertion point for stage branch{{` + string(rune(ModelGongGraphStructInsertionCopyBranch)) + `}} default: _ = fromT // to espace compilation issue when model is empty } return } // insertion point for stage branch per struct{{` + string(rune(ModelGongGraphStructInsertionCopyBranchPerStruct)) + `}} // UnstageBranch stages instance and apply UnstageBranch on all gongstruct instances that are // referenced by pointers or slices of pointers of the insance // // the algorithm stops along the course of graph if a vertex is already staged func UnstageBranch[Type Gongstruct](stage *StageStruct, instance *Type) { switch target := any(instance).(type) { // insertion point for unstage branch{{` + string(rune(ModelGongGraphStructInsertionUnstageBranch)) + `}} default: _ = target } } // insertion point for unstage branch per struct{{` + string(rune(ModelGongGraphStructInsertionUnstageBranchPerStruct)) + `}}`
View Source
const ModelGongMarshallFileTemplate = `// generated code - do not edit package models import ( "fmt" "log" "os" "path/filepath" "regexp" "sort" "strings" ) const marshallRes = ` + "`" + `package {{PackageName}} import ( "time" "{{ModelsPackageName}}" // injection point for ident package import declaration{{ImportPackageDeclaration}} ) // generated in order to avoid error in the package import // if there are no elements in the stage to marshall var _ time.Time // _ point for meta package dummy declaration{{ImportPackageDummyDeclaration}} // When parsed, those maps will help with the renaming process var _ map[string]any = map[string]any{ // injection point for docLink to identifiers{{EntriesDocLinkStringDocLinkIdentifier}} } // function will stage objects func _(stage *models.StageStruct) { // Declaration of instances to stage{{Identifiers}} // Setup of values{{ValueInitializers}} // Setup of pointers{{PointersInitializers}} }` + "`" + ` const IdentifiersDecls = ` + "`" + ` {{Identifier}} := (&models.{{GeneratedStructName}}{}).Stage(stage)` + "`" + ` const StringInitStatement = ` + "`" + ` {{Identifier}}.{{GeneratedFieldName}} = ` + "`" + " + \"" + "`" + `"` + ` + ` + "`" + `{{GeneratedFieldNameValue}}` + "`" + ` + "` + "`" + `"` + ` const StringEnumInitStatement = ` + "`" + ` {{Identifier}}.{{GeneratedFieldName}} = {{GeneratedFieldNameValue}}` + "`" + ` const NumberInitStatement = ` + "`" + ` {{Identifier}}.{{GeneratedFieldName}} = {{GeneratedFieldNameValue}}` + "`" + ` const PointerFieldInitStatement = ` + "`" + ` {{Identifier}}.{{GeneratedFieldName}} = {{GeneratedFieldNameValue}}` + "`" + ` const SliceOfPointersFieldInitStatement = ` + "`" + ` {{Identifier}}.{{GeneratedFieldName}} = append({{Identifier}}.{{GeneratedFieldName}}, {{GeneratedFieldNameValue}})` + "`" + ` const TimeInitStatement = ` + "`" + ` {{Identifier}}.{{GeneratedFieldName}}, _ = time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", "{{GeneratedFieldNameValue}}")` + "`" + ` // Marshall marshall the stage content into the file as an instanciation into a stage func (stage *StageStruct) Marshall(file *os.File, modelsPackageName, packageName string) { name := file.Name() if !strings.HasSuffix(name, ".go") { log.Fatalln(name + " is not a go filename") } log.Println("filename of marshall output is " + name) newBase := filepath.Base(file.Name()) res := marshallRes res = strings.ReplaceAll(res, "{{databaseName}}", strings.ReplaceAll(newBase, ".go", "")) res = strings.ReplaceAll(res, "{{PackageName}}", packageName) res = strings.ReplaceAll(res, "{{ModelsPackageName}}", modelsPackageName) // map of identifiers // var StageMapDstructIds map[*Dstruct]string identifiersDecl := "" initializerStatements := "" pointersInitializesStatements := "" id := "" _ = id decl := "" _ = decl setValueField := "" _ = setValueField // insertion initialization of objects to stage{{` + string(rune(ModelGongMarshallStructInsertionUnmarshallDeclarations)) + `}} // insertion initialization of objects to stage{{` + string(rune(ModelGongMarshallStructInsertionUnmarshallPointersInitializations)) + `}} res = strings.ReplaceAll(res, "{{Identifiers}}", identifiersDecl) res = strings.ReplaceAll(res, "{{ValueInitializers}}", initializerStatements) res = strings.ReplaceAll(res, "{{PointersInitializers}}", pointersInitializesStatements) if stage.MetaPackageImportAlias != "" { res = strings.ReplaceAll(res, "{{ImportPackageDeclaration}}", fmt.Sprintf("\n\t%s %s", stage.MetaPackageImportAlias, stage.MetaPackageImportPath)) res = strings.ReplaceAll(res, "{{ImportPackageDummyDeclaration}}", fmt.Sprintf("\nvar _ %s.StageStruct", stage.MetaPackageImportAlias)) var entries string // regenerate the map of doc link renaming // the key and value are set to the value because // if it has been renamed, this is the new value that matters valuesOrdered := make([]GONG__Identifier, 0) for _, value := range stage.Map_DocLink_Renaming { valuesOrdered = append(valuesOrdered, value) } sort.Slice(valuesOrdered[:], func(i, j int) bool { return valuesOrdered[i].Ident < valuesOrdered[j].Ident }) for _, value := range valuesOrdered { // get the number of points in the value to find if it is a field // or a struct switch value.Type { case GONG__ENUM_CAST_INT: entries += fmt.Sprintf("\n\n\t\"%s\": %s(0),", value.Ident, value.Ident) case GONG__ENUM_CAST_STRING: entries += fmt.Sprintf("\n\n\t\"%s\": %s(\"\"),", value.Ident, value.Ident) case GONG__FIELD_VALUE: // substitute the second point with "{})." joker := "__substitute_for_first_point__" valueIdentifier := strings.Replace(value.Ident, ".", joker, 1) valueIdentifier = strings.Replace(valueIdentifier, ".", "{}).", 1) valueIdentifier = strings.Replace(valueIdentifier, joker, ".", 1) entries += fmt.Sprintf("\n\n\t\"%s\": (%s,", value.Ident, valueIdentifier) case GONG__IDENTIFIER_CONST: entries += fmt.Sprintf("\n\n\t\"%s\": %s,", value.Ident, value.Ident) case GONG__STRUCT_INSTANCE: entries += fmt.Sprintf("\n\n\t\"%s\": &(%s{}),", value.Ident, value.Ident) } } // res = strings.ReplaceAll(res, "{{EntriesDocLinkStringDocLinkIdentifier}}", entries) } fmt.Fprintln(file, res) } // unique identifier per struct func generatesIdentifier(gongStructName string, idx int, instanceName string) (identifier string) { identifier = instanceName // Make a Regex to say we only want letters and numbers reg, err := regexp.Compile("[^a-zA-Z0-9]+") if err != nil { log.Fatal(err) } processedString := reg.ReplaceAllString(instanceName, "_") identifier = fmt.Sprintf("__%s__%06d_%s", gongStructName, idx, processedString) return } `
View Source
const ModelGongOrchestratorFileTemplate = `// generated code - do not edit package models // insertion point{{` + string(rune(ModelGongOrchestratorStruct)) + `}} func SetOrchestratorOnAfterUpdate[Type Gongstruct](stage *StageStruct) { var ret Type switch any(ret).(type) { // insertion point{{` + string(rune(ModelGongOrchestratorSwitch)) + `}} } } `
View Source
const ModelGongSerializeFileTemplate = `// generated code - do not edit package models import ( "cmp" "fmt" "log" "slices" "unicode/utf8" "github.com/xuri/excelize/v2" ) func SerializeStage(stage *StageStruct, filename string) { f := excelize.NewFile() { // insertion point{{` + string(rune(ModelGongSerializeStruct)) + `}} } // Create a style with wrap text enabled wrapStyle, err := f.NewStyle(&excelize.Style{ Alignment: &excelize.Alignment{ WrapText: true, }, }) _ = wrapStyle if err != nil { fmt.Println("failed to create style:", err) return } // Create a style with bold text boldStyle, err := f.NewStyle(&excelize.Style{ Font: &excelize.Font{ Bold: true, }, }) _ = boldStyle if err != nil { fmt.Println("failed to create bold style:", err) return } // Get all sheet names sheetList := f.GetSheetList() for _, sheet := range sheetList { // Read all rows of the current sheet rows, err := f.GetRows(sheet) if err != nil { fmt.Printf("failed to get rows for sheet %q: %v\n", sheet, err) continue } // If there's no data at all, skip this sheet if len(rows) == 0 { continue } // The first row of the sheet firstRow := rows[0] // Track the first and last “used” column in the first row, // so we can later apply an AutoFilter from the first to last used col var firstUsedColIdx, lastUsedColIdx int for colIdx, cellValue := range firstRow { if cellValue == "" { // Skip columns with empty first-row cells continue } // Convert zero-based colIdx to 1-based for Excelize, // then get the column name (A, B, C, etc.) colName, err := excelize.ColumnNumberToName(colIdx + 1) if err != nil { fmt.Printf("failed to convert column number: %v\n", err) continue } // Apply wrap-text style to this entire column colRange := colName + ":" + colName if err := f.SetColStyle(sheet, colRange, wrapStyle); err != nil { fmt.Printf("failed to set col style on %s: %v\n", colRange, err) continue } // Make the first row (cell in row 1) bold in this column cellRef := fmt.Sprintf("%s1", colName) if err := f.SetCellStyle(sheet, cellRef, cellRef, boldStyle); err != nil { fmt.Printf("failed to set cell style on %s: %v\n", cellRef, err) continue } // Update our “first used” and “last used” column indices if firstUsedColIdx == 0 { firstUsedColIdx = colIdx + 1 } if colIdx+1 > lastUsedColIdx { lastUsedColIdx = colIdx + 1 } } // If we found at least one non-empty column in row 1, enable AutoFilter if firstUsedColIdx != 0 && lastUsedColIdx >= firstUsedColIdx { startCol, _ := excelize.ColumnNumberToName(firstUsedColIdx) endCol, _ := excelize.ColumnNumberToName(lastUsedColIdx) styleRange := fmt.Sprintf("%s:%s", startCol, endCol) autoFilterRange := fmt.Sprintf("%s1:%s1", startCol, endCol) startCellString := fmt.Sprintf("%s1", startCol) endCellString := fmt.Sprintf("%s1", endCol) if err := f.SetColStyle(sheet, styleRange, wrapStyle); err != nil { fmt.Println("failed to set column style:", err) return } // Apply the bold style to the first row (A1:XFD1) if err := f.SetCellStyle(sheet, startCellString, endCellString, boldStyle); err != nil { fmt.Println("failed to set bold style:", err) return } var opts []excelize.AutoFilterOptions if err := f.AutoFilter(sheet, autoFilterRange, opts); err != nil { fmt.Printf("failed to enable auto filter on range %s: %v\n", autoFilterRange, err) } } } var tab ExcelizeTabulator tab.SetExcelizeFile(f) { f.DeleteSheet("Sheet1") if err := f.SaveAs(filename); err != nil { fmt.Println("cannot write xl file : ", err) } } } // Tabulator is an interface for writing to a table strings type Tabulator interface { AddSheet(sheetName string) AddRow(sheetName string) int AddCell(sheetName string, rowId, columnIndex int, value string) } func Serialize[Type Gongstruct](stage *StageStruct, tab Tabulator) { sheetName := GetGongstructName[Type]() // Create a new sheet. tab.AddSheet(sheetName) headerRowIndex := tab.AddRow(sheetName) for colIndex, fieldName := range GetFields[Type]() { tab.AddCell(sheetName, headerRowIndex, colIndex, fieldName) // f.SetCellStr(sheetName, fmt.Sprintf("%s%d", IntToLetters(int32(index+1)), line), fieldName) } set := *GetGongstructInstancesSet[Type](stage) for instance := range set { line := tab.AddRow(sheetName) for index, fieldName := range GetFields[Type]() { tab.AddCell(sheetName, line, index, GetFieldStringValue( any(*instance).(Type), fieldName).valueString) // f.SetCellStr(sheetName, fmt.Sprintf("%s%d", IntToLetters(int32(index+1)), line), GetFieldStringValue( // any(*instance).(Type), fieldName)) } } } type ExcelizeTabulator struct { f *excelize.File } func (tab *ExcelizeTabulator) SetExcelizeFile(f *excelize.File) { tab.f = f } func (tab *ExcelizeTabulator) AddSheet(sheetName string) { } func (tab *ExcelizeTabulator) AddRow(sheetName string) (rowId int) { return } func (tab *ExcelizeTabulator) AddCell(sheetName string, rowId, columnIndex int, value string) { } func SerializeExcelizePointerToGongstruct[Type PointerToGongstruct](stage *StageStruct, f *excelize.File) { sheetName := GetPointerToGongstructName[Type]() // Create a new sheet. f.NewSheet(sheetName) set := *GetGongstructInstancesSetFromPointerType[Type](stage) var sortedSlice []Type for key := range set { sortedSlice = append(sortedSlice, key) } slices.SortFunc(sortedSlice, func(a, b Type) int { return cmp.Compare(a.GetName(), b.GetName()) }) line := 1 for index, fieldName := range GetFieldsFromPointer[Type]() { f.SetCellStr(sheetName, fmt.Sprintf("%s%d", IntToLetters(int32(index+1)), line), fieldName) } f.AutoFilter(sheetName, fmt.Sprintf("%s%d", IntToLetters(int32(1)), line), []excelize.AutoFilterOptions{}) for _, instance := range sortedSlice { line = line + 1 for index, fieldName := range GetFieldsFromPointer[Type]() { fieldStringValue := GetFieldStringValueFromPointer(instance, fieldName) f.SetCellStr(sheetName, fmt.Sprintf("%s%d", IntToLetters(int32(index+1)), line), fieldStringValue.GetValueString()) } } // Autofit all columns according to their text content cols, err := f.GetCols(sheetName) if err != nil { log.Panicln("SerializeExcelize") } for idx, col := range cols { largestWidth := 0 for _, rowCell := range col { cellWidth := utf8.RuneCountInString(rowCell) + 2 // + 2 for margin if cellWidth > largestWidth { largestWidth = cellWidth } } name, err := excelize.ColumnNumberToName(idx + 1) if err != nil { log.Panicln("SerializeExcelize") } f.SetColWidth(sheetName, name, name, float64(largestWidth)) } } func SerializeExcelize[Type Gongstruct](stage *StageStruct, f *excelize.File) { sheetName := GetGongstructName[Type]() // Create a new sheet. f.NewSheet(sheetName) set := *GetGongstructInstancesSet[Type](stage) line := 1 for index, fieldName := range GetFields[Type]() { f.SetCellStr(sheetName, fmt.Sprintf("%s%d", IntToLetters(int32(index+1)), line), fieldName) } f.AutoFilter(sheetName, fmt.Sprintf("%s%d", IntToLetters(int32(1)), line), []excelize.AutoFilterOptions{}) for instance := range set { line = line + 1 for index, fieldName := range GetFields[Type]() { fieldStringValue := GetFieldStringValue(any(*instance).(Type), fieldName) f.SetCellStr(sheetName, fmt.Sprintf("%s%d", IntToLetters(int32(index+1)), line), fieldStringValue.GetValueString()) } } // Autofit all columns according to their text content cols, err := f.GetCols(sheetName) if err != nil { log.Panicln("SerializeExcelize") } for idx, col := range cols { largestWidth := 0 for _, rowCell := range col { cellWidth := utf8.RuneCountInString(rowCell) + 2 // + 2 for margin if cellWidth > largestWidth { largestWidth = cellWidth } } name, err := excelize.ColumnNumberToName(idx + 1) if err != nil { log.Panicln("SerializeExcelize") } f.SetColWidth(sheetName, name, name, float64(largestWidth)) } } func IntToLetters(number int32) (letters string) { number-- if firstLetter := number / 26; firstLetter > 0 { letters += IntToLetters(firstLetter) letters += string('A' + number%26) } else { letters += string('A' + number) } return } `
View Source
const ModelGongWopFileTemplate = `// generated code - do not edit package models import "time" // to avoid compile error if no time field is present var __GONG_time_The_fool_doth_think_he_is_wise__ = time.Hour // insertion point{{` + string(rune(ModelGongWopStruct)) + `}} `
Variables ¶
View Source
var GongFileFieldFieldSubTemplateCode map[GongFilePerStructSubTemplateId]string = map[GongFilePerStructSubTemplateId]string{ GongFileFieldSubTmplStringFieldName: `"{{FieldName}}"`, GongFileFieldSubTmplReverseField: ` rf.GongstructName = "{{AssocStructName}}" rf.Fieldname = "{{FieldName}}" res = append(res, rf)`, GongFileFieldSubTmplStringValueBasicFieldBool: ` case "{{FieldName}}": res.valueString = fmt.Sprintf("%t", inferedInstance.{{FieldName}}) res.valueBool = inferedInstance.{{FieldName}} res.GongFieldValueType = GongFieldValueTypeBool`, GongFileFieldSubTmplStringValueBasicFieldInt: ` case "{{FieldName}}": res.valueString = fmt.Sprintf("%d", inferedInstance.{{FieldName}}) res.valueInt = inferedInstance.{{FieldName}} res.GongFieldValueType = GongFieldValueTypeInt`, GongFileFieldSubTmplStringValueBasicFieldIntDuration: ` case "{{FieldName}}": if math.Abs(inferedInstance.{{FieldName}}.Hours()) >= 24 { days := __Gong__Abs(int(int(inferedInstance.{{FieldName}}.Hours()) / 24)) months := int(days / 31) days = days - months*31 remainingHours := int(inferedInstance.{{FieldName}}.Hours()) % 24 remainingMinutes := int(inferedInstance.{{FieldName}}.Minutes()) % 60 remainingSeconds := int(inferedInstance.{{FieldName}}.Seconds()) % 60 if inferedInstance.{{FieldName}}.Hours() < 0 { res.valueString = "- " } if months > 0 { if months > 1 { res.valueString = res.valueString + fmt.Sprintf("%d months", months) } else { res.valueString = res.valueString + fmt.Sprintf("%d month", months) } } if days > 0 { if months != 0 { res.valueString = res.valueString + ", " } if days > 1 { res.valueString = res.valueString + fmt.Sprintf("%d days", days) } else { res.valueString = res.valueString + fmt.Sprintf("%d day", days) } } if remainingHours != 0 || remainingMinutes != 0 || remainingSeconds != 0 { if days != 0 || (days == 0 && months != 0) { res.valueString = res.valueString + ", " } res.valueString = res.valueString + fmt.Sprintf("%d hours, %d minutes, %d seconds\n", remainingHours, remainingMinutes, remainingSeconds) } } else { res.valueString = fmt.Sprintf("%s\n", inferedInstance.{{FieldName}}.String()) }`, GongFileFieldSubTmplStringValueBasicFieldEnumString: ` case "{{FieldName}}": enum := inferedInstance.{{FieldName}} res.valueString = enum.ToCodeString()`, GongFileFieldSubTmplStringValueBasicFieldEnumInt: ` case "{{FieldName}}": enum := inferedInstance.{{FieldName}} res.valueString = enum.ToCodeString()`, GongFileFieldSubTmplStringValueBasicFieldFloat64: ` case "{{FieldName}}": res.valueString = fmt.Sprintf("%f", inferedInstance.{{FieldName}}) res.valueFloat = inferedInstance.{{FieldName}} res.GongFieldValueType = GongFieldValueTypeFloat`, GongFileFieldSubTmplStringValueBasicFieldString: ` case "{{FieldName}}": res.valueString = inferedInstance.{{FieldName}}`, GongFileFieldSubTmplStringValueTimeField: ` case "{{FieldName}}": res.valueString = inferedInstance.{{FieldName}}.String()`, GongFileFieldSubTmplStringValueTimeFieldBespokeFormat: ` case "{{FieldName}}": res.valueString = inferedInstance.{{FieldName}}.Format("{{TimeFormat}}")`, GongFileFieldSubTmplStringValuePointerField: ` case "{{FieldName}}": if inferedInstance.{{FieldName}} != nil { res.valueString = inferedInstance.{{FieldName}}.Name }`, GongFileFieldSubTmplStringValueSliceOfPointersField: ` case "{{FieldName}}": for idx, __instance__ := range inferedInstance.{{FieldName}} { if idx > 0 { res.valueString += "\n" } res.valueString += __instance__.Name }`, GongFileFieldSubTmplAssociationNamePointerField: ` // field is initialized with an instance of {{AssocStructName}} with the name of the field {{FieldName}}: &{{AssocStructName}}{Name: "{{FieldName}}"},`, GongFileFieldSubTmplAssociationNameSliceOfPointersField: ` // field is initialized with an instance of {{AssocStructName}} with the name of the field {{FieldName}}: []*{{AssocStructName}}{{Name: "{{FieldName}}"}},`, GongFileFieldSubTmplAssociationPromotedNamePointerField: ` // field is initialized with an instance of {{AssocStructName}} with the name of the field {{FieldName}}: &{{AssocStructName}}{{{CompositeAssocStructName}}: {{CompositeAssocStructName}}{Name: "{{FieldName}}"}},`, GongFileFieldSubTmplAssociationPromotedNameSliceOfPointersField: ` // field is initialized with an instance of {{AssocStructName}} with the name of the field {{FieldName}}: []*{{AssocStructName}}{{{{CompositeAssocStructName}}: {{CompositeAssocStructName}}{Name: "{{FieldName}}"}}},`, GongFileFieldSubTmplAssociationNameEnclosingCompositePointerField: ` // field is initialized with {{AssocCompositeStructName}} problem with composites `, GongFileFieldSubTmplAssociationNameCompositePointerField: ` // {{FieldName}}: &{{AssocStructName}}{Name: "{{FieldName}}"},`, GongFileFieldSubTmplPointerFieldPointerAssociationMapFunction: ` case "{{FieldName}}": res := make(map[*{{AssocStructName}}][]*{{Structname}}) for {{structname}} := range stage.{{Structname}}s { if {{structname}}.{{FieldName}} != nil { {{assocstructname}}_ := {{structname}}.{{FieldName}} var {{structname}}s []*{{Structname}} _, ok := res[{{assocstructname}}_] if ok { {{structname}}s = res[{{assocstructname}}_] } else { {{structname}}s = make([]*{{Structname}}, 0) } {{structname}}s = append({{structname}}s, {{structname}}) res[{{assocstructname}}_] = {{structname}}s } } return any(res).(map[*End][]*Start)`, GongFileSliceOfPointersReverseMap: ` {{Structname}}_{{FieldName}}_reverseMap map[*{{AssocStructName}}]*{{Structname}} `, GongFileFieldSubTmplPointerFieldSliceOfPointersAssociationMapFunction: ` case "{{FieldName}}": res := make(map[*{{AssocStructName}}]*{{Structname}}) for {{structname}} := range stage.{{Structname}}s { for _, {{assocstructname}}_ := range {{structname}}.{{FieldName}} { res[{{assocstructname}}_] = {{structname}} } } return any(res).(map[*End]*Start)`, }
for each sub template code, there is the sub template code
View Source
var GongGraphFileFieldFieldSubTemplateCode map[GongGraphFilePerStructSubTemplateId]string = map[GongGraphFilePerStructSubTemplateId]string{ GongGraphFileFieldSubTmplStagePointerField: ` if {{structname}}.{{FieldName}} != nil { StageBranch(stage, {{structname}}.{{FieldName}}) }`, GongGraphFileFieldSubTmplStageSliceOfPointersField: ` for _, _{{assocstructname}} := range {{structname}}.{{FieldName}} { StageBranch(stage, _{{assocstructname}}) }`, GongGraphFileFieldSubTmplCopyPointerField: ` if {{structname}}From.{{FieldName}} != nil { {{structname}}To.{{FieldName}} = CopyBranch{{AssocStructName}}(mapOrigCopy, {{structname}}From.{{FieldName}}) }`, GongGraphFileFieldSubTmplCopyPointerFieldAndStop: ` if {{structname}}From.{{FieldName}} != nil { {{structname}}To.{{FieldName}} = {{structname}}From.{{FieldName}} }`, GongGraphFileFieldSubTmplCopySliceOfPointersField: ` for _, _{{assocstructname}} := range {{structname}}From.{{FieldName}} { {{structname}}To.{{FieldName}} = append({{structname}}To.{{FieldName}}, CopyBranch{{AssocStructName}}(mapOrigCopy, _{{assocstructname}})) }`, GongGraphFileFieldSubTmplUnstagePointerField: ` if {{structname}}.{{FieldName}} != nil { UnstageBranch(stage, {{structname}}.{{FieldName}}) }`, GongGraphFileFieldSubTmplUnstageSliceOfPointersField: ` for _, _{{assocstructname}} := range {{structname}}.{{FieldName}} { UnstageBranch(stage, _{{assocstructname}}) }`, }
View Source
var GongMarshallFileFieldFieldSubTemplateCode map[GongMarshallFilePerStructSubTemplateId]string = map[GongMarshallFilePerStructSubTemplateId]string{ GongMarshallFileFieldSubTmplSetBasicFieldBool: ` setValueField = NumberInitStatement setValueField = strings.ReplaceAll(setValueField, "{{Identifier}}", id) setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldName}}", "{{FieldName}}") setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldNameValue}}", fmt.Sprintf("%t", {{structname}}.{{FieldName}})) initializerStatements += setValueField `, GongMarshallFileFieldSubTmplSetTimeField: ` setValueField = TimeInitStatement setValueField = strings.ReplaceAll(setValueField, "{{Identifier}}", id) setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldName}}", "{{FieldName}}") setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldNameValue}}", {{structname}}.{{FieldName}}.String()) initializerStatements += setValueField `, GongMarshallFileFieldSubTmplSetBasicFieldInt: ` setValueField = NumberInitStatement setValueField = strings.ReplaceAll(setValueField, "{{Identifier}}", id) setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldName}}", "{{FieldName}}") setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldNameValue}}", fmt.Sprintf("%d", {{structname}}.{{FieldName}})) initializerStatements += setValueField `, GongMarshallFileFieldSubTmplSetBasicFieldEnumString: ` if {{structname}}.{{FieldName}} != "" { setValueField = StringEnumInitStatement setValueField = strings.ReplaceAll(setValueField, "{{Identifier}}", id) setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldName}}", "{{FieldName}}") setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldNameValue}}", "models."+{{structname}}.{{FieldName}}.ToCodeString()) initializerStatements += setValueField } `, GongMarshallFileFieldSubTmplSetBasicFieldEnumInt: ` setValueField = NumberInitStatement setValueField = strings.ReplaceAll(setValueField, "{{Identifier}}", id) setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldName}}", "{{FieldName}}") setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldNameValue}}", "models."+{{structname}}.{{FieldName}}.ToCodeString()) initializerStatements += setValueField `, GongMarshallFileFieldSubTmplSetBasicFieldFloat64: ` setValueField = NumberInitStatement setValueField = strings.ReplaceAll(setValueField, "{{Identifier}}", id) setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldName}}", "{{FieldName}}") setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldNameValue}}", fmt.Sprintf("%f", {{structname}}.{{FieldName}})) initializerStatements += setValueField `, GongMarshallFileFieldSubTmplSetBasicFieldString: ` setValueField = StringInitStatement setValueField = strings.ReplaceAll(setValueField, "{{Identifier}}", id) setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldName}}", "{{FieldName}}") setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldNameValue}}", string({{structname}}.{{FieldName}})) initializerStatements += setValueField `, GongMarshallFileFieldSubTmplSetBasicFieldStringDocLink: ` setValueField = StringInitStatement setValueField = strings.ReplaceAll(setValueField, "\n\t{{Identifier}}", fmt.Sprintf("\n\n\t//gong:ident [%s] comment added to overcome the problem with the comment map association\n\t{{Identifier}}", string({{structname}}.{{FieldName}}))) setValueField = strings.ReplaceAll(setValueField, "{{Identifier}}", id) setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldName}}", "{{FieldName}}") setValueField = strings.ReplaceAll(setValueField, "{{GeneratedFieldNameValue}}", string({{structname}}.{{FieldName}})) initializerStatements += setValueField `, GongMarshallFileFieldSubTmplSetPointerField: ` if {{structname}}.{{FieldName}} != nil { setPointerField = PointerFieldInitStatement setPointerField = strings.ReplaceAll(setPointerField, "{{Identifier}}", id) setPointerField = strings.ReplaceAll(setPointerField, "{{GeneratedFieldName}}", "{{FieldName}}") setPointerField = strings.ReplaceAll(setPointerField, "{{GeneratedFieldNameValue}}", map_{{AssocStructName}}_Identifiers[{{structname}}.{{FieldName}}]) pointersInitializesStatements += setPointerField } `, GongMarshallFileFieldSubTmplSetSliceOfPointersField: ` for _, _{{assocstructname}} := range {{structname}}.{{FieldName}} { setPointerField = SliceOfPointersFieldInitStatement setPointerField = strings.ReplaceAll(setPointerField, "{{Identifier}}", id) setPointerField = strings.ReplaceAll(setPointerField, "{{GeneratedFieldName}}", "{{FieldName}}") setPointerField = strings.ReplaceAll(setPointerField, "{{GeneratedFieldNameValue}}", map_{{AssocStructName}}_Identifiers[_{{assocstructname}}]) pointersInitializesStatements += setPointerField } `, }
View Source
var GongModelEnumValueSubTemplateCode map[GongModelEnumValueSubTemplateId]string = map[GongModelEnumValueSubTemplateId]string{ GongModelEnumValueFromString: ` case {{GongEnumValue}}: *{{enumName}} = {{GongEnumCode}} return`, GongModelEnumValueFromCodeString: ` case "{{GongEnumCode}}": *{{enumName}} = {{GongEnumCode}}`, GongModelEnumValueToString: ` case {{GongEnumCode}}: res = {{GongEnumValue}}`, GongModelEnumValueToCodeString: ` case {{GongEnumCode}}: res = "{{GongEnumCode}}"`, GongModelEnumCodes: ` res = append(res, "{{GongEnumCode}}")`, GongModelEnumCodeValues: ` res = append(res, {{GongEnumValue}})`, }
View Source
var GongSliceFileFieldFieldSubTemplateCode map[GongSliceSubTemplateId]string = map[GongSliceSubTemplateId]string{ GongSliceSubTmplSliceOfPointersToStruct: ` if fieldName == "{{FieldName}}" { // walk all instances of the owning type for _instance := range *GetGongstructInstancesSetFromPointerType[OwningType](stage) { if any(_instance).(*{{Structname}}) != owningInstanceInfered { _inferedTypeInstance := any(_instance).(*{{Structname}}) reference := make([]FieldType, 0) targetFieldSlice := any(_inferedTypeInstance.{{FieldName}}).([]FieldType) copy(targetFieldSlice, reference) _inferedTypeInstance.{{FieldName}} = _inferedTypeInstance.{{FieldName}}[0:] for _, fieldInstance := range reference { if _, ok := setOfFieldInstances[any(fieldInstance).(FieldType)]; !ok { _inferedTypeInstance.{{FieldName}} = append(_inferedTypeInstance.{{FieldName}}, any(fieldInstance).(*{{AssociationStructName}})) } } } } }`, GongSliceSubTmplSliceOfPointersReverseMapComputation: ` clear(stage.{{Structname}}_{{FieldNameForReverseMapField}}_reverseMap) stage.{{Structname}}_{{FieldNameForReverseMapField}}_reverseMap = make(map[*{{AssociationStructName}}]*{{Structname}}) for {{structname}} := range stage.{{Structname}}s { _ = {{structname}} for _, _{{associationStructName}} := range {{structname}}.{{FieldName}} { stage.{{Structname}}_{{FieldNameForReverseMapField}}_reverseMap[_{{associationStructName}}] = {{structname}} } }`, }
View Source
var GongSliceGongstructSubTemplateCode map[GongSliceGongstructInsertionId]string = map[GongSliceGongstructInsertionId]string{ GongSliceCase: ` case *{{Structname}}: // insertion point per field{{perFieldCode}} `, GongSliceReverseMapCompute: ` // Compute reverse map for named struct {{Structname}} // insertion point per field{{sliceOfPointerFieldReverseMapComputationCode}} `, }
View Source
var GongWopSubSubTemplate map[GongWopSubSubTemplateInsertionsId]string = map[GongWopSubSubTemplateInsertionsId]string{ GongWopBasicFieldDecl: `{{DeclarationPrefixPrologue}} {{FieldName}} {{BasicKindName}}{{DeclarationPrefixEpilogue}}`, GongWopEnumFieldDecl: `{{DeclarationPrefixPrologue}} {{FieldName}} {{EnumType}}{{DeclarationPrefixEpilogue}}`, GongWopTimeFieldDecl: `{{DeclarationPrefixPrologue}} {{FieldName}} time.Time{{DeclarationPrefixEpilogue}}`, GongWopDurationFieldDecl: `{{DeclarationPrefixPrologue}} {{FieldName}} time.Duration{{DeclarationPrefixEpilogue}}`, GongWopBasicFieldCopy: ` to.{{FieldName}} = from.{{FieldName}}`, }
View Source
var ModelGongAstFieldSubTemplateCode map[ModelGongAstFieldInsertionId]string = map[ModelGongAstFieldInsertionId]string{ ModelGongAstFieldAssignString: ` case "{{FieldName}}": // remove first and last char fielValue := basicLit.Value[1 : len(basicLit.Value)-1] __gong__map_{{Structname}}[identifier].{{FieldName}} = fielValue`, ModelGongAstFieldAssignInt: ` case "{{FieldName}}": // convert string to int fielValue, err := strconv.ParseInt(basicLit.Value, 10, 64) if err != nil { log.Fatalln(err) } __gong__map_{{Structname}}[identifier].{{FieldName}} = int(exprSign) * int(fielValue)`, ModelGongAstFieldAssignDuration: ` case "{{FieldName}}": // convert string to duration fielValue, err := strconv.ParseInt(basicLit.Value, 10, 64) if err != nil { log.Fatalln(err) } __gong__map_{{Structname}}[identifier].{{FieldName}} = time.Duration(int(exprSign) * int(fielValue))`, ModelGongAstFieldAssignFloat64: ` case "{{FieldName}}": // convert string to float64 fielValue, err := strconv.ParseFloat(basicLit.Value, 64) if err != nil { log.Fatalln(err) } __gong__map_{{Structname}}[identifier].{{FieldName}} = exprSign * fielValue`, ModelGongAstFieldAssignBoolean: ` case "{{FieldName}}": // convert string to boolean fielValue, err := strconv.ParseBool(ident.Name) if err != nil { log.Fatalln(err) } __gong__map_{{Structname}}[identifier].{{FieldName}} = fielValue`, ModelGongAstFieldAssignPointer: ` case "{{FieldName}}": targetIdentifier := ident.Name __gong__map_{{Structname}}[identifier].{{FieldName}} = __gong__map_{{AssociationStructName}}[targetIdentifier]`, ModelGongAstFieldAssignEnum: ` case "{{FieldName}}": var val {{EnumType}} err := (&val).FromCodeString(enumValue) if err != nil { log.Fatalln(err) } __gong__map_{{Structname}}[identifier].{{FieldName}} = {{EnumType}}(val)`, ModelGongAstFieldAssignDate: ` case "{{FieldName}}": __gong__map_{{Structname}}[identifier].{{FieldName}}, _ = time.Parse( "2006-01-02 15:04:05.999999999 -0700 MST", date)`, ModelGongAstFieldAssignSliceOfPointers: ` case "{{FieldName}}": // remove first and last char targetIdentifier := ident.Name target := __gong__map_{{AssociationStructName}}[targetIdentifier] __gong__map_{{Structname}}[identifier].{{FieldName}} = append(__gong__map_{{Structname}}[identifier].{{FieldName}}, target)`, }
View Source
var ModelGongAstStructSubTemplateCode map[ModelGongAstStructInsertionId]string = map[ModelGongAstStructInsertionId]string{ ModelGongAstGenericMaps: ` var __gong__map_{{Structname}} = make(map[string]*{{Structname}})`, ModelGongAstStageProcessing: ` case "{{Structname}}": instance{{Structname}} := new({{Structname}}) instance{{Structname}}.Name = instanceName instance{{Structname}}.Stage(stage) instance = any(instance{{Structname}}) __gong__map_{{Structname}}[identifier] = instance{{Structname}}`, ModelGongAstBasicLitAssignment: ` case "{{Structname}}": switch fieldName { // insertion point for field dependant code{{basicLitAssignCode}} }`, ModelGongAstIdentBooleanAndPointerAssignment: ` case "{{Structname}}": switch fieldName { // insertion point for field dependant code{{boolAndPointerAssignCode}} }`, ModelGongAstIdentEnumAssignment: ` case "{{Structname}}": switch fieldName { // insertion point for enum assign code{{enumAssignCode}} }`, ModelGongAstDateAssignment: ` case "{{Structname}}": switch fieldName { // insertion point for date assign code{{dateAssignCode}} }`, ModelGongAstSliceOfPointersAssignment: ` case "{{Structname}}": switch fieldName { // insertion point for slice of pointers assign code{{sliceOfPointersAssignCode}} }`, }
View Source
var ModelGongCallbacksStructSubTemplateCode map[string]string = map[string]string{ string(rune(ModelGongCallbacksCreate)): ` case *{{Structname}}: if stage.OnAfter{{Structname}}CreateCallback != nil { stage.OnAfter{{Structname}}CreateCallback.OnAfterCreate(stage, target) }`, string(rune(ModelGongCallbacksUpdate)): ` case *{{Structname}}: newTarget := any(new).(*{{Structname}}) if stage.OnAfter{{Structname}}UpdateCallback != nil { stage.OnAfter{{Structname}}UpdateCallback.OnAfterUpdate(stage, oldTarget, newTarget) }`, string(rune(ModelGongCallbacksRead)): ` case *{{Structname}}: if stage.OnAfter{{Structname}}ReadCallback != nil { stage.OnAfter{{Structname}}ReadCallback.OnAfterRead(stage, target) }`, string(rune(ModelGongCallbacksDelete)): ` case *{{Structname}}: if stage.OnAfter{{Structname}}DeleteCallback != nil { staged := any(staged).(*{{Structname}}) stage.OnAfter{{Structname}}DeleteCallback.OnAfterDelete(stage, staged, front) }`, string(rune(ModelGongCallbacksSetFuncCreate)): ` case *{{Structname}}: stage.OnAfter{{Structname}}CreateCallback = any(callback).(OnAfterCreateInterface[{{Structname}}]) `, string(rune(ModelGongCallbacksSetFuncUpdate)): ` case *{{Structname}}: stage.OnAfter{{Structname}}UpdateCallback = any(callback).(OnAfterUpdateInterface[{{Structname}}]) `, string(rune(ModelGongCallbacksSetFuncRead)): ` case *{{Structname}}: stage.OnAfter{{Structname}}ReadCallback = any(callback).(OnAfterReadInterface[{{Structname}}]) `, string(rune(ModelGongCallbacksSetFuncDelete)): ` case *{{Structname}}: stage.OnAfter{{Structname}}DeleteCallback = any(callback).(OnAfterDeleteInterface[{{Structname}}]) `, }
View Source
var ModelGongCoderFieldSubTemplateCode map[ModelGongCoderFieldInsertionId]string = map[ModelGongCoderFieldInsertionId]string{ ModelGongCoderFieldCodeString: ` fieldCoder.{{FieldName}} = "{{Value}}"`, ModelGongCoderFieldCodeInt: ` fieldCoder.{{FieldName}} = {{Value}}`, ModelGongCoderFieldCodeFloat64: ` fieldCoder.{{FieldName}} = {{Value}}`, ModelGongCoderFieldCodeDate: ` fieldCoder.{{FieldName}} = time.Date({{Value}}, time.January, 0, 0, 0, 0, 0, time.UTC)`, ModelGongCoderFieldCodeBoolean: ` fieldCoder.{{FieldName}} = {{Value}}`, ModelGongCoderFieldNameString: ` if field == "{{Value}}" { return "{{FieldName}}" }`, ModelGongCoderFieldNameInt: ` if field == {{Value}} { return "{{FieldName}}" }`, ModelGongCoderFieldNameFloat64: ` if field == {{Value}} { return "{{FieldName}}" }`, ModelGongCoderFieldNameDate: ` if field == time.Date({{Value}}, time.January, 0, 0, 0, 0, 0, time.UTC) { return "{{FieldName}}" }`, ModelGongCoderFieldNameBoolean: ` if field == {{Value}} { return "{{FieldName}}" }`, }
View Source
var ModelGongCoderStructSubTemplateCode map[ModelGongCoderStructInsertionId]string = map[ModelGongCoderStructInsertionId]string{ ModelGongCoderGenericGongstructTypes: ` | *{{Structname}} | []*{{Structname}}`, ModelGongCoderGenericGongstructCoder: ` case {{Structname}}: fieldCoder := {{Structname}}{} // insertion point for field dependant code{{FieldCode}} return (any)(fieldCoder).(Type)`, ModelGongCoderGenericGongstructNamerString: ` case *{{Structname}}: switch field := any(field).(type) { case string: // insertion point for field dependant name{{FieldNameString}} case int, int64: // insertion point for field dependant name{{FieldNameInt}} case float64: // insertion point for field dependant name{{FieldNameFloat64}} case time.Time: // insertion point for field dependant name{{FieldNameDate}} case bool: // insertion point for field dependant name{{FieldNameBoolean}} }`, }
View Source
var ModelGongEnumSubTemplateCode map[ModelGongEnumInsertionId]string = map[ModelGongEnumInsertionId]string{ ModelGongEnumUtilityFunctions: ` // Utility function for {{EnumName}} // if enum values are string, it is stored with the value // if enum values are int, they are stored with the code of the value func ({{enumName}} {{EnumName}}) To{{Type}}() (res {{type}}) { // migration of former implementation of enum switch {{enumName}} { // insertion code per enum code{{ToStringPerCodeCode}} } return } func ({{enumName}} *{{EnumName}}) From{{Type}}(input {{type}}) (err error) { switch input { // insertion code per enum code{{FromStringPerCodeCode}} default: return errUnkownEnum } } func ({{enumName}} *{{EnumName}}) FromCodeString(input string) (err error) { switch input { // insertion code per enum code{{FromCodeStringPerCodeCode}} default: return errUnkownEnum } return } func ({{enumName}} *{{EnumName}}) ToCodeString() (res string) { switch *{{enumName}} { // insertion code per enum code{{ToCodeStringPerCodeCode}} } return } func ({{enumName}} {{EnumName}}) Codes() (res []string) { res = make([]string, 0) // insertion code per enum code{{codes}} return } func ({{enumName}} {{EnumName}}) CodeValues() (res []{{type}}) { res = make([]{{type}}, 0) // insertion code per enum code{{codeValues}} return } `, ModelGongStructInsertionGenericEnumStringTypes: ` | {{EnumName}}`, ModelGongStructInsertionGenericEnumIntTypes: ` | {{EnumName}}`, ModelGongStructInsertionGenericPointerToEnumIntTypes: ` | *{{EnumName}}`, }
View Source
var ModelGongGraphStructSubTemplateCode map[ModelGongGraphStructInsertionId]string = map[ModelGongGraphStructInsertionId]string{ ModelGongGraphStructInsertionIsStaged: ` case *{{Structname}}: ok = stage.IsStaged{{Structname}}(target) `, ModelGongGraphStructInsertionIsStagedPerStruct: ` func (stage *StageStruct) IsStaged{{Structname}}({{structname}} *{{Structname}}) (ok bool) { _, ok = stage.{{Structname}}s[{{structname}}] return } `, ModelGongGraphStructInsertionStageBranch: ` case *{{Structname}}: stage.StageBranch{{Structname}}(target) `, ModelGongGraphStructInsertionStageBranchPerStruct: ` func (stage *StageStruct) StageBranch{{Structname}}({{structname}} *{{Structname}}) { // check if instance is already staged if IsStaged(stage, {{structname}}) { return } {{structname}}.Stage(stage) //insertion point for the staging of instances referenced by pointers{{StagingPointers}} //insertion point for the staging of instances referenced by slice of pointers{{StagingSliceOfPointers}} } `, ModelGongGraphStructInsertionCopyBranch: ` case *{{Structname}}: toT := CopyBranch{{Structname}}(mapOrigCopy, fromT) return any(toT).(*Type) `, ModelGongGraphStructInsertionCopyBranchPerStruct: ` func CopyBranch{{Structname}}(mapOrigCopy map[any]any, {{structname}}From *{{Structname}}) ({{structname}}To *{{Structname}}) { // {{structname}}From has already been copied if _{{structname}}To, ok := mapOrigCopy[{{structname}}From]; ok { {{structname}}To = _{{structname}}To.(*{{Structname}}) return } {{structname}}To = new({{Structname}}) mapOrigCopy[{{structname}}From] = {{structname}}To {{structname}}From.CopyBasicFields({{structname}}To) //insertion point for the staging of instances referenced by pointers{{CopyingPointers}} //insertion point for the staging of instances referenced by slice of pointers{{CopyingSliceOfPointers}} return } `, ModelGongGraphStructInsertionUnstageBranch: ` case *{{Structname}}: stage.UnstageBranch{{Structname}}(target) `, ModelGongGraphStructInsertionUnstageBranchPerStruct: ` func (stage *StageStruct) UnstageBranch{{Structname}}({{structname}} *{{Structname}}) { // check if instance is already staged if !IsStaged(stage, {{structname}}) { return } {{structname}}.Unstage(stage) //insertion point for the staging of instances referenced by pointers{{UnstagingPointers}} //insertion point for the staging of instances referenced by slice of pointers{{UnstagingSliceOfPointers}} } `, }
View Source
var ModelGongMarshallStructSubTemplateCode map[ModelGongMarshallStructInsertionId]string = map[ModelGongMarshallStructInsertionId]string{ ModelGongMarshallStructInsertionUnmarshallDeclarations: ` map_{{Structname}}_Identifiers := make(map[*{{Structname}}]string) _ = map_{{Structname}}_Identifiers {{structname}}Ordered := []*{{Structname}}{} for {{structname}} := range stage.{{Structname}}s { {{structname}}Ordered = append({{structname}}Ordered, {{structname}}) } sort.Slice({{structname}}Ordered[:], func(i, j int) bool { return {{structname}}Ordered[i].Name < {{structname}}Ordered[j].Name }) if len({{structname}}Ordered) > 0 { identifiersDecl += "\n" } for idx, {{structname}} := range {{structname}}Ordered { id = generatesIdentifier("{{Structname}}", idx, {{structname}}.Name) map_{{Structname}}_Identifiers[{{structname}}] = id decl = IdentifiersDecls decl = strings.ReplaceAll(decl, "{{Identifier}}", id) decl = strings.ReplaceAll(decl, "{{GeneratedStructName}}", "{{Structname}}") decl = strings.ReplaceAll(decl, "{{GeneratedFieldNameValue}}", {{structname}}.Name) identifiersDecl += decl initializerStatements += "\n" // Initialisation of values{{ValuesInitialization}} } `, ModelGongMarshallStructInsertionUnmarshallPointersInitializations: ` for idx, {{structname}} := range {{structname}}Ordered { var setPointerField string _ = setPointerField id = generatesIdentifier("{{Structname}}", idx, {{structname}}.Name) map_{{Structname}}_Identifiers[{{structname}}] = id // Initialisation of values{{PointersInitialization}} } `, }
View Source
var ModelGongOrchestratorStructSubTemplateCode map[string]string = map[string]string{ string(rune(ModelGongOrchestratorStruct)): ` // {{Structname}}Orchestrator type {{Structname}}Orchestrator struct { } func (orchestrator *{{Structname}}Orchestrator) OnAfterUpdate( gongsvgStage *StageStruct, staged{{Structname}}, backRepo{{Structname}} *{{Structname}}) { staged{{Structname}}.OnAfterUpdate(gongsvgStage, staged{{Structname}}, backRepo{{Structname}}) }`, string(rune(ModelGongOrchestratorSwitch)): ` case {{Structname}}: stage.OnAfter{{Structname}}UpdateCallback = new({{Structname}}Orchestrator)`, }
View Source
var ModelGongSerializeStructSubTemplateCode map[string]string = map[string]string{ string(rune(ModelGongSerializeStruct)): ` SerializeExcelizePointerToGongstruct[*{{Structname}}](stage, f)`, }
View Source
var ModelGongStructSubTemplateCode map[ModelGongStructInsertionId]string = map[ModelGongStructInsertionId]string{ ModelGongStructInsertionCommitCheckout: ` Commit{{Structname}}({{structname}} *{{Structname}}) Checkout{{Structname}}({{structname}} *{{Structname}})`, ModelGongStructInsertionGenericGetFields: ` case {{Structname}}:{{ListOfFieldsName}}`, ModelGongStructInsertionGenericGetReverseFields: ` case {{Structname}}:{{ListOfReverseFields}}`, ModelGongStructInsertionGenericGetFieldsFromPointer: ` case *{{Structname}}:{{ListOfFieldsName}}`, ModelGongStructInsertionGenericGetFieldValues: ` case {{Structname}}: switch fieldName { // string value of fields{{StringValueOfFields}} }`, ModelGongStructInsertionGenericGetFieldValuesFromPointer: ` case *{{Structname}}: switch fieldName { // string value of fields{{StringValueOfFields}} }`, ModelGongStructInsertionStageFunctions: ` // Stage puts {{structname}} to the model stage func ({{structname}} *{{Structname}}) Stage(stage *StageStruct) *{{Structname}} { stage.{{Structname}}s[{{structname}}] = __member stage.{{Structname}}s_mapString[{{structname}}.Name] = {{structname}} return {{structname}} } // Unstage removes {{structname}} off the model stage func ({{structname}} *{{Structname}}) Unstage(stage *StageStruct) *{{Structname}} { delete(stage.{{Structname}}s, {{structname}}) delete(stage.{{Structname}}s_mapString, {{structname}}.Name) return {{structname}} } // UnstageVoid removes {{structname}} off the model stage func ({{structname}} *{{Structname}}) UnstageVoid(stage *StageStruct) { delete(stage.{{Structname}}s, {{structname}}) delete(stage.{{Structname}}s_mapString, {{structname}}.Name) } // commit {{structname}} to the back repo (if it is already staged) func ({{structname}} *{{Structname}}) Commit(stage *StageStruct) *{{Structname}} { if _, ok := stage.{{Structname}}s[{{structname}}]; ok { if stage.BackRepo != nil { stage.BackRepo.Commit{{Structname}}({{structname}}) } } return {{structname}} } func ({{structname}} *{{Structname}}) CommitVoid(stage *StageStruct) { {{structname}}.Commit(stage) } // Checkout {{structname}} to the back repo (if it is already staged) func ({{structname}} *{{Structname}}) Checkout(stage *StageStruct) *{{Structname}} { if _, ok := stage.{{Structname}}s[{{structname}}]; ok { if stage.BackRepo != nil { stage.BackRepo.Checkout{{Structname}}({{structname}}) } } return {{structname}} } // for satisfaction of GongStruct interface func ({{structname}} *{{Structname}}) GetName() (res string) { return {{structname}}.Name } `, ModelGongStructInsertionCreateCallback: ` CreateORM{{Structname}}({{Structname}} *{{Structname}})`, ModelGongStructInsertionDeleteCallback: ` DeleteORM{{Structname}}({{Structname}} *{{Structname}})`, ModelGongStructInsertionArrayDefintion: ` {{Structname}}s map[*{{Structname}}]any {{Structname}}s_mapString map[string]*{{Structname}} // insertion point for slice of pointers maps{{SliceOfPointersReverseMaps}} OnAfter{{Structname}}CreateCallback OnAfterCreateInterface[{{Structname}}] OnAfter{{Structname}}UpdateCallback OnAfterUpdateInterface[{{Structname}}] OnAfter{{Structname}}DeleteCallback OnAfterDeleteInterface[{{Structname}}] OnAfter{{Structname}}ReadCallback OnAfterReadInterface[{{Structname}}] `, ModelGongStructInsertionArrayInitialisation: ` {{Structname}}s: make(map[*{{Structname}}]any), {{Structname}}s_mapString: make(map[string]*{{Structname}}), `, ModelGongStructInsertionArrayReset: ` stage.{{Structname}}s = make(map[*{{Structname}}]any) stage.{{Structname}}s_mapString = make(map[string]*{{Structname}}) `, ModelGongStructInsertionArrayNil: ` stage.{{Structname}}s = nil stage.{{Structname}}s_mapString = nil `, ModelGongStructInsertionArrayUnstage: ` for {{structname}} := range stage.{{Structname}}s { {{structname}}.Unstage(stage) } `, ModelGongStructInsertionUnmarshallDeclarations: ` map_{{Structname}}_Identifiers := make(map[*{{Structname}}]string) _ = map_{{Structname}}_Identifiers {{structname}}Ordered := []*{{Structname}}{} for {{structname}} := range stage.{{Structname}}s { {{structname}}Ordered = append({{structname}}Ordered, {{structname}}) } sort.Slice({{structname}}Ordered[:], func(i, j int) bool { return {{structname}}Ordered[i].Name < {{structname}}Ordered[j].Name }) for idx, {{structname}} := range {{structname}}Ordered { id = generatesIdentifier("{{Structname}}", idx, {{structname}}.Name) map_{{Structname}}_Identifiers[{{structname}}] = id decl = IdentifiersDecls decl = strings.ReplaceAll(decl, "{{Identifier}}", id) decl = strings.ReplaceAll(decl, "{{GeneratedStructName}}", "{{Structname}}") decl = strings.ReplaceAll(decl, "{{GeneratedFieldNameValue}}", {{structname}}.Name) identifiersDecl += decl // Initialisation of values{{ValuesInitialization}} } `, ModelGongStructInsertionUnmarshallPointersInitializations: ` for idx, {{structname}} := range {{structname}}Ordered { var setPointerField string _ = setPointerField id = generatesIdentifier("{{Structname}}", idx, {{structname}}.Name) map_{{Structname}}_Identifiers[{{structname}}] = id // Initialisation of values{{PointersInitialization}} } `, ModelGongStructInsertionComputeNbInstances: ` stage.Map_GongStructName_InstancesNb["{{Structname}}"] = len(stage.{{Structname}}s)`, ModelGongStructInsertionGenericReversePointerAssociationsMaps: ` // reverse maps of direct associations of {{Structname}} case {{Structname}}: switch fieldname { // insertion point for per direct association field{{fieldReversePointerAssociationMapCode}} }`, ModelGongStructInsertionGenericReverseSliceOfPointersAssociationsMaps: ` // reverse maps of direct associations of {{Structname}} case {{Structname}}: switch fieldname { // insertion point for per direct association field{{fieldReverseSliceOfPointersAssociationMapCode}} }`, ModelGongStructInsertionGenericGongstructName: ` case {{Structname}}: res = "{{Structname}}"`, ModelGongStructInsertionGenericPointerToGongstructName: ` case *{{Structname}}: res = "{{Structname}}"`, ModelGongStructInsertionGenericGetSetFunctions: ` case map[*{{Structname}}]any: return any(&stage.{{Structname}}s).(*Type)`, ModelGongStructInsertionGenericGetMapFunctions: ` case map[string]*{{Structname}}: return any(&stage.{{Structname}}s_mapString).(*Type)`, ModelGongStructInsertionGenericInstancesSetFunctions: ` case {{Structname}}: return any(&stage.{{Structname}}s).(*map[*Type]any)`, ModelGongStructInsertionGenericInstancesSetFromPointerTypeFunctions: ` case *{{Structname}}: return any(&stage.{{Structname}}s).(*map[Type]any)`, ModelGongStructInsertionGenericInstancesMapFunctions: ` case {{Structname}}: return any(&stage.{{Structname}}s_mapString).(*map[string]*Type)`, ModelGongStructInsertionGenericGetAssociationNameFunctions: ` case {{Structname}}: return any(&{{Structname}}{ // Initialisation of associations{{associationFieldInitialization}} }).(*Type)`, }
View Source
var ModelGongWopStructSubTemplateCode map[ModelGongWopStructInsertionId]string = map[ModelGongWopStructInsertionId]string{ ModelGongWopStruct: ` type {{Structname}}_WOP struct { // insertion point{{FieldCode}} } func (from *{{Structname}}) CopyBasicFields(to *{{Structname}}) { // insertion point{{FieldsCopyCode}} } `, }
Functions ¶
func CodeGeneratorModelGong ¶
func GongAstGenerator ¶
Types ¶
type GongFilePerStructSubTemplateId ¶
type GongFilePerStructSubTemplateId int
Sub sub Templates identifiers per gong field
For each gongstruct, a code snippet will be generated from each sub template
const ( GongFileFieldSubTmplStringFieldName GongFilePerStructSubTemplateId = iota GongFileFieldSubTmplReverseField GongFileFieldSubTmplStringValueBasicFieldBool GongFileFieldSubTmplStringValueBasicFieldInt GongFileFieldSubTmplStringValueBasicFieldIntDuration GongFileFieldSubTmplStringValueBasicFieldEnumString GongFileFieldSubTmplStringValueBasicFieldEnumInt GongFileFieldSubTmplStringValueBasicFieldFloat64 GongFileFieldSubTmplStringValueBasicFieldString GongFileFieldSubTmplStringValueTimeField GongFileFieldSubTmplStringValueTimeFieldBespokeFormat GongFileFieldSubTmplStringValuePointerField GongFileFieldSubTmplStringValueSliceOfPointersField GongFileFieldSubTmplAssociationNamePointerField GongFileFieldSubTmplAssociationNameSliceOfPointersField GongFileFieldSubTmplAssociationPromotedNamePointerField GongFileFieldSubTmplAssociationPromotedNameSliceOfPointersField GongFileFieldSubTmplAssociationNameEnclosingCompositePointerField GongFileFieldSubTmplAssociationNameCompositePointerField GongFileFieldSubTmplPointerFieldPointerAssociationMapFunction GongFileFieldSubTmplPointerFieldSliceOfPointersAssociationMapFunction GongFileSliceOfPointersReverseMap )
type GongGraphFilePerStructSubTemplateId ¶
type GongGraphFilePerStructSubTemplateId int
const ( GongGraphFileFieldSubTmplStagePointerField GongGraphFilePerStructSubTemplateId = iota GongGraphFileFieldSubTmplStageSliceOfPointersField GongGraphFileFieldSubTmplCopyPointerField GongGraphFileFieldSubTmplCopyPointerFieldAndStop GongGraphFileFieldSubTmplCopySliceOfPointersField GongGraphFileFieldSubTmplUnstagePointerField GongGraphFileFieldSubTmplUnstageSliceOfPointersField )
type GongMarshallFilePerStructSubTemplateId ¶
type GongMarshallFilePerStructSubTemplateId int
const ( GongMarshallFileFieldSubTmplSetBasicFieldBool GongMarshallFilePerStructSubTemplateId = iota GongMarshallFileFieldSubTmplSetBasicFieldInt GongMarshallFileFieldSubTmplSetBasicFieldEnumString GongMarshallFileFieldSubTmplSetBasicFieldEnumInt GongMarshallFileFieldSubTmplSetBasicFieldFloat64 GongMarshallFileFieldSubTmplSetBasicFieldString GongMarshallFileFieldSubTmplSetBasicFieldStringDocLink GongMarshallFileFieldSubTmplSetTimeField GongMarshallFileFieldSubTmplSetPointerField GongMarshallFileFieldSubTmplSetSliceOfPointersField )
type GongModelEnumValueSubTemplateId ¶
type GongModelEnumValueSubTemplateId int
gongenum value template
const ( GongModelEnumValueFromString GongModelEnumValueSubTemplateId = iota GongModelEnumValueFromCodeString GongModelEnumValueToString GongModelEnumValueToCodeString GongModelEnumCodes GongModelEnumCodeValues )
type GongSliceGongstructInsertionId ¶
type GongSliceGongstructInsertionId int
const ( GongSliceCase GongSliceGongstructInsertionId = iota GongSliceReverseMapCompute GongSliceGongstructInsertionNb )
type GongSliceSubTemplateId ¶
type GongSliceSubTemplateId int
const ( GongSliceSubTmplSliceOfPointersToStruct GongSliceSubTemplateId = iota GongSliceSubTmplSliceOfPointersReverseMapComputation )
type GongWopSubSubTemplateInsertionsId ¶
type GongWopSubSubTemplateInsertionsId int
const ( GongWopBasicFieldDecl GongWopSubSubTemplateInsertionsId = iota + 100 GongWopEnumFieldDecl GongWopTimeFieldDecl GongWopDurationFieldDecl GongWopBasicFieldCopy )
type ModelGongAstFieldInsertionId ¶
type ModelGongAstFieldInsertionId int
const ( ModelGongAstFieldAssignString ModelGongAstFieldInsertionId = iota ModelGongAstFieldAssignInt ModelGongAstFieldAssignFloat64 ModelGongAstFieldAssignDate ModelGongAstFieldAssignDuration ModelGongAstFieldAssignBoolean ModelGongAstFieldAssignPointer ModelGongAstFieldAssignSliceOfPointers ModelGongAstFieldAssignEnum ModelGongAstFieldInsertionsNb )
type ModelGongAstStructInsertionId ¶
type ModelGongAstStructInsertionId int
insertion points are places where the code is generated per gong struct
const ( ModelGongAstGenericMaps ModelGongAstStructInsertionId = iota ModelGongAstStageProcessing ModelGongAstBasicLitAssignment ModelGongAstIdentBooleanAndPointerAssignment ModelGongAstIdentEnumAssignment ModelGongAstDateAssignment ModelGongAstSliceOfPointersAssignment ModelGongAstStructInsertionsNb )
type ModelGongCallbacksStructInsertionId ¶
type ModelGongCallbacksStructInsertionId int
const ( ModelGongCallbacksCreate ModelGongCallbacksStructInsertionId = iota ModelGongCallbacksUpdate ModelGongCallbacksRead ModelGongCallbacksDelete ModelGongCallbacksSetFuncCreate ModelGongCallbacksSetFuncUpdate ModelGongCallbacksSetFuncRead ModelGongCallbacksSetFuncDelete )
type ModelGongCoderFieldInsertionId ¶
type ModelGongCoderFieldInsertionId int
const ( ModelGongCoderFieldCodeString ModelGongCoderFieldInsertionId = iota ModelGongCoderFieldCodeInt ModelGongCoderFieldCodeFloat64 ModelGongCoderFieldCodeDate ModelGongCoderFieldCodeBoolean ModelGongCoderFieldNameString ModelGongCoderFieldNameInt ModelGongCoderFieldNameFloat64 ModelGongCoderFieldNameDate ModelGongCoderFieldNameBoolean ModelGongCoderFieldInsertionsNb )
type ModelGongCoderStructInsertionId ¶
type ModelGongCoderStructInsertionId int
insertion points are places where the code is generated per gong struct
const ( ModelGongCoderGenericGongstructTypes ModelGongCoderStructInsertionId = iota ModelGongCoderGenericGongstructCoder ModelGongCoderGenericGongstructNamerString ModelGongCoderStructInsertionsNb )
type ModelGongEnumInsertionId ¶
type ModelGongEnumInsertionId int
insertion code for all enums
const ( // iota + 40 is to separate the insertion code of gongstruct from insertion code of gongenum ModelGongEnumUtilityFunctions ModelGongEnumInsertionId = iota + 40 ModelGongStructInsertionGenericEnumStringTypes ModelGongStructInsertionGenericEnumIntTypes ModelGongStructInsertionGenericPointerToEnumIntTypes ModelGongEnumInsertionsNb )
type ModelGongGraphStructInsertionId ¶
type ModelGongGraphStructInsertionId int
insertion points are places where the code is generated per gong struct
const ( ModelGongGraphStructInsertionIsStaged ModelGongGraphStructInsertionId = iota ModelGongGraphStructInsertionIsStagedPerStruct ModelGongGraphStructInsertionStageBranch ModelGongGraphStructInsertionStageBranchPerStruct ModelGongGraphStructInsertionCopyBranch ModelGongGraphStructInsertionCopyBranchPerStruct ModelGongGraphStructInsertionUnstageBranch ModelGongGraphStructInsertionUnstageBranchPerStruct ModelGongGraphStructInsertionsNb )
type ModelGongMarshallStructInsertionId ¶
type ModelGongMarshallStructInsertionId int
insertion points are places where the code is generated per gong struct
const ( ModelGongMarshallStructInsertionUnmarshallDeclarations ModelGongMarshallStructInsertionId = iota ModelGongMarshallStructInsertionUnmarshallPointersInitializations ModelGongMarshallStructInsertionsNb )
type ModelGongOrchestratorStructInsertionId ¶
type ModelGongOrchestratorStructInsertionId int
const ( ModelGongOrchestratorStruct ModelGongOrchestratorStructInsertionId = iota ModelGongOrchestratorSwitch )
type ModelGongSerializeStructInsertionId ¶
type ModelGongSerializeStructInsertionId int
const (
ModelGongSerializeStruct ModelGongSerializeStructInsertionId = iota
)
type ModelGongStructInsertionId ¶
type ModelGongStructInsertionId int
insertion points are places where the code is generated per gong struct
const ( ModelGongStructInsertionCommitCheckout ModelGongStructInsertionId = iota ModelGongStructInsertionStageFunctions ModelGongStructInsertionCreateCallback ModelGongStructInsertionDeleteCallback ModelGongStructInsertionArrayDefintion ModelGongStructInsertionArrayInitialisation ModelGongStructInsertionArrayReset ModelGongStructInsertionArrayNil ModelGongStructInsertionArrayUnstage ModelGongStructInsertionUnmarshallDeclarations ModelGongStructInsertionUnmarshallPointersInitializations ModelGongStructInsertionComputeNbInstances ModelGongStructInsertionGenericGetFields ModelGongStructInsertionGenericGetReverseFields ModelGongStructInsertionGenericGetFieldsFromPointer ModelGongStructInsertionGenericGetFieldValues ModelGongStructInsertionGenericGetFieldValuesFromPointer ModelGongStructInsertionGenericReversePointerAssociationsMaps ModelGongStructInsertionGenericReverseSliceOfPointersAssociationsMaps ModelGongStructInsertionGenericGongstructName ModelGongStructInsertionGenericPointerToGongstructName ModelGongStructInsertionGenericGetSetFunctions ModelGongStructInsertionGenericGetMapFunctions ModelGongStructInsertionGenericInstancesSetFunctions ModelGongStructInsertionGenericInstancesSetFromPointerTypeFunctions ModelGongStructInsertionGenericInstancesSetFromPointerTypeFunctionsReturnType ModelGongStructInsertionGenericInstancesMapFunctions ModelGongStructInsertionGenericGetAssociationNameFunctions ModelGongStructInsertionsNb )
type ModelGongWopStructInsertionId ¶
type ModelGongWopStructInsertionId int
const ( ModelGongWopStruct ModelGongWopStructInsertionId = iota ModelGongWopStructInsertionsNb )
Click to show internal directories.
Click to hide internal directories.