Skip to content

Commit

Permalink
feat: Add Any helper functions (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
amaury1093 authored Nov 16, 2022
1 parent 47964f2 commit ad42ce8
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ go install github.com/cosmos/cosmos-proto/cmd/protoc-gen-go-pulsar

cd path/to/proto/files

protoc --go-pulsar_out=. --go-pulsar_opt=paths=source_relative --go-pulsar_opt=features=marshal+unmarshal+size -I .
protoc --go-pulsar_out=. --go-pulsar_opt=paths=source_relative --go-pulsar_opt=features=protoc+fast -I .
NAME_OF_FILE.proto

## Acknowledgements
Expand Down
63 changes: 63 additions & 0 deletions any/any.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (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

import (
"google.golang.org/protobuf/proto"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
"google.golang.org/protobuf/types/known/anypb"
)

// New marshals src into a new Any instance.
func New(src proto.Message) (*anypb.Any, error) {
dst := new(anypb.Any)
if err := MarshalFrom(dst, src, proto.MarshalOptions{}); err != nil {
return nil, err
}
return dst, nil
}

// MarshalFrom marshals src into dst as the underlying message
// using the provided marshal options.
//
// If no options are specified, call dst.MarshalFrom instead.
func MarshalFrom(dst *anypb.Any, src proto.Message, opts proto.MarshalOptions) error {
if src == nil {
return protoimpl.X.NewError("invalid nil source message")
}
b, err := opts.Marshal(src)
if err != nil {
return err
}
dst.TypeUrl = string(src.ProtoReflect().Descriptor().FullName())
dst.Value = b
return nil
}
33 changes: 33 additions & 0 deletions any/any_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package any_test

import (
"testing"

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

"github.com/cosmos/cosmos-proto/any"
"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{})
require.NoError(t, err)
require.Equal(t, "A", dst1.TypeUrl) // Make sure there's no "type.googleapis.com/" prefix.

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

// Round trip.
newValue, err := anypb.UnmarshalNew(dst2, proto.UnmarshalOptions{})
require.NoError(t, err)
diff := cmp.Diff(value, newValue, protocmp.Transform())
require.Empty(t, diff)
}
19 changes: 19 additions & 0 deletions any/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Package any is a helper library to be used as a replacement for some of the
// official "google.golang.org/protobuf/types/known/anypb"'s functions which
// prepend the "type.googleapis.com" prefix in type URLs.
//
// In the Cosmos SDK, an Any's TypeURL starts with a `/` character, e.g.
// "/cosmos.bank.v1beta1.MsgSend". However, if we pack this MsgSend into
// an anypb.Any using the offical anypb package's helper functions, we get a
// TypeURL which is "type.googleapis.com/cosmos.bank.v1beta1.MsgSend".
//
// Therefore, the following 3 functions/methods cannot be used within the
// Cosmos context:
// - anypb.New
// - anypb.MarshalFrom
// - anypb.Any#MarshalFrom
// as all of them append the unwanted prefix.
//
// This package exposes the `New` and `MarshalFrom` helper functions, which do
// not prepend any prefix to type URLs.
package any

0 comments on commit ad42ce8

Please sign in to comment.