some deletions
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / github.com / !burnt!sushi / toml@v0.3.1 / parse.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/github.com/!burnt!sushi/toml@v0.3.1/parse.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/github.com/!burnt!sushi/toml@v0.3.1/parse.go
deleted file mode 100644 (file)
index 50869ef..0000000
+++ /dev/null
@@ -1,592 +0,0 @@
-package toml
-
-import (
-       "fmt"
-       "strconv"
-       "strings"
-       "time"
-       "unicode"
-       "unicode/utf8"
-)
-
-type parser struct {
-       mapping map[string]interface{}
-       types   map[string]tomlType
-       lx      *lexer
-
-       // A list of keys in the order that they appear in the TOML data.
-       ordered []Key
-
-       // the full key for the current hash in scope
-       context Key
-
-       // the base key name for everything except hashes
-       currentKey string
-
-       // rough approximation of line number
-       approxLine int
-
-       // A map of 'key.group.names' to whether they were created implicitly.
-       implicits map[string]bool
-}
-
-type parseError string
-
-func (pe parseError) Error() string {
-       return string(pe)
-}
-
-func parse(data string) (p *parser, err error) {
-       defer func() {
-               if r := recover(); r != nil {
-                       var ok bool
-                       if err, ok = r.(parseError); ok {
-                               return
-                       }
-                       panic(r)
-               }
-       }()
-
-       p = &parser{
-               mapping:   make(map[string]interface{}),
-               types:     make(map[string]tomlType),
-               lx:        lex(data),
-               ordered:   make([]Key, 0),
-               implicits: make(map[string]bool),
-       }
-       for {
-               item := p.next()
-               if item.typ == itemEOF {
-                       break
-               }
-               p.topLevel(item)
-       }
-
-       return p, nil
-}
-
-func (p *parser) panicf(format string, v ...interface{}) {
-       msg := fmt.Sprintf("Near line %d (last key parsed '%s'): %s",
-               p.approxLine, p.current(), fmt.Sprintf(format, v...))
-       panic(parseError(msg))
-}
-
-func (p *parser) next() item {
-       it := p.lx.nextItem()
-       if it.typ == itemError {
-               p.panicf("%s", it.val)
-       }
-       return it
-}
-
-func (p *parser) bug(format string, v ...interface{}) {
-       panic(fmt.Sprintf("BUG: "+format+"\n\n", v...))
-}
-
-func (p *parser) expect(typ itemType) item {
-       it := p.next()
-       p.assertEqual(typ, it.typ)
-       return it
-}
-
-func (p *parser) assertEqual(expected, got itemType) {
-       if expected != got {
-               p.bug("Expected '%s' but got '%s'.", expected, got)
-       }
-}
-
-func (p *parser) topLevel(item item) {
-       switch item.typ {
-       case itemCommentStart:
-               p.approxLine = item.line
-               p.expect(itemText)
-       case itemTableStart:
-               kg := p.next()
-               p.approxLine = kg.line
-
-               var key Key
-               for ; kg.typ != itemTableEnd && kg.typ != itemEOF; kg = p.next() {
-                       key = append(key, p.keyString(kg))
-               }
-               p.assertEqual(itemTableEnd, kg.typ)
-
-               p.establishContext(key, false)
-               p.setType("", tomlHash)
-               p.ordered = append(p.ordered, key)
-       case itemArrayTableStart:
-               kg := p.next()
-               p.approxLine = kg.line
-
-               var key Key
-               for ; kg.typ != itemArrayTableEnd && kg.typ != itemEOF; kg = p.next() {
-                       key = append(key, p.keyString(kg))
-               }
-               p.assertEqual(itemArrayTableEnd, kg.typ)
-
-               p.establishContext(key, true)
-               p.setType("", tomlArrayHash)
-               p.ordered = append(p.ordered, key)
-       case itemKeyStart:
-               kname := p.next()
-               p.approxLine = kname.line
-               p.currentKey = p.keyString(kname)
-
-               val, typ := p.value(p.next())
-               p.setValue(p.currentKey, val)
-               p.setType(p.currentKey, typ)
-               p.ordered = append(p.ordered, p.context.add(p.currentKey))
-               p.currentKey = ""
-       default:
-               p.bug("Unexpected type at top level: %s", item.typ)
-       }
-}
-
-// Gets a string for a key (or part of a key in a table name).
-func (p *parser) keyString(it item) string {
-       switch it.typ {
-       case itemText:
-               return it.val
-       case itemString, itemMultilineString,
-               itemRawString, itemRawMultilineString:
-               s, _ := p.value(it)
-               return s.(string)
-       default:
-               p.bug("Unexpected key type: %s", it.typ)
-               panic("unreachable")
-       }
-}
-
-// value translates an expected value from the lexer into a Go value wrapped
-// as an empty interface.
-func (p *parser) value(it item) (interface{}, tomlType) {
-       switch it.typ {
-       case itemString:
-               return p.replaceEscapes(it.val), p.typeOfPrimitive(it)
-       case itemMultilineString:
-               trimmed := stripFirstNewline(stripEscapedWhitespace(it.val))
-               return p.replaceEscapes(trimmed), p.typeOfPrimitive(it)
-       case itemRawString:
-               return it.val, p.typeOfPrimitive(it)
-       case itemRawMultilineString:
-               return stripFirstNewline(it.val), p.typeOfPrimitive(it)
-       case itemBool:
-               switch it.val {
-               case "true":
-                       return true, p.typeOfPrimitive(it)
-               case "false":
-                       return false, p.typeOfPrimitive(it)
-               }
-               p.bug("Expected boolean value, but got '%s'.", it.val)
-       case itemInteger:
-               if !numUnderscoresOK(it.val) {
-                       p.panicf("Invalid integer %q: underscores must be surrounded by digits",
-                               it.val)
-               }
-               val := strings.Replace(it.val, "_", "", -1)
-               num, err := strconv.ParseInt(val, 10, 64)
-               if err != nil {
-                       // Distinguish integer values. Normally, it'd be a bug if the lexer
-                       // provides an invalid integer, but it's possible that the number is
-                       // out of range of valid values (which the lexer cannot determine).
-                       // So mark the former as a bug but the latter as a legitimate user
-                       // error.
-                       if e, ok := err.(*strconv.NumError); ok &&
-                               e.Err == strconv.ErrRange {
-
-                               p.panicf("Integer '%s' is out of the range of 64-bit "+
-                                       "signed integers.", it.val)
-                       } else {
-                               p.bug("Expected integer value, but got '%s'.", it.val)
-                       }
-               }
-               return num, p.typeOfPrimitive(it)
-       case itemFloat:
-               parts := strings.FieldsFunc(it.val, func(r rune) bool {
-                       switch r {
-                       case '.', 'e', 'E':
-                               return true
-                       }
-                       return false
-               })
-               for _, part := range parts {
-                       if !numUnderscoresOK(part) {
-                               p.panicf("Invalid float %q: underscores must be "+
-                                       "surrounded by digits", it.val)
-                       }
-               }
-               if !numPeriodsOK(it.val) {
-                       // As a special case, numbers like '123.' or '1.e2',
-                       // which are valid as far as Go/strconv are concerned,
-                       // must be rejected because TOML says that a fractional
-                       // part consists of '.' followed by 1+ digits.
-                       p.panicf("Invalid float %q: '.' must be followed "+
-                               "by one or more digits", it.val)
-               }
-               val := strings.Replace(it.val, "_", "", -1)
-               num, err := strconv.ParseFloat(val, 64)
-               if err != nil {
-                       if e, ok := err.(*strconv.NumError); ok &&
-                               e.Err == strconv.ErrRange {
-
-                               p.panicf("Float '%s' is out of the range of 64-bit "+
-                                       "IEEE-754 floating-point numbers.", it.val)
-                       } else {
-                               p.panicf("Invalid float value: %q", it.val)
-                       }
-               }
-               return num, p.typeOfPrimitive(it)
-       case itemDatetime:
-               var t time.Time
-               var ok bool
-               var err error
-               for _, format := range []string{
-                       "2006-01-02T15:04:05Z07:00",
-                       "2006-01-02T15:04:05",
-                       "2006-01-02",
-               } {
-                       t, err = time.ParseInLocation(format, it.val, time.Local)
-                       if err == nil {
-                               ok = true
-                               break
-                       }
-               }
-               if !ok {
-                       p.panicf("Invalid TOML Datetime: %q.", it.val)
-               }
-               return t, p.typeOfPrimitive(it)
-       case itemArray:
-               array := make([]interface{}, 0)
-               types := make([]tomlType, 0)
-
-               for it = p.next(); it.typ != itemArrayEnd; it = p.next() {
-                       if it.typ == itemCommentStart {
-                               p.expect(itemText)
-                               continue
-                       }
-
-                       val, typ := p.value(it)
-                       array = append(array, val)
-                       types = append(types, typ)
-               }
-               return array, p.typeOfArray(types)
-       case itemInlineTableStart:
-               var (
-                       hash         = make(map[string]interface{})
-                       outerContext = p.context
-                       outerKey     = p.currentKey
-               )
-
-               p.context = append(p.context, p.currentKey)
-               p.currentKey = ""
-               for it := p.next(); it.typ != itemInlineTableEnd; it = p.next() {
-                       if it.typ != itemKeyStart {
-                               p.bug("Expected key start but instead found %q, around line %d",
-                                       it.val, p.approxLine)
-                       }
-                       if it.typ == itemCommentStart {
-                               p.expect(itemText)
-                               continue
-                       }
-
-                       // retrieve key
-                       k := p.next()
-                       p.approxLine = k.line
-                       kname := p.keyString(k)
-
-                       // retrieve value
-                       p.currentKey = kname
-                       val, typ := p.value(p.next())
-                       // make sure we keep metadata up to date
-                       p.setType(kname, typ)
-                       p.ordered = append(p.ordered, p.context.add(p.currentKey))
-                       hash[kname] = val
-               }
-               p.context = outerContext
-               p.currentKey = outerKey
-               return hash, tomlHash
-       }
-       p.bug("Unexpected value type: %s", it.typ)
-       panic("unreachable")
-}
-
-// numUnderscoresOK checks whether each underscore in s is surrounded by
-// characters that are not underscores.
-func numUnderscoresOK(s string) bool {
-       accept := false
-       for _, r := range s {
-               if r == '_' {
-                       if !accept {
-                               return false
-                       }
-                       accept = false
-                       continue
-               }
-               accept = true
-       }
-       return accept
-}
-
-// numPeriodsOK checks whether every period in s is followed by a digit.
-func numPeriodsOK(s string) bool {
-       period := false
-       for _, r := range s {
-               if period && !isDigit(r) {
-                       return false
-               }
-               period = r == '.'
-       }
-       return !period
-}
-
-// establishContext sets the current context of the parser,
-// where the context is either a hash or an array of hashes. Which one is
-// set depends on the value of the `array` parameter.
-//
-// Establishing the context also makes sure that the key isn't a duplicate, and
-// will create implicit hashes automatically.
-func (p *parser) establishContext(key Key, array bool) {
-       var ok bool
-
-       // Always start at the top level and drill down for our context.
-       hashContext := p.mapping
-       keyContext := make(Key, 0)
-
-       // We only need implicit hashes for key[0:-1]
-       for _, k := range key[0 : len(key)-1] {
-               _, ok = hashContext[k]
-               keyContext = append(keyContext, k)
-
-               // No key? Make an implicit hash and move on.
-               if !ok {
-                       p.addImplicit(keyContext)
-                       hashContext[k] = make(map[string]interface{})
-               }
-
-               // If the hash context is actually an array of tables, then set
-               // the hash context to the last element in that array.
-               //
-               // Otherwise, it better be a table, since this MUST be a key group (by
-               // virtue of it not being the last element in a key).
-               switch t := hashContext[k].(type) {
-               case []map[string]interface{}:
-                       hashContext = t[len(t)-1]
-               case map[string]interface{}:
-                       hashContext = t
-               default:
-                       p.panicf("Key '%s' was already created as a hash.", keyContext)
-               }
-       }
-
-       p.context = keyContext
-       if array {
-               // If this is the first element for this array, then allocate a new
-               // list of tables for it.
-               k := key[len(key)-1]
-               if _, ok := hashContext[k]; !ok {
-                       hashContext[k] = make([]map[string]interface{}, 0, 5)
-               }
-
-               // Add a new table. But make sure the key hasn't already been used
-               // for something else.
-               if hash, ok := hashContext[k].([]map[string]interface{}); ok {
-                       hashContext[k] = append(hash, make(map[string]interface{}))
-               } else {
-                       p.panicf("Key '%s' was already created and cannot be used as "+
-                               "an array.", keyContext)
-               }
-       } else {
-               p.setValue(key[len(key)-1], make(map[string]interface{}))
-       }
-       p.context = append(p.context, key[len(key)-1])
-}
-
-// setValue sets the given key to the given value in the current context.
-// It will make sure that the key hasn't already been defined, account for
-// implicit key groups.
-func (p *parser) setValue(key string, value interface{}) {
-       var tmpHash interface{}
-       var ok bool
-
-       hash := p.mapping
-       keyContext := make(Key, 0)
-       for _, k := range p.context {
-               keyContext = append(keyContext, k)
-               if tmpHash, ok = hash[k]; !ok {
-                       p.bug("Context for key '%s' has not been established.", keyContext)
-               }
-               switch t := tmpHash.(type) {
-               case []map[string]interface{}:
-                       // The context is a table of hashes. Pick the most recent table
-                       // defined as the current hash.
-                       hash = t[len(t)-1]
-               case map[string]interface{}:
-                       hash = t
-               default:
-                       p.bug("Expected hash to have type 'map[string]interface{}', but "+
-                               "it has '%T' instead.", tmpHash)
-               }
-       }
-       keyContext = append(keyContext, key)
-
-       if _, ok := hash[key]; ok {
-               // Typically, if the given key has already been set, then we have
-               // to raise an error since duplicate keys are disallowed. However,
-               // it's possible that a key was previously defined implicitly. In this
-               // case, it is allowed to be redefined concretely. (See the
-               // `tests/valid/implicit-and-explicit-after.toml` test in `toml-test`.)
-               //
-               // But we have to make sure to stop marking it as an implicit. (So that
-               // another redefinition provokes an error.)
-               //
-               // Note that since it has already been defined (as a hash), we don't
-               // want to overwrite it. So our business is done.
-               if p.isImplicit(keyContext) {
-                       p.removeImplicit(keyContext)
-                       return
-               }
-
-               // Otherwise, we have a concrete key trying to override a previous
-               // key, which is *always* wrong.
-               p.panicf("Key '%s' has already been defined.", keyContext)
-       }
-       hash[key] = value
-}
-
-// setType sets the type of a particular value at a given key.
-// It should be called immediately AFTER setValue.
-//
-// Note that if `key` is empty, then the type given will be applied to the
-// current context (which is either a table or an array of tables).
-func (p *parser) setType(key string, typ tomlType) {
-       keyContext := make(Key, 0, len(p.context)+1)
-       for _, k := range p.context {
-               keyContext = append(keyContext, k)
-       }
-       if len(key) > 0 { // allow type setting for hashes
-               keyContext = append(keyContext, key)
-       }
-       p.types[keyContext.String()] = typ
-}
-
-// addImplicit sets the given Key as having been created implicitly.
-func (p *parser) addImplicit(key Key) {
-       p.implicits[key.String()] = true
-}
-
-// removeImplicit stops tagging the given key as having been implicitly
-// created.
-func (p *parser) removeImplicit(key Key) {
-       p.implicits[key.String()] = false
-}
-
-// isImplicit returns true if the key group pointed to by the key was created
-// implicitly.
-func (p *parser) isImplicit(key Key) bool {
-       return p.implicits[key.String()]
-}
-
-// current returns the full key name of the current context.
-func (p *parser) current() string {
-       if len(p.currentKey) == 0 {
-               return p.context.String()
-       }
-       if len(p.context) == 0 {
-               return p.currentKey
-       }
-       return fmt.Sprintf("%s.%s", p.context, p.currentKey)
-}
-
-func stripFirstNewline(s string) string {
-       if len(s) == 0 || s[0] != '\n' {
-               return s
-       }
-       return s[1:]
-}
-
-func stripEscapedWhitespace(s string) string {
-       esc := strings.Split(s, "\\\n")
-       if len(esc) > 1 {
-               for i := 1; i < len(esc); i++ {
-                       esc[i] = strings.TrimLeftFunc(esc[i], unicode.IsSpace)
-               }
-       }
-       return strings.Join(esc, "")
-}
-
-func (p *parser) replaceEscapes(str string) string {
-       var replaced []rune
-       s := []byte(str)
-       r := 0
-       for r < len(s) {
-               if s[r] != '\\' {
-                       c, size := utf8.DecodeRune(s[r:])
-                       r += size
-                       replaced = append(replaced, c)
-                       continue
-               }
-               r += 1
-               if r >= len(s) {
-                       p.bug("Escape sequence at end of string.")
-                       return ""
-               }
-               switch s[r] {
-               default:
-                       p.bug("Expected valid escape code after \\, but got %q.", s[r])
-                       return ""
-               case 'b':
-                       replaced = append(replaced, rune(0x0008))
-                       r += 1
-               case 't':
-                       replaced = append(replaced, rune(0x0009))
-                       r += 1
-               case 'n':
-                       replaced = append(replaced, rune(0x000A))
-                       r += 1
-               case 'f':
-                       replaced = append(replaced, rune(0x000C))
-                       r += 1
-               case 'r':
-                       replaced = append(replaced, rune(0x000D))
-                       r += 1
-               case '"':
-                       replaced = append(replaced, rune(0x0022))
-                       r += 1
-               case '\\':
-                       replaced = append(replaced, rune(0x005C))
-                       r += 1
-               case 'u':
-                       // At this point, we know we have a Unicode escape of the form
-                       // `uXXXX` at [r, r+5). (Because the lexer guarantees this
-                       // for us.)
-                       escaped := p.asciiEscapeToUnicode(s[r+1 : r+5])
-                       replaced = append(replaced, escaped)
-                       r += 5
-               case 'U':
-                       // At this point, we know we have a Unicode escape of the form
-                       // `uXXXX` at [r, r+9). (Because the lexer guarantees this
-                       // for us.)
-                       escaped := p.asciiEscapeToUnicode(s[r+1 : r+9])
-                       replaced = append(replaced, escaped)
-                       r += 9
-               }
-       }
-       return string(replaced)
-}
-
-func (p *parser) asciiEscapeToUnicode(bs []byte) rune {
-       s := string(bs)
-       hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32)
-       if err != nil {
-               p.bug("Could not parse '%s' as a hexadecimal number, but the "+
-                       "lexer claims it's OK: %s", s, err)
-       }
-       if !utf8.ValidRune(rune(hex)) {
-               p.panicf("Escaped character '\\u%s' is not valid UTF-8.", s)
-       }
-       return rune(hex)
-}
-
-func isStringType(ty itemType) bool {
-       return ty == itemString || ty == itemMultilineString ||
-               ty == itemRawString || ty == itemRawMultilineString
-}