URI: 
       exec.go - hugo - [fork] hugo port for 9front
  HTML git clone https://git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       exec.go (34214B)
       ---
            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.
            4 
            5 package template
            6 
            7 import (
            8         "errors"
            9         "fmt"
           10         "github.com/gohugoio/hugo/tpl/internal/go_templates/fmtsort"
           11         "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate/parse"
           12         "io"
           13         "reflect"
           14         "runtime"
           15         "strings"
           16 )
           17 
           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()
           23 
           24 func initMaxExecDepth() int {
           25         if runtime.GOARCH == "wasm" {
           26                 return 1000
           27         }
           28         return 100000
           29 }
           30 
           31 // state represents the state of an execution. It's not part of the
           32 // template so that multiple executions of the same template
           33 // can execute in parallel.
           34 type stateOld struct {
           35         tmpl  *Template
           36         wr    io.Writer
           37         node  parse.Node // current node, for errors
           38         vars  []variable // push-down stack of variable values.
           39         depth int        // the height of the stack of executing templates.
           40 }
           41 
           42 // variable holds the dynamic value of a variable such as $, $x etc.
           43 type variable struct {
           44         name  string
           45         value reflect.Value
           46 }
           47 
           48 // push pushes a new variable on the stack.
           49 func (s *state) push(name string, value reflect.Value) {
           50         s.vars = append(s.vars, variable{name, value})
           51 }
           52 
           53 // mark returns the length of the variable stack.
           54 func (s *state) mark() int {
           55         return len(s.vars)
           56 }
           57 
           58 // pop pops the variable stack up to the mark.
           59 func (s *state) pop(mark int) {
           60         s.vars = s.vars[0:mark]
           61 }
           62 
           63 // setVar overwrites the last declared variable with the given name.
           64 // Used by variable assignments.
           65 func (s *state) setVar(name string, value reflect.Value) {
           66         for i := s.mark() - 1; i >= 0; i-- {
           67                 if s.vars[i].name == name {
           68                         s.vars[i].value = value
           69                         return
           70                 }
           71         }
           72         s.errorf("undefined variable: %s", name)
           73 }
           74 
           75 // setTopVar overwrites the top-nth variable on the stack. Used by range iterations.
           76 func (s *state) setTopVar(n int, value reflect.Value) {
           77         s.vars[len(s.vars)-n].value = value
           78 }
           79 
           80 // varValue returns the value of the named variable.
           81 func (s *state) varValue(name string) reflect.Value {
           82         for i := s.mark() - 1; i >= 0; i-- {
           83                 if s.vars[i].name == name {
           84                         return s.vars[i].value
           85                 }
           86         }
           87         s.errorf("undefined variable: %s", name)
           88         return zero
           89 }
           90 
           91 var zero reflect.Value
           92 
           93 type missingValType struct{}
           94 
           95 var missingVal = reflect.ValueOf(missingValType{})
           96 
           97 var missingValReflectType = reflect.TypeFor[missingValType]()
           98 
           99 func isMissing(v reflect.Value) bool {
          100         return v.IsValid() && v.Type() == missingValReflectType
          101 }
          102 
          103 // at marks the state to be on node n, for error reporting.
          104 func (s *state) at(node parse.Node) {
          105         s.node = node
          106 }
          107 
          108 // doublePercent returns the string with %'s replaced by %%, if necessary,
          109 // so it can be used safely inside a Printf format string.
          110 func doublePercent(str string) string {
          111         return strings.ReplaceAll(str, "%", "%%")
          112 }
          113 
          114 // TODO: It would be nice if ExecError was more broken down, but
          115 // the way ErrorContext embeds the template name makes the
          116 // processing too clumsy.
          117 
          118 // ExecError is the custom error type returned when Execute has an
          119 // error evaluating its template. (If a write error occurs, the actual
          120 // error is returned; it will not be of type ExecError.)
          121 type ExecError struct {
          122         Name string // Name of template.
          123         Err  error  // Pre-formatted error.
          124 }
          125 
          126 func (e ExecError) Error() string {
          127         return e.Err.Error()
          128 }
          129 
          130 func (e ExecError) Unwrap() error {
          131         return e.Err
          132 }
          133 
          134 // errorf records an ExecError and terminates processing.
          135 func (s *state) errorf(format string, args ...any) {
          136         name := doublePercent(s.tmpl.Name())
          137         if s.node == nil {
          138                 format = fmt.Sprintf("template: %s: %s", name, format)
          139         } else {
          140                 location, context := s.tmpl.ErrorContext(s.node)
          141                 format = fmt.Sprintf("template: %s: executing %q at <%s>: %s", location, name, doublePercent(context), format)
          142         }
          143         panic(ExecError{
          144                 Name: s.tmpl.Name(),
          145                 Err:  fmt.Errorf(format, args...),
          146         })
          147 }
          148 
          149 // writeError is the wrapper type used internally when Execute has an
          150 // error writing to its output. We strip the wrapper in errRecover.
          151 // Note that this is not an implementation of error, so it cannot escape
          152 // from the package as an error value.
          153 type writeError struct {
          154         Err error // Original error.
          155 }
          156 
          157 func (s *state) writeError(err error) {
          158         panic(writeError{
          159                 Err: err,
          160         })
          161 }
          162 
          163 // errRecover is the handler that turns panics into returns from the top
          164 // level of Parse.
          165 func errRecover(errp *error) {
          166         e := recover()
          167         if e != nil {
          168                 switch err := e.(type) {
          169                 case runtime.Error:
          170                         panic(e)
          171                 case writeError:
          172                         *errp = err.Err // Strip the wrapper.
          173                 case ExecError:
          174                         *errp = err // Keep the wrapper.
          175                 default:
          176                         panic(e)
          177                 }
          178         }
          179 }
          180 
          181 // ExecuteTemplate applies the template associated with t that has the given name
          182 // to the specified data object and writes the output to wr.
          183 // If an error occurs executing the template or writing its output,
          184 // execution stops, but partial results may already have been written to
          185 // the output writer.
          186 // A template may be executed safely in parallel, although if parallel
          187 // executions share a Writer the output may be interleaved.
          188 func (t *Template) ExecuteTemplate(wr io.Writer, name string, data any) error {
          189         tmpl := t.Lookup(name)
          190         if tmpl == nil {
          191                 return fmt.Errorf("template: no template %q associated with template %q", name, t.name)
          192         }
          193         return tmpl.Execute(wr, data)
          194 }
          195 
          196 // Execute applies a parsed template to the specified data object,
          197 // and writes the output to wr.
          198 // If an error occurs executing the template or writing its output,
          199 // execution stops, but partial results may already have been written to
          200 // the output writer.
          201 // A template may be executed safely in parallel, although if parallel
          202 // executions share a Writer the output may be interleaved.
          203 //
          204 // If data is a [reflect.Value], the template applies to the concrete
          205 // value that the reflect.Value holds, as in [fmt.Print].
          206 func (t *Template) Execute(wr io.Writer, data any) error {
          207         return t.execute(wr, data)
          208 }
          209 
          210 func (t *Template) execute(wr io.Writer, data any) (err error) {
          211         defer errRecover(&err)
          212         value, ok := data.(reflect.Value)
          213         if !ok {
          214                 value = reflect.ValueOf(data)
          215         }
          216         state := &state{
          217                 tmpl: t,
          218                 wr:   wr,
          219                 vars: []variable{{"$", value}},
          220         }
          221         if t.Tree == nil || t.Root == nil {
          222                 state.errorf("%q is an incomplete or empty template", t.Name())
          223         }
          224         state.walk(value, t.Root)
          225         return
          226 }
          227 
          228 // DefinedTemplates returns a string listing the defined templates,
          229 // prefixed by the string "; defined templates are: ". If there are none,
          230 // it returns the empty string. For generating an error message here
          231 // and in [html/template].
          232 func (t *Template) DefinedTemplates() string {
          233         if t.common == nil {
          234                 return ""
          235         }
          236         var b strings.Builder
          237         t.muTmpl.RLock()
          238         defer t.muTmpl.RUnlock()
          239         for name, tmpl := range t.tmpl {
          240                 if tmpl.Tree == nil || tmpl.Root == nil {
          241                         continue
          242                 }
          243                 if b.Len() == 0 {
          244                         b.WriteString("; defined templates are: ")
          245                 } else {
          246                         b.WriteString(", ")
          247                 }
          248                 fmt.Fprintf(&b, "%q", name)
          249         }
          250         return b.String()
          251 }
          252 
          253 // Sentinel errors for use with panic to signal early exits from range loops.
          254 var (
          255         walkBreak    = errors.New("break")
          256         walkContinue = errors.New("continue")
          257 )
          258 
          259 // Walk functions step through the major pieces of the template structure,
          260 // generating output as they go.
          261 func (s *state) walk(dot reflect.Value, node parse.Node) {
          262         s.at(node)
          263         switch node := node.(type) {
          264         case *parse.ActionNode:
          265                 // Do not pop variables so they persist until next end.
          266                 // Also, if the action declares variables, don't print the result.
          267                 val := s.evalPipeline(dot, node.Pipe)
          268                 if len(node.Pipe.Decl) == 0 {
          269                         s.printValue(node, val)
          270                 }
          271         case *parse.BreakNode:
          272                 panic(walkBreak)
          273         case *parse.CommentNode:
          274         case *parse.ContinueNode:
          275                 panic(walkContinue)
          276         case *parse.IfNode:
          277                 s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.ElseList)
          278         case *parse.ListNode:
          279                 for _, node := range node.Nodes {
          280                         s.walk(dot, node)
          281                 }
          282         case *parse.RangeNode:
          283                 s.walkRange(dot, node)
          284         case *parse.TemplateNode:
          285                 s.walkTemplate(dot, node)
          286         case *parse.TextNode:
          287                 if _, err := s.wr.Write(node.Text); err != nil {
          288                         s.writeError(err)
          289                 }
          290         case *parse.WithNode:
          291                 s.walkIfOrWith(parse.NodeWith, dot, node.Pipe, node.List, node.ElseList)
          292         default:
          293                 s.errorf("unknown node: %s", node)
          294         }
          295 }
          296 
          297 // walkIfOrWith walks an 'if' or 'with' node. The two control structures
          298 // are identical in behavior except that 'with' sets dot.
          299 func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.PipeNode, list, elseList *parse.ListNode) {
          300         defer s.pop(s.mark())
          301         val := s.evalPipeline(dot, pipe)
          302         truth, ok := isTrue(indirectInterface(val))
          303         if !ok {
          304                 s.errorf("if/with can't use %v", val)
          305         }
          306         if truth {
          307                 if typ == parse.NodeWith {
          308                         s.walk(val, list)
          309                 } else {
          310                         s.walk(dot, list)
          311                 }
          312         } else if elseList != nil {
          313                 s.walk(dot, elseList)
          314         }
          315 }
          316 
          317 // IsTrue reports whether the value is 'true', in the sense of not the zero of its type,
          318 // and whether the value has a meaningful truth value. This is the definition of
          319 // truth used by if and other such actions.
          320 func IsTrue(val any) (truth, ok bool) {
          321         return isTrue(reflect.ValueOf(val))
          322 }
          323 
          324 func isTrueOld(val reflect.Value) (truth, ok bool) {
          325         if !val.IsValid() {
          326                 // Something like var x interface{}, never set. It's a form of nil.
          327                 return false, true
          328         }
          329         switch val.Kind() {
          330         case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
          331                 truth = val.Len() > 0
          332         case reflect.Bool:
          333                 truth = val.Bool()
          334         case reflect.Complex64, reflect.Complex128:
          335                 truth = val.Complex() != 0
          336         case reflect.Chan, reflect.Func, reflect.Pointer, reflect.Interface:
          337                 truth = !val.IsNil()
          338         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
          339                 truth = val.Int() != 0
          340         case reflect.Float32, reflect.Float64:
          341                 truth = val.Float() != 0
          342         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
          343                 truth = val.Uint() != 0
          344         case reflect.Struct:
          345                 truth = true // Struct values are always true.
          346         default:
          347                 return
          348         }
          349         return truth, true
          350 }
          351 
          352 func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
          353         s.at(r)
          354         defer func() {
          355                 if r := recover(); r != nil && r != walkBreak {
          356                         panic(r)
          357                 }
          358         }()
          359         defer s.pop(s.mark())
          360         val, _ := indirect(s.evalPipeline(dot, r.Pipe))
          361         // mark top of stack before any variables in the body are pushed.
          362         mark := s.mark()
          363         oneIteration := func(index, elem reflect.Value) {
          364                 if len(r.Pipe.Decl) > 0 {
          365                         if r.Pipe.IsAssign {
          366                                 // With two variables, index comes first.
          367                                 // With one, we use the element.
          368                                 if len(r.Pipe.Decl) > 1 {
          369                                         s.setVar(r.Pipe.Decl[0].Ident[0], index)
          370                                 } else {
          371                                         s.setVar(r.Pipe.Decl[0].Ident[0], elem)
          372                                 }
          373                         } else {
          374                                 // Set top var (lexically the second if there
          375                                 // are two) to the element.
          376                                 s.setTopVar(1, elem)
          377                         }
          378                 }
          379                 if len(r.Pipe.Decl) > 1 {
          380                         if r.Pipe.IsAssign {
          381                                 s.setVar(r.Pipe.Decl[1].Ident[0], elem)
          382                         } else {
          383                                 // Set next var (lexically the first if there
          384                                 // are two) to the index.
          385                                 s.setTopVar(2, index)
          386                         }
          387                 }
          388                 defer s.pop(mark)
          389                 defer func() {
          390                         // Consume panic(walkContinue)
          391                         if r := recover(); r != nil && r != walkContinue {
          392                                 panic(r)
          393                         }
          394                 }()
          395                 s.walk(elem, r.List)
          396         }
          397         switch val.Kind() {
          398         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
          399                 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
          400                 if len(r.Pipe.Decl) > 1 {
          401                         s.errorf("can't use %v to iterate over more than one variable", val)
          402                         break
          403                 }
          404                 run := false
          405                 for v := range val.Seq() {
          406                         run = true
          407                         // Pass element as second value, as we do for channels.
          408                         oneIteration(reflect.Value{}, v)
          409                 }
          410                 if !run {
          411                         break
          412                 }
          413                 return
          414         case reflect.Array, reflect.Slice:
          415                 if val.Len() == 0 {
          416                         break
          417                 }
          418                 for i := 0; i < val.Len(); i++ {
          419                         oneIteration(reflect.ValueOf(i), val.Index(i))
          420                 }
          421                 return
          422         case reflect.Map:
          423                 if val.Len() == 0 {
          424                         break
          425                 }
          426                 om := fmtsort.Sort(val)
          427                 for _, m := range om {
          428                         oneIteration(m.Key, m.Value)
          429                 }
          430                 return
          431         case reflect.Chan:
          432                 if val.IsNil() {
          433                         break
          434                 }
          435                 if val.Type().ChanDir() == reflect.SendDir {
          436                         s.errorf("range over send-only channel %v", val)
          437                         break
          438                 }
          439                 i := 0
          440                 for ; ; i++ {
          441                         elem, ok := val.Recv()
          442                         if !ok {
          443                                 break
          444                         }
          445                         oneIteration(reflect.ValueOf(i), elem)
          446                 }
          447                 if i == 0 {
          448                         break
          449                 }
          450                 return
          451         case reflect.Invalid:
          452                 break // An invalid value is likely a nil map, etc. and acts like an empty map.
          453         case reflect.Func:
          454                 if val.Type().CanSeq() {
          455                         if len(r.Pipe.Decl) > 1 {
          456                                 s.errorf("can't use %v iterate over more than one variable", val)
          457                                 break
          458                         }
          459                         run := false
          460                         for v := range val.Seq() {
          461                                 run = true
          462                                 // Pass element as second value,
          463                                 // as we do for channels.
          464                                 oneIteration(reflect.Value{}, v)
          465                         }
          466                         if !run {
          467                                 break
          468                         }
          469                         return
          470                 }
          471                 if val.Type().CanSeq2() {
          472                         run := false
          473                         for i, v := range val.Seq2() {
          474                                 run = true
          475                                 if len(r.Pipe.Decl) > 1 {
          476                                         oneIteration(i, v)
          477                                 } else {
          478                                         // If there is only one range variable,
          479                                         // oneIteration will use the
          480                                         // second value.
          481                                         oneIteration(reflect.Value{}, i)
          482                                 }
          483                         }
          484                         if !run {
          485                                 break
          486                         }
          487                         return
          488                 }
          489                 fallthrough
          490         default:
          491                 s.errorf("range can't iterate over %v", val)
          492         }
          493         if r.ElseList != nil {
          494                 s.walk(dot, r.ElseList)
          495         }
          496 }
          497 
          498 func (s *state) walkTemplate(dot reflect.Value, t *parse.TemplateNode) {
          499         s.at(t)
          500         tmpl := s.tmpl.Lookup(t.Name)
          501         if tmpl == nil {
          502                 s.errorf("template %q not defined", t.Name)
          503         }
          504         if s.depth == maxExecDepth {
          505                 s.errorf("exceeded maximum template depth (%v)", maxExecDepth)
          506         }
          507         // Variables declared by the pipeline persist.
          508         dot = s.evalPipeline(dot, t.Pipe)
          509         newState := *s
          510         newState.depth++
          511         newState.tmpl = tmpl
          512         // No dynamic scoping: template invocations inherit no variables.
          513         newState.vars = []variable{{"$", dot}}
          514         newState.walk(dot, tmpl.Root)
          515 }
          516 
          517 // Eval functions evaluate pipelines, commands, and their elements and extract
          518 // values from the data structure by examining fields, calling methods, and so on.
          519 // The printing of those values happens only through walk functions.
          520 
          521 // evalPipeline returns the value acquired by evaluating a pipeline. If the
          522 // pipeline has a variable declaration, the variable will be pushed on the
          523 // stack. Callers should therefore pop the stack after they are finished
          524 // executing commands depending on the pipeline value.
          525 func (s *state) evalPipeline(dot reflect.Value, pipe *parse.PipeNode) (value reflect.Value) {
          526         if pipe == nil {
          527                 return
          528         }
          529         s.at(pipe)
          530         value = missingVal
          531         for _, cmd := range pipe.Cmds {
          532                 value = s.evalCommand(dot, cmd, value) // previous value is this one's final arg.
          533                 // If the object has type interface{}, dig down one level to the thing inside.
          534                 if value.Kind() == reflect.Interface && value.Type().NumMethod() == 0 {
          535                         value = value.Elem()
          536                 }
          537         }
          538         for _, variable := range pipe.Decl {
          539                 if pipe.IsAssign {
          540                         s.setVar(variable.Ident[0], value)
          541                 } else {
          542                         s.push(variable.Ident[0], value)
          543                 }
          544         }
          545         return value
          546 }
          547 
          548 func (s *state) notAFunction(args []parse.Node, final reflect.Value) {
          549         if len(args) > 1 || !isMissing(final) {
          550                 s.errorf("can't give argument to non-function %s", args[0])
          551         }
          552 }
          553 
          554 func (s *state) evalCommand(dot reflect.Value, cmd *parse.CommandNode, final reflect.Value) reflect.Value {
          555         firstWord := cmd.Args[0]
          556         switch n := firstWord.(type) {
          557         case *parse.FieldNode:
          558                 return s.evalFieldNode(dot, n, cmd.Args, final)
          559         case *parse.ChainNode:
          560                 return s.evalChainNode(dot, n, cmd.Args, final)
          561         case *parse.IdentifierNode:
          562                 // Must be a function.
          563                 return s.evalFunction(dot, n, cmd, cmd.Args, final)
          564         case *parse.PipeNode:
          565                 // Parenthesized pipeline. The arguments are all inside the pipeline; final must be absent.
          566                 s.notAFunction(cmd.Args, final)
          567                 return s.evalPipeline(dot, n)
          568         case *parse.VariableNode:
          569                 return s.evalVariableNode(dot, n, cmd.Args, final)
          570         }
          571         s.at(firstWord)
          572         s.notAFunction(cmd.Args, final)
          573         switch word := firstWord.(type) {
          574         case *parse.BoolNode:
          575                 return reflect.ValueOf(word.True)
          576         case *parse.DotNode:
          577                 return dot
          578         case *parse.NilNode:
          579                 s.errorf("nil is not a command")
          580         case *parse.NumberNode:
          581                 return s.idealConstant(word)
          582         case *parse.StringNode:
          583                 return reflect.ValueOf(word.Text)
          584         }
          585         s.errorf("can't evaluate command %q", firstWord)
          586         panic("not reached")
          587 }
          588 
          589 // idealConstant is called to return the value of a number in a context where
          590 // we don't know the type. In that case, the syntax of the number tells us
          591 // its type, and we use Go rules to resolve. Note there is no such thing as
          592 // a uint ideal constant in this situation - the value must be of int type.
          593 func (s *state) idealConstant(constant *parse.NumberNode) reflect.Value {
          594         // These are ideal constants but we don't know the type
          595         // and we have no context.  (If it was a method argument,
          596         // we'd know what we need.) The syntax guides us to some extent.
          597         s.at(constant)
          598         switch {
          599         case constant.IsComplex:
          600                 return reflect.ValueOf(constant.Complex128) // incontrovertible.
          601 
          602         case constant.IsFloat &&
          603                 !isHexInt(constant.Text) && !isRuneInt(constant.Text) &&
          604                 strings.ContainsAny(constant.Text, ".eEpP"):
          605                 return reflect.ValueOf(constant.Float64)
          606 
          607         case constant.IsInt:
          608                 n := int(constant.Int64)
          609                 if int64(n) != constant.Int64 {
          610                         s.errorf("%s overflows int", constant.Text)
          611                 }
          612                 return reflect.ValueOf(n)
          613 
          614         case constant.IsUint:
          615                 s.errorf("%s overflows int", constant.Text)
          616         }
          617         return zero
          618 }
          619 
          620 func isRuneInt(s string) bool {
          621         return len(s) > 0 && s[0] == '\''
          622 }
          623 
          624 func isHexInt(s string) bool {
          625         return len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') && !strings.ContainsAny(s, "pP")
          626 }
          627 
          628 func (s *state) evalFieldNode(dot reflect.Value, field *parse.FieldNode, args []parse.Node, final reflect.Value) reflect.Value {
          629         s.at(field)
          630         return s.evalFieldChain(dot, dot, field, field.Ident, args, final)
          631 }
          632 
          633 func (s *state) evalChainNode(dot reflect.Value, chain *parse.ChainNode, args []parse.Node, final reflect.Value) reflect.Value {
          634         s.at(chain)
          635         if len(chain.Field) == 0 {
          636                 s.errorf("internal error: no fields in evalChainNode")
          637         }
          638         if chain.Node.Type() == parse.NodeNil {
          639                 s.errorf("indirection through explicit nil in %s", chain)
          640         }
          641         // (pipe).Field1.Field2 has pipe as .Node, fields as .Field. Eval the pipeline, then the fields.
          642         pipe := s.evalArg(dot, nil, chain.Node)
          643         return s.evalFieldChain(dot, pipe, chain, chain.Field, args, final)
          644 }
          645 
          646 func (s *state) evalVariableNode(dot reflect.Value, variable *parse.VariableNode, args []parse.Node, final reflect.Value) reflect.Value {
          647         // $x.Field has $x as the first ident, Field as the second. Eval the var, then the fields.
          648         s.at(variable)
          649         value := s.varValue(variable.Ident[0])
          650         if len(variable.Ident) == 1 {
          651                 s.notAFunction(args, final)
          652                 return value
          653         }
          654         return s.evalFieldChain(dot, value, variable, variable.Ident[1:], args, final)
          655 }
          656 
          657 // evalFieldChain evaluates .X.Y.Z possibly followed by arguments.
          658 // dot is the environment in which to evaluate arguments, while
          659 // receiver is the value being walked along the chain.
          660 func (s *state) evalFieldChain(dot, receiver reflect.Value, node parse.Node, ident []string, args []parse.Node, final reflect.Value) reflect.Value {
          661         n := len(ident)
          662         for i := 0; i < n-1; i++ {
          663                 receiver = s.evalField(dot, ident[i], node, nil, missingVal, receiver)
          664         }
          665         // Now if it's a method, it gets the arguments.
          666         return s.evalField(dot, ident[n-1], node, args, final, receiver)
          667 }
          668 
          669 func (s *state) evalFunctionOld(dot reflect.Value, node *parse.IdentifierNode, cmd parse.Node, args []parse.Node, final reflect.Value) reflect.Value {
          670         s.at(node)
          671         name := node.Ident
          672         function, isBuiltin, ok := findFunction(name, s.tmpl)
          673         if !ok {
          674                 s.errorf("%q is not a defined function", name)
          675         }
          676         return s.evalCall(dot, function, isBuiltin, cmd, name, args, final)
          677 }
          678 
          679 // evalField evaluates an expression like (.Field) or (.Field arg1 arg2).
          680 // The 'final' argument represents the return value from the preceding
          681 // value of the pipeline, if any.
          682 func (s *state) evalFieldOld(dot reflect.Value, fieldName string, node parse.Node, args []parse.Node, final, receiver reflect.Value) reflect.Value {
          683         if !receiver.IsValid() {
          684                 if s.tmpl.option.missingKey == mapError { // Treat invalid value as missing map key.
          685                         s.errorf("nil data; no entry for key %q", fieldName)
          686                 }
          687                 return zero
          688         }
          689         typ := receiver.Type()
          690         receiver, isNil := indirect(receiver)
          691         if receiver.Kind() == reflect.Interface && isNil {
          692                 // Calling a method on a nil interface can't work. The
          693                 // MethodByName method call below would panic.
          694                 s.errorf("nil pointer evaluating %s.%s", typ, fieldName)
          695                 return zero
          696         }
          697 
          698         // Unless it's an interface, need to get to a value of type *T to guarantee
          699         // we see all methods of T and *T.
          700         ptr := receiver
          701         if ptr.Kind() != reflect.Interface && ptr.Kind() != reflect.Pointer && ptr.CanAddr() {
          702                 ptr = ptr.Addr()
          703         }
          704         if method := ptr.MethodByName(fieldName); method.IsValid() {
          705                 return s.evalCall(dot, method, false, node, fieldName, args, final)
          706         }
          707         hasArgs := len(args) > 1 || !isMissing(final)
          708         // It's not a method; must be a field of a struct or an element of a map.
          709         switch receiver.Kind() {
          710         case reflect.Struct:
          711                 tField, ok := receiver.Type().FieldByName(fieldName)
          712                 if ok {
          713                         field, err := receiver.FieldByIndexErr(tField.Index)
          714                         if !tField.IsExported() {
          715                                 s.errorf("%s is an unexported field of struct type %s", fieldName, typ)
          716                         }
          717                         if err != nil {
          718                                 s.errorf("%v", err)
          719                         }
          720                         // If it's a function, we must call it.
          721                         if hasArgs {
          722                                 s.errorf("%s has arguments but cannot be invoked as function", fieldName)
          723                         }
          724                         return field
          725                 }
          726         case reflect.Map:
          727                 // If it's a map, attempt to use the field name as a key.
          728                 nameVal := reflect.ValueOf(fieldName)
          729                 if nameVal.Type().AssignableTo(receiver.Type().Key()) {
          730                         if hasArgs {
          731                                 s.errorf("%s is not a method but has arguments", fieldName)
          732                         }
          733                         result := receiver.MapIndex(nameVal)
          734                         if !result.IsValid() {
          735                                 switch s.tmpl.option.missingKey {
          736                                 case mapInvalid:
          737                                         // Just use the invalid value.
          738                                 case mapZeroValue:
          739                                         result = reflect.Zero(receiver.Type().Elem())
          740                                 case mapError:
          741                                         s.errorf("map has no entry for key %q", fieldName)
          742                                 }
          743                         }
          744                         return result
          745                 }
          746         case reflect.Pointer:
          747                 etyp := receiver.Type().Elem()
          748                 if etyp.Kind() == reflect.Struct {
          749                         if _, ok := etyp.FieldByName(fieldName); !ok {
          750                                 // If there's no such field, say "can't evaluate"
          751                                 // instead of "nil pointer evaluating".
          752                                 break
          753                         }
          754                 }
          755                 if isNil {
          756                         s.errorf("nil pointer evaluating %s.%s", typ, fieldName)
          757                 }
          758         }
          759         s.errorf("can't evaluate field %s in type %s", fieldName, typ)
          760         panic("not reached")
          761 }
          762 
          763 var (
          764         errorType        = reflect.TypeFor[error]()
          765         fmtStringerType  = reflect.TypeFor[fmt.Stringer]()
          766         reflectValueType = reflect.TypeFor[reflect.Value]()
          767 )
          768 
          769 // evalCall executes a function or method call. If it's a method, fun already has the receiver bound, so
          770 // it looks just like a function call. The arg list, if non-nil, includes (in the manner of the shell), arg[0]
          771 // as the function itself.
          772 func (s *state) evalCallOld(dot, fun reflect.Value, isBuiltin bool, node parse.Node, name string, args []parse.Node, final reflect.Value) reflect.Value {
          773         if args != nil {
          774                 args = args[1:] // Zeroth arg is function name/node; not passed to function.
          775         }
          776         typ := fun.Type()
          777         numIn := len(args)
          778         if !isMissing(final) {
          779                 numIn++
          780         }
          781         numFixed := len(args)
          782         if typ.IsVariadic() {
          783                 numFixed = typ.NumIn() - 1 // last arg is the variadic one.
          784                 if numIn < numFixed {
          785                         s.errorf("wrong number of args for %s: want at least %d got %d", name, typ.NumIn()-1, len(args))
          786                 }
          787         } else if numIn != typ.NumIn() {
          788                 s.errorf("wrong number of args for %s: want %d got %d", name, typ.NumIn(), numIn)
          789         }
          790         if err := goodFunc(name, typ); err != nil {
          791                 s.errorf("%v", err)
          792         }
          793 
          794         unwrap := func(v reflect.Value) reflect.Value {
          795                 if v.Type() == reflectValueType {
          796                         v = v.Interface().(reflect.Value)
          797                 }
          798                 return v
          799         }
          800 
          801         // Special case for builtin and/or, which short-circuit.
          802         if isBuiltin && (name == "and" || name == "or") {
          803                 argType := typ.In(0)
          804                 var v reflect.Value
          805                 for _, arg := range args {
          806                         v = s.evalArg(dot, argType, arg).Interface().(reflect.Value)
          807                         if truth(v) == (name == "or") {
          808                                 // This value was already unwrapped
          809                                 // by the .Interface().(reflect.Value).
          810                                 return v
          811                         }
          812                 }
          813                 if !final.Equal(missingVal) {
          814                         // The last argument to and/or is coming from
          815                         // the pipeline. We didn't short circuit on an earlier
          816                         // argument, so we are going to return this one.
          817                         // We don't have to evaluate final, but we do
          818                         // have to check its type. Then, since we are
          819                         // going to return it, we have to unwrap it.
          820                         v = unwrap(s.validateType(final, argType))
          821                 }
          822                 return v
          823         }
          824 
          825         // Build the arg list.
          826         argv := make([]reflect.Value, numIn)
          827         // Args must be evaluated. Fixed args first.
          828         i := 0
          829         for ; i < numFixed && i < len(args); i++ {
          830                 argv[i] = s.evalArg(dot, typ.In(i), args[i])
          831         }
          832         // Now the ... args.
          833         if typ.IsVariadic() {
          834                 argType := typ.In(typ.NumIn() - 1).Elem() // Argument is a slice.
          835                 for ; i < len(args); i++ {
          836                         argv[i] = s.evalArg(dot, argType, args[i])
          837                 }
          838         }
          839         // Add final value if necessary.
          840         if !isMissing(final) {
          841                 t := typ.In(typ.NumIn() - 1)
          842                 if typ.IsVariadic() {
          843                         if numIn-1 < numFixed {
          844                                 // The added final argument corresponds to a fixed parameter of the function.
          845                                 // Validate against the type of the actual parameter.
          846                                 t = typ.In(numIn - 1)
          847                         } else {
          848                                 // The added final argument corresponds to the variadic part.
          849                                 // Validate against the type of the elements of the variadic slice.
          850                                 t = t.Elem()
          851                         }
          852                 }
          853                 argv[i] = s.validateType(final, t)
          854         }
          855 
          856         // Special case for the "call" builtin.
          857         // Insert the name of the callee function as the first argument.
          858         if isBuiltin && name == "call" {
          859                 var calleeName string
          860                 if len(args) == 0 {
          861                         // final must be present or we would have errored out above.
          862                         calleeName = final.String()
          863                 } else {
          864                         calleeName = args[0].String()
          865                 }
          866                 argv = append([]reflect.Value{reflect.ValueOf(calleeName)}, argv...)
          867                 fun = reflect.ValueOf(call)
          868         }
          869 
          870         v, err := safeCall(fun, argv)
          871         // If we have an error that is not nil, stop execution and return that
          872         // error to the caller.
          873         if err != nil {
          874                 s.at(node)
          875                 s.errorf("error calling %s: %w", name, err)
          876         }
          877         return unwrap(v)
          878 }
          879 
          880 // canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
          881 func canBeNil(typ reflect.Type) bool {
          882         switch typ.Kind() {
          883         case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice:
          884                 return true
          885         case reflect.Struct:
          886                 return typ == reflectValueType
          887         }
          888         return false
          889 }
          890 
          891 // validateType guarantees that the value is valid and assignable to the type.
          892 func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Value {
          893         if !value.IsValid() {
          894                 if typ == nil {
          895                         // An untyped nil interface{}. Accept as a proper nil value.
          896                         return reflect.ValueOf(nil)
          897                 }
          898                 if canBeNil(typ) {
          899                         // Like above, but use the zero value of the non-nil type.
          900                         return reflect.Zero(typ)
          901                 }
          902                 s.errorf("invalid value; expected %s", typ)
          903         }
          904         if typ == reflectValueType && value.Type() != typ {
          905                 return reflect.ValueOf(value)
          906         }
          907         if typ != nil && !value.Type().AssignableTo(typ) {
          908                 if value.Kind() == reflect.Interface && !value.IsNil() {
          909                         value = value.Elem()
          910                         if value.Type().AssignableTo(typ) {
          911                                 return value
          912                         }
          913                         // fallthrough
          914                 }
          915                 // Does one dereference or indirection work? We could do more, as we
          916                 // do with method receivers, but that gets messy and method receivers
          917                 // are much more constrained, so it makes more sense there than here.
          918                 // Besides, one is almost always all you need.
          919                 switch {
          920                 case value.Kind() == reflect.Pointer && value.Type().Elem().AssignableTo(typ):
          921                         value = value.Elem()
          922                         if !value.IsValid() {
          923                                 s.errorf("dereference of nil pointer of type %s", typ)
          924                         }
          925                 case reflect.PointerTo(value.Type()).AssignableTo(typ) && value.CanAddr():
          926                         value = value.Addr()
          927                 default:
          928                         s.errorf("wrong type for value; expected %s; got %s", typ, value.Type())
          929                 }
          930         }
          931         return value
          932 }
          933 
          934 func (s *state) evalArg(dot reflect.Value, typ reflect.Type, n parse.Node) reflect.Value {
          935         s.at(n)
          936         switch arg := n.(type) {
          937         case *parse.DotNode:
          938                 return s.validateType(dot, typ)
          939         case *parse.NilNode:
          940                 if canBeNil(typ) {
          941                         return reflect.Zero(typ)
          942                 }
          943                 s.errorf("cannot assign nil to %s", typ)
          944         case *parse.FieldNode:
          945                 return s.validateType(s.evalFieldNode(dot, arg, []parse.Node{n}, missingVal), typ)
          946         case *parse.VariableNode:
          947                 return s.validateType(s.evalVariableNode(dot, arg, nil, missingVal), typ)
          948         case *parse.PipeNode:
          949                 return s.validateType(s.evalPipeline(dot, arg), typ)
          950         case *parse.IdentifierNode:
          951                 return s.validateType(s.evalFunction(dot, arg, arg, nil, missingVal), typ)
          952         case *parse.ChainNode:
          953                 return s.validateType(s.evalChainNode(dot, arg, nil, missingVal), typ)
          954         }
          955         switch typ.Kind() {
          956         case reflect.Bool:
          957                 return s.evalBool(typ, n)
          958         case reflect.Complex64, reflect.Complex128:
          959                 return s.evalComplex(typ, n)
          960         case reflect.Float32, reflect.Float64:
          961                 return s.evalFloat(typ, n)
          962         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
          963                 return s.evalInteger(typ, n)
          964         case reflect.Interface:
          965                 if typ.NumMethod() == 0 {
          966                         return s.evalEmptyInterface(dot, n)
          967                 }
          968         case reflect.Struct:
          969                 if typ == reflectValueType {
          970                         return reflect.ValueOf(s.evalEmptyInterface(dot, n))
          971                 }
          972         case reflect.String:
          973                 return s.evalString(typ, n)
          974         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
          975                 return s.evalUnsignedInteger(typ, n)
          976         }
          977         s.errorf("can't handle %s for arg of type %s", n, typ)
          978         panic("not reached")
          979 }
          980 
          981 func (s *state) evalBool(typ reflect.Type, n parse.Node) reflect.Value {
          982         s.at(n)
          983         if n, ok := n.(*parse.BoolNode); ok {
          984                 value := reflect.New(typ).Elem()
          985                 value.SetBool(n.True)
          986                 return value
          987         }
          988         s.errorf("expected bool; found %s", n)
          989         panic("not reached")
          990 }
          991 
          992 func (s *state) evalString(typ reflect.Type, n parse.Node) reflect.Value {
          993         s.at(n)
          994         if n, ok := n.(*parse.StringNode); ok {
          995                 value := reflect.New(typ).Elem()
          996                 value.SetString(n.Text)
          997                 return value
          998         }
          999         s.errorf("expected string; found %s", n)
         1000         panic("not reached")
         1001 }
         1002 
         1003 func (s *state) evalInteger(typ reflect.Type, n parse.Node) reflect.Value {
         1004         s.at(n)
         1005         if n, ok := n.(*parse.NumberNode); ok && n.IsInt {
         1006                 value := reflect.New(typ).Elem()
         1007                 value.SetInt(n.Int64)
         1008                 return value
         1009         }
         1010         s.errorf("expected integer; found %s", n)
         1011         panic("not reached")
         1012 }
         1013 
         1014 func (s *state) evalUnsignedInteger(typ reflect.Type, n parse.Node) reflect.Value {
         1015         s.at(n)
         1016         if n, ok := n.(*parse.NumberNode); ok && n.IsUint {
         1017                 value := reflect.New(typ).Elem()
         1018                 value.SetUint(n.Uint64)
         1019                 return value
         1020         }
         1021         s.errorf("expected unsigned integer; found %s", n)
         1022         panic("not reached")
         1023 }
         1024 
         1025 func (s *state) evalFloat(typ reflect.Type, n parse.Node) reflect.Value {
         1026         s.at(n)
         1027         if n, ok := n.(*parse.NumberNode); ok && n.IsFloat {
         1028                 value := reflect.New(typ).Elem()
         1029                 value.SetFloat(n.Float64)
         1030                 return value
         1031         }
         1032         s.errorf("expected float; found %s", n)
         1033         panic("not reached")
         1034 }
         1035 
         1036 func (s *state) evalComplex(typ reflect.Type, n parse.Node) reflect.Value {
         1037         if n, ok := n.(*parse.NumberNode); ok && n.IsComplex {
         1038                 value := reflect.New(typ).Elem()
         1039                 value.SetComplex(n.Complex128)
         1040                 return value
         1041         }
         1042         s.errorf("expected complex; found %s", n)
         1043         panic("not reached")
         1044 }
         1045 
         1046 func (s *state) evalEmptyInterface(dot reflect.Value, n parse.Node) reflect.Value {
         1047         s.at(n)
         1048         switch n := n.(type) {
         1049         case *parse.BoolNode:
         1050                 return reflect.ValueOf(n.True)
         1051         case *parse.DotNode:
         1052                 return dot
         1053         case *parse.FieldNode:
         1054                 return s.evalFieldNode(dot, n, nil, missingVal)
         1055         case *parse.IdentifierNode:
         1056                 return s.evalFunction(dot, n, n, nil, missingVal)
         1057         case *parse.NilNode:
         1058                 // NilNode is handled in evalArg, the only place that calls here.
         1059                 s.errorf("evalEmptyInterface: nil (can't happen)")
         1060         case *parse.NumberNode:
         1061                 return s.idealConstant(n)
         1062         case *parse.StringNode:
         1063                 return reflect.ValueOf(n.Text)
         1064         case *parse.VariableNode:
         1065                 return s.evalVariableNode(dot, n, nil, missingVal)
         1066         case *parse.PipeNode:
         1067                 return s.evalPipeline(dot, n)
         1068         }
         1069         s.errorf("can't handle assignment of %s to empty interface argument", n)
         1070         panic("not reached")
         1071 }
         1072 
         1073 // indirect returns the item at the end of indirection, and a bool to indicate
         1074 // if it's nil. If the returned bool is true, the returned value's kind will be
         1075 // either a pointer or interface.
         1076 func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
         1077         for ; v.Kind() == reflect.Pointer || v.Kind() == reflect.Interface; v = v.Elem() {
         1078                 if v.IsNil() {
         1079                         return v, true
         1080                 }
         1081         }
         1082         return v, false
         1083 }
         1084 
         1085 // indirectInterface returns the concrete value in an interface value,
         1086 // or else the zero reflect.Value.
         1087 // That is, if v represents the interface value x, the result is the same as reflect.ValueOf(x):
         1088 // the fact that x was an interface value is forgotten.
         1089 func indirectInterface(v reflect.Value) reflect.Value {
         1090         if v.Kind() != reflect.Interface {
         1091                 return v
         1092         }
         1093         if v.IsNil() {
         1094                 return reflect.Value{}
         1095         }
         1096         return v.Elem()
         1097 }
         1098 
         1099 // printValue writes the textual representation of the value to the output of
         1100 // the template.
         1101 func (s *state) printValue(n parse.Node, v reflect.Value) {
         1102         s.at(n)
         1103         iface, ok := printableValue(v)
         1104         if !ok {
         1105                 s.errorf("can't print %s of type %s", n, v.Type())
         1106         }
         1107         _, err := fmt.Fprint(s.wr, iface)
         1108         if err != nil {
         1109                 s.writeError(err)
         1110         }
         1111 }
         1112 
         1113 // printableValue returns the, possibly indirected, interface value inside v that
         1114 // is best for a call to formatted printer.
         1115 func printableValue(v reflect.Value) (any, bool) {
         1116         if v.Kind() == reflect.Pointer {
         1117                 v, _ = indirect(v) // fmt.Fprint handles nil.
         1118         }
         1119         if !v.IsValid() {
         1120                 return "<no value>", true
         1121         }
         1122 
         1123         if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) {
         1124                 if v.CanAddr() && (reflect.PointerTo(v.Type()).Implements(errorType) || reflect.PointerTo(v.Type()).Implements(fmtStringerType)) {
         1125                         v = v.Addr()
         1126                 } else {
         1127                         switch v.Kind() {
         1128                         case reflect.Chan, reflect.Func:
         1129                                 return nil, false
         1130                         }
         1131                 }
         1132         }
         1133         return v.Interface(), true
         1134 }