package pgtype

import (
	
	
	
	
	

	
)

type CompositeTypeField struct {
	Name string
	OID  uint32
}

type CompositeType struct {
	status Status

	typeName string

	fields           []CompositeTypeField
	valueTranscoders []ValueTranscoder
}
NewCompositeType creates a CompositeType from fields and ci. ci is used to find the ValueTranscoders used for fields. All field OIDs must be previously registered in ci.
func ( string,  []CompositeTypeField,  *ConnInfo) (*CompositeType, error) {
	 := make([]ValueTranscoder, len())

	for  := range  {
		,  := .DataTypeForOID([].OID)
		if ! {
			return nil, fmt.Errorf("no data type registered for oid: %d", [].OID)
		}

		 := NewValue(.Value)
		,  := .(ValueTranscoder)
		if ! {
			return nil, fmt.Errorf("data type for oid does not implement ValueTranscoder: %d", [].OID)
		}

		[] = 
	}

	return &CompositeType{typeName: , fields: , valueTranscoders: }, nil
}
NewCompositeTypeValues creates a CompositeType from fields and values. fields and values must have the same length. Prefer NewCompositeType unless overriding the transcoding of fields is required.
func ( string,  []CompositeTypeField,  []ValueTranscoder) (*CompositeType, error) {
	if len() != len() {
		return nil, errors.New("fields and valueTranscoders must have same length")
	}

	return &CompositeType{typeName: , fields: , valueTranscoders: }, nil
}

func ( CompositeType) () interface{} {
	switch .status {
	case Present:
		 := make(map[string]interface{}, len(.valueTranscoders))
		for  := range .valueTranscoders {
			[.fields[].Name] = .valueTranscoders[].Get()
		}
		return 
	case Null:
		return nil
	default:
		return .status
	}
}

func ( *CompositeType) () Value {
	 := &CompositeType{
		typeName:         .typeName,
		fields:           .fields,
		valueTranscoders: make([]ValueTranscoder, len(.valueTranscoders)),
	}

	for  := range .valueTranscoders {
		.valueTranscoders[] = NewValue(.valueTranscoders[]).(ValueTranscoder)
	}

	return 
}

func ( *CompositeType) () string {
	return .typeName
}

func ( *CompositeType) () []CompositeTypeField {
	return .fields
}

func ( *CompositeType) ( interface{}) error {
	if  == nil {
		.status = Null
		return nil
	}

	switch value := .(type) {
	case []interface{}:
		if len() != len(.valueTranscoders) {
			return fmt.Errorf("Number of fields don't match. CompositeType has %d fields", len(.valueTranscoders))
		}
		for ,  := range  {
			if  := .valueTranscoders[].Set();  != nil {
				return 
			}
		}
		.status = Present
	case *[]interface{}:
		if  == nil {
			.status = Null
			return nil
		}
		return .(*)
	default:
		return fmt.Errorf("Can not convert %v to Composite", )
	}

	return nil
}
AssignTo should never be called on composite value directly
func ( CompositeType) ( interface{}) error {
	switch .status {
	case Present:
		switch v := .(type) {
		case []interface{}:
			if len() != len(.valueTranscoders) {
				return fmt.Errorf("Number of fields don't match. CompositeType has %d fields", len(.valueTranscoders))
			}
			for  := range .valueTranscoders {
				if [] == nil {
					continue
				}

				 := assignToOrSet(.valueTranscoders[], [])
				if  != nil {
					return fmt.Errorf("unable to assign to dst[%d]: %v", , )
				}
			}
			return nil
		case *[]interface{}:
			return .(*)
		default:
			if ,  := .assignToPtrStruct();  {
				return 
			}

			if ,  := GetAssignToDstType();  {
				return .()
			}
			return fmt.Errorf("unable to assign to %T", )
		}
	case Null:
		return NullAssignTo()
	}
	return fmt.Errorf("cannot decode %#v into %T", , )
}

func ( Value,  interface{}) error {
	 := .AssignTo()
Try to use get / set instead -- this avoids every type having to be able to AssignTo type of self.
		 := false
		if ,  := .(Value);  {
			 := .Set(.Get())
			 =  == nil
		}
		if ! {
			return 
		}
	}

	return nil
}

func ( CompositeType) ( interface{}) (bool, error) {
	 := reflect.ValueOf()
	if .Kind() != reflect.Ptr {
		return false, nil
	}

	if .IsNil() {
		return false, nil
	}

	 := .Elem()
	 := .Type()

	if .Kind() != reflect.Struct {
		return false, nil
	}

	 := make([]int, 0, .NumField())
	for  := 0;  < .NumField(); ++ {
		 := .Field()
		if .PkgPath == "" {
			 = append(, )
		}
	}

	if len() != len(.valueTranscoders) {
		return false, nil
	}

	for  := range  {
		 := assignToOrSet(.valueTranscoders[], .Field([]).Addr().Interface())
		if  != nil {
			return true, fmt.Errorf("unable to assign to field %s: %v", .Field([]).Name, )
		}
	}

	return true, nil
}

func ( CompositeType) ( *ConnInfo,  []byte) ( []byte,  error) {
	switch .status {
	case Null:
		return nil, nil
	case Undefined:
		return nil, errUndefined
	}

	 := NewCompositeBinaryBuilder(, )
	for  := range .valueTranscoders {
		.AppendEncoder(.fields[].OID, .valueTranscoders[])
	}

	return .Finish()
}
DecodeBinary implements BinaryDecoder interface. Opposite to Record, fields in a composite act as a "schema" and decoding fails if SQL value can't be assigned due to type mismatch
func ( *CompositeType) ( *ConnInfo,  []byte) error {
	if  == nil {
		.status = Null
		return nil
	}

	 := NewCompositeBinaryScanner(, )

	for ,  := range .valueTranscoders {
		.ScanDecoder()
	}

	if .Err() != nil {
		return .Err()
	}

	.status = Present

	return nil
}

func ( *CompositeType) ( *ConnInfo,  []byte) error {
	if  == nil {
		.status = Null
		return nil
	}

	 := NewCompositeTextScanner(, )

	for ,  := range .valueTranscoders {
		.ScanDecoder()
	}

	if .Err() != nil {
		return .Err()
	}

	.status = Present

	return nil
}

func ( CompositeType) ( *ConnInfo,  []byte) ( []byte,  error) {
	switch .status {
	case Null:
		return nil, nil
	case Undefined:
		return nil, errUndefined
	}

	 := NewCompositeTextBuilder(, )
	for ,  := range .valueTranscoders {
		.AppendEncoder()
	}

	return .Finish()
}

type CompositeBinaryScanner struct {
	ci  *ConnInfo
	rp  int
	src []byte

	fieldCount int32
	fieldBytes []byte
	fieldOID   uint32
	err        error
}
NewCompositeBinaryScanner a scanner over a binary encoded composite balue.
func ( *ConnInfo,  []byte) *CompositeBinaryScanner {
	 := 0
	if len([:]) < 4 {
		return &CompositeBinaryScanner{err: fmt.Errorf("Record incomplete %v", )}
	}

	 := int32(binary.BigEndian.Uint32([:]))
	 += 4

	return &CompositeBinaryScanner{
		ci:         ,
		rp:         ,
		src:        ,
		fieldCount: ,
	}
}
ScanDecoder calls Next and decodes the result with d.
func ( *CompositeBinaryScanner) ( BinaryDecoder) {
	if .err != nil {
		return
	}

	if .Next() {
		.err = .DecodeBinary(.ci, .fieldBytes)
	} else {
		.err = errors.New("read past end of composite")
	}
}
ScanDecoder calls Next and scans the result into d.
func ( *CompositeBinaryScanner) ( interface{}) {
	if .err != nil {
		return
	}

	if .Next() {
		.err = .ci.Scan(.OID(), BinaryFormatCode, .Bytes(), )
	} else {
		.err = errors.New("read past end of composite")
	}
}
Next advances the scanner to the next field. It returns false after the last field is read or an error occurs. After Next returns false, the Err method can be called to check if any errors occurred.
func ( *CompositeBinaryScanner) () bool {
	if .err != nil {
		return false
	}

	if .rp == len(.src) {
		return false
	}

	if len(.src[.rp:]) < 8 {
		.err = fmt.Errorf("Record incomplete %v", .src)
		return false
	}
	.fieldOID = binary.BigEndian.Uint32(.src[.rp:])
	.rp += 4

	 := int(int32(binary.BigEndian.Uint32(.src[.rp:])))
	.rp += 4

	if  >= 0 {
		if len(.src[.rp:]) <  {
			.err = fmt.Errorf("Record incomplete rp=%d src=%v", .rp, .src)
			return false
		}
		.fieldBytes = .src[.rp : .rp+]
		.rp += 
	} else {
		.fieldBytes = nil
	}

	return true
}

func ( *CompositeBinaryScanner) () int {
	return int(.fieldCount)
}
Bytes returns the bytes of the field most recently read by Scan().
func ( *CompositeBinaryScanner) () []byte {
	return .fieldBytes
}
OID returns the OID of the field most recently read by Scan().
func ( *CompositeBinaryScanner) () uint32 {
	return .fieldOID
}
Err returns any error encountered by the scanner.
func ( *CompositeBinaryScanner) () error {
	return .err
}

type CompositeTextScanner struct {
	ci  *ConnInfo
	rp  int
	src []byte

	fieldBytes []byte
	err        error
}
NewCompositeTextScanner a scanner over a text encoded composite value.
func ( *ConnInfo,  []byte) *CompositeTextScanner {
	if len() < 2 {
		return &CompositeTextScanner{err: fmt.Errorf("Record incomplete %v", )}
	}

	if [0] != '(' {
		return &CompositeTextScanner{err: fmt.Errorf("composite text format must start with '('")}
	}

	if [len()-1] != ')' {
		return &CompositeTextScanner{err: fmt.Errorf("composite text format must end with ')'")}
	}

	return &CompositeTextScanner{
		ci:  ,
		rp:  1,
		src: ,
	}
}
ScanDecoder calls Next and decodes the result with d.
func ( *CompositeTextScanner) ( TextDecoder) {
	if .err != nil {
		return
	}

	if .Next() {
		.err = .DecodeText(.ci, .fieldBytes)
	} else {
		.err = errors.New("read past end of composite")
	}
}
ScanDecoder calls Next and scans the result into d.
func ( *CompositeTextScanner) ( interface{}) {
	if .err != nil {
		return
	}

	if .Next() {
		.err = .ci.Scan(0, TextFormatCode, .Bytes(), )
	} else {
		.err = errors.New("read past end of composite")
	}
}
Next advances the scanner to the next field. It returns false after the last field is read or an error occurs. After Next returns false, the Err method can be called to check if any errors occurred.
func ( *CompositeTextScanner) () bool {
	if .err != nil {
		return false
	}

	if .rp == len(.src) {
		return false
	}

	switch .src[.rp] {
	case ',', ')': // null
		.rp++
		.fieldBytes = nil
		return true
	case '"': // quoted value
		.rp++
		.fieldBytes = make([]byte, 0, 16)
		for {
			 := .src[.rp]

			if  == '"' {
				.rp++
				if .src[.rp] == '"' {
					.fieldBytes = append(.fieldBytes, '"')
					.rp++
				} else {
					break
				}
			} else {
				.fieldBytes = append(.fieldBytes, )
				.rp++
			}
		}
		.rp++
		return true
	default: // unquoted value
		 := .rp
		for {
			 := .src[.rp]
			if  == ',' ||  == ')' {
				break
			}
			.rp++
		}
		.fieldBytes = .src[:.rp]
		.rp++
		return true
	}
}
Bytes returns the bytes of the field most recently read by Scan().
func ( *CompositeTextScanner) () []byte {
	return .fieldBytes
}
Err returns any error encountered by the scanner.
func ( *CompositeTextScanner) () error {
	return .err
}

type CompositeBinaryBuilder struct {
	ci         *ConnInfo
	buf        []byte
	startIdx   int
	fieldCount uint32
	err        error
}

func ( *ConnInfo,  []byte) *CompositeBinaryBuilder {
	 := len()
	 = append(, 0, 0, 0, 0) // allocate room for number of fields
	return &CompositeBinaryBuilder{ci: , buf: , startIdx: }
}

func ( *CompositeBinaryBuilder) ( uint32,  interface{}) {
	if .err != nil {
		return
	}

	,  := .ci.DataTypeForOID()
	if ! {
		.err = fmt.Errorf("unknown data type for OID: %d", )
		return
	}

	 := .Value.Set()
	if  != nil {
		.err = 
		return
	}

	,  := .Value.(BinaryEncoder)
	if ! {
		.err = fmt.Errorf("unable to encode binary for OID: %d", )
		return
	}

	.AppendEncoder(, )
}

func ( *CompositeBinaryBuilder) ( uint32,  BinaryEncoder) {
	if .err != nil {
		return
	}

	.buf = pgio.AppendUint32(.buf, )
	 := len(.buf)
	.buf = pgio.AppendInt32(.buf, -1)
	,  := .EncodeBinary(.ci, .buf)
	if  != nil {
		.err = 
		return
	}
	if  != nil {
		binary.BigEndian.PutUint32([:], uint32(len()-len(.buf)))
		.buf = 
	}

	.fieldCount++
}

func ( *CompositeBinaryBuilder) () ([]byte, error) {
	if .err != nil {
		return nil, .err
	}

	binary.BigEndian.PutUint32(.buf[.startIdx:], .fieldCount)
	return .buf, nil
}

type CompositeTextBuilder struct {
	ci         *ConnInfo
	buf        []byte
	startIdx   int
	fieldCount uint32
	err        error
	fieldBuf   [32]byte
}

func ( *ConnInfo,  []byte) *CompositeTextBuilder {
	 = append(, '(') // allocate room for number of fields
	return &CompositeTextBuilder{ci: , buf: }
}

func ( *CompositeTextBuilder) ( interface{}) {
	if .err != nil {
		return
	}

	if  == nil {
		.buf = append(.buf, ',')
		return
	}

	,  := .ci.DataTypeForValue()
	if ! {
		.err = fmt.Errorf("unknown data type for field: %v", )
		return
	}

	 := .Value.Set()
	if  != nil {
		.err = 
		return
	}

	,  := .Value.(TextEncoder)
	if ! {
		.err = fmt.Errorf("unable to encode text for value: %v", )
		return
	}

	.AppendEncoder()
}

func ( *CompositeTextBuilder) ( TextEncoder) {
	if .err != nil {
		return
	}

	,  := .EncodeText(.ci, .fieldBuf[0:0])
	if  != nil {
		.err = 
		return
	}
	if  != nil {
		.buf = append(.buf, quoteCompositeFieldIfNeeded(string())...)
	}

	.buf = append(.buf, ',')
}

func ( *CompositeTextBuilder) () ([]byte, error) {
	if .err != nil {
		return nil, .err
	}

	.buf[len(.buf)-1] = ')'
	return .buf, nil
}

var quoteCompositeReplacer = strings.NewReplacer(`\`, `\\`, `"`, `\"`)

func ( string) string {
	return `"` + quoteCompositeReplacer.Replace() + `"`
}

func ( string) string {
	if  == "" || [0] == ' ' || [len()-1] == ' ' || strings.ContainsAny(, `(),"\`) {
		return quoteCompositeField()
	}
	return