package avro

import (
	
	
	
	
	
	

	
)

func createDecoderOfMap( *decoderContext,  *MapSchema,  reflect2.Type) ValDecoder {
	if .Kind() == reflect.Map {
		 := .(reflect2.MapType).Key()
		switch {
		case .Kind() == reflect.String:
			return decoderOfMap(, , )
		case .Implements(textUnmarshalerType):
			return decoderOfMapUnmarshaler(, , )
		}
	}

	return &errorDecoder{err: fmt.Errorf("avro: %s is unsupported for Avro %s", .String(), .Type())}
}

func createEncoderOfMap( *encoderContext,  *MapSchema,  reflect2.Type) ValEncoder {
	if .Kind() == reflect.Map {
		 := .(reflect2.MapType).Key()
		switch {
		case .Kind() == reflect.String:
			return encoderOfMap(, , )
		case .Implements(textMarshalerType):
			return encoderOfMapMarshaler(, , )
		}
	}

	return &errorEncoder{err: fmt.Errorf("avro: %s is unsupported for Avro %s", .String(), .Type())}
}

func decoderOfMap( *decoderContext,  *MapSchema,  reflect2.Type) ValDecoder {
	 := .(*reflect2.UnsafeMapType)
	 := decoderOfType(, .Values(), .Elem())

	return &mapDecoder{
		mapType:  ,
		elemType: .Elem(),
		decoder:  ,
	}
}

type mapDecoder struct {
	mapType  *reflect2.UnsafeMapType
	elemType reflect2.Type
	decoder  ValDecoder
}

func ( *mapDecoder) ( unsafe.Pointer,  *Reader) {
	if .mapType.UnsafeIsNil() {
		.mapType.UnsafeSet(, .mapType.UnsafeMakeMap(0))
	}

	for {
		,  := .ReadBlockHeader()
		if  == 0 {
			break
		}

		for range  {
			 := reflect2.PtrOf(.ReadString())
			 := .elemType.UnsafeNew()
			.decoder.Decode(, )
			if .Error != nil {
				.Error = fmt.Errorf("reading map[string]%s: %w", .elemType.String(), .Error)
				return
			}

			.mapType.UnsafeSetIndex(, , )
		}
	}

	if .Error != nil && !errors.Is(.Error, io.EOF) {
		.Error = fmt.Errorf("%v: %w", .mapType, .Error)
	}
}

func decoderOfMapUnmarshaler( *decoderContext,  *MapSchema,  reflect2.Type) ValDecoder {
	 := .(*reflect2.UnsafeMapType)
	 := decoderOfType(, .Values(), .Elem())

	return &mapDecoderUnmarshaler{
		mapType:  ,
		keyType:  .Key(),
		elemType: .Elem(),
		decoder:  ,
	}
}

type mapDecoderUnmarshaler struct {
	mapType  *reflect2.UnsafeMapType
	keyType  reflect2.Type
	elemType reflect2.Type
	decoder  ValDecoder
}

func ( *mapDecoderUnmarshaler) ( unsafe.Pointer,  *Reader) {
	if .mapType.UnsafeIsNil() {
		.mapType.UnsafeSet(, .mapType.UnsafeMakeMap(0))
	}

	for {
		,  := .ReadBlockHeader()
		if  == 0 {
			break
		}

		for range  {
			 := .keyType.UnsafeNew()
			 := .keyType.UnsafeIndirect()
			if reflect2.IsNil() {
				 := .keyType.(*reflect2.UnsafePtrType)
				 := .Elem().UnsafeNew()
				*((*unsafe.Pointer)()) = 
				 = .keyType.UnsafeIndirect()
			}
			 := .(encoding.TextUnmarshaler)
			 := .UnmarshalText([]byte(.ReadString()))
			if  != nil {
				.ReportError("mapDecoderUnmarshaler", .Error())
				return
			}

			 := .elemType.UnsafeNew()
			.decoder.Decode(, )

			.mapType.UnsafeSetIndex(, , )
		}
	}

	if .Error != nil && !errors.Is(.Error, io.EOF) {
		.Error = fmt.Errorf("%v: %w", .mapType, .Error)
	}
}

func encoderOfMap( *encoderContext,  *MapSchema,  reflect2.Type) ValEncoder {
	 := .(*reflect2.UnsafeMapType)
	 := encoderOfType(, .Values(), .Elem())

	return &mapEncoder{
		blockLength: .cfg.getBlockLength(),
		mapType:     ,
		encoder:     ,
	}
}

type mapEncoder struct {
	blockLength int
	mapType     *reflect2.UnsafeMapType
	encoder     ValEncoder
}

func ( *mapEncoder) ( unsafe.Pointer,  *Writer) {
	 := .blockLength

	 := .mapType.UnsafeIterate()

	for {
		 := .WriteBlockCB(func( *Writer) int64 {
			var  int
			for  = 0; .HasNext() &&  < ; ++ {
				,  := .UnsafeNext()
				.WriteString(*((*string)()))
				.encoder.Encode(, )
			}

			return int64()
		})

		if  == 0 {
			break
		}
	}

	if .Error != nil && !errors.Is(.Error, io.EOF) {
		.Error = fmt.Errorf("%v: %w", .mapType, .Error)
	}
}

func encoderOfMapMarshaler( *encoderContext,  *MapSchema,  reflect2.Type) ValEncoder {
	 := .(*reflect2.UnsafeMapType)
	 := encoderOfType(, .Values(), .Elem())

	return &mapEncoderMarshaller{
		blockLength: .cfg.getBlockLength(),
		mapType:     ,
		keyType:     .Key(),
		encoder:     ,
	}
}

type mapEncoderMarshaller struct {
	blockLength int
	mapType     *reflect2.UnsafeMapType
	keyType     reflect2.Type
	encoder     ValEncoder
}

func ( *mapEncoderMarshaller) ( unsafe.Pointer,  *Writer) {
	 := .blockLength

	 := .mapType.UnsafeIterate()

	for {
		 := .WriteBlockCB(func( *Writer) int64 {
			var  int
			for  = 0; .HasNext() &&  < ; ++ {
				,  := .UnsafeNext()

				 := .keyType.UnsafeIndirect()
				if .keyType.IsNullable() && reflect2.IsNil() {
					.Error = errors.New("avro: mapEncoderMarshaller: encoding nil TextMarshaller")
					return int64(0)
				}
				 := ().(encoding.TextMarshaler)
				,  := .MarshalText()
				if  != nil {
					.Error = 
					return int64(0)
				}
				.WriteString(string())

				.encoder.Encode(, )
			}
			return int64()
		})

		if  == 0 {
			break
		}
	}

	if .Error != nil && !errors.Is(.Error, io.EOF) {
		.Error = fmt.Errorf("%v: %w", .mapType, .Error)
	}
}