Reputation: 189
I'm using grpc in my go project. Below is code:
example.proto:
syntax = "proto3";
message Example {
string message = 1;
google.protobuf.Any details = 2;
}
main.go
func logMessage (m string, d interface{}) {
message := & example.message{
message: m,
details: ??
}
log(&message)
}
But I'm not sure how to deal with the details(interface{}) field. I know I can use any type for interface, but not sure how to use it here. Anyone can help? Thanks
Upvotes: 9
Views: 34603
Reputation: 1
func ConvertInterfaceToAny(v interface{}) (*any.Any, error) {
anyValue := &any.Any{}
bytes, _ := json.Marshal(v)
bytesValue := &wrappers.BytesValue{
Value: bytes,
}
err := anypb.MarshalFrom(anyValue, bytesValue, proto.MarshalOptions{})
return anyValue, err
}
Upvotes: -1
Reputation: 1
func interfaceToAny(v interface{}) (*anypb.Any, error) {
bytes, err := json.Marshal(v)
if err != nil {
println("error json.Marshal interfaceToAny")
return nil, err
}
m := api.Bytes{B: bytes}
return anypb.New(&m)
}
message Bytes {
bytes b = 1;
}
Upvotes: -1
Reputation: 31
func pbany(v interface{}) (*anypb.Any, error) {
pv, ok := v.(proto.Message)
if !ok {
return &anypb.Any{}, fmt.Errorf("%v is not proto.Message", pv)
}
return anypb.New(pv)
use anypb.New
api, In your code, pass d
to pbany function
Upvotes: 3
Reputation: 1995
Since protobuf/ptypes is deprecated, it worth using anypb.UnmarshalTo
import (
"google.golang.org/protobuf/types/known/anypb"
"github.com/golang/protobuf/ptypes/any"
)
func Unmarshal(data *any.Any) (*YourMessage, err) {
var m YourMessage
err := anypb.UnmarshalTo(data, &m, proto.UnmarshalOptions{})
return &m,err
}
Upvotes: 13
Reputation: 21035
The protobuf/ptypes package has utilities to convert to/from arbitrary proto messages to any:
func MarshalAny(m proto.Message) (*anypb.Any, error)
MarshalAny marshals the given message m into an anypb.Any message.
func UnmarshalAny(any *anypb.Any, m proto.Message) error
UnmarshalAny unmarshals the encoded value contained in the anypb.Any message into the provided message m. It returns an error if the target message does not match the type in the Any message or if an unmarshal error occurs.
In your example, you would use something along the lines of:
func logMessage (m string, d proto.Message) {
details, err := ptypes.MarshalAny(d)
if err != nil {
panic(err)
}
message := & example.message{
message: m,
details: details
}
log(&message)
}
Upvotes: 11