func UnmarshalByTypeURL(typeURL string, value []byte) (interface{}, error) {
	return unmarshal(typeURL, value, nil)
}
UnmarshalByTypeURL unmarshals the given type and value to into a concrete type.
package typeurl
import (
	"encoding/json"
	"path"
	"reflect"
	"sync"
	"github.com/gogo/protobuf/proto"
	"github.com/gogo/protobuf/types"
	"github.com/pkg/errors"
)
var (
	mu       sync.RWMutex
	registry = make(map[reflect.Type]string)
)
var (
	ErrNotFound = errors.New("not found")
)
func Register(v interface{}, args ...string) {
	var (
		t = tryDereference(v)
		p = path.Join(args...)
	)
	mu.Lock()
	defer mu.Unlock()
	if et, ok := registry[t]; ok {
		if et != p {
			panic(errors.Errorf("type registered with alternate path %q != %q", et, p))
		}
		return
	}
	registry[t] = p
}
func TypeURL(v interface{}) (string, error) {
	mu.RLock()
	u, ok := registry[tryDereference(v)]
	mu.RUnlock()
	if !ok {
		pb, ok := v.(proto.Message)
		if !ok {
			return "", errors.Wrapf(ErrNotFound, "type %s", reflect.TypeOf(v))
		}
		return proto.MessageName(pb), nil
	}
	return u, nil
}
func Is(any *types.Any, v interface{}) bool {
	tryDereference(v)
	url, err := TypeURL(v)
	if err != nil {
		return false
	}
	return any.TypeUrl == url
}
func MarshalAny(v interface{}) (*types.Any, error) {
	var marshal func(v interface{}) ([]byte, error)
	switch t := v.(type) {
	case *types.Any:
		return t, nil
	case proto.Message:
		marshal = func(v interface{}) ([]byte, error) {
			return proto.Marshal(t)
		}
	default:
		marshal = json.Marshal
	}
	url, err := TypeURL(v)
	if err != nil {
		return nil, err
	}
	data, err := marshal(v)
	if err != nil {
		return nil, err
	}
	return &types.Any{
		TypeUrl: url,
		Value:   data,
	}, nil
}
func UnmarshalAny(any *types.Any) (interface{}, error) {
	return UnmarshalByTypeURL(any.TypeUrl, any.Value)
}