github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/yaml/ast/ast.go (about)

     1  package ast
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"math"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/bingoohuang/gg/pkg/yaml/token"
    11  	"golang.org/x/xerrors"
    12  )
    13  
    14  var (
    15  	ErrInvalidTokenType  = xerrors.New("invalid token type")
    16  	ErrInvalidAnchorName = xerrors.New("invalid anchor name")
    17  	ErrInvalidAliasName  = xerrors.New("invalid alias name")
    18  )
    19  
    20  // NodeType type identifier of node
    21  type NodeType int
    22  
    23  const (
    24  	// UnknownNodeType type identifier for default
    25  	UnknownNodeType NodeType = iota
    26  	// DocumentType type identifier for document node
    27  	DocumentType
    28  	// NullType type identifier for null node
    29  	NullType
    30  	// BoolType type identifier for boolean node
    31  	BoolType
    32  	// IntegerType type identifier for integer node
    33  	IntegerType
    34  	// FloatType type identifier for float node
    35  	FloatType
    36  	// InfinityType type identifier for infinity node
    37  	InfinityType
    38  	// NanType type identifier for nan node
    39  	NanType
    40  	// StringType type identifier for string node
    41  	StringType
    42  	// MergeKeyType type identifier for merge key node
    43  	MergeKeyType
    44  	// LiteralType type identifier for literal node
    45  	LiteralType
    46  	// MappingType type identifier for mapping node
    47  	MappingType
    48  	// MappingKeyType type identifier for mapping key node
    49  	MappingKeyType
    50  	// MappingValueType type identifier for mapping value node
    51  	MappingValueType
    52  	// SequenceType type identifier for sequence node
    53  	SequenceType
    54  	// AnchorType type identifier for anchor node
    55  	AnchorType
    56  	// AliasType type identifier for alias node
    57  	AliasType
    58  	// DirectiveType type identifier for directive node
    59  	DirectiveType
    60  	// TagType type identifier for tag node
    61  	TagType
    62  	// CommentType type identifier for comment node
    63  	CommentType
    64  	// CommentGroupType type identifier for comment group node
    65  	CommentGroupType
    66  )
    67  
    68  // String node type identifier to text
    69  func (t NodeType) String() string {
    70  	switch t {
    71  	case UnknownNodeType:
    72  		return "UnknownNode"
    73  	case DocumentType:
    74  		return "Document"
    75  	case NullType:
    76  		return "Null"
    77  	case BoolType:
    78  		return "Bool"
    79  	case IntegerType:
    80  		return "Integer"
    81  	case FloatType:
    82  		return "Float"
    83  	case InfinityType:
    84  		return "Infinity"
    85  	case NanType:
    86  		return "Nan"
    87  	case StringType:
    88  		return "String"
    89  	case MergeKeyType:
    90  		return "MergeKey"
    91  	case LiteralType:
    92  		return "Literal"
    93  	case MappingType:
    94  		return "Mapping"
    95  	case MappingKeyType:
    96  		return "MappingKey"
    97  	case MappingValueType:
    98  		return "MappingValue"
    99  	case SequenceType:
   100  		return "Sequence"
   101  	case AnchorType:
   102  		return "Anchor"
   103  	case AliasType:
   104  		return "Alias"
   105  	case DirectiveType:
   106  		return "Directive"
   107  	case TagType:
   108  		return "Tag"
   109  	case CommentType:
   110  		return "Comment"
   111  	case CommentGroupType:
   112  		return "CommentGroup"
   113  	}
   114  	return ""
   115  }
   116  
   117  // String node type identifier to YAML Structure name
   118  // based on https://yaml.org/spec/1.2/spec.html
   119  func (t NodeType) YAMLName() string {
   120  	switch t {
   121  	case UnknownNodeType:
   122  		return "unknown"
   123  	case DocumentType:
   124  		return "document"
   125  	case NullType:
   126  		return "null"
   127  	case BoolType:
   128  		return "boolean"
   129  	case IntegerType:
   130  		return "int"
   131  	case FloatType:
   132  		return "float"
   133  	case InfinityType:
   134  		return "inf"
   135  	case NanType:
   136  		return "nan"
   137  	case StringType:
   138  		return "string"
   139  	case MergeKeyType:
   140  		return "merge key"
   141  	case LiteralType:
   142  		return "scalar"
   143  	case MappingType:
   144  		return "mapping"
   145  	case MappingKeyType:
   146  		return "key"
   147  	case MappingValueType:
   148  		return "value"
   149  	case SequenceType:
   150  		return "sequence"
   151  	case AnchorType:
   152  		return "anchor"
   153  	case AliasType:
   154  		return "alias"
   155  	case DirectiveType:
   156  		return "directive"
   157  	case TagType:
   158  		return "tag"
   159  	case CommentType:
   160  		return "comment"
   161  	case CommentGroupType:
   162  		return "comment"
   163  	}
   164  	return ""
   165  }
   166  
   167  // Node type of node
   168  type Node interface {
   169  	io.Reader
   170  	// String node to text
   171  	String() string
   172  	// GetToken returns token instance
   173  	GetToken() *token.Token
   174  	// Type returns type of node
   175  	Type() NodeType
   176  	// AddColumn add column number to child nodes recursively
   177  	AddColumn(int)
   178  	// SetComment set comment token to node
   179  	SetComment(*CommentGroupNode) error
   180  	// Comment returns comment token instance
   181  	GetComment() *CommentGroupNode
   182  	// MarshalYAML
   183  	MarshalYAML() ([]byte, error)
   184  	// already read length
   185  	readLen() int
   186  	// append read length
   187  	addReadLen(int)
   188  	// clean read length
   189  	clearLen()
   190  	// String node to text without comment
   191  	stringWithoutComment() string
   192  }
   193  
   194  // ScalarNode type for scalar node
   195  type ScalarNode interface {
   196  	Node
   197  	GetValue() interface{}
   198  }
   199  
   200  type BaseNode struct {
   201  	Comment *CommentGroupNode
   202  	read    int
   203  }
   204  
   205  func addCommentString(base string, node *CommentGroupNode) string {
   206  	return fmt.Sprintf("%s %s", base, node.String())
   207  }
   208  
   209  func (n *BaseNode) readLen() int {
   210  	return n.read
   211  }
   212  
   213  func (n *BaseNode) clearLen() {
   214  	n.read = 0
   215  }
   216  
   217  func (n *BaseNode) addReadLen(len int) {
   218  	n.read += len
   219  }
   220  
   221  // GetComment returns comment token instance
   222  func (n *BaseNode) GetComment() *CommentGroupNode {
   223  	return n.Comment
   224  }
   225  
   226  // SetComment set comment token
   227  func (n *BaseNode) SetComment(node *CommentGroupNode) error {
   228  	n.Comment = node
   229  	return nil
   230  }
   231  
   232  func min(a, b int) int {
   233  	if a < b {
   234  		return a
   235  	}
   236  	return b
   237  }
   238  
   239  func readNode(p []byte, node Node) (int, error) {
   240  	s := node.String()
   241  	readLen := node.readLen()
   242  	remain := len(s) - readLen
   243  	if remain == 0 {
   244  		node.clearLen()
   245  		return 0, io.EOF
   246  	}
   247  	size := min(remain, len(p))
   248  	for idx, b := range s[readLen : readLen+size] {
   249  		p[idx] = byte(b)
   250  	}
   251  	node.addReadLen(size)
   252  	return size, nil
   253  }
   254  
   255  // Null create node for null value
   256  func Null(tk *token.Token) Node {
   257  	return &NullNode{
   258  		BaseNode: &BaseNode{},
   259  		Token:    tk,
   260  	}
   261  }
   262  
   263  // Bool create node for boolean value
   264  func Bool(tk *token.Token) Node {
   265  	b, _ := strconv.ParseBool(tk.Value)
   266  	return &BoolNode{
   267  		BaseNode: &BaseNode{},
   268  		Token:    tk,
   269  		Value:    b,
   270  	}
   271  }
   272  
   273  // Integer create node for integer value
   274  func Integer(tk *token.Token) Node {
   275  	value := removeUnderScoreFromNumber(tk.Value)
   276  	switch tk.Type {
   277  	case token.BinaryIntegerType:
   278  		// skip two characters because binary token starts with '0b'
   279  		skipCharacterNum := 2
   280  		negativePrefix := ""
   281  		if value[0] == '-' {
   282  			skipCharacterNum++
   283  			negativePrefix = "-"
   284  		}
   285  		if len(negativePrefix) > 0 {
   286  			i, _ := strconv.ParseInt(negativePrefix+value[skipCharacterNum:], 2, 64)
   287  			return &IntegerNode{
   288  				BaseNode: &BaseNode{},
   289  				Token:    tk,
   290  				Value:    i,
   291  			}
   292  		}
   293  		i, _ := strconv.ParseUint(negativePrefix+value[skipCharacterNum:], 2, 64)
   294  		return &IntegerNode{
   295  			BaseNode: &BaseNode{},
   296  			Token:    tk,
   297  			Value:    i,
   298  		}
   299  	case token.OctetIntegerType:
   300  		// octet token starts with '0o' or '-0o' or '0' or '-0'
   301  		skipCharacterNum := 1
   302  		negativePrefix := ""
   303  		if value[0] == '-' {
   304  			skipCharacterNum++
   305  			if len(value) > 2 && value[2] == 'o' {
   306  				skipCharacterNum++
   307  			}
   308  			negativePrefix = "-"
   309  		} else {
   310  			if value[1] == 'o' {
   311  				skipCharacterNum++
   312  			}
   313  		}
   314  		if len(negativePrefix) > 0 {
   315  			i, _ := strconv.ParseInt(negativePrefix+value[skipCharacterNum:], 8, 64)
   316  			return &IntegerNode{
   317  				BaseNode: &BaseNode{},
   318  				Token:    tk,
   319  				Value:    i,
   320  			}
   321  		}
   322  		i, _ := strconv.ParseUint(value[skipCharacterNum:], 8, 64)
   323  		return &IntegerNode{
   324  			BaseNode: &BaseNode{},
   325  			Token:    tk,
   326  			Value:    i,
   327  		}
   328  	case token.HexIntegerType:
   329  		// hex token starts with '0x' or '-0x'
   330  		skipCharacterNum := 2
   331  		negativePrefix := ""
   332  		if value[0] == '-' {
   333  			skipCharacterNum++
   334  			negativePrefix = "-"
   335  		}
   336  		if len(negativePrefix) > 0 {
   337  			i, _ := strconv.ParseInt(negativePrefix+value[skipCharacterNum:], 16, 64)
   338  			return &IntegerNode{
   339  				BaseNode: &BaseNode{},
   340  				Token:    tk,
   341  				Value:    i,
   342  			}
   343  		}
   344  		i, _ := strconv.ParseUint(value[skipCharacterNum:], 16, 64)
   345  		return &IntegerNode{
   346  			BaseNode: &BaseNode{},
   347  			Token:    tk,
   348  			Value:    i,
   349  		}
   350  	}
   351  	if value[0] == '-' || value[0] == '+' {
   352  		i, _ := strconv.ParseInt(value, 10, 64)
   353  		return &IntegerNode{
   354  			BaseNode: &BaseNode{},
   355  			Token:    tk,
   356  			Value:    i,
   357  		}
   358  	}
   359  	i, _ := strconv.ParseUint(value, 10, 64)
   360  	return &IntegerNode{
   361  		BaseNode: &BaseNode{},
   362  		Token:    tk,
   363  		Value:    i,
   364  	}
   365  }
   366  
   367  // Float create node for float value
   368  func Float(tk *token.Token) Node {
   369  	f, _ := strconv.ParseFloat(removeUnderScoreFromNumber(tk.Value), 64)
   370  	return &FloatNode{
   371  		BaseNode: &BaseNode{},
   372  		Token:    tk,
   373  		Value:    f,
   374  	}
   375  }
   376  
   377  // Infinity create node for .inf or -.inf value
   378  func Infinity(tk *token.Token) *InfinityNode {
   379  	node := &InfinityNode{
   380  		BaseNode: &BaseNode{},
   381  		Token:    tk,
   382  	}
   383  	switch tk.Value {
   384  	case ".inf", ".Inf", ".INF":
   385  		node.Value = math.Inf(0)
   386  	case "-.inf", "-.Inf", "-.INF":
   387  		node.Value = math.Inf(-1)
   388  	}
   389  	return node
   390  }
   391  
   392  // Nan create node for .nan value
   393  func Nan(tk *token.Token) *NanNode {
   394  	return &NanNode{
   395  		BaseNode: &BaseNode{},
   396  		Token:    tk,
   397  	}
   398  }
   399  
   400  // String create node for string value
   401  func String(tk *token.Token) *StringNode {
   402  	return &StringNode{
   403  		BaseNode: &BaseNode{},
   404  		Token:    tk,
   405  		Value:    tk.Value,
   406  	}
   407  }
   408  
   409  // Comment create node for comment
   410  func Comment(tk *token.Token) *CommentNode {
   411  	return &CommentNode{
   412  		BaseNode: &BaseNode{},
   413  		Token:    tk,
   414  	}
   415  }
   416  
   417  func CommentGroup(comments []*token.Token) *CommentGroupNode {
   418  	nodes := []*CommentNode{}
   419  	for _, comment := range comments {
   420  		nodes = append(nodes, Comment(comment))
   421  	}
   422  	return &CommentGroupNode{
   423  		BaseNode: &BaseNode{},
   424  		Comments: nodes,
   425  	}
   426  }
   427  
   428  // MergeKey create node for merge key ( << )
   429  func MergeKey(tk *token.Token) *MergeKeyNode {
   430  	return &MergeKeyNode{
   431  		BaseNode: &BaseNode{},
   432  		Token:    tk,
   433  	}
   434  }
   435  
   436  // Mapping create node for map
   437  func Mapping(tk *token.Token, isFlowStyle bool, values ...*MappingValueNode) *MappingNode {
   438  	node := &MappingNode{
   439  		BaseNode:    &BaseNode{},
   440  		Start:       tk,
   441  		IsFlowStyle: isFlowStyle,
   442  		Values:      []*MappingValueNode{},
   443  	}
   444  	node.Values = append(node.Values, values...)
   445  	return node
   446  }
   447  
   448  // MappingValue create node for mapping value
   449  func MappingValue(tk *token.Token, key Node, value Node) *MappingValueNode {
   450  	return &MappingValueNode{
   451  		BaseNode: &BaseNode{},
   452  		Start:    tk,
   453  		Key:      key,
   454  		Value:    value,
   455  	}
   456  }
   457  
   458  // MappingKey create node for map key ( '?' ).
   459  func MappingKey(tk *token.Token) *MappingKeyNode {
   460  	return &MappingKeyNode{
   461  		BaseNode: &BaseNode{},
   462  		Start:    tk,
   463  	}
   464  }
   465  
   466  // Sequence create node for sequence
   467  func Sequence(tk *token.Token, isFlowStyle bool) *SequenceNode {
   468  	return &SequenceNode{
   469  		BaseNode:    &BaseNode{},
   470  		Start:       tk,
   471  		IsFlowStyle: isFlowStyle,
   472  		Values:      []Node{},
   473  	}
   474  }
   475  
   476  func Anchor(tk *token.Token) *AnchorNode {
   477  	return &AnchorNode{
   478  		BaseNode: &BaseNode{},
   479  		Start:    tk,
   480  	}
   481  }
   482  
   483  func Alias(tk *token.Token) *AliasNode {
   484  	return &AliasNode{
   485  		BaseNode: &BaseNode{},
   486  		Start:    tk,
   487  	}
   488  }
   489  
   490  func Document(tk *token.Token, body Node) *DocumentNode {
   491  	return &DocumentNode{
   492  		BaseNode: &BaseNode{},
   493  		Start:    tk,
   494  		Body:     body,
   495  	}
   496  }
   497  
   498  func Directive(tk *token.Token) *DirectiveNode {
   499  	return &DirectiveNode{
   500  		BaseNode: &BaseNode{},
   501  		Start:    tk,
   502  	}
   503  }
   504  
   505  func Literal(tk *token.Token) *LiteralNode {
   506  	return &LiteralNode{
   507  		BaseNode: &BaseNode{},
   508  		Start:    tk,
   509  	}
   510  }
   511  
   512  func Tag(tk *token.Token) *TagNode {
   513  	return &TagNode{
   514  		BaseNode: &BaseNode{},
   515  		Start:    tk,
   516  	}
   517  }
   518  
   519  // File contains all documents in YAML file
   520  type File struct {
   521  	Name string
   522  	Docs []*DocumentNode
   523  }
   524  
   525  // Read implements (io.Reader).Read
   526  func (f *File) Read(p []byte) (int, error) {
   527  	for _, doc := range f.Docs {
   528  		n, err := doc.Read(p)
   529  		if err == io.EOF {
   530  			continue
   531  		}
   532  		return n, nil
   533  	}
   534  	return 0, io.EOF
   535  }
   536  
   537  // String all documents to text
   538  func (f *File) String() string {
   539  	docs := []string{}
   540  	for _, doc := range f.Docs {
   541  		docs = append(docs, doc.String())
   542  	}
   543  	return strings.Join(docs, "\n")
   544  }
   545  
   546  func (f *File) stringWithoutComment() string {
   547  	return f.String()
   548  }
   549  
   550  // DocumentNode type of Document
   551  type DocumentNode struct {
   552  	*BaseNode
   553  	Start *token.Token // position of DocumentHeader ( `---` )
   554  	End   *token.Token // position of DocumentEnd ( `...` )
   555  	Body  Node
   556  }
   557  
   558  // Read implements (io.Reader).Read
   559  func (d *DocumentNode) Read(p []byte) (int, error) {
   560  	return readNode(p, d)
   561  }
   562  
   563  // Type returns DocumentNodeType
   564  func (d *DocumentNode) Type() NodeType { return DocumentType }
   565  
   566  // GetToken returns token instance
   567  func (d *DocumentNode) GetToken() *token.Token {
   568  	return d.Body.GetToken()
   569  }
   570  
   571  // AddColumn add column number to child nodes recursively
   572  func (d *DocumentNode) AddColumn(col int) {
   573  	if d.Body != nil {
   574  		d.Body.AddColumn(col)
   575  	}
   576  }
   577  
   578  // String document to text
   579  func (d *DocumentNode) String() string {
   580  	doc := []string{}
   581  	if d.Start != nil {
   582  		doc = append(doc, d.Start.Value)
   583  	}
   584  	doc = append(doc, d.Body.String())
   585  	if d.End != nil {
   586  		doc = append(doc, d.End.Value)
   587  	}
   588  	return strings.Join(doc, "\n")
   589  }
   590  
   591  func (d *DocumentNode) stringWithoutComment() string {
   592  	return d.String()
   593  }
   594  
   595  // MarshalYAML encodes to a YAML text
   596  func (d *DocumentNode) MarshalYAML() ([]byte, error) {
   597  	return []byte(d.String()), nil
   598  }
   599  
   600  func removeUnderScoreFromNumber(num string) string {
   601  	return strings.ReplaceAll(num, "_", "")
   602  }
   603  
   604  // NullNode type of null node
   605  type NullNode struct {
   606  	*BaseNode
   607  	Token *token.Token
   608  }
   609  
   610  // Read implements (io.Reader).Read
   611  func (n *NullNode) Read(p []byte) (int, error) {
   612  	return readNode(p, n)
   613  }
   614  
   615  // Type returns NullType
   616  func (n *NullNode) Type() NodeType { return NullType }
   617  
   618  // GetToken returns token instance
   619  func (n *NullNode) GetToken() *token.Token {
   620  	return n.Token
   621  }
   622  
   623  // AddColumn add column number to child nodes recursively
   624  func (n *NullNode) AddColumn(col int) {
   625  	n.Token.AddColumn(col)
   626  }
   627  
   628  // GetValue returns nil value
   629  func (n *NullNode) GetValue() interface{} {
   630  	return nil
   631  }
   632  
   633  // String returns `null` text
   634  func (n *NullNode) String() string {
   635  	if n.Comment != nil {
   636  		return fmt.Sprintf("null %s", n.Comment.String())
   637  	}
   638  	return n.stringWithoutComment()
   639  }
   640  
   641  func (n *NullNode) stringWithoutComment() string {
   642  	return "null"
   643  }
   644  
   645  // MarshalYAML encodes to a YAML text
   646  func (n *NullNode) MarshalYAML() ([]byte, error) {
   647  	return []byte(n.String()), nil
   648  }
   649  
   650  // IntegerNode type of integer node
   651  type IntegerNode struct {
   652  	*BaseNode
   653  	Token *token.Token
   654  	Value interface{} // int64 or uint64 value
   655  }
   656  
   657  // Read implements (io.Reader).Read
   658  func (n *IntegerNode) Read(p []byte) (int, error) {
   659  	return readNode(p, n)
   660  }
   661  
   662  // Type returns IntegerType
   663  func (n *IntegerNode) Type() NodeType { return IntegerType }
   664  
   665  // GetToken returns token instance
   666  func (n *IntegerNode) GetToken() *token.Token {
   667  	return n.Token
   668  }
   669  
   670  // AddColumn add column number to child nodes recursively
   671  func (n *IntegerNode) AddColumn(col int) {
   672  	n.Token.AddColumn(col)
   673  }
   674  
   675  // GetValue returns int64 value
   676  func (n *IntegerNode) GetValue() interface{} {
   677  	return n.Value
   678  }
   679  
   680  // String int64 to text
   681  func (n *IntegerNode) String() string {
   682  	if n.Comment != nil {
   683  		return addCommentString(n.Token.Value, n.Comment)
   684  	}
   685  	return n.stringWithoutComment()
   686  }
   687  
   688  func (n *IntegerNode) stringWithoutComment() string {
   689  	return n.Token.Value
   690  }
   691  
   692  // MarshalYAML encodes to a YAML text
   693  func (n *IntegerNode) MarshalYAML() ([]byte, error) {
   694  	return []byte(n.String()), nil
   695  }
   696  
   697  // FloatNode type of float node
   698  type FloatNode struct {
   699  	*BaseNode
   700  	Token     *token.Token
   701  	Precision int
   702  	Value     float64
   703  }
   704  
   705  // Read implements (io.Reader).Read
   706  func (n *FloatNode) Read(p []byte) (int, error) {
   707  	return readNode(p, n)
   708  }
   709  
   710  // Type returns FloatType
   711  func (n *FloatNode) Type() NodeType { return FloatType }
   712  
   713  // GetToken returns token instance
   714  func (n *FloatNode) GetToken() *token.Token {
   715  	return n.Token
   716  }
   717  
   718  // AddColumn add column number to child nodes recursively
   719  func (n *FloatNode) AddColumn(col int) {
   720  	n.Token.AddColumn(col)
   721  }
   722  
   723  // GetValue returns float64 value
   724  func (n *FloatNode) GetValue() interface{} {
   725  	return n.Value
   726  }
   727  
   728  // String float64 to text
   729  func (n *FloatNode) String() string {
   730  	if n.Comment != nil {
   731  		return addCommentString(n.Token.Value, n.Comment)
   732  	}
   733  	return n.stringWithoutComment()
   734  }
   735  
   736  func (n *FloatNode) stringWithoutComment() string {
   737  	return n.Token.Value
   738  }
   739  
   740  // MarshalYAML encodes to a YAML text
   741  func (n *FloatNode) MarshalYAML() ([]byte, error) {
   742  	return []byte(n.String()), nil
   743  }
   744  
   745  // StringNode type of string node
   746  type StringNode struct {
   747  	*BaseNode
   748  	Token *token.Token
   749  	Value string
   750  }
   751  
   752  // Read implements (io.Reader).Read
   753  func (n *StringNode) Read(p []byte) (int, error) {
   754  	return readNode(p, n)
   755  }
   756  
   757  // Type returns StringType
   758  func (n *StringNode) Type() NodeType { return StringType }
   759  
   760  // GetToken returns token instance
   761  func (n *StringNode) GetToken() *token.Token {
   762  	return n.Token
   763  }
   764  
   765  // AddColumn add column number to child nodes recursively
   766  func (n *StringNode) AddColumn(col int) {
   767  	n.Token.AddColumn(col)
   768  }
   769  
   770  // GetValue returns string value
   771  func (n *StringNode) GetValue() interface{} {
   772  	return n.Value
   773  }
   774  
   775  // String string value to text with quote or literal header if required
   776  func (n *StringNode) String() string {
   777  	switch n.Token.Type {
   778  	case token.SingleQuoteType:
   779  		quoted := fmt.Sprintf(`'%s'`, n.Value)
   780  		if n.Comment != nil {
   781  			return addCommentString(quoted, n.Comment)
   782  		}
   783  		return quoted
   784  	case token.DoubleQuoteType:
   785  		quoted := strconv.Quote(n.Value)
   786  		if n.Comment != nil {
   787  			return addCommentString(quoted, n.Comment)
   788  		}
   789  		return quoted
   790  	}
   791  
   792  	lbc := token.DetectLineBreakCharacter(n.Value)
   793  	if strings.Contains(n.Value, lbc) {
   794  		// This block assumes that the line breaks in this inside scalar content and the Outside scalar content are the same.
   795  		// It works mostly, but inconsistencies occur if line break characters are mixed.
   796  		header := token.LiteralBlockHeader(n.Value)
   797  		space := strings.Repeat(" ", n.Token.Position.Column-1)
   798  		values := []string{}
   799  		for _, v := range strings.Split(n.Value, lbc) {
   800  			values = append(values, fmt.Sprintf("%s  %s", space, v))
   801  		}
   802  		block := strings.TrimSuffix(strings.TrimSuffix(strings.Join(values, lbc), fmt.Sprintf("%s  %s", lbc, space)), fmt.Sprintf("  %s", space))
   803  		return fmt.Sprintf("%s%s%s", header, lbc, block)
   804  	} else if len(n.Value) > 0 && (n.Value[0] == '{' || n.Value[0] == '[') {
   805  		return fmt.Sprintf(`'%s'`, n.Value)
   806  	}
   807  	if n.Comment != nil {
   808  		return addCommentString(n.Value, n.Comment)
   809  	}
   810  	return n.Value
   811  }
   812  
   813  func (n *StringNode) stringWithoutComment() string {
   814  	switch n.Token.Type {
   815  	case token.SingleQuoteType:
   816  		quoted := fmt.Sprintf(`'%s'`, n.Value)
   817  		return quoted
   818  	case token.DoubleQuoteType:
   819  		quoted := strconv.Quote(n.Value)
   820  		return quoted
   821  	}
   822  
   823  	lbc := token.DetectLineBreakCharacter(n.Value)
   824  	if strings.Contains(n.Value, lbc) {
   825  		// This block assumes that the line breaks in this inside scalar content and the Outside scalar content are the same.
   826  		// It works mostly, but inconsistencies occur if line break characters are mixed.
   827  		header := token.LiteralBlockHeader(n.Value)
   828  		space := strings.Repeat(" ", n.Token.Position.Column-1)
   829  		values := []string{}
   830  		for _, v := range strings.Split(n.Value, lbc) {
   831  			values = append(values, fmt.Sprintf("%s  %s", space, v))
   832  		}
   833  		block := strings.TrimSuffix(strings.TrimSuffix(strings.Join(values, lbc), fmt.Sprintf("%s  %s", lbc, space)), fmt.Sprintf("  %s", space))
   834  		return fmt.Sprintf("%s%s%s", header, lbc, block)
   835  	} else if len(n.Value) > 0 && (n.Value[0] == '{' || n.Value[0] == '[') {
   836  		return fmt.Sprintf(`'%s'`, n.Value)
   837  	}
   838  	return n.Value
   839  }
   840  
   841  // MarshalYAML encodes to a YAML text
   842  func (n *StringNode) MarshalYAML() ([]byte, error) {
   843  	return []byte(n.String()), nil
   844  }
   845  
   846  // LiteralNode type of literal node
   847  type LiteralNode struct {
   848  	*BaseNode
   849  	Start *token.Token
   850  	Value *StringNode
   851  }
   852  
   853  // Read implements (io.Reader).Read
   854  func (n *LiteralNode) Read(p []byte) (int, error) {
   855  	return readNode(p, n)
   856  }
   857  
   858  // Type returns LiteralType
   859  func (n *LiteralNode) Type() NodeType { return LiteralType }
   860  
   861  // GetToken returns token instance
   862  func (n *LiteralNode) GetToken() *token.Token {
   863  	return n.Start
   864  }
   865  
   866  // AddColumn add column number to child nodes recursively
   867  func (n *LiteralNode) AddColumn(col int) {
   868  	n.Start.AddColumn(col)
   869  	if n.Value != nil {
   870  		n.Value.AddColumn(col)
   871  	}
   872  }
   873  
   874  // GetValue returns string value
   875  func (n *LiteralNode) GetValue() interface{} {
   876  	return n.String()
   877  }
   878  
   879  // String literal to text
   880  func (n *LiteralNode) String() string {
   881  	origin := n.Value.GetToken().Origin
   882  	lit := strings.TrimRight(strings.TrimRight(origin, " "), "\n")
   883  	if n.Comment != nil {
   884  		return fmt.Sprintf("%s %s\n%s", n.Start.Value, n.Comment.String(), lit)
   885  	}
   886  	return fmt.Sprintf("%s\n%s", n.Start.Value, lit)
   887  }
   888  
   889  func (n *LiteralNode) stringWithoutComment() string {
   890  	return n.String()
   891  }
   892  
   893  // MarshalYAML encodes to a YAML text
   894  func (n *LiteralNode) MarshalYAML() ([]byte, error) {
   895  	return []byte(n.String()), nil
   896  }
   897  
   898  // MergeKeyNode type of merge key node
   899  type MergeKeyNode struct {
   900  	*BaseNode
   901  	Token *token.Token
   902  }
   903  
   904  // Read implements (io.Reader).Read
   905  func (n *MergeKeyNode) Read(p []byte) (int, error) {
   906  	return readNode(p, n)
   907  }
   908  
   909  // Type returns MergeKeyType
   910  func (n *MergeKeyNode) Type() NodeType { return MergeKeyType }
   911  
   912  // GetToken returns token instance
   913  func (n *MergeKeyNode) GetToken() *token.Token {
   914  	return n.Token
   915  }
   916  
   917  // GetValue returns '<<' value
   918  func (n *MergeKeyNode) GetValue() interface{} {
   919  	return n.Token.Value
   920  }
   921  
   922  // String returns '<<' value
   923  func (n *MergeKeyNode) String() string {
   924  	return n.Token.Value
   925  }
   926  
   927  func (n *MergeKeyNode) stringWithoutComment() string {
   928  	return n.Token.Value
   929  }
   930  
   931  // AddColumn add column number to child nodes recursively
   932  func (n *MergeKeyNode) AddColumn(col int) {
   933  	n.Token.AddColumn(col)
   934  }
   935  
   936  // MarshalYAML encodes to a YAML text
   937  func (n *MergeKeyNode) MarshalYAML() ([]byte, error) {
   938  	return []byte(n.String()), nil
   939  }
   940  
   941  // BoolNode type of boolean node
   942  type BoolNode struct {
   943  	*BaseNode
   944  	Token *token.Token
   945  	Value bool
   946  }
   947  
   948  // Read implements (io.Reader).Read
   949  func (n *BoolNode) Read(p []byte) (int, error) {
   950  	return readNode(p, n)
   951  }
   952  
   953  // Type returns BoolType
   954  func (n *BoolNode) Type() NodeType { return BoolType }
   955  
   956  // GetToken returns token instance
   957  func (n *BoolNode) GetToken() *token.Token {
   958  	return n.Token
   959  }
   960  
   961  // AddColumn add column number to child nodes recursively
   962  func (n *BoolNode) AddColumn(col int) {
   963  	n.Token.AddColumn(col)
   964  }
   965  
   966  // GetValue returns boolean value
   967  func (n *BoolNode) GetValue() interface{} {
   968  	return n.Value
   969  }
   970  
   971  // String boolean to text
   972  func (n *BoolNode) String() string {
   973  	if n.Comment != nil {
   974  		return addCommentString(n.Token.Value, n.Comment)
   975  	}
   976  	return n.stringWithoutComment()
   977  }
   978  
   979  func (n *BoolNode) stringWithoutComment() string {
   980  	return n.Token.Value
   981  }
   982  
   983  // MarshalYAML encodes to a YAML text
   984  func (n *BoolNode) MarshalYAML() ([]byte, error) {
   985  	return []byte(n.String()), nil
   986  }
   987  
   988  // InfinityNode type of infinity node
   989  type InfinityNode struct {
   990  	*BaseNode
   991  	Token *token.Token
   992  	Value float64
   993  }
   994  
   995  // Read implements (io.Reader).Read
   996  func (n *InfinityNode) Read(p []byte) (int, error) {
   997  	return readNode(p, n)
   998  }
   999  
  1000  // Type returns InfinityType
  1001  func (n *InfinityNode) Type() NodeType { return InfinityType }
  1002  
  1003  // GetToken returns token instance
  1004  func (n *InfinityNode) GetToken() *token.Token {
  1005  	return n.Token
  1006  }
  1007  
  1008  // AddColumn add column number to child nodes recursively
  1009  func (n *InfinityNode) AddColumn(col int) {
  1010  	n.Token.AddColumn(col)
  1011  }
  1012  
  1013  // GetValue returns math.Inf(0) or math.Inf(-1)
  1014  func (n *InfinityNode) GetValue() interface{} {
  1015  	return n.Value
  1016  }
  1017  
  1018  // String infinity to text
  1019  func (n *InfinityNode) String() string {
  1020  	if n.Comment != nil {
  1021  		return addCommentString(n.Token.Value, n.Comment)
  1022  	}
  1023  	return n.stringWithoutComment()
  1024  }
  1025  
  1026  func (n *InfinityNode) stringWithoutComment() string {
  1027  	return n.Token.Value
  1028  }
  1029  
  1030  // MarshalYAML encodes to a YAML text
  1031  func (n *InfinityNode) MarshalYAML() ([]byte, error) {
  1032  	return []byte(n.String()), nil
  1033  }
  1034  
  1035  // NanNode type of nan node
  1036  type NanNode struct {
  1037  	*BaseNode
  1038  	Token *token.Token
  1039  }
  1040  
  1041  // Read implements (io.Reader).Read
  1042  func (n *NanNode) Read(p []byte) (int, error) {
  1043  	return readNode(p, n)
  1044  }
  1045  
  1046  // Type returns NanType
  1047  func (n *NanNode) Type() NodeType { return NanType }
  1048  
  1049  // GetToken returns token instance
  1050  func (n *NanNode) GetToken() *token.Token {
  1051  	return n.Token
  1052  }
  1053  
  1054  // AddColumn add column number to child nodes recursively
  1055  func (n *NanNode) AddColumn(col int) {
  1056  	n.Token.AddColumn(col)
  1057  }
  1058  
  1059  // GetValue returns math.NaN()
  1060  func (n *NanNode) GetValue() interface{} {
  1061  	return math.NaN()
  1062  }
  1063  
  1064  // String returns .nan
  1065  func (n *NanNode) String() string {
  1066  	if n.Comment != nil {
  1067  		return addCommentString(n.Token.Value, n.Comment)
  1068  	}
  1069  	return n.stringWithoutComment()
  1070  }
  1071  
  1072  func (n *NanNode) stringWithoutComment() string {
  1073  	return n.Token.Value
  1074  }
  1075  
  1076  // MarshalYAML encodes to a YAML text
  1077  func (n *NanNode) MarshalYAML() ([]byte, error) {
  1078  	return []byte(n.String()), nil
  1079  }
  1080  
  1081  // MapNode interface of MappingValueNode / MappingNode
  1082  type MapNode interface {
  1083  	MapRange() *MapNodeIter
  1084  }
  1085  
  1086  // MapNodeIter is an iterator for ranging over a MapNode
  1087  type MapNodeIter struct {
  1088  	values []*MappingValueNode
  1089  	idx    int
  1090  }
  1091  
  1092  const (
  1093  	startRangeIndex = -1
  1094  )
  1095  
  1096  // Next advances the map iterator and reports whether there is another entry.
  1097  // It returns false when the iterator is exhausted.
  1098  func (m *MapNodeIter) Next() bool {
  1099  	m.idx++
  1100  	next := m.idx < len(m.values)
  1101  	return next
  1102  }
  1103  
  1104  // Key returns the key of the iterator's current map node entry.
  1105  func (m *MapNodeIter) Key() Node {
  1106  	return m.values[m.idx].Key
  1107  }
  1108  
  1109  // Value returns the value of the iterator's current map node entry.
  1110  func (m *MapNodeIter) Value() Node {
  1111  	return m.values[m.idx].Value
  1112  }
  1113  
  1114  // MappingNode type of mapping node
  1115  type MappingNode struct {
  1116  	*BaseNode
  1117  	Start       *token.Token
  1118  	End         *token.Token
  1119  	IsFlowStyle bool
  1120  	Values      []*MappingValueNode
  1121  }
  1122  
  1123  func (n *MappingNode) startPos() *token.Position {
  1124  	if len(n.Values) == 0 {
  1125  		return n.Start.Position
  1126  	}
  1127  	return n.Values[0].Key.GetToken().Position
  1128  }
  1129  
  1130  // Merge merge key/value of map.
  1131  func (n *MappingNode) Merge(target *MappingNode) {
  1132  	keyToMapValueMap := map[string]*MappingValueNode{}
  1133  	for _, value := range n.Values {
  1134  		key := value.Key.String()
  1135  		keyToMapValueMap[key] = value
  1136  	}
  1137  	column := n.startPos().Column - target.startPos().Column
  1138  	target.AddColumn(column)
  1139  	for _, value := range target.Values {
  1140  		mapValue, exists := keyToMapValueMap[value.Key.String()]
  1141  		if exists {
  1142  			mapValue.Value = value.Value
  1143  		} else {
  1144  			n.Values = append(n.Values, value)
  1145  		}
  1146  	}
  1147  }
  1148  
  1149  // SetIsFlowStyle set value to IsFlowStyle field recursively.
  1150  func (n *MappingNode) SetIsFlowStyle(isFlow bool) {
  1151  	n.IsFlowStyle = isFlow
  1152  	for _, value := range n.Values {
  1153  		value.SetIsFlowStyle(isFlow)
  1154  	}
  1155  }
  1156  
  1157  // Read implements (io.Reader).Read
  1158  func (n *MappingNode) Read(p []byte) (int, error) {
  1159  	return readNode(p, n)
  1160  }
  1161  
  1162  // Type returns MappingType
  1163  func (n *MappingNode) Type() NodeType { return MappingType }
  1164  
  1165  // GetToken returns token instance
  1166  func (n *MappingNode) GetToken() *token.Token {
  1167  	return n.Start
  1168  }
  1169  
  1170  // AddColumn add column number to child nodes recursively
  1171  func (n *MappingNode) AddColumn(col int) {
  1172  	n.Start.AddColumn(col)
  1173  	n.End.AddColumn(col)
  1174  	for _, value := range n.Values {
  1175  		value.AddColumn(col)
  1176  	}
  1177  }
  1178  
  1179  func (n *MappingNode) flowStyleString(commentMode bool) string {
  1180  	values := []string{}
  1181  	for _, value := range n.Values {
  1182  		values = append(values, strings.TrimLeft(value.String(), " "))
  1183  	}
  1184  	mapText := fmt.Sprintf("{%s}", strings.Join(values, ", "))
  1185  	if commentMode && n.Comment != nil {
  1186  		return addCommentString(mapText, n.Comment)
  1187  	}
  1188  	return mapText
  1189  }
  1190  
  1191  func (n *MappingNode) blockStyleString(commentMode bool) string {
  1192  	values := []string{}
  1193  	for _, value := range n.Values {
  1194  		values = append(values, value.String())
  1195  	}
  1196  	mapText := strings.Join(values, "\n")
  1197  	if commentMode && n.Comment != nil {
  1198  		value := values[0]
  1199  		var spaceNum int
  1200  		for i := 0; i < len(value); i++ {
  1201  			if value[i] != ' ' {
  1202  				break
  1203  			}
  1204  			spaceNum++
  1205  		}
  1206  		comment := n.Comment.StringWithSpace(spaceNum)
  1207  		return fmt.Sprintf("%s\n%s", comment, mapText)
  1208  	}
  1209  	return mapText
  1210  }
  1211  
  1212  // String mapping values to text
  1213  func (n *MappingNode) String() string {
  1214  	if len(n.Values) == 0 {
  1215  		if n.Comment != nil {
  1216  			return addCommentString("{}", n.Comment)
  1217  		}
  1218  		return "{}"
  1219  	}
  1220  
  1221  	commentMode := true
  1222  	if n.IsFlowStyle || len(n.Values) == 0 {
  1223  		return n.flowStyleString(commentMode)
  1224  	}
  1225  	return n.blockStyleString(commentMode)
  1226  }
  1227  
  1228  func (n *MappingNode) stringWithoutComment() string {
  1229  	commentMode := false
  1230  	if n.IsFlowStyle || len(n.Values) == 0 {
  1231  		return n.flowStyleString(commentMode)
  1232  	}
  1233  	return n.blockStyleString(commentMode)
  1234  }
  1235  
  1236  // MapRange implements MapNode protocol
  1237  func (n *MappingNode) MapRange() *MapNodeIter {
  1238  	return &MapNodeIter{
  1239  		idx:    startRangeIndex,
  1240  		values: n.Values,
  1241  	}
  1242  }
  1243  
  1244  // MarshalYAML encodes to a YAML text
  1245  func (n *MappingNode) MarshalYAML() ([]byte, error) {
  1246  	return []byte(n.String()), nil
  1247  }
  1248  
  1249  // MappingKeyNode type of tag node
  1250  type MappingKeyNode struct {
  1251  	*BaseNode
  1252  	Start *token.Token
  1253  	Value Node
  1254  }
  1255  
  1256  // Read implements (io.Reader).Read
  1257  func (n *MappingKeyNode) Read(p []byte) (int, error) {
  1258  	return readNode(p, n)
  1259  }
  1260  
  1261  // Type returns MappingKeyType
  1262  func (n *MappingKeyNode) Type() NodeType { return MappingKeyType }
  1263  
  1264  // GetToken returns token instance
  1265  func (n *MappingKeyNode) GetToken() *token.Token {
  1266  	return n.Start
  1267  }
  1268  
  1269  // AddColumn add column number to child nodes recursively
  1270  func (n *MappingKeyNode) AddColumn(col int) {
  1271  	n.Start.AddColumn(col)
  1272  	if n.Value != nil {
  1273  		n.Value.AddColumn(col)
  1274  	}
  1275  }
  1276  
  1277  // String tag to text
  1278  func (n *MappingKeyNode) String() string {
  1279  	return fmt.Sprintf("%s %s", n.Start.Value, n.Value.String())
  1280  }
  1281  
  1282  func (n *MappingKeyNode) stringWithoutComment() string {
  1283  	return fmt.Sprintf("%s %s", n.Start.Value, n.Value.String())
  1284  }
  1285  
  1286  // MarshalYAML encodes to a YAML text
  1287  func (n *MappingKeyNode) MarshalYAML() ([]byte, error) {
  1288  	return []byte(n.String()), nil
  1289  }
  1290  
  1291  // MappingValueNode type of mapping value
  1292  type MappingValueNode struct {
  1293  	*BaseNode
  1294  	Start *token.Token
  1295  	Key   Node
  1296  	Value Node
  1297  }
  1298  
  1299  // Replace replace value node.
  1300  func (n *MappingValueNode) Replace(value Node) error {
  1301  	column := n.Value.GetToken().Position.Column - value.GetToken().Position.Column
  1302  	value.AddColumn(column)
  1303  	n.Value = value
  1304  	return nil
  1305  }
  1306  
  1307  // Read implements (io.Reader).Read
  1308  func (n *MappingValueNode) Read(p []byte) (int, error) {
  1309  	return readNode(p, n)
  1310  }
  1311  
  1312  // Type returns MappingValueType
  1313  func (n *MappingValueNode) Type() NodeType { return MappingValueType }
  1314  
  1315  // GetToken returns token instance
  1316  func (n *MappingValueNode) GetToken() *token.Token {
  1317  	return n.Start
  1318  }
  1319  
  1320  // AddColumn add column number to child nodes recursively
  1321  func (n *MappingValueNode) AddColumn(col int) {
  1322  	n.Start.AddColumn(col)
  1323  	if n.Key != nil {
  1324  		n.Key.AddColumn(col)
  1325  	}
  1326  	if n.Value != nil {
  1327  		n.Value.AddColumn(col)
  1328  	}
  1329  }
  1330  
  1331  // SetIsFlowStyle set value to IsFlowStyle field recursively.
  1332  func (n *MappingValueNode) SetIsFlowStyle(isFlow bool) {
  1333  	switch value := n.Value.(type) {
  1334  	case *MappingNode:
  1335  		value.SetIsFlowStyle(isFlow)
  1336  	case *MappingValueNode:
  1337  		value.SetIsFlowStyle(isFlow)
  1338  	case *SequenceNode:
  1339  		value.SetIsFlowStyle(isFlow)
  1340  	}
  1341  }
  1342  
  1343  // String mapping value to text
  1344  func (n *MappingValueNode) String() string {
  1345  	if n.Comment != nil {
  1346  		return fmt.Sprintf(
  1347  			"%s\n%s",
  1348  			n.Comment.StringWithSpace(n.Key.GetToken().Position.Column-1),
  1349  			n.toString(),
  1350  		)
  1351  	}
  1352  	return n.toString()
  1353  }
  1354  
  1355  func (n *MappingValueNode) toString() string {
  1356  	space := strings.Repeat(" ", n.Key.GetToken().Position.Column-1)
  1357  	keyIndentLevel := n.Key.GetToken().Position.IndentLevel
  1358  	valueIndentLevel := n.Value.GetToken().Position.IndentLevel
  1359  	keyComment := n.Key.GetComment()
  1360  	if _, ok := n.Value.(ScalarNode); ok {
  1361  		return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
  1362  	} else if keyIndentLevel < valueIndentLevel {
  1363  		if keyComment != nil {
  1364  			return fmt.Sprintf(
  1365  				"%s%s: %s\n%s",
  1366  				space,
  1367  				n.Key.stringWithoutComment(),
  1368  				keyComment.String(),
  1369  				n.Value.String(),
  1370  			)
  1371  		}
  1372  		return fmt.Sprintf("%s%s:\n%s", space, n.Key.String(), n.Value.String())
  1373  	} else if m, ok := n.Value.(*MappingNode); ok && (m.IsFlowStyle || len(m.Values) == 0) {
  1374  		return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
  1375  	} else if s, ok := n.Value.(*SequenceNode); ok && (s.IsFlowStyle || len(s.Values) == 0) {
  1376  		return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
  1377  	} else if _, ok := n.Value.(*AnchorNode); ok {
  1378  		return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
  1379  	} else if _, ok := n.Value.(*AliasNode); ok {
  1380  		return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
  1381  	}
  1382  	if keyComment != nil {
  1383  		return fmt.Sprintf(
  1384  			"%s%s: %s\n%s",
  1385  			space,
  1386  			n.Key.stringWithoutComment(),
  1387  			keyComment.String(),
  1388  			n.Value.String(),
  1389  		)
  1390  	}
  1391  	if m, ok := n.Value.(*MappingNode); ok && m.Comment != nil {
  1392  		return fmt.Sprintf(
  1393  			"%s%s: %s",
  1394  			space,
  1395  			n.Key.String(),
  1396  			strings.TrimLeft(n.Value.String(), " "),
  1397  		)
  1398  	}
  1399  	return fmt.Sprintf("%s%s:\n%s", space, n.Key.String(), n.Value.String())
  1400  }
  1401  
  1402  func (n *MappingValueNode) stringWithoutComment() string {
  1403  	space := strings.Repeat(" ", n.Key.GetToken().Position.Column-1)
  1404  	keyIndentLevel := n.Key.GetToken().Position.IndentLevel
  1405  	valueIndentLevel := n.Value.GetToken().Position.IndentLevel
  1406  	if _, ok := n.Value.(ScalarNode); ok {
  1407  		return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
  1408  	} else if keyIndentLevel < valueIndentLevel {
  1409  		return fmt.Sprintf("%s%s:\n%s", space, n.Key.String(), n.Value.String())
  1410  	} else if m, ok := n.Value.(*MappingNode); ok && (m.IsFlowStyle || len(m.Values) == 0) {
  1411  		return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
  1412  	} else if s, ok := n.Value.(*SequenceNode); ok && (s.IsFlowStyle || len(s.Values) == 0) {
  1413  		return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
  1414  	} else if _, ok := n.Value.(*AnchorNode); ok {
  1415  		return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
  1416  	} else if _, ok := n.Value.(*AliasNode); ok {
  1417  		return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String())
  1418  	}
  1419  	return fmt.Sprintf("%s%s:\n%s", space, n.Key.String(), n.Value.String())
  1420  }
  1421  
  1422  // MapRange implements MapNode protocol
  1423  func (n *MappingValueNode) MapRange() *MapNodeIter {
  1424  	return &MapNodeIter{
  1425  		idx:    startRangeIndex,
  1426  		values: []*MappingValueNode{n},
  1427  	}
  1428  }
  1429  
  1430  // MarshalYAML encodes to a YAML text
  1431  func (n *MappingValueNode) MarshalYAML() ([]byte, error) {
  1432  	return []byte(n.String()), nil
  1433  }
  1434  
  1435  // ArrayNode interface of SequenceNode
  1436  type ArrayNode interface {
  1437  	ArrayRange() *ArrayNodeIter
  1438  }
  1439  
  1440  // ArrayNodeIter is an iterator for ranging over a ArrayNode
  1441  type ArrayNodeIter struct {
  1442  	values []Node
  1443  	idx    int
  1444  }
  1445  
  1446  // Next advances the array iterator and reports whether there is another entry.
  1447  // It returns false when the iterator is exhausted.
  1448  func (m *ArrayNodeIter) Next() bool {
  1449  	m.idx++
  1450  	next := m.idx < len(m.values)
  1451  	return next
  1452  }
  1453  
  1454  // Value returns the value of the iterator's current array entry.
  1455  func (m *ArrayNodeIter) Value() Node {
  1456  	return m.values[m.idx]
  1457  }
  1458  
  1459  // Len returns length of array
  1460  func (m *ArrayNodeIter) Len() int {
  1461  	return len(m.values)
  1462  }
  1463  
  1464  // SequenceNode type of sequence node
  1465  type SequenceNode struct {
  1466  	*BaseNode
  1467  	Start         *token.Token
  1468  	End           *token.Token
  1469  	IsFlowStyle   bool
  1470  	Values        []Node
  1471  	ValueComments []*CommentGroupNode
  1472  }
  1473  
  1474  // Replace replace value node.
  1475  func (n *SequenceNode) Replace(idx int, value Node) error {
  1476  	if len(n.Values) <= idx {
  1477  		return xerrors.Errorf(
  1478  			"invalid index for sequence: sequence length is %d, but specified %d index",
  1479  			len(n.Values), idx,
  1480  		)
  1481  	}
  1482  	column := n.Values[idx].GetToken().Position.Column - value.GetToken().Position.Column
  1483  	value.AddColumn(column)
  1484  	n.Values[idx] = value
  1485  	return nil
  1486  }
  1487  
  1488  // Merge merge sequence value.
  1489  func (n *SequenceNode) Merge(target *SequenceNode) {
  1490  	column := n.Start.Position.Column - target.Start.Position.Column
  1491  	target.AddColumn(column)
  1492  	for _, value := range target.Values {
  1493  		n.Values = append(n.Values, value)
  1494  	}
  1495  }
  1496  
  1497  // SetIsFlowStyle set value to IsFlowStyle field recursively.
  1498  func (n *SequenceNode) SetIsFlowStyle(isFlow bool) {
  1499  	n.IsFlowStyle = isFlow
  1500  	for _, value := range n.Values {
  1501  		switch value := value.(type) {
  1502  		case *MappingNode:
  1503  			value.SetIsFlowStyle(isFlow)
  1504  		case *MappingValueNode:
  1505  			value.SetIsFlowStyle(isFlow)
  1506  		case *SequenceNode:
  1507  			value.SetIsFlowStyle(isFlow)
  1508  		}
  1509  	}
  1510  }
  1511  
  1512  // Read implements (io.Reader).Read
  1513  func (n *SequenceNode) Read(p []byte) (int, error) {
  1514  	return readNode(p, n)
  1515  }
  1516  
  1517  // Type returns SequenceType
  1518  func (n *SequenceNode) Type() NodeType { return SequenceType }
  1519  
  1520  // GetToken returns token instance
  1521  func (n *SequenceNode) GetToken() *token.Token {
  1522  	return n.Start
  1523  }
  1524  
  1525  // AddColumn add column number to child nodes recursively
  1526  func (n *SequenceNode) AddColumn(col int) {
  1527  	n.Start.AddColumn(col)
  1528  	n.End.AddColumn(col)
  1529  	for _, value := range n.Values {
  1530  		value.AddColumn(col)
  1531  	}
  1532  }
  1533  
  1534  func (n *SequenceNode) flowStyleString() string {
  1535  	values := []string{}
  1536  	for _, value := range n.Values {
  1537  		values = append(values, value.String())
  1538  	}
  1539  	return fmt.Sprintf("[%s]", strings.Join(values, ", "))
  1540  }
  1541  
  1542  func (n *SequenceNode) blockStyleString() string {
  1543  	space := strings.Repeat(" ", n.Start.Position.Column-1)
  1544  	values := []string{}
  1545  	if n.Comment != nil {
  1546  		values = append(values, n.Comment.StringWithSpace(n.Start.Position.Column-1))
  1547  	}
  1548  
  1549  	for idx, value := range n.Values {
  1550  		valueStr := value.String()
  1551  		splittedValues := strings.Split(valueStr, "\n")
  1552  		trimmedFirstValue := strings.TrimLeft(splittedValues[0], " ")
  1553  		diffLength := len(splittedValues[0]) - len(trimmedFirstValue)
  1554  		newValues := []string{trimmedFirstValue}
  1555  		for i := 1; i < len(splittedValues); i++ {
  1556  			if len(splittedValues[i]) <= diffLength {
  1557  				// this line is \n or white space only
  1558  				newValues = append(newValues, "")
  1559  				continue
  1560  			}
  1561  			trimmed := splittedValues[i][diffLength:]
  1562  			newValues = append(newValues, fmt.Sprintf("%s  %s", space, trimmed))
  1563  		}
  1564  		newValue := strings.Join(newValues, "\n")
  1565  		if len(n.ValueComments) == len(n.Values) && n.ValueComments[idx] != nil {
  1566  			values = append(values, n.ValueComments[idx].StringWithSpace(n.Start.Position.Column-1))
  1567  		}
  1568  		values = append(values, fmt.Sprintf("%s- %s", space, newValue))
  1569  	}
  1570  	return strings.Join(values, "\n")
  1571  }
  1572  
  1573  // String sequence to text
  1574  func (n *SequenceNode) String() string {
  1575  	if n.IsFlowStyle || len(n.Values) == 0 {
  1576  		return n.flowStyleString()
  1577  	}
  1578  	return n.blockStyleString()
  1579  }
  1580  
  1581  func (n *SequenceNode) stringWithoutComment() string {
  1582  	if n.IsFlowStyle || len(n.Values) == 0 {
  1583  		return n.flowStyleString()
  1584  	}
  1585  	return n.blockStyleString()
  1586  }
  1587  
  1588  // ArrayRange implements ArrayNode protocol
  1589  func (n *SequenceNode) ArrayRange() *ArrayNodeIter {
  1590  	return &ArrayNodeIter{
  1591  		idx:    startRangeIndex,
  1592  		values: n.Values,
  1593  	}
  1594  }
  1595  
  1596  // MarshalYAML encodes to a YAML text
  1597  func (n *SequenceNode) MarshalYAML() ([]byte, error) {
  1598  	return []byte(n.String()), nil
  1599  }
  1600  
  1601  // AnchorNode type of anchor node
  1602  type AnchorNode struct {
  1603  	*BaseNode
  1604  	Start *token.Token
  1605  	Name  Node
  1606  	Value Node
  1607  }
  1608  
  1609  func (n *AnchorNode) SetName(name string) error {
  1610  	if n.Name == nil {
  1611  		return ErrInvalidAnchorName
  1612  	}
  1613  	s, ok := n.Name.(*StringNode)
  1614  	if !ok {
  1615  		return ErrInvalidAnchorName
  1616  	}
  1617  	s.Value = name
  1618  	return nil
  1619  }
  1620  
  1621  // Read implements (io.Reader).Read
  1622  func (n *AnchorNode) Read(p []byte) (int, error) {
  1623  	return readNode(p, n)
  1624  }
  1625  
  1626  // Type returns AnchorType
  1627  func (n *AnchorNode) Type() NodeType { return AnchorType }
  1628  
  1629  // GetToken returns token instance
  1630  func (n *AnchorNode) GetToken() *token.Token {
  1631  	return n.Start
  1632  }
  1633  
  1634  // AddColumn add column number to child nodes recursively
  1635  func (n *AnchorNode) AddColumn(col int) {
  1636  	n.Start.AddColumn(col)
  1637  	if n.Name != nil {
  1638  		n.Name.AddColumn(col)
  1639  	}
  1640  	if n.Value != nil {
  1641  		n.Value.AddColumn(col)
  1642  	}
  1643  }
  1644  
  1645  // String anchor to text
  1646  func (n *AnchorNode) String() string {
  1647  	value := n.Value.String()
  1648  	if len(strings.Split(value, "\n")) > 1 {
  1649  		return fmt.Sprintf("&%s\n%s", n.Name.String(), value)
  1650  	} else if s, ok := n.Value.(*SequenceNode); ok && !s.IsFlowStyle {
  1651  		return fmt.Sprintf("&%s\n%s", n.Name.String(), value)
  1652  	} else if m, ok := n.Value.(*MappingNode); ok && !m.IsFlowStyle {
  1653  		return fmt.Sprintf("&%s\n%s", n.Name.String(), value)
  1654  	}
  1655  	return fmt.Sprintf("&%s %s", n.Name.String(), value)
  1656  }
  1657  
  1658  func (n *AnchorNode) stringWithoutComment() string {
  1659  	return n.String()
  1660  }
  1661  
  1662  // MarshalYAML encodes to a YAML text
  1663  func (n *AnchorNode) MarshalYAML() ([]byte, error) {
  1664  	return []byte(n.String()), nil
  1665  }
  1666  
  1667  // AliasNode type of alias node
  1668  type AliasNode struct {
  1669  	*BaseNode
  1670  	Start *token.Token
  1671  	Value Node
  1672  }
  1673  
  1674  func (n *AliasNode) SetName(name string) error {
  1675  	if n.Value == nil {
  1676  		return ErrInvalidAliasName
  1677  	}
  1678  	s, ok := n.Value.(*StringNode)
  1679  	if !ok {
  1680  		return ErrInvalidAliasName
  1681  	}
  1682  	s.Value = name
  1683  	return nil
  1684  }
  1685  
  1686  // Read implements (io.Reader).Read
  1687  func (n *AliasNode) Read(p []byte) (int, error) {
  1688  	return readNode(p, n)
  1689  }
  1690  
  1691  // Type returns AliasType
  1692  func (n *AliasNode) Type() NodeType { return AliasType }
  1693  
  1694  // GetToken returns token instance
  1695  func (n *AliasNode) GetToken() *token.Token {
  1696  	return n.Start
  1697  }
  1698  
  1699  // AddColumn add column number to child nodes recursively
  1700  func (n *AliasNode) AddColumn(col int) {
  1701  	n.Start.AddColumn(col)
  1702  	if n.Value != nil {
  1703  		n.Value.AddColumn(col)
  1704  	}
  1705  }
  1706  
  1707  // String alias to text
  1708  func (n *AliasNode) String() string {
  1709  	return fmt.Sprintf("*%s", n.Value.String())
  1710  }
  1711  
  1712  func (n *AliasNode) stringWithoutComment() string {
  1713  	return fmt.Sprintf("*%s", n.Value.String())
  1714  }
  1715  
  1716  // MarshalYAML encodes to a YAML text
  1717  func (n *AliasNode) MarshalYAML() ([]byte, error) {
  1718  	return []byte(n.String()), nil
  1719  }
  1720  
  1721  // DirectiveNode type of directive node
  1722  type DirectiveNode struct {
  1723  	*BaseNode
  1724  	Start *token.Token
  1725  	Value Node
  1726  }
  1727  
  1728  // Read implements (io.Reader).Read
  1729  func (n *DirectiveNode) Read(p []byte) (int, error) {
  1730  	return readNode(p, n)
  1731  }
  1732  
  1733  // Type returns DirectiveType
  1734  func (n *DirectiveNode) Type() NodeType { return DirectiveType }
  1735  
  1736  // GetToken returns token instance
  1737  func (n *DirectiveNode) GetToken() *token.Token {
  1738  	return n.Start
  1739  }
  1740  
  1741  // AddColumn add column number to child nodes recursively
  1742  func (n *DirectiveNode) AddColumn(col int) {
  1743  	if n.Value != nil {
  1744  		n.Value.AddColumn(col)
  1745  	}
  1746  }
  1747  
  1748  // String directive to text
  1749  func (n *DirectiveNode) String() string {
  1750  	return fmt.Sprintf("%s%s", n.Start.Value, n.Value.String())
  1751  }
  1752  
  1753  func (n *DirectiveNode) stringWithoutComment() string {
  1754  	return fmt.Sprintf("%s%s", n.Start.Value, n.Value.String())
  1755  }
  1756  
  1757  // MarshalYAML encodes to a YAML text
  1758  func (n *DirectiveNode) MarshalYAML() ([]byte, error) {
  1759  	return []byte(n.String()), nil
  1760  }
  1761  
  1762  // TagNode type of tag node
  1763  type TagNode struct {
  1764  	*BaseNode
  1765  	Start *token.Token
  1766  	Value Node
  1767  }
  1768  
  1769  // Read implements (io.Reader).Read
  1770  func (n *TagNode) Read(p []byte) (int, error) {
  1771  	return readNode(p, n)
  1772  }
  1773  
  1774  // Type returns TagType
  1775  func (n *TagNode) Type() NodeType { return TagType }
  1776  
  1777  // GetToken returns token instance
  1778  func (n *TagNode) GetToken() *token.Token {
  1779  	return n.Start
  1780  }
  1781  
  1782  // AddColumn add column number to child nodes recursively
  1783  func (n *TagNode) AddColumn(col int) {
  1784  	n.Start.AddColumn(col)
  1785  	if n.Value != nil {
  1786  		n.Value.AddColumn(col)
  1787  	}
  1788  }
  1789  
  1790  // String tag to text
  1791  func (n *TagNode) String() string {
  1792  	return fmt.Sprintf("%s %s", n.Start.Value, n.Value.String())
  1793  }
  1794  
  1795  func (n *TagNode) stringWithoutComment() string {
  1796  	return fmt.Sprintf("%s %s", n.Start.Value, n.Value.String())
  1797  }
  1798  
  1799  // MarshalYAML encodes to a YAML text
  1800  func (n *TagNode) MarshalYAML() ([]byte, error) {
  1801  	return []byte(n.String()), nil
  1802  }
  1803  
  1804  // CommentNode type of comment node
  1805  type CommentNode struct {
  1806  	*BaseNode
  1807  	Token *token.Token
  1808  }
  1809  
  1810  // Read implements (io.Reader).Read
  1811  func (n *CommentNode) Read(p []byte) (int, error) {
  1812  	return readNode(p, n)
  1813  }
  1814  
  1815  // Type returns TagType
  1816  func (n *CommentNode) Type() NodeType { return CommentType }
  1817  
  1818  // GetToken returns token instance
  1819  func (n *CommentNode) GetToken() *token.Token { return n.Token }
  1820  
  1821  // AddColumn add column number to child nodes recursively
  1822  func (n *CommentNode) AddColumn(col int) {
  1823  	if n.Token == nil {
  1824  		return
  1825  	}
  1826  	n.Token.AddColumn(col)
  1827  }
  1828  
  1829  // String comment to text
  1830  func (n *CommentNode) String() string {
  1831  	return fmt.Sprintf("#%s", n.Token.Value)
  1832  }
  1833  
  1834  func (n *CommentNode) stringWithoutComment() string {
  1835  	return ""
  1836  }
  1837  
  1838  // MarshalYAML encodes to a YAML text
  1839  func (n *CommentNode) MarshalYAML() ([]byte, error) {
  1840  	return []byte(n.String()), nil
  1841  }
  1842  
  1843  // CommentGroupNode type of comment node
  1844  type CommentGroupNode struct {
  1845  	*BaseNode
  1846  	Comments []*CommentNode
  1847  }
  1848  
  1849  // Read implements (io.Reader).Read
  1850  func (n *CommentGroupNode) Read(p []byte) (int, error) {
  1851  	return readNode(p, n)
  1852  }
  1853  
  1854  // Type returns TagType
  1855  func (n *CommentGroupNode) Type() NodeType { return CommentType }
  1856  
  1857  // GetToken returns token instance
  1858  func (n *CommentGroupNode) GetToken() *token.Token {
  1859  	if len(n.Comments) > 0 {
  1860  		return n.Comments[0].Token
  1861  	}
  1862  	return nil
  1863  }
  1864  
  1865  // AddColumn add column number to child nodes recursively
  1866  func (n *CommentGroupNode) AddColumn(col int) {
  1867  	for _, comment := range n.Comments {
  1868  		comment.AddColumn(col)
  1869  	}
  1870  }
  1871  
  1872  // String comment to text
  1873  func (n *CommentGroupNode) String() string {
  1874  	values := []string{}
  1875  	for _, comment := range n.Comments {
  1876  		values = append(values, comment.String())
  1877  	}
  1878  	return strings.Join(values, "\n")
  1879  }
  1880  
  1881  func (n *CommentGroupNode) StringWithSpace(col int) string {
  1882  	space := strings.Repeat(" ", col)
  1883  	values := []string{}
  1884  	for _, comment := range n.Comments {
  1885  		values = append(values, space+comment.String())
  1886  	}
  1887  	return strings.Join(values, "\n")
  1888  }
  1889  
  1890  func (n *CommentGroupNode) stringWithoutComment() string {
  1891  	return ""
  1892  }
  1893  
  1894  // MarshalYAML encodes to a YAML text
  1895  func (n *CommentGroupNode) MarshalYAML() ([]byte, error) {
  1896  	return []byte(n.String()), nil
  1897  }
  1898  
  1899  // Visitor has Visit method that is invokded for each node encountered by Walk.
  1900  // If the result visitor w is not nil, Walk visits each of the children of node with the visitor w,
  1901  // followed by a call of w.Visit(nil).
  1902  type Visitor interface {
  1903  	Visit(Node) Visitor
  1904  }
  1905  
  1906  // Walk traverses an AST in depth-first order: It starts by calling v.Visit(node); node must not be nil.
  1907  // If the visitor w returned by v.Visit(node) is not nil,
  1908  // Walk is invoked recursively with visitor w for each of the non-nil children of node,
  1909  // followed by a call of w.Visit(nil).
  1910  func Walk(v Visitor, node Node) {
  1911  	if v = v.Visit(node); v == nil {
  1912  		return
  1913  	}
  1914  
  1915  	switch n := node.(type) {
  1916  	case *CommentNode:
  1917  	case *NullNode:
  1918  	case *IntegerNode:
  1919  	case *FloatNode:
  1920  	case *StringNode:
  1921  	case *MergeKeyNode:
  1922  	case *BoolNode:
  1923  	case *InfinityNode:
  1924  	case *NanNode:
  1925  	case *LiteralNode:
  1926  		Walk(v, n.Value)
  1927  	case *DirectiveNode:
  1928  		Walk(v, n.Value)
  1929  	case *TagNode:
  1930  		Walk(v, n.Value)
  1931  	case *DocumentNode:
  1932  		Walk(v, n.Body)
  1933  	case *MappingNode:
  1934  		for _, value := range n.Values {
  1935  			Walk(v, value)
  1936  		}
  1937  	case *MappingKeyNode:
  1938  		Walk(v, n.Value)
  1939  	case *MappingValueNode:
  1940  		Walk(v, n.Key)
  1941  		Walk(v, n.Value)
  1942  	case *SequenceNode:
  1943  		for _, value := range n.Values {
  1944  			Walk(v, value)
  1945  		}
  1946  	case *AnchorNode:
  1947  		Walk(v, n.Name)
  1948  		Walk(v, n.Value)
  1949  	case *AliasNode:
  1950  		Walk(v, n.Value)
  1951  	}
  1952  }
  1953  
  1954  type filterWalker struct {
  1955  	typ     NodeType
  1956  	results []Node
  1957  }
  1958  
  1959  func (v *filterWalker) Visit(n Node) Visitor {
  1960  	if v.typ == n.Type() {
  1961  		v.results = append(v.results, n)
  1962  	}
  1963  	return v
  1964  }
  1965  
  1966  type parentFinder struct {
  1967  	target Node
  1968  }
  1969  
  1970  func (f *parentFinder) walk(parent, node Node) Node {
  1971  	if f.target == node {
  1972  		return parent
  1973  	}
  1974  	switch n := node.(type) {
  1975  	case *CommentNode:
  1976  		return nil
  1977  	case *NullNode:
  1978  		return nil
  1979  	case *IntegerNode:
  1980  		return nil
  1981  	case *FloatNode:
  1982  		return nil
  1983  	case *StringNode:
  1984  		return nil
  1985  	case *MergeKeyNode:
  1986  		return nil
  1987  	case *BoolNode:
  1988  		return nil
  1989  	case *InfinityNode:
  1990  		return nil
  1991  	case *NanNode:
  1992  		return nil
  1993  	case *LiteralNode:
  1994  		return f.walk(node, n.Value)
  1995  	case *DirectiveNode:
  1996  		return f.walk(node, n.Value)
  1997  	case *TagNode:
  1998  		return f.walk(node, n.Value)
  1999  	case *DocumentNode:
  2000  		return f.walk(node, n.Body)
  2001  	case *MappingNode:
  2002  		for _, value := range n.Values {
  2003  			if found := f.walk(node, value); found != nil {
  2004  				return found
  2005  			}
  2006  		}
  2007  	case *MappingKeyNode:
  2008  		return f.walk(node, n.Value)
  2009  	case *MappingValueNode:
  2010  		if found := f.walk(node, n.Key); found != nil {
  2011  			return found
  2012  		}
  2013  		return f.walk(node, n.Value)
  2014  	case *SequenceNode:
  2015  		for _, value := range n.Values {
  2016  			if found := f.walk(node, value); found != nil {
  2017  				return found
  2018  			}
  2019  		}
  2020  	case *AnchorNode:
  2021  		if found := f.walk(node, n.Name); found != nil {
  2022  			return found
  2023  		}
  2024  		return f.walk(node, n.Value)
  2025  	case *AliasNode:
  2026  		return f.walk(node, n.Value)
  2027  	}
  2028  	return nil
  2029  }
  2030  
  2031  // Parent get parent node from child node.
  2032  func Parent(root, child Node) Node {
  2033  	finder := &parentFinder{target: child}
  2034  	return finder.walk(root, root)
  2035  }
  2036  
  2037  // Filter returns a list of nodes that match the given type.
  2038  func Filter(typ NodeType, node Node) []Node {
  2039  	walker := &filterWalker{typ: typ}
  2040  	Walk(walker, node)
  2041  	return walker.results
  2042  }
  2043  
  2044  // FilterFile returns a list of nodes that match the given type.
  2045  func FilterFile(typ NodeType, file *File) []Node {
  2046  	results := []Node{}
  2047  	for _, doc := range file.Docs {
  2048  		walker := &filterWalker{typ: typ}
  2049  		Walk(walker, doc)
  2050  		results = append(results, walker.results...)
  2051  	}
  2052  	return results
  2053  }
  2054  
  2055  type ErrInvalidMergeType struct {
  2056  	dst Node
  2057  	src Node
  2058  }
  2059  
  2060  func (e *ErrInvalidMergeType) Error() string {
  2061  	return fmt.Sprintf("cannot merge %s into %s", e.src.Type(), e.dst.Type())
  2062  }
  2063  
  2064  // Merge merge document, map, sequence node.
  2065  func Merge(dst Node, src Node) error {
  2066  	if doc, ok := src.(*DocumentNode); ok {
  2067  		src = doc.Body
  2068  	}
  2069  	err := &ErrInvalidMergeType{dst: dst, src: src}
  2070  	switch dst.Type() {
  2071  	case DocumentType:
  2072  		node := dst.(*DocumentNode)
  2073  		return Merge(node.Body, src)
  2074  	case MappingType:
  2075  		node := dst.(*MappingNode)
  2076  		target, ok := src.(*MappingNode)
  2077  		if !ok {
  2078  			return err
  2079  		}
  2080  		node.Merge(target)
  2081  		return nil
  2082  	case SequenceType:
  2083  		node := dst.(*SequenceNode)
  2084  		target, ok := src.(*SequenceNode)
  2085  		if !ok {
  2086  			return err
  2087  		}
  2088  		node.Merge(target)
  2089  		return nil
  2090  	}
  2091  	return err
  2092  }