1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
package protokit
import (
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/plugin"
"fmt"
"io"
"io/ioutil"
"os"
)
// Plugin describes an interface for running protoc code generator plugins
type Plugin interface {
Generate(req *plugin_go.CodeGeneratorRequest) (*plugin_go.CodeGeneratorResponse, error)
}
// RunPlugin runs the supplied plugin by reading input from stdin and generating output to stdout.
func RunPlugin(p Plugin) error {
return RunPluginWithIO(p, os.Stdin, os.Stdout)
}
// RunPluginWithIO runs the supplied plugin using the supplied reader and writer for IO.
func RunPluginWithIO(p Plugin, r io.Reader, w io.Writer) error {
req, err := readRequest(r)
if err != nil {
return err
}
resp, err := p.Generate(req)
if err != nil {
return err
}
return writeResponse(w, resp)
}
func readRequest(r io.Reader) (*plugin_go.CodeGeneratorRequest, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
req := new(plugin_go.CodeGeneratorRequest)
if err = proto.Unmarshal(data, req); err != nil {
return nil, err
}
if len(req.GetFileToGenerate()) == 0 {
return nil, fmt.Errorf("no files were supplied to the generator")
}
return req, nil
}
func writeResponse(w io.Writer, resp *plugin_go.CodeGeneratorResponse) error {
data, err := proto.Marshal(resp)
if err != nil {
return err
}
if _, err := w.Write(data); err != nil {
return err
}
return nil
}
|