diff --git a/codec/codec.go b/codec/codec.go index 0fa2429..1514fc0 100644 --- a/codec/codec.go +++ b/codec/codec.go @@ -28,7 +28,7 @@ type ProtoReader interface { // ReadProto reads a uvarint size and then a protobuf from r. // If the size read is zero, nothing more is read. -func ReadProto(r ProtoReader, pb interface{}) error { +func ReadProto(r ProtoReader, pb proto.Message) error { size, err := binary.ReadUvarint(r) if err != nil { return err @@ -44,7 +44,7 @@ func ReadProto(r ProtoReader, pb interface{}) error { // WriteProto writes a uvarint size and then a protobuf to w. // If the data takes no space (like rpc.InvalidRequest), // only a zero size is written. -func WriteProto(w io.Writer, pb interface{}) error { +func WriteProto(w io.Writer, pb proto.Message) error { // Allocate enough space for the biggest uvarint var size [binary.MaxVarintLen64]byte @@ -93,7 +93,12 @@ func (s *ServerCodec) ReadRequestHeader(req *rpc.Request) error { // ReadRequestBody reads a uvarint from the connection and decodes that many // subsequent bytes into the given protobuf (which should be a pointer to a // struct that is generated by the proto package). -func (s *ServerCodec) ReadRequestBody(pb interface{}) error { +func (s *ServerCodec) ReadRequestBody(obj interface{}) error { + pb, ok := obj.(proto.Message) + if !ok { + return fmt.Errorf("%T does not implement proto.Message", obj) + } + return ReadProto(s.r, pb) } @@ -101,7 +106,12 @@ func (s *ServerCodec) ReadRequestBody(pb interface{}) error { // to the connection (each prefixed with a uvarint indicating its size). If // the response was invalid, the size of the body of the resp is reported as // having size zero and is not sent. -func (s *ServerCodec) WriteResponse(resp *rpc.Response, pb interface{}) error { +func (s *ServerCodec) WriteResponse(resp *rpc.Response, obj interface{}) error { + pb, ok := obj.(proto.Message) + if !ok { + return fmt.Errorf("%T does not implement proto.Message", obj) + } + // Write the header header := wire.Header{ Method: &resp.ServiceMethod, @@ -140,7 +150,12 @@ func NewClientCodec(conn net.Conn) *ClientCodec { // WriteRequest writes the appropriate header protobuf and the given protobuf // to the connection (each prefixed with a uvarint indicating its size). -func (c *ClientCodec) WriteRequest(req *rpc.Request, pb interface{}) error { +func (c *ClientCodec) WriteRequest(req *rpc.Request, obj interface{}) error { + pb, ok := obj.(proto.Message) + if !ok { + return fmt.Errorf("%T does not implement proto.Message", obj) + } + // Write the header header := wire.Header{ Method: &req.ServiceMethod, @@ -180,7 +195,12 @@ func (c *ClientCodec) ReadResponseHeader(resp *rpc.Response) error { // struct that is generated by the proto package). If the uvarint size read // is zero, nothing is done (this indicates an error condition, which was // encapsulated in the header) -func (c *ClientCodec) ReadResponseBody(pb interface{}) error { +func (c *ClientCodec) ReadResponseBody(obj interface{}) error { + pb, ok := obj.(proto.Message) + if !ok { + return fmt.Errorf("%T does not implement proto.Message", obj) + } + return ReadProto(c.r, pb) } diff --git a/codec/codec_test.go b/codec/codec_test.go index ae50b0e..8893822 100644 --- a/codec/codec_test.go +++ b/codec/codec_test.go @@ -11,11 +11,15 @@ import ( type InvalidRequest struct{} +func (InvalidRequest) ProtoMessage() {} +func (InvalidRequest) Reset() {} +func (InvalidRequest) String() string { return "" } + func TestWriteProto(t *testing.T) { tests := []struct { Desc string - Out interface{} - In interface{} + Out proto.Message + In proto.Message }{ { Desc: "Test the zero size proto", diff --git a/example_ae/whoami/whoami.ae.go b/example_ae/whoami/whoami.ae.go index f907713..d8d80e9 100644 --- a/example_ae/whoami/whoami.ae.go +++ b/example_ae/whoami/whoami.ae.go @@ -1,17 +1,20 @@ // +build appengine -// Code generated by protoc-gen-go from "whoami/whoami.proto" +// Code generated by protoc-gen-go. +// source: whoami/whoami.proto // DO NOT EDIT! package whoami -import "math" +import json "encoding/json" +import math "math" import "net/url" import "net/http" import "github.com/kylelemons/go-rpcgen/webrpc" -// Reference proto and math imports to suppress error if they are not otherwise used. +// Reference proto, json, and math imports to suppress error if they are not otherwise used. +var _ = &json.SyntaxError{} var _ = math.Inf type Empty struct { @@ -19,6 +22,7 @@ type Empty struct { } func (this *Empty) Reset() { *this = Empty{} } +func (*Empty) ProtoMessage() {} type YouAre struct { IpAddr *string `protobuf:"bytes,1,req,name=ip_addr" json:"ip_addr,omitempty"` @@ -26,6 +30,14 @@ type YouAre struct { } func (this *YouAre) Reset() { *this = YouAre{} } +func (*YouAre) ProtoMessage() {} + +func (this *YouAre) GetIpAddr() string { + if this != nil && this.IpAddr != nil { + return *this.IpAddr + } + return "" +} func init() { } diff --git a/example_ae/whoami/whoami.pb.go b/example_ae/whoami/whoami.pb.go index 9673230..a852c95 100644 --- a/example_ae/whoami/whoami.pb.go +++ b/example_ae/whoami/whoami.pb.go @@ -1,19 +1,22 @@ // +build !appengine -// Code generated by protoc-gen-go from "whoami/whoami.proto" +// Code generated by protoc-gen-go. +// source: whoami/whoami.proto // DO NOT EDIT! package whoami import proto "code.google.com/p/goprotobuf/proto" -import "math" +import json "encoding/json" +import math "math" import "net/url" import "net/http" import "github.com/kylelemons/go-rpcgen/webrpc" -// Reference proto and math imports to suppress error if they are not otherwise used. -var _ = proto.GetString +// Reference proto, json, and math imports to suppress error if they are not otherwise used. +var _ = proto.Marshal +var _ = &json.SyntaxError{} var _ = math.Inf type Empty struct { @@ -22,6 +25,7 @@ type Empty struct { func (this *Empty) Reset() { *this = Empty{} } func (this *Empty) String() string { return proto.CompactTextString(this) } +func (*Empty) ProtoMessage() {} type YouAre struct { IpAddr *string `protobuf:"bytes,1,req,name=ip_addr" json:"ip_addr,omitempty"` @@ -30,6 +34,14 @@ type YouAre struct { func (this *YouAre) Reset() { *this = YouAre{} } func (this *YouAre) String() string { return proto.CompactTextString(this) } +func (*YouAre) ProtoMessage() {} + +func (this *YouAre) GetIpAddr() string { + if this != nil && this.IpAddr != nil { + return *this.IpAddr + } + return "" +} func init() { } diff --git a/examples/add/addservice/addservice.pb.go b/examples/add/addservice/addservice.pb.go index 8189ab6..35cc8b2 100644 --- a/examples/add/addservice/addservice.pb.go +++ b/examples/add/addservice/addservice.pb.go @@ -1,10 +1,12 @@ -// Code generated by protoc-gen-go from "examples/add/addservice/addservice.proto" +// Code generated by protoc-gen-go. +// source: examples/add/addservice/addservice.proto // DO NOT EDIT! package addservice import proto "code.google.com/p/goprotobuf/proto" -import "math" +import json "encoding/json" +import math "math" import "net" import "net/rpc" @@ -13,8 +15,9 @@ import "net/url" import "net/http" import "github.com/kylelemons/go-rpcgen/webrpc" -// Reference proto and math imports to suppress error if they are not otherwise used. -var _ = proto.GetString +// Reference proto, json, and math imports to suppress error if they are not otherwise used. +var _ = proto.Marshal +var _ = &json.SyntaxError{} var _ = math.Inf type AddMessage struct { @@ -25,6 +28,21 @@ type AddMessage struct { func (this *AddMessage) Reset() { *this = AddMessage{} } func (this *AddMessage) String() string { return proto.CompactTextString(this) } +func (*AddMessage) ProtoMessage() {} + +func (this *AddMessage) GetX() int32 { + if this != nil && this.X != nil { + return *this.X + } + return 0 +} + +func (this *AddMessage) GetY() int32 { + if this != nil && this.Y != nil { + return *this.Y + } + return 0 +} type SumMessage struct { Z *int32 `protobuf:"varint,1,req,name=z" json:"z,omitempty"` @@ -33,6 +51,14 @@ type SumMessage struct { func (this *SumMessage) Reset() { *this = SumMessage{} } func (this *SumMessage) String() string { return proto.CompactTextString(this) } +func (*SumMessage) ProtoMessage() {} + +func (this *SumMessage) GetZ() int32 { + if this != nil && this.Z != nil { + return *this.Z + } + return 0 +} func init() { } diff --git a/examples/echo/echoservice/echoservice.pb.go b/examples/echo/echoservice/echoservice.pb.go index ed36ca7..7ab1602 100644 --- a/examples/echo/echoservice/echoservice.pb.go +++ b/examples/echo/echoservice/echoservice.pb.go @@ -1,10 +1,12 @@ -// Code generated by protoc-gen-go from "examples/echo/echoservice/echoservice.proto" +// Code generated by protoc-gen-go. +// source: examples/echo/echoservice/echoservice.proto // DO NOT EDIT! package echoservice import proto "code.google.com/p/goprotobuf/proto" -import "math" +import json "encoding/json" +import math "math" import "net" import "net/rpc" @@ -13,8 +15,9 @@ import "net/url" import "net/http" import "github.com/kylelemons/go-rpcgen/webrpc" -// Reference proto and math imports to suppress error if they are not otherwise used. -var _ = proto.GetString +// Reference proto, json, and math imports to suppress error if they are not otherwise used. +var _ = proto.Marshal +var _ = &json.SyntaxError{} var _ = math.Inf type Payload struct { @@ -24,6 +27,14 @@ type Payload struct { func (this *Payload) Reset() { *this = Payload{} } func (this *Payload) String() string { return proto.CompactTextString(this) } +func (*Payload) ProtoMessage() {} + +func (this *Payload) GetMessage() string { + if this != nil && this.Message != nil { + return *this.Message + } + return "" +} func init() { } diff --git a/examples/remote/offload/offload.pb.go b/examples/remote/offload/offload.pb.go index 7ca77e6..077447f 100644 --- a/examples/remote/offload/offload.pb.go +++ b/examples/remote/offload/offload.pb.go @@ -1,10 +1,12 @@ -// Code generated by protoc-gen-go from "examples/remote/offload/offload.proto" +// Code generated by protoc-gen-go. +// source: examples/remote/offload/offload.proto // DO NOT EDIT! package offload import proto "code.google.com/p/goprotobuf/proto" -import "math" +import json "encoding/json" +import math "math" import "net" import "net/rpc" @@ -13,8 +15,9 @@ import "net/url" import "net/http" import "github.com/kylelemons/go-rpcgen/webrpc" -// Reference proto and math imports to suppress error if they are not otherwise used. -var _ = proto.GetString +// Reference proto, json, and math imports to suppress error if they are not otherwise used. +var _ = proto.Marshal +var _ = &json.SyntaxError{} var _ = math.Inf type DataSet struct { @@ -24,6 +27,14 @@ type DataSet struct { func (this *DataSet) Reset() { *this = DataSet{} } func (this *DataSet) String() string { return proto.CompactTextString(this) } +func (*DataSet) ProtoMessage() {} + +func (this *DataSet) GetData() string { + if this != nil && this.Data != nil { + return *this.Data + } + return "" +} type ResultSet struct { Result *string `protobuf:"bytes,1,opt,name=result" json:"result,omitempty"` @@ -32,6 +43,14 @@ type ResultSet struct { func (this *ResultSet) Reset() { *this = ResultSet{} } func (this *ResultSet) String() string { return proto.CompactTextString(this) } +func (*ResultSet) ProtoMessage() {} + +func (this *ResultSet) GetResult() string { + if this != nil && this.Result != nil { + return *this.Result + } + return "" +} func init() { } diff --git a/plugin/wire/wire.pb.go b/plugin/wire/wire.pb.go index 2d6fd29..55a6b06 100644 --- a/plugin/wire/wire.pb.go +++ b/plugin/wire/wire.pb.go @@ -1,13 +1,16 @@ -// Code generated by protoc-gen-go from "plugin/wire/wire.proto" +// Code generated by protoc-gen-go. +// source: plugin/wire/wire.proto // DO NOT EDIT! package wire import proto "code.google.com/p/goprotobuf/proto" -import "math" +import json "encoding/json" +import math "math" -// Reference proto and math imports to suppress error if they are not otherwise used. -var _ = proto.GetString +// Reference proto, json, and math imports to suppress error if they are not otherwise used. +var _ = proto.Marshal +var _ = &json.SyntaxError{} var _ = math.Inf type Header struct { @@ -19,6 +22,28 @@ type Header struct { func (this *Header) Reset() { *this = Header{} } func (this *Header) String() string { return proto.CompactTextString(this) } +func (*Header) ProtoMessage() {} + +func (this *Header) GetMethod() string { + if this != nil && this.Method != nil { + return *this.Method + } + return "" +} + +func (this *Header) GetSeq() uint64 { + if this != nil && this.Seq != nil { + return *this.Seq + } + return 0 +} + +func (this *Header) GetError() string { + if this != nil && this.Error != nil { + return *this.Error + } + return "" +} func init() { } diff --git a/protoc-gen-go/main.go b/protoc-gen-go/main.go index ec9aa3d..330cf66 100644 --- a/protoc-gen-go/main.go +++ b/protoc-gen-go/main.go @@ -72,7 +72,7 @@ func main() { g.Fail("no files to generate") } - g.CommandLineParameters(proto.GetString(g.Request.Parameter)) + g.CommandLineParameters(g.Request.GetParameter()) // Create a wrapped version of the Descriptors and EnumDescriptors that // point to the file that defines them. diff --git a/protoc-gen-go/testdata/service.pb.go b/protoc-gen-go/testdata/service.pb.go index eb6f8b4..76b314d 100644 --- a/protoc-gen-go/testdata/service.pb.go +++ b/protoc-gen-go/testdata/service.pb.go @@ -1,10 +1,12 @@ -// Code generated by protoc-gen-go from "protoc-gen-go/testdata/service.proto" +// Code generated by protoc-gen-go. +// source: protoc-gen-go/testdata/service.proto // DO NOT EDIT! package svc import proto "code.google.com/p/goprotobuf/proto" -import "math" +import json "encoding/json" +import math "math" import "net" import "net/rpc" @@ -13,8 +15,9 @@ import "net/url" import "net/http" import "github.com/kylelemons/go-rpcgen/webrpc" -// Reference proto and math imports to suppress error if they are not otherwise used. -var _ = proto.GetString +// Reference proto, json, and math imports to suppress error if they are not otherwise used. +var _ = proto.Marshal +var _ = &json.SyntaxError{} var _ = math.Inf type Args struct { @@ -25,6 +28,21 @@ type Args struct { func (this *Args) Reset() { *this = Args{} } func (this *Args) String() string { return proto.CompactTextString(this) } +func (*Args) ProtoMessage() {} + +func (this *Args) GetA() string { + if this != nil && this.A != nil { + return *this.A + } + return "" +} + +func (this *Args) GetB() string { + if this != nil && this.B != nil { + return *this.B + } + return "" +} type Return struct { C *string `protobuf:"bytes,1,req,name=c" json:"c,omitempty"` @@ -33,6 +51,14 @@ type Return struct { func (this *Return) Reset() { *this = Return{} } func (this *Return) String() string { return proto.CompactTextString(this) } +func (*Return) ProtoMessage() {} + +func (this *Return) GetC() string { + if this != nil && this.C != nil { + return *this.C + } + return "" +} func init() { } diff --git a/webrpc/proto.go b/webrpc/proto.go index 3d935e8..e529f92 100644 --- a/webrpc/proto.go +++ b/webrpc/proto.go @@ -17,14 +17,24 @@ var ProtoBuf Protocol = pbProtocol{} type pbProtocol struct{} func (pbProtocol) String() string { return "application/protobuf" } -func (pbProtocol) Decode(r io.Reader, pb interface{}) error { +func (pbProtocol) Decode(r io.Reader, obj interface{}) error { + pb, ok := obj.(proto.Message) + if !ok { + return fmt.Errorf("%T does not implement proto.Message", obj) + } + body, err := ioutil.ReadAll(r) if err != nil { return fmt.Errorf("webrpc: decode: %s", err) } return proto.Unmarshal(body, pb) } -func (pbProtocol) Encode(w io.Writer, pb interface{}) error { +func (pbProtocol) Encode(w io.Writer, obj interface{}) error { + pb, ok := obj.(proto.Message) + if !ok { + return fmt.Errorf("%T does not implement proto.Message", obj) + } + body, err := proto.Marshal(pb) if err != nil { return fmt.Errorf("webrpc: encode: %s", err)