vendor/google.golang.org/protobuf/internal/encoding/text/decode.go
changeset 260 445e01aede7e
parent 256 6d9efbef00a9
equal deleted inserted replaced
259:db4911b0c721 260:445e01aede7e
     6 
     6 
     7 import (
     7 import (
     8 	"bytes"
     8 	"bytes"
     9 	"fmt"
     9 	"fmt"
    10 	"io"
    10 	"io"
    11 	"regexp"
       
    12 	"strconv"
    11 	"strconv"
    13 	"unicode/utf8"
    12 	"unicode/utf8"
    14 
    13 
    15 	"google.golang.org/protobuf/internal/errors"
    14 	"google.golang.org/protobuf/internal/errors"
    16 )
    15 )
   379 	case '<':
   378 	case '<':
   380 		return MessageOpen, '>'
   379 		return MessageOpen, '>'
   381 	case '[':
   380 	case '[':
   382 		return ListOpen, ']'
   381 		return ListOpen, ']'
   383 	}
   382 	}
   384 	panic(fmt.Sprintf("Decoder: openStack contains invalid byte %s", string(openCh)))
   383 	panic(fmt.Sprintf("Decoder: openStack contains invalid byte %c", openCh))
   385 }
   384 }
   386 
   385 
   387 func (d *Decoder) pushOpenStack(ch byte) {
   386 func (d *Decoder) pushOpenStack(ch byte) {
   388 	d.openStack = append(d.openStack, ch)
   387 	d.openStack = append(d.openStack, ch)
   389 }
   388 }
   419 			}
   418 			}
   420 		}
   419 		}
   421 		return Token{}, d.newSyntaxError("invalid field number: %s", d.in[:num.size])
   420 		return Token{}, d.newSyntaxError("invalid field number: %s", d.in[:num.size])
   422 	}
   421 	}
   423 
   422 
   424 	return Token{}, d.newSyntaxError("invalid field name: %s", errRegexp.Find(d.in))
   423 	return Token{}, d.newSyntaxError("invalid field name: %s", errId(d.in))
   425 }
   424 }
   426 
   425 
   427 // parseTypeName parses Any type URL or extension field name. The name is
   426 // parseTypeName parses Any type URL or extension field name. The name is
   428 // enclosed in [ and ] characters. The C++ parser does not handle many legal URL
   427 // enclosed in [ and ] characters. The C++ parser does not handle many legal URL
   429 // strings. This implementation is more liberal and allows for the pattern
   428 // strings. This implementation is more liberal and allows for the pattern
   569 
   568 
   570 	if tok, ok := d.parseNumberValue(); ok {
   569 	if tok, ok := d.parseNumberValue(); ok {
   571 		return tok, nil
   570 		return tok, nil
   572 	}
   571 	}
   573 
   572 
   574 	return Token{}, d.newSyntaxError("invalid scalar value: %s", errRegexp.Find(d.in))
   573 	return Token{}, d.newSyntaxError("invalid scalar value: %s", errId(d.in))
   575 }
   574 }
   576 
   575 
   577 // parseLiteralValue parses a literal value. A literal value is used for
   576 // parseLiteralValue parses a literal value. A literal value is used for
   578 // bools, special floats and enums. This function simply identifies that the
   577 // bools, special floats and enums. This function simply identifies that the
   579 // field value is a literal.
   578 // field value is a literal.
   651 		}
   650 		}
   652 	}
   651 	}
   653 	return b
   652 	return b
   654 }
   653 }
   655 
   654 
   656 // Any sequence that looks like a non-delimiter (for error reporting).
   655 // errId extracts a byte sequence that looks like an invalid ID
   657 var errRegexp = regexp.MustCompile(`^([-+._a-zA-Z0-9\/]+|.)`)
   656 // (for the purposes of error reporting).
       
   657 func errId(seq []byte) []byte {
       
   658 	const maxLen = 32
       
   659 	for i := 0; i < len(seq); {
       
   660 		if i > maxLen {
       
   661 			return append(seq[:i:i], "…"...)
       
   662 		}
       
   663 		r, size := utf8.DecodeRune(seq[i:])
       
   664 		if r > utf8.RuneSelf || (r != '/' && isDelim(byte(r))) {
       
   665 			if i == 0 {
       
   666 				// Either the first byte is invalid UTF-8 or a
       
   667 				// delimiter, or the first rune is non-ASCII.
       
   668 				// Return it as-is.
       
   669 				i = size
       
   670 			}
       
   671 			return seq[:i:i]
       
   672 		}
       
   673 		i += size
       
   674 	}
       
   675 	// No delimiter found.
       
   676 	return seq
       
   677 }
   658 
   678 
   659 // isDelim returns true if given byte is a delimiter character.
   679 // isDelim returns true if given byte is a delimiter character.
   660 func isDelim(c byte) bool {
   680 func isDelim(c byte) bool {
   661 	return !(c == '-' || c == '+' || c == '.' || c == '_' ||
   681 	return !(c == '-' || c == '+' || c == '.' || c == '_' ||
   662 		('a' <= c && c <= 'z') ||
   682 		('a' <= c && c <= 'z') ||