1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
18 // maxExecDepth specifies the maximum stack depth of templates within
19 // templates. This limit is only practically reached by accidentally
20 // recursive template invocations. This limit allows us to return
21 // an error instead of triggering a stack overflow.
22 var maxExecDepth
= initMaxExecDepth()
24 func initMaxExecDepth() int {
25 // For gccgo we make this 1000 rather than 100000 to avoid
26 // stack overflow on non-split-stack systems.
27 if runtime
.GOARCH
== "wasm" || runtime
.Compiler
== "gccgo" {
33 // state represents the state of an execution. It's not part of the
34 // template so that multiple executions of the same template
35 // can execute in parallel.
39 node parse
.Node
// current node, for errors
40 vars
[]variable
// push-down stack of variable values.
41 depth
int // the height of the stack of executing templates.
44 // variable holds the dynamic value of a variable such as $, $x etc.
45 type variable
struct {
50 // push pushes a new variable on the stack.
51 func (s
*state
) push(name
string, value reflect
.Value
) {
52 s
.vars
= append(s
.vars
, variable
{name
, value
})
55 // mark returns the length of the variable stack.
56 func (s
*state
) mark() int {
60 // pop pops the variable stack up to the mark.
61 func (s
*state
) pop(mark
int) {
62 s
.vars
= s
.vars
[0:mark
]
65 // setVar overwrites the last declared variable with the given name.
66 // Used by variable assignments.
67 func (s
*state
) setVar(name
string, value reflect
.Value
) {
68 for i
:= s
.mark() - 1; i
>= 0; i
-- {
69 if s
.vars
[i
].name
== name
{
70 s
.vars
[i
].value
= value
74 s
.errorf("undefined variable: %s", name
)
77 // setTopVar overwrites the top-nth variable on the stack. Used by range iterations.
78 func (s
*state
) setTopVar(n
int, value reflect
.Value
) {
79 s
.vars
[len(s
.vars
)-n
].value
= value
82 // varValue returns the value of the named variable.
83 func (s
*state
) varValue(name
string) reflect
.Value
{
84 for i
:= s
.mark() - 1; i
>= 0; i
-- {
85 if s
.vars
[i
].name
== name
{
86 return s
.vars
[i
].value
89 s
.errorf("undefined variable: %s", name
)
93 var zero reflect
.Value
95 type missingValType
struct{}
97 var missingVal
= reflect
.ValueOf(missingValType
{})
99 // at marks the state to be on node n, for error reporting.
100 func (s
*state
) at(node parse
.Node
) {
104 // doublePercent returns the string with %'s replaced by %%, if necessary,
105 // so it can be used safely inside a Printf format string.
106 func doublePercent(str
string) string {
107 return strings
.ReplaceAll(str
, "%", "%%")
110 // TODO: It would be nice if ExecError was more broken down, but
111 // the way ErrorContext embeds the template name makes the
112 // processing too clumsy.
114 // ExecError is the custom error type returned when Execute has an
115 // error evaluating its template. (If a write error occurs, the actual
116 // error is returned; it will not be of type ExecError.)
117 type ExecError
struct {
118 Name
string // Name of template.
119 Err error
// Pre-formatted error.
122 func (e ExecError
) Error() string {
126 func (e ExecError
) Unwrap() error
{
130 // errorf records an ExecError and terminates processing.
131 func (s
*state
) errorf(format
string, args
...any
) {
132 name
:= doublePercent(s
.tmpl
.Name())
134 format
= fmt
.Sprintf("template: %s: %s", name
, format
)
136 location
, context
:= s
.tmpl
.ErrorContext(s
.node
)
137 format
= fmt
.Sprintf("template: %s: executing %q at <%s>: %s", location
, name
, doublePercent(context
), format
)
141 Err
: fmt
.Errorf(format
, args
...),
145 // writeError is the wrapper type used internally when Execute has an
146 // error writing to its output. We strip the wrapper in errRecover.
147 // Note that this is not an implementation of error, so it cannot escape
148 // from the package as an error value.
149 type writeError
struct {
150 Err error
// Original error.
153 func (s
*state
) writeError(err error
) {
159 // errRecover is the handler that turns panics into returns from the top
161 func errRecover(errp
*error
) {
164 switch err
:= e
.(type) {
168 *errp
= err
.Err
// Strip the wrapper.
170 *errp
= err
// Keep the wrapper.
177 // ExecuteTemplate applies the template associated with t that has the given name
178 // to the specified data object and writes the output to wr.
179 // If an error occurs executing the template or writing its output,
180 // execution stops, but partial results may already have been written to
181 // the output writer.
182 // A template may be executed safely in parallel, although if parallel
183 // executions share a Writer the output may be interleaved.
184 func (t
*Template
) ExecuteTemplate(wr io
.Writer
, name
string, data any
) error
{
185 tmpl
:= t
.Lookup(name
)
187 return fmt
.Errorf("template: no template %q associated with template %q", name
, t
.name
)
189 return tmpl
.Execute(wr
, data
)
192 // Execute applies a parsed template to the specified data object,
193 // and writes the output to wr.
194 // If an error occurs executing the template or writing its output,
195 // execution stops, but partial results may already have been written to
196 // the output writer.
197 // A template may be executed safely in parallel, although if parallel
198 // executions share a Writer the output may be interleaved.
200 // If data is a reflect.Value, the template applies to the concrete
201 // value that the reflect.Value holds, as in fmt.Print.
202 func (t
*Template
) Execute(wr io
.Writer
, data any
) error
{
203 return t
.execute(wr
, data
)
206 func (t
*Template
) execute(wr io
.Writer
, data any
) (err error
) {
207 defer errRecover(&err
)
208 value
, ok
:= data
.(reflect
.Value
)
210 value
= reflect
.ValueOf(data
)
215 vars
: []variable
{{"$", value
}},
217 if t
.Tree
== nil || t
.Root
== nil {
218 state
.errorf("%q is an incomplete or empty template", t
.Name())
220 state
.walk(value
, t
.Root
)
224 // DefinedTemplates returns a string listing the defined templates,
225 // prefixed by the string "; defined templates are: ". If there are none,
226 // it returns the empty string. For generating an error message here
227 // and in html/template.
228 func (t
*Template
) DefinedTemplates() string {
232 var b strings
.Builder
234 defer t
.muTmpl
.RUnlock()
235 for name
, tmpl
:= range t
.tmpl
{
236 if tmpl
.Tree
== nil || tmpl
.Root
== nil {
240 b
.WriteString("; defined templates are: ")
244 fmt
.Fprintf(&b
, "%q", name
)
249 // Sentinel errors for use with panic to signal early exits from range loops.
251 walkBreak
= errors
.New("break")
252 walkContinue
= errors
.New("continue")
255 // Walk functions step through the major pieces of the template structure,
256 // generating output as they go.
257 func (s
*state
) walk(dot reflect
.Value
, node parse
.Node
) {
259 switch node
:= node
.(type) {
260 case *parse
.ActionNode
:
261 // Do not pop variables so they persist until next end.
262 // Also, if the action declares variables, don't print the result.
263 val
:= s
.evalPipeline(dot
, node
.Pipe
)
264 if len(node
.Pipe
.Decl
) == 0 {
265 s
.printValue(node
, val
)
267 case *parse
.BreakNode
:
269 case *parse
.CommentNode
:
270 case *parse
.ContinueNode
:
273 s
.walkIfOrWith(parse
.NodeIf
, dot
, node
.Pipe
, node
.List
, node
.ElseList
)
274 case *parse
.ListNode
:
275 for _
, node
:= range node
.Nodes
{
278 case *parse
.RangeNode
:
279 s
.walkRange(dot
, node
)
280 case *parse
.TemplateNode
:
281 s
.walkTemplate(dot
, node
)
282 case *parse
.TextNode
:
283 if _
, err
:= s
.wr
.Write(node
.Text
); err
!= nil {
286 case *parse
.WithNode
:
287 s
.walkIfOrWith(parse
.NodeWith
, dot
, node
.Pipe
, node
.List
, node
.ElseList
)
289 s
.errorf("unknown node: %s", node
)
293 // walkIfOrWith walks an 'if' or 'with' node. The two control structures
294 // are identical in behavior except that 'with' sets dot.
295 func (s
*state
) walkIfOrWith(typ parse
.NodeType
, dot reflect
.Value
, pipe
*parse
.PipeNode
, list
, elseList
*parse
.ListNode
) {
296 defer s
.pop(s
.mark())
297 val
:= s
.evalPipeline(dot
, pipe
)
298 truth
, ok
:= isTrue(indirectInterface(val
))
300 s
.errorf("if/with can't use %v", val
)
303 if typ
== parse
.NodeWith
{
308 } else if elseList
!= nil {
309 s
.walk(dot
, elseList
)
313 // IsTrue reports whether the value is 'true', in the sense of not the zero of its type,
314 // and whether the value has a meaningful truth value. This is the definition of
315 // truth used by if and other such actions.
316 func IsTrue(val any
) (truth
, ok
bool) {
317 return isTrue(reflect
.ValueOf(val
))
320 func isTrue(val reflect
.Value
) (truth
, ok
bool) {
322 // Something like var x interface{}, never set. It's a form of nil.
326 case reflect
.Array
, reflect
.Map
, reflect
.Slice
, reflect
.String
:
327 truth
= val
.Len() > 0
330 case reflect
.Complex64
, reflect
.Complex128
:
331 truth
= val
.Complex() != 0
332 case reflect
.Chan
, reflect
.Func
, reflect
.Pointer
, reflect
.Interface
:
334 case reflect
.Int
, reflect
.Int8
, reflect
.Int16
, reflect
.Int32
, reflect
.Int64
:
335 truth
= val
.Int() != 0
336 case reflect
.Float32
, reflect
.Float64
:
337 truth
= val
.Float() != 0
338 case reflect
.Uint
, reflect
.Uint8
, reflect
.Uint16
, reflect
.Uint32
, reflect
.Uint64
, reflect
.Uintptr
:
339 truth
= val
.Uint() != 0
341 truth
= true // Struct values are always true.
348 func (s
*state
) walkRange(dot reflect
.Value
, r
*parse
.RangeNode
) {
351 if r
:= recover(); r
!= nil && r
!= walkBreak
{
355 defer s
.pop(s
.mark())
356 val
, _
:= indirect(s
.evalPipeline(dot
, r
.Pipe
))
357 // mark top of stack before any variables in the body are pushed.
359 oneIteration
:= func(index
, elem reflect
.Value
) {
360 // Set top var (lexically the second if there are two) to the element.
361 if len(r
.Pipe
.Decl
) > 0 {
364 // Set next var (lexically the first if there are two) to the index.
365 if len(r
.Pipe
.Decl
) > 1 {
366 s
.setTopVar(2, index
)
370 // Consume panic(walkContinue)
371 if r
:= recover(); r
!= nil && r
!= walkContinue
{
378 case reflect
.Array
, reflect
.Slice
:
382 for i
:= 0; i
< val
.Len(); i
++ {
383 oneIteration(reflect
.ValueOf(i
), val
.Index(i
))
390 om
:= fmtsort
.Sort(val
)
391 for i
, key
:= range om
.Key
{
392 oneIteration(key
, om
.Value
[i
])
399 if val
.Type().ChanDir() == reflect
.SendDir
{
400 s
.errorf("range over send-only channel %v", val
)
405 elem
, ok
:= val
.Recv()
409 oneIteration(reflect
.ValueOf(i
), elem
)
415 case reflect
.Invalid
:
416 break // An invalid value is likely a nil map, etc. and acts like an empty map.
418 s
.errorf("range can't iterate over %v", val
)
420 if r
.ElseList
!= nil {
421 s
.walk(dot
, r
.ElseList
)
425 func (s
*state
) walkTemplate(dot reflect
.Value
, t
*parse
.TemplateNode
) {
427 tmpl
:= s
.tmpl
.Lookup(t
.Name
)
429 s
.errorf("template %q not defined", t
.Name
)
431 if s
.depth
== maxExecDepth
{
432 s
.errorf("exceeded maximum template depth (%v)", maxExecDepth
)
434 // Variables declared by the pipeline persist.
435 dot
= s
.evalPipeline(dot
, t
.Pipe
)
439 // No dynamic scoping: template invocations inherit no variables.
440 newState
.vars
= []variable
{{"$", dot
}}
441 newState
.walk(dot
, tmpl
.Root
)
444 // Eval functions evaluate pipelines, commands, and their elements and extract
445 // values from the data structure by examining fields, calling methods, and so on.
446 // The printing of those values happens only through walk functions.
448 // evalPipeline returns the value acquired by evaluating a pipeline. If the
449 // pipeline has a variable declaration, the variable will be pushed on the
450 // stack. Callers should therefore pop the stack after they are finished
451 // executing commands depending on the pipeline value.
452 func (s
*state
) evalPipeline(dot reflect
.Value
, pipe
*parse
.PipeNode
) (value reflect
.Value
) {
458 for _
, cmd
:= range pipe
.Cmds
{
459 value
= s
.evalCommand(dot
, cmd
, value
) // previous value is this one's final arg.
460 // If the object has type interface{}, dig down one level to the thing inside.
461 if value
.Kind() == reflect
.Interface
&& value
.Type().NumMethod() == 0 {
462 value
= reflect
.ValueOf(value
.Interface()) // lovely!
465 for _
, variable
:= range pipe
.Decl
{
467 s
.setVar(variable
.Ident
[0], value
)
469 s
.push(variable
.Ident
[0], value
)
475 func (s
*state
) notAFunction(args
[]parse
.Node
, final reflect
.Value
) {
476 if len(args
) > 1 || final
!= missingVal
{
477 s
.errorf("can't give argument to non-function %s", args
[0])
481 func (s
*state
) evalCommand(dot reflect
.Value
, cmd
*parse
.CommandNode
, final reflect
.Value
) reflect
.Value
{
482 firstWord
:= cmd
.Args
[0]
483 switch n
:= firstWord
.(type) {
484 case *parse
.FieldNode
:
485 return s
.evalFieldNode(dot
, n
, cmd
.Args
, final
)
486 case *parse
.ChainNode
:
487 return s
.evalChainNode(dot
, n
, cmd
.Args
, final
)
488 case *parse
.IdentifierNode
:
489 // Must be a function.
490 return s
.evalFunction(dot
, n
, cmd
, cmd
.Args
, final
)
491 case *parse
.PipeNode
:
492 // Parenthesized pipeline. The arguments are all inside the pipeline; final must be absent.
493 s
.notAFunction(cmd
.Args
, final
)
494 return s
.evalPipeline(dot
, n
)
495 case *parse
.VariableNode
:
496 return s
.evalVariableNode(dot
, n
, cmd
.Args
, final
)
499 s
.notAFunction(cmd
.Args
, final
)
500 switch word
:= firstWord
.(type) {
501 case *parse
.BoolNode
:
502 return reflect
.ValueOf(word
.True
)
506 s
.errorf("nil is not a command")
507 case *parse
.NumberNode
:
508 return s
.idealConstant(word
)
509 case *parse
.StringNode
:
510 return reflect
.ValueOf(word
.Text
)
512 s
.errorf("can't evaluate command %q", firstWord
)
516 // idealConstant is called to return the value of a number in a context where
517 // we don't know the type. In that case, the syntax of the number tells us
518 // its type, and we use Go rules to resolve. Note there is no such thing as
519 // a uint ideal constant in this situation - the value must be of int type.
520 func (s
*state
) idealConstant(constant
*parse
.NumberNode
) reflect
.Value
{
521 // These are ideal constants but we don't know the type
522 // and we have no context. (If it was a method argument,
523 // we'd know what we need.) The syntax guides us to some extent.
526 case constant
.IsComplex
:
527 return reflect
.ValueOf(constant
.Complex128
) // incontrovertible.
529 case constant
.IsFloat
&&
530 !isHexInt(constant
.Text
) && !isRuneInt(constant
.Text
) &&
531 strings
.ContainsAny(constant
.Text
, ".eEpP"):
532 return reflect
.ValueOf(constant
.Float64
)
535 n
:= int(constant
.Int64
)
536 if int64(n
) != constant
.Int64
{
537 s
.errorf("%s overflows int", constant
.Text
)
539 return reflect
.ValueOf(n
)
541 case constant
.IsUint
:
542 s
.errorf("%s overflows int", constant
.Text
)
547 func isRuneInt(s
string) bool {
548 return len(s
) > 0 && s
[0] == '\''
551 func isHexInt(s
string) bool {
552 return len(s
) > 2 && s
[0] == '0' && (s
[1] == 'x' || s
[1] == 'X') && !strings
.ContainsAny(s
, "pP")
555 func (s
*state
) evalFieldNode(dot reflect
.Value
, field
*parse
.FieldNode
, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
557 return s
.evalFieldChain(dot
, dot
, field
, field
.Ident
, args
, final
)
560 func (s
*state
) evalChainNode(dot reflect
.Value
, chain
*parse
.ChainNode
, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
562 if len(chain
.Field
) == 0 {
563 s
.errorf("internal error: no fields in evalChainNode")
565 if chain
.Node
.Type() == parse
.NodeNil
{
566 s
.errorf("indirection through explicit nil in %s", chain
)
568 // (pipe).Field1.Field2 has pipe as .Node, fields as .Field. Eval the pipeline, then the fields.
569 pipe
:= s
.evalArg(dot
, nil, chain
.Node
)
570 return s
.evalFieldChain(dot
, pipe
, chain
, chain
.Field
, args
, final
)
573 func (s
*state
) evalVariableNode(dot reflect
.Value
, variable
*parse
.VariableNode
, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
574 // $x.Field has $x as the first ident, Field as the second. Eval the var, then the fields.
576 value
:= s
.varValue(variable
.Ident
[0])
577 if len(variable
.Ident
) == 1 {
578 s
.notAFunction(args
, final
)
581 return s
.evalFieldChain(dot
, value
, variable
, variable
.Ident
[1:], args
, final
)
584 // evalFieldChain evaluates .X.Y.Z possibly followed by arguments.
585 // dot is the environment in which to evaluate arguments, while
586 // receiver is the value being walked along the chain.
587 func (s
*state
) evalFieldChain(dot
, receiver reflect
.Value
, node parse
.Node
, ident
[]string, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
589 for i
:= 0; i
< n
-1; i
++ {
590 receiver
= s
.evalField(dot
, ident
[i
], node
, nil, missingVal
, receiver
)
592 // Now if it's a method, it gets the arguments.
593 return s
.evalField(dot
, ident
[n
-1], node
, args
, final
, receiver
)
596 func (s
*state
) evalFunction(dot reflect
.Value
, node
*parse
.IdentifierNode
, cmd parse
.Node
, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
599 function
, isBuiltin
, ok
:= findFunction(name
, s
.tmpl
)
601 s
.errorf("%q is not a defined function", name
)
603 return s
.evalCall(dot
, function
, isBuiltin
, cmd
, name
, args
, final
)
606 // evalField evaluates an expression like (.Field) or (.Field arg1 arg2).
607 // The 'final' argument represents the return value from the preceding
608 // value of the pipeline, if any.
609 func (s
*state
) evalField(dot reflect
.Value
, fieldName
string, node parse
.Node
, args
[]parse
.Node
, final
, receiver reflect
.Value
) reflect
.Value
{
610 if !receiver
.IsValid() {
611 if s
.tmpl
.option
.missingKey
== mapError
{ // Treat invalid value as missing map key.
612 s
.errorf("nil data; no entry for key %q", fieldName
)
616 typ
:= receiver
.Type()
617 receiver
, isNil
:= indirect(receiver
)
618 if receiver
.Kind() == reflect
.Interface
&& isNil
{
619 // Calling a method on a nil interface can't work. The
620 // MethodByName method call below would panic.
621 s
.errorf("nil pointer evaluating %s.%s", typ
, fieldName
)
625 // Unless it's an interface, need to get to a value of type *T to guarantee
626 // we see all methods of T and *T.
628 if ptr
.Kind() != reflect
.Interface
&& ptr
.Kind() != reflect
.Pointer
&& ptr
.CanAddr() {
631 if method
:= ptr
.MethodByName(fieldName
); method
.IsValid() {
632 return s
.evalCall(dot
, method
, false, node
, fieldName
, args
, final
)
634 hasArgs
:= len(args
) > 1 || final
!= missingVal
635 // It's not a method; must be a field of a struct or an element of a map.
636 switch receiver
.Kind() {
638 tField
, ok
:= receiver
.Type().FieldByName(fieldName
)
640 field
, err
:= receiver
.FieldByIndexErr(tField
.Index
)
641 if !tField
.IsExported() {
642 s
.errorf("%s is an unexported field of struct type %s", fieldName
, typ
)
647 // If it's a function, we must call it.
649 s
.errorf("%s has arguments but cannot be invoked as function", fieldName
)
654 // If it's a map, attempt to use the field name as a key.
655 nameVal
:= reflect
.ValueOf(fieldName
)
656 if nameVal
.Type().AssignableTo(receiver
.Type().Key()) {
658 s
.errorf("%s is not a method but has arguments", fieldName
)
660 result
:= receiver
.MapIndex(nameVal
)
661 if !result
.IsValid() {
662 switch s
.tmpl
.option
.missingKey
{
664 // Just use the invalid value.
666 result
= reflect
.Zero(receiver
.Type().Elem())
668 s
.errorf("map has no entry for key %q", fieldName
)
673 case reflect
.Pointer
:
674 etyp
:= receiver
.Type().Elem()
675 if etyp
.Kind() == reflect
.Struct
{
676 if _
, ok
:= etyp
.FieldByName(fieldName
); !ok
{
677 // If there's no such field, say "can't evaluate"
678 // instead of "nil pointer evaluating".
683 s
.errorf("nil pointer evaluating %s.%s", typ
, fieldName
)
686 s
.errorf("can't evaluate field %s in type %s", fieldName
, typ
)
691 errorType
= reflect
.TypeOf((*error
)(nil)).Elem()
692 fmtStringerType
= reflect
.TypeOf((*fmt
.Stringer
)(nil)).Elem()
693 reflectValueType
= reflect
.TypeOf((*reflect
.Value
)(nil)).Elem()
696 // evalCall executes a function or method call. If it's a method, fun already has the receiver bound, so
697 // it looks just like a function call. The arg list, if non-nil, includes (in the manner of the shell), arg[0]
698 // as the function itself.
699 func (s
*state
) evalCall(dot
, fun reflect
.Value
, isBuiltin
bool, node parse
.Node
, name
string, args
[]parse
.Node
, final reflect
.Value
) reflect
.Value
{
701 args
= args
[1:] // Zeroth arg is function name/node; not passed to function.
705 if final
!= missingVal
{
708 numFixed
:= len(args
)
709 if typ
.IsVariadic() {
710 numFixed
= typ
.NumIn() - 1 // last arg is the variadic one.
711 if numIn
< numFixed
{
712 s
.errorf("wrong number of args for %s: want at least %d got %d", name
, typ
.NumIn()-1, len(args
))
714 } else if numIn
!= typ
.NumIn() {
715 s
.errorf("wrong number of args for %s: want %d got %d", name
, typ
.NumIn(), numIn
)
718 // TODO: This could still be a confusing error; maybe goodFunc should provide info.
719 s
.errorf("can't call method/function %q with %d results", name
, typ
.NumOut())
722 unwrap
:= func(v reflect
.Value
) reflect
.Value
{
723 if v
.Type() == reflectValueType
{
724 v
= v
.Interface().(reflect
.Value
)
729 // Special case for builtin and/or, which short-circuit.
730 if isBuiltin
&& (name
== "and" || name
== "or") {
733 for _
, arg
:= range args
{
734 v
= s
.evalArg(dot
, argType
, arg
).Interface().(reflect
.Value
)
735 if truth(v
) == (name
== "or") {
736 // This value was already unwrapped
737 // by the .Interface().(reflect.Value).
741 if final
!= missingVal
{
742 // The last argument to and/or is coming from
743 // the pipeline. We didn't short circuit on an earlier
744 // argument, so we are going to return this one.
745 // We don't have to evaluate final, but we do
746 // have to check its type. Then, since we are
747 // going to return it, we have to unwrap it.
748 v
= unwrap(s
.validateType(final
, argType
))
753 // Build the arg list.
754 argv
:= make([]reflect
.Value
, numIn
)
755 // Args must be evaluated. Fixed args first.
757 for ; i
< numFixed
&& i
< len(args
); i
++ {
758 argv
[i
] = s
.evalArg(dot
, typ
.In(i
), args
[i
])
761 if typ
.IsVariadic() {
762 argType
:= typ
.In(typ
.NumIn() - 1).Elem() // Argument is a slice.
763 for ; i
< len(args
); i
++ {
764 argv
[i
] = s
.evalArg(dot
, argType
, args
[i
])
767 // Add final value if necessary.
768 if final
!= missingVal
{
769 t
:= typ
.In(typ
.NumIn() - 1)
770 if typ
.IsVariadic() {
771 if numIn
-1 < numFixed
{
772 // The added final argument corresponds to a fixed parameter of the function.
773 // Validate against the type of the actual parameter.
774 t
= typ
.In(numIn
- 1)
776 // The added final argument corresponds to the variadic part.
777 // Validate against the type of the elements of the variadic slice.
781 argv
[i
] = s
.validateType(final
, t
)
783 v
, err
:= safeCall(fun
, argv
)
784 // If we have an error that is not nil, stop execution and return that
785 // error to the caller.
788 s
.errorf("error calling %s: %w", name
, err
)
793 // canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
794 func canBeNil(typ reflect
.Type
) bool {
796 case reflect
.Chan
, reflect
.Func
, reflect
.Interface
, reflect
.Map
, reflect
.Pointer
, reflect
.Slice
:
799 return typ
== reflectValueType
804 // validateType guarantees that the value is valid and assignable to the type.
805 func (s
*state
) validateType(value reflect
.Value
, typ reflect
.Type
) reflect
.Value
{
806 if !value
.IsValid() {
808 // An untyped nil interface{}. Accept as a proper nil value.
809 return reflect
.ValueOf(nil)
812 // Like above, but use the zero value of the non-nil type.
813 return reflect
.Zero(typ
)
815 s
.errorf("invalid value; expected %s", typ
)
817 if typ
== reflectValueType
&& value
.Type() != typ
{
818 return reflect
.ValueOf(value
)
820 if typ
!= nil && !value
.Type().AssignableTo(typ
) {
821 if value
.Kind() == reflect
.Interface
&& !value
.IsNil() {
823 if value
.Type().AssignableTo(typ
) {
828 // Does one dereference or indirection work? We could do more, as we
829 // do with method receivers, but that gets messy and method receivers
830 // are much more constrained, so it makes more sense there than here.
831 // Besides, one is almost always all you need.
833 case value
.Kind() == reflect
.Pointer
&& value
.Type().Elem().AssignableTo(typ
):
835 if !value
.IsValid() {
836 s
.errorf("dereference of nil pointer of type %s", typ
)
838 case reflect
.PointerTo(value
.Type()).AssignableTo(typ
) && value
.CanAddr():
841 s
.errorf("wrong type for value; expected %s; got %s", typ
, value
.Type())
847 func (s
*state
) evalArg(dot reflect
.Value
, typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
849 switch arg
:= n
.(type) {
851 return s
.validateType(dot
, typ
)
854 return reflect
.Zero(typ
)
856 s
.errorf("cannot assign nil to %s", typ
)
857 case *parse
.FieldNode
:
858 return s
.validateType(s
.evalFieldNode(dot
, arg
, []parse
.Node
{n
}, missingVal
), typ
)
859 case *parse
.VariableNode
:
860 return s
.validateType(s
.evalVariableNode(dot
, arg
, nil, missingVal
), typ
)
861 case *parse
.PipeNode
:
862 return s
.validateType(s
.evalPipeline(dot
, arg
), typ
)
863 case *parse
.IdentifierNode
:
864 return s
.validateType(s
.evalFunction(dot
, arg
, arg
, nil, missingVal
), typ
)
865 case *parse
.ChainNode
:
866 return s
.validateType(s
.evalChainNode(dot
, arg
, nil, missingVal
), typ
)
870 return s
.evalBool(typ
, n
)
871 case reflect
.Complex64
, reflect
.Complex128
:
872 return s
.evalComplex(typ
, n
)
873 case reflect
.Float32
, reflect
.Float64
:
874 return s
.evalFloat(typ
, n
)
875 case reflect
.Int
, reflect
.Int8
, reflect
.Int16
, reflect
.Int32
, reflect
.Int64
:
876 return s
.evalInteger(typ
, n
)
877 case reflect
.Interface
:
878 if typ
.NumMethod() == 0 {
879 return s
.evalEmptyInterface(dot
, n
)
882 if typ
== reflectValueType
{
883 return reflect
.ValueOf(s
.evalEmptyInterface(dot
, n
))
886 return s
.evalString(typ
, n
)
887 case reflect
.Uint
, reflect
.Uint8
, reflect
.Uint16
, reflect
.Uint32
, reflect
.Uint64
, reflect
.Uintptr
:
888 return s
.evalUnsignedInteger(typ
, n
)
890 s
.errorf("can't handle %s for arg of type %s", n
, typ
)
894 func (s
*state
) evalBool(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
896 if n
, ok
:= n
.(*parse
.BoolNode
); ok
{
897 value
:= reflect
.New(typ
).Elem()
898 value
.SetBool(n
.True
)
901 s
.errorf("expected bool; found %s", n
)
905 func (s
*state
) evalString(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
907 if n
, ok
:= n
.(*parse
.StringNode
); ok
{
908 value
:= reflect
.New(typ
).Elem()
909 value
.SetString(n
.Text
)
912 s
.errorf("expected string; found %s", n
)
916 func (s
*state
) evalInteger(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
918 if n
, ok
:= n
.(*parse
.NumberNode
); ok
&& n
.IsInt
{
919 value
:= reflect
.New(typ
).Elem()
920 value
.SetInt(n
.Int64
)
923 s
.errorf("expected integer; found %s", n
)
927 func (s
*state
) evalUnsignedInteger(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
929 if n
, ok
:= n
.(*parse
.NumberNode
); ok
&& n
.IsUint
{
930 value
:= reflect
.New(typ
).Elem()
931 value
.SetUint(n
.Uint64
)
934 s
.errorf("expected unsigned integer; found %s", n
)
938 func (s
*state
) evalFloat(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
940 if n
, ok
:= n
.(*parse
.NumberNode
); ok
&& n
.IsFloat
{
941 value
:= reflect
.New(typ
).Elem()
942 value
.SetFloat(n
.Float64
)
945 s
.errorf("expected float; found %s", n
)
949 func (s
*state
) evalComplex(typ reflect
.Type
, n parse
.Node
) reflect
.Value
{
950 if n
, ok
:= n
.(*parse
.NumberNode
); ok
&& n
.IsComplex
{
951 value
:= reflect
.New(typ
).Elem()
952 value
.SetComplex(n
.Complex128
)
955 s
.errorf("expected complex; found %s", n
)
959 func (s
*state
) evalEmptyInterface(dot reflect
.Value
, n parse
.Node
) reflect
.Value
{
961 switch n
:= n
.(type) {
962 case *parse
.BoolNode
:
963 return reflect
.ValueOf(n
.True
)
966 case *parse
.FieldNode
:
967 return s
.evalFieldNode(dot
, n
, nil, missingVal
)
968 case *parse
.IdentifierNode
:
969 return s
.evalFunction(dot
, n
, n
, nil, missingVal
)
971 // NilNode is handled in evalArg, the only place that calls here.
972 s
.errorf("evalEmptyInterface: nil (can't happen)")
973 case *parse
.NumberNode
:
974 return s
.idealConstant(n
)
975 case *parse
.StringNode
:
976 return reflect
.ValueOf(n
.Text
)
977 case *parse
.VariableNode
:
978 return s
.evalVariableNode(dot
, n
, nil, missingVal
)
979 case *parse
.PipeNode
:
980 return s
.evalPipeline(dot
, n
)
982 s
.errorf("can't handle assignment of %s to empty interface argument", n
)
986 // indirect returns the item at the end of indirection, and a bool to indicate
987 // if it's nil. If the returned bool is true, the returned value's kind will be
988 // either a pointer or interface.
989 func indirect(v reflect
.Value
) (rv reflect
.Value
, isNil
bool) {
990 for ; v
.Kind() == reflect
.Pointer || v
.Kind() == reflect
.Interface
; v
= v
.Elem() {
998 // indirectInterface returns the concrete value in an interface value,
999 // or else the zero reflect.Value.
1000 // That is, if v represents the interface value x, the result is the same as reflect.ValueOf(x):
1001 // the fact that x was an interface value is forgotten.
1002 func indirectInterface(v reflect
.Value
) reflect
.Value
{
1003 if v
.Kind() != reflect
.Interface
{
1007 return reflect
.Value
{}
1012 // printValue writes the textual representation of the value to the output of
1014 func (s
*state
) printValue(n parse
.Node
, v reflect
.Value
) {
1016 iface
, ok
:= printableValue(v
)
1018 s
.errorf("can't print %s of type %s", n
, v
.Type())
1020 _
, err
:= fmt
.Fprint(s
.wr
, iface
)
1026 // printableValue returns the, possibly indirected, interface value inside v that
1027 // is best for a call to formatted printer.
1028 func printableValue(v reflect
.Value
) (any
, bool) {
1029 if v
.Kind() == reflect
.Pointer
{
1030 v
, _
= indirect(v
) // fmt.Fprint handles nil.
1033 return "<no value>", true
1036 if !v
.Type().Implements(errorType
) && !v
.Type().Implements(fmtStringerType
) {
1037 if v
.CanAddr() && (reflect
.PointerTo(v
.Type()).Implements(errorType
) || reflect
.PointerTo(v
.Type()).Implements(fmtStringerType
)) {
1041 case reflect
.Chan
, reflect
.Func
:
1046 return v
.Interface(), true