Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / k8s.io / client-go / third_party / forked / golang / template / funcs.go
1 //This package is copied from Go library text/template.
2 //The original private functions eq, ge, gt, le, lt, and ne
3 //are exported as public functions.
4 package template
5
6 import (
7         "bytes"
8         "errors"
9         "fmt"
10         "io"
11         "net/url"
12         "reflect"
13         "strings"
14         "unicode"
15         "unicode/utf8"
16 )
17
18 var Equal = eq
19 var GreaterEqual = ge
20 var Greater = gt
21 var LessEqual = le
22 var Less = lt
23 var NotEqual = ne
24
25 // FuncMap is the type of the map defining the mapping from names to functions.
26 // Each function must have either a single return value, or two return values of
27 // which the second has type error. In that case, if the second (error)
28 // return value evaluates to non-nil during execution, execution terminates and
29 // Execute returns that error.
30 type FuncMap map[string]interface{}
31
32 var builtins = FuncMap{
33         "and":      and,
34         "call":     call,
35         "html":     HTMLEscaper,
36         "index":    index,
37         "js":       JSEscaper,
38         "len":      length,
39         "not":      not,
40         "or":       or,
41         "print":    fmt.Sprint,
42         "printf":   fmt.Sprintf,
43         "println":  fmt.Sprintln,
44         "urlquery": URLQueryEscaper,
45
46         // Comparisons
47         "eq": eq, // ==
48         "ge": ge, // >=
49         "gt": gt, // >
50         "le": le, // <=
51         "lt": lt, // <
52         "ne": ne, // !=
53 }
54
55 var builtinFuncs = createValueFuncs(builtins)
56
57 // createValueFuncs turns a FuncMap into a map[string]reflect.Value
58 func createValueFuncs(funcMap FuncMap) map[string]reflect.Value {
59         m := make(map[string]reflect.Value)
60         addValueFuncs(m, funcMap)
61         return m
62 }
63
64 // addValueFuncs adds to values the functions in funcs, converting them to reflect.Values.
65 func addValueFuncs(out map[string]reflect.Value, in FuncMap) {
66         for name, fn := range in {
67                 v := reflect.ValueOf(fn)
68                 if v.Kind() != reflect.Func {
69                         panic("value for " + name + " not a function")
70                 }
71                 if !goodFunc(v.Type()) {
72                         panic(fmt.Errorf("can't install method/function %q with %d results", name, v.Type().NumOut()))
73                 }
74                 out[name] = v
75         }
76 }
77
78 // AddFuncs adds to values the functions in funcs. It does no checking of the input -
79 // call addValueFuncs first.
80 func addFuncs(out, in FuncMap) {
81         for name, fn := range in {
82                 out[name] = fn
83         }
84 }
85
86 // goodFunc checks that the function or method has the right result signature.
87 func goodFunc(typ reflect.Type) bool {
88         // We allow functions with 1 result or 2 results where the second is an error.
89         switch {
90         case typ.NumOut() == 1:
91                 return true
92         case typ.NumOut() == 2 && typ.Out(1) == errorType:
93                 return true
94         }
95         return false
96 }
97
98 // findFunction looks for a function in the template, and global map.
99 func findFunction(name string) (reflect.Value, bool) {
100         if fn := builtinFuncs[name]; fn.IsValid() {
101                 return fn, true
102         }
103         return reflect.Value{}, false
104 }
105
106 // Indexing.
107
108 // index returns the result of indexing its first argument by the following
109 // arguments.  Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each
110 // indexed item must be a map, slice, or array.
111 func index(item interface{}, indices ...interface{}) (interface{}, error) {
112         v := reflect.ValueOf(item)
113         for _, i := range indices {
114                 index := reflect.ValueOf(i)
115                 var isNil bool
116                 if v, isNil = indirect(v); isNil {
117                         return nil, fmt.Errorf("index of nil pointer")
118                 }
119                 switch v.Kind() {
120                 case reflect.Array, reflect.Slice, reflect.String:
121                         var x int64
122                         switch index.Kind() {
123                         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
124                                 x = index.Int()
125                         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
126                                 x = int64(index.Uint())
127                         default:
128                                 return nil, fmt.Errorf("cannot index slice/array with type %s", index.Type())
129                         }
130                         if x < 0 || x >= int64(v.Len()) {
131                                 return nil, fmt.Errorf("index out of range: %d", x)
132                         }
133                         v = v.Index(int(x))
134                 case reflect.Map:
135                         if !index.IsValid() {
136                                 index = reflect.Zero(v.Type().Key())
137                         }
138                         if !index.Type().AssignableTo(v.Type().Key()) {
139                                 return nil, fmt.Errorf("%s is not index type for %s", index.Type(), v.Type())
140                         }
141                         if x := v.MapIndex(index); x.IsValid() {
142                                 v = x
143                         } else {
144                                 v = reflect.Zero(v.Type().Elem())
145                         }
146                 default:
147                         return nil, fmt.Errorf("can't index item of type %s", v.Type())
148                 }
149         }
150         return v.Interface(), nil
151 }
152
153 // Length
154
155 // length returns the length of the item, with an error if it has no defined length.
156 func length(item interface{}) (int, error) {
157         v, isNil := indirect(reflect.ValueOf(item))
158         if isNil {
159                 return 0, fmt.Errorf("len of nil pointer")
160         }
161         switch v.Kind() {
162         case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
163                 return v.Len(), nil
164         }
165         return 0, fmt.Errorf("len of type %s", v.Type())
166 }
167
168 // Function invocation
169
170 // call returns the result of evaluating the first argument as a function.
171 // The function must return 1 result, or 2 results, the second of which is an error.
172 func call(fn interface{}, args ...interface{}) (interface{}, error) {
173         v := reflect.ValueOf(fn)
174         typ := v.Type()
175         if typ.Kind() != reflect.Func {
176                 return nil, fmt.Errorf("non-function of type %s", typ)
177         }
178         if !goodFunc(typ) {
179                 return nil, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut())
180         }
181         numIn := typ.NumIn()
182         var dddType reflect.Type
183         if typ.IsVariadic() {
184                 if len(args) < numIn-1 {
185                         return nil, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1)
186                 }
187                 dddType = typ.In(numIn - 1).Elem()
188         } else {
189                 if len(args) != numIn {
190                         return nil, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn)
191                 }
192         }
193         argv := make([]reflect.Value, len(args))
194         for i, arg := range args {
195                 value := reflect.ValueOf(arg)
196                 // Compute the expected type. Clumsy because of variadics.
197                 var argType reflect.Type
198                 if !typ.IsVariadic() || i < numIn-1 {
199                         argType = typ.In(i)
200                 } else {
201                         argType = dddType
202                 }
203                 if !value.IsValid() && canBeNil(argType) {
204                         value = reflect.Zero(argType)
205                 }
206                 if !value.Type().AssignableTo(argType) {
207                         return nil, fmt.Errorf("arg %d has type %s; should be %s", i, value.Type(), argType)
208                 }
209                 argv[i] = value
210         }
211         result := v.Call(argv)
212         if len(result) == 2 && !result[1].IsNil() {
213                 return result[0].Interface(), result[1].Interface().(error)
214         }
215         return result[0].Interface(), nil
216 }
217
218 // Boolean logic.
219
220 func truth(a interface{}) bool {
221         t, _ := isTrue(reflect.ValueOf(a))
222         return t
223 }
224
225 // and computes the Boolean AND of its arguments, returning
226 // the first false argument it encounters, or the last argument.
227 func and(arg0 interface{}, args ...interface{}) interface{} {
228         if !truth(arg0) {
229                 return arg0
230         }
231         for i := range args {
232                 arg0 = args[i]
233                 if !truth(arg0) {
234                         break
235                 }
236         }
237         return arg0
238 }
239
240 // or computes the Boolean OR of its arguments, returning
241 // the first true argument it encounters, or the last argument.
242 func or(arg0 interface{}, args ...interface{}) interface{} {
243         if truth(arg0) {
244                 return arg0
245         }
246         for i := range args {
247                 arg0 = args[i]
248                 if truth(arg0) {
249                         break
250                 }
251         }
252         return arg0
253 }
254
255 // not returns the Boolean negation of its argument.
256 func not(arg interface{}) (truth bool) {
257         truth, _ = isTrue(reflect.ValueOf(arg))
258         return !truth
259 }
260
261 // Comparison.
262
263 // TODO: Perhaps allow comparison between signed and unsigned integers.
264
265 var (
266         errBadComparisonType = errors.New("invalid type for comparison")
267         errBadComparison     = errors.New("incompatible types for comparison")
268         errNoComparison      = errors.New("missing argument for comparison")
269 )
270
271 type kind int
272
273 const (
274         invalidKind kind = iota
275         boolKind
276         complexKind
277         intKind
278         floatKind
279         integerKind
280         stringKind
281         uintKind
282 )
283
284 func basicKind(v reflect.Value) (kind, error) {
285         switch v.Kind() {
286         case reflect.Bool:
287                 return boolKind, nil
288         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
289                 return intKind, nil
290         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
291                 return uintKind, nil
292         case reflect.Float32, reflect.Float64:
293                 return floatKind, nil
294         case reflect.Complex64, reflect.Complex128:
295                 return complexKind, nil
296         case reflect.String:
297                 return stringKind, nil
298         }
299         return invalidKind, errBadComparisonType
300 }
301
302 // eq evaluates the comparison a == b || a == c || ...
303 func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
304         v1 := reflect.ValueOf(arg1)
305         k1, err := basicKind(v1)
306         if err != nil {
307                 return false, err
308         }
309         if len(arg2) == 0 {
310                 return false, errNoComparison
311         }
312         for _, arg := range arg2 {
313                 v2 := reflect.ValueOf(arg)
314                 k2, err := basicKind(v2)
315                 if err != nil {
316                         return false, err
317                 }
318                 truth := false
319                 if k1 != k2 {
320                         // Special case: Can compare integer values regardless of type's sign.
321                         switch {
322                         case k1 == intKind && k2 == uintKind:
323                                 truth = v1.Int() >= 0 && uint64(v1.Int()) == v2.Uint()
324                         case k1 == uintKind && k2 == intKind:
325                                 truth = v2.Int() >= 0 && v1.Uint() == uint64(v2.Int())
326                         default:
327                                 return false, errBadComparison
328                         }
329                 } else {
330                         switch k1 {
331                         case boolKind:
332                                 truth = v1.Bool() == v2.Bool()
333                         case complexKind:
334                                 truth = v1.Complex() == v2.Complex()
335                         case floatKind:
336                                 truth = v1.Float() == v2.Float()
337                         case intKind:
338                                 truth = v1.Int() == v2.Int()
339                         case stringKind:
340                                 truth = v1.String() == v2.String()
341                         case uintKind:
342                                 truth = v1.Uint() == v2.Uint()
343                         default:
344                                 panic("invalid kind")
345                         }
346                 }
347                 if truth {
348                         return true, nil
349                 }
350         }
351         return false, nil
352 }
353
354 // ne evaluates the comparison a != b.
355 func ne(arg1, arg2 interface{}) (bool, error) {
356         // != is the inverse of ==.
357         equal, err := eq(arg1, arg2)
358         return !equal, err
359 }
360
361 // lt evaluates the comparison a < b.
362 func lt(arg1, arg2 interface{}) (bool, error) {
363         v1 := reflect.ValueOf(arg1)
364         k1, err := basicKind(v1)
365         if err != nil {
366                 return false, err
367         }
368         v2 := reflect.ValueOf(arg2)
369         k2, err := basicKind(v2)
370         if err != nil {
371                 return false, err
372         }
373         truth := false
374         if k1 != k2 {
375                 // Special case: Can compare integer values regardless of type's sign.
376                 switch {
377                 case k1 == intKind && k2 == uintKind:
378                         truth = v1.Int() < 0 || uint64(v1.Int()) < v2.Uint()
379                 case k1 == uintKind && k2 == intKind:
380                         truth = v2.Int() >= 0 && v1.Uint() < uint64(v2.Int())
381                 default:
382                         return false, errBadComparison
383                 }
384         } else {
385                 switch k1 {
386                 case boolKind, complexKind:
387                         return false, errBadComparisonType
388                 case floatKind:
389                         truth = v1.Float() < v2.Float()
390                 case intKind:
391                         truth = v1.Int() < v2.Int()
392                 case stringKind:
393                         truth = v1.String() < v2.String()
394                 case uintKind:
395                         truth = v1.Uint() < v2.Uint()
396                 default:
397                         panic("invalid kind")
398                 }
399         }
400         return truth, nil
401 }
402
403 // le evaluates the comparison <= b.
404 func le(arg1, arg2 interface{}) (bool, error) {
405         // <= is < or ==.
406         lessThan, err := lt(arg1, arg2)
407         if lessThan || err != nil {
408                 return lessThan, err
409         }
410         return eq(arg1, arg2)
411 }
412
413 // gt evaluates the comparison a > b.
414 func gt(arg1, arg2 interface{}) (bool, error) {
415         // > is the inverse of <=.
416         lessOrEqual, err := le(arg1, arg2)
417         if err != nil {
418                 return false, err
419         }
420         return !lessOrEqual, nil
421 }
422
423 // ge evaluates the comparison a >= b.
424 func ge(arg1, arg2 interface{}) (bool, error) {
425         // >= is the inverse of <.
426         lessThan, err := lt(arg1, arg2)
427         if err != nil {
428                 return false, err
429         }
430         return !lessThan, nil
431 }
432
433 // HTML escaping.
434
435 var (
436         htmlQuot = []byte("&#34;") // shorter than "&quot;"
437         htmlApos = []byte("&#39;") // shorter than "&apos;" and apos was not in HTML until HTML5
438         htmlAmp  = []byte("&amp;")
439         htmlLt   = []byte("&lt;")
440         htmlGt   = []byte("&gt;")
441 )
442
443 // HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
444 func HTMLEscape(w io.Writer, b []byte) {
445         last := 0
446         for i, c := range b {
447                 var html []byte
448                 switch c {
449                 case '"':
450                         html = htmlQuot
451                 case '\'':
452                         html = htmlApos
453                 case '&':
454                         html = htmlAmp
455                 case '<':
456                         html = htmlLt
457                 case '>':
458                         html = htmlGt
459                 default:
460                         continue
461                 }
462                 w.Write(b[last:i])
463                 w.Write(html)
464                 last = i + 1
465         }
466         w.Write(b[last:])
467 }
468
469 // HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
470 func HTMLEscapeString(s string) string {
471         // Avoid allocation if we can.
472         if strings.IndexAny(s, `'"&<>`) < 0 {
473                 return s
474         }
475         var b bytes.Buffer
476         HTMLEscape(&b, []byte(s))
477         return b.String()
478 }
479
480 // HTMLEscaper returns the escaped HTML equivalent of the textual
481 // representation of its arguments.
482 func HTMLEscaper(args ...interface{}) string {
483         return HTMLEscapeString(evalArgs(args))
484 }
485
486 // JavaScript escaping.
487
488 var (
489         jsLowUni = []byte(`\u00`)
490         hex      = []byte("0123456789ABCDEF")
491
492         jsBackslash = []byte(`\\`)
493         jsApos      = []byte(`\'`)
494         jsQuot      = []byte(`\"`)
495         jsLt        = []byte(`\x3C`)
496         jsGt        = []byte(`\x3E`)
497 )
498
499 // JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
500 func JSEscape(w io.Writer, b []byte) {
501         last := 0
502         for i := 0; i < len(b); i++ {
503                 c := b[i]
504
505                 if !jsIsSpecial(rune(c)) {
506                         // fast path: nothing to do
507                         continue
508                 }
509                 w.Write(b[last:i])
510
511                 if c < utf8.RuneSelf {
512                         // Quotes, slashes and angle brackets get quoted.
513                         // Control characters get written as \u00XX.
514                         switch c {
515                         case '\\':
516                                 w.Write(jsBackslash)
517                         case '\'':
518                                 w.Write(jsApos)
519                         case '"':
520                                 w.Write(jsQuot)
521                         case '<':
522                                 w.Write(jsLt)
523                         case '>':
524                                 w.Write(jsGt)
525                         default:
526                                 w.Write(jsLowUni)
527                                 t, b := c>>4, c&0x0f
528                                 w.Write(hex[t : t+1])
529                                 w.Write(hex[b : b+1])
530                         }
531                 } else {
532                         // Unicode rune.
533                         r, size := utf8.DecodeRune(b[i:])
534                         if unicode.IsPrint(r) {
535                                 w.Write(b[i : i+size])
536                         } else {
537                                 fmt.Fprintf(w, "\\u%04X", r)
538                         }
539                         i += size - 1
540                 }
541                 last = i + 1
542         }
543         w.Write(b[last:])
544 }
545
546 // JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
547 func JSEscapeString(s string) string {
548         // Avoid allocation if we can.
549         if strings.IndexFunc(s, jsIsSpecial) < 0 {
550                 return s
551         }
552         var b bytes.Buffer
553         JSEscape(&b, []byte(s))
554         return b.String()
555 }
556
557 func jsIsSpecial(r rune) bool {
558         switch r {
559         case '\\', '\'', '"', '<', '>':
560                 return true
561         }
562         return r < ' ' || utf8.RuneSelf <= r
563 }
564
565 // JSEscaper returns the escaped JavaScript equivalent of the textual
566 // representation of its arguments.
567 func JSEscaper(args ...interface{}) string {
568         return JSEscapeString(evalArgs(args))
569 }
570
571 // URLQueryEscaper returns the escaped value of the textual representation of
572 // its arguments in a form suitable for embedding in a URL query.
573 func URLQueryEscaper(args ...interface{}) string {
574         return url.QueryEscape(evalArgs(args))
575 }
576
577 // evalArgs formats the list of arguments into a string. It is therefore equivalent to
578 //      fmt.Sprint(args...)
579 // except that each argument is indirected (if a pointer), as required,
580 // using the same rules as the default string evaluation during template
581 // execution.
582 func evalArgs(args []interface{}) string {
583         ok := false
584         var s string
585         // Fast path for simple common case.
586         if len(args) == 1 {
587                 s, ok = args[0].(string)
588         }
589         if !ok {
590                 for i, arg := range args {
591                         a, ok := printableValue(reflect.ValueOf(arg))
592                         if ok {
593                                 args[i] = a
594                         } // else left fmt do its thing
595                 }
596                 s = fmt.Sprint(args...)
597         }
598         return s
599 }