github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/codec/types/any.go (about)

     1  package types
     2  
     3  import (
     4  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     5  	"github.com/gogo/protobuf/proto"
     6  )
     7  
     8  type Any struct {
     9  	// A URL/resource name that uniquely identifies the type of the serialized
    10  	// protocol buffer message. This string must contain at least
    11  	// one "/" character. The last segment of the URL's path must represent
    12  	// the fully qualified name of the type (as in
    13  	// `path/google.protobuf.Duration`). The name should be in a canonical form
    14  	// (e.g., leading "." is not accepted).
    15  	//
    16  	// In practice, teams usually precompile into the binary all types that they
    17  	// expect it to use in the context of Any. However, for URLs which use the
    18  	// scheme `http`, `https`, or no scheme, one can optionally set up a type
    19  	// server that maps type URLs to message definitions as follows:
    20  	//
    21  	// * If no scheme is provided, `https` is assumed.
    22  	// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
    23  	//   value in binary format, or produce an error.
    24  	// * Applications are allowed to cache lookup results based on the
    25  	//   URL, or have them precompiled into a binary to avoid any
    26  	//   lookup. Therefore, binary compatibility needs to be preserved
    27  	//   on changes to types. (Use versioned type names to manage
    28  	//   breaking changes.)
    29  	//
    30  	// Note: this functionality is not currently available in the official
    31  	// protobuf release, and it is not used for type URLs beginning with
    32  	// type.googleapis.com.
    33  	//
    34  	// Schemes other than `http`, `https` (or the empty scheme) might be
    35  	// used with implementation specific semantics.
    36  
    37  	// nolint
    38  	TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"`
    39  	// Must be a valid serialized protocol buffer of the above specified type.
    40  	Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
    41  
    42  	// nolint
    43  	XXX_NoUnkeyedLiteral struct{} `json:"-"`
    44  
    45  	// nolint
    46  	XXX_unrecognized []byte `json:"-"`
    47  
    48  	// nolint
    49  	XXX_sizecache int32 `json:"-"`
    50  
    51  	cachedValue interface{}
    52  
    53  	compat *anyCompat
    54  }
    55  
    56  // NewAnyWithValue constructs a new Any packed with the value provided or
    57  // returns an error if that value couldn't be packed. This also caches
    58  // the packed value so that it can be retrieved from GetCachedValue without
    59  // unmarshaling
    60  func NewAnyWithValue(v proto.Message) (*Any, error) {
    61  	if v == nil {
    62  		return nil, sdkerrors.Wrap(sdkerrors.ErrPackAny, "Expecting non nil value to create a new Any")
    63  	}
    64  	return NewAnyWithCustomTypeURL(v, "/"+proto.MessageName(v))
    65  }
    66  
    67  // NewAnyWithCustomTypeURL same as NewAnyWithValue, but sets a custom type url, instead
    68  // using the one from proto.Message.
    69  // NOTE: This functions should be only used for types with additional logic bundled
    70  // into the protobuf Any serialization. For simple marshaling you should use NewAnyWithValue.
    71  func NewAnyWithCustomTypeURL(v proto.Message, typeURL string) (*Any, error) {
    72  	bz, err := proto.Marshal(v)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	return &Any{
    77  		TypeUrl:     typeURL,
    78  		Value:       bz,
    79  		cachedValue: v,
    80  	}, nil
    81  }
    82  
    83  // UnsafePackAny packs the value x in the Any and instead of returning the error
    84  // in the case of a packing failure, keeps the cached value. This should only
    85  // be used in situations where compatibility is needed with amino. Amino-only
    86  // values can safely be packed using this method when they will only be
    87  // marshaled with amino and not protobuf.
    88  func UnsafePackAny(x interface{}) *Any {
    89  	if msg, ok := x.(proto.Message); ok {
    90  		any, err := NewAnyWithValue(msg)
    91  		if err == nil {
    92  			return any
    93  		}
    94  	}
    95  	return &Any{cachedValue: x}
    96  }
    97  
    98  // pack packs the value x in the Any or returns an error. This also caches
    99  // the packed value so that it can be retrieved from GetCachedValue without
   100  // unmarshaling
   101  func (any *Any) pack(x proto.Message) error {
   102  	any.TypeUrl = "/" + proto.MessageName(x)
   103  	bz, err := proto.Marshal(x)
   104  	if err != nil {
   105  		return err
   106  	}
   107  
   108  	any.Value = bz
   109  	any.cachedValue = x
   110  
   111  	return nil
   112  }
   113  
   114  // GetCachedValue returns the cached value from the Any if present
   115  func (any *Any) GetCachedValue() interface{} {
   116  	return any.cachedValue
   117  }
   118  
   119  // ClearCachedValue clears the cached value from the Any
   120  func (any *Any) ClearCachedValue() {
   121  	any.cachedValue = nil
   122  }