// generateUserTypes iterates through the user types and generates the data structures and // marshaling code. func (g *Generator) generateUserTypes(verdir string, version *design.APIVersionDefinition) error { utFile := filepath.Join(verdir, "user_types.go") utWr, err := NewUserTypesWriter(utFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application User Types", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("fmt"), codegen.SimpleImport("time"), } if !version.IsDefault() { appPkg, err := AppPackagePath() if err != nil { return err } imports = append(imports, codegen.SimpleImport(appPkg)) } utWr.WriteHeader(title, packageName(version), imports) err = version.IterateUserTypes(func(t *design.UserTypeDefinition) error { data := &UserTypeTemplateData{ UserType: t, Versioned: version.Version != "", DefaultPkg: TargetPackage, } return utWr.Execute(data) }) g.genfiles = append(g.genfiles, utFile) if err != nil { return err } return utWr.FormatCode() }
// generateContexts iterates through the version resources and actions and generates the action // contexts. func (g *Generator) generateContexts(verdir string, api *design.APIDefinition, version *design.APIVersionDefinition) error { ctxFile := filepath.Join(verdir, "contexts.go") ctxWr, err := NewContextsWriter(ctxFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Contexts", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("fmt"), codegen.SimpleImport("golang.org/x/net/context"), codegen.SimpleImport("strconv"), codegen.SimpleImport("strings"), codegen.SimpleImport("time"), codegen.SimpleImport("github.com/goadesign/goa"), } if !version.IsDefault() { appPkg, err := AppPackagePath() if err != nil { return err } imports = append(imports, codegen.SimpleImport(appPkg)) } ctxWr.WriteHeader(title, packageName(version), imports) err = version.IterateResources(func(r *design.ResourceDefinition) error { if !r.SupportsVersion(version.Version) { return nil } return r.IterateActions(func(a *design.ActionDefinition) error { ctxName := codegen.Goify(a.Name, true) + codegen.Goify(a.Parent.Name, true) + "Context" headers := r.Headers.Merge(a.Headers) if headers != nil && len(headers.Type.ToObject()) == 0 { headers = nil // So that {{if .Headers}} returns false in templates } params := a.AllParams() if params != nil && len(params.Type.ToObject()) == 0 { params = nil // So that {{if .Params}} returns false in templates } ctxData := ContextTemplateData{ Name: ctxName, ResourceName: r.Name, ActionName: a.Name, Payload: a.Payload, Params: params, Headers: headers, Routes: a.Routes, Responses: MergeResponses(r.Responses, a.Responses), API: api, Version: version, DefaultPkg: TargetPackage, } return ctxWr.Execute(&ctxData) }) }) g.genfiles = append(g.genfiles, ctxFile) if err != nil { return err } return ctxWr.FormatCode() }
// generateControllers iterates through the version resources and generates the low level // controllers. func (g *Generator) generateControllers(verdir string, version *design.APIVersionDefinition) error { ctlFile := filepath.Join(verdir, "controllers.go") ctlWr, err := NewControllersWriter(ctlFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Controllers", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/julienschmidt/httprouter"), codegen.SimpleImport("github.com/goadesign/goa"), } if !version.IsDefault() { appPkg, err := AppPackagePath() if err != nil { return err } imports = append(imports, codegen.SimpleImport(appPkg)) } ctlWr.WriteHeader(title, packageName(version), imports) var controllersData []*ControllerTemplateData version.IterateResources(func(r *design.ResourceDefinition) error { if !r.SupportsVersion(version.Version) { return nil } data := &ControllerTemplateData{Resource: codegen.Goify(r.Name, true)} err := r.IterateActions(func(a *design.ActionDefinition) error { context := fmt.Sprintf("%s%sContext", codegen.Goify(a.Name, true), codegen.Goify(r.Name, true)) unmarshal := fmt.Sprintf("unmarshal%s%sPayload", codegen.Goify(a.Name, true), codegen.Goify(r.Name, true)) action := map[string]interface{}{ "Name": codegen.Goify(a.Name, true), "Routes": a.Routes, "Context": context, "Unmarshal": unmarshal, "Payload": a.Payload, } data.Actions = append(data.Actions, action) return nil }) if err != nil { return err } if len(data.Actions) > 0 { data.Version = version controllersData = append(controllersData, data) } return nil }) g.genfiles = append(g.genfiles, ctlFile) if err = ctlWr.Execute(controllersData); err != nil { return err } return ctlWr.FormatCode() }
// generateMediaTypes iterates through the media types and generate the data structures and // marshaling code. func (g *Generator) generateMediaTypes(verdir string, version *design.APIVersionDefinition) error { mtFile := filepath.Join(verdir, "media_types.go") mtWr, err := NewMediaTypesWriter(mtFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Media Types", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("github.com/goadesign/goa"), codegen.SimpleImport("fmt"), codegen.SimpleImport("time"), } if !version.IsDefault() { appPkg, err := AppPackagePath() if err != nil { return err } imports = append(imports, codegen.SimpleImport(appPkg)) } mtWr.WriteHeader(title, packageName(version), imports) err = version.IterateMediaTypes(func(mt *design.MediaTypeDefinition) error { data := &MediaTypeTemplateData{ MediaType: mt, Versioned: version.Version != "", DefaultPkg: TargetPackage, } if mt.Type.IsObject() || mt.Type.IsArray() { return mtWr.Execute(data) } return nil }) g.genfiles = append(g.genfiles, mtFile) if err != nil { return err } return mtWr.FormatCode() }
// generateControllers iterates through the version resources and generates the low level // controllers. func (g *Generator) generateControllers(verdir string, version *design.APIVersionDefinition) error { ctlFile := filepath.Join(verdir, "controllers.go") ctlWr, err := NewControllersWriter(ctlFile) if err != nil { panic(err) // bug } title := fmt.Sprintf("%s: Application Controllers", version.Context()) imports := []*codegen.ImportSpec{ codegen.SimpleImport("net/http"), codegen.SimpleImport("golang.org/x/net/context"), codegen.SimpleImport("github.com/goadesign/goa"), } if !version.IsDefault() { appPkg, err := AppPackagePath() if err != nil { return err } imports = append(imports, codegen.SimpleImport(appPkg)) } encoderMap, err := BuildEncoderMap(version.Produces, true) if err != nil { return err } decoderMap, err := BuildEncoderMap(version.Consumes, false) if err != nil { return err } encoderImports := make(map[string]bool) for _, data := range encoderMap { encoderImports[data.PackagePath] = true } for _, data := range decoderMap { encoderImports[data.PackagePath] = true } for packagePath := range encoderImports { if !design.IsGoaEncoder(packagePath) { imports = append(imports, codegen.SimpleImport(packagePath)) } } ctlWr.WriteHeader(title, packageName(version), imports) var controllersData []*ControllerTemplateData version.IterateResources(func(r *design.ResourceDefinition) error { if !r.SupportsVersion(version.Version) { return nil } data := &ControllerTemplateData{API: design.Design, Resource: codegen.Goify(r.Name, true)} err := r.IterateActions(func(a *design.ActionDefinition) error { context := fmt.Sprintf("%s%sContext", codegen.Goify(a.Name, true), codegen.Goify(r.Name, true)) unmarshal := fmt.Sprintf("unmarshal%s%sPayload", codegen.Goify(a.Name, true), codegen.Goify(r.Name, true)) action := map[string]interface{}{ "Name": codegen.Goify(a.Name, true), "Routes": a.Routes, "Context": context, "Unmarshal": unmarshal, "Payload": a.Payload, } data.Actions = append(data.Actions, action) return nil }) if err != nil { return err } if len(data.Actions) > 0 { data.EncoderMap = encoderMap data.DecoderMap = decoderMap data.Version = version controllersData = append(controllersData, data) } return nil }) g.genfiles = append(g.genfiles, ctlFile) if err = ctlWr.Execute(controllersData); err != nil { return err } return ctlWr.FormatCode() }