| 623 | } |
| 624 | |
| 625 | func (c *stringFormatChecker) verifyString(sub ast.Expr) (bool, int64) { |
| 626 | paramA := cel.TypeParamType("A") |
| 627 | paramB := cel.TypeParamType("B") |
| 628 | subVerified := c.verifyTypeOneOf(sub.ID(), |
| 629 | cel.ListType(paramA), cel.MapType(paramA, paramB), |
| 630 | cel.IntType, cel.UintType, cel.DoubleType, cel.BoolType, cel.StringType, |
| 631 | cel.TimestampType, cel.BytesType, cel.DurationType, cel.TypeType, cel.NullType) |
| 632 | if !subVerified { |
| 633 | return false, sub.ID() |
| 634 | } |
| 635 | switch sub.Kind() { |
| 636 | case ast.ListKind: |
| 637 | for _, e := range sub.AsList().Elements() { |
| 638 | // recursively verify if we're dealing with a list/map |
| 639 | verified, id := c.verifyString(e) |
| 640 | if !verified { |
| 641 | return false, id |
| 642 | } |
| 643 | } |
| 644 | return true, sub.ID() |
| 645 | case ast.MapKind: |
| 646 | for _, e := range sub.AsMap().Entries() { |
| 647 | // recursively verify if we're dealing with a list/map |
| 648 | entry := e.AsMapEntry() |
| 649 | verified, id := c.verifyString(entry.Key()) |
| 650 | if !verified { |
| 651 | return false, id |
| 652 | } |
| 653 | verified, id = c.verifyString(entry.Value()) |
| 654 | if !verified { |
| 655 | return false, id |
| 656 | } |
| 657 | } |
| 658 | return true, sub.ID() |
| 659 | default: |
| 660 | return true, sub.ID() |
| 661 | } |
| 662 | } |
| 663 | |
| 664 | // helper routines for reporting common errors during string formatting static validation and |
| 665 | // runtime execution. |