package json

import (
	
	
	
	
	

	
	
	
)

type Decoder struct {
	s *decoder.Stream
}

const (
	nul = '\000'
)

type emptyInterface struct {
	typ *runtime.Type
	ptr unsafe.Pointer
}

func unmarshal( []byte,  interface{},  ...DecodeOptionFunc) error {
	 := make([]byte, len()+1) // append nul byte to the end
	copy(, )

	 := (*emptyInterface)(unsafe.Pointer(&))

	if  := validateType(.typ, uintptr(.ptr));  != nil {
		return 
	}
	,  := decoder.CompileToGetDecoder(.typ)
	if  != nil {
		return 
	}
	 := decoder.TakeRuntimeContext()
	.Buf = 
	.Option.Flags = 0
	for ,  := range  {
		(.Option)
	}
	,  := .Decode(, 0, 0, .ptr)
	if  != nil {
		decoder.ReleaseRuntimeContext()
		return 
	}
	decoder.ReleaseRuntimeContext()
	return validateEndBuf(, )
}

func unmarshalContext( context.Context,  []byte,  interface{},  ...DecodeOptionFunc) error {
	 := make([]byte, len()+1) // append nul byte to the end
	copy(, )

	 := (*emptyInterface)(unsafe.Pointer(&))

	if  := validateType(.typ, uintptr(.ptr));  != nil {
		return 
	}
	,  := decoder.CompileToGetDecoder(.typ)
	if  != nil {
		return 
	}
	 := decoder.TakeRuntimeContext()
	.Buf = 
	.Option.Flags = 0
	.Option.Flags |= decoder.ContextOption
	.Option.Context = 
	for ,  := range  {
		(.Option)
	}
	,  := .Decode(, 0, 0, .ptr)
	if  != nil {
		decoder.ReleaseRuntimeContext()
		return 
	}
	decoder.ReleaseRuntimeContext()
	return validateEndBuf(, )
}

var (
	pathDecoder = decoder.NewPathDecoder()
)

func extractFromPath( *Path,  []byte,  ...DecodeOptionFunc) ([][]byte, error) {
	if .path.RootSelectorOnly {
		return [][]byte{}, nil
	}
	 := make([]byte, len()+1) // append nul byte to the end
	copy(, )

	 := decoder.TakeRuntimeContext()
	.Buf = 
	.Option.Flags = 0
	.Option.Flags |= decoder.PathOption
	.Option.Path = .path
	for ,  := range  {
		(.Option)
	}
	, ,  := pathDecoder.DecodePath(, 0, 0)
	if  != nil {
		decoder.ReleaseRuntimeContext()
		return nil, 
	}
	decoder.ReleaseRuntimeContext()
	if  := validateEndBuf(, );  != nil {
		return nil, 
	}
	return , nil
}

func unmarshalNoEscape( []byte,  interface{},  ...DecodeOptionFunc) error {
	 := make([]byte, len()+1) // append nul byte to the end
	copy(, )

	 := (*emptyInterface)(unsafe.Pointer(&))

	if  := validateType(.typ, uintptr(.ptr));  != nil {
		return 
	}
	,  := decoder.CompileToGetDecoder(.typ)
	if  != nil {
		return 
	}

	 := decoder.TakeRuntimeContext()
	.Buf = 
	.Option.Flags = 0
	for ,  := range  {
		(.Option)
	}
	,  := .Decode(, 0, 0, noescape(.ptr))
	if  != nil {
		decoder.ReleaseRuntimeContext()
		return 
	}
	decoder.ReleaseRuntimeContext()
	return validateEndBuf(, )
}

func validateEndBuf( []byte,  int64) error {
	for {
		switch [] {
		case ' ', '\t', '\n', '\r':
			++
			continue
		case nul:
			return nil
		}
		return errors.ErrSyntax(
			fmt.Sprintf("invalid character '%c' after top-level value", []),
			+1,
		)
	}
}

//nolint:staticcheck
//go:nosplit
func noescape( unsafe.Pointer) unsafe.Pointer {
	 := uintptr()
	return unsafe.Pointer( ^ 0)
}

func validateType( *runtime.Type,  uintptr) error {
	if  == nil || .Kind() != reflect.Ptr ||  == 0 {
		return &InvalidUnmarshalError{Type: runtime.RType2Type()}
	}
	return nil
}

// NewDecoder returns a new decoder that reads from r.
//
// The decoder introduces its own buffering and may
// read data from r beyond the JSON values requested.
func ( io.Reader) *Decoder {
	 := decoder.NewStream()
	return &Decoder{
		s: ,
	}
}

// Buffered returns a reader of the data remaining in the Decoder's
// buffer. The reader is valid until the next call to Decode.
func ( *Decoder) () io.Reader {
	return .s.Buffered()
}

// Decode reads the next JSON-encoded value from its
// input and stores it in the value pointed to by v.
//
// See the documentation for Unmarshal for details about
// the conversion of JSON into a Go value.
func ( *Decoder) ( interface{}) error {
	return .DecodeWithOption()
}

// DecodeContext reads the next JSON-encoded value from its
// input and stores it in the value pointed to by v with context.Context.
func ( *Decoder) ( context.Context,  interface{}) error {
	.s.Option.Flags |= decoder.ContextOption
	.s.Option.Context = 
	return .DecodeWithOption()
}

func ( *Decoder) ( interface{},  ...DecodeOptionFunc) error {
	 := (*emptyInterface)(unsafe.Pointer(&))
	 := .typ
	 := uintptr(.ptr)
	 := uintptr(unsafe.Pointer())
	// noescape trick for header.typ ( reflect.*rtype )
	 := *(**runtime.Type)(unsafe.Pointer(&))

	if  := validateType(, );  != nil {
		return 
	}

	,  := decoder.CompileToGetDecoder()
	if  != nil {
		return 
	}
	if  := .s.PrepareForDecode();  != nil {
		return 
	}
	 := .s
	for ,  := range  {
		(.Option)
	}
	if  := .DecodeStream(, 0, .ptr);  != nil {
		return 
	}
	.Reset()
	return nil
}

func ( *Decoder) () bool {
	return .s.More()
}

func ( *Decoder) () (Token, error) {
	return .s.Token()
}

// DisallowUnknownFields causes the Decoder to return an error when the destination
// is a struct and the input contains object keys which do not match any
// non-ignored, exported fields in the destination.
func ( *Decoder) () {
	.s.DisallowUnknownFields = true
}

func ( *Decoder) () int64 {
	return .s.TotalOffset()
}

// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
// Number instead of as a float64.
func ( *Decoder) () {
	.s.UseNumber = true
}