package jsoniter

import (
	
	
	
	
	
	
)

func decoderOfMap( *ctx,  reflect2.Type) ValDecoder {
	 := .(*reflect2.UnsafeMapType)
	 := decoderOfMapKey(.append("[mapKey]"), .Key())
	 := decoderOfType(.append("[mapElem]"), .Elem())
	return &mapDecoder{
		mapType:     ,
		keyType:     .Key(),
		elemType:    .Elem(),
		keyDecoder:  ,
		elemDecoder: ,
	}
}

func encoderOfMap( *ctx,  reflect2.Type) ValEncoder {
	 := .(*reflect2.UnsafeMapType)
	if .sortMapKeys {
		return &sortKeysMapEncoder{
			mapType:     ,
			keyEncoder:  encoderOfMapKey(.append("[mapKey]"), .Key()),
			elemEncoder: encoderOfType(.append("[mapElem]"), .Elem()),
		}
	}
	return &mapEncoder{
		mapType:     ,
		keyEncoder:  encoderOfMapKey(.append("[mapKey]"), .Key()),
		elemEncoder: encoderOfType(.append("[mapElem]"), .Elem()),
	}
}

func decoderOfMapKey( *ctx,  reflect2.Type) ValDecoder {
	 := .decoderExtension.CreateMapKeyDecoder()
	if  != nil {
		return 
	}
	for ,  := range .extraExtensions {
		 := .CreateMapKeyDecoder()
		if  != nil {
			return 
		}
	}

	 := reflect2.PtrTo()
	if .Implements(unmarshalerType) {
		return &referenceDecoder{
			&unmarshalerDecoder{
				valType: ,
			},
		}
	}
	if .Implements(unmarshalerType) {
		return &unmarshalerDecoder{
			valType: ,
		}
	}
	if .Implements(textUnmarshalerType) {
		return &referenceDecoder{
			&textUnmarshalerDecoder{
				valType: ,
			},
		}
	}
	if .Implements(textUnmarshalerType) {
		return &textUnmarshalerDecoder{
			valType: ,
		}
	}

	switch .Kind() {
	case reflect.String:
		return decoderOfType(, reflect2.DefaultTypeOfKind(reflect.String))
	case reflect.Bool,
		reflect.Uint8, reflect.Int8,
		reflect.Uint16, reflect.Int16,
		reflect.Uint32, reflect.Int32,
		reflect.Uint64, reflect.Int64,
		reflect.Uint, reflect.Int,
		reflect.Float32, reflect.Float64,
		reflect.Uintptr:
		 = reflect2.DefaultTypeOfKind(.Kind())
		return &numericMapKeyDecoder{decoderOfType(, )}
	default:
		return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", )}
	}
}

func encoderOfMapKey( *ctx,  reflect2.Type) ValEncoder {
	 := .encoderExtension.CreateMapKeyEncoder()
	if  != nil {
		return 
	}
	for ,  := range .extraExtensions {
		 := .CreateMapKeyEncoder()
		if  != nil {
			return 
		}
	}

	if  == textMarshalerType {
		return &directTextMarshalerEncoder{
			stringEncoder: .EncoderOf(reflect2.TypeOf("")),
		}
	}
	if .Implements(textMarshalerType) {
		return &textMarshalerEncoder{
			valType:       ,
			stringEncoder: .EncoderOf(reflect2.TypeOf("")),
		}
	}

	switch .Kind() {
	case reflect.String:
		return encoderOfType(, reflect2.DefaultTypeOfKind(reflect.String))
	case reflect.Bool,
		reflect.Uint8, reflect.Int8,
		reflect.Uint16, reflect.Int16,
		reflect.Uint32, reflect.Int32,
		reflect.Uint64, reflect.Int64,
		reflect.Uint, reflect.Int,
		reflect.Float32, reflect.Float64,
		reflect.Uintptr:
		 = reflect2.DefaultTypeOfKind(.Kind())
		return &numericMapKeyEncoder{encoderOfType(, )}
	default:
		if .Kind() == reflect.Interface {
			return &dynamicMapKeyEncoder{, }
		}
		return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", )}
	}
}

type mapDecoder struct {
	mapType     *reflect2.UnsafeMapType
	keyType     reflect2.Type
	elemType    reflect2.Type
	keyDecoder  ValDecoder
	elemDecoder ValDecoder
}

func ( *mapDecoder) ( unsafe.Pointer,  *Iterator) {
	 := .mapType
	 := .nextToken()
	if  == 'n' {
		.skipThreeBytes('u', 'l', 'l')
		*(*unsafe.Pointer)() = nil
		.UnsafeSet(, .UnsafeNew())
		return
	}
	if .UnsafeIsNil() {
		.UnsafeSet(, .UnsafeMakeMap(0))
	}
	if  != '{' {
		.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{}))
		return
	}
	 = .nextToken()
	if  == '}' {
		return
	}
	.unreadByte()
	 := .keyType.UnsafeNew()
	.keyDecoder.Decode(, )
	 = .nextToken()
	if  != ':' {
		.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{}))
		return
	}
	 := .elemType.UnsafeNew()
	.elemDecoder.Decode(, )
	.mapType.UnsafeSetIndex(, , )
	for  = .nextToken();  == ',';  = .nextToken() {
		 := .keyType.UnsafeNew()
		.keyDecoder.Decode(, )
		 = .nextToken()
		if  != ':' {
			.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{}))
			return
		}
		 := .elemType.UnsafeNew()
		.elemDecoder.Decode(, )
		.mapType.UnsafeSetIndex(, , )
	}
	if  != '}' {
		.ReportError("ReadMapCB", `expect }, but found `+string([]byte{}))
	}
}

type numericMapKeyDecoder struct {
	decoder ValDecoder
}

func ( *numericMapKeyDecoder) ( unsafe.Pointer,  *Iterator) {
	 := .nextToken()
	if  != '"' {
		.ReportError("ReadMapCB", `expect ", but found `+string([]byte{}))
		return
	}
	.decoder.Decode(, )
	 = .nextToken()
	if  != '"' {
		.ReportError("ReadMapCB", `expect ", but found `+string([]byte{}))
		return
	}
}

type numericMapKeyEncoder struct {
	encoder ValEncoder
}

func ( *numericMapKeyEncoder) ( unsafe.Pointer,  *Stream) {
	.writeByte('"')
	.encoder.Encode(, )
	.writeByte('"')
}

func ( *numericMapKeyEncoder) ( unsafe.Pointer) bool {
	return false
}

type dynamicMapKeyEncoder struct {
	ctx     *ctx
	valType reflect2.Type
}

func ( *dynamicMapKeyEncoder) ( unsafe.Pointer,  *Stream) {
	 := .valType.UnsafeIndirect()
	encoderOfMapKey(.ctx, reflect2.TypeOf()).Encode(reflect2.PtrOf(), )
}

func ( *dynamicMapKeyEncoder) ( unsafe.Pointer) bool {
	 := .valType.UnsafeIndirect()
	return encoderOfMapKey(.ctx, reflect2.TypeOf()).IsEmpty(reflect2.PtrOf())
}

type mapEncoder struct {
	mapType     *reflect2.UnsafeMapType
	keyEncoder  ValEncoder
	elemEncoder ValEncoder
}

func ( *mapEncoder) ( unsafe.Pointer,  *Stream) {
	if *(*unsafe.Pointer)() == nil {
		.WriteNil()
		return
	}
	.WriteObjectStart()
	 := .mapType.UnsafeIterate()
	for  := 0; .HasNext(); ++ {
		if  != 0 {
			.WriteMore()
		}
		,  := .UnsafeNext()
		.keyEncoder.Encode(, )
		if .indention > 0 {
			.writeTwoBytes(byte(':'), byte(' '))
		} else {
			.writeByte(':')
		}
		.elemEncoder.Encode(, )
	}
	.WriteObjectEnd()
}

func ( *mapEncoder) ( unsafe.Pointer) bool {
	 := .mapType.UnsafeIterate()
	return !.HasNext()
}

type sortKeysMapEncoder struct {
	mapType     *reflect2.UnsafeMapType
	keyEncoder  ValEncoder
	elemEncoder ValEncoder
}

func ( *sortKeysMapEncoder) ( unsafe.Pointer,  *Stream) {
	if *(*unsafe.Pointer)() == nil {
		.WriteNil()
		return
	}
	.WriteObjectStart()
	 := .mapType.UnsafeIterate()
	 := .cfg.BorrowStream(nil)
	.Attachment = .Attachment
	 := .cfg.BorrowIterator(nil)
	 := encodedKeyValues{}
	for .HasNext() {
		,  := .UnsafeNext()
		 := .Buffered()
		.keyEncoder.Encode(, )
		if .Error != nil && .Error != io.EOF && .Error == nil {
			.Error = .Error
		}
		 := .Buffer()[:]
		.ResetBytes()
		 := .ReadString()
		if .indention > 0 {
			.writeTwoBytes(byte(':'), byte(' '))
		} else {
			.writeByte(':')
		}
		.elemEncoder.Encode(, )
		 = append(, encodedKV{
			key:      ,
			keyValue: .Buffer()[:],
		})
	}
	sort.Sort()
	for ,  := range  {
		if  != 0 {
			.WriteMore()
		}
		.Write(.keyValue)
	}
	if .Error != nil && .Error == nil {
		.Error = .Error
	}
	.WriteObjectEnd()
	.cfg.ReturnStream()
	.cfg.ReturnIterator()
}

func ( *sortKeysMapEncoder) ( unsafe.Pointer) bool {
	 := .mapType.UnsafeIterate()
	return !.HasNext()
}

type encodedKeyValues []encodedKV

type encodedKV struct {
	key      string
	keyValue []byte
}

func ( encodedKeyValues) () int           { return len() }
func ( encodedKeyValues) (,  int)      { [], [] = [], [] }
func ( encodedKeyValues) (,  int) bool { return [].key < [].key }