Repository: goccy/go-yaml (go)

Issue:
validation crash on missing nested required field
Hey @goccy, 

I've run the following test:
```go
package main 

import (
	"strings"

	"github.com/goccy/go-yaml"
	"gopkg.in/go-playground/validator.v9"
)

type Person struct {
	Name string `yaml:"name" validate:"required"`
	Age  int    `yaml:"age" validate:"gte=0,lt=120"`
	Addr *PersonAddress `yaml:"addr" validate:"required,dive,required"`
}
type PersonAddress struct {
	Number string `yaml:"number" validate:"required"`
	State string `yaml:"state" validate:"required"`
}


func main() {
	yml := `
name: itai
age: 10
addr:
  number: seven
` // missing State
	validate := validator.New()
	dec := yaml.NewDecoder(
		strings.NewReader(yml),
		yaml.Validator(validate),
	)
	var v Person
	err := dec.Decode(&v)
	if err == nil {
		panic("expected error")
	}
}
```

got the following crash log:
```bash
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x10effb2]

goroutine 1 [running]:
github.com/goccy/go-yaml.(*Decoder).decodeStruct(0xc0001fe000, 0x11b2480, 0xc0000a9fc0, 0x199, 0x1210c20, 0xc000105a80, 0x28, 0x11aa560)
        /Users/itai/work/go-yaml/decode.go:855 +0x1b12
github.com/goccy/go-yaml.(*Decoder).decodeValue(0xc0001fe000, 0x11b2480, 0xc0000a9fc0, 0x199, 0x1210c20, 0xc000105a80, 0x0, 0x2a)
        /Users/itai/work/go-yaml/decode.go:473 +0x1b0a
github.com/goccy/go-yaml.(*Decoder).decode(0xc0001fe000, 0x1189e00, 0xc0000a9fc0, 0x16, 0x1189e00, 0x1337a20)
        /Users/itai/work/go-yaml/decode.go:1243 +0xd2
github.com/goccy/go-yaml.(*Decoder).Decode(0xc0001fe000, 0x1189e00, 0xc0000a9fc0, 0x1006cbf, 0xc00008e058)
        /Users/itai/work/go-yaml/decode.go:1272 +0x272
main.main()
        /Users/itati/work/go-yaml/cmd/validate/cmd.go:34 +0x1f6
exit status 2

shell returned 1
```

It seems that `structFieldMap` doesn't contain "State" `fieldName`, so we crash on null pointer deref (structField.RenderName)
```go
					structField := structFieldMap[fieldName]
					node, exists := keyToNodeMap[structField.RenderName]
```

Pull request description:
Fix nested struct validation
fixes #146 


Patch:
diff --git a/README.md b/README.md
index 2ea8afe..6a45ed5 100644
--- a/README.md
+++ b/README.md
@@ -299,67 +299,6 @@ fmt.Println(authors)
 // [john ken]
 ```
 
-## 5.1 Print customized error with YAML source code
-
-```go
-package main
-
-import (
-  "fmt"
-
-  "github.com/goccy/go-yaml"
-  "github.com/goccy/go-yaml/parser"
-  "github.com/goccy/go-yaml/printer"
-)
-
-func yamlSourceByPath(originalSource string, pathStr string) (string, error) {
-  file, err := parser.ParseBytes([]byte(originalSource), 0)
-  if err != nil {
-    return "", err
-  }
-  path, err := yaml.PathString(pathStr)
-  if err != nil {
-    return "", err
-  }
-  node, err := path.FilterFile(file)
-  if err != nil {
-    return "", err
-  }
-  var p printer.Printer
-  return p.PrintErrorToken(node.GetToken(), true), nil
-}
-
-func main() {
-  yml := `
-a: 1
-b: "hello"
-`
-  var v struct {
-    A int
-    B string
-  }
-  if err := yaml.Unmarshal([]byte(yml), &v); err != nil {
-    panic(err)
-  }
-  if v.A != 2 {
-    // output error with YAML source
-    source, err := yamlSourceByPath(yml, "$.a")
-    if err != nil {
-      panic(err)
-    }
-    fmt.Printf("a value expected 2 but actual %d:\n%s\n", v.A, source)
-  }
-}
-```
-
-`printer.PrintErrorToken` can output YAML source with error point,
-and you can get `token.Token` of error point by `yaml.Path` .
-
-output result is following 
-
-<img src="https://user-images.githubusercontent.com/209884/84148813-7aca8680-aa9a-11ea-8fc9-37dece2ebdac.png"></img>
-
-
 # Installation
 
 ```
diff --git a/ast/ast.go b/ast/ast.go
index cc0ed08..b6827aa 100644
--- a/ast/ast.go
+++ b/ast/ast.go
@@ -519,7 +519,7 @@ func (n *StringNode) String() string {
 	case token.SingleQuoteType:
 		return fmt.Sprintf(`'%s'`, n.Value)
 	case token.DoubleQuoteType:
-		return strconv.Quote(n.Value)
+		return fmt.Sprintf(`"%s"`, n.Value)
 	}
 
 	lbc := token.DetectLineBreakCharacter(n.Value)
@@ -586,7 +586,7 @@ func (n *LiteralNode) GetValue() interface{} {
 // String literal to text
 func (n *LiteralNode) String() string {
 	origin := n.Value.GetToken().Origin
-	return fmt.Sprintf("%s\n%s", n.Start.Value, strings.TrimRight(strings.TrimRight(origin, " "), "\n"))
+	return fmt.Sprintf("|\n%s", strings.TrimRight(strings.TrimRight(origin, " "), "\n"))
 }
 
 // MergeKeyNode type of merge key node
@@ -1035,11 +1035,6 @@ func (n *SequenceNode) blockStyleString() string {
 		diffLength := len(splittedValues[0]) - len(trimmedFirstValue)
 		newValues := []string{trimmedFirstValue}
 		for i := 1; i < len(splittedValues); i++ {
-			if len(splittedValues[i]) <= diffLength {
-				// this line is \n or white space only
-				newValues = append(newValues, "")
-				continue
-			}
 			trimmed := splittedValues[i][diffLength:]
 			newValues = append(newValues, fmt.Sprintf("%s  %s", space, trimmed))
 		}
diff --git a/decode.go b/decode.go
index b5fbc8a..1008028 100644
--- a/decode.go
+++ b/decode.go
@@ -92,20 +92,14 @@ func (d *Decoder) castToFloat(v interface{}) interface{} {
 	return 0
 }
 
-func (d *Decoder) mergeValueNode(value ast.Node) ast.Node {
-	if value.Type() == ast.AliasType {
-		aliasNode := value.(*ast.AliasNode)
-		aliasName := aliasNode.Value.GetToken().Value
-		return d.anchorNodeMap[aliasName]
-	}
-	return value
-}
-
 func (d *Decoder) setToMapValue(node ast.Node, m map[string]interface{}) {
 	switch n := node.(type) {
 	case *ast.MappingValueNode:
-		if n.Key.Type() == ast.MergeKeyType {
-			d.setToMapValue(d.mergeValueNode(n.Value), m)
+		if n.Key.Type() == ast.MergeKeyType && n.Value.Type() == ast.AliasType {
+			aliasNode := n.Value.(*ast.AliasNode)
+			aliasName := aliasNode.Value.GetToken().Value
+			node := d.anchorNodeMap[aliasName]
+			d.setToMapValue(node, m)
 		} else {
 			key := n.Key.GetToken().Value
 			m[key] = d.nodeToValue(n.Value)
@@ -120,8 +114,11 @@ func (d *Decoder) setToMapValue(node ast.Node, m map[string]interface{}) {
 func (d *Decoder) setToOrderedMapValue(node ast.Node, m *MapSlice) {
 	switch n := node.(type) {
 	case *ast.MappingValueNode:
-		if n.Key.Type() == ast.MergeKeyType {
-			d.setToOrderedMapValue(d.mergeValueNode(n.Value), m)
+		if n.Key.Type() == ast.MergeKeyType && n.Value.Type() == ast.AliasType {
+			aliasNode := n.Value.(*ast.AliasNode)
+			aliasName := aliasNode.Value.GetToken().Value
+			node := d.anchorNodeMap[aliasName]
+			d.setToOrderedMapValue(node, m)
 		} else {
 			key := n.Key.GetToken().Value
 			*m = append(*m, MapItem{Key: key, Value: d.nodeToValue(n.Value)})
@@ -174,15 +171,17 @@ func (d *Decoder) nodeToValue(node ast.Node) interface{} {
 	case *ast.LiteralNode:
 		return n.Value.GetValue()
 	case *ast.MappingValueNode:
-		if n.Key.Type() == ast.MergeKeyType {
-			value := d.mergeValueNode(n.Value)
+		if n.Key.Type() == ast.MergeKeyType && n.Value.Type() == ast.AliasType {
+			aliasNode := n.Value.(*ast.AliasNode)
+			aliasName := aliasNode.Value.GetToken().Value
+			node := d.anchorNodeMap[aliasName]
 			if d.useOrderedMap {
 				m := MapSlice{}
-				d.setToOrderedMapValue(value, &m)
+				d.setToOrderedMapValue(node, &m)
 				return m
 			}
 			m := map[string]interface{}{}
-			d.setToMapValue(value, m)
+			d.setToMapValue(node, m)
 			return m
 		}
 		key := n.Key.GetToken().Value
@@ -215,34 +214,6 @@ func (d *Decoder) nodeToValue(node ast.Node) interface{} {
 	return nil
 }
 
-func (d *Decoder) resolveAlias(node ast.Node) ast.Node {
-	switch n := node.(type) {
-	case *ast.MappingNode:
-		for idx, value := range n.Values {
-			n.Values[idx] = d.resolveAlias(value).(*ast.MappingValueNode)
-		}
-	case *ast.MappingValueNode:
-		if n.Key.Type() == ast.MergeKeyType && n.Value.Type() == ast.AliasType {
-			value := d.resolveAlias(n.Value)
-			keyColumn := n.Key.GetToken().Position.Column
-			requiredColumn := keyColumn + 2
-			value.AddColumn(requiredColumn)
-			n.Value = value
-		} else {
-			n.Key = d.resolveAlias(n.Key)
-			n.Value = d.resolveAlias(n.Value)
-		}
-	case *ast.SequenceNode:
-		for idx, value := range n.Values {
-			n.Values[idx] = d.resolveAlias(value)
-		}
-	case *ast.AliasNode:
-		aliasName := n.Value.GetToken().Value
-		return d.resolveAlias(d.anchorNodeMap[aliasName])
-	}
-	return node
-}
-
 func (d *Decoder) getMapNode(node ast.Node) (ast.MapNode, error) {
 	if _, ok := node.(*ast.NullNode); ok {
 		return nil, nil
@@ -405,8 +376,8 @@ func (d *Decoder) deleteStructKeys(structType reflect.Type, unknownFields map[st
 			continue
 		}
 
-		structField, ok := structFieldMap[field.Name]
-		if !ok {
+		structField, exists := structFieldMap[field.Name]
+		if !exists {
 			continue
 		}
 
@@ -419,51 +390,6 @@ func (d *Decoder) deleteStructKeys(structType reflect.Type, unknownFields map[st
 	return nil
 }
 
-func (d *Decoder) lastNode(node ast.Node) ast.Node {
-	switch n := node.(type) {
-	case *ast.MappingNode:
-		if len(n.Values) > 0 {
-			return d.lastNode(n.Values[len(n.Values)-1])
-		}
-	case *ast.MappingValueNode:
-		return d.lastNode(n.Value)
-	case *ast.SequenceNode:
-		if len(n.Values) > 0 {
-			return d.lastNode(n.Values[len(n.Values)-1])
-		}
-	}
-	return node
-}
-
-func (d *Decoder) unmarshalableDocument(node ast.Node) []byte {
-	node = d.resolveAlias(node)
-	doc := node.String()
-	last := d.lastNode(node)
-	if last != nil && last.Type() == ast.LiteralType {
-		doc += "\n"
-	}
-	return []byte(doc)
-}
-
-func (d *Decoder) unmarshalableText(node ast.Node) ([]byte, bool) {
-	node = d.resolveAlias(node)
-	if node.Type() == ast.AnchorType {
-		node = node.(*ast.AnchorNode).Value
-	}
-	switch n := node.(type) {
-	case *ast.StringNode:
-		return []byte(n.Value), true
-	case *ast.LiteralNode:
-		return []byte(n.Value.GetToken().Value), true
-	default:
-		scalar, ok := n.(ast.ScalarNode)
-		if ok {
-			return []byte(fmt.Sprint(scalar.GetValue())), true
-		}
-	}
-	return nil, false
-}
-
 func (d *Decoder) decodeValue(dst reflect.Value, src ast.Node) error {
 	if src.Type() == ast.AnchorType {
 		anchorName := src.(*ast.AnchorNode).Name.GetToken().Value
@@ -473,7 +399,13 @@ func (d *Decoder) decodeValue(dst reflect.Value, src ast.Node) error {
 	}
 	valueType := dst.Type()
 	if unmarshaler, ok := dst.Addr().Interface().(BytesUnmarshaler); ok {
-		if err := unmarshaler.UnmarshalYAML(d.unmarshalableDocument(src)); err != nil {
+		var b string
+		if scalar, isScalar := src.(ast.ScalarNode); isScalar {
+			b = fmt.Sprint(scalar.GetValue())
+		} else {
+			b = src.String()
+		}
+		if err := unmarshaler.UnmarshalYAML([]byte(b)); err != nil {
 			return errors.Wrapf(err, "failed to UnmarshalYAML")
 		}
 		return nil
@@ -494,13 +426,16 @@ func (d *Decoder) decodeValue(dst reflect.Value, src ast.Node) error {
 	} else if _, ok := dst.Addr().Interface().(*time.Time); ok {
 		return d.decodeTime(dst, src)
 	} else if unmarshaler, isText := dst.Addr().Interface().(encoding.TextUnmarshaler); isText {
-		b, ok := d.unmarshalableText(src)
-		if ok {
-			if err := unmarshaler.UnmarshalText(b); err != nil {
-				return errors.Wrapf(err, "failed to UnmarshalText")
-			}
-			return nil
+		var b string
+		if scalar, isScalar := src.(ast.ScalarNode); isScalar {
+			b = scalar.GetValue().(string)
+		} else {
+			b = src.String()
+		}
+		if err := unmarshaler.UnmarshalText([]byte(b)); err != nil {
+			return errors.Wrapf(err, "failed to UnmarshalText")
 		}
+		return nil
 	}
 	switch valueType.Kind() {
 	case reflect.Ptr:
@@ -916,7 +851,10 @@ func (d *Decoder) decodeStruct(dst reflect.Value, src ast.Node) error {
 						continue
 					}
 					fieldName := fieldErr.StructField()
-					structField := structFieldMap[fieldName]
+					structField, exists := structFieldMap[fieldName]
+					if !exists {
+						continue
+					}
 					node, exists := keyToNodeMap[structField.RenderName]
 					if exists {
 						// TODO: to make FieldError message cutomizable
diff --git a/printer/printer.go b/printer/printer.go
index bc3d723..b540524 100644
--- a/printer/printer.go
+++ b/printer/printer.go
@@ -255,7 +255,7 @@ func (p *Printer) printBeforeTokens(tk *token.Token, minLine, extLine int) token
 		}
 		tk = tk.Prev
 	}
-	minTk := tk.Clone()
+	minTk := tk
 	if minTk.Prev != nil {
 		// add white spaces to minTk by prev token
 		prev := minTk.Prev
@@ -266,9 +266,8 @@ func (p *Printer) printBeforeTokens(tk *token.Token, minLine, extLine int) token
 	tokens := token.Tokens{minTk}
 	tk = minTk.Next
 	for tk != nil && tk.Position.Line <= extLine {
-		clonedTk := tk.Clone()
-		tokens.Add(clonedTk)
-		tk = clonedTk.Next
+		tokens.Add(tk)
+		tk = tk.Next
 	}
 	lastTk := tokens[len(tokens)-1]
 	trimmedOrigin := p.removeRightSideWhiteSpaceChar(lastTk.Origin)
@@ -276,13 +275,11 @@ func (p *Printer) printBeforeTokens(tk *token.Token, minLine, extLine int) token
 	lastTk.Origin = trimmedOrigin
 
 	if lastTk.Next != nil && len(suffix) > 1 {
-		next := lastTk.Next.Clone()
 		// add suffix to header of next token
 		if suffix[0] == '\n' || suffix[0] == '\r' {
 			suffix = suffix[1:]
 		}
-		next.Origin = suffix + next.Origin
-		lastTk.Next = next
+		lastTk.Next.Origin = suffix + lastTk.Next.Origin
 	}
 	return tokens
 }
@@ -310,15 +307,14 @@ func (p *Printer) printAfterTokens(tk *token.Token, maxLine int) token.Tokens {
 	if tk.Position.Line > maxLine {
 		return tokens
 	}
-	minTk := tk.Clone()
+	minTk := tk
 	minTk.Origin = p.removeLeftSideNewLineChar(minTk.Origin)
 	tokens.Add(minTk)
 	tk = minTk.Next
 	for tk != nil && tk.Position.Line <= maxLine {
-		clonedTk := tk.Clone()
-		p.addNewLineCharIfDocumentHeader(clonedTk)
-		tokens.Add(clonedTk)
-		tk = clonedTk.Next
+		p.addNewLineCharIfDocumentHeader(tk)
+		tokens.Add(tk)
+		tk = tk.Next
 	}
 	return tokens
 }
diff --git a/scanner/context.go b/scanner/context.go
index e629a5c..32fceb9 100644
--- a/scanner/context.go
+++ b/scanner/context.go
@@ -88,14 +88,14 @@ func (c *Context) addBuf(r rune) {
 		return
 	}
 	c.buf = append(c.buf, r)
-	if r != ' ' && r != '\t' {
+	if r != ' ' {
 		c.notSpaceCharPos = len(c.buf)
 	}
 }
 
 func (c *Context) addOriginBuf(r rune) {
 	c.obuf = append(c.obuf, r)
-	if r != ' ' && r != '\t' {
+	if r != ' ' {
 		c.notSpaceOrgCharPos = len(c.obuf)
 	}
 }
diff --git a/scanner/scanner.go b/scanner/scanner.go
index 3a6fbe0..5b91b31 100644
--- a/scanner/scanner.go
+++ b/scanner/scanner.go
@@ -200,20 +200,12 @@ func (s *Scanner) scanSingleQuote(ctx *Context) (tk *token.Token, pos int) {
 	src := ctx.src
 	size := len(src)
 	value := []rune{}
-	isFirstLineChar := false
 	for idx := startIndex; idx < size; idx++ {
 		c := src[idx]
 		pos = idx + 1
 		ctx.addOriginBuf(c)
-		if s.isNewLineChar(c) {
-			value = append(value, ' ')
-			isFirstLineChar = true
-			continue
-		} else if c == ' ' && isFirstLineChar {
-			continue
-		} else if c != '\'' {
+		if c != '\'' {
 			value = append(value, c)
-			isFirstLineChar = false
 			continue
 		}
 		if idx+1 < len(ctx.src) && ctx.src[idx+1] == '\'' {
@@ -230,24 +222,6 @@ func (s *Scanner) scanSingleQuote(ctx *Context) (tk *token.Token, pos int) {
 	return
 }
 
-func hexToInt(b rune) int {
-	if b >= 'A' && b <= 'F' {
-		return int(b) - 'A' + 10
-	}
-	if b >= 'a' && b <= 'f' {
-		return int(b) - 'a' + 10
-	}
-	return int(b) - '0'
-}
-
-func hexRunesToInt(b []rune) int {
-	sum := 0
-	for i := 0; i < len(b); i++ {
-		sum += hexToInt(b[i]) << (uint(len(b)-i-1) * 4)
-	}
-	return sum
-}
-
 func (s *Scanner) scanDoubleQuote(ctx *Context) (tk *token.Token, pos int) {
 	ctx.addOriginBuf('"')
 	startIndex := ctx.idx + 1
@@ -255,102 +229,24 @@ func (s *Scanner) scanDoubleQuote(ctx *Context) (tk *token.Token, pos int) {
 	src := ctx.src
 	size := len(src)
 	value := []rune{}
-	isFirstLineChar := false
 	for idx := startIndex; idx < size; idx++ {
 		c := src[idx]
 		pos = idx + 1
 		ctx.addOriginBuf(c)
-		if s.isNewLineChar(c) {
-			value = append(value, ' ')
-			isFirstLineChar = true
-			continue
-		} else if c == ' ' && isFirstLineChar {
-			continue
-		} else if c == '\\' {
-			isFirstLineChar = false
+		if c == '\\' {
 			if idx+1 < size {
 				nextChar := src[idx+1]
 				switch nextChar {
-				case 'b':
-					ctx.addOriginBuf(nextChar)
-					value = append(value, '\b')
-					idx++
-					continue
-				case 'e':
-					ctx.addOriginBuf(nextChar)
-					value = append(value, '\x1B')
-					idx++
-					continue
-				case 'f':
-					ctx.addOriginBuf(nextChar)
-					value = append(value, '\f')
-					idx++
-					continue
 				case 'n':
 					ctx.addOriginBuf(nextChar)
 					value = append(value, '\n')
 					idx++
 					continue
-				case 'v':
-					ctx.addOriginBuf(nextChar)
-					value = append(value, '\v')
-					idx++
-					continue
-				case 'L': // LS (#x2028)
-					ctx.addOriginBuf(nextChar)
-					value = append(value, []rune{'\xE2', '\x80', '\xA8'}...)
-					idx++
-					continue
-				case 'N': // NEL (#x85)
-					ctx.addOriginBuf(nextChar)
-					value = append(value, []rune{'\xC2', '\x85'}...)
-					idx++
-					continue
-				case 'P': // PS (#x2029)
-					ctx.addOriginBuf(nextChar)
-					value = append(value, []rune{'\xE2', '\x80', '\xA9'}...)
-					idx++
-					continue
-				case '_': // #xA0
-					ctx.addOriginBuf(nextChar)
-					value = append(value, []rune{'\xC2', '\xA0'}...)
-					idx++
-					continue
 				case '"':
 					ctx.addOriginBuf(nextChar)
 					value = append(value, nextChar)
 					idx++
 					continue
-				case 'x':
-					if idx+3 >= size {
-						// TODO: need to return error
-						//err = xerrors.New("invalid escape character \\x")
-						return
-					}
-					codeNum := hexRunesToInt(src[idx+2 : idx+4])
-					value = append(value, rune(codeNum))
-					idx += 3
-					continue
-				case 'u':
-					if idx+5 >= size {
-						// TODO: need to return error
-						//err = xerrors.New("invalid escape character \\u")
-						return
-					}
-					codeNum := hexRunesToInt(src[idx+2 : idx+6])
-					value = append(value, rune(codeNum))
-					idx += 5
-					continue
-				case 'U':
-					if idx+9 >= size {
-						// TODO: need to return error
-						//err = xerrors.New("invalid escape character \\U")
-						return
-					}
-					codeNum := hexRunesToInt(src[idx+2 : idx+10])
-					value = append(value, rune(codeNum))
-					idx += 9
-					continue
 				case '\\':
 					ctx.addOriginBuf(nextChar)
 					idx++
@@ -360,7 +256,6 @@ func (s *Scanner) scanDoubleQuote(ctx *Context) (tk *token.Token, pos int) {
 			continue
 		} else if c != '"' {
 			value = append(value, c)
-			isFirstLineChar = false
 			continue
 		}
 		tk = token.DoubleQuote(string(value), string(ctx.obuf), s.pos())
@@ -417,7 +312,7 @@ func (s *Scanner) scanComment(ctx *Context) (tk *token.Token, pos int) {
 func (s *Scanner) scanLiteral(ctx *Context, c rune) {
 	ctx.addOriginBuf(c)
 	if ctx.isEOS() {
-		if ctx.isLiteral {
+		if c != '\r' && c != '\n' {
 			ctx.addBuf(c)
 		}
 		value := ctx.bufferedSrc()
@@ -448,7 +343,7 @@ func (s *Scanner) scanLiteral(ctx *Context, c rune) {
 func (s *Scanner) scanLiteralHeader(ctx *Context) (pos int, err error) {
 	header := ctx.currentChar()
 	ctx.addOriginBuf(header)
-	ctx.progress(1) // skip '|' or '>' character
+	ctx.progress(1) // skip '|' or '<' character
 	for idx, c := range ctx.src[ctx.idx:] {
 		pos = idx
 		ctx.addOriginBuf(c)
diff --git a/token/token.go b/token/token.go
index 860db4a..1016d8f 100644
--- a/token/token.go
+++ b/token/token.go
@@ -681,19 +681,6 @@ func (t *Token) AddColumn(col int) {
 	t.Position.Column += col
 }
 
-// Clone copy token ( preserve Prev/Next reference )
-func (t *Token) Clone() *Token {
-	if t == nil {
-		return nil
-	}
-	copied := *t
-	if t.Position != nil {
-		pos := *(t.Position)
-		copied.Position = &pos
-	}
-	return &copied
-}
-
 // Tokens type of token collection
 type Tokens []*Token
 
diff --git a/yaml.go b/yaml.go
index c582567..6177b88 100644
--- a/yaml.go
+++ b/yaml.go
@@ -91,7 +91,7 @@ type MapSlice []MapItem
 //         B int
 //     }
 //     yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
-//     yaml.Marshal(&T{F: 1}) // Returns "a: 1\nb: 0\n"
+//     yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
 //
 func Marshal(v interface{}) ([]byte, error) {
 	var buf bytes.Buffer


Test patch:
diff --git a/decode_test.go b/decode_test.go
index d9714ff..ef995bb 100644
--- a/decode_test.go
+++ b/decode_test.go
@@ -6,7 +6,6 @@ import (
 	"io"
 	"log"
 	"math"
-	"net"
 	"reflect"
 	"strconv"
 	"strings"
@@ -14,7 +13,6 @@ import (
 	"time"
 
 	"github.com/goccy/go-yaml"
-	"golang.org/x/xerrors"
 )
 
 type Child struct {
@@ -355,14 +353,6 @@ func TestDecoder(t *testing.T) {
 			`'1': '\\"2\\"'`,
 			map[interface{}]interface{}{"1": `\\"2\\"`},
 		},
-		{
-			"'1': '   1\n    2\n    3'",
-			map[interface{}]interface{}{"1": "   1 2 3"},
-		},
-		{
-			"'1': '\n    2\n    3'",
-			map[interface{}]interface{}{"1": " 2 3"},
-		},
 
 		// Double Quoted values.
 		{
@@ -393,26 +383,14 @@ func TestDecoder(t *testing.T) {
 			`"1": "\\\"2\\\""`,
 			map[interface{}]interface{}{"1": `\"2\"`},
 		},
-		{
-			"'1': \"   1\n    2\n    3\"",
-			map[interface{}]interface{}{"1": "   1 2 3"},
-		},
-		{
-			"'1': \"\n    2\n    3\"",
-			map[interface{}]interface{}{"1": " 2 3"},
-		},
-		{
-			`"1": "a\x2Fb"`,
-			map[interface{}]interface{}{"1": `a/b`},
-		},
-		{
-			`"1": "a\u002Fb"`,
-			map[interface{}]interface{}{"1": `a/b`},
-		},
-		{
-			`"1": "a\x2Fb\u002Fc\U0000002Fd"`,
-			map[interface{}]interface{}{"1": `a/b/c/d`},
-		},
+
+		/*
+			// TODO: Escape string
+			{
+				`"1": "a\x2Fb\u002Fc\U0000002Fd"`,
+				map[interface{}]interface{}{"1": `a/b/c/d`},
+			},
+		*/
 
 		{
 			"a: -b_c",
@@ -1655,152 +1633,52 @@ complecated: string
 	//            ^
 }
 
-type unmarshalableYAMLStringValue string
+type unmarshalableStringValue string
 
-func (v *unmarshalableYAMLStringValue) UnmarshalYAML(b []byte) error {
-	var s string
-	if err := yaml.Unmarshal(b, &s); err != nil {
-		return err
-	}
-	*v = unmarshalableYAMLStringValue(s)
-	return nil
-}
-
-type unmarshalableTextStringValue string
-
-func (v *unmarshalableTextStringValue) UnmarshalText(b []byte) error {
-	*v = unmarshalableTextStringValue(string(b))
+func (v *unmarshalableStringValue) UnmarshalYAML(raw []byte) error {
+	*v = unmarshalableStringValue(string(raw))
 	return nil
 }
 
 type unmarshalableStringContainer struct {
-	A unmarshalableYAMLStringValue `yaml:"a"`
-	B unmarshalableTextStringValue `yaml:"b"`
+	V unmarshalableStringValue `yaml:"value" json:"value"`
 }
 
 func TestUnmarshalableString(t *testing.T) {
 	t.Run("empty string", func(t *testing.T) {
 		t.Parallel()
-		yml := `
-a: ""
-b: ""
-`
 		var container unmarshalableStringContainer
-		if err := yaml.Unmarshal([]byte(yml), &container); err != nil {
+		if err := yaml.Unmarshal([]byte(`value: ""`), &container); err != nil {
 			t.Fatalf("failed to unmarshal %v", err)
 		}
-		if container.A != "" {
-			t.Fatalf("expected empty string, but %q is set", container.A)
-		}
-		if container.B != "" {
-			t.Fatalf("expected empty string, but %q is set", container.B)
+		if container.V != "" {
+			t.Fatalf("expected empty string, but %q is set", container.V)
 		}
 	})
 	t.Run("filled string", func(t *testing.T) {
 		t.Parallel()
-		yml := `
-a: "aaa"
-b: "bbb"
-`
 		var container unmarshalableStringContainer
-		if err := yaml.Unmarshal([]byte(yml), &container); err != nil {
+		if err := yaml.Unmarshal([]byte(`value: "aaa"`), &container); err != nil {
 			t.Fatalf("failed to unmarshal %v", err)
 		}
-		if container.A != "aaa" {
-			t.Fatalf("expected \"aaa\", but %q is set", container.A)
-		}
-		if container.B != "bbb" {
-			t.Fatalf("expected \"bbb\", but %q is set", container.B)
+		if container.V != "aaa" {
+			t.Fatalf("expected \"aaa\", but %q is set", container.V)
 		}
 	})
 	t.Run("single-quoted string", func(t *testing.T) {
 		t.Parallel()
-		yml := `
-a: 'aaa'
-b: 'bbb'
-`
 		var container unmarshalableStringContainer
-		if err := yaml.Unmarshal([]byte(yml), &container); err != nil {
+		if err := yaml.Unmarshal([]byte(`value: 'aaa'`), &container); err != nil {
 			t.Fatalf("failed to unmarshal %v", err)
 		}
-		if container.A != "aaa" {
-			t.Fatalf("expected \"aaa\", but %q is set", container.A)
-		}
-		if container.B != "bbb" {
-			t.Fatalf("expected \"aaa\", but %q is set", container.B)
-		}
-	})
-	t.Run("literal", func(t *testing.T) {
-		t.Parallel()
-		yml := `
-a: |
- a
- b
- c
-b: |
- a
- b
- c
-`
-		var container unmarshalableStringContainer
-		if err := yaml.Unmarshal([]byte(yml), &container); err != nil {
-			t.Fatalf("failed to unmarshal %v", err)
-		}
-		if container.A != "a\nb\nc\n" {
-			t.Fatalf("expected \"a\nb\nc\n\", but %q is set", container.A)
-		}
-		if container.B != "a\nb\nc\n" {
-			t.Fatalf("expected \"a\nb\nc\n\", but %q is set", container.B)
-		}
-	})
-	t.Run("anchor/alias", func(t *testing.T) {
-		yml := `
-a: &x 1
-b: *x
-c: &y hello
-d: *y
-`
-		var v struct {
-			A, B, C, D unmarshalableTextStringValue
-		}
-		if err := yaml.Unmarshal([]byte(yml), &v); err != nil {
-			t.Fatal(err)
-		}
-		if v.A != "1" {
-			t.Fatal("failed to unmarshal")
-		}
-		if v.B != "1" {
-			t.Fatal("failed to unmarshal")
-		}
-		if v.C != "hello" {
-			t.Fatal("failed to unmarshal")
-		}
-		if v.D != "hello" {
-			t.Fatal("failed to unmarshal")
-		}
-	})
-	t.Run("net.IP", func(t *testing.T) {
-		yml := `
-a: &a 127.0.0.1
-b: *a
-`
-		var v struct {
-			A, B net.IP
-		}
-		if err := yaml.Unmarshal([]byte(yml), &v); err != nil {
-			t.Fatal(err)
-		}
-		if v.A.String() != net.IPv4(127, 0, 0, 1).String() {
-			t.Fatal("failed to unmarshal")
-		}
-		if v.B.String() != net.IPv4(127, 0, 0, 1).String() {
-			t.Fatal("failed to unmarshal")
+		if container.V != "aaa" {
+			t.Fatalf("expected \"aaa\", but %q is set", container.V)
 		}
 	})
 }
 
 type unmarshalablePtrStringContainer struct {
-	V *string `yaml:"value"`
+	V *string `yaml:"value" json:"value"`
 }
 
 func TestUnmarshalablePtrString(t *testing.T) {
@@ -1810,7 +1688,7 @@ func TestUnmarshalablePtrString(t *testing.T) {
 		if err := yaml.Unmarshal([]byte(`value: ""`), &container); err != nil {
 			t.Fatalf("failed to unmarshal %v", err)
 		}
-		if container.V == nil || *container.V != "" {
+		if *container.V != "" {
 			t.Fatalf("expected empty string, but %q is set", *container.V)
 		}
 	})
@@ -1839,7 +1717,7 @@ func (v *unmarshalableIntValue) UnmarshalYAML(raw []byte) error {
 }
 
 type unmarshalableIntContainer struct {
-	V unmarshalableIntValue `yaml:"value"`
+	V unmarshalableIntValue `yaml:"value" json:"value"`
 }
 
 func TestUnmarshalableInt(t *testing.T) {
@@ -1876,7 +1754,7 @@ func TestUnmarshalableInt(t *testing.T) {
 }
 
 type unmarshalablePtrIntContainer struct {
-	V *int `yaml:"value"`
+	V *int `yaml:"value" json:"value"`
 }
 
 func TestUnmarshalablePtrInt(t *testing.T) {
@@ -1886,7 +1764,7 @@ func TestUnmarshalablePtrInt(t *testing.T) {
 		if err := yaml.Unmarshal([]byte(`value: 0`), &container); err != nil {
 			t.Fatalf("failed to unmarshal %v", err)
 		}
-		if container.V == nil || *container.V != 0 {
+		if *container.V != 0 {
 			t.Fatalf("expected 0, but %q is set", *container.V)
 		}
 	})
@@ -1997,180 +1875,3 @@ k: l
 		t.Fatal("failed to stream decoding")
 	}
 }
-
-type unmarshalYAMLWithAliasString string
-
-func (v *unmarshalYAMLWithAliasString) UnmarshalYAML(b []byte) error {
-	var s string
-	if err := yaml.Unmarshal(b, &s); err != nil {
-		return err
-	}
-	*v = unmarshalYAMLWithAliasString(s)
-	return nil
-}
-
-type unmarshalYAMLWithAliasMap map[string]interface{}
-
-func (v *unmarshalYAMLWithAliasMap) UnmarshalYAML(b []byte) error {
-	var m map[string]interface{}
-	if err := yaml.Unmarshal(b, &m); err != nil {
-		return err
-	}
-	*v = unmarshalYAMLWithAliasMap(m)
-	return nil
-}
-
-func TestDecoder_UnmarshalYAMLWithAlias(t *testing.T) {
-	yml := `
-anchors:
- x: &x "\"hello\" \"world\""
- map: &y
-   a: b
-   c: d
-   d: *x
-a: *x
-b:
- <<: *y
- e: f
-`
-	var v struct {
-		A unmarshalYAMLWithAliasString
-		B unmarshalYAMLWithAliasMap
-	}
-	if err := yaml.Unmarshal([]byte(yml), &v); err != nil {
-		t.Fatalf("%+v", err)
-	}
-	if v.A != `"hello" "world"` {
-		t.Fatal("failed to unmarshal with alias")
-	}
-	if len(v.B) != 4 {
-		t.Fatal("failed to unmarshal with alias")
-	}
-	if v.B["a"] != "b" {
-		t.Fatal("failed to unmarshal with alias")
-	}
-	if v.B["c"] != "d" {
-		t.Fatal("failed to unmarshal with alias")
-	}
-	if v.B["d"] != `"hello" "world"` {
-		t.Fatal("failed to unmarshal with alias")
-	}
-}
-
-type unmarshalString string
-
-func (u *unmarshalString) UnmarshalYAML(b []byte) error {
-	*u = unmarshalString(string(b))
-	return nil
-}
-
-type unmarshalList struct {
-	v []map[string]unmarshalString
-}
-
-func (u *unmarshalList) UnmarshalYAML(b []byte) error {
-	expected := `
- - b: c
-   d: |
-     hello
-
-     hello
-   f: g
- - h: i`
-	actual := "\n" + string(b)
-	if expected != actual {
-		return xerrors.Errorf("unexpected bytes: expected [%q] but got [%q]", expected, actual)
-	}
-	var v []map[string]unmarshalString
-	if err := yaml.Unmarshal(b, &v); err != nil {
-		return err
-	}
-	u.v = v
-	return nil
-}
-
-func TestDecoder_UnmarshalBytesWithSeparatedList(t *testing.T) {
-	yml := `
-a:
- - b: c
-   d: |
-     hello
-
-     hello
-   f: g
- - h: i
-`
-	var v struct {
-		A unmarshalList
-	}
-	if err := yaml.Unmarshal([]byte(yml), &v); err != nil {
-		t.Fatal(err)
-	}
-	if len(v.A.v) != 2 {
-		t.Fatalf("failed to unmarshal %+v", v)
-	}
-	if len(v.A.v[0]) != 3 {
-		t.Fatalf("failed to unmarshal %+v", v.A.v[0])
-	}
-	if len(v.A.v[1]) != 1 {
-		t.Fatalf("failed to unmarshal %+v", v.A.v[1])
-	}
-}
-
-func TestDecoder_LiteralWithNewLine(t *testing.T) {
-	type A struct {
-		Node     string `yaml:"b"`
-		LastNode string `yaml:"last"`
-	}
-	tests := []A{
-		A{
-			Node: "hello\nworld",
-		},
-		A{
-			Node: "hello\nworld\n",
-		},
-		A{
-			Node: "hello\nworld\n\n",
-		},
-		A{
-			LastNode: "hello\nworld",
-		},
-		A{
-			LastNode: "hello\nworld\n",
-		},
-		A{
-			LastNode: "hello\nworld\n\n",
-		},
-	}
-	// struct(want) -> Marshal -> Unmarchal -> struct(got)
-	for _, want := range tests {
-		bytes, _ := yaml.Marshal(want)
-		got := A{}
-		if err := yaml.Unmarshal(bytes, &got); err != nil {
-			t.Fatal(err)
-		}
-		if want.Node != got.Node {
-			t.Fatalf("expected:%q but got %q", want.Node, got.Node)
-		}
-		if want.LastNode != got.LastNode {
-			t.Fatalf("expected:%q but got %q", want.LastNode, got.LastNode)
-		}
-	}
-}
-
-func TestDecoder_TabCharacterAtRight(t *testing.T) {
-	yml := `
-- a: [2 , 2] 			
-  b: [2 , 2] 			
-  c: [2 , 2]`
-	var v []map[string][]int
-	if err := yaml.Unmarshal([]byte(yml), &v); err != nil {
-		t.Fatal(err)
-	}
-	if len(v) != 1 {
-		t.Fatalf("failed to unmarshal %+v", v)
-	}
-	if len(v[0]) != 3 {
-		t.Fatalf("failed to unmarshal %+v", v)
-	}
-}
diff --git a/parser/parser_test.go b/parser/parser_test.go
index c0451f1..c41766e 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -518,30 +518,6 @@ a:
   d: e
 - f: g
   h: i
-`,
-		},
-		{
-			`
-a: |-
-  value
-b: c
-`,
-			`
-a: |-
-  value
-b: c
-`,
-		},
-		{
-			`
-a:  |+
-  value
-b: c
-`,
-			`
-a: |+
-  value
-b: c
 `,
 		},
 	}
diff --git a/validate_test.go b/validate_test.go
index b21e4d3..9640235 100644
--- a/validate_test.go
+++ b/validate_test.go
@@ -1,45 +1,79 @@
 package yaml_test
 
 import (
-	"fmt"
 	"strings"
+	"testing"
 
 	"github.com/goccy/go-yaml"
 	"gopkg.in/go-playground/validator.v9"
 )
 
-type Person struct {
-	Name string `validate:"required"`
-	Age  int    `validate:"gte=0,lt=120"`
-}
+func TestStructValidator(t *testing.T) {
 
-func ExampleStructValidator() {
-	yml := `---
+	cases := []struct {
+		TestName    string
+		YAMLContent string
+		ExpectedErr string
+		Instance    interface{}
+	}{
+		{
+			TestName: "Test Simple Validation",
+			YAMLContent: `---
 - name: john
   age: 20
 - name: tom
   age: -1
 - name: ken
-  age: 10
-`
-	validate := validator.New()
-	dec := yaml.NewDecoder(
-		strings.NewReader(yml),
-		yaml.Validator(validate),
-	)
-	var v []*Person
-	err := dec.Decode(&v)
-	if err == nil {
-		panic("expected error")
+  age: 10`,
+			ExpectedErr: `[5:8] Key: 'Age' Error:Field validation for 'Age' failed on the 'gte' tag
+   2 | - name: john
+   3 |   age: 20
+   4 | - name: tom
+>  5 |   age: -1
+              ^
+   6 | - name: ken
+   7 |   age: 10`,
+			Instance: &[]struct {
+				Name string `yaml:"name" validate:"required"`
+				Age  int    `yaml:"age" validate:"gte=0,lt=120"`
+			}{},
+		},
+		{
+			TestName: "Test Nested Validation Missing Internal Required",
+			YAMLContent: `---
+name: john
+age: 10
+addr:
+  number: seven`,
+			ExpectedErr: "",
+			Instance: &struct {
+				Name string `yaml:"name" validate:"required"`
+				Age  int    `yaml:"age" validate:"gte=0,lt=120"`
+				Addr struct {
+					Number string `yaml:"number" validate:"required"`
+					State  string `yaml:"state" validate:"required"`
+				} `yaml:"addr"`
+			}{},
+		},
+	}
+
+	for _, tc := range cases {
+		tc := tc // NOTE: https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables
+		t.Run(tc.TestName, func(t *testing.T) {
+			validate := validator.New()
+			dec := yaml.NewDecoder(
+				strings.NewReader(tc.YAMLContent),
+				yaml.Validator(validate),
+			)
+			err := dec.Decode(tc.Instance)
+			switch {
+			case tc.ExpectedErr != "" && err == nil:
+				t.Fatal("expected error")
+			case tc.ExpectedErr == "" && err != nil:
+				t.Fatalf("unexpected error: %v", err)
+			case tc.ExpectedErr != "" && tc.ExpectedErr != err.Error():
+				t.Fatalf("expected `%s` but actual `%s`", tc.ExpectedErr, err.Error())
+			}
+		})
 	}
-	fmt.Printf("%v", err)
-	// OUTPUT:
-	// [5:8] Key: 'Person.Age' Error:Field validation for 'Age' failed on the 'gte' tag
-	//        2 | - name: john
-	//        3 |   age: 20
-	//        4 | - name: tom
-	//     >  5 |   age: -1
-	//                   ^
-	//        6 | - name: ken
-	//        7 |   age: 10
 }