Description
This program currently type-checks correctly, but then fails with "proto: no encoder for Empty empty.Empty [GetProperties]". The reason, from what I can tell, is that the proto package registers en-/decoders per message and then looks them up via their reflect.Type. It would be nice, if messages where correctly embeddable.
A (conceptually) simple way to do that, would be to change the ProtoMessage()
method to ProtoMessage() proto.Message
and have the generated types return themselves from it. The functions in the proto-package can then, instead of operating on a pb Message
parameter, operate on pb.ProtoMessage()
instead.
My specific usecase is, that I want to be able to attach additional methods to protobufs (or rather, have an interface that also guarantees protobuf-encodability). Currently I'm trying type Actuator interface{ proto.Message; Actuate(Context) error }
, and recommend embedding a concrete message to a struct and add the Actuate
method to that. I thought of alternatives (like changing it to interface{ Proto() proto.Message; … }
or interface{ Marshal() ([]byte, error); Unmarshal([]byte) error; … }
), but all of them require additional boilerplate for each implementation of Actuator
. Correctly embeddable Messages would neatly avoid that.
Activity
dsnet commentedon Dec 27, 2017
The fundamental issue is that the
proto.Message
interface is marginally better thaninterface{}
. It is just a marker and the logic in theproto
package makes all sort of deep assumptions about what the message looks like (i.e., that it is a flat struct with fields).#364 is intended to make
proto.Message
into a behaviorally complete interface, eliminating this problem.typednil
keyword for checking whether an interface value is a typed nil. golang/go#24635