package vm_indent

import (
	
	
	

	
	
)

const uintptrSize = 4 << (^uintptr(0) >> 63)

var (
	appendInt           = encoder.AppendInt
	appendUint          = encoder.AppendUint
	appendFloat32       = encoder.AppendFloat32
	appendFloat64       = encoder.AppendFloat64
	appendString        = encoder.AppendString
	appendByteSlice     = encoder.AppendByteSlice
	appendNumber        = encoder.AppendNumber
	appendStructEnd     = encoder.AppendStructEndIndent
	appendIndent        = encoder.AppendIndent
	errUnsupportedValue = encoder.ErrUnsupportedValue
	errUnsupportedFloat = encoder.ErrUnsupportedFloat
	mapiterinit         = encoder.MapIterInit
	mapiterkey          = encoder.MapIterKey
	mapitervalue        = encoder.MapIterValue
	mapiternext         = encoder.MapIterNext
	maplen              = encoder.MapLen
)

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

type nonEmptyInterface struct {
	itab *struct {
		ityp *runtime.Type // static interface type
		typ  *runtime.Type // dynamic concrete type
		// unused fields...
	}
	ptr unsafe.Pointer
}

func errUnimplementedOp( encoder.OpType) error {
	return fmt.Errorf("encoder (indent): opcode %s has not been implemented", )
}

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

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

func loadNPtr( uintptr,  uint32,  uint8) uintptr {
	 :=  + uintptr()
	 := **(**uintptr)(unsafe.Pointer(&))
	for  := uint8(0);  < ; ++ {
		if  == 0 {
			return 0
		}
		 = ptrToPtr()
	}
	return 
}

func ptrToUint64( uintptr,  uint8) uint64 {
	switch  {
	case 8:
		return (uint64)(**(**uint8)(unsafe.Pointer(&)))
	case 16:
		return (uint64)(**(**uint16)(unsafe.Pointer(&)))
	case 32:
		return (uint64)(**(**uint32)(unsafe.Pointer(&)))
	case 64:
		return **(**uint64)(unsafe.Pointer(&))
	}
	return 0
}
func ptrToFloat32( uintptr) float32            { return **(**float32)(unsafe.Pointer(&)) }
func ptrToFloat64( uintptr) float64            { return **(**float64)(unsafe.Pointer(&)) }
func ptrToBool( uintptr) bool                  { return **(**bool)(unsafe.Pointer(&)) }
func ptrToBytes( uintptr) []byte               { return **(**[]byte)(unsafe.Pointer(&)) }
func ptrToNumber( uintptr) json.Number         { return **(**json.Number)(unsafe.Pointer(&)) }
func ptrToString( uintptr) string              { return **(**string)(unsafe.Pointer(&)) }
func ptrToSlice( uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&)) }
func ptrToPtr( uintptr) uintptr {
	return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&)))
}
func ptrToNPtr( uintptr,  uint8) uintptr {
	for  := uint8(0);  < ; ++ {
		if  == 0 {
			return 0
		}
		 = ptrToPtr()
	}
	return 
}

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

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

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

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

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

func appendColon( *encoder.RuntimeContext,  []byte) []byte {
	return append([:len()-2], ':', ' ')
}

func appendMapKeyValue( *encoder.RuntimeContext,  *encoder.Opcode, , ,  []byte) []byte {
	 = appendIndent(, , .Indent+1)
	 = append(, ...)
	[len()-2] = ':'
	[len()-1] = ' '
	return append(, ...)
}

func appendMapEnd( *encoder.RuntimeContext,  *encoder.Opcode,  []byte) []byte {
	 = [:len()-2]
	 = append(, '\n')
	 = appendIndent(, , .Indent)
	return append(, '}', ',', '\n')
}

func appendArrayHead( *encoder.RuntimeContext,  *encoder.Opcode,  []byte) []byte {
	 = append(, '[', '\n')
	return appendIndent(, , .Indent+1)
}

func appendArrayEnd( *encoder.RuntimeContext,  *encoder.Opcode,  []byte) []byte {
	 = [:len()-2]
	 = append(, '\n')
	 = appendIndent(, , .Indent)
	return append(, ']', ',', '\n')
}

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

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

func appendObjectEnd( *encoder.RuntimeContext,  *encoder.Opcode,  []byte) []byte {
	 := len() - 1
	// replace comma to newline
	[-1] = '\n'
	 = appendIndent(, [:], .Indent)
	return append(, '}', ',', '\n')
}

func appendMarshalJSON( *encoder.RuntimeContext,  *encoder.Opcode,  []byte,  interface{}) ([]byte, error) {
	return encoder.AppendMarshalJSONIndent(, , , )
}

func appendMarshalText( *encoder.RuntimeContext,  *encoder.Opcode,  []byte,  interface{}) ([]byte, error) {
	return encoder.AppendMarshalTextIndent(, , , )
}

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

func appendStructKey( *encoder.RuntimeContext,  *encoder.Opcode,  []byte) []byte {
	 = appendIndent(, , .Indent)
	 = append(, .Key...)
	return append(, ' ')
}

func appendStructEndSkipLast( *encoder.RuntimeContext,  *encoder.Opcode,  []byte) []byte {
	 := len() - 1
	if [-1] == '{' {
		[] = '}'
	} else {
		if [] == '\n' {
			// to remove ',' and '\n' characters
			 = [:len()-2]
		}
		 = append(, '\n')
		 = appendIndent(, , .Indent-1)
		 = append(, '}')
	}
	return appendComma(, )
}

func restoreIndent( *encoder.RuntimeContext,  *encoder.Opcode,  uintptr) {
	.BaseIndent = uint32(load(, .Length))
}

func storeIndent( uintptr,  *encoder.Opcode,  uintptr) {
	store(, .Length, )
}

func appendArrayElemIndent( *encoder.RuntimeContext,  *encoder.Opcode,  []byte) []byte {
	return appendIndent(, , .Indent+1)
}

func appendMapKeyIndent( *encoder.RuntimeContext,  *encoder.Opcode,  []byte) []byte {
	return appendIndent(, , .Indent)
}