package text
import (
)
type Kind uint8
const (
Invalid Kind = iota
EOF
Name
Scalar
MessageOpen
MessageClose
ListOpen
ListClose
comma
semicolon
bof = Invalid
)
func ( Kind) () string {
switch {
case Invalid:
return "<invalid>"
case EOF:
return "eof"
case Scalar:
return "scalar"
case Name:
return "name"
case MessageOpen:
return "{"
case MessageClose:
return "}"
case ListOpen:
return "["
case ListClose:
return "]"
case comma:
return ","
case semicolon:
return ";"
default:
return fmt.Sprintf("<invalid:%v>", uint8())
}
}
type NameKind uint8
const (
IdentName NameKind = iota + 1
TypeName
FieldNumber
)
func ( NameKind) () string {
switch {
case IdentName:
return "IdentName"
case TypeName:
return "TypeName"
case FieldNumber:
return "FieldNumber"
default:
return fmt.Sprintf("<invalid:%v>", uint8())
}
}
const hasSeparator = 1 << 7
const (
numberValue = iota + 1
stringValue
literalValue
)
const isNegative = 1 << 7
type Token struct {
kind Kind
attrs uint8
numAttrs uint8
pos int
raw []byte
str string
}
func ( Token) () Kind {
return .kind
}
func ( Token) () string {
return string(.raw)
}
func ( Token) () int {
return .pos
}
func ( Token) () NameKind {
if .kind == Name {
return NameKind(.attrs &^ hasSeparator)
}
panic(fmt.Sprintf("Token is not a Name type: %s", .kind))
}
func ( Token) () bool {
if .kind == Name {
return .attrs&hasSeparator != 0
}
panic(fmt.Sprintf("Token is not a Name type: %s", .kind))
}
func ( Token) () string {
if .kind == Name && .attrs&uint8(IdentName) != 0 {
return string(.raw)
}
panic(fmt.Sprintf("Token is not an IdentName: %s:%s", .kind, NameKind(.attrs&^hasSeparator)))
}
func ( Token) () string {
if .kind == Name && .attrs&uint8(TypeName) != 0 {
return .str
}
panic(fmt.Sprintf("Token is not a TypeName: %s:%s", .kind, NameKind(.attrs&^hasSeparator)))
}
func ( Token) () int32 {
if .kind != Name || .attrs&uint8(FieldNumber) == 0 {
panic(fmt.Sprintf("Token is not a FieldNumber: %s:%s", .kind, NameKind(.attrs&^hasSeparator)))
}
, := strconv.ParseInt(string(.raw), 10, 32)
return int32()
}
func ( Token) () (string, bool) {
if .kind != Scalar || .attrs != stringValue {
return "", false
}
return .str, true
}
func ( Token) () (string, bool) {
if .kind != Scalar || .attrs != literalValue || (len(.raw) > 0 && .raw[0] == '-') {
return "", false
}
return string(.raw), true
}
func ( Token) () (bool, bool) {
if .kind != Scalar {
return false, false
}
switch .attrs {
case literalValue:
if , := boolLits[string(.raw)]; {
return , true
}
case numberValue:
, := strconv.ParseUint(.str, 0, 64)
if == nil {
switch {
case 0:
return false, true
case 1:
return true, true
}
}
}
return false, false
}
var boolLits = map[string]bool{
"t": true,
"true": true,
"True": true,
"f": false,
"false": false,
"False": false,
}
func ( Token) () (uint64, bool) {
if .kind != Scalar || .attrs != numberValue ||
.numAttrs&isNegative > 0 || .numAttrs&numFloat > 0 {
return 0, false
}
, := strconv.ParseUint(.str, 0, 64)
if != nil {
return 0, false
}
return , true
}
func ( Token) () (uint32, bool) {
if .kind != Scalar || .attrs != numberValue ||
.numAttrs&isNegative > 0 || .numAttrs&numFloat > 0 {
return 0, false
}
, := strconv.ParseUint(.str, 0, 32)
if != nil {
return 0, false
}
return uint32(), true
}
func ( Token) () (int64, bool) {
if .kind != Scalar || .attrs != numberValue || .numAttrs&numFloat > 0 {
return 0, false
}
if , := strconv.ParseInt(.str, 0, 64); == nil {
return , true
}
if flags.ProtoLegacy && (.numAttrs == numHex) {
if , := strconv.ParseUint(.str, 0, 64); == nil {
return int64(), true
}
}
return 0, false
}
func ( Token) () (int32, bool) {
if .kind != Scalar || .attrs != numberValue || .numAttrs&numFloat > 0 {
return 0, false
}
if , := strconv.ParseInt(.str, 0, 32); == nil {
return int32(), true
}
if flags.ProtoLegacy && (.numAttrs == numHex) {
if , := strconv.ParseUint(.str, 0, 32); == nil {
return int32(), true
}
}
return 0, false
}
func ( Token) () (float64, bool) {
if .kind != Scalar {
return 0, false
}
switch .attrs {
case literalValue:
if , := floatLits[strings.ToLower(string(.raw))]; {
return , true
}
case numberValue:
, := strconv.ParseFloat(.str, 64)
if == nil {
return , true
}
:= .(*strconv.NumError)
if .Err == strconv.ErrRange {
return , true
}
}
return 0, false
}
func ( Token) () (float32, bool) {
if .kind != Scalar {
return 0, false
}
switch .attrs {
case literalValue:
if , := floatLits[strings.ToLower(string(.raw))]; {
return float32(), true
}
case numberValue:
, := strconv.ParseFloat(.str, 64)
if == nil {
return float32(), true
}
:= .(*strconv.NumError)
if .Err == strconv.ErrRange {
return float32(), true
}
}
return 0, false
}
var floatLits = map[string]float64{
"nan": math.NaN(),
"inf": math.Inf(1),
"infinity": math.Inf(1),
"-inf": math.Inf(-1),
"-infinity": math.Inf(-1),
}
func (, Token) bool {
return .kind == .kind &&
.attrs == .attrs &&
.numAttrs == .numAttrs &&
.pos == .pos &&
bytes.Equal(.raw, .raw) &&
.str == .str
}