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

package dmi

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

type PhysicalInventoryRequest struct {
	DeviceUuid           *Uuid    `protobuf:"bytes,1,opt,name=device_uuid,json=deviceUuid,proto3" json:"device_uuid,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_PhysicalInventoryRequest proto.InternalMessageInfo

func (m *PhysicalInventoryRequest) GetDeviceUuid() *Uuid {
	if m != nil {
		return m.DeviceUuid
	}
	return nil
}

type PhysicalInventoryResponse struct {
	Status               Status    `protobuf:"varint,1,opt,name=status,proto3,enum=dmi.Status" json:"status,omitempty"`
	Reason               Reason    `protobuf:"varint,2,opt,name=reason,proto3,enum=dmi.Reason" json:"reason,omitempty"`
	Inventory            *Hardware `protobuf:"bytes,3,opt,name=inventory,proto3" json:"inventory,omitempty"`
	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
	XXX_unrecognized     []byte    `json:"-"`
	XXX_sizecache        int32     `json:"-"`
}

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

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

var xxx_messageInfo_PhysicalInventoryResponse proto.InternalMessageInfo

func (m *PhysicalInventoryResponse) GetStatus() Status {
	if m != nil {
		return m.Status
	}
	return Status_UNDEFINED_STATUS
}

func (m *PhysicalInventoryResponse) GetReason() Reason {
	if m != nil {
		return m.Reason
	}
	return Reason_UNDEFINED_REASON
}

func (m *PhysicalInventoryResponse) GetInventory() *Hardware {
	if m != nil {
		return m.Inventory
	}
	return nil
}

type HWComponentInfoGetRequest struct {
	DeviceUuid           *Uuid    `protobuf:"bytes,1,opt,name=device_uuid,json=deviceUuid,proto3" json:"device_uuid,omitempty"`
	ComponentUuid        *Uuid    `protobuf:"bytes,2,opt,name=component_uuid,json=componentUuid,proto3" json:"component_uuid,omitempty"`
	ComponentName        string   `protobuf:"bytes,3,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *HWComponentInfoGetRequest) Reset()         { *m = HWComponentInfoGetRequest{} }
func (m *HWComponentInfoGetRequest) String() string { return proto.CompactTextString(m) }
func (*HWComponentInfoGetRequest) ProtoMessage()    {}
func (*HWComponentInfoGetRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_eae902e73066286d, []int{2}
}

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

var xxx_messageInfo_HWComponentInfoGetRequest proto.InternalMessageInfo

func (m *HWComponentInfoGetRequest) GetDeviceUuid() *Uuid {
	if m != nil {
		return m.DeviceUuid
	}
	return nil
}

func (m *HWComponentInfoGetRequest) GetComponentUuid() *Uuid {
	if m != nil {
		return m.ComponentUuid
	}
	return nil
}

func (m *HWComponentInfoGetRequest) GetComponentName() string {
	if m != nil {
		return m.ComponentName
	}
	return ""
}

type HWComponentInfoSetRequest struct {
	DeviceUuid           *Uuid                `protobuf:"bytes,1,opt,name=device_uuid,json=deviceUuid,proto3" json:"device_uuid,omitempty"`
	ComponentUuid        *Uuid                `protobuf:"bytes,2,opt,name=component_uuid,json=componentUuid,proto3" json:"component_uuid,omitempty"`
	ComponentName        string               `protobuf:"bytes,3,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"`
	Changes              *ModifiableComponent `protobuf:"bytes,4,opt,name=changes,proto3" json:"changes,omitempty"`
	XXX_NoUnkeyedLiteral struct{}             `json:"-"`
	XXX_unrecognized     []byte               `json:"-"`
	XXX_sizecache        int32                `json:"-"`
}

func (m *HWComponentInfoSetRequest) Reset()         { *m = HWComponentInfoSetRequest{} }
func (m *HWComponentInfoSetRequest) String() string { return proto.CompactTextString(m) }
func (*HWComponentInfoSetRequest) ProtoMessage()    {}
func (*HWComponentInfoSetRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_eae902e73066286d, []int{3}
}

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

var xxx_messageInfo_HWComponentInfoSetRequest proto.InternalMessageInfo

func (m *HWComponentInfoSetRequest) GetDeviceUuid() *Uuid {
	if m != nil {
		return m.DeviceUuid
	}
	return nil
}

func (m *HWComponentInfoSetRequest) GetComponentUuid() *Uuid {
	if m != nil {
		return m.ComponentUuid
	}
	return nil
}

func (m *HWComponentInfoSetRequest) GetComponentName() string {
	if m != nil {
		return m.ComponentName
	}
	return ""
}

func (m *HWComponentInfoSetRequest) GetChanges() *ModifiableComponent {
	if m != nil {
		return m.Changes
	}
	return nil
}

type HWComponentInfoSetResponse struct {
	Status               Status   `protobuf:"varint,1,opt,name=status,proto3,enum=dmi.Status" json:"status,omitempty"`
	Reason               Reason   `protobuf:"varint,2,opt,name=reason,proto3,enum=dmi.Reason" json:"reason,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *HWComponentInfoSetResponse) Reset()         { *m = HWComponentInfoSetResponse{} }
func (m *HWComponentInfoSetResponse) String() string { return proto.CompactTextString(m) }
func (*HWComponentInfoSetResponse) ProtoMessage()    {}
func (*HWComponentInfoSetResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_eae902e73066286d, []int{4}
}

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

var xxx_messageInfo_HWComponentInfoSetResponse proto.InternalMessageInfo

func (m *HWComponentInfoSetResponse) GetStatus() Status {
	if m != nil {
		return m.Status
	}
	return Status_UNDEFINED_STATUS
}

func (m *HWComponentInfoSetResponse) GetReason() Reason {
	if m != nil {
		return m.Reason
	}
	return Reason_UNDEFINED_REASON
}

type StartManagingDeviceResponse struct {
	Status               Status   `protobuf:"varint,1,opt,name=status,proto3,enum=dmi.Status" json:"status,omitempty"`
	Reason               Reason   `protobuf:"varint,2,opt,name=reason,proto3,enum=dmi.Reason" json:"reason,omitempty"`
	DeviceUuid           *Uuid    `protobuf:"bytes,3,opt,name=device_uuid,json=deviceUuid,proto3" json:"device_uuid,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *StartManagingDeviceResponse) Reset()         { *m = StartManagingDeviceResponse{} }
func (m *StartManagingDeviceResponse) String() string { return proto.CompactTextString(m) }
func (*StartManagingDeviceResponse) ProtoMessage()    {}
func (*StartManagingDeviceResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_eae902e73066286d, []int{5}
}

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

var xxx_messageInfo_StartManagingDeviceResponse proto.InternalMessageInfo

func (m *StartManagingDeviceResponse) GetStatus() Status {
	if m != nil {
		return m.Status
	}
	return Status_UNDEFINED_STATUS
}

func (m *StartManagingDeviceResponse) GetReason() Reason {
	if m != nil {
		return m.Reason
	}
	return Reason_UNDEFINED_REASON
}

func (m *StartManagingDeviceResponse) GetDeviceUuid() *Uuid {
	if m != nil {
		return m.DeviceUuid
	}
	return nil
}

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

func (m *StopManagingDeviceRequest) Reset()         { *m = StopManagingDeviceRequest{} }
func (m *StopManagingDeviceRequest) String() string { return proto.CompactTextString(m) }
func (*StopManagingDeviceRequest) ProtoMessage()    {}
func (*StopManagingDeviceRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_eae902e73066286d, []int{6}
}

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

var xxx_messageInfo_StopManagingDeviceRequest proto.InternalMessageInfo

func (m *StopManagingDeviceRequest) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

type StopManagingDeviceResponse struct {
	Status               Status   `protobuf:"varint,1,opt,name=status,proto3,enum=dmi.Status" json:"status,omitempty"`
	Reason               Reason   `protobuf:"varint,2,opt,name=reason,proto3,enum=dmi.Reason" json:"reason,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *StopManagingDeviceResponse) Reset()         { *m = StopManagingDeviceResponse{} }
func (m *StopManagingDeviceResponse) String() string { return proto.CompactTextString(m) }
func (*StopManagingDeviceResponse) ProtoMessage()    {}
func (*StopManagingDeviceResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_eae902e73066286d, []int{7}
}

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

var xxx_messageInfo_StopManagingDeviceResponse proto.InternalMessageInfo

func (m *StopManagingDeviceResponse) GetStatus() Status {
	if m != nil {
		return m.Status
	}
	return Status_UNDEFINED_STATUS
}

func (m *StopManagingDeviceResponse) GetReason() Reason {
	if m != nil {
		return m.Reason
	}
	return Reason_UNDEFINED_REASON
}

func init() {
	proto.RegisterType((*PhysicalInventoryRequest)(nil), "dmi.PhysicalInventoryRequest")
	proto.RegisterType((*PhysicalInventoryResponse)(nil), "dmi.PhysicalInventoryResponse")
	proto.RegisterType((*HWComponentInfoGetRequest)(nil), "dmi.HWComponentInfoGetRequest")
	proto.RegisterType((*HWComponentInfoSetRequest)(nil), "dmi.HWComponentInfoSetRequest")
	proto.RegisterType((*HWComponentInfoSetResponse)(nil), "dmi.HWComponentInfoSetResponse")
	proto.RegisterType((*StartManagingDeviceResponse)(nil), "dmi.StartManagingDeviceResponse")
	proto.RegisterType((*StopManagingDeviceRequest)(nil), "dmi.StopManagingDeviceRequest")
	proto.RegisterType((*StopManagingDeviceResponse)(nil), "dmi.StopManagingDeviceResponse")
}

func init() { proto.RegisterFile("dmi/hw_management_service.proto", fileDescriptor_eae902e73066286d) }

var fileDescriptor_eae902e73066286d = []byte{
	// 527 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0xd1, 0x6a, 0x13, 0x41,
	0x14, 0x65, 0x9b, 0x52, 0xc9, 0x8d, 0x0d, 0x38, 0xfa, 0xb0, 0x59, 0xb1, 0x2d, 0x2b, 0x82, 0x28,
	0xcd, 0x96, 0xf4, 0x49, 0x7c, 0x53, 0x69, 0xd2, 0x87, 0x14, 0xd9, 0xa5, 0x04, 0x7c, 0x09, 0x93,
	0x9d, 0x9b, 0x64, 0xa0, 0x33, 0xb3, 0xee, 0xcc, 0xa6, 0xf4, 0x37, 0xf4, 0x07, 0xfc, 0x13, 0x7f,
	0xc2, 0x0f, 0x92, 0x9d, 0xdd, 0x6c, 0x42, 0x92, 0x15, 0x91, 0x0a, 0x7d, 0xdb, 0xcc, 0x39, 0xf7,
	0x70, 0xee, 0x99, 0xb9, 0x37, 0x70, 0xcc, 0x04, 0x0f, 0xe6, 0xb7, 0x63, 0x41, 0x25, 0x9d, 0xa1,
	0x40, 0x69, 0xc6, 0x1a, 0xd3, 0x05, 0x8f, 0xb1, 0x9b, 0xa4, 0xca, 0x28, 0xd2, 0x60, 0x82, 0x7b,
	0x4f, 0x72, 0x56, 0xac, 0x84, 0x50, 0x52, 0x17, 0xe7, 0xde, 0xe3, 0xa2, 0xb0, 0xf8, 0xe5, 0x5f,
	0x80, 0xfb, 0x79, 0x7e, 0xa7, 0x79, 0x4c, 0x6f, 0x2e, 0xe5, 0x02, 0xa5, 0x51, 0xe9, 0x5d, 0x88,
	0x5f, 0x33, 0xd4, 0x86, 0xbc, 0x81, 0x16, 0xc3, 0x5c, 0x71, 0x9c, 0x65, 0x9c, 0xb9, 0xce, 0x89,
	0xf3, 0xba, 0xd5, 0x6b, 0x76, 0x99, 0xe0, 0xdd, 0xeb, 0x8c, 0xb3, 0x10, 0x0a, 0x34, 0xff, 0xf6,
	0xbf, 0x39, 0xd0, 0xd9, 0x21, 0xa4, 0x13, 0x25, 0x35, 0x92, 0x97, 0x70, 0xa0, 0x0d, 0x35, 0x99,
	0xb6, 0x22, 0xed, 0x5e, 0xcb, 0x8a, 0x44, 0xf6, 0x28, 0x2c, 0xa1, 0x9c, 0x94, 0x22, 0xd5, 0x4a,
	0xba, 0x7b, 0x6b, 0xa4, 0xd0, 0x1e, 0x85, 0x25, 0x44, 0xde, 0x42, 0x93, 0x2f, 0xe5, 0xdd, 0x86,
	0x75, 0x74, 0x68, 0x79, 0x03, 0x9a, 0xb2, 0x5b, 0x9a, 0x62, 0xb8, 0xc2, 0xfd, 0x1f, 0x0e, 0x74,
	0x06, 0xa3, 0x8f, 0x4a, 0x24, 0x4a, 0xa2, 0x34, 0x97, 0x72, 0xaa, 0xfa, 0x68, 0xfe, 0xa1, 0x3d,
	0x72, 0x06, 0xed, 0x78, 0x29, 0x53, 0xd0, 0xf7, 0x36, 0xe9, 0x87, 0x15, 0xc1, 0x56, 0xbc, 0x5a,
	0xaf, 0x90, 0x54, 0xa0, 0x75, 0xdb, 0x5c, 0xa3, 0x5d, 0x51, 0x81, 0xfe, 0xaf, 0x6d, 0x8b, 0xd1,
	0xc3, 0xb2, 0x48, 0x7a, 0xf0, 0x28, 0x9e, 0x53, 0x39, 0x43, 0xed, 0xee, 0x5b, 0x45, 0xd7, 0x2a,
	0x0e, 0x15, 0xe3, 0x53, 0x4e, 0x27, 0x37, 0x58, 0xb9, 0x0f, 0x97, 0x44, 0x7f, 0x0a, 0xde, 0xae,
	0xae, 0xee, 0xfb, 0x39, 0xf8, 0xdf, 0x1d, 0x78, 0x1e, 0x19, 0x9a, 0x9a, 0x61, 0x3e, 0x06, 0x5c,
	0xce, 0x3e, 0xd9, 0x40, 0xfe, 0xc3, 0xc3, 0xdb, 0xb8, 0x8a, 0xc6, 0x9f, 0x86, 0x21, 0x80, 0x4e,
	0x64, 0x54, 0xb2, 0xe9, 0xa9, 0xb8, 0x53, 0x02, 0xfb, 0x36, 0x6b, 0xc7, 0x66, 0x6d, 0xbf, 0xf3,
	0xb8, 0x76, 0x15, 0xdc, 0x77, 0x13, 0xbd, 0x9f, 0x0d, 0xe8, 0x5c, 0x51, 0xc3, 0x17, 0x38, 0x18,
	0x0d, 0xab, 0xc5, 0x11, 0x15, 0x7b, 0x83, 0x44, 0xf0, 0x74, 0x47, 0x96, 0xa4, 0xf6, 0xba, 0xbd,
	0x93, 0xa5, 0x91, 0xba, 0xfc, 0xcf, 0x1c, 0x72, 0x0d, 0x64, 0xbb, 0x35, 0x72, 0x54, 0x56, 0xd6,
	0x84, 0xe4, 0x1d, 0xd7, 0xe2, 0x65, 0x26, 0x23, 0x78, 0xd6, 0x47, 0xb3, 0xb5, 0x71, 0xc8, 0x0b,
	0x5b, 0x58, 0xb7, 0xd2, 0xbc, 0xa3, 0x3a, 0xb8, 0xf2, 0x7b, 0x01, 0xa4, 0x8f, 0x66, 0xe3, 0xf1,
	0x96, 0x7e, 0x6b, 0x77, 0x89, 0xd7, 0xb6, 0x78, 0x85, 0x96, 0x7d, 0xff, 0xa5, 0xce, 0x6a, 0xe0,
	0xcb, 0xbe, 0xeb, 0x47, 0xe7, 0xc3, 0xfb, 0x2f, 0xef, 0x66, 0xdc, 0xcc, 0xb3, 0x49, 0x37, 0x56,
	0x22, 0x50, 0x09, 0xca, 0x58, 0xa5, 0x2c, 0x28, 0x1e, 0xdf, 0xe9, 0xea, 0xcf, 0xe0, 0x94, 0x4b,
	0x83, 0xe9, 0x94, 0xc6, 0x18, 0x2c, 0xce, 0x83, 0x99, 0x0a, 0x98, 0xe0, 0x93, 0x03, 0xbb, 0xf3,
	0xcf, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x47, 0xf4, 0xba, 0x3c, 0x06, 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

// NativeHWManagementServiceClient is the client API for NativeHWManagementService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type NativeHWManagementServiceClient interface {
	// Initializes context for a device and sets up required states
	// In the call to StartManagingDevice, the fields of ModifiableComponent which are relevant
	// and their meanings in this context is mentioned below:
	// name = The unique name that needs to be assigned to this hardware;
	// class = COMPONENT_TYPE_UNDEFINED;
	// parent = nil;
	// alias = Optional;
	// asset_id = Optional;
	// uri = IP Address of the Hardware;
	StartManagingDevice(ctx context.Context, in *ModifiableComponent, opts ...grpc.CallOption) (NativeHWManagementService_StartManagingDeviceClient, error)
	// Stop management of a device and clean up any context and caches for that device
	StopManagingDevice(ctx context.Context, in *StopManagingDeviceRequest, opts ...grpc.CallOption) (*StopManagingDeviceResponse, error)
	// Get the HW inventory details of the Device
	GetPhysicalInventory(ctx context.Context, in *PhysicalInventoryRequest, opts ...grpc.CallOption) (NativeHWManagementService_GetPhysicalInventoryClient, error)
	// Get the details of a particular HW component
	GetHWComponentInfo(ctx context.Context, in *HWComponentInfoGetRequest, opts ...grpc.CallOption) (NativeHWManagementService_GetHWComponentInfoClient, error)
	// Sets the permissible attributes of a HW component
	SetHWComponentInfo(ctx context.Context, in *HWComponentInfoSetRequest, opts ...grpc.CallOption) (*HWComponentInfoSetResponse, error)
}

type nativeHWManagementServiceClient struct {
	cc *grpc.ClientConn
}

func NewNativeHWManagementServiceClient(cc *grpc.ClientConn) NativeHWManagementServiceClient {
	return &nativeHWManagementServiceClient{cc}
}

func (c *nativeHWManagementServiceClient) StartManagingDevice(ctx context.Context, in *ModifiableComponent, opts ...grpc.CallOption) (NativeHWManagementService_StartManagingDeviceClient, error) {
	stream, err := c.cc.NewStream(ctx, &_NativeHWManagementService_serviceDesc.Streams[0], "/dmi.NativeHWManagementService/StartManagingDevice", opts...)
	if err != nil {
		return nil, err
	}
	x := &nativeHWManagementServiceStartManagingDeviceClient{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 NativeHWManagementService_StartManagingDeviceClient interface {
	Recv() (*StartManagingDeviceResponse, error)
	grpc.ClientStream
}

type nativeHWManagementServiceStartManagingDeviceClient struct {
	grpc.ClientStream
}

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

func (c *nativeHWManagementServiceClient) StopManagingDevice(ctx context.Context, in *StopManagingDeviceRequest, opts ...grpc.CallOption) (*StopManagingDeviceResponse, error) {
	out := new(StopManagingDeviceResponse)
	err := c.cc.Invoke(ctx, "/dmi.NativeHWManagementService/StopManagingDevice", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *nativeHWManagementServiceClient) GetPhysicalInventory(ctx context.Context, in *PhysicalInventoryRequest, opts ...grpc.CallOption) (NativeHWManagementService_GetPhysicalInventoryClient, error) {
	stream, err := c.cc.NewStream(ctx, &_NativeHWManagementService_serviceDesc.Streams[1], "/dmi.NativeHWManagementService/GetPhysicalInventory", opts...)
	if err != nil {
		return nil, err
	}
	x := &nativeHWManagementServiceGetPhysicalInventoryClient{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 NativeHWManagementService_GetPhysicalInventoryClient interface {
	Recv() (*PhysicalInventoryResponse, error)
	grpc.ClientStream
}

type nativeHWManagementServiceGetPhysicalInventoryClient struct {
	grpc.ClientStream
}

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

func (c *nativeHWManagementServiceClient) GetHWComponentInfo(ctx context.Context, in *HWComponentInfoGetRequest, opts ...grpc.CallOption) (NativeHWManagementService_GetHWComponentInfoClient, error) {
	stream, err := c.cc.NewStream(ctx, &_NativeHWManagementService_serviceDesc.Streams[2], "/dmi.NativeHWManagementService/GetHWComponentInfo", opts...)
	if err != nil {
		return nil, err
	}
	x := &nativeHWManagementServiceGetHWComponentInfoClient{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 NativeHWManagementService_GetHWComponentInfoClient interface {
	Recv() (*Component, error)
	grpc.ClientStream
}

type nativeHWManagementServiceGetHWComponentInfoClient struct {
	grpc.ClientStream
}

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

func (c *nativeHWManagementServiceClient) SetHWComponentInfo(ctx context.Context, in *HWComponentInfoSetRequest, opts ...grpc.CallOption) (*HWComponentInfoSetResponse, error) {
	out := new(HWComponentInfoSetResponse)
	err := c.cc.Invoke(ctx, "/dmi.NativeHWManagementService/SetHWComponentInfo", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// NativeHWManagementServiceServer is the server API for NativeHWManagementService service.
type NativeHWManagementServiceServer interface {
	// Initializes context for a device and sets up required states
	// In the call to StartManagingDevice, the fields of ModifiableComponent which are relevant
	// and their meanings in this context is mentioned below:
	// name = The unique name that needs to be assigned to this hardware;
	// class = COMPONENT_TYPE_UNDEFINED;
	// parent = nil;
	// alias = Optional;
	// asset_id = Optional;
	// uri = IP Address of the Hardware;
	StartManagingDevice(*ModifiableComponent, NativeHWManagementService_StartManagingDeviceServer) error
	// Stop management of a device and clean up any context and caches for that device
	StopManagingDevice(context.Context, *StopManagingDeviceRequest) (*StopManagingDeviceResponse, error)
	// Get the HW inventory details of the Device
	GetPhysicalInventory(*PhysicalInventoryRequest, NativeHWManagementService_GetPhysicalInventoryServer) error
	// Get the details of a particular HW component
	GetHWComponentInfo(*HWComponentInfoGetRequest, NativeHWManagementService_GetHWComponentInfoServer) error
	// Sets the permissible attributes of a HW component
	SetHWComponentInfo(context.Context, *HWComponentInfoSetRequest) (*HWComponentInfoSetResponse, error)
}

func RegisterNativeHWManagementServiceServer(s *grpc.Server, srv NativeHWManagementServiceServer) {
	s.RegisterService(&_NativeHWManagementService_serviceDesc, srv)
}

func _NativeHWManagementService_StartManagingDevice_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(ModifiableComponent)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(NativeHWManagementServiceServer).StartManagingDevice(m, &nativeHWManagementServiceStartManagingDeviceServer{stream})
}

type NativeHWManagementService_StartManagingDeviceServer interface {
	Send(*StartManagingDeviceResponse) error
	grpc.ServerStream
}

type nativeHWManagementServiceStartManagingDeviceServer struct {
	grpc.ServerStream
}

func (x *nativeHWManagementServiceStartManagingDeviceServer) Send(m *StartManagingDeviceResponse) error {
	return x.ServerStream.SendMsg(m)
}

func _NativeHWManagementService_StopManagingDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(StopManagingDeviceRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(NativeHWManagementServiceServer).StopManagingDevice(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/dmi.NativeHWManagementService/StopManagingDevice",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(NativeHWManagementServiceServer).StopManagingDevice(ctx, req.(*StopManagingDeviceRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _NativeHWManagementService_GetPhysicalInventory_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(PhysicalInventoryRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(NativeHWManagementServiceServer).GetPhysicalInventory(m, &nativeHWManagementServiceGetPhysicalInventoryServer{stream})
}

type NativeHWManagementService_GetPhysicalInventoryServer interface {
	Send(*PhysicalInventoryResponse) error
	grpc.ServerStream
}

type nativeHWManagementServiceGetPhysicalInventoryServer struct {
	grpc.ServerStream
}

func (x *nativeHWManagementServiceGetPhysicalInventoryServer) Send(m *PhysicalInventoryResponse) error {
	return x.ServerStream.SendMsg(m)
}

func _NativeHWManagementService_GetHWComponentInfo_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(HWComponentInfoGetRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(NativeHWManagementServiceServer).GetHWComponentInfo(m, &nativeHWManagementServiceGetHWComponentInfoServer{stream})
}

type NativeHWManagementService_GetHWComponentInfoServer interface {
	Send(*Component) error
	grpc.ServerStream
}

type nativeHWManagementServiceGetHWComponentInfoServer struct {
	grpc.ServerStream
}

func (x *nativeHWManagementServiceGetHWComponentInfoServer) Send(m *Component) error {
	return x.ServerStream.SendMsg(m)
}

func _NativeHWManagementService_SetHWComponentInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(HWComponentInfoSetRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(NativeHWManagementServiceServer).SetHWComponentInfo(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/dmi.NativeHWManagementService/SetHWComponentInfo",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(NativeHWManagementServiceServer).SetHWComponentInfo(ctx, req.(*HWComponentInfoSetRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _NativeHWManagementService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "dmi.NativeHWManagementService",
	HandlerType: (*NativeHWManagementServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "StopManagingDevice",
			Handler:    _NativeHWManagementService_StopManagingDevice_Handler,
		},
		{
			MethodName: "SetHWComponentInfo",
			Handler:    _NativeHWManagementService_SetHWComponentInfo_Handler,
		},
	},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "StartManagingDevice",
			Handler:       _NativeHWManagementService_StartManagingDevice_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "GetPhysicalInventory",
			Handler:       _NativeHWManagementService_GetPhysicalInventory_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "GetHWComponentInfo",
			Handler:       _NativeHWManagementService_GetHWComponentInfo_Handler,
			ServerStreams: true,
		},
	},
	Metadata: "dmi/hw_management_service.proto",
}
