// Code generated by protoc-gen-go. DO NOT EDIT.
// source: proxy.proto

package proto

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	context "golang.org/x/net/context"
	grpc "google.golang.org/grpc"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package

type RunCommandRequest struct {
	Command              string   `protobuf:"bytes,1,opt,name=command,proto3" json:"command,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *RunCommandRequest) Reset()         { *m = RunCommandRequest{} }
func (m *RunCommandRequest) String() string { return proto.CompactTextString(m) }
func (*RunCommandRequest) ProtoMessage()    {}
func (*RunCommandRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_700b50b08ed8dbaf, []int{0}
}

func (m *RunCommandRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_RunCommandRequest.Unmarshal(m, b)
}
func (m *RunCommandRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_RunCommandRequest.Marshal(b, m, deterministic)
}
func (m *RunCommandRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_RunCommandRequest.Merge(m, src)
}
func (m *RunCommandRequest) XXX_Size() int {
	return xxx_messageInfo_RunCommandRequest.Size(m)
}
func (m *RunCommandRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_RunCommandRequest.DiscardUnknown(m)
}

var xxx_messageInfo_RunCommandRequest proto.InternalMessageInfo

func (m *RunCommandRequest) GetCommand() string {
	if m != nil {
		return m.Command
	}
	return ""
}

type RunCommandResponse struct {
	EffectiveCommand     string   `protobuf:"bytes,1,opt,name=effective_command,json=effectiveCommand,proto3" json:"effective_command,omitempty"`
	Lines                []string `protobuf:"bytes,2,rep,name=lines,proto3" json:"lines,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *RunCommandResponse) Reset()         { *m = RunCommandResponse{} }
func (m *RunCommandResponse) String() string { return proto.CompactTextString(m) }
func (*RunCommandResponse) ProtoMessage()    {}
func (*RunCommandResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_700b50b08ed8dbaf, []int{1}
}

func (m *RunCommandResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_RunCommandResponse.Unmarshal(m, b)
}
func (m *RunCommandResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_RunCommandResponse.Marshal(b, m, deterministic)
}
func (m *RunCommandResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_RunCommandResponse.Merge(m, src)
}
func (m *RunCommandResponse) XXX_Size() int {
	return xxx_messageInfo_RunCommandResponse.Size(m)
}
func (m *RunCommandResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_RunCommandResponse.DiscardUnknown(m)
}

var xxx_messageInfo_RunCommandResponse proto.InternalMessageInfo

func (m *RunCommandResponse) GetEffectiveCommand() string {
	if m != nil {
		return m.EffectiveCommand
	}
	return ""
}

func (m *RunCommandResponse) GetLines() []string {
	if m != nil {
		return m.Lines
	}
	return nil
}

func init() {
	proto.RegisterType((*RunCommandRequest)(nil), "proto.RunCommandRequest")
	proto.RegisterType((*RunCommandResponse)(nil), "proto.RunCommandResponse")
}

func init() { proto.RegisterFile("proxy.proto", fileDescriptor_700b50b08ed8dbaf) }

var fileDescriptor_700b50b08ed8dbaf = []byte{
	// 165 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2e, 0x28, 0xca, 0xaf,
	0xa8, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x53, 0x4a, 0xba, 0x5c, 0x82, 0x41,
	0xa5, 0x79, 0xce, 0xf9, 0xb9, 0xb9, 0x89, 0x79, 0x29, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25,
	0x42, 0x12, 0x5c, 0xec, 0xc9, 0x10, 0x11, 0x09, 0x46, 0x05, 0x46, 0x0d, 0xce, 0x20, 0x18, 0x57,
	0x29, 0x9c, 0x4b, 0x08, 0x59, 0x79, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0xaa, 0x90, 0x36, 0x97, 0x60,
	0x6a, 0x5a, 0x5a, 0x6a, 0x72, 0x49, 0x66, 0x59, 0x6a, 0x3c, 0xaa, 0x4e, 0x01, 0xb8, 0x04, 0x54,
	0x93, 0x90, 0x08, 0x17, 0x6b, 0x4e, 0x66, 0x5e, 0x6a, 0xb1, 0x04, 0x93, 0x02, 0xb3, 0x06, 0x67,
	0x10, 0x84, 0x63, 0xe4, 0xcf, 0xc5, 0xe5, 0x6b, 0x66, 0x64, 0x64, 0x10, 0x00, 0x72, 0xa2, 0x90,
	0x23, 0x17, 0x17, 0xc2, 0x1a, 0x21, 0x09, 0x88, 0x93, 0xf5, 0x30, 0x1c, 0x2a, 0x25, 0x89, 0x45,
	0x06, 0xe2, 0xa6, 0x24, 0x36, 0xb0, 0x8c, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x39, 0x6d, 0xab,
	0xdd, 0xf5, 0x00, 0x00, 0x00,
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4

// M6220ProxyClient is the client API for M6220Proxy service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type M6220ProxyClient interface {
	RunCommand(ctx context.Context, in *RunCommandRequest, opts ...grpc.CallOption) (*RunCommandResponse, error)
}

type m6220ProxyClient struct {
	cc *grpc.ClientConn
}

func NewM6220ProxyClient(cc *grpc.ClientConn) M6220ProxyClient {
	return &m6220ProxyClient{cc}
}

func (c *m6220ProxyClient) RunCommand(ctx context.Context, in *RunCommandRequest, opts ...grpc.CallOption) (*RunCommandResponse, error) {
	out := new(RunCommandResponse)
	err := c.cc.Invoke(ctx, "/proto.M6220Proxy/RunCommand", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// M6220ProxyServer is the server API for M6220Proxy service.
type M6220ProxyServer interface {
	RunCommand(context.Context, *RunCommandRequest) (*RunCommandResponse, error)
}

func RegisterM6220ProxyServer(s *grpc.Server, srv M6220ProxyServer) {
	s.RegisterService(&_M6220Proxy_serviceDesc, srv)
}

func _M6220Proxy_RunCommand_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(RunCommandRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(M6220ProxyServer).RunCommand(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/proto.M6220Proxy/RunCommand",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(M6220ProxyServer).RunCommand(ctx, req.(*RunCommandRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _M6220Proxy_serviceDesc = grpc.ServiceDesc{
	ServiceName: "proto.M6220Proxy",
	HandlerType: (*M6220ProxyServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "RunCommand",
			Handler:    _M6220Proxy_RunCommand_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "proxy.proto",
}
