Skip to content

Commit

Permalink
refactor!: Rename to anyutil (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
amaury1093 authored Mar 9, 2023
1 parent bd5ba28 commit 78e33f2
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 6 deletions.
51 changes: 50 additions & 1 deletion any/any.go → anyutil/any.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,18 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package any
package anyutil

import (
"fmt"
"strings"

"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
"google.golang.org/protobuf/types/dynamicpb"
"google.golang.org/protobuf/types/known/anypb"
)

Expand Down Expand Up @@ -61,3 +68,45 @@ func MarshalFrom(dst *anypb.Any, src proto.Message, opts proto.MarshalOptions) e
dst.Value = b
return nil
}

// Unpack unpacks the message inside an any, first using the provided
// typeResolver (defaults to protoregistry.GlobalTypes), and if that fails,
// then using the provided fileResolver (defaults to protoregistry.GlobalFiles)
// with dynamicpb.
func Unpack(any *anypb.Any, fileResolver protodesc.Resolver, typeResolver protoregistry.MessageTypeResolver) (proto.Message, error) {
if typeResolver == nil {
typeResolver = protoregistry.GlobalTypes
}

url := any.TypeUrl
typ, err := typeResolver.FindMessageByURL(url)
if err == protoregistry.NotFound {
if fileResolver == nil {
fileResolver = protoregistry.GlobalFiles
}

// If the proto v2 registry doesn't have this message, then we use
// protoFiles (which can e.g. be initialized to gogo's MergedRegistry)
// to retrieve the message descriptor, and then use dynamicpb on that
// message descriptor to create a proto.Message
typeURL := strings.TrimPrefix(any.TypeUrl, "/")

msgDesc, err := fileResolver.FindDescriptorByName(protoreflect.FullName(typeURL))
if err != nil {
return nil, fmt.Errorf("protoFiles does not have descriptor %s: %w", any.TypeUrl, err)
}

typ = dynamicpb.NewMessageType(msgDesc.(protoreflect.MessageDescriptor))

} else if err != nil {
return nil, err
}

packedMsg := typ.New().Interface()
err = any.UnmarshalTo(packedMsg)
if err != nil {
return nil, fmt.Errorf("cannot unmarshal msg %s: %w", any.TypeUrl, err)
}

return packedMsg, nil
}
26 changes: 22 additions & 4 deletions any/any_test.go → anyutil/any_test.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
package any_test
package anyutil_test

import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/testing/protocmp"
"google.golang.org/protobuf/types/known/anypb"

"github.com/cosmos/cosmos-proto/any"
"github.com/cosmos/cosmos-proto/anyutil"
"github.com/cosmos/cosmos-proto/testpb"
)

func TestAny(t *testing.T) {
value := &testpb.A{SomeBoolean: true}

dst1 := &anypb.Any{}
err := any.MarshalFrom(dst1, value, proto.MarshalOptions{})
err := anyutil.MarshalFrom(dst1, value, proto.MarshalOptions{})
require.NoError(t, err)
require.Equal(t, "/A", dst1.TypeUrl) // Make sure there's no "type.googleapis.com/" prefix.

dst2, err := any.New(value)
dst2, err := anyutil.New(value)
require.NoError(t, err)
require.Equal(t, "/A", dst2.TypeUrl) // Make sure there's no "type.googleapis.com/" prefix.

Expand All @@ -31,3 +32,20 @@ func TestAny(t *testing.T) {
diff := cmp.Diff(value, newValue, protocmp.Transform())
require.Empty(t, diff)
}

func TestUnpack(t *testing.T) {
value := &testpb.A{SomeBoolean: true}
any, err := anyutil.New(value)
require.NoError(t, err)

msg, err := anyutil.Unpack(any, nil, nil)
require.NoError(t, err)
diff := cmp.Diff(value, msg, protocmp.Transform())
require.Empty(t, diff)

// Test the same thing with using the dynamicpb path.
msg, err = anyutil.Unpack(any, protoregistry.GlobalFiles, &protoregistry.Types{})
require.NoError(t, err)
diff = cmp.Diff(value, msg, protocmp.Transform())
require.Empty(t, diff)
}
2 changes: 1 addition & 1 deletion any/doc.go → anyutil/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
//
// This package exposes the `New` and `MarshalFrom` helper functions, which do
// not prepend any prefix to type URLs.
package any
package anyutil

0 comments on commit 78e33f2

Please sign in to comment.