MCPcopy Create free account
hub / github.com/goadesign/goa / validateAttribute

Function validateAttribute

codegen/validation.go:263–318  ·  view source on GitHub ↗
(ctx *AttributeContext, att *expr.AttributeExpr, put expr.UserType, target, context string, req, view bool, seen map[string]*bytes.Buffer)

Source from the content-addressed store, hash-verified

261}
262
263func validateAttribute(ctx *AttributeContext, att *expr.AttributeExpr, put expr.UserType, target, context string, req, view bool, seen map[string]*bytes.Buffer) string {
264 ut, isUT := att.Type.(expr.UserType)
265 if !isUT {
266 code := recurseValidationCode(att, put, ctx, req, false, view, target, context, seen).String()
267 if code == "" {
268 return ""
269 }
270 if expr.IsArray(att.Type) || expr.IsMap(att.Type) || expr.IsUnion(att.Type) {
271 return code
272 }
273 if !ctx.Pointer && (req || (att.DefaultValue != nil && ctx.UseDefault)) {
274 return code
275 }
276 cond := fmt.Sprintf("if %s != nil {\n", target)
277 if strings.HasPrefix(code, cond) {
278 return code
279 }
280 return fmt.Sprintf("%s%s\n}", cond, code)
281 }
282 // Alias user types: validate underlying attribute with alias flag so that
283 // validation operates on the base value type while preserving pointer
284 // semantics from the current attribute context.
285 if expr.IsAlias(ut) {
286 // Preserve field-level attributes (e.g., DefaultValue, Required) while
287 // validating alias user types against their underlying base. Passing
288 // the original attribute with alias=true ensures validations operate
289 // on the correct value type without dropping field defaults.
290 code := recurseValidationCode(att, put, ctx, req, true, view, target, context, seen).String()
291 if code == "" {
292 return ""
293 }
294 // For optional pointer fields, wrap validation code in nil check
295 if !ctx.Pointer && (req || (att.DefaultValue != nil && ctx.UseDefault)) {
296 return code
297 }
298 cond := fmt.Sprintf("if %s != nil {\n", target)
299 if strings.HasPrefix(code, cond) {
300 return code
301 }
302 return fmt.Sprintf("%s%s\n}", cond, code)
303 }
304 if !hasValidations(ctx, ut) {
305 return ""
306 }
307 var buf bytes.Buffer
308 name := ctx.Scope.Name(att, "", ctx.Pointer, ctx.UseDefault)
309 // Use the scoped type name directly to preserve identifiers such as
310 // protocol buffer-reserved names that include a trailing underscore
311 // (e.g., Message_). Applying Goify here would drop underscores and
312 // cause mismatches between function declarations and call sites.
313 data := map[string]any{"name": name, "target": target}
314 if err := userValT.Execute(&buf, data); err != nil {
315 panic(err) // bug
316 }
317 return fmt.Sprintf("if %s != nil {\n\t%s\n}", target, buf.String())
318}
319
320// validationCode produces Go code that runs the validations defined in the

Callers 1

recurseValidationCodeFunction · 0.85

Calls 9

IsArrayFunction · 0.92
IsMapFunction · 0.92
IsUnionFunction · 0.92
IsAliasFunction · 0.92
recurseValidationCodeFunction · 0.85
hasValidationsFunction · 0.85
ExecuteMethod · 0.80
StringMethod · 0.65
NameMethod · 0.65

Tested by

no test coverage detected