package encoder

import (
	
	
	
	
	
	
	
	
	
	
	

	
	
)

func ( OpType) () bool {
	switch  {
	case OpStructHead:
		return true
	case OpStructHeadSlice:
		return true
	case OpStructHeadArray:
		return true
	case OpStructHeadMap:
		return true
	case OpStructHeadStruct:
		return true
	case OpStructHeadOmitEmpty:
		return true
	case OpStructHeadOmitEmptySlice:
		return true
	case OpStructHeadOmitEmptyArray:
		return true
	case OpStructHeadOmitEmptyMap:
		return true
	case OpStructHeadOmitEmptyStruct:
		return true
	case OpStructHeadSlicePtr:
		return true
	case OpStructHeadOmitEmptySlicePtr:
		return true
	case OpStructHeadArrayPtr:
		return true
	case OpStructHeadOmitEmptyArrayPtr:
		return true
	case OpStructHeadMapPtr:
		return true
	case OpStructHeadOmitEmptyMapPtr:
		return true
	}
	return false
}

func ( OpType) () bool {
	switch  {
	case OpStructField:
		return true
	case OpStructFieldSlice:
		return true
	case OpStructFieldArray:
		return true
	case OpStructFieldMap:
		return true
	case OpStructFieldStruct:
		return true
	case OpStructFieldOmitEmpty:
		return true
	case OpStructFieldOmitEmptySlice:
		return true
	case OpStructFieldOmitEmptyArray:
		return true
	case OpStructFieldOmitEmptyMap:
		return true
	case OpStructFieldOmitEmptyStruct:
		return true
	case OpStructFieldSlicePtr:
		return true
	case OpStructFieldOmitEmptySlicePtr:
		return true
	case OpStructFieldArrayPtr:
		return true
	case OpStructFieldOmitEmptyArrayPtr:
		return true
	case OpStructFieldMapPtr:
		return true
	case OpStructFieldOmitEmptyMapPtr:
		return true
	}
	return false
}

type OpcodeSet struct {
	Type                     *runtime.Type
	NoescapeKeyCode          *Opcode
	EscapeKeyCode            *Opcode
	InterfaceNoescapeKeyCode *Opcode
	InterfaceEscapeKeyCode   *Opcode
	CodeLength               int
	EndCode                  *Opcode
	Code                     Code
	QueryCache               map[string]*OpcodeSet
	cacheMu                  sync.RWMutex
}

func ( *OpcodeSet) ( string) *OpcodeSet {
	.cacheMu.RLock()
	 := .QueryCache[]
	.cacheMu.RUnlock()
	return 
}

func ( *OpcodeSet) ( string,  *OpcodeSet) {
	.cacheMu.Lock()
	.QueryCache[] = 
	.cacheMu.Unlock()
}

type CompiledCode struct {
	Code    *Opcode
	Linked  bool // whether recursive code already have linked
	CurLen  uintptr
	NextLen uintptr
}

const StartDetectingCyclesAfter = 1000

func ( uintptr,  uintptr) uintptr {
	 :=  + 
	return **(**uintptr)(unsafe.Pointer(&))
}

func ( uintptr,  uintptr,  uintptr) {
	 :=  + 
	**(**uintptr)(unsafe.Pointer(&)) = 
}

func ( uintptr,  uintptr,  int) uintptr {
	 :=  + 
	 := **(**uintptr)(unsafe.Pointer(&))
	if  == 0 {
		return 0
	}
	return PtrToPtr()
	/*
		for i := 0; i < ptrNum; i++ {
			if p == 0 {
				return p
			}
			p = PtrToPtr(p)
		}
		return p
	*/
}

func ( uintptr) uint64              { return **(**uint64)(unsafe.Pointer(&)) }
func ( uintptr) float32            { return **(**float32)(unsafe.Pointer(&)) }
func ( uintptr) float64            { return **(**float64)(unsafe.Pointer(&)) }
func ( uintptr) bool                  { return **(**bool)(unsafe.Pointer(&)) }
func ( uintptr) []byte               { return **(**[]byte)(unsafe.Pointer(&)) }
func ( uintptr) json.Number         { return **(**json.Number)(unsafe.Pointer(&)) }
func ( uintptr) string              { return **(**string)(unsafe.Pointer(&)) }
func ( uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&)) }
func ( uintptr) uintptr {
	return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&)))
}
func ( uintptr,  int) uintptr {
	for  := 0;  < ; ++ {
		if  == 0 {
			return 0
		}
		 = PtrToPtr()
	}
	return 
}

func ( uintptr) unsafe.Pointer {
	return *(*unsafe.Pointer)(unsafe.Pointer(&))
}
func ( *Opcode,  uintptr) interface{} {
	return *(*interface{})(unsafe.Pointer(&emptyInterface{
		typ: .Type,
		ptr: *(*unsafe.Pointer)(unsafe.Pointer(&)),
	}))
}

func ( *Opcode,  uintptr) *errors.UnsupportedValueError {
	 := *(*interface{})(unsafe.Pointer(&emptyInterface{
		typ: .Type,
		ptr: *(*unsafe.Pointer)(unsafe.Pointer(&)),
	}))
	return &errors.UnsupportedValueError{
		Value: reflect.ValueOf(),
		Str:   fmt.Sprintf("encountered a cycle via %s", .Type),
	}
}

func ( float64) *errors.UnsupportedValueError {
	return &errors.UnsupportedValueError{
		Value: reflect.ValueOf(),
		Str:   strconv.FormatFloat(, 'g', -1, 64),
	}
}

func ( *Opcode,  error) *errors.MarshalerError {
	return &errors.MarshalerError{
		Type: runtime.RType2Type(.Type),
		Err:  ,
	}
}

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

type MapItem struct {
	Key   []byte
	Value []byte
}

type Mapslice struct {
	Items []MapItem
}

func ( *Mapslice) () int {
	return len(.Items)
}

func ( *Mapslice) (,  int) bool {
	return bytes.Compare(.Items[].Key, .Items[].Key) < 0
}

func ( *Mapslice) (,  int) {
	.Items[], .Items[] = .Items[], .Items[]
}

//nolint:structcheck,unused
type mapIter struct {
	key         unsafe.Pointer
	elem        unsafe.Pointer
	t           unsafe.Pointer
	h           unsafe.Pointer
	buckets     unsafe.Pointer
	bptr        unsafe.Pointer
	overflow    unsafe.Pointer
	oldoverflow unsafe.Pointer
	startBucket uintptr
	offset      uint8
	wrapped     bool
	B           uint8
	i           uint8
	bucket      uintptr
	checkBucket uintptr
}

type MapContext struct {
	Start int
	First int
	Idx   int
	Slice *Mapslice
	Buf   []byte
	Len   int
	Iter  mapIter
}

var mapContextPool = sync.Pool{
	New: func() interface{} {
		return &MapContext{
			Slice: &Mapslice{},
		}
	},
}

func ( int,  bool) *MapContext {
	 := mapContextPool.Get().(*MapContext)
	if ! {
		if len(.Slice.Items) <  {
			.Slice.Items = make([]MapItem, )
		} else {
			.Slice.Items = .Slice.Items[:]
		}
	}
	.Buf = .Buf[:0]
	.Iter = mapIter{}
	.Idx = 0
	.Len = 
	return 
}

func ( *MapContext) {
	mapContextPool.Put()
}

//go:linkname MapIterInit runtime.mapiterinit
//go:noescape
func ( *runtime.Type,  unsafe.Pointer,  *mapIter)

//go:linkname MapIterKey reflect.mapiterkey
//go:noescape
func ( *mapIter) unsafe.Pointer

//go:linkname MapIterNext reflect.mapiternext
//go:noescape
func ( *mapIter)

//go:linkname MapLen reflect.maplen
//go:noescape
func ( unsafe.Pointer) int

func ( *RuntimeContext,  []byte,  []byte) []byte {
	if  == nil {
		return append(, `null`...)
	}
	 := base64.StdEncoding.EncodedLen(len())
	 = append(, '"')
	 := len()
	 := cap([:])
	var  []byte
	if  >  {
		 = [ : +]
	} else {
		 = make([]byte, )
	}
	base64.StdEncoding.Encode(, )
	return append(append(, ...), '"')
}

func ( *RuntimeContext,  []byte,  float32) []byte {
	 := float64()
	 := math.Abs()
	 := byte('f')
	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
	if  != 0 {
		 := float32()
		if  < 1e-6 ||  >= 1e21 {
			 = 'e'
		}
	}
	return strconv.AppendFloat(, , , -1, 32)
}

func ( *RuntimeContext,  []byte,  float64) []byte {
	 := math.Abs()
	 := byte('f')
	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
	if  != 0 {
		if  < 1e-6 ||  >= 1e21 {
			 = 'e'
		}
	}
	return strconv.AppendFloat(, , , -1, 64)
}

func ( *RuntimeContext,  []byte,  bool) []byte {
	if  {
		return append(, "true"...)
	}
	return append(, "false"...)
}

var (
	floatTable = [256]bool{
		'0': true,
		'1': true,
		'2': true,
		'3': true,
		'4': true,
		'5': true,
		'6': true,
		'7': true,
		'8': true,
		'9': true,
		'.': true,
		'e': true,
		'E': true,
		'+': true,
		'-': true,
	}
)

func ( *RuntimeContext,  []byte,  json.Number) ([]byte, error) {
	if len() == 0 {
		return append(, '0'), nil
	}
	for  := 0;  < len(); ++ {
		if !floatTable[[]] {
			return nil, fmt.Errorf("json: invalid number literal %q", )
		}
	}
	 = append(, ...)
	return , nil
}

func ( *RuntimeContext,  *Opcode,  []byte,  interface{}) ([]byte, error) {
	 := reflect.ValueOf() // convert by dynamic interface type
	if (.Flags & AddrForMarshalerFlags) != 0 {
		if .CanAddr() {
			 = .Addr()
		} else {
			 := reflect.New(.Type())
			.Elem().Set()
			 = 
		}
	}

	if .Kind() == reflect.Ptr && .IsNil() {
		return AppendNull(, ), nil
	}

	 = .Interface()
	var  []byte
	if (.Flags & MarshalerContextFlags) != 0 {
		,  := .(marshalerContext)
		if ! {
			return AppendNull(, ), nil
		}
		 := .Option.Context
		if .Option.Flag&FieldQueryOption != 0 {
			 = SetFieldQueryToContext(, .FieldQuery)
		}
		,  := .MarshalJSON()
		if  != nil {
			return nil, &errors.MarshalerError{Type: reflect.TypeOf(), Err: }
		}
		 = 
	} else {
		,  := .(json.Marshaler)
		if ! {
			return AppendNull(, ), nil
		}
		,  := .MarshalJSON()
		if  != nil {
			return nil, &errors.MarshalerError{Type: reflect.TypeOf(), Err: }
		}
		 = 
	}
	 := .MarshalBuf[:0]
	 = append(append(, ...), nul)
	,  := compact(, , (.Option.Flag&HTMLEscapeOption) != 0)
	if  != nil {
		return nil, &errors.MarshalerError{Type: reflect.TypeOf(), Err: }
	}
	.MarshalBuf = 
	return , nil
}

func ( *RuntimeContext,  *Opcode,  []byte,  interface{}) ([]byte, error) {
	 := reflect.ValueOf() // convert by dynamic interface type
	if (.Flags & AddrForMarshalerFlags) != 0 {
		if .CanAddr() {
			 = .Addr()
		} else {
			 := reflect.New(.Type())
			.Elem().Set()
			 = 
		}
	}
	 = .Interface()
	var  []byte
	if (.Flags & MarshalerContextFlags) != 0 {
		,  := .(marshalerContext)
		if ! {
			return AppendNull(, ), nil
		}
		,  := .MarshalJSON(.Option.Context)
		if  != nil {
			return nil, &errors.MarshalerError{Type: reflect.TypeOf(), Err: }
		}
		 = 
	} else {
		,  := .(json.Marshaler)
		if ! {
			return AppendNull(, ), nil
		}
		,  := .MarshalJSON()
		if  != nil {
			return nil, &errors.MarshalerError{Type: reflect.TypeOf(), Err: }
		}
		 = 
	}
	 := .MarshalBuf[:0]
	 = append(append(, ...), nul)
	,  := doIndent(
		,
		,
		string(.Prefix)+strings.Repeat(string(.IndentStr), int(.BaseIndent+.Indent)),
		string(.IndentStr),
		(.Option.Flag&HTMLEscapeOption) != 0,
	)
	if  != nil {
		return nil, &errors.MarshalerError{Type: reflect.TypeOf(), Err: }
	}
	.MarshalBuf = 
	return , nil
}

func ( *RuntimeContext,  *Opcode,  []byte,  interface{}) ([]byte, error) {
	 := reflect.ValueOf() // convert by dynamic interface type
	if (.Flags & AddrForMarshalerFlags) != 0 {
		if .CanAddr() {
			 = .Addr()
		} else {
			 := reflect.New(.Type())
			.Elem().Set()
			 = 
		}
	}
	 = .Interface()
	,  := .(encoding.TextMarshaler)
	if ! {
		return AppendNull(, ), nil
	}
	,  := .MarshalText()
	if  != nil {
		return nil, &errors.MarshalerError{Type: reflect.TypeOf(), Err: }
	}
	return AppendString(, , *(*string)(unsafe.Pointer(&))), nil
}

func ( *RuntimeContext,  *Opcode,  []byte,  interface{}) ([]byte, error) {
	 := reflect.ValueOf() // convert by dynamic interface type
	if (.Flags & AddrForMarshalerFlags) != 0 {
		if .CanAddr() {
			 = .Addr()
		} else {
			 := reflect.New(.Type())
			.Elem().Set()
			 = 
		}
	}
	 = .Interface()
	,  := .(encoding.TextMarshaler)
	if ! {
		return AppendNull(, ), nil
	}
	,  := .MarshalText()
	if  != nil {
		return nil, &errors.MarshalerError{Type: reflect.TypeOf(), Err: }
	}
	return AppendString(, , *(*string)(unsafe.Pointer(&))), nil
}

func ( *RuntimeContext,  []byte) []byte {
	return append(, "null"...)
}

func ( *RuntimeContext,  []byte) []byte {
	return append(, ',')
}

func ( *RuntimeContext,  []byte) []byte {
	return append(, ',', '\n')
}

func ( *RuntimeContext,  []byte) []byte {
	return append(, '}', ',')
}

func ( *RuntimeContext,  *Opcode,  []byte) []byte {
	 = append(, '\n')
	 = append(, .Prefix...)
	 := .BaseIndent + .Indent - 1
	for  := uint32(0);  < ; ++ {
		 = append(, .IndentStr...)
	}
	return append(, '}', ',', '\n')
}

func ( *RuntimeContext,  []byte,  uint32) []byte {
	 = append(, .Prefix...)
	 := .BaseIndent + 
	for  := uint32(0);  < ; ++ {
		 = append(, .IndentStr...)
	}
	return 
}

func ( interface{}) bool {
	 := reflect.ValueOf()
	switch .Kind() {
	case reflect.Bool:
		return !.Bool()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return .Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return .Uint() == 0
	case reflect.Float32, reflect.Float64:
		return math.Float64bits(.Float()) == 0
	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Func:
		return .IsNil()
	case reflect.Slice:
		return .IsNil() || .Len() == 0
	case reflect.String:
		return .Len() == 0
	}
	return false
}