6
protov1 "github.com/golang/protobuf/proto"
7
"github.com/pkg/errors"
8
"google.golang.org/protobuf/proto"
9
"google.golang.org/protobuf/reflect/protoreflect"
10
"google.golang.org/protobuf/reflect/protoregistry"
11
"google.golang.org/protobuf/types/known/anypb"
14
const googleApis = "type.googleapis.com/"
20
func MarshalAnyDeterministic(pb proto.Message) (*anypb.Any, error) {
21
bytes, err := proto.MarshalOptions{Deterministic: true}.Marshal(pb)
25
name := string(protov1.MessageV2(pb).ProtoReflect().Descriptor().FullName())
26
return &anypb.Any{TypeUrl: googleApis + name, Value: bytes}, nil
29
func MustMarshalAny(pb proto.Message) *anypb.Any {
30
msg, err := MarshalAnyDeterministic(pb)
37
func UnmarshalAnyTo(src *anypb.Any, dst proto.Message) error {
38
return anypb.UnmarshalTo(src, dst, proto.UnmarshalOptions{})
43
func MergeAnys(dst *anypb.Any, src *anypb.Any) (*anypb.Any, error) {
50
if src.TypeUrl != dst.TypeUrl {
51
return nil, errors.Errorf("type URL of dst %q is different than src %q", dst.TypeUrl, src.TypeUrl)
54
msgType, err := FindMessageType(dst.TypeUrl)
59
dstMsg := msgType.New().Interface()
60
if err := proto.Unmarshal(dst.Value, dstMsg); err != nil {
64
srcMsg := msgType.New().Interface()
65
if err := proto.Unmarshal(src.Value, srcMsg); err != nil {
70
return MarshalAnyDeterministic(dstMsg)
73
func FindMessageType(typeUrl string) (protoreflect.MessageType, error) {
76
msgTypeName := strings.ReplaceAll(typeUrl, googleApis, "")
77
fullName := protoreflect.FullName(msgTypeName)
79
return protoregistry.GlobalTypes.FindMessageByName(fullName)