diff options
| author | 2023-02-25 13:12:40 +0100 | |
|---|---|---|
| committer | 2023-02-25 12:12:40 +0000 | |
| commit | ecdc8379fa8f9d88faca626e7de748c2afbe4910 (patch) | |
| tree | 8c20a5826db2136fc89bee45e15355c5899fa65b /vendor/github.com/goccy/go-json/internal/decoder | |
| parent | [bugfix] Fix deleted status causing issues when getting bookmark (#1551) (diff) | |
| download | gotosocial-ecdc8379fa8f9d88faca626e7de748c2afbe4910.tar.xz | |
[chore] Update gin to v1.9.0 (#1553)
Diffstat (limited to 'vendor/github.com/goccy/go-json/internal/decoder')
23 files changed, 1457 insertions, 0 deletions
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go b/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go index 030cb7a97..b6876cf0d 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go @@ -35,3 +35,7 @@ func (d *anonymousFieldDecoder) Decode(ctx *RuntimeContext, cursor, depth int64,  	p = *(*unsafe.Pointer)(p)  	return d.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+d.offset))  } + +func (d *anonymousFieldDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return d.dec.DecodePath(ctx, cursor, depth) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/array.go b/vendor/github.com/goccy/go-json/internal/decoder/array.go index 21f1fd585..8ef91cfa1 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/array.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/array.go @@ -1,6 +1,7 @@  package decoder  import ( +	"fmt"  	"unsafe"  	"github.com/goccy/go-json/internal/errors" @@ -167,3 +168,7 @@ func (d *arrayDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe  		}  	}  } + +func (d *arrayDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, fmt.Errorf("json: array decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/assign.go b/vendor/github.com/goccy/go-json/internal/decoder/assign.go new file mode 100644 index 000000000..c53e6ad9f --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/assign.go @@ -0,0 +1,438 @@ +package decoder + +import ( +	"fmt" +	"reflect" +	"strconv" +) + +var ( +	nilValue = reflect.ValueOf(nil) +) + +func AssignValue(src, dst reflect.Value) error { +	if dst.Type().Kind() != reflect.Ptr { +		return fmt.Errorf("invalid dst type. required pointer type: %T", dst.Type()) +	} +	casted, err := castValue(dst.Elem().Type(), src) +	if err != nil { +		return err +	} +	dst.Elem().Set(casted) +	return nil +} + +func castValue(t reflect.Type, v reflect.Value) (reflect.Value, error) { +	switch t.Kind() { +	case reflect.Int: +		vv, err := castInt(v) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(int(vv.Int())), nil +	case reflect.Int8: +		vv, err := castInt(v) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(int8(vv.Int())), nil +	case reflect.Int16: +		vv, err := castInt(v) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(int16(vv.Int())), nil +	case reflect.Int32: +		vv, err := castInt(v) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(int32(vv.Int())), nil +	case reflect.Int64: +		return castInt(v) +	case reflect.Uint: +		vv, err := castUint(v) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(uint(vv.Uint())), nil +	case reflect.Uint8: +		vv, err := castUint(v) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(uint8(vv.Uint())), nil +	case reflect.Uint16: +		vv, err := castUint(v) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(uint16(vv.Uint())), nil +	case reflect.Uint32: +		vv, err := castUint(v) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(uint32(vv.Uint())), nil +	case reflect.Uint64: +		return castUint(v) +	case reflect.Uintptr: +		vv, err := castUint(v) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(uintptr(vv.Uint())), nil +	case reflect.String: +		return castString(v) +	case reflect.Bool: +		return castBool(v) +	case reflect.Float32: +		vv, err := castFloat(v) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(float32(vv.Float())), nil +	case reflect.Float64: +		return castFloat(v) +	case reflect.Array: +		return castArray(t, v) +	case reflect.Slice: +		return castSlice(t, v) +	case reflect.Map: +		return castMap(t, v) +	case reflect.Struct: +		return castStruct(t, v) +	} +	return v, nil +} + +func castInt(v reflect.Value) (reflect.Value, error) { +	switch v.Type().Kind() { +	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: +		return v, nil +	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: +		return reflect.ValueOf(int64(v.Uint())), nil +	case reflect.String: +		i64, err := strconv.ParseInt(v.String(), 10, 64) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(i64), nil +	case reflect.Bool: +		if v.Bool() { +			return reflect.ValueOf(int64(1)), nil +		} +		return reflect.ValueOf(int64(0)), nil +	case reflect.Float32, reflect.Float64: +		return reflect.ValueOf(int64(v.Float())), nil +	case reflect.Array: +		if v.Len() > 0 { +			return castInt(v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to int64 from empty array") +	case reflect.Slice: +		if v.Len() > 0 { +			return castInt(v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to int64 from empty slice") +	case reflect.Interface: +		return castInt(reflect.ValueOf(v.Interface())) +	case reflect.Map: +		return nilValue, fmt.Errorf("failed to cast to int64 from map") +	case reflect.Struct: +		return nilValue, fmt.Errorf("failed to cast to int64 from struct") +	case reflect.Ptr: +		return castInt(v.Elem()) +	} +	return nilValue, fmt.Errorf("failed to cast to int64 from %s", v.Type().Kind()) +} + +func castUint(v reflect.Value) (reflect.Value, error) { +	switch v.Type().Kind() { +	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: +		return reflect.ValueOf(uint64(v.Int())), nil +	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: +		return v, nil +	case reflect.String: +		u64, err := strconv.ParseUint(v.String(), 10, 64) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(u64), nil +	case reflect.Bool: +		if v.Bool() { +			return reflect.ValueOf(uint64(1)), nil +		} +		return reflect.ValueOf(uint64(0)), nil +	case reflect.Float32, reflect.Float64: +		return reflect.ValueOf(uint64(v.Float())), nil +	case reflect.Array: +		if v.Len() > 0 { +			return castUint(v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to uint64 from empty array") +	case reflect.Slice: +		if v.Len() > 0 { +			return castUint(v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to uint64 from empty slice") +	case reflect.Interface: +		return castUint(reflect.ValueOf(v.Interface())) +	case reflect.Map: +		return nilValue, fmt.Errorf("failed to cast to uint64 from map") +	case reflect.Struct: +		return nilValue, fmt.Errorf("failed to cast to uint64 from struct") +	case reflect.Ptr: +		return castUint(v.Elem()) +	} +	return nilValue, fmt.Errorf("failed to cast to uint64 from %s", v.Type().Kind()) +} + +func castString(v reflect.Value) (reflect.Value, error) { +	switch v.Type().Kind() { +	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: +		return reflect.ValueOf(fmt.Sprint(v.Int())), nil +	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: +		return reflect.ValueOf(fmt.Sprint(v.Uint())), nil +	case reflect.String: +		return v, nil +	case reflect.Bool: +		if v.Bool() { +			return reflect.ValueOf("true"), nil +		} +		return reflect.ValueOf("false"), nil +	case reflect.Float32, reflect.Float64: +		return reflect.ValueOf(fmt.Sprint(v.Float())), nil +	case reflect.Array: +		if v.Len() > 0 { +			return castString(v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to string from empty array") +	case reflect.Slice: +		if v.Len() > 0 { +			return castString(v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to string from empty slice") +	case reflect.Interface: +		return castString(reflect.ValueOf(v.Interface())) +	case reflect.Map: +		return nilValue, fmt.Errorf("failed to cast to string from map") +	case reflect.Struct: +		return nilValue, fmt.Errorf("failed to cast to string from struct") +	case reflect.Ptr: +		return castString(v.Elem()) +	} +	return nilValue, fmt.Errorf("failed to cast to string from %s", v.Type().Kind()) +} + +func castBool(v reflect.Value) (reflect.Value, error) { +	switch v.Type().Kind() { +	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: +		switch v.Int() { +		case 0: +			return reflect.ValueOf(false), nil +		case 1: +			return reflect.ValueOf(true), nil +		} +		return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Int()) +	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: +		switch v.Uint() { +		case 0: +			return reflect.ValueOf(false), nil +		case 1: +			return reflect.ValueOf(true), nil +		} +		return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Uint()) +	case reflect.String: +		b, err := strconv.ParseBool(v.String()) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(b), nil +	case reflect.Bool: +		return v, nil +	case reflect.Float32, reflect.Float64: +		switch v.Float() { +		case 0: +			return reflect.ValueOf(false), nil +		case 1: +			return reflect.ValueOf(true), nil +		} +		return nilValue, fmt.Errorf("failed to cast to bool from %f", v.Float()) +	case reflect.Array: +		if v.Len() > 0 { +			return castBool(v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to string from empty array") +	case reflect.Slice: +		if v.Len() > 0 { +			return castBool(v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to string from empty slice") +	case reflect.Interface: +		return castBool(reflect.ValueOf(v.Interface())) +	case reflect.Map: +		return nilValue, fmt.Errorf("failed to cast to string from map") +	case reflect.Struct: +		return nilValue, fmt.Errorf("failed to cast to string from struct") +	case reflect.Ptr: +		return castBool(v.Elem()) +	} +	return nilValue, fmt.Errorf("failed to cast to bool from %s", v.Type().Kind()) +} + +func castFloat(v reflect.Value) (reflect.Value, error) { +	switch v.Type().Kind() { +	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: +		return reflect.ValueOf(float64(v.Int())), nil +	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: +		return reflect.ValueOf(float64(v.Uint())), nil +	case reflect.String: +		f64, err := strconv.ParseFloat(v.String(), 64) +		if err != nil { +			return nilValue, err +		} +		return reflect.ValueOf(f64), nil +	case reflect.Bool: +		if v.Bool() { +			return reflect.ValueOf(float64(1)), nil +		} +		return reflect.ValueOf(float64(0)), nil +	case reflect.Float32, reflect.Float64: +		return v, nil +	case reflect.Array: +		if v.Len() > 0 { +			return castFloat(v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to float64 from empty array") +	case reflect.Slice: +		if v.Len() > 0 { +			return castFloat(v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to float64 from empty slice") +	case reflect.Interface: +		return castFloat(reflect.ValueOf(v.Interface())) +	case reflect.Map: +		return nilValue, fmt.Errorf("failed to cast to float64 from map") +	case reflect.Struct: +		return nilValue, fmt.Errorf("failed to cast to float64 from struct") +	case reflect.Ptr: +		return castFloat(v.Elem()) +	} +	return nilValue, fmt.Errorf("failed to cast to float64 from %s", v.Type().Kind()) +} + +func castArray(t reflect.Type, v reflect.Value) (reflect.Value, error) { +	kind := v.Type().Kind() +	if kind == reflect.Interface { +		return castArray(t, reflect.ValueOf(v.Interface())) +	} +	if kind != reflect.Slice && kind != reflect.Array { +		return nilValue, fmt.Errorf("failed to cast to array from %s", kind) +	} +	if t.Elem() == v.Type().Elem() { +		return v, nil +	} +	if t.Len() != v.Len() { +		return nilValue, fmt.Errorf("failed to cast [%d]array from slice of %d length", t.Len(), v.Len()) +	} +	ret := reflect.New(t).Elem() +	for i := 0; i < v.Len(); i++ { +		vv, err := castValue(t.Elem(), v.Index(i)) +		if err != nil { +			return nilValue, err +		} +		ret.Index(i).Set(vv) +	} +	return ret, nil +} + +func castSlice(t reflect.Type, v reflect.Value) (reflect.Value, error) { +	kind := v.Type().Kind() +	if kind == reflect.Interface { +		return castSlice(t, reflect.ValueOf(v.Interface())) +	} +	if kind != reflect.Slice && kind != reflect.Array { +		return nilValue, fmt.Errorf("failed to cast to slice from %s", kind) +	} +	if t.Elem() == v.Type().Elem() { +		return v, nil +	} +	ret := reflect.MakeSlice(t, v.Len(), v.Len()) +	for i := 0; i < v.Len(); i++ { +		vv, err := castValue(t.Elem(), v.Index(i)) +		if err != nil { +			return nilValue, err +		} +		ret.Index(i).Set(vv) +	} +	return ret, nil +} + +func castMap(t reflect.Type, v reflect.Value) (reflect.Value, error) { +	ret := reflect.MakeMap(t) +	switch v.Type().Kind() { +	case reflect.Map: +		iter := v.MapRange() +		for iter.Next() { +			key, err := castValue(t.Key(), iter.Key()) +			if err != nil { +				return nilValue, err +			} +			value, err := castValue(t.Elem(), iter.Value()) +			if err != nil { +				return nilValue, err +			} +			ret.SetMapIndex(key, value) +		} +		return ret, nil +	case reflect.Interface: +		return castMap(t, reflect.ValueOf(v.Interface())) +	case reflect.Slice: +		if v.Len() > 0 { +			return castMap(t, v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to map from empty slice") +	} +	return nilValue, fmt.Errorf("failed to cast to map from %s", v.Type().Kind()) +} + +func castStruct(t reflect.Type, v reflect.Value) (reflect.Value, error) { +	ret := reflect.New(t).Elem() +	switch v.Type().Kind() { +	case reflect.Map: +		iter := v.MapRange() +		for iter.Next() { +			key := iter.Key() +			k, err := castString(key) +			if err != nil { +				return nilValue, err +			} +			fieldName := k.String() +			field, ok := t.FieldByName(fieldName) +			if ok { +				value, err := castValue(field.Type, iter.Value()) +				if err != nil { +					return nilValue, err +				} +				ret.FieldByName(fieldName).Set(value) +			} +		} +		return ret, nil +	case reflect.Struct: +		for i := 0; i < v.Type().NumField(); i++ { +			name := v.Type().Field(i).Name +			ret.FieldByName(name).Set(v.FieldByName(name)) +		} +		return ret, nil +	case reflect.Interface: +		return castStruct(t, reflect.ValueOf(v.Interface())) +	case reflect.Slice: +		if v.Len() > 0 { +			return castStruct(t, v.Index(0)) +		} +		return nilValue, fmt.Errorf("failed to cast to struct from empty slice") +	default: +		return nilValue, fmt.Errorf("failed to cast to struct from %s", v.Type().Kind()) +	} +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/bool.go b/vendor/github.com/goccy/go-json/internal/decoder/bool.go index 455042a53..ba6cf5bc4 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/bool.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/bool.go @@ -1,6 +1,7 @@  package decoder  import ( +	"fmt"  	"unsafe"  	"github.com/goccy/go-json/internal/errors" @@ -76,3 +77,7 @@ func (d *boolDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.  	}  	return 0, errors.ErrUnexpectedEndOfJSON("bool", cursor)  } + +func (d *boolDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, fmt.Errorf("json: bool decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/bytes.go b/vendor/github.com/goccy/go-json/internal/decoder/bytes.go index 92c7dcf64..939bf4327 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/bytes.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/bytes.go @@ -2,6 +2,7 @@ package decoder  import (  	"encoding/base64" +	"fmt"  	"unsafe"  	"github.com/goccy/go-json/internal/errors" @@ -78,6 +79,10 @@ func (d *bytesDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe  	return cursor, nil  } +func (d *bytesDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, fmt.Errorf("json: []byte decoder does not support decode path") +} +  func (d *bytesDecoder) decodeStreamBinary(s *Stream, depth int64, p unsafe.Pointer) ([]byte, error) {  	c := s.skipWhiteSpace()  	if c == '[' { diff --git a/vendor/github.com/goccy/go-json/internal/decoder/float.go b/vendor/github.com/goccy/go-json/internal/decoder/float.go index dfb7168da..9b2eb8b35 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/float.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/float.go @@ -156,3 +156,15 @@ func (d *floatDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe  	d.op(p, f64)  	return cursor, nil  } + +func (d *floatDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	buf := ctx.Buf +	bytes, c, err := d.decodeByte(buf, cursor) +	if err != nil { +		return nil, 0, err +	} +	if bytes == nil { +		return [][]byte{nullbytes}, c, nil +	} +	return [][]byte{bytes}, c, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/func.go b/vendor/github.com/goccy/go-json/internal/decoder/func.go index ee3563711..4cc12ca81 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/func.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/func.go @@ -2,6 +2,7 @@ package decoder  import (  	"bytes" +	"fmt"  	"unsafe"  	"github.com/goccy/go-json/internal/errors" @@ -139,3 +140,7 @@ func (d *funcDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.  	}  	return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)  } + +func (d *funcDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, fmt.Errorf("json: func decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/int.go b/vendor/github.com/goccy/go-json/internal/decoder/int.go index 509b753d6..1a7f08199 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/int.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/int.go @@ -240,3 +240,7 @@ func (d *intDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.P  	d.op(p, i64)  	return cursor, nil  } + +func (d *intDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, fmt.Errorf("json: int decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/interface.go b/vendor/github.com/goccy/go-json/internal/decoder/interface.go index 4dbb4be4a..45c69ab8c 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/interface.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/interface.go @@ -94,6 +94,7 @@ func (d *interfaceDecoder) numDecoder(s *Stream) Decoder {  var (  	emptyInterfaceType = runtime.Type2RType(reflect.TypeOf((*interface{})(nil)).Elem()) +	EmptyInterfaceType = emptyInterfaceType  	interfaceMapType   = runtime.Type2RType(  		reflect.TypeOf((*map[string]interface{})(nil)).Elem(),  	) @@ -456,3 +457,72 @@ func (d *interfaceDecoder) decodeEmptyInterface(ctx *RuntimeContext, cursor, dep  	}  	return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)  } + +func NewPathDecoder() Decoder { +	ifaceDecoder := &interfaceDecoder{ +		typ:        emptyInterfaceType, +		structName: "", +		fieldName:  "", +		floatDecoder: newFloatDecoder("", "", func(p unsafe.Pointer, v float64) { +			*(*interface{})(p) = v +		}), +		numberDecoder: newNumberDecoder("", "", func(p unsafe.Pointer, v json.Number) { +			*(*interface{})(p) = v +		}), +		stringDecoder: newStringDecoder("", ""), +	} +	ifaceDecoder.sliceDecoder = newSliceDecoder( +		ifaceDecoder, +		emptyInterfaceType, +		emptyInterfaceType.Size(), +		"", "", +	) +	ifaceDecoder.mapDecoder = newMapDecoder( +		interfaceMapType, +		stringType, +		ifaceDecoder.stringDecoder, +		interfaceMapType.Elem(), +		ifaceDecoder, +		"", "", +	) +	return ifaceDecoder +} + +var ( +	truebytes  = []byte("true") +	falsebytes = []byte("false") +) + +func (d *interfaceDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	buf := ctx.Buf +	cursor = skipWhiteSpace(buf, cursor) +	switch buf[cursor] { +	case '{': +		return d.mapDecoder.DecodePath(ctx, cursor, depth) +	case '[': +		return d.sliceDecoder.DecodePath(ctx, cursor, depth) +	case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': +		return d.floatDecoder.DecodePath(ctx, cursor, depth) +	case '"': +		return d.stringDecoder.DecodePath(ctx, cursor, depth) +	case 't': +		if err := validateTrue(buf, cursor); err != nil { +			return nil, 0, err +		} +		cursor += 4 +		return [][]byte{truebytes}, cursor, nil +	case 'f': +		if err := validateFalse(buf, cursor); err != nil { +			return nil, 0, err +		} +		cursor += 5 +		return [][]byte{falsebytes}, cursor, nil +	case 'n': +		if err := validateNull(buf, cursor); err != nil { +			return nil, 0, err +		} +		cursor += 4 +		return [][]byte{nullbytes}, cursor, nil +	} +	return nil, cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/invalid.go b/vendor/github.com/goccy/go-json/internal/decoder/invalid.go index 1ef50a7d3..4c9721b09 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/invalid.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/invalid.go @@ -43,3 +43,13 @@ func (d *invalidDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsa  		Field:  d.fieldName,  	}  } + +func (d *invalidDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, &errors.UnmarshalTypeError{ +		Value:  "object", +		Type:   runtime.RType2Type(d.typ), +		Offset: cursor, +		Struct: d.structName, +		Field:  d.fieldName, +	} +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/map.go b/vendor/github.com/goccy/go-json/internal/decoder/map.go index cb55ef006..7a6eea34f 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/map.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/map.go @@ -185,3 +185,96 @@ func (d *mapDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.P  		cursor++  	}  } + +func (d *mapDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	buf := ctx.Buf +	depth++ +	if depth > maxDecodeNestingDepth { +		return nil, 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) +	} + +	cursor = skipWhiteSpace(buf, cursor) +	buflen := int64(len(buf)) +	if buflen < 2 { +		return nil, 0, errors.ErrExpected("{} for map", cursor) +	} +	switch buf[cursor] { +	case 'n': +		if err := validateNull(buf, cursor); err != nil { +			return nil, 0, err +		} +		cursor += 4 +		return [][]byte{nullbytes}, cursor, nil +	case '{': +	default: +		return nil, 0, errors.ErrExpected("{ character for map value", cursor) +	} +	cursor++ +	cursor = skipWhiteSpace(buf, cursor) +	if buf[cursor] == '}' { +		cursor++ +		return nil, cursor, nil +	} +	keyDecoder, ok := d.keyDecoder.(*stringDecoder) +	if !ok { +		return nil, 0, &errors.UnmarshalTypeError{ +			Value:  "string", +			Type:   reflect.TypeOf(""), +			Offset: cursor, +			Struct: d.structName, +			Field:  d.fieldName, +		} +	} +	ret := [][]byte{} +	for { +		key, keyCursor, err := keyDecoder.decodeByte(buf, cursor) +		if err != nil { +			return nil, 0, err +		} +		cursor = skipWhiteSpace(buf, keyCursor) +		if buf[cursor] != ':' { +			return nil, 0, errors.ErrExpected("colon after object key", cursor) +		} +		cursor++ +		child, found, err := ctx.Option.Path.Field(string(key)) +		if err != nil { +			return nil, 0, err +		} +		if found { +			if child != nil { +				oldPath := ctx.Option.Path.node +				ctx.Option.Path.node = child +				paths, c, err := d.valueDecoder.DecodePath(ctx, cursor, depth) +				if err != nil { +					return nil, 0, err +				} +				ctx.Option.Path.node = oldPath +				ret = append(ret, paths...) +				cursor = c +			} else { +				start := cursor +				end, err := skipValue(buf, cursor, depth) +				if err != nil { +					return nil, 0, err +				} +				ret = append(ret, buf[start:end]) +				cursor = end +			} +		} else { +			c, err := skipValue(buf, cursor, depth) +			if err != nil { +				return nil, 0, err +			} +			cursor = c +		} +		cursor = skipWhiteSpace(buf, cursor) +		if buf[cursor] == '}' { +			cursor++ +			return ret, cursor, nil +		} +		if buf[cursor] != ',' { +			return nil, 0, errors.ErrExpected("comma after object value", cursor) +		} +		cursor++ +	} +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/number.go b/vendor/github.com/goccy/go-json/internal/decoder/number.go index bf63773e3..10e5435e6 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/number.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/number.go @@ -51,6 +51,17 @@ func (d *numberDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf  	return cursor, nil  } +func (d *numberDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	bytes, c, err := d.decodeByte(ctx.Buf, cursor) +	if err != nil { +		return nil, 0, err +	} +	if bytes == nil { +		return [][]byte{nullbytes}, c, nil +	} +	return [][]byte{bytes}, c, nil +} +  func (d *numberDecoder) decodeStreamByte(s *Stream) ([]byte, error) {  	start := s.cursor  	for { diff --git a/vendor/github.com/goccy/go-json/internal/decoder/option.go b/vendor/github.com/goccy/go-json/internal/decoder/option.go index e41f876b0..502f772eb 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/option.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/option.go @@ -7,9 +7,11 @@ type OptionFlags uint8  const (  	FirstWinOption OptionFlags = 1 << iota  	ContextOption +	PathOption  )  type Option struct {  	Flags   OptionFlags  	Context context.Context +	Path    *Path  } diff --git a/vendor/github.com/goccy/go-json/internal/decoder/path.go b/vendor/github.com/goccy/go-json/internal/decoder/path.go new file mode 100644 index 000000000..a15ff69e3 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/path.go @@ -0,0 +1,670 @@ +package decoder + +import ( +	"fmt" +	"reflect" +	"strconv" + +	"github.com/goccy/go-json/internal/errors" +	"github.com/goccy/go-json/internal/runtime" +) + +type PathString string + +func (s PathString) Build() (*Path, error) { +	builder := new(PathBuilder) +	return builder.Build([]rune(s)) +} + +type PathBuilder struct { +	root                    PathNode +	node                    PathNode +	singleQuotePathSelector bool +	doubleQuotePathSelector bool +} + +func (b *PathBuilder) Build(buf []rune) (*Path, error) { +	node, err := b.build(buf) +	if err != nil { +		return nil, err +	} +	return &Path{ +		node:                    node, +		RootSelectorOnly:        node == nil, +		SingleQuotePathSelector: b.singleQuotePathSelector, +		DoubleQuotePathSelector: b.doubleQuotePathSelector, +	}, nil +} + +func (b *PathBuilder) build(buf []rune) (PathNode, error) { +	if len(buf) == 0 { +		return nil, errors.ErrEmptyPath() +	} +	if buf[0] != '$' { +		return nil, errors.ErrInvalidPath("JSON Path must start with a $ character") +	} +	if len(buf) == 1 { +		return nil, nil +	} +	buf = buf[1:] +	offset, err := b.buildNext(buf) +	if err != nil { +		return nil, err +	} +	if len(buf) > offset { +		return nil, errors.ErrInvalidPath("remain invalid path %q", buf[offset:]) +	} +	return b.root, nil +} + +func (b *PathBuilder) buildNextCharIfExists(buf []rune, cursor int) (int, error) { +	if len(buf) > cursor { +		offset, err := b.buildNext(buf[cursor:]) +		if err != nil { +			return 0, err +		} +		return cursor + 1 + offset, nil +	} +	return cursor, nil +} + +func (b *PathBuilder) buildNext(buf []rune) (int, error) { +	switch buf[0] { +	case '.': +		if len(buf) == 1 { +			return 0, errors.ErrInvalidPath("JSON Path ends with dot character") +		} +		offset, err := b.buildSelector(buf[1:]) +		if err != nil { +			return 0, err +		} +		return offset + 1, nil +	case '[': +		if len(buf) == 1 { +			return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character") +		} +		offset, err := b.buildIndex(buf[1:]) +		if err != nil { +			return 0, err +		} +		return offset + 1, nil +	default: +		return 0, errors.ErrInvalidPath("expect dot or left bracket character. but found %c character", buf[0]) +	} +} + +func (b *PathBuilder) buildSelector(buf []rune) (int, error) { +	switch buf[0] { +	case '.': +		if len(buf) == 1 { +			return 0, errors.ErrInvalidPath("JSON Path ends with double dot character") +		} +		offset, err := b.buildPathRecursive(buf[1:]) +		if err != nil { +			return 0, err +		} +		return 1 + offset, nil +	case '[', ']', '$', '*': +		return 0, errors.ErrInvalidPath("found invalid path character %c after dot", buf[0]) +	} +	for cursor := 0; cursor < len(buf); cursor++ { +		switch buf[cursor] { +		case '$', '*', ']': +			return 0, errors.ErrInvalidPath("found %c character in field selector context", buf[cursor]) +		case '.': +			if cursor+1 >= len(buf) { +				return 0, errors.ErrInvalidPath("JSON Path ends with dot character") +			} +			selector := buf[:cursor] +			b.addSelectorNode(string(selector)) +			offset, err := b.buildSelector(buf[cursor+1:]) +			if err != nil { +				return 0, err +			} +			return cursor + 1 + offset, nil +		case '[': +			if cursor+1 >= len(buf) { +				return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character") +			} +			selector := buf[:cursor] +			b.addSelectorNode(string(selector)) +			offset, err := b.buildIndex(buf[cursor+1:]) +			if err != nil { +				return 0, err +			} +			return cursor + 1 + offset, nil +		case '"': +			if cursor+1 >= len(buf) { +				return 0, errors.ErrInvalidPath("JSON Path ends with double quote character") +			} +			offset, err := b.buildQuoteSelector(buf[cursor+1:], DoubleQuotePathSelector) +			if err != nil { +				return 0, err +			} +			return cursor + 1 + offset, nil +		} +	} +	b.addSelectorNode(string(buf)) +	return len(buf), nil +} + +func (b *PathBuilder) buildQuoteSelector(buf []rune, sel QuotePathSelector) (int, error) { +	switch buf[0] { +	case '[', ']', '$', '.', '*', '\'', '"': +		return 0, errors.ErrInvalidPath("found invalid path character %c after quote", buf[0]) +	} +	for cursor := 0; cursor < len(buf); cursor++ { +		switch buf[cursor] { +		case '\'': +			if sel != SingleQuotePathSelector { +				return 0, errors.ErrInvalidPath("found double quote character in field selector with single quote context") +			} +			if len(buf) <= cursor+1 { +				return 0, errors.ErrInvalidPath("JSON Path ends with single quote character in field selector context") +			} +			if buf[cursor+1] != ']' { +				return 0, errors.ErrInvalidPath("expect right bracket for field selector with single quote but found %c", buf[cursor+1]) +			} +			selector := buf[:cursor] +			b.addSelectorNode(string(selector)) +			b.singleQuotePathSelector = true +			return b.buildNextCharIfExists(buf, cursor+2) +		case '"': +			if sel != DoubleQuotePathSelector { +				return 0, errors.ErrInvalidPath("found single quote character in field selector with double quote context") +			} +			selector := buf[:cursor] +			b.addSelectorNode(string(selector)) +			b.doubleQuotePathSelector = true +			return b.buildNextCharIfExists(buf, cursor+1) +		} +	} +	return 0, errors.ErrInvalidPath("couldn't find quote character in selector quote path context") +} + +func (b *PathBuilder) buildPathRecursive(buf []rune) (int, error) { +	switch buf[0] { +	case '.', '[', ']', '$', '*': +		return 0, errors.ErrInvalidPath("found invalid path character %c after double dot", buf[0]) +	} +	for cursor := 0; cursor < len(buf); cursor++ { +		switch buf[cursor] { +		case '$', '*', ']': +			return 0, errors.ErrInvalidPath("found %c character in field selector context", buf[cursor]) +		case '.': +			if cursor+1 >= len(buf) { +				return 0, errors.ErrInvalidPath("JSON Path ends with dot character") +			} +			selector := buf[:cursor] +			b.addRecursiveNode(string(selector)) +			offset, err := b.buildSelector(buf[cursor+1:]) +			if err != nil { +				return 0, err +			} +			return cursor + 1 + offset, nil +		case '[': +			if cursor+1 >= len(buf) { +				return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character") +			} +			selector := buf[:cursor] +			b.addRecursiveNode(string(selector)) +			offset, err := b.buildIndex(buf[cursor+1:]) +			if err != nil { +				return 0, err +			} +			return cursor + 1 + offset, nil +		} +	} +	b.addRecursiveNode(string(buf)) +	return len(buf), nil +} + +func (b *PathBuilder) buildIndex(buf []rune) (int, error) { +	switch buf[0] { +	case '.', '[', ']', '$': +		return 0, errors.ErrInvalidPath("found invalid path character %c after left bracket", buf[0]) +	case '\'': +		if len(buf) == 1 { +			return 0, errors.ErrInvalidPath("JSON Path ends with single quote character") +		} +		offset, err := b.buildQuoteSelector(buf[1:], SingleQuotePathSelector) +		if err != nil { +			return 0, err +		} +		return 1 + offset, nil +	case '*': +		if len(buf) == 1 { +			return 0, errors.ErrInvalidPath("JSON Path ends with star character") +		} +		if buf[1] != ']' { +			return 0, errors.ErrInvalidPath("expect right bracket character for index all path but found %c character", buf[1]) +		} +		b.addIndexAllNode() +		offset := len("*]") +		if len(buf) > 2 { +			buildOffset, err := b.buildNext(buf[2:]) +			if err != nil { +				return 0, err +			} +			return offset + buildOffset, nil +		} +		return offset, nil +	} + +	for cursor := 0; cursor < len(buf); cursor++ { +		switch buf[cursor] { +		case ']': +			index, err := strconv.ParseInt(string(buf[:cursor]), 10, 64) +			if err != nil { +				return 0, errors.ErrInvalidPath("%q is unexpected index path", buf[:cursor]) +			} +			b.addIndexNode(int(index)) +			return b.buildNextCharIfExists(buf, cursor+1) +		} +	} +	return 0, errors.ErrInvalidPath("couldn't find right bracket character in index path context") +} + +func (b *PathBuilder) addIndexAllNode() { +	node := newPathIndexAllNode() +	if b.root == nil { +		b.root = node +		b.node = node +	} else { +		b.node = b.node.chain(node) +	} +} + +func (b *PathBuilder) addRecursiveNode(selector string) { +	node := newPathRecursiveNode(selector) +	if b.root == nil { +		b.root = node +		b.node = node +	} else { +		b.node = b.node.chain(node) +	} +} + +func (b *PathBuilder) addSelectorNode(name string) { +	node := newPathSelectorNode(name) +	if b.root == nil { +		b.root = node +		b.node = node +	} else { +		b.node = b.node.chain(node) +	} +} + +func (b *PathBuilder) addIndexNode(idx int) { +	node := newPathIndexNode(idx) +	if b.root == nil { +		b.root = node +		b.node = node +	} else { +		b.node = b.node.chain(node) +	} +} + +type QuotePathSelector int + +const ( +	SingleQuotePathSelector QuotePathSelector = 1 +	DoubleQuotePathSelector QuotePathSelector = 2 +) + +type Path struct { +	node                    PathNode +	RootSelectorOnly        bool +	SingleQuotePathSelector bool +	DoubleQuotePathSelector bool +} + +func (p *Path) Field(sel string) (PathNode, bool, error) { +	if p.node == nil { +		return nil, false, nil +	} +	return p.node.Field(sel) +} + +func (p *Path) Get(src, dst reflect.Value) error { +	if p.node == nil { +		return nil +	} +	return p.node.Get(src, dst) +} + +func (p *Path) String() string { +	if p.node == nil { +		return "$" +	} +	return p.node.String() +} + +type PathNode interface { +	fmt.Stringer +	Index(idx int) (PathNode, bool, error) +	Field(fieldName string) (PathNode, bool, error) +	Get(src, dst reflect.Value) error +	chain(PathNode) PathNode +	target() bool +	single() bool +} + +type BasePathNode struct { +	child PathNode +} + +func (n *BasePathNode) chain(node PathNode) PathNode { +	n.child = node +	return node +} + +func (n *BasePathNode) target() bool { +	return n.child == nil +} + +func (n *BasePathNode) single() bool { +	return true +} + +type PathSelectorNode struct { +	*BasePathNode +	selector string +} + +func newPathSelectorNode(selector string) *PathSelectorNode { +	return &PathSelectorNode{ +		BasePathNode: &BasePathNode{}, +		selector:     selector, +	} +} + +func (n *PathSelectorNode) Index(idx int) (PathNode, bool, error) { +	return nil, false, &errors.PathError{} +} + +func (n *PathSelectorNode) Field(fieldName string) (PathNode, bool, error) { +	if n.selector == fieldName { +		return n.child, true, nil +	} +	return nil, false, nil +} + +func (n *PathSelectorNode) Get(src, dst reflect.Value) error { +	switch src.Type().Kind() { +	case reflect.Map: +		iter := src.MapRange() +		for iter.Next() { +			key, ok := iter.Key().Interface().(string) +			if !ok { +				return fmt.Errorf("invalid map key type %T", src.Type().Key()) +			} +			child, found, err := n.Field(key) +			if err != nil { +				return err +			} +			if found { +				if child != nil { +					return child.Get(iter.Value(), dst) +				} +				return AssignValue(iter.Value(), dst) +			} +		} +	case reflect.Struct: +		typ := src.Type() +		for i := 0; i < typ.Len(); i++ { +			tag := runtime.StructTagFromField(typ.Field(i)) +			child, found, err := n.Field(tag.Key) +			if err != nil { +				return err +			} +			if found { +				if child != nil { +					return child.Get(src.Field(i), dst) +				} +				return AssignValue(src.Field(i), dst) +			} +		} +	case reflect.Ptr: +		return n.Get(src.Elem(), dst) +	case reflect.Interface: +		return n.Get(reflect.ValueOf(src.Interface()), dst) +	case reflect.Float64, reflect.String, reflect.Bool: +		return AssignValue(src, dst) +	} +	return fmt.Errorf("failed to get %s value from %s", n.selector, src.Type()) +} + +func (n *PathSelectorNode) String() string { +	s := fmt.Sprintf(".%s", n.selector) +	if n.child != nil { +		s += n.child.String() +	} +	return s +} + +type PathIndexNode struct { +	*BasePathNode +	selector int +} + +func newPathIndexNode(selector int) *PathIndexNode { +	return &PathIndexNode{ +		BasePathNode: &BasePathNode{}, +		selector:     selector, +	} +} + +func (n *PathIndexNode) Index(idx int) (PathNode, bool, error) { +	if n.selector == idx { +		return n.child, true, nil +	} +	return nil, false, nil +} + +func (n *PathIndexNode) Field(fieldName string) (PathNode, bool, error) { +	return nil, false, &errors.PathError{} +} + +func (n *PathIndexNode) Get(src, dst reflect.Value) error { +	switch src.Type().Kind() { +	case reflect.Array, reflect.Slice: +		if src.Len() > n.selector { +			if n.child != nil { +				return n.child.Get(src.Index(n.selector), dst) +			} +			return AssignValue(src.Index(n.selector), dst) +		} +	case reflect.Ptr: +		return n.Get(src.Elem(), dst) +	case reflect.Interface: +		return n.Get(reflect.ValueOf(src.Interface()), dst) +	} +	return fmt.Errorf("failed to get [%d] value from %s", n.selector, src.Type()) +} + +func (n *PathIndexNode) String() string { +	s := fmt.Sprintf("[%d]", n.selector) +	if n.child != nil { +		s += n.child.String() +	} +	return s +} + +type PathIndexAllNode struct { +	*BasePathNode +} + +func newPathIndexAllNode() *PathIndexAllNode { +	return &PathIndexAllNode{ +		BasePathNode: &BasePathNode{}, +	} +} + +func (n *PathIndexAllNode) Index(idx int) (PathNode, bool, error) { +	return n.child, true, nil +} + +func (n *PathIndexAllNode) Field(fieldName string) (PathNode, bool, error) { +	return nil, false, &errors.PathError{} +} + +func (n *PathIndexAllNode) Get(src, dst reflect.Value) error { +	switch src.Type().Kind() { +	case reflect.Array, reflect.Slice: +		var arr []interface{} +		for i := 0; i < src.Len(); i++ { +			var v interface{} +			rv := reflect.ValueOf(&v) +			if n.child != nil { +				if err := n.child.Get(src.Index(i), rv); err != nil { +					return err +				} +			} else { +				if err := AssignValue(src.Index(i), rv); err != nil { +					return err +				} +			} +			arr = append(arr, v) +		} +		if err := AssignValue(reflect.ValueOf(arr), dst); err != nil { +			return err +		} +		return nil +	case reflect.Ptr: +		return n.Get(src.Elem(), dst) +	case reflect.Interface: +		return n.Get(reflect.ValueOf(src.Interface()), dst) +	} +	return fmt.Errorf("failed to get all value from %s", src.Type()) +} + +func (n *PathIndexAllNode) String() string { +	s := "[*]" +	if n.child != nil { +		s += n.child.String() +	} +	return s +} + +type PathRecursiveNode struct { +	*BasePathNode +	selector string +} + +func newPathRecursiveNode(selector string) *PathRecursiveNode { +	node := newPathSelectorNode(selector) +	return &PathRecursiveNode{ +		BasePathNode: &BasePathNode{ +			child: node, +		}, +		selector: selector, +	} +} + +func (n *PathRecursiveNode) Field(fieldName string) (PathNode, bool, error) { +	if n.selector == fieldName { +		return n.child, true, nil +	} +	return nil, false, nil +} + +func (n *PathRecursiveNode) Index(_ int) (PathNode, bool, error) { +	return n, true, nil +} + +func valueToSliceValue(v interface{}) []interface{} { +	rv := reflect.ValueOf(v) +	ret := []interface{}{} +	if rv.Type().Kind() == reflect.Slice || rv.Type().Kind() == reflect.Array { +		for i := 0; i < rv.Len(); i++ { +			ret = append(ret, rv.Index(i).Interface()) +		} +		return ret +	} +	return []interface{}{v} +} + +func (n *PathRecursiveNode) Get(src, dst reflect.Value) error { +	if n.child == nil { +		return fmt.Errorf("failed to get by recursive path ..%s", n.selector) +	} +	var arr []interface{} +	switch src.Type().Kind() { +	case reflect.Map: +		iter := src.MapRange() +		for iter.Next() { +			key, ok := iter.Key().Interface().(string) +			if !ok { +				return fmt.Errorf("invalid map key type %T", src.Type().Key()) +			} +			child, found, err := n.Field(key) +			if err != nil { +				return err +			} +			if found { +				var v interface{} +				rv := reflect.ValueOf(&v) +				_ = child.Get(iter.Value(), rv) +				arr = append(arr, valueToSliceValue(v)...) +			} else { +				var v interface{} +				rv := reflect.ValueOf(&v) +				_ = n.Get(iter.Value(), rv) +				if v != nil { +					arr = append(arr, valueToSliceValue(v)...) +				} +			} +		} +		_ = AssignValue(reflect.ValueOf(arr), dst) +		return nil +	case reflect.Struct: +		typ := src.Type() +		for i := 0; i < typ.Len(); i++ { +			tag := runtime.StructTagFromField(typ.Field(i)) +			child, found, err := n.Field(tag.Key) +			if err != nil { +				return err +			} +			if found { +				var v interface{} +				rv := reflect.ValueOf(&v) +				_ = child.Get(src.Field(i), rv) +				arr = append(arr, valueToSliceValue(v)...) +			} else { +				var v interface{} +				rv := reflect.ValueOf(&v) +				_ = n.Get(src.Field(i), rv) +				if v != nil { +					arr = append(arr, valueToSliceValue(v)...) +				} +			} +		} +		_ = AssignValue(reflect.ValueOf(arr), dst) +		return nil +	case reflect.Array, reflect.Slice: +		for i := 0; i < src.Len(); i++ { +			var v interface{} +			rv := reflect.ValueOf(&v) +			_ = n.Get(src.Index(i), rv) +			if v != nil { +				arr = append(arr, valueToSliceValue(v)...) +			} +		} +		_ = AssignValue(reflect.ValueOf(arr), dst) +		return nil +	case reflect.Ptr: +		return n.Get(src.Elem(), dst) +	case reflect.Interface: +		return n.Get(reflect.ValueOf(src.Interface()), dst) +	} +	return fmt.Errorf("failed to get %s value from %s", n.selector, src.Type()) +} + +func (n *PathRecursiveNode) String() string { +	s := fmt.Sprintf("..%s", n.selector) +	if n.child != nil { +		s += n.child.String() +	} +	return s +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/ptr.go b/vendor/github.com/goccy/go-json/internal/decoder/ptr.go index 2c83b9c44..de12e105c 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/ptr.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/ptr.go @@ -1,6 +1,7 @@  package decoder  import ( +	"fmt"  	"unsafe"  	"github.com/goccy/go-json/internal/runtime" @@ -34,6 +35,10 @@ func (d *ptrDecoder) contentDecoder() Decoder {  //go:linkname unsafe_New reflect.unsafe_New  func unsafe_New(*runtime.Type) unsafe.Pointer +func UnsafeNew(t *runtime.Type) unsafe.Pointer { +	return unsafe_New(t) +} +  func (d *ptrDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {  	if s.skipWhiteSpace() == nul {  		s.read() @@ -85,3 +90,7 @@ func (d *ptrDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.P  	cursor = c  	return cursor, nil  } + +func (d *ptrDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, fmt.Errorf("json: ptr decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/slice.go b/vendor/github.com/goccy/go-json/internal/decoder/slice.go index 85b6e1119..30a23e4b5 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/slice.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/slice.go @@ -299,3 +299,82 @@ func (d *sliceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe  		}  	}  } + +func (d *sliceDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	buf := ctx.Buf +	depth++ +	if depth > maxDecodeNestingDepth { +		return nil, 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) +	} + +	ret := [][]byte{} +	for { +		switch buf[cursor] { +		case ' ', '\n', '\t', '\r': +			cursor++ +			continue +		case 'n': +			if err := validateNull(buf, cursor); err != nil { +				return nil, 0, err +			} +			cursor += 4 +			return [][]byte{nullbytes}, cursor, nil +		case '[': +			cursor++ +			cursor = skipWhiteSpace(buf, cursor) +			if buf[cursor] == ']' { +				cursor++ +				return ret, cursor, nil +			} +			idx := 0 +			for { +				child, found, err := ctx.Option.Path.node.Index(idx) +				if err != nil { +					return nil, 0, err +				} +				if found { +					if child != nil { +						oldPath := ctx.Option.Path.node +						ctx.Option.Path.node = child +						paths, c, err := d.valueDecoder.DecodePath(ctx, cursor, depth) +						if err != nil { +							return nil, 0, err +						} +						ctx.Option.Path.node = oldPath +						ret = append(ret, paths...) +						cursor = c +					} else { +						start := cursor +						end, err := skipValue(buf, cursor, depth) +						if err != nil { +							return nil, 0, err +						} +						ret = append(ret, buf[start:end]) +						cursor = end +					} +				} else { +					c, err := skipValue(buf, cursor, depth) +					if err != nil { +						return nil, 0, err +					} +					cursor = c +				} +				cursor = skipWhiteSpace(buf, cursor) +				switch buf[cursor] { +				case ']': +					cursor++ +					return ret, cursor, nil +				case ',': +					idx++ +				default: +					return nil, 0, errors.ErrInvalidCharacter(buf[cursor], "slice", cursor) +				} +				cursor++ +			} +		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': +			return nil, 0, d.errNumber(cursor) +		default: +			return nil, 0, errors.ErrUnexpectedEndOfJSON("slice", cursor) +		} +	} +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/string.go b/vendor/github.com/goccy/go-json/internal/decoder/string.go index d07ad7101..32602c908 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/string.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/string.go @@ -60,6 +60,17 @@ func (d *stringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf  	return cursor, nil  } +func (d *stringDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	bytes, c, err := d.decodeByte(ctx.Buf, cursor) +	if err != nil { +		return nil, 0, err +	} +	if bytes == nil { +		return [][]byte{nullbytes}, c, nil +	} +	return [][]byte{bytes}, c, nil +} +  var (  	hexToInt = [256]int{  		'0': 0, diff --git a/vendor/github.com/goccy/go-json/internal/decoder/struct.go b/vendor/github.com/goccy/go-json/internal/decoder/struct.go index 2c6468045..6d3265489 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/struct.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/struct.go @@ -817,3 +817,7 @@ func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsaf  		cursor++  	}  } + +func (d *structDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, fmt.Errorf("json: struct decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/type.go b/vendor/github.com/goccy/go-json/internal/decoder/type.go index 70e9907c8..beaf3ab86 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/type.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/type.go @@ -10,6 +10,7 @@ import (  type Decoder interface {  	Decode(*RuntimeContext, int64, int64, unsafe.Pointer) (int64, error) +	DecodePath(*RuntimeContext, int64, int64) ([][]byte, int64, error)  	DecodeStream(*Stream, int64, unsafe.Pointer) error  } diff --git a/vendor/github.com/goccy/go-json/internal/decoder/uint.go b/vendor/github.com/goccy/go-json/internal/decoder/uint.go index a62c51492..4131731b8 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/uint.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/uint.go @@ -188,3 +188,7 @@ func (d *uintDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.  	d.op(p, u64)  	return cursor, nil  } + +func (d *uintDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, fmt.Errorf("json: uint decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go index e9b25c68f..4cd6dbd57 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go @@ -3,6 +3,7 @@ package decoder  import (  	"context"  	"encoding/json" +	"fmt"  	"unsafe"  	"github.com/goccy/go-json/internal/errors" @@ -97,3 +98,7 @@ func (d *unmarshalJSONDecoder) Decode(ctx *RuntimeContext, cursor, depth int64,  	}  	return end, nil  } + +func (d *unmarshalJSONDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, fmt.Errorf("json: unmarshal json decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go index 1ef287782..6d37993f0 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go @@ -3,6 +3,7 @@ package decoder  import (  	"bytes"  	"encoding" +	"fmt"  	"unicode"  	"unicode/utf16"  	"unicode/utf8" @@ -142,6 +143,10 @@ func (d *unmarshalTextDecoder) Decode(ctx *RuntimeContext, cursor, depth int64,  	return end, nil  } +func (d *unmarshalTextDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, fmt.Errorf("json: unmarshal text decoder does not support decode path") +} +  func unquoteBytes(s []byte) (t []byte, ok bool) {  	length := len(s)  	if length < 2 || s[0] != '"' || s[length-1] != '"' { diff --git a/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go b/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go index 66227ae02..0c4e2e6ea 100644 --- a/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go +++ b/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go @@ -1,6 +1,7 @@  package decoder  import ( +	"fmt"  	"reflect"  	"unsafe" @@ -66,3 +67,7 @@ func (d *wrappedStringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64,  	ctx.Buf = oldBuf  	return c, nil  } + +func (d *wrappedStringDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { +	return nil, 0, fmt.Errorf("json: wrapped string decoder does not support decode path") +}  | 
