func SetExtension(msg proto.Message, extd *desc.FieldDescriptor, val interface{}) error {
	if !extd.IsExtension() {
		return fmt.Errorf("given field %s is not an extension", extd.GetFullyQualifiedName())
	}
	if dm, ok := msg.(*Message); ok {
		return dm.TrySetField(extd, val)
	}
	md, err := desc.LoadMessageDescriptorForMessage(msg)
	if err != nil {
		return err
	}
	if err := checkField(extd, md); err != nil {
		return err
	}
	val, err = validFieldValue(extd, val)
	if err != nil {
		return err
	}
	var b codec.Buffer
	b.SetDeterministic(defaultDeterminism)
	if err := b.EncodeFieldValue(extd, val); err != nil {
		return err
	}
	proto.SetRawExtension(msg, extd.GetNumber(), b.Bytes())
	return nil
}
SetExtension sets the given extension value. If the given message is not a
dynamic message, the given extension may not be recognized (or may differ
from the compiled and linked in version of the extension. So in that case,
this function will serialize the given value to bytes and then use
proto.SetRawExtension to set the value.
package dynamic
import (
	"fmt"
	"github.com/golang/protobuf/proto"
	"github.com/jhump/protoreflect/codec"
	"github.com/jhump/protoreflect/desc"
)