// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package impl

import (
	
	

	
	
	
)

func ( protoreflect.FieldDescriptor,  reflect.Type) (*MessageInfo, pointerCoderFuncs) {
	 := getMessageInfo()
	if  == nil {
		panic(fmt.Sprintf("invalid field: %v: unsupported message type %v", .FullName(), ))
	}
	switch .Kind() {
	case protoreflect.MessageKind:
		return , pointerCoderFuncs{
			size:      sizeOpaqueMessage,
			marshal:   appendOpaqueMessage,
			unmarshal: consumeOpaqueMessage,
			isInit:    isInitOpaqueMessage,
			merge:     mergeOpaqueMessage,
		}
	case protoreflect.GroupKind:
		return , pointerCoderFuncs{
			size:      sizeOpaqueGroup,
			marshal:   appendOpaqueGroup,
			unmarshal: consumeOpaqueGroup,
			isInit:    isInitOpaqueMessage,
			merge:     mergeOpaqueMessage,
		}
	}
	panic("unexpected field kind")
}

func ( pointer,  *coderFieldInfo,  marshalOptions) ( int) {
	return protowire.SizeBytes(.mi.sizePointer(.AtomicGetPointer(), )) + .tagsize
}

func ( []byte,  pointer,  *coderFieldInfo,  marshalOptions) ([]byte, error) {
	 := .AtomicGetPointer()
	 := .mi.sizePointer(, )
	 = protowire.AppendVarint(, .wiretag)
	 = protowire.AppendVarint(, uint64())
	 := len()
	,  := .mi.marshalAppendPointer(, , )
	if  := len() - ;  !=  &&  == nil {
		return nil, errors.MismatchedSizeCalculation(, )
	}
	return , 
}

func ( []byte,  pointer,  protowire.Type,  *coderFieldInfo,  unmarshalOptions) ( unmarshalOutput,  error) {
	if  != protowire.BytesType {
		return , errUnknown
	}
	,  := protowire.ConsumeBytes()
	if  < 0 {
		return , errDecode
	}
	 := .AtomicGetPointer()
	if .IsNil() {
		 = .AtomicSetPointerIfNil(pointerOfValue(reflect.New(.mi.GoReflectType.Elem())))
	}
	,  := .mi.unmarshalPointer(, , 0, )
	if  != nil {
		return , 
	}
	.n = 
	.initialized = .initialized
	return , nil
}

func ( pointer,  *coderFieldInfo) error {
	 := .AtomicGetPointer()
	if .IsNil() {
		return nil
	}
	return .mi.checkInitializedPointer()
}

func (,  pointer,  *coderFieldInfo,  mergeOptions) {
	 := .AtomicGetPointer()
	if .IsNil() {
		 = .AtomicSetPointerIfNil(pointerOfValue(reflect.New(.mi.GoReflectType.Elem())))
	}
	.mi.mergePointer(, .AtomicGetPointer(), )
}

func ( pointer,  *coderFieldInfo,  marshalOptions) ( int) {
	return 2*.tagsize + .mi.sizePointer(.AtomicGetPointer(), )
}

func ( []byte,  pointer,  *coderFieldInfo,  marshalOptions) ([]byte, error) {
	 = protowire.AppendVarint(, .wiretag) // start group
	,  := .mi.marshalAppendPointer(, .AtomicGetPointer(), )
	 = protowire.AppendVarint(, .wiretag+1) // end group
	return , 
}

func ( []byte,  pointer,  protowire.Type,  *coderFieldInfo,  unmarshalOptions) ( unmarshalOutput,  error) {
	if  != protowire.StartGroupType {
		return , errUnknown
	}
	 := .AtomicGetPointer()
	if .IsNil() {
		 = .AtomicSetPointerIfNil(pointerOfValue(reflect.New(.mi.GoReflectType.Elem())))
	}
	,  := .mi.unmarshalPointer(, , .num, )
	return , 
}

func ( protoreflect.FieldDescriptor,  reflect.Type) (*MessageInfo, pointerCoderFuncs) {
	if .Kind() != reflect.Ptr || .Elem().Kind() != reflect.Slice {
		panic(fmt.Sprintf("invalid field: %v: unsupported type for opaque repeated message: %v", .FullName(), ))
	}
	 := .Elem().Elem() // *[]*T -> *T
	 := getMessageInfo()
	if  == nil {
		panic(fmt.Sprintf("invalid field: %v: unsupported message type %v", .FullName(), ))
	}
	switch .Kind() {
	case protoreflect.MessageKind:
		return , pointerCoderFuncs{
			size:      sizeOpaqueMessageSlice,
			marshal:   appendOpaqueMessageSlice,
			unmarshal: consumeOpaqueMessageSlice,
			isInit:    isInitOpaqueMessageSlice,
			merge:     mergeOpaqueMessageSlice,
		}
	case protoreflect.GroupKind:
		return , pointerCoderFuncs{
			size:      sizeOpaqueGroupSlice,
			marshal:   appendOpaqueGroupSlice,
			unmarshal: consumeOpaqueGroupSlice,
			isInit:    isInitOpaqueMessageSlice,
			merge:     mergeOpaqueMessageSlice,
		}
	}
	panic("unexpected field kind")
}

func ( pointer,  *coderFieldInfo,  marshalOptions) ( int) {
	 := .AtomicGetPointer().PointerSlice()
	 := 0
	for ,  := range  {
		 += protowire.SizeBytes(.mi.sizePointer(, )) + .tagsize
	}
	return 
}

func ( []byte,  pointer,  *coderFieldInfo,  marshalOptions) ([]byte, error) {
	 := .AtomicGetPointer().PointerSlice()
	var  error
	for ,  := range  {
		 = protowire.AppendVarint(, .wiretag)
		 := .mi.sizePointer(, )
		 = protowire.AppendVarint(, uint64())
		 := len()
		,  = .mi.marshalAppendPointer(, , )
		if  != nil {
			return , 
		}
		if  := len() - ;  !=  {
			return nil, errors.MismatchedSizeCalculation(, )
		}
	}
	return , nil
}

func ( []byte,  pointer,  protowire.Type,  *coderFieldInfo,  unmarshalOptions) ( unmarshalOutput,  error) {
	if  != protowire.BytesType {
		return , errUnknown
	}
	,  := protowire.ConsumeBytes()
	if  < 0 {
		return , errDecode
	}
	 := pointerOfValue(reflect.New(.mi.GoReflectType.Elem()))
	,  := .mi.unmarshalPointer(, , 0, )
	if  != nil {
		return , 
	}
	 := .AtomicGetPointer()
	if .IsNil() {
		 = .AtomicSetPointerIfNil(pointerOfValue(reflect.New(.ft.Elem())))
	}
	.AppendPointerSlice()
	.n = 
	.initialized = .initialized
	return , nil
}

func ( pointer,  *coderFieldInfo) error {
	 := .AtomicGetPointer()
	if .IsNil() {
		return nil
	}
	 := .PointerSlice()
	for ,  := range  {
		if  := .mi.checkInitializedPointer();  != nil {
			return 
		}
	}
	return nil
}

func (,  pointer,  *coderFieldInfo,  mergeOptions) {
	 := .AtomicGetPointer()
	if .IsNil() {
		 = .AtomicSetPointerIfNil(pointerOfValue(reflect.New(.ft.Elem())))
	}
	for ,  := range .AtomicGetPointer().PointerSlice() {
		 := pointerOfValue(reflect.New(.mi.GoReflectType.Elem()))
		.mi.mergePointer(, , )
		.AppendPointerSlice()
	}
}

func ( pointer,  *coderFieldInfo,  marshalOptions) ( int) {
	 := .AtomicGetPointer().PointerSlice()
	 := 0
	for ,  := range  {
		 += 2*.tagsize + .mi.sizePointer(, )
	}
	return 
}

func ( []byte,  pointer,  *coderFieldInfo,  marshalOptions) ([]byte, error) {
	 := .AtomicGetPointer().PointerSlice()
	var  error
	for ,  := range  {
		 = protowire.AppendVarint(, .wiretag) // start group
		,  = .mi.marshalAppendPointer(, , )
		if  != nil {
			return , 
		}
		 = protowire.AppendVarint(, .wiretag+1) // end group
	}
	return , nil
}

func ( []byte,  pointer,  protowire.Type,  *coderFieldInfo,  unmarshalOptions) ( unmarshalOutput,  error) {
	if  != protowire.StartGroupType {
		return , errUnknown
	}
	 := pointerOfValue(reflect.New(.mi.GoReflectType.Elem()))
	,  = .mi.unmarshalPointer(, , .num, )
	if  != nil {
		return , 
	}
	 := .AtomicGetPointer()
	if .IsNil() {
		 = .AtomicSetPointerIfNil(pointerOfValue(reflect.New(.ft.Elem())))
	}
	.AppendPointerSlice()
	return , 
}