package json
import (
)
func ( []byte, interface{}) error {
var decodeState
:= checkValid(, &.scan)
if != nil {
return
}
.init()
return .unmarshal()
}
type Unmarshaler interface {
UnmarshalJSON([]byte) error
}
type UnmarshalTypeError struct {
Value string
Type reflect.Type
Offset int64
Struct string
Field string
}
func ( *UnmarshalTypeError) () string {
if .Struct != "" || .Field != "" {
return "json: cannot unmarshal " + .Value + " into Go struct field " + .Struct + "." + .Field + " of type " + .Type.String()
}
return "json: cannot unmarshal " + .Value + " into Go value of type " + .Type.String()
}
type UnmarshalFieldError struct {
Key string
Type reflect.Type
Field reflect.StructField
}
func ( *UnmarshalFieldError) () string {
return "json: cannot unmarshal object key " + strconv.Quote(.Key) + " into unexported field " + .Field.Name + " of type " + .Type.String()
}
type InvalidUnmarshalError struct {
Type reflect.Type
}
func ( *InvalidUnmarshalError) () string {
if .Type == nil {
return "json: Unmarshal(nil)"
}
if .Type.Kind() != reflect.Ptr {
return "json: Unmarshal(non-pointer " + .Type.String() + ")"
}
return "json: Unmarshal(nil " + .Type.String() + ")"
}
func ( *decodeState) ( interface{}) error {
:= reflect.ValueOf()
if .Kind() != reflect.Ptr || .IsNil() {
return &InvalidUnmarshalError{reflect.TypeOf()}
}
.scan.reset()
.scanWhile(scanSkipSpace)
:= .value()
if != nil {
return .addErrorContext()
}
return .savedError
}
type Number string
func ( Number) () string { return string() }
func ( Number) () (float64, error) {
return strconv.ParseFloat(string(), 64)
}
func ( Number) () (int64, error) {
return strconv.ParseInt(string(), 10, 64)
}
type decodeState struct {
data []byte
off int
opcode int
scan scanner
errorContext struct {
Struct reflect.Type
FieldStack []string
}
savedError error
useNumber bool
disallowUnknownFields bool
}
func ( *decodeState) () int {
return .off - 1
}
const phasePanicMsg = "JSON decoder out of sync - data changing underfoot?"
func ( *decodeState) ( []byte) *decodeState {
.data =
.off = 0
.savedError = nil
.errorContext.Struct = nil
.errorContext.FieldStack = .errorContext.FieldStack[:0]
return
}
func ( *decodeState) ( error) {
if .savedError == nil {
.savedError = .addErrorContext()
}
}
func ( *decodeState) ( error) error {
if .errorContext.Struct != nil || len(.errorContext.FieldStack) > 0 {
switch err := .(type) {
case *UnmarshalTypeError:
.Struct = .errorContext.Struct.Name()
.Field = strings.Join(.errorContext.FieldStack, ".")
return
}
}
return
}
func ( *decodeState) () {
, , := &.scan, .data, .off
:= len(.parseState)
for {
:= .step(, [])
++
if len(.parseState) < {
.off =
.opcode =
return
}
}
}
func ( *decodeState) () {
if .off < len(.data) {
.opcode = .scan.step(&.scan, .data[.off])
.off++
} else {
.opcode = .scan.eof()
.off = len(.data) + 1
}
}
func ( *decodeState) ( int) {
, , := &.scan, .data, .off
for < len() {
:= .step(, [])
++
if != {
.opcode =
.off =
return
}
}
.off = len() + 1
.opcode = .scan.eof()
}
func ( *decodeState) () {
, := .data, .off
:
switch [-1] {
case '"':
for ; < len(); ++ {
switch [] {
case '\\':
++
case '"':
++
break
}
}
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-':
for ; < len(); ++ {
switch [] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'.', 'e', 'E', '+', '-':
default:
break
}
}
case 't':
+= len("rue")
case 'f':
+= len("alse")
case 'n':
+= len("ull")
}
if < len() {
.opcode = stateEndValue(&.scan, [])
} else {
.opcode = scanEnd
}
.off = + 1
}
func ( *decodeState) ( reflect.Value) error {
switch .opcode {
default:
panic(phasePanicMsg)
case scanBeginArray:
if .IsValid() {
if := .array(); != nil {
return
}
} else {
.skip()
}
.scanNext()
case scanBeginObject:
if .IsValid() {
if := .object(); != nil {
return
}
} else {
.skip()
}
.scanNext()
case scanBeginLiteral:
:= .readIndex()
.rescanLiteral()
if .IsValid() {
if := .literalStore(.data[:.readIndex()], , false); != nil {
return
}
}
}
return nil
}
type unquotedValue struct{}
func ( *decodeState) () interface{} {
switch .opcode {
default:
panic(phasePanicMsg)
case scanBeginArray, scanBeginObject:
.skip()
.scanNext()
case scanBeginLiteral:
:= .literalInterface()
switch .(type) {
case nil, string:
return
}
}
return unquotedValue{}
}
func ( reflect.Value, bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
:=
:= false
if .Kind() != reflect.Ptr && .Type().Name() != "" && .CanAddr() {
= true
= .Addr()
}
for {
if .Kind() == reflect.Interface && !.IsNil() {
:= .Elem()
if .Kind() == reflect.Ptr && !.IsNil() && (! || .Elem().Kind() == reflect.Ptr) {
= false
=
continue
}
}
if .Kind() != reflect.Ptr {
break
}
if && .CanSet() {
break
}
if .Elem().Kind() == reflect.Interface && .Elem().Elem() == {
= .Elem()
break
}
if .IsNil() {
.Set(reflect.New(.Type().Elem()))
}
if .Type().NumMethod() > 0 && .CanInterface() {
if , := .Interface().(Unmarshaler); {
return , nil, reflect.Value{}
}
if ! {
if , := .Interface().(encoding.TextUnmarshaler); {
return nil, , reflect.Value{}
}
}
}
if {
=
= false
} else {
= .Elem()
}
}
return nil, nil,
}
func ( *decodeState) ( reflect.Value) error {
, , := indirect(, false)
if != nil {
:= .readIndex()
.skip()
return .UnmarshalJSON(.data[:.off])
}
if != nil {
.saveError(&UnmarshalTypeError{Value: "array", Type: .Type(), Offset: int64(.off)})
.skip()
return nil
}
=
switch .Kind() {
case reflect.Interface:
if .NumMethod() == 0 {
:= .arrayInterface()
.Set(reflect.ValueOf())
return nil
}
fallthrough
default:
.saveError(&UnmarshalTypeError{Value: "array", Type: .Type(), Offset: int64(.off)})
.skip()
return nil
case reflect.Array, reflect.Slice:
break
}
:= 0
for {
.scanWhile(scanSkipSpace)
if .opcode == scanEndArray {
break
}
if .Kind() == reflect.Slice {
if >= .Cap() {
:= .Cap() + .Cap()/2
if < 4 {
= 4
}
:= reflect.MakeSlice(.Type(), .Len(), )
reflect.Copy(, )
.Set()
}
if >= .Len() {
.SetLen( + 1)
}
}
if < .Len() {
if := .value(.Index()); != nil {
return
}
} else {
if := .value(reflect.Value{}); != nil {
return
}
}
++
if .opcode == scanSkipSpace {
.scanWhile(scanSkipSpace)
}
if .opcode == scanEndArray {
break
}
if .opcode != scanArrayValue {
panic(phasePanicMsg)
}
}
if < .Len() {
if .Kind() == reflect.Array {
:= reflect.Zero(.Type().Elem())
for ; < .Len(); ++ {
.Index().Set()
}
} else {
.SetLen()
}
}
if == 0 && .Kind() == reflect.Slice {
.Set(reflect.MakeSlice(.Type(), 0, 0))
}
return nil
}
var nullLiteral = []byte("null")
var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
func ( *decodeState) ( reflect.Value) error {
, , := indirect(, false)
if != nil {
:= .readIndex()
.skip()
return .UnmarshalJSON(.data[:.off])
}
if != nil {
.saveError(&UnmarshalTypeError{Value: "object", Type: .Type(), Offset: int64(.off)})
.skip()
return nil
}
=
:= .Type()
if .Kind() == reflect.Interface && .NumMethod() == 0 {
:= .objectInterface()
.Set(reflect.ValueOf())
return nil
}
var structFields
switch .Kind() {
case reflect.Map:
switch .Key().Kind() {
case reflect.String,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
default:
if !reflect.PtrTo(.Key()).Implements(textUnmarshalerType) {
.saveError(&UnmarshalTypeError{Value: "object", Type: , Offset: int64(.off)})
.skip()
return nil
}
}
if .IsNil() {
.Set(reflect.MakeMap())
}
case reflect.Struct:
= cachedTypeFields()
default:
.saveError(&UnmarshalTypeError{Value: "object", Type: , Offset: int64(.off)})
.skip()
return nil
}
var reflect.Value
:= .errorContext
for {
.scanWhile(scanSkipSpace)
if .opcode == scanEndObject {
break
}
if .opcode != scanBeginLiteral {
panic(phasePanicMsg)
}
:= .readIndex()
.rescanLiteral()
:= .data[:.readIndex()]
, := unquoteBytes()
if ! {
panic(phasePanicMsg)
}
var reflect.Value
:= false
if .Kind() == reflect.Map {
:= .Elem()
if !.IsValid() {
= reflect.New().Elem()
} else {
.Set(reflect.Zero())
}
=
} else {
var *field
if , := .nameIndex[string()]; {
= &.list[]
} else {
for := range .list {
:= &.list[]
if .equalFold(.nameBytes, ) {
=
break
}
}
}
if != nil {
=
= .quoted
for , := range .index {
if .Kind() == reflect.Ptr {
if .IsNil() {
if !.CanSet() {
.saveError(fmt.Errorf("json: cannot set embedded pointer to unexported struct: %v", .Type().Elem()))
= reflect.Value{}
= false
break
}
.Set(reflect.New(.Type().Elem()))
}
= .Elem()
}
= .Field()
}
.errorContext.FieldStack = append(.errorContext.FieldStack, .name)
.errorContext.Struct =
} else if .disallowUnknownFields {
.saveError(fmt.Errorf("json: unknown field %q", ))
}
}
if .opcode == scanSkipSpace {
.scanWhile(scanSkipSpace)
}
if .opcode != scanObjectKey {
panic(phasePanicMsg)
}
.scanWhile(scanSkipSpace)
if {
switch qv := .valueQuoted().(type) {
case nil:
if := .literalStore(nullLiteral, , false); != nil {
return
}
case string:
if := .literalStore([]byte(), , true); != nil {
return
}
default:
.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", .Type()))
}
} else {
if := .value(); != nil {
return
}
}
if .Kind() == reflect.Map {
:= .Key()
var reflect.Value
switch {
case reflect.PtrTo().Implements(textUnmarshalerType):
= reflect.New()
if := .literalStore(, , true); != nil {
return
}
= .Elem()
case .Kind() == reflect.String:
= reflect.ValueOf().Convert()
default:
switch .Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
:= string()
, := strconv.ParseInt(, 10, 64)
if != nil || reflect.Zero().OverflowInt() {
.saveError(&UnmarshalTypeError{Value: "number " + , Type: , Offset: int64( + 1)})
break
}
= reflect.ValueOf().Convert()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
:= string()
, := strconv.ParseUint(, 10, 64)
if != nil || reflect.Zero().OverflowUint() {
.saveError(&UnmarshalTypeError{Value: "number " + , Type: , Offset: int64( + 1)})
break
}
= reflect.ValueOf().Convert()
default:
panic("json: Unexpected key type")
}
}
if .IsValid() {
.SetMapIndex(, )
}
}
if .opcode == scanSkipSpace {
.scanWhile(scanSkipSpace)
}
.errorContext.FieldStack = .errorContext.FieldStack[:len(.FieldStack)]
.errorContext.Struct = .Struct
if .opcode == scanEndObject {
break
}
if .opcode != scanObjectValue {
panic(phasePanicMsg)
}
}
return nil
}
func ( *decodeState) ( string) (interface{}, error) {
if .useNumber {
return Number(), nil
}
, := strconv.ParseFloat(, 64)
if != nil {
return nil, &UnmarshalTypeError{Value: "number " + , Type: reflect.TypeOf(0.0), Offset: int64(.off)}
}
return , nil
}
var numberType = reflect.TypeOf(Number(""))
func ( *decodeState) ( []byte, reflect.Value, bool) error {
if len() == 0 {
.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", , .Type()))
return nil
}
:= [0] == 'n'
, , := indirect(, )
if != nil {
return .UnmarshalJSON()
}
if != nil {
if [0] != '"' {
if {
.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", , .Type()))
return nil
}
:= "number"
switch [0] {
case 'n':
= "null"
case 't', 'f':
= "bool"
}
.saveError(&UnmarshalTypeError{Value: , Type: .Type(), Offset: int64(.readIndex())})
return nil
}
, := unquoteBytes()
if ! {
if {
return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", , .Type())
}
panic(phasePanicMsg)
}
return .UnmarshalText()
}
=
switch := [0]; {
case 'n':
if && string() != "null" {
.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", , .Type()))
break
}
switch .Kind() {
case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
.Set(reflect.Zero(.Type()))
}
case 't', 'f':
:= [0] == 't'
if && string() != "true" && string() != "false" {
.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", , .Type()))
break
}
switch .Kind() {
default:
if {
.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", , .Type()))
} else {
.saveError(&UnmarshalTypeError{Value: "bool", Type: .Type(), Offset: int64(.readIndex())})
}
case reflect.Bool:
.SetBool()
case reflect.Interface:
if .NumMethod() == 0 {
.Set(reflect.ValueOf())
} else {
.saveError(&UnmarshalTypeError{Value: "bool", Type: .Type(), Offset: int64(.readIndex())})
}
}
case '"':
, := unquoteBytes()
if ! {
if {
return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", , .Type())
}
panic(phasePanicMsg)
}
switch .Kind() {
default:
.saveError(&UnmarshalTypeError{Value: "string", Type: .Type(), Offset: int64(.readIndex())})
case reflect.Slice:
if .Type().Elem().Kind() != reflect.Uint8 {
.saveError(&UnmarshalTypeError{Value: "string", Type: .Type(), Offset: int64(.readIndex())})
break
}
:= make([]byte, base64.StdEncoding.DecodedLen(len()))
, := base64.StdEncoding.Decode(, )
if != nil {
.saveError()
break
}
.SetBytes([:])
case reflect.String:
if .Type() == numberType && !isValidNumber(string()) {
return fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", )
}
.SetString(string())
case reflect.Interface:
if .NumMethod() == 0 {
.Set(reflect.ValueOf(string()))
} else {
.saveError(&UnmarshalTypeError{Value: "string", Type: .Type(), Offset: int64(.readIndex())})
}
}
default:
if != '-' && ( < '0' || > '9') {
if {
return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", , .Type())
}
panic(phasePanicMsg)
}
:= string()
switch .Kind() {
default:
if .Kind() == reflect.String && .Type() == numberType {
.SetString()
break
}
if {
return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", , .Type())
}
.saveError(&UnmarshalTypeError{Value: "number", Type: .Type(), Offset: int64(.readIndex())})
case reflect.Interface:
, := .convertNumber()
if != nil {
.saveError()
break
}
if .NumMethod() != 0 {
.saveError(&UnmarshalTypeError{Value: "number", Type: .Type(), Offset: int64(.readIndex())})
break
}
.Set(reflect.ValueOf())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
, := strconv.ParseInt(, 10, 64)
if != nil || .OverflowInt() {
.saveError(&UnmarshalTypeError{Value: "number " + , Type: .Type(), Offset: int64(.readIndex())})
break
}
.SetInt()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
, := strconv.ParseUint(, 10, 64)
if != nil || .OverflowUint() {
.saveError(&UnmarshalTypeError{Value: "number " + , Type: .Type(), Offset: int64(.readIndex())})
break
}
.SetUint()
case reflect.Float32, reflect.Float64:
, := strconv.ParseFloat(, .Type().Bits())
if != nil || .OverflowFloat() {
.saveError(&UnmarshalTypeError{Value: "number " + , Type: .Type(), Offset: int64(.readIndex())})
break
}
.SetFloat()
}
}
return nil
}
func ( *decodeState) () ( interface{}) {
switch .opcode {
default:
panic(phasePanicMsg)
case scanBeginArray:
= .arrayInterface()
.scanNext()
case scanBeginObject:
= .objectInterface()
.scanNext()
case scanBeginLiteral:
= .literalInterface()
}
return
}
func ( *decodeState) () []interface{} {
var = make([]interface{}, 0)
for {
.scanWhile(scanSkipSpace)
if .opcode == scanEndArray {
break
}
= append(, .valueInterface())
if .opcode == scanSkipSpace {
.scanWhile(scanSkipSpace)
}
if .opcode == scanEndArray {
break
}
if .opcode != scanArrayValue {
panic(phasePanicMsg)
}
}
return
}
func ( *decodeState) () map[string]interface{} {
:= make(map[string]interface{})
for {
.scanWhile(scanSkipSpace)
if .opcode == scanEndObject {
break
}
if .opcode != scanBeginLiteral {
panic(phasePanicMsg)
}
:= .readIndex()
.rescanLiteral()
:= .data[:.readIndex()]
, := unquote()
if ! {
panic(phasePanicMsg)
}
if .opcode == scanSkipSpace {
.scanWhile(scanSkipSpace)
}
if .opcode != scanObjectKey {
panic(phasePanicMsg)
}
.scanWhile(scanSkipSpace)
[] = .valueInterface()
if .opcode == scanSkipSpace {
.scanWhile(scanSkipSpace)
}
if .opcode == scanEndObject {
break
}
if .opcode != scanObjectValue {
panic(phasePanicMsg)
}
}
return
}
func ( *decodeState) () interface{} {
:= .readIndex()
.rescanLiteral()
:= .data[:.readIndex()]
switch := [0]; {
case 'n':
return nil
case 't', 'f':
return == 't'
case '"':
, := unquote()
if ! {
panic(phasePanicMsg)
}
return
default:
if != '-' && ( < '0' || > '9') {
panic(phasePanicMsg)
}
, := .convertNumber(string())
if != nil {
.saveError()
}
return
}
}
func ( []byte) rune {
if len() < 6 || [0] != '\\' || [1] != 'u' {
return -1
}
var rune
for , := range [2:6] {
switch {
case '0' <= && <= '9':
= - '0'
case 'a' <= && <= 'f':
= - 'a' + 10
case 'A' <= && <= 'F':
= - 'A' + 10
default:
return -1
}
= *16 + rune()
}
return
}
func ( []byte) ( string, bool) {
, = unquoteBytes()
= string()
return
}
func ( []byte) ( []byte, bool) {
if len() < 2 || [0] != '"' || [len()-1] != '"' {
return
}
= [1 : len()-1]
:= 0
for < len() {
:= []
if == '\\' || == '"' || < ' ' {
break
}
if < utf8.RuneSelf {
++
continue
}
, := utf8.DecodeRune([:])
if == utf8.RuneError && == 1 {
break
}
+=
}
if == len() {
return , true
}
:= make([]byte, len()+2*utf8.UTFMax)
:= copy(, [0:])
for < len() {
if >= len()-2*utf8.UTFMax {
:= make([]byte, (len()+utf8.UTFMax)*2)
copy(, [0:])
=
}
switch := []; {
case == '\\':
++
if >= len() {
return
}
switch [] {
default:
return
case '"', '\\', '/', '\'':
[] = []
++
++
case 'b':
[] = '\b'
++
++
case 'f':
[] = '\f'
++
++
case 'n':
[] = '\n'
++
++
case 'r':
[] = '\r'
++
++
case 't':
[] = '\t'
++
++
case 'u':
--
:= getu4([:])
if < 0 {
return
}
+= 6
if utf16.IsSurrogate() {
:= getu4([:])
if := utf16.DecodeRune(, ); != unicode.ReplacementChar {
+= 6
+= utf8.EncodeRune([:], )
break
}
= unicode.ReplacementChar
}
+= utf8.EncodeRune([:], )
}
case == '"', < ' ':
return
case < utf8.RuneSelf:
[] =
++
++
default:
, := utf8.DecodeRune([:])
+=
+= utf8.EncodeRune([:], )
}
}
return [0:], true
}