func (e *FieldError) Flatten() map[string]*FieldError {
	errs := map[string]*FieldError{}
	if e.IsPlaceholderErr {
		if e.IsSliceOrArray {
			for key, err := range e.SliceOrArrayErrs {
				fe, ok := err.(*FieldError)
				if ok {
					if flat := fe.Flatten(); flat != nil && len(flat) > 0 {
						for k, v := range flat {
							if fe.IsPlaceholderErr {
								errs[fmt.Sprintf("[%#v]%s", key, k)] = v
							} else {
								errs[fmt.Sprintf("[%#v]", key)] = v
							}
						}
					}
				} else {
					se := err.(*StructErrors)
					if flat := se.Flatten(); flat != nil && len(flat) > 0 {
						for k, v := range flat {
							errs[fmt.Sprintf("[%#v].%s.%s", key, se.Struct, k)] = v
						}
					}
				}
			}
		}
		if e.IsMap {
			for key, err := range e.MapErrs {
				fe, ok := err.(*FieldError)
				if ok {
					if flat := fe.Flatten(); flat != nil && len(flat) > 0 {
						for k, v := range flat {
							if fe.IsPlaceholderErr {
								errs[fmt.Sprintf("[%#v]%s", key, k)] = v
							} else {
								errs[fmt.Sprintf("[%#v]", key)] = v
							}
						}
					}
				} else {
					se := err.(*StructErrors)
					if flat := se.Flatten(); flat != nil && len(flat) > 0 {
						for k, v := range flat {
							errs[fmt.Sprintf("[%#v].%s.%s", key, se.Struct, k)] = v
						}
					}
				}
			}
		}
		return errs
	}
	errs[e.Field] = e
	return errs
}
Flatten flattens the FieldError hierarchical structure into a flat namespace style field name
for those that want/need it.
This is now needed because of the new dive functionality
package validator
import (
	"bytes"
	"errors"
	"fmt"
	"reflect"
	"strings"
	"sync"
	"time"
	"unicode"
)
const (
	utf8HexComma        = "0x2C"
	tagSeparator        = ","
	orSeparator         = "|"
	noValidationTag     = "-"
	tagKeySeparator     = "="
	structOnlyTag       = "structonly"
	omitempty           = "omitempty"
	required            = "required"
	fieldErrMsg         = "Field validation for \"%s\" failed on the \"%s\" tag"
	sliceErrMsg         = "Field validation for \"%s\" failed at index \"%d\" with error(s): %s"
	mapErrMsg           = "Field validation for \"%s\" failed on key \"%v\" with error(s): %s"
	structErrMsg        = "Struct:%s\n"
	diveTag             = "dive"
	existsTag           = "exists"
	arrayIndexFieldName = "%s[%d]"
	mapIndexFieldName   = "%s[%v]"
)
var structPool *sync.Pool
func newStructErrors() interface{} {
	return &StructErrors{
		Errors:       map[string]*FieldError{},
		StructErrors: map[string]*StructErrors{},
	}
}
type cachedTags struct {
	keyVals [][]string
	isOrVal bool
}
type cachedField struct {
	index          int
	name           string
	tags           []*cachedTags
	tag            string
	kind           reflect.Kind
	typ            reflect.Type
	isTime         bool
	isSliceOrArray bool
	isMap          bool
	isTimeSubtype  bool
	sliceSubtype   reflect.Type
	mapSubtype     reflect.Type
	sliceSubKind   reflect.Kind
	mapSubKind     reflect.Kind
	dive           bool
	diveTag        string
}
type cachedStruct struct {
	children int
	name     string
	kind     reflect.Kind
	fields   []*cachedField
}
type structsCacheMap struct {
	lock sync.RWMutex
	m    map[reflect.Type]*cachedStruct
}
func (s *structsCacheMap) Get(key reflect.Type) (*cachedStruct, bool) {
	s.lock.RLock()
	defer s.lock.RUnlock()
	value, ok := s.m[key]
	return value, ok
}
func (s *structsCacheMap) Set(key reflect.Type, value *cachedStruct) {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.m[key] = value
}
var structCache = &structsCacheMap{m: map[reflect.Type]*cachedStruct{}}
type fieldsCacheMap struct {
	lock sync.RWMutex
	m    map[string][]*cachedTags
}
func (s *fieldsCacheMap) Get(key string) ([]*cachedTags, bool) {
	s.lock.RLock()
	defer s.lock.RUnlock()
	value, ok := s.m[key]
	return value, ok
}
func (s *fieldsCacheMap) Set(key string, value []*cachedTags) {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.m[key] = value
}
var fieldsCache = &fieldsCacheMap{m: map[string][]*cachedTags{}}
type FieldError struct {
	Field            string
	Tag              string
	Kind             reflect.Kind
	Type             reflect.Type
	Param            string
	Value            interface{}
	IsPlaceholderErr bool
	IsSliceOrArray   bool
	IsMap            bool
	SliceOrArrayErrs map[int]error          
	MapErrs          map[interface{}]error  
}
func (e *FieldError) Error() string {
	if e.IsPlaceholderErr {
		buff := bytes.NewBufferString("")
		if e.IsSliceOrArray {
			for j, err := range e.SliceOrArrayErrs {
				buff.WriteString("\n")
				buff.WriteString(fmt.Sprintf(sliceErrMsg, e.Field, j, "\n"+err.Error()))
			}
		} else if e.IsMap {
			for key, err := range e.MapErrs {
				buff.WriteString(fmt.Sprintf(mapErrMsg, e.Field, key, "\n"+err.Error()))
			}
		}
		return strings.TrimSpace(buff.String())
	}
	return fmt.Sprintf(fieldErrMsg, e.Field, e.Tag)
}