package jsoniter

import (
	
	
	

	
)

var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem()
var unmarshalerType = reflect2.TypeOfPtr((*json.Unmarshaler)(nil)).Elem()
var textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem()
var textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem()

func createDecoderOfMarshaler( *ctx,  reflect2.Type) ValDecoder {
	 := reflect2.PtrTo()
	if .Implements(unmarshalerType) {
		return &referenceDecoder{
			&unmarshalerDecoder{},
		}
	}
	if .Implements(textUnmarshalerType) {
		return &referenceDecoder{
			&textUnmarshalerDecoder{},
		}
	}
	return nil
}

func createEncoderOfMarshaler( *ctx,  reflect2.Type) ValEncoder {
	if  == marshalerType {
		 := createCheckIsEmpty(, )
		var  ValEncoder = &directMarshalerEncoder{
			checkIsEmpty: ,
		}
		return 
	}
	if .Implements(marshalerType) {
		 := createCheckIsEmpty(, )
		var  ValEncoder = &marshalerEncoder{
			valType:      ,
			checkIsEmpty: ,
		}
		return 
	}
	 := reflect2.PtrTo()
	if .prefix != "" && .Implements(marshalerType) {
		 := createCheckIsEmpty(, )
		var  ValEncoder = &marshalerEncoder{
			valType:      ,
			checkIsEmpty: ,
		}
		return &referenceEncoder{}
	}
	if  == textMarshalerType {
		 := createCheckIsEmpty(, )
		var  ValEncoder = &directTextMarshalerEncoder{
			checkIsEmpty:  ,
			stringEncoder: .EncoderOf(reflect2.TypeOf("")),
		}
		return 
	}
	if .Implements(textMarshalerType) {
		 := createCheckIsEmpty(, )
		var  ValEncoder = &textMarshalerEncoder{
			valType:       ,
			stringEncoder: .EncoderOf(reflect2.TypeOf("")),
			checkIsEmpty:  ,
		}
		return 
	}
	// if prefix is empty, the type is the root type
	if .prefix != "" && .Implements(textMarshalerType) {
		 := createCheckIsEmpty(, )
		var  ValEncoder = &textMarshalerEncoder{
			valType:       ,
			stringEncoder: .EncoderOf(reflect2.TypeOf("")),
			checkIsEmpty:  ,
		}
		return &referenceEncoder{}
	}
	return nil
}

type marshalerEncoder struct {
	checkIsEmpty checkIsEmpty
	valType      reflect2.Type
}

func ( *marshalerEncoder) ( unsafe.Pointer,  *Stream) {
	 := .valType.UnsafeIndirect()
	if .valType.IsNullable() && reflect2.IsNil() {
		.WriteNil()
		return
	}
	 := .(json.Marshaler)
	,  := .MarshalJSON()
	if  != nil {
		.Error = 
	} else {
		// html escape was already done by jsoniter
		// but the extra '\n' should be trimed
		 := len()
		if  > 0 && [-1] == '\n' {
			 = [:-1]
		}
		.Write()
	}
}

func ( *marshalerEncoder) ( unsafe.Pointer) bool {
	return .checkIsEmpty.IsEmpty()
}

type directMarshalerEncoder struct {
	checkIsEmpty checkIsEmpty
}

func ( *directMarshalerEncoder) ( unsafe.Pointer,  *Stream) {
	 := *(*json.Marshaler)()
	if  == nil {
		.WriteNil()
		return
	}
	,  := .MarshalJSON()
	if  != nil {
		.Error = 
	} else {
		.Write()
	}
}

func ( *directMarshalerEncoder) ( unsafe.Pointer) bool {
	return .checkIsEmpty.IsEmpty()
}

type textMarshalerEncoder struct {
	valType       reflect2.Type
	stringEncoder ValEncoder
	checkIsEmpty  checkIsEmpty
}

func ( *textMarshalerEncoder) ( unsafe.Pointer,  *Stream) {
	 := .valType.UnsafeIndirect()
	if .valType.IsNullable() && reflect2.IsNil() {
		.WriteNil()
		return
	}
	 := ().(encoding.TextMarshaler)
	,  := .MarshalText()
	if  != nil {
		.Error = 
	} else {
		 := string()
		.stringEncoder.Encode(unsafe.Pointer(&), )
	}
}

func ( *textMarshalerEncoder) ( unsafe.Pointer) bool {
	return .checkIsEmpty.IsEmpty()
}

type directTextMarshalerEncoder struct {
	stringEncoder ValEncoder
	checkIsEmpty  checkIsEmpty
}

func ( *directTextMarshalerEncoder) ( unsafe.Pointer,  *Stream) {
	 := *(*encoding.TextMarshaler)()
	if  == nil {
		.WriteNil()
		return
	}
	,  := .MarshalText()
	if  != nil {
		.Error = 
	} else {
		 := string()
		.stringEncoder.Encode(unsafe.Pointer(&), )
	}
}

func ( *directTextMarshalerEncoder) ( unsafe.Pointer) bool {
	return .checkIsEmpty.IsEmpty()
}

type unmarshalerDecoder struct {
	valType reflect2.Type
}

func ( *unmarshalerDecoder) ( unsafe.Pointer,  *Iterator) {
	 := .valType
	 := .UnsafeIndirect()
	 := .(json.Unmarshaler)
	.nextToken()
	.unreadByte() // skip spaces
	 := .SkipAndReturnBytes()
	 := .UnmarshalJSON()
	if  != nil {
		.ReportError("unmarshalerDecoder", .Error())
	}
}

type textUnmarshalerDecoder struct {
	valType reflect2.Type
}

func ( *textUnmarshalerDecoder) ( unsafe.Pointer,  *Iterator) {
	 := .valType
	 := .UnsafeIndirect()
	if reflect2.IsNil() {
		 := .(*reflect2.UnsafePtrType)
		 := .Elem()
		 := .UnsafeNew()
		.UnsafeSet(, unsafe.Pointer(&))
		 = .UnsafeIndirect()
	}
	 := ().(encoding.TextUnmarshaler)
	 := .ReadString()
	 := .UnmarshalText([]byte())
	if  != nil {
		.ReportError("textUnmarshalerDecoder", .Error())
	}
}