(ctx *hcl.EvalContext)
| 382 | } |
| 383 | |
| 384 | func (e *expression) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { |
| 385 | switch v := e.src.(type) { |
| 386 | case *stringVal: |
| 387 | if ctx != nil { |
| 388 | // Parse string contents as a HCL native language expression. |
| 389 | // We only do this if we have a context, so passing a nil context |
| 390 | // is how the caller specifies that interpolations are not allowed |
| 391 | // and that the string should just be returned verbatim. |
| 392 | templateSrc := v.Value |
| 393 | expr, diags := hclsyntax.ParseTemplate( |
| 394 | []byte(templateSrc), |
| 395 | v.SrcRange.Filename, |
| 396 | |
| 397 | // This won't produce _exactly_ the right result, since |
| 398 | // the hclsyntax parser can't "see" any escapes we removed |
| 399 | // while parsing JSON, but it's better than nothing. |
| 400 | hcl.Pos{ |
| 401 | Line: v.SrcRange.Start.Line, |
| 402 | |
| 403 | // skip over the opening quote mark |
| 404 | Byte: v.SrcRange.Start.Byte + 1, |
| 405 | Column: v.SrcRange.Start.Column + 1, |
| 406 | }, |
| 407 | ) |
| 408 | if diags.HasErrors() { |
| 409 | return cty.DynamicVal, diags |
| 410 | } |
| 411 | val, evalDiags := expr.Value(ctx) |
| 412 | diags = append(diags, evalDiags...) |
| 413 | return val, diags |
| 414 | } |
| 415 | |
| 416 | return cty.StringVal(v.Value), nil |
| 417 | case *numberVal: |
| 418 | return cty.NumberVal(v.Value), nil |
| 419 | case *booleanVal: |
| 420 | return cty.BoolVal(v.Value), nil |
| 421 | case *arrayVal: |
| 422 | var diags hcl.Diagnostics |
| 423 | vals := []cty.Value{} |
| 424 | for _, jsonVal := range v.Values { |
| 425 | val, valDiags := (&expression{src: jsonVal}).Value(ctx) |
| 426 | vals = append(vals, val) |
| 427 | diags = append(diags, valDiags...) |
| 428 | } |
| 429 | return cty.TupleVal(vals), diags |
| 430 | case *objectVal: |
| 431 | var diags hcl.Diagnostics |
| 432 | attrs := map[string]cty.Value{} |
| 433 | attrRanges := map[string]hcl.Range{} |
| 434 | known := true |
| 435 | for _, jsonAttr := range v.Attrs { |
| 436 | // In this one context we allow keys to contain interpolation |
| 437 | // expressions too, assuming we're evaluating in interpolation |
| 438 | // mode. This achieves parity with the native syntax where |
| 439 | // object expressions can have dynamic keys, while block contents |
| 440 | // may not. |
| 441 | name, nameDiags := (&expression{src: &stringVal{ |
nothing calls this directly
no test coverage detected