// Code generated by protoc-gen-go. DO NOT EDIT.
// source: api/bbsim/bbsim_dmi.proto

package bbsim

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 DmiEvent struct {
	EventName            string   `protobuf:"bytes,1,opt,name=event_name,json=eventName,proto3" json:"event_name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_DmiEvent proto.InternalMessageInfo

func (m *DmiEvent) GetEventName() string {
	if m != nil {
		return m.EventName
	}
	return ""
}

type DmiCreateEventResponse struct {
	StatusCode           int32    `protobuf:"varint,1,opt,name=status_code,json=statusCode,proto3" json:"status_code,omitempty"`
	Message              string   `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_DmiCreateEventResponse proto.InternalMessageInfo

func (m *DmiCreateEventResponse) GetStatusCode() int32 {
	if m != nil {
		return m.StatusCode
	}
	return 0
}

func (m *DmiCreateEventResponse) GetMessage() string {
	if m != nil {
		return m.Message
	}
	return ""
}

func init() {
	proto.RegisterType((*DmiEvent)(nil), "bbsim.DmiEvent")
	proto.RegisterType((*DmiCreateEventResponse)(nil), "bbsim.DmiCreateEventResponse")
}

func init() { proto.RegisterFile("api/bbsim/bbsim_dmi.proto", fileDescriptor_49e784b4938902cc) }

var fileDescriptor_49e784b4938902cc = []byte{
	// 216 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x31, 0x4b, 0xc5, 0x30,
	0x14, 0x85, 0x7d, 0xc2, 0x53, 0x7b, 0xdf, 0x20, 0x64, 0x90, 0x2a, 0x3c, 0x94, 0x8a, 0xa0, 0x4b,
	0x0a, 0xfa, 0x03, 0x84, 0xb6, 0x6e, 0xe2, 0x50, 0x37, 0x97, 0x92, 0x34, 0x97, 0x9a, 0xe1, 0xe6,
	0x86, 0x26, 0xf5, 0xf7, 0x8b, 0x69, 0xab, 0x0e, 0x6f, 0x09, 0xb9, 0x1f, 0x9c, 0xc3, 0xc7, 0x81,
	0x4b, 0xe5, 0x6d, 0xa9, 0x75, 0xb0, 0x34, 0xbf, 0x9d, 0x21, 0x2b, 0xfd, 0xc8, 0x91, 0xc5, 0x36,
	0x81, 0xe2, 0x01, 0xce, 0x1a, 0xb2, 0x2f, 0x5f, 0xe8, 0xa2, 0xd8, 0x03, 0xe0, 0xcf, 0xa7, 0x73,
	0x8a, 0x30, 0xdf, 0xdc, 0x6c, 0xee, 0xb3, 0x36, 0x4b, 0xe4, 0x4d, 0x11, 0x16, 0xef, 0x70, 0xd1,
	0x90, 0xad, 0x47, 0x54, 0x11, 0x53, 0xa0, 0xc5, 0xe0, 0xd9, 0x05, 0x14, 0xd7, 0xb0, 0x0b, 0x51,
	0xc5, 0x29, 0x74, 0x3d, 0x9b, 0x39, 0xb9, 0x6d, 0x61, 0x46, 0x35, 0x1b, 0x14, 0x39, 0x9c, 0x12,
	0x86, 0xa0, 0x06, 0xcc, 0x8f, 0x53, 0xed, 0x7a, 0x3e, 0xbe, 0x42, 0x56, 0x55, 0x8b, 0x99, 0x78,
	0x86, 0xdd, 0xbf, 0x7a, 0x71, 0x2e, 0x93, 0xa3, 0x5c, 0x05, 0xaf, 0xf6, 0x7f, 0xe0, 0x80, 0x46,
	0x71, 0x54, 0xdd, 0x7d, 0xdc, 0x0e, 0x36, 0x7e, 0x4e, 0x5a, 0xf6, 0x4c, 0x25, 0x7b, 0x74, 0x3d,
	0x8f, 0x66, 0x59, 0xe0, 0x77, 0x0b, 0x7d, 0x92, 0x26, 0x78, 0xfa, 0x0e, 0x00, 0x00, 0xff, 0xff,
	0xd2, 0x6b, 0xb3, 0x25, 0x1f, 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

// BBsimDmiClient is the client API for BBsimDmi service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type BBsimDmiClient interface {
	// Ask the DMI Server to create an event
	CreateEvent(ctx context.Context, in *DmiEvent, opts ...grpc.CallOption) (*DmiCreateEventResponse, error)
}

type bBsimDmiClient struct {
	cc *grpc.ClientConn
}

func NewBBsimDmiClient(cc *grpc.ClientConn) BBsimDmiClient {
	return &bBsimDmiClient{cc}
}

func (c *bBsimDmiClient) CreateEvent(ctx context.Context, in *DmiEvent, opts ...grpc.CallOption) (*DmiCreateEventResponse, error) {
	out := new(DmiCreateEventResponse)
	err := c.cc.Invoke(ctx, "/bbsim.BBsim_dmi/CreateEvent", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// BBsimDmiServer is the server API for BBsimDmi service.
type BBsimDmiServer interface {
	// Ask the DMI Server to create an event
	CreateEvent(context.Context, *DmiEvent) (*DmiCreateEventResponse, error)
}

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

func (*UnimplementedBBsimDmiServer) CreateEvent(ctx context.Context, req *DmiEvent) (*DmiCreateEventResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method CreateEvent not implemented")
}

func RegisterBBsimDmiServer(s *grpc.Server, srv BBsimDmiServer) {
	s.RegisterService(&_BBsimDmi_serviceDesc, srv)
}

func _BBsimDmi_CreateEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(DmiEvent)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(BBsimDmiServer).CreateEvent(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/bbsim.BBsim_dmi/CreateEvent",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(BBsimDmiServer).CreateEvent(ctx, req.(*DmiEvent))
	}
	return interceptor(ctx, in, info, handler)
}

var _BBsimDmi_serviceDesc = grpc.ServiceDesc{
	ServiceName: "bbsim.BBsim_dmi",
	HandlerType: (*BBsimDmiServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "CreateEvent",
			Handler:    _BBsimDmi_CreateEvent_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "api/bbsim/bbsim_dmi.proto",
}
