func (m DIDCommMsgMap) SetID(id string, opts ...Opt) {
	if m == nil {
		return
	}
	o := getOptions(opts...)
	if o.V == V2 {
		m[jsonIDV2] = id
		return
	}
	m[jsonIDV1] = id
}
SetID sets the message id.
package service
import (
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"reflect"
	"strings"
	"time"
	"github.com/mitchellh/mapstructure"
	"github.com/hyperledger/aries-framework-go/pkg/doc/did"
)
const (
	jsonIDV1           = "@id"
	jsonIDV2           = "id"
	jsonTypeV1         = "@type"
	jsonTypeV2         = "type"
	jsonThread         = "~thread"
	jsonThreadID       = "thid"
	jsonParentThreadID = "pthid"
	jsonMetadata       = "_internal_metadata"
	basePIURI = "https://didcomm.org/"
	oldPIURI  = "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/"
)
type Version string
const (
	V1 Version = "v1"
	V2 Version = "v2"
)
type Metadata struct {
	Payload map[string]interface{} `json:"_internal_metadata,omitempty"`
}
type DIDCommMsgMap map[string]interface{}
func (m *DIDCommMsgMap) UnmarshalJSON(b []byte) error {
	defer func() {
		if (*m) != nil {
			(*m)[jsonMetadata] = map[string]interface{}{}
		}
	}()
	return json.Unmarshal(b, (*map[string]interface{})(m))
}
func (m DIDCommMsgMap) MarshalJSON() ([]byte, error) {
	if m != nil {
		metadata := m[jsonMetadata]
		delete(m, jsonMetadata)
		defer func() { m[jsonMetadata] = metadata }()
	}
	return json.Marshal(map[string]interface{}(m))
}
func ParseDIDCommMsgMap(payload []byte) (DIDCommMsgMap, error) {
	var msg DIDCommMsgMap
	err := json.Unmarshal(payload, &msg)
	if err != nil {
		return nil, fmt.Errorf("invalid payload data format: %w", err)
	}
	_, ok := msg[jsonTypeV1]
	if typ := msg.Type(); typ != "" && ok {
		msg[jsonTypeV1] = strings.Replace(typ, oldPIURI, basePIURI, 1)
	}
	return msg, nil
}
func NewDIDCommMsgMap(v interface{}) DIDCommMsgMap {
	msg := toMap(v)
	msg[jsonMetadata] = map[string]interface{}{}
	return msg
}
func (m DIDCommMsgMap) ThreadID() (string, error) {
	if m == nil {
		return "", ErrInvalidMessage
	}
	thid, err := m.threadIDV1()
	if err == nil || !errors.Is(err, ErrThreadIDNotFound) {
		return thid, err
	}
	return m.threadIDV2()
}
func (m DIDCommMsgMap) threadIDV2() (string, error) {
	id := m.idV2()
	threadID, ok := m[jsonThreadID].(string)
	if ok && threadID != "" {
		if id == "" {
			return "", ErrInvalidMessage
		}
		return threadID, nil
	}
	if id != "" {
		return id, nil
	}
	return "", ErrThreadIDNotFound
}
func (m DIDCommMsgMap) threadIDV1() (string, error) {
	msgID := m.idV1()
	thread, ok := m[jsonThread].(map[string]interface{})
	if ok && thread[jsonThreadID] != nil {
		var thID string
		if v, ok := thread[jsonThreadID].(string); ok {
			thID = v
		}
		if len(thID) > 0 && msgID == "" {
			return "", ErrInvalidMessage
		}
		if len(thID) > 0 {
			return thID, nil
		}
	}
	if len(msgID) > 0 {
		return msgID, nil
	}
	return "", ErrThreadIDNotFound
}
func (m DIDCommMsgMap) Metadata() map[string]interface{} {
	if m[jsonMetadata] == nil {
		return nil
	}
	metadata, ok := m[jsonMetadata].(map[string]interface{})
	if !ok {
		return nil
	}
	return metadata
}
func (m DIDCommMsgMap) typeV1() string {
	if m == nil || m[jsonTypeV1] == nil {
		return ""
	}
	res, ok := m[jsonTypeV1].(string)
	if !ok {
		return ""
	}
	return res
}
func (m DIDCommMsgMap) typeV2() string {
	if m == nil || m[jsonTypeV2] == nil {
		return ""
	}
	res, ok := m[jsonTypeV2].(string)
	if !ok {
		return ""
	}
	return res
}
func (m DIDCommMsgMap) Type() string {
	if val := m.typeV1(); val != "" {
		return val
	}
	return m.typeV2()
}
func (m DIDCommMsgMap) ParentThreadID() string {
	if m == nil {
		return ""
	}
	parentThreadID, ok := m[jsonParentThreadID].(string)
	if ok && parentThreadID != "" {
		return parentThreadID
	}
	if m[jsonThread] == nil {
		return ""
	}
	if thread, ok := m[jsonThread].(map[string]interface{}); ok && thread != nil {
		if pthID, ok := thread[jsonParentThreadID].(string); ok && pthID != "" {
			return pthID
		}
	}
	return ""
}
func (m DIDCommMsgMap) idV1() string {
	if m == nil || m[jsonIDV1] == nil {
		return ""
	}
	res, ok := m[jsonIDV1].(string)
	if !ok {
		return ""
	}
	return res
}
func (m DIDCommMsgMap) idV2() string {
	if m == nil || m[jsonIDV2] == nil {
		return ""
	}
	res, ok := m[jsonIDV2].(string)
	if !ok {
		return ""
	}
	return res
}
func (m DIDCommMsgMap) ID() string {
	if val := m.idV1(); val != "" {
		return val
	}
	return m.idV2()
}
type Opt func(o *options)
type options struct {
	V Version
}
func getOptions(opts ...Opt) *options {
	o := &options{}
	for i := range opts {
		opts[i](o)
	}
	if o.V == "" {
		o.V = V1
	}
	return o
}
func WithVersion(v Version) Opt {
	return func(o *options) {
		o.V = v
	}
}