buildResponseBodyType builds the TypeData for a response body. The data makes it possible to generate a function that creates the server response body from the service method result/projected result or error. body is the response (success or error) HTTP body. att is the result/projected attribute.
(body, att *expr.AttributeExpr, loc *codegen.Location, e *expr.HTTPEndpointExpr, svr bool, view *string, sd *ServiceData)
| 2229 | // |
| 2230 | // view is the view name to add as a suffix to the type name. |
| 2231 | func (sds *ServicesData) buildResponseBodyType(body, att *expr.AttributeExpr, loc *codegen.Location, e *expr.HTTPEndpointExpr, svr bool, view *string, sd *ServiceData) *TypeData { |
| 2232 | if body.Type == expr.Empty { |
| 2233 | return nil |
| 2234 | } |
| 2235 | var ( |
| 2236 | name string |
| 2237 | varname string |
| 2238 | desc string |
| 2239 | def string |
| 2240 | ref string |
| 2241 | validateDef string |
| 2242 | validateRef string |
| 2243 | viewName string |
| 2244 | mustInit bool |
| 2245 | |
| 2246 | svc = sd.Service |
| 2247 | httpctx = httpContext(sd.Scope, false, svr) |
| 2248 | pkg = pkgWithDefault(loc, sd.Service.PkgName) |
| 2249 | svcctx = serviceContext(pkg, sd.Service.Scope) |
| 2250 | ) |
| 2251 | // Project the response body when the design fixes the response to a single |
| 2252 | // view so the generated transport code uses the effective wire shape. |
| 2253 | if view != nil && *view != "" { |
| 2254 | viewName = *view |
| 2255 | body = expr.DupAtt(body) |
| 2256 | if rt, ok := body.Type.(*expr.ResultTypeExpr); ok { |
| 2257 | var err error |
| 2258 | rt, err = expr.Project(rt, *view) |
| 2259 | if err != nil { |
| 2260 | panic(err) |
| 2261 | } |
| 2262 | body.Type = rt |
| 2263 | if svr { |
| 2264 | sd.ServerTypeNames[rt.Name()] = false |
| 2265 | } else { |
| 2266 | sd.ClientTypeNames[rt.Name()] = false |
| 2267 | } |
| 2268 | } |
| 2269 | } |
| 2270 | |
| 2271 | name = body.Type.Name() |
| 2272 | ref = sd.Scope.GoTypeRef(body) |
| 2273 | mustInit = att.Type != expr.Empty && needInit(body.Type) |
| 2274 | |
| 2275 | addMarshalTags(body, make(map[string]struct{})) |
| 2276 | |
| 2277 | if ut, ok := body.Type.(expr.UserType); ok { |
| 2278 | // response body is a user type. |
| 2279 | varname = codegen.Goify(ut.Name(), true) |
| 2280 | def = goTypeDef(sd.Scope, ut.Attribute(), !svr, svr) |
| 2281 | desc = fmt.Sprintf("%s is the type of the %q service %q endpoint HTTP response body.", |
| 2282 | varname, svc.Name, e.Name()) |
| 2283 | if !svr && view == nil { |
| 2284 | // generate validation code for unmarshaled type (client-side). |
| 2285 | validateDef = codegen.ValidationCode(body, ut, httpctx, true, expr.IsAlias(body.Type), false, "body") |
| 2286 | if validateDef != "" { |
| 2287 | target := "&body" |
| 2288 | if expr.IsArray(ut) { |
no test coverage detected