path.go raw

   1  package yaml
   2  
   3  import (
   4  	"bytes"
   5  	"fmt"
   6  	"io"
   7  	"strconv"
   8  	"strings"
   9  
  10  	"github.com/goccy/go-yaml/ast"
  11  	"github.com/goccy/go-yaml/internal/errors"
  12  	"github.com/goccy/go-yaml/parser"
  13  	"github.com/goccy/go-yaml/printer"
  14  )
  15  
  16  // PathString create Path from string
  17  //
  18  // YAMLPath rule
  19  // $     : the root object/element
  20  // .     : child operator
  21  // ..    : recursive descent
  22  // [num] : object/element of array by number
  23  // [*]   : all objects/elements for array.
  24  //
  25  // If you want to use reserved characters such as `.` and `*` as a key name,
  26  // enclose them in single quotation as follows ( $.foo.'bar.baz-*'.hoge ).
  27  // If you want to use a single quote with reserved characters, escape it with `\` ( $.foo.'bar.baz\'s value'.hoge ).
  28  func PathString(s string) (*Path, error) {
  29  	buf := []rune(s)
  30  	length := len(buf)
  31  	cursor := 0
  32  	builder := &PathBuilder{}
  33  	for cursor < length {
  34  		c := buf[cursor]
  35  		switch c {
  36  		case '$':
  37  			builder = builder.Root()
  38  			cursor++
  39  		case '.':
  40  			b, buf, c, err := parsePathDot(builder, buf, cursor)
  41  			if err != nil {
  42  				return nil, errors.Wrapf(err, "failed to parse path of dot")
  43  			}
  44  			length = len(buf)
  45  			builder = b
  46  			cursor = c
  47  		case '[':
  48  			b, buf, c, err := parsePathIndex(builder, buf, cursor)
  49  			if err != nil {
  50  				return nil, errors.Wrapf(err, "failed to parse path of index")
  51  			}
  52  			length = len(buf)
  53  			builder = b
  54  			cursor = c
  55  		default:
  56  			return nil, errors.Wrapf(ErrInvalidPathString, "invalid path at %d", cursor)
  57  		}
  58  	}
  59  	return builder.Build(), nil
  60  }
  61  
  62  func parsePathRecursive(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune, int, error) {
  63  	length := len(buf)
  64  	cursor += 2 // skip .. characters
  65  	start := cursor
  66  	for ; cursor < length; cursor++ {
  67  		c := buf[cursor]
  68  		switch c {
  69  		case '$':
  70  			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '$' after '..' character")
  71  		case '*':
  72  			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '*' after '..' character")
  73  		case '.', '[':
  74  			goto end
  75  		case ']':
  76  			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified ']' after '..' character")
  77  		}
  78  	}
  79  end:
  80  	if start == cursor {
  81  		return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "not found recursive selector")
  82  	}
  83  	return b.Recursive(string(buf[start:cursor])), buf, cursor, nil
  84  }
  85  
  86  func parsePathDot(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune, int, error) {
  87  	length := len(buf)
  88  	if cursor+1 < length && buf[cursor+1] == '.' {
  89  		b, buf, c, err := parsePathRecursive(b, buf, cursor)
  90  		if err != nil {
  91  			return nil, nil, 0, errors.Wrapf(err, "failed to parse path of recursive")
  92  		}
  93  		return b, buf, c, nil
  94  	}
  95  	cursor++ // skip . character
  96  	start := cursor
  97  
  98  	// if started single quote, looking for end single quote char
  99  	if cursor < length && buf[cursor] == '\'' {
 100  		return parseQuotedKey(b, buf, cursor)
 101  	}
 102  	for ; cursor < length; cursor++ {
 103  		c := buf[cursor]
 104  		switch c {
 105  		case '$':
 106  			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '$' after '.' character")
 107  		case '*':
 108  			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '*' after '.' character")
 109  		case '.', '[':
 110  			goto end
 111  		case ']':
 112  			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified ']' after '.' character")
 113  		}
 114  	}
 115  end:
 116  	if start == cursor {
 117  		return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "cloud not find by empty key")
 118  	}
 119  	return b.child(string(buf[start:cursor])), buf, cursor, nil
 120  }
 121  
 122  func parseQuotedKey(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune, int, error) {
 123  	cursor++ // skip single quote
 124  	start := cursor
 125  	length := len(buf)
 126  	var foundEndDelim bool
 127  	for ; cursor < length; cursor++ {
 128  		switch buf[cursor] {
 129  		case '\\':
 130  			buf = append(append([]rune{}, buf[:cursor]...), buf[cursor+1:]...)
 131  			length = len(buf)
 132  		case '\'':
 133  			foundEndDelim = true
 134  			goto end
 135  		}
 136  	}
 137  end:
 138  	if !foundEndDelim {
 139  		return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "could not find end delimiter for key")
 140  	}
 141  	if start == cursor {
 142  		return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "could not find by empty key")
 143  	}
 144  	selector := buf[start:cursor]
 145  	cursor++
 146  	if cursor < length {
 147  		switch buf[cursor] {
 148  		case '$':
 149  			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '$' after '.' character")
 150  		case '*':
 151  			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '*' after '.' character")
 152  		case ']':
 153  			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified ']' after '.' character")
 154  		}
 155  	}
 156  	return b.child(string(selector)), buf, cursor, nil
 157  }
 158  
 159  func parsePathIndex(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune, int, error) {
 160  	length := len(buf)
 161  	cursor++ // skip '[' character
 162  	if length <= cursor {
 163  		return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "unexpected end of YAML Path")
 164  	}
 165  	c := buf[cursor]
 166  	switch c {
 167  	case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*':
 168  		start := cursor
 169  		cursor++
 170  		for ; cursor < length; cursor++ {
 171  			c := buf[cursor]
 172  			switch c {
 173  			case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
 174  				continue
 175  			}
 176  			break
 177  		}
 178  		if buf[cursor] != ']' {
 179  			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "invalid character %s at %d", string(buf[cursor]), cursor)
 180  		}
 181  		numOrAll := string(buf[start:cursor])
 182  		if numOrAll == "*" {
 183  			return b.IndexAll(), buf, cursor + 1, nil
 184  		}
 185  		num, err := strconv.ParseInt(numOrAll, 10, 64)
 186  		if err != nil {
 187  			return nil, nil, 0, errors.Wrapf(err, "failed to parse number")
 188  		}
 189  		return b.Index(uint(num)), buf, cursor + 1, nil
 190  	}
 191  	return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "invalid character %s at %d", c, cursor)
 192  }
 193  
 194  // Path represent YAMLPath ( like a JSONPath ).
 195  type Path struct {
 196  	node pathNode
 197  }
 198  
 199  // String path to text.
 200  func (p *Path) String() string {
 201  	return p.node.String()
 202  }
 203  
 204  // Read decode from r and set extracted value by YAMLPath to v.
 205  func (p *Path) Read(r io.Reader, v interface{}) error {
 206  	node, err := p.ReadNode(r)
 207  	if err != nil {
 208  		return errors.Wrapf(err, "failed to read node")
 209  	}
 210  	if err := Unmarshal([]byte(node.String()), v); err != nil {
 211  		return errors.Wrapf(err, "failed to unmarshal")
 212  	}
 213  	return nil
 214  }
 215  
 216  // ReadNode create AST from r and extract node by YAMLPath.
 217  func (p *Path) ReadNode(r io.Reader) (ast.Node, error) {
 218  	if p.node == nil {
 219  		return nil, ErrInvalidPath
 220  	}
 221  	var buf bytes.Buffer
 222  	if _, err := io.Copy(&buf, r); err != nil {
 223  		return nil, errors.Wrapf(err, "failed to copy from reader")
 224  	}
 225  	f, err := parser.ParseBytes(buf.Bytes(), 0)
 226  	if err != nil {
 227  		return nil, errors.Wrapf(err, "failed to parse yaml")
 228  	}
 229  	node, err := p.FilterFile(f)
 230  	if err != nil {
 231  		return nil, errors.Wrapf(err, "failed to filter from ast.File")
 232  	}
 233  	return node, nil
 234  }
 235  
 236  // Filter filter from target by YAMLPath and set it to v.
 237  func (p *Path) Filter(target, v interface{}) error {
 238  	b, err := Marshal(target)
 239  	if err != nil {
 240  		return errors.Wrapf(err, "failed to marshal target value")
 241  	}
 242  	if err := p.Read(bytes.NewBuffer(b), v); err != nil {
 243  		return errors.Wrapf(err, "failed to read")
 244  	}
 245  	return nil
 246  }
 247  
 248  // FilterFile filter from ast.File by YAMLPath.
 249  func (p *Path) FilterFile(f *ast.File) (ast.Node, error) {
 250  	for _, doc := range f.Docs {
 251  		node, err := p.FilterNode(doc.Body)
 252  		if err != nil {
 253  			return nil, errors.Wrapf(err, "failed to filter node by path ( %s )", p.node)
 254  		}
 255  		if node != nil {
 256  			return node, nil
 257  		}
 258  	}
 259  	return nil, errors.Wrapf(ErrNotFoundNode, "failed to find path ( %s )", p.node)
 260  }
 261  
 262  // FilterNode filter from node by YAMLPath.
 263  func (p *Path) FilterNode(node ast.Node) (ast.Node, error) {
 264  	n, err := p.node.filter(node)
 265  	if err != nil {
 266  		return nil, errors.Wrapf(err, "failed to filter node by path ( %s )", p.node)
 267  	}
 268  	return n, nil
 269  }
 270  
 271  // MergeFromReader merge YAML text into ast.File.
 272  func (p *Path) MergeFromReader(dst *ast.File, src io.Reader) error {
 273  	var buf bytes.Buffer
 274  	if _, err := io.Copy(&buf, src); err != nil {
 275  		return errors.Wrapf(err, "failed to copy from reader")
 276  	}
 277  	file, err := parser.ParseBytes(buf.Bytes(), 0)
 278  	if err != nil {
 279  		return errors.Wrapf(err, "failed to parse")
 280  	}
 281  	if err := p.MergeFromFile(dst, file); err != nil {
 282  		return errors.Wrapf(err, "failed to merge file")
 283  	}
 284  	return nil
 285  }
 286  
 287  // MergeFromFile merge ast.File into ast.File.
 288  func (p *Path) MergeFromFile(dst *ast.File, src *ast.File) error {
 289  	base, err := p.FilterFile(dst)
 290  	if err != nil {
 291  		return errors.Wrapf(err, "failed to filter file")
 292  	}
 293  	for _, doc := range src.Docs {
 294  		if err := ast.Merge(base, doc); err != nil {
 295  			return errors.Wrapf(err, "failed to merge")
 296  		}
 297  	}
 298  	return nil
 299  }
 300  
 301  // MergeFromNode merge ast.Node into ast.File.
 302  func (p *Path) MergeFromNode(dst *ast.File, src ast.Node) error {
 303  	base, err := p.FilterFile(dst)
 304  	if err != nil {
 305  		return errors.Wrapf(err, "failed to filter file")
 306  	}
 307  	if err := ast.Merge(base, src); err != nil {
 308  		return errors.Wrapf(err, "failed to merge")
 309  	}
 310  	return nil
 311  }
 312  
 313  // ReplaceWithReader replace ast.File with io.Reader.
 314  func (p *Path) ReplaceWithReader(dst *ast.File, src io.Reader) error {
 315  	var buf bytes.Buffer
 316  	if _, err := io.Copy(&buf, src); err != nil {
 317  		return errors.Wrapf(err, "failed to copy from reader")
 318  	}
 319  	file, err := parser.ParseBytes(buf.Bytes(), 0)
 320  	if err != nil {
 321  		return errors.Wrapf(err, "failed to parse")
 322  	}
 323  	if err := p.ReplaceWithFile(dst, file); err != nil {
 324  		return errors.Wrapf(err, "failed to replace file")
 325  	}
 326  	return nil
 327  }
 328  
 329  // ReplaceWithFile replace ast.File with ast.File.
 330  func (p *Path) ReplaceWithFile(dst *ast.File, src *ast.File) error {
 331  	for _, doc := range src.Docs {
 332  		if err := p.ReplaceWithNode(dst, doc); err != nil {
 333  			return errors.Wrapf(err, "failed to replace file by path ( %s )", p.node)
 334  		}
 335  	}
 336  	return nil
 337  }
 338  
 339  // ReplaceNode replace ast.File with ast.Node.
 340  func (p *Path) ReplaceWithNode(dst *ast.File, node ast.Node) error {
 341  	for _, doc := range dst.Docs {
 342  		if node.Type() == ast.DocumentType {
 343  			node = node.(*ast.DocumentNode).Body
 344  		}
 345  		if err := p.node.replace(doc.Body, node); err != nil {
 346  			return errors.Wrapf(err, "failed to replace node by path ( %s )", p.node)
 347  		}
 348  	}
 349  	return nil
 350  }
 351  
 352  // AnnotateSource add annotation to passed source ( see section 5.1 in README.md ).
 353  func (p *Path) AnnotateSource(source []byte, colored bool) ([]byte, error) {
 354  	file, err := parser.ParseBytes([]byte(source), 0)
 355  	if err != nil {
 356  		return nil, err
 357  	}
 358  	node, err := p.FilterFile(file)
 359  	if err != nil {
 360  		return nil, err
 361  	}
 362  	var pp printer.Printer
 363  	return []byte(pp.PrintErrorToken(node.GetToken(), colored)), nil
 364  }
 365  
 366  // PathBuilder represent builder for YAMLPath.
 367  type PathBuilder struct {
 368  	root *rootNode
 369  	node pathNode
 370  }
 371  
 372  // Root add '$' to current path.
 373  func (b *PathBuilder) Root() *PathBuilder {
 374  	root := newRootNode()
 375  	return &PathBuilder{root: root, node: root}
 376  }
 377  
 378  // IndexAll add '[*]' to current path.
 379  func (b *PathBuilder) IndexAll() *PathBuilder {
 380  	b.node = b.node.chain(newIndexAllNode())
 381  	return b
 382  }
 383  
 384  // Recursive add '..selector' to current path.
 385  func (b *PathBuilder) Recursive(selector string) *PathBuilder {
 386  	b.node = b.node.chain(newRecursiveNode(selector))
 387  	return b
 388  }
 389  
 390  func (b *PathBuilder) containsReservedPathCharacters(path string) bool {
 391  	if strings.Contains(path, ".") {
 392  		return true
 393  	}
 394  	if strings.Contains(path, "*") {
 395  		return true
 396  	}
 397  	return false
 398  }
 399  
 400  func (b *PathBuilder) enclosedSingleQuote(name string) bool {
 401  	return strings.HasPrefix(name, "'") && strings.HasSuffix(name, "'")
 402  }
 403  
 404  func (b *PathBuilder) normalizeSelectorName(name string) string {
 405  	if b.enclosedSingleQuote(name) {
 406  		// already escaped name
 407  		return name
 408  	}
 409  	if b.containsReservedPathCharacters(name) {
 410  		escapedName := strings.ReplaceAll(name, `'`, `\'`)
 411  		return "'" + escapedName + "'"
 412  	}
 413  	return name
 414  }
 415  
 416  func (b *PathBuilder) child(name string) *PathBuilder {
 417  	b.node = b.node.chain(newSelectorNode(name))
 418  	return b
 419  }
 420  
 421  // Child add '.name' to current path.
 422  func (b *PathBuilder) Child(name string) *PathBuilder {
 423  	return b.child(b.normalizeSelectorName(name))
 424  }
 425  
 426  // Index add '[idx]' to current path.
 427  func (b *PathBuilder) Index(idx uint) *PathBuilder {
 428  	b.node = b.node.chain(newIndexNode(idx))
 429  	return b
 430  }
 431  
 432  // Build build YAMLPath.
 433  func (b *PathBuilder) Build() *Path {
 434  	return &Path{node: b.root}
 435  }
 436  
 437  type pathNode interface {
 438  	fmt.Stringer
 439  	chain(pathNode) pathNode
 440  	filter(ast.Node) (ast.Node, error)
 441  	replace(ast.Node, ast.Node) error
 442  }
 443  
 444  type basePathNode struct {
 445  	child pathNode
 446  }
 447  
 448  func (n *basePathNode) chain(node pathNode) pathNode {
 449  	n.child = node
 450  	return node
 451  }
 452  
 453  type rootNode struct {
 454  	*basePathNode
 455  }
 456  
 457  func newRootNode() *rootNode {
 458  	return &rootNode{basePathNode: &basePathNode{}}
 459  }
 460  
 461  func (n *rootNode) String() string {
 462  	s := "$"
 463  	if n.child != nil {
 464  		s += n.child.String()
 465  	}
 466  	return s
 467  }
 468  
 469  func (n *rootNode) filter(node ast.Node) (ast.Node, error) {
 470  	if n.child == nil {
 471  		return nil, nil
 472  	}
 473  	filtered, err := n.child.filter(node)
 474  	if err != nil {
 475  		return nil, errors.Wrapf(err, "failed to filter")
 476  	}
 477  	return filtered, nil
 478  }
 479  
 480  func (n *rootNode) replace(node ast.Node, target ast.Node) error {
 481  	if n.child == nil {
 482  		return nil
 483  	}
 484  	if err := n.child.replace(node, target); err != nil {
 485  		return errors.Wrapf(err, "failed to replace")
 486  	}
 487  	return nil
 488  }
 489  
 490  type selectorNode struct {
 491  	*basePathNode
 492  	selector string
 493  }
 494  
 495  func newSelectorNode(selector string) *selectorNode {
 496  	return &selectorNode{
 497  		basePathNode: &basePathNode{},
 498  		selector:     selector,
 499  	}
 500  }
 501  
 502  func (n *selectorNode) filter(node ast.Node) (ast.Node, error) {
 503  	switch node.Type() {
 504  	case ast.MappingType:
 505  		for _, value := range node.(*ast.MappingNode).Values {
 506  			key := value.Key.GetToken().Value
 507  			if key == n.selector {
 508  				if n.child == nil {
 509  					return value.Value, nil
 510  				}
 511  				filtered, err := n.child.filter(value.Value)
 512  				if err != nil {
 513  					return nil, errors.Wrapf(err, "failed to filter")
 514  				}
 515  				return filtered, nil
 516  			}
 517  		}
 518  	case ast.MappingValueType:
 519  		value := node.(*ast.MappingValueNode)
 520  		key := value.Key.GetToken().Value
 521  		if key == n.selector {
 522  			if n.child == nil {
 523  				return value.Value, nil
 524  			}
 525  			filtered, err := n.child.filter(value.Value)
 526  			if err != nil {
 527  				return nil, errors.Wrapf(err, "failed to filter")
 528  			}
 529  			return filtered, nil
 530  		}
 531  	default:
 532  		return nil, errors.Wrapf(ErrInvalidQuery, "expected node type is map or map value. but got %s", node.Type())
 533  	}
 534  	return nil, nil
 535  }
 536  
 537  func (n *selectorNode) replaceMapValue(value *ast.MappingValueNode, target ast.Node) error {
 538  	key := value.Key.GetToken().Value
 539  	if key != n.selector {
 540  		return nil
 541  	}
 542  	if n.child == nil {
 543  		if err := value.Replace(target); err != nil {
 544  			return errors.Wrapf(err, "failed to replace")
 545  		}
 546  	} else {
 547  		if err := n.child.replace(value.Value, target); err != nil {
 548  			return errors.Wrapf(err, "failed to replace")
 549  		}
 550  	}
 551  	return nil
 552  }
 553  
 554  func (n *selectorNode) replace(node ast.Node, target ast.Node) error {
 555  	switch node.Type() {
 556  	case ast.MappingType:
 557  		for _, value := range node.(*ast.MappingNode).Values {
 558  			if err := n.replaceMapValue(value, target); err != nil {
 559  				return errors.Wrapf(err, "failed to replace map value")
 560  			}
 561  		}
 562  	case ast.MappingValueType:
 563  		value := node.(*ast.MappingValueNode)
 564  		if err := n.replaceMapValue(value, target); err != nil {
 565  			return errors.Wrapf(err, "failed to replace map value")
 566  		}
 567  	default:
 568  		return errors.Wrapf(ErrInvalidQuery, "expected node type is map or map value. but got %s", node.Type())
 569  	}
 570  	return nil
 571  }
 572  
 573  func (n *selectorNode) String() string {
 574  	s := fmt.Sprintf(".%s", n.selector)
 575  	if n.child != nil {
 576  		s += n.child.String()
 577  	}
 578  	return s
 579  }
 580  
 581  type indexNode struct {
 582  	*basePathNode
 583  	selector uint
 584  }
 585  
 586  func newIndexNode(selector uint) *indexNode {
 587  	return &indexNode{
 588  		basePathNode: &basePathNode{},
 589  		selector:     selector,
 590  	}
 591  }
 592  
 593  func (n *indexNode) filter(node ast.Node) (ast.Node, error) {
 594  	if node.Type() != ast.SequenceType {
 595  		return nil, errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
 596  	}
 597  	sequence := node.(*ast.SequenceNode)
 598  	if n.selector >= uint(len(sequence.Values)) {
 599  		return nil, errors.Wrapf(ErrInvalidQuery, "expected index is %d. but got sequences has %d items", n.selector, sequence.Values)
 600  	}
 601  	value := sequence.Values[n.selector]
 602  	if n.child == nil {
 603  		return value, nil
 604  	}
 605  	filtered, err := n.child.filter(value)
 606  	if err != nil {
 607  		return nil, errors.Wrapf(err, "failed to filter")
 608  	}
 609  	return filtered, nil
 610  }
 611  
 612  func (n *indexNode) replace(node ast.Node, target ast.Node) error {
 613  	if node.Type() != ast.SequenceType {
 614  		return errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
 615  	}
 616  	sequence := node.(*ast.SequenceNode)
 617  	if n.selector >= uint(len(sequence.Values)) {
 618  		return errors.Wrapf(ErrInvalidQuery, "expected index is %d. but got sequences has %d items", n.selector, sequence.Values)
 619  	}
 620  	if n.child == nil {
 621  		if err := sequence.Replace(int(n.selector), target); err != nil {
 622  			return errors.Wrapf(err, "failed to replace")
 623  		}
 624  		return nil
 625  	}
 626  	if err := n.child.replace(sequence.Values[n.selector], target); err != nil {
 627  		return errors.Wrapf(err, "failed to replace")
 628  	}
 629  	return nil
 630  }
 631  
 632  func (n *indexNode) String() string {
 633  	s := fmt.Sprintf("[%d]", n.selector)
 634  	if n.child != nil {
 635  		s += n.child.String()
 636  	}
 637  	return s
 638  }
 639  
 640  type indexAllNode struct {
 641  	*basePathNode
 642  }
 643  
 644  func newIndexAllNode() *indexAllNode {
 645  	return &indexAllNode{
 646  		basePathNode: &basePathNode{},
 647  	}
 648  }
 649  
 650  func (n *indexAllNode) String() string {
 651  	s := "[*]"
 652  	if n.child != nil {
 653  		s += n.child.String()
 654  	}
 655  	return s
 656  }
 657  
 658  func (n *indexAllNode) filter(node ast.Node) (ast.Node, error) {
 659  	if node.Type() != ast.SequenceType {
 660  		return nil, errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
 661  	}
 662  	sequence := node.(*ast.SequenceNode)
 663  	if n.child == nil {
 664  		return sequence, nil
 665  	}
 666  	out := *sequence
 667  	out.Values = []ast.Node{}
 668  	for _, value := range sequence.Values {
 669  		filtered, err := n.child.filter(value)
 670  		if err != nil {
 671  			return nil, errors.Wrapf(err, "failed to filter")
 672  		}
 673  		out.Values = append(out.Values, filtered)
 674  	}
 675  	return &out, nil
 676  }
 677  
 678  func (n *indexAllNode) replace(node ast.Node, target ast.Node) error {
 679  	if node.Type() != ast.SequenceType {
 680  		return errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
 681  	}
 682  	sequence := node.(*ast.SequenceNode)
 683  	if n.child == nil {
 684  		for idx := range sequence.Values {
 685  			if err := sequence.Replace(idx, target); err != nil {
 686  				return errors.Wrapf(err, "failed to replace")
 687  			}
 688  		}
 689  		return nil
 690  	}
 691  	for _, value := range sequence.Values {
 692  		if err := n.child.replace(value, target); err != nil {
 693  			return errors.Wrapf(err, "failed to replace")
 694  		}
 695  	}
 696  	return nil
 697  }
 698  
 699  type recursiveNode struct {
 700  	*basePathNode
 701  	selector string
 702  }
 703  
 704  func newRecursiveNode(selector string) *recursiveNode {
 705  	return &recursiveNode{
 706  		basePathNode: &basePathNode{},
 707  		selector:     selector,
 708  	}
 709  }
 710  
 711  func (n *recursiveNode) String() string {
 712  	s := fmt.Sprintf("..%s", n.selector)
 713  	if n.child != nil {
 714  		s += n.child.String()
 715  	}
 716  	return s
 717  }
 718  
 719  func (n *recursiveNode) filterNode(node ast.Node) (*ast.SequenceNode, error) {
 720  	sequence := &ast.SequenceNode{BaseNode: &ast.BaseNode{}}
 721  	switch typedNode := node.(type) {
 722  	case *ast.MappingNode:
 723  		for _, value := range typedNode.Values {
 724  			seq, err := n.filterNode(value)
 725  			if err != nil {
 726  				return nil, errors.Wrapf(err, "failed to filter")
 727  			}
 728  			sequence.Values = append(sequence.Values, seq.Values...)
 729  		}
 730  	case *ast.MappingValueNode:
 731  		key := typedNode.Key.GetToken().Value
 732  		if n.selector == key {
 733  			sequence.Values = append(sequence.Values, typedNode.Value)
 734  		}
 735  		seq, err := n.filterNode(typedNode.Value)
 736  		if err != nil {
 737  			return nil, errors.Wrapf(err, "failed to filter")
 738  		}
 739  		sequence.Values = append(sequence.Values, seq.Values...)
 740  	case *ast.SequenceNode:
 741  		for _, value := range typedNode.Values {
 742  			seq, err := n.filterNode(value)
 743  			if err != nil {
 744  				return nil, errors.Wrapf(err, "failed to filter")
 745  			}
 746  			sequence.Values = append(sequence.Values, seq.Values...)
 747  		}
 748  	}
 749  	return sequence, nil
 750  }
 751  
 752  func (n *recursiveNode) filter(node ast.Node) (ast.Node, error) {
 753  	sequence, err := n.filterNode(node)
 754  	if err != nil {
 755  		return nil, errors.Wrapf(err, "failed to filter")
 756  	}
 757  	sequence.Start = node.GetToken()
 758  	return sequence, nil
 759  }
 760  
 761  func (n *recursiveNode) replaceNode(node ast.Node, target ast.Node) error {
 762  	switch typedNode := node.(type) {
 763  	case *ast.MappingNode:
 764  		for _, value := range typedNode.Values {
 765  			if err := n.replaceNode(value, target); err != nil {
 766  				return errors.Wrapf(err, "failed to replace")
 767  			}
 768  		}
 769  	case *ast.MappingValueNode:
 770  		key := typedNode.Key.GetToken().Value
 771  		if n.selector == key {
 772  			if err := typedNode.Replace(target); err != nil {
 773  				return errors.Wrapf(err, "failed to replace")
 774  			}
 775  		}
 776  		if err := n.replaceNode(typedNode.Value, target); err != nil {
 777  			return errors.Wrapf(err, "failed to replace")
 778  		}
 779  	case *ast.SequenceNode:
 780  		for _, value := range typedNode.Values {
 781  			if err := n.replaceNode(value, target); err != nil {
 782  				return errors.Wrapf(err, "failed to replace")
 783  			}
 784  		}
 785  	}
 786  	return nil
 787  }
 788  
 789  func (n *recursiveNode) replace(node ast.Node, target ast.Node) error {
 790  	if err := n.replaceNode(node, target); err != nil {
 791  		return errors.Wrapf(err, "failed to replace")
 792  	}
 793  	return nil
 794  }
 795