func makeCodegenModel(name, pkg string, schema spec.Schema, specDoc *spec.Document) *genModel { receiver := "m" props := make(map[string]genModelProperty) for pn, p := range schema.Properties { var required bool for _, v := range schema.Required { if v == pn { required = true break } } props[swag.ToJSONName(pn)] = makeGenModelProperty( "\""+pn+"\"", swag.ToJSONName(pn), swag.ToGoName(pn), receiver, "i", receiver+"."+swag.ToGoName(pn), p, required) } for _, p := range schema.AllOf { if p.Ref.GetURL() != nil { tn := filepath.Base(p.Ref.GetURL().Fragment) p = specDoc.Spec().Definitions[tn] } mod := makeCodegenModel(name, pkg, p, specDoc) if mod != nil { for _, prop := range mod.Properties { props[prop.ParamName] = prop } } } var properties []genModelProperty var hasValidations bool for _, v := range props { if v.HasValidations { hasValidations = v.HasValidations } properties = append(properties, v) } return &genModel{ Package: filepath.Base(pkg), ClassName: swag.ToGoName(name), Name: swag.ToJSONName(name), ReceiverName: receiver, Properties: properties, Description: schema.Description, DocString: modelDocString(swag.ToGoName(name), schema.Description), HumanClassName: swag.ToHumanNameLower(swag.ToGoName(name)), HasValidations: hasValidations, } }
// func makeCodegenApp(operations map[string]spec.Operation, includeUI bool) genApp { func (a *appGenerator) makeCodegenApp() genApp { sw := a.SpecDoc.Spec() // app := makeCodegenApp(a.Operations, a.IncludeUI) receiver := strings.ToLower(a.Name[:1]) appName := swag.ToGoName(a.Name) var defaultImports []string jsonb, _ := json.MarshalIndent(a.SpecDoc.Spec(), "", " ") consumesJSON := false var consumes []genSerGroup for _, cons := range a.SpecDoc.RequiredConsumes() { cn, ok := mediaTypeNames[cons] if !ok { continue } nm := swag.ToJSONName(cn) if nm == "json" { consumesJSON = true } if ser, ok := getSerializer(consumes, cn); ok { ser.AllSerializers = append(ser.AllSerializers, genSerializer{ AppName: ser.AppName, ReceiverName: ser.ReceiverName, ClassName: ser.ClassName, HumanClassName: ser.HumanClassName, Name: ser.Name, MediaType: cons, Implementation: knownConsumers[nm], }) continue } ser := genSerializer{ AppName: appName, ReceiverName: receiver, ClassName: swag.ToGoName(cn), HumanClassName: swag.ToHumanNameLower(cn), Name: nm, MediaType: cons, Implementation: knownConsumers[nm], } consumes = append(consumes, genSerGroup{ AppName: ser.AppName, ReceiverName: ser.ReceiverName, ClassName: ser.ClassName, HumanClassName: ser.HumanClassName, Name: ser.Name, MediaType: cons, AllSerializers: []genSerializer{ser}, Implementation: ser.Implementation, }) } producesJSON := false var produces []genSerGroup for _, prod := range a.SpecDoc.RequiredProduces() { pn, ok := mediaTypeNames[prod] if !ok { continue } nm := swag.ToJSONName(pn) if nm == "json" { producesJSON = true } if ser, ok := getSerializer(produces, pn); ok { ser.AllSerializers = append(ser.AllSerializers, genSerializer{ AppName: ser.AppName, ReceiverName: ser.ReceiverName, ClassName: ser.ClassName, HumanClassName: ser.HumanClassName, Name: ser.Name, MediaType: prod, Implementation: knownProducers[nm], }) continue } ser := genSerializer{ AppName: appName, ReceiverName: receiver, ClassName: swag.ToGoName(pn), HumanClassName: swag.ToHumanNameLower(pn), Name: nm, MediaType: prod, Implementation: knownProducers[nm], } produces = append(produces, genSerGroup{ AppName: ser.AppName, ReceiverName: ser.ReceiverName, ClassName: ser.ClassName, HumanClassName: ser.HumanClassName, Name: ser.Name, MediaType: prod, Implementation: ser.Implementation, AllSerializers: []genSerializer{ser}, }) } var security []genSecurityScheme for _, scheme := range a.SpecDoc.RequiredSchemes() { if req, ok := a.SpecDoc.Spec().SecurityDefinitions[scheme]; ok { if req.Type == "basic" || req.Type == "apiKey" { security = append(security, genSecurityScheme{ AppName: appName, ReceiverName: receiver, ClassName: swag.ToGoName(req.Name), HumanClassName: swag.ToHumanNameLower(req.Name), Name: swag.ToJSONName(req.Name), IsBasicAuth: strings.ToLower(req.Type) == "basic", IsAPIKeyAuth: strings.ToLower(req.Type) == "apikey", Principal: a.Principal, Source: req.In, }) } } } var genMods []genModel defaultImports = append(defaultImports, filepath.Join(baseImport(a.Target), a.ModelsPackage)) for mn, m := range a.Models { mod := *makeCodegenModel( mn, a.ModelsPackage, m, a.SpecDoc, ) mod.ReceiverName = receiver genMods = append(genMods, mod) } var genOps []genOperation tns := make(map[string]struct{}) for on, o := range a.Operations { authed := len(a.SpecDoc.SecurityRequirementsFor(&o)) > 0 ap := a.APIPackage if a.APIPackage == a.Package { ap = "" } if len(o.Tags) > 0 { for _, tag := range o.Tags { tns[tag] = struct{}{} op := makeCodegenOperation(on, tag, a.ModelsPackage, a.Principal, a.Target, o, authed) op.ReceiverName = receiver genOps = append(genOps, op) } } else { op := makeCodegenOperation(on, ap, a.ModelsPackage, a.Principal, a.Target, o, authed) op.ReceiverName = receiver genOps = append(genOps, op) } } for k := range tns { defaultImports = append(defaultImports, filepath.Join(baseImport(a.Target), a.ServerPackage, a.APIPackage, k)) } defaultConsumes := "application/json" rc := a.SpecDoc.RequiredConsumes() if !consumesJSON && len(rc) > 0 { defaultConsumes = rc[0] } defaultProduces := "application/json" rp := a.SpecDoc.RequiredProduces() if !producesJSON && len(rp) > 0 { defaultProduces = rp[0] } return genApp{ Package: a.Package, ReceiverName: receiver, AppName: swag.ToGoName(a.Name), HumanAppName: swag.ToHumanNameLower(a.Name), Name: swag.ToJSONName(a.Name), ExternalDocs: sw.ExternalDocs, Info: sw.Info, Consumes: consumes, Produces: produces, DefaultConsumes: defaultConsumes, DefaultProduces: defaultProduces, DefaultImports: defaultImports, SecurityDefinitions: security, Models: genMods, Operations: genOps, IncludeUI: a.IncludeUI, Principal: a.Principal, SwaggerJSON: fmt.Sprintf("%#v", jsonb), } }
func makeCodegenOperation(name, pkg, modelsPkg, principal, target string, operation spec.Operation, authorized bool) genOperation { receiver := "o" var params, qp, pp, hp, fp []genParameter var hasQueryParams bool for _, p := range operation.Parameters { cp := makeCodegenParameter(receiver, modelsPkg, p) if cp.IsQueryParam { hasQueryParams = true qp = append(qp, cp) } if cp.IsFormParam { fp = append(fp, cp) } if cp.IsPathParam { pp = append(pp, cp) } if cp.IsHeaderParam { hp = append(hp, cp) } params = append(params, cp) } var successModel string var returnsPrimitive, returnsFormatted, returnsContainer, returnsMap bool if operation.Responses != nil { if r, ok := operation.Responses.StatusCodeResponses[200]; ok { tn := typeForSchema(r.Schema, modelsPkg) _, returnsPrimitive = primitives[tn] _, returnsFormatted = customFormatters[tn] returnsContainer = r.Schema.Items != nil || r.Schema.Type.Contains("array") returnsMap = strings.HasPrefix(tn, "map") successModel = tn } } prin := principal if prin == "" { prin = "interface{}" } zero, ok := zeroes[successModel] if !ok { zero = "nil" } return genOperation{ Package: pkg, ClassName: swag.ToGoName(name), Name: swag.ToJSONName(name), Description: operation.Description, DocString: operationDocString(swag.ToGoName(name), operation), ReceiverName: receiver, HumanClassName: swag.ToHumanNameLower(swag.ToGoName(name)), DefaultImports: []string{filepath.Join(baseImport(filepath.Join(target, "..")), modelsPkg)}, Params: params, Summary: operation.Summary, QueryParams: qp, PathParams: pp, HeaderParams: hp, FormParams: fp, HasQueryParams: hasQueryParams, SuccessModel: successModel, SuccessZero: zero, ReturnsPrimitive: returnsPrimitive, ReturnsFormatted: returnsFormatted, ReturnsContainer: returnsContainer, ReturnsMap: returnsMap, ReturnsComplexObject: !returnsPrimitive && !returnsFormatted && !returnsContainer && !returnsMap, Authorized: authorized, Principal: prin, } }