go-yaml/token/token.go

1009 lines
24 KiB
Go
Raw Normal View History

2019-10-16 18:19:15 +09:00
package token
2019-10-19 18:28:36 +09:00
import (
"fmt"
"strings"
)
2019-10-16 18:19:15 +09:00
2019-10-21 02:26:45 +09:00
// Character type for character
2019-10-16 18:19:15 +09:00
type Character byte
const (
2019-10-21 02:26:45 +09:00
// SequenceEntryCharacter character for sequence entry
2019-10-16 18:19:15 +09:00
SequenceEntryCharacter Character = '-'
2019-10-21 02:26:45 +09:00
// MappingKeyCharacter character for mapping key
MappingKeyCharacter = '?'
// MappingValueCharacter character for mapping value
MappingValueCharacter = ':'
// CollectEntryCharacter character for collect entry
CollectEntryCharacter = ','
// SequenceStartCharacter character for sequence start
SequenceStartCharacter = '['
// SequenceEndCharacter character for sequence end
SequenceEndCharacter = ']'
// MappingStartCharacter character for mapping start
MappingStartCharacter = '{'
// MappingEndCharacter character for mapping end
MappingEndCharacter = '}'
// CommentCharacter character for comment
CommentCharacter = '#'
// AnchorCharacter character for anchor
AnchorCharacter = '&'
// AliasCharacter character for alias
AliasCharacter = '*'
// TagCharacter character for tag
TagCharacter = '!'
// LiteralCharacter character for literal
LiteralCharacter = '|'
// FoldedCharacter character for folded
FoldedCharacter = '>'
// SingleQuoteCharacter character for single quote
SingleQuoteCharacter = '\''
// DoubleQuoteCharacter character for double quote
DoubleQuoteCharacter = '"'
// DirectiveCharacter character for directive
DirectiveCharacter = '%'
// SpaceCharacter character for space
SpaceCharacter = ' '
// LineBreakCharacter character for line break
LineBreakCharacter = '\n'
2019-10-16 18:19:15 +09:00
)
2019-10-21 12:53:30 +09:00
// Type type identifier for token
2019-10-16 18:19:15 +09:00
type Type int
const (
2019-10-21 02:26:45 +09:00
// UnknownType reserve for invalid type
2019-10-16 18:19:15 +09:00
UnknownType Type = iota
2019-10-21 02:26:45 +09:00
// DocumentHeaderType type for DocumentHeader token
2019-10-16 18:19:15 +09:00
DocumentHeaderType
2019-10-21 02:26:45 +09:00
// DocumentEndType type for DocumentEnd token
2019-10-16 18:19:15 +09:00
DocumentEndType
2019-10-21 02:26:45 +09:00
// SequenceEntryType type for SequenceEntry token
2019-10-16 18:19:15 +09:00
SequenceEntryType
2019-10-21 02:26:45 +09:00
// MappingKeyType type for MappingKey token
2019-10-16 18:19:15 +09:00
MappingKeyType
2019-10-21 02:26:45 +09:00
// MappingValueType type for MappingValue token
2019-10-16 18:19:15 +09:00
MappingValueType
2019-10-21 02:26:45 +09:00
// MergeKeyType type for MergeKey token
2019-10-16 18:19:15 +09:00
MergeKeyType
2019-10-21 02:26:45 +09:00
// CollectEntryType type for CollectEntry token
2019-10-16 18:19:15 +09:00
CollectEntryType
2019-10-21 02:26:45 +09:00
// SequenceStartType type for SequenceStart token
2019-10-16 18:19:15 +09:00
SequenceStartType
2019-10-21 02:26:45 +09:00
// SequenceEndType type for SequenceEnd token
2019-10-16 18:19:15 +09:00
SequenceEndType
2019-10-21 02:26:45 +09:00
// MappingStartType type for MappingStart token
2019-10-16 18:19:15 +09:00
MappingStartType
2019-10-21 02:26:45 +09:00
// MappingEndType type for MappingEnd token
2019-10-16 18:19:15 +09:00
MappingEndType
2019-10-21 02:26:45 +09:00
// CommentType type for Comment token
2019-10-16 18:19:15 +09:00
CommentType
2019-10-21 02:26:45 +09:00
// AnchorType type for Anchor token
2019-10-16 18:19:15 +09:00
AnchorType
2019-10-21 02:26:45 +09:00
// AliasType type for Alias token
2019-10-16 18:19:15 +09:00
AliasType
2019-10-21 02:26:45 +09:00
// TagType type for Tag token
2019-10-16 18:19:15 +09:00
TagType
2019-10-21 02:26:45 +09:00
// LiteralType type for Literal token
2019-10-16 18:19:15 +09:00
LiteralType
2019-10-21 02:26:45 +09:00
// FoldedType type for Folded token
2019-10-16 18:19:15 +09:00
FoldedType
2019-10-21 02:26:45 +09:00
// SingleQuoteType type for SingleQuote token
2019-10-16 18:19:15 +09:00
SingleQuoteType
2019-10-21 02:26:45 +09:00
// DoubleQuoteType type for DoubleQuote token
2019-10-16 18:19:15 +09:00
DoubleQuoteType
2019-10-21 02:26:45 +09:00
// DirectiveType type for Directive token
2019-10-16 18:19:15 +09:00
DirectiveType
2019-10-21 02:26:45 +09:00
// SpaceType type for Space token
2019-10-16 18:19:15 +09:00
SpaceType
2019-10-21 02:26:45 +09:00
// NullType type for Null token
2019-10-16 18:19:15 +09:00
NullType
2019-10-21 02:26:45 +09:00
// InfinityType type for Infinity token
2019-10-16 18:19:15 +09:00
InfinityType
2019-10-21 02:26:45 +09:00
// NanType type for Nan token
2019-10-16 18:19:15 +09:00
NanType
2019-10-21 02:26:45 +09:00
// IntegerType type for Integer token
2019-10-16 18:19:15 +09:00
IntegerType
// BinaryIntegerType type for BinaryInteger token
BinaryIntegerType
// OctetIntegerType type for OctetInteger token
OctetIntegerType
// HexIntegerType type for HexInteger token
HexIntegerType
2019-10-21 02:26:45 +09:00
// FloatType type for Float token
2019-10-16 18:19:15 +09:00
FloatType
2019-10-21 02:26:45 +09:00
// StringType type for String token
2019-10-16 18:19:15 +09:00
StringType
2019-10-21 02:26:45 +09:00
// BoolType type for Bool token
2019-10-16 18:19:15 +09:00
BoolType
)
2019-10-21 02:26:45 +09:00
// String type identifier to text
2019-10-16 18:19:15 +09:00
func (t Type) String() string {
switch t {
case UnknownType:
return "Unknown"
case DocumentHeaderType:
return "DocumentHeader"
case DocumentEndType:
return "DocumentEnd"
case SequenceEntryType:
return "SequenceEntry"
case MappingKeyType:
return "MappingKey"
case MappingValueType:
return "MappingValue"
case MergeKeyType:
return "MergeKey"
case CollectEntryType:
return "CollectEntry"
case SequenceStartType:
return "SequenceStart"
case SequenceEndType:
return "SequenceEnd"
case MappingStartType:
return "MappingStart"
case MappingEndType:
return "MappingEnd"
case CommentType:
return "Comment"
case AnchorType:
return "Anchor"
case AliasType:
return "Alias"
case TagType:
return "Tag"
case LiteralType:
return "Literal"
case FoldedType:
return "Folded"
case SingleQuoteType:
return "SingleQuote"
case DoubleQuoteType:
return "DoubleQuote"
case DirectiveType:
return "Directive"
case SpaceType:
return "Space"
case StringType:
return "String"
case BoolType:
return "Bool"
case IntegerType:
return "Integer"
case BinaryIntegerType:
return "BinaryInteger"
case OctetIntegerType:
return "OctetInteger"
case HexIntegerType:
return "HexInteger"
2019-10-16 18:19:15 +09:00
case FloatType:
return "Float"
case NullType:
return "Null"
case InfinityType:
return "Infinity"
case NanType:
return "Nan"
}
return ""
}
2019-10-21 02:26:45 +09:00
// CharacterType type for character category
2019-10-16 18:19:15 +09:00
type CharacterType int
const (
2019-10-21 02:26:45 +09:00
// CharacterTypeIndicator type of indicator character
2019-10-16 18:19:15 +09:00
CharacterTypeIndicator CharacterType = iota
2019-10-21 02:26:45 +09:00
// CharacterTypeWhiteSpace type of white space character
2019-10-16 18:19:15 +09:00
CharacterTypeWhiteSpace
2019-10-21 02:26:45 +09:00
// CharacterTypeMiscellaneous type of miscellaneous character
2019-10-16 18:19:15 +09:00
CharacterTypeMiscellaneous
2019-10-21 02:26:45 +09:00
// CharacterTypeEscaped type of escaped character
2019-10-16 18:19:15 +09:00
CharacterTypeEscaped
)
2019-10-21 02:26:45 +09:00
// String character type identifier to text
2019-10-16 18:19:15 +09:00
func (c CharacterType) String() string {
switch c {
case CharacterTypeIndicator:
return "Indicator"
case CharacterTypeWhiteSpace:
return "WhiteSpcae"
case CharacterTypeMiscellaneous:
return "Miscellaneous"
case CharacterTypeEscaped:
return "Escaped"
}
return ""
}
2019-10-21 02:26:45 +09:00
// Indicator type for indicator
2019-10-16 18:19:15 +09:00
type Indicator int
const (
2019-10-21 02:26:45 +09:00
// NotIndicator not indicator
NotIndicator Indicator = iota
// BlockStructureIndicator indicator for block structure ( '-', '?', ':' )
BlockStructureIndicator
// FlowCollectionIndicator indicator for flow collection ( '[', ']', '{', '}', ',' )
FlowCollectionIndicator
// CommentIndicator indicator for comment ( '#' )
CommentIndicator
// NodePropertyIndicator indicator for node property ( '!', '&', '*' )
NodePropertyIndicator
// BlockScalarIndicator indicator for block scalar ( '|', '>' )
BlockScalarIndicator
// QuotedScalarIndicator indicator for quoted scalar ( ''', '"' )
QuotedScalarIndicator
// DirectiveIndicator indicator for directive ( '%' )
DirectiveIndicator
// InvalidUseOfReservedIndicator indicator for invalid use of reserved keyword ( '@', '`' )
InvalidUseOfReservedIndicator
2019-10-16 18:19:15 +09:00
)
2019-10-21 02:26:45 +09:00
// String indicator to text
2019-10-16 18:19:15 +09:00
func (i Indicator) String() string {
switch i {
case NotIndicator:
return "NotIndicator"
case BlockStructureIndicator:
return "BlockStructure"
case FlowCollectionIndicator:
return "FlowCollection"
case CommentIndicator:
return "Comment"
case NodePropertyIndicator:
return "NodeProperty"
case BlockScalarIndicator:
return "BlockScalar"
case QuotedScalarIndicator:
return "QuotedScalar"
case DirectiveIndicator:
return "Directive"
case InvalidUseOfReservedIndicator:
return "InvalidUseOfReserved"
}
return ""
}
var (
2019-10-31 17:23:56 +09:00
reservedNullKeywords = []string{
"null",
"Null",
"NULL",
"~",
}
reservedBoolKeywords = []string{
"true",
"True",
"TRUE",
"false",
"False",
"FALSE",
}
reservedInfKeywords = []string{
".inf",
".Inf",
".INF",
"-.inf",
"-.Inf",
"-.INF",
2019-10-16 18:19:15 +09:00
}
2019-10-31 17:23:56 +09:00
reservedNanKeywords = []string{
".nan",
".NaN",
".NAN",
}
reservedKeywordMap = map[string]func(string, string, *Position) *Token{}
2019-10-16 18:19:15 +09:00
)
2019-10-31 17:23:56 +09:00
func reservedKeywordToken(typ Type, value, org string, pos *Position) *Token {
return &Token{
Type: typ,
CharacterType: CharacterTypeMiscellaneous,
Indicator: NotIndicator,
Value: value,
Origin: org,
Position: pos,
}
}
func init() {
for _, keyword := range reservedNullKeywords {
reservedKeywordMap[keyword] = func(value, org string, pos *Position) *Token {
return reservedKeywordToken(NullType, value, org, pos)
}
}
for _, keyword := range reservedBoolKeywords {
reservedKeywordMap[keyword] = func(value, org string, pos *Position) *Token {
return reservedKeywordToken(BoolType, value, org, pos)
}
}
for _, keyword := range reservedInfKeywords {
reservedKeywordMap[keyword] = func(value, org string, pos *Position) *Token {
return reservedKeywordToken(InfinityType, value, org, pos)
}
}
for _, keyword := range reservedNanKeywords {
reservedKeywordMap[keyword] = func(value, org string, pos *Position) *Token {
return reservedKeywordToken(NanType, value, org, pos)
}
}
}
2019-10-21 02:26:45 +09:00
// ReservedTagKeyword type of reserved tag keyword
2019-10-16 18:19:15 +09:00
type ReservedTagKeyword string
const (
2019-10-21 02:26:45 +09:00
// IntegerTag `!!int` tag
IntegerTag ReservedTagKeyword = "!!int"
// FloatTag `!!float` tag
FloatTag = "!!float"
// NullTag `!!null` tag
NullTag = "!!null"
// SequenceTag `!!seq` tag
SequenceTag = "!!seq"
// MappingTag `!!map` tag
MappingTag = "!!map"
// StringTag `!!str` tag
StringTag = "!!str"
// BinaryTag `!!binary` tag
BinaryTag = "!!binary"
// OrderedMapTag `!!omap` tag
OrderedMapTag = "!!omap"
// SetTag `!!set` tag
SetTag = "!!set"
2019-11-01 14:22:06 +09:00
// TimestampTag `!!timestamp` tag
TimestampTag = "!!timestamp"
2019-10-16 18:19:15 +09:00
)
var (
2019-10-21 12:53:30 +09:00
// ReservedTagKeywordMap map for reserved tag keywords
2019-10-16 18:19:15 +09:00
ReservedTagKeywordMap = map[ReservedTagKeyword]func(string, string, *Position) *Token{
IntegerTag: func(value, org string, pos *Position) *Token {
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
}
},
FloatTag: func(value, org string, pos *Position) *Token {
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
}
},
NullTag: func(value, org string, pos *Position) *Token {
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
}
},
SequenceTag: func(value, org string, pos *Position) *Token {
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
}
},
MappingTag: func(value, org string, pos *Position) *Token {
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
}
},
StringTag: func(value, org string, pos *Position) *Token {
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
}
},
BinaryTag: func(value, org string, pos *Position) *Token {
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
}
},
OrderedMapTag: func(value, org string, pos *Position) *Token {
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
}
},
SetTag: func(value, org string, pos *Position) *Token {
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
}
},
2019-11-01 14:22:06 +09:00
TimestampTag: func(value, org string, pos *Position) *Token {
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
}
},
2019-10-16 18:19:15 +09:00
}
)
type numType int
const (
numTypeNone numType = iota
numTypeBinary
numTypeOctet
numTypeHex
numTypeFloat
)
type numStat struct {
isNum bool
typ numType
}
func getNumberStat(str string) *numStat {
stat := &numStat{}
if str == "" {
return stat
}
if str == "-" || str == "." || str == "+" || str == "_" {
return stat
}
if str[0] == '_' {
return stat
}
dotFound := false
isNegative := false
isExponent := false
if str[0] == '-' {
isNegative = true
2019-10-16 18:19:15 +09:00
}
for idx, c := range str {
switch c {
case 'x':
if (isNegative && idx == 2) || (!isNegative && idx == 1) {
continue
}
case 'o':
if (isNegative && idx == 2) || (!isNegative && idx == 1) {
continue
}
2019-10-16 18:19:15 +09:00
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
continue
case 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F':
if (len(str) > 2 && str[0] == '0' && str[1] == 'x') ||
(len(str) > 3 && isNegative && str[1] == '0' && str[2] == 'x') {
// hex number
continue
}
if c == 'b' && ((isNegative && idx == 2) || (!isNegative && idx == 1)) {
// binary number
continue
}
if (c == 'e' || c == 'E') && dotFound {
// exponent
isExponent = true
continue
}
2019-10-16 18:19:15 +09:00
case '.':
if dotFound {
// multiple dot
return stat
2019-10-16 18:19:15 +09:00
}
dotFound = true
2019-10-16 18:19:15 +09:00
continue
case '-':
if idx == 0 || isExponent {
2019-10-16 18:19:15 +09:00
continue
}
case '+':
if idx == 0 || isExponent {
continue
}
case '_':
continue
2019-10-16 18:19:15 +09:00
}
return stat
2019-10-16 18:19:15 +09:00
}
stat.isNum = true
switch {
case dotFound:
stat.typ = numTypeFloat
case strings.HasPrefix(str, "0b") || strings.HasPrefix(str, "-0b"):
stat.typ = numTypeBinary
case strings.HasPrefix(str, "0x") || strings.HasPrefix(str, "-0x"):
stat.typ = numTypeHex
case strings.HasPrefix(str, "0o") || strings.HasPrefix(str, "-0o"):
stat.typ = numTypeOctet
2019-10-29 19:46:55 +09:00
case (len(str) > 1 && str[0] == '0') || (len(str) > 1 && str[0] == '-' && str[1] == '0'):
stat.typ = numTypeOctet
2019-10-16 18:19:15 +09:00
}
return stat
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
// IsNeedQuoted whether need quote for passed string or not
2019-10-19 18:28:36 +09:00
func IsNeedQuoted(value string) bool {
2019-10-29 19:46:55 +09:00
if value == "" {
return true
}
2019-10-31 17:23:56 +09:00
if _, exists := reservedKeywordMap[value]; exists {
2019-10-19 18:28:36 +09:00
return true
}
if stat := getNumberStat(value); stat.isNum {
2019-10-19 18:28:36 +09:00
return true
}
if strings.IndexByte(value, ':') == 1 {
return true
}
if strings.IndexByte(value, '#') > 0 {
return true
}
for _, c := range value {
if c == '\\' {
return true
}
}
return false
}
// LiteralBlockHeader detect literal block scalar header
func LiteralBlockHeader(value string) string {
lbc := DetectLineBreakCharacter(value)
switch {
case !strings.Contains(value, lbc):
return ""
case strings.HasSuffix(value, fmt.Sprintf("%s%s", lbc, lbc)):
return "|+"
case strings.HasSuffix(value, lbc):
return "|"
default:
return "|-"
}
}
2019-10-21 02:26:45 +09:00
// New create reserved keyword token or number token and other string token
2019-10-16 18:19:15 +09:00
func New(value string, org string, pos *Position) *Token {
2019-10-31 17:23:56 +09:00
fn := reservedKeywordMap[value]
2019-10-16 18:19:15 +09:00
if fn != nil {
return fn(value, org, pos)
}
if stat := getNumberStat(value); stat.isNum {
2019-10-16 18:19:15 +09:00
tk := &Token{
Type: IntegerType,
CharacterType: CharacterTypeMiscellaneous,
Indicator: NotIndicator,
Value: value,
Origin: org,
Position: pos,
}
switch stat.typ {
case numTypeFloat:
2019-10-16 18:19:15 +09:00
tk.Type = FloatType
case numTypeBinary:
tk.Type = BinaryIntegerType
case numTypeOctet:
tk.Type = OctetIntegerType
case numTypeHex:
tk.Type = HexIntegerType
2019-10-16 18:19:15 +09:00
}
return tk
}
return String(value, org, pos)
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
// Position type for position in YAML document
2019-10-16 18:19:15 +09:00
type Position struct {
Line int
Column int
Offset int
IndentNum int
IndentLevel int
}
2019-10-21 02:26:45 +09:00
// String position to text
2019-10-16 18:19:15 +09:00
func (p *Position) String() string {
return fmt.Sprintf("[level:%d,line:%d,column:%d,offset:%d]", p.IndentLevel, p.Line, p.Column, p.Offset)
}
2019-10-21 02:26:45 +09:00
// Token type for token
2019-10-16 18:19:15 +09:00
type Token struct {
Type Type
CharacterType CharacterType
Indicator Indicator
Value string
Origin string
Position *Position
Next *Token
Prev *Token
}
2019-10-21 02:26:45 +09:00
// PreviousType previous token type
func (t *Token) PreviousType() Type {
if t.Prev != nil {
return t.Prev.Type
}
return UnknownType
}
2019-10-21 02:26:45 +09:00
// NextType next token type
2019-10-16 18:19:15 +09:00
func (t *Token) NextType() Type {
if t.Next != nil {
return t.Next.Type
}
return UnknownType
}
// AddColumn append column number to current position of column
func (t *Token) AddColumn(col int) {
if t == nil {
return
}
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
}
2019-10-21 02:26:45 +09:00
// Tokens type of token collection
2019-10-16 18:19:15 +09:00
type Tokens []*Token
func (t *Tokens) add(tk *Token) {
tokens := *t
if len(tokens) == 0 {
tokens = append(tokens, tk)
} else {
last := tokens[len(tokens)-1]
last.Next = tk
tk.Prev = last
tokens = append(tokens, tk)
}
*t = tokens
}
2019-10-21 02:26:45 +09:00
// Add append new some tokens
2019-10-16 18:19:15 +09:00
func (t *Tokens) Add(tks ...*Token) {
for _, tk := range tks {
t.add(tk)
}
}
2019-10-21 02:26:45 +09:00
// Dump dump all token structures for debugging
2019-10-16 18:19:15 +09:00
func (t Tokens) Dump() {
for _, tk := range t {
fmt.Printf("- %+v\n", tk)
}
}
// String create token for String
func String(value string, org string, pos *Position) *Token {
return &Token{
Type: StringType,
CharacterType: CharacterTypeMiscellaneous,
Indicator: NotIndicator,
Value: value,
Origin: org,
Position: pos,
}
}
2019-10-21 02:26:45 +09:00
// SequenceEntry create token for SequenceEntry
func SequenceEntry(org string, pos *Position) *Token {
return &Token{
Type: SequenceEntryType,
CharacterType: CharacterTypeIndicator,
Indicator: BlockStructureIndicator,
Value: string(SequenceEntryCharacter),
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// MappingKey create token for MappingKey
func MappingKey(pos *Position) *Token {
return &Token{
Type: MappingKeyType,
CharacterType: CharacterTypeIndicator,
Indicator: BlockStructureIndicator,
Value: string(MappingKeyCharacter),
Origin: string(MappingKeyCharacter),
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// MappingValue create token for MappingValue
func MappingValue(pos *Position) *Token {
return &Token{
Type: MappingValueType,
CharacterType: CharacterTypeIndicator,
Indicator: BlockStructureIndicator,
Value: string(MappingValueCharacter),
Origin: string(MappingValueCharacter),
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// CollectEntry create token for CollectEntry
func CollectEntry(org string, pos *Position) *Token {
return &Token{
Type: CollectEntryType,
CharacterType: CharacterTypeIndicator,
Indicator: FlowCollectionIndicator,
Value: string(CollectEntryCharacter),
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// SequenceStart create token for SequenceStart
func SequenceStart(org string, pos *Position) *Token {
return &Token{
Type: SequenceStartType,
CharacterType: CharacterTypeIndicator,
Indicator: FlowCollectionIndicator,
Value: string(SequenceStartCharacter),
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// SequenceEnd create token for SequenceEnd
func SequenceEnd(org string, pos *Position) *Token {
return &Token{
Type: SequenceEndType,
CharacterType: CharacterTypeIndicator,
Indicator: FlowCollectionIndicator,
Value: string(SequenceEndCharacter),
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// MappingStart create token for MappingStart
func MappingStart(org string, pos *Position) *Token {
return &Token{
Type: MappingStartType,
CharacterType: CharacterTypeIndicator,
Indicator: FlowCollectionIndicator,
Value: string(MappingStartCharacter),
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// MappingEnd create token for MappingEnd
func MappingEnd(org string, pos *Position) *Token {
return &Token{
Type: MappingEndType,
CharacterType: CharacterTypeIndicator,
Indicator: FlowCollectionIndicator,
Value: string(MappingEndCharacter),
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// Comment create token for Comment
func Comment(value string, org string, pos *Position) *Token {
return &Token{
Type: CommentType,
CharacterType: CharacterTypeIndicator,
Indicator: CommentIndicator,
Value: value,
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// Anchor create token for Anchor
func Anchor(org string, pos *Position) *Token {
return &Token{
Type: AnchorType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: string(AnchorCharacter),
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// Alias create token for Alias
func Alias(org string, pos *Position) *Token {
return &Token{
Type: AliasType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: string(AliasCharacter),
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// Tag create token for Tag
func Tag(value string, org string, pos *Position) *Token {
fn := ReservedTagKeywordMap[ReservedTagKeyword(value)]
if fn != nil {
return fn(value, org, pos)
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// Literal create token for Literal
func Literal(value string, org string, pos *Position) *Token {
return &Token{
Type: LiteralType,
CharacterType: CharacterTypeIndicator,
Indicator: BlockScalarIndicator,
Value: value,
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// Folded create token for Folded
func Folded(value string, org string, pos *Position) *Token {
return &Token{
Type: FoldedType,
CharacterType: CharacterTypeIndicator,
Indicator: BlockScalarIndicator,
Value: value,
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// SingleQuote create token for SingleQuote
func SingleQuote(value string, org string, pos *Position) *Token {
return &Token{
Type: SingleQuoteType,
CharacterType: CharacterTypeIndicator,
Indicator: QuotedScalarIndicator,
Value: value,
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// DoubleQuote create token for DoubleQuote
func DoubleQuote(value string, org string, pos *Position) *Token {
return &Token{
Type: DoubleQuoteType,
CharacterType: CharacterTypeIndicator,
Indicator: QuotedScalarIndicator,
Value: value,
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// Directive create token for Directive
func Directive(pos *Position) *Token {
return &Token{
Type: DirectiveType,
CharacterType: CharacterTypeIndicator,
Indicator: DirectiveIndicator,
Value: string(DirectiveCharacter),
Origin: string(DirectiveCharacter),
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// Space create token for Space
func Space(pos *Position) *Token {
return &Token{
Type: SpaceType,
CharacterType: CharacterTypeWhiteSpace,
Indicator: NotIndicator,
Value: string(SpaceCharacter),
Origin: string(SpaceCharacter),
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// MergeKey create token for MergeKey
func MergeKey(org string, pos *Position) *Token {
return &Token{
Type: MergeKeyType,
CharacterType: CharacterTypeMiscellaneous,
Indicator: NotIndicator,
Value: "<<",
Origin: org,
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// DocumentHeader create token for DocumentHeader
func DocumentHeader(pos *Position) *Token {
return &Token{
Type: DocumentHeaderType,
CharacterType: CharacterTypeMiscellaneous,
Indicator: NotIndicator,
Value: "---",
Origin: "---",
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
// DocumentEnd create token for DocumentEnd
func DocumentEnd(pos *Position) *Token {
return &Token{
Type: DocumentEndType,
CharacterType: CharacterTypeMiscellaneous,
Indicator: NotIndicator,
Value: "...",
Origin: "...",
Position: pos,
2019-10-16 18:19:15 +09:00
}
2019-10-21 02:26:45 +09:00
}
2020-02-17 22:12:08 +09:00
// DetectLineBreakCharacter detect line break character in only one inside scalar content scope.
func DetectLineBreakCharacter(src string) string {
nc := strings.Count(src, "\n")
rc := strings.Count(src, "\r")
rnc := strings.Count(src, "\r\n")
switch {
2020-02-17 22:00:01 +09:00
case nc == rnc && rc == rnc:
return "\r\n"
case rc > nc:
return "\r"
default:
return "\n"
}
}