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

package tls

import (
	context "context"
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
	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.ProtoPackageIsVersion3 // please upgrade the proto package

type DutShellRequest struct {
	// dut is some identifier for the DUT.  This could be the DUT
	// hostname, but the caller shouldn't know or care whether this is a
	// hostname or not, as they would not be able to use the hostname to
	// SSH or otherwise interact with the DUT directly.
	Dut                  string   `protobuf:"bytes,1,opt,name=dut,proto3" json:"dut,omitempty"`
	Command              string   `protobuf:"bytes,2,opt,name=command,proto3" json:"command,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_DutShellRequest proto.InternalMessageInfo

func (m *DutShellRequest) GetDut() string {
	if m != nil {
		return m.Dut
	}
	return ""
}

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

// For the last response in the stream, exited will be true and status
// will be set.
type DutShellResponse struct {
	Status               int32    `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
	Exited               bool     `protobuf:"varint,2,opt,name=exited,proto3" json:"exited,omitempty"`
	Stdout               []byte   `protobuf:"bytes,3,opt,name=stdout,proto3" json:"stdout,omitempty"`
	Stderr               []byte   `protobuf:"bytes,4,opt,name=stderr,proto3" json:"stderr,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_DutShellResponse proto.InternalMessageInfo

func (m *DutShellResponse) GetStatus() int32 {
	if m != nil {
		return m.Status
	}
	return 0
}

func (m *DutShellResponse) GetExited() bool {
	if m != nil {
		return m.Exited
	}
	return false
}

func (m *DutShellResponse) GetStdout() []byte {
	if m != nil {
		return m.Stdout
	}
	return nil
}

func (m *DutShellResponse) GetStderr() []byte {
	if m != nil {
		return m.Stderr
	}
	return nil
}

func init() {
	proto.RegisterType((*DutShellRequest)(nil), "tls.DutShellRequest")
	proto.RegisterType((*DutShellResponse)(nil), "tls.DutShellResponse")
}

func init() { proto.RegisterFile("tls/common.proto", fileDescriptor_3b853cac387a48f4) }

var fileDescriptor_3b853cac387a48f4 = []byte{
	// 229 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xc1, 0x4a, 0xc4, 0x30,
	0x10, 0x86, 0xa9, 0xd5, 0xba, 0x06, 0xc1, 0x12, 0x54, 0x82, 0xa7, 0x65, 0x4f, 0x7b, 0x31, 0x11,
	0x3d, 0x79, 0xf0, 0xe2, 0xfa, 0x04, 0xf1, 0xe6, 0xad, 0x6e, 0xc7, 0x6e, 0x21, 0xed, 0xac, 0x33,
	0x13, 0xf0, 0xf1, 0xa5, 0x69, 0xab, 0xd0, 0x5b, 0xbe, 0x8f, 0xcc, 0x9f, 0xfc, 0xa3, 0x4a, 0x09,
	0xec, 0xf6, 0xd8, 0x75, 0xd8, 0xdb, 0x23, 0xa1, 0xa0, 0xce, 0x25, 0xf0, 0xe6, 0x45, 0x5d, 0xbd,
	0x45, 0x79, 0x3f, 0x40, 0x08, 0x1e, 0xbe, 0x23, 0xb0, 0xe8, 0x52, 0xe5, 0x75, 0x14, 0x93, 0xad,
	0xb3, 0xed, 0x85, 0x1f, 0x8e, 0xda, 0xa8, 0xf3, 0x61, 0xb2, 0xea, 0x6b, 0x73, 0x92, 0xec, 0x8c,
	0x1b, 0x52, 0xe5, 0xff, 0x38, 0x1f, 0xb1, 0x67, 0xd0, 0xb7, 0xaa, 0x60, 0xa9, 0x24, 0x72, 0x8a,
	0x38, 0xf3, 0x13, 0x0d, 0x1e, 0x7e, 0x5a, 0x81, 0x31, 0x64, 0xe5, 0x27, 0x1a, 0xef, 0xd7, 0x18,
	0xc5, 0xe4, 0xeb, 0x6c, 0x7b, 0xe9, 0x27, 0x9a, 0x3c, 0x10, 0x99, 0xd3, 0x3f, 0x0f, 0x44, 0x8f,
	0x3b, 0x55, 0xec, 0x52, 0x0f, 0xfd, 0xac, 0x56, 0xf3, 0xeb, 0xfa, 0xda, 0x4a, 0x60, 0xbb, 0xe8,
	0x72, 0x77, 0xb3, 0xb0, 0xe3, 0x17, 0x1f, 0xb2, 0x57, 0xf7, 0x71, 0xdf, 0xa0, 0xdd, 0x1f, 0x08,
	0xbb, 0x36, 0x76, 0x16, 0xa9, 0x71, 0x33, 0x20, 0xbb, 0xb6, 0xff, 0xa2, 0xca, 0xa5, 0x35, 0xb9,
	0x06, 0x9d, 0x04, 0xfe, 0x2c, 0x12, 0x3d, 0xfd, 0x06, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x6e, 0x53,
	0x31, 0x48, 0x01, 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

// CommonClient is the client API for Common service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type CommonClient interface {
	// Runs a shell command with the default shell.
	// Does not spawn a tty.
	DutShell(ctx context.Context, in *DutShellRequest, opts ...grpc.CallOption) (Common_DutShellClient, error)
}

type commonClient struct {
	cc *grpc.ClientConn
}

func NewCommonClient(cc *grpc.ClientConn) CommonClient {
	return &commonClient{cc}
}

func (c *commonClient) DutShell(ctx context.Context, in *DutShellRequest, opts ...grpc.CallOption) (Common_DutShellClient, error) {
	stream, err := c.cc.NewStream(ctx, &_Common_serviceDesc.Streams[0], "/tls.Common/DutShell", opts...)
	if err != nil {
		return nil, err
	}
	x := &commonDutShellClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type Common_DutShellClient interface {
	Recv() (*DutShellResponse, error)
	grpc.ClientStream
}

type commonDutShellClient struct {
	grpc.ClientStream
}

func (x *commonDutShellClient) Recv() (*DutShellResponse, error) {
	m := new(DutShellResponse)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

// CommonServer is the server API for Common service.
type CommonServer interface {
	// Runs a shell command with the default shell.
	// Does not spawn a tty.
	DutShell(*DutShellRequest, Common_DutShellServer) error
}

// UnimplementedCommonServer can be embedded to have forward compatible implementations.
type UnimplementedCommonServer struct {
}

func (*UnimplementedCommonServer) DutShell(req *DutShellRequest, srv Common_DutShellServer) error {
	return status.Errorf(codes.Unimplemented, "method DutShell not implemented")
}

func RegisterCommonServer(s *grpc.Server, srv CommonServer) {
	s.RegisterService(&_Common_serviceDesc, srv)
}

func _Common_DutShell_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(DutShellRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(CommonServer).DutShell(m, &commonDutShellServer{stream})
}

type Common_DutShellServer interface {
	Send(*DutShellResponse) error
	grpc.ServerStream
}

type commonDutShellServer struct {
	grpc.ServerStream
}

func (x *commonDutShellServer) Send(m *DutShellResponse) error {
	return x.ServerStream.SendMsg(m)
}

var _Common_serviceDesc = grpc.ServiceDesc{
	ServiceName: "tls.Common",
	HandlerType: (*CommonServer)(nil),
	Methods:     []grpc.MethodDesc{},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "DutShell",
			Handler:       _Common_DutShell_Handler,
			ServerStreams: true,
		},
	},
	Metadata: "tls/common.proto",
}
