// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.36.11
// 	protoc        v4.25.8
// source: voltha_protos/inter_adapter.proto

package inter_adapter

import (
	common "github.com/opencord/voltha-protos/v5/go/common"
	openolt "github.com/opencord/voltha-protos/v5/go/openolt"
	tech_profile "github.com/opencord/voltha-protos/v5/go/tech_profile"
	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
	unsafe "unsafe"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

type OmciMessage struct {
	state          protoimpl.MessageState      `protogen:"open.v1"`
	Message        []byte                      `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
	ConnectStatus  common.ConnectStatus_Types  `protobuf:"varint,2,opt,name=connect_status,json=connectStatus,proto3,enum=common.ConnectStatus_Types" json:"connect_status,omitempty"`
	ProxyAddress   *voltha.Device_ProxyAddress `protobuf:"bytes,3,opt,name=proxy_address,json=proxyAddress,proto3" json:"proxy_address,omitempty"`
	ParentDeviceId string                      `protobuf:"bytes,4,opt,name=parent_device_id,json=parentDeviceId,proto3" json:"parent_device_id,omitempty"`
	ChildDeviceId  string                      `protobuf:"bytes,5,opt,name=child_device_id,json=childDeviceId,proto3" json:"child_device_id,omitempty"`
	unknownFields  protoimpl.UnknownFields
	sizeCache      protoimpl.SizeCache
}

func (x *OmciMessage) Reset() {
	*x = OmciMessage{}
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[0]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *OmciMessage) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*OmciMessage) ProtoMessage() {}

func (x *OmciMessage) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[0]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use OmciMessage.ProtoReflect.Descriptor instead.
func (*OmciMessage) Descriptor() ([]byte, []int) {
	return file_voltha_protos_inter_adapter_proto_rawDescGZIP(), []int{0}
}

func (x *OmciMessage) GetMessage() []byte {
	if x != nil {
		return x.Message
	}
	return nil
}

func (x *OmciMessage) GetConnectStatus() common.ConnectStatus_Types {
	if x != nil {
		return x.ConnectStatus
	}
	return common.ConnectStatus_Types(0)
}

func (x *OmciMessage) GetProxyAddress() *voltha.Device_ProxyAddress {
	if x != nil {
		return x.ProxyAddress
	}
	return nil
}

func (x *OmciMessage) GetParentDeviceId() string {
	if x != nil {
		return x.ParentDeviceId
	}
	return ""
}

func (x *OmciMessage) GetChildDeviceId() string {
	if x != nil {
		return x.ChildDeviceId
	}
	return ""
}

type OmciMessages struct {
	state          protoimpl.MessageState      `protogen:"open.v1"`
	Messages       [][]byte                    `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"`
	ConnectStatus  common.ConnectStatus_Types  `protobuf:"varint,2,opt,name=connect_status,json=connectStatus,proto3,enum=common.ConnectStatus_Types" json:"connect_status,omitempty"`
	ProxyAddress   *voltha.Device_ProxyAddress `protobuf:"bytes,3,opt,name=proxy_address,json=proxyAddress,proto3" json:"proxy_address,omitempty"`
	ParentDeviceId string                      `protobuf:"bytes,4,opt,name=parent_device_id,json=parentDeviceId,proto3" json:"parent_device_id,omitempty"`
	ChildDeviceId  string                      `protobuf:"bytes,5,opt,name=child_device_id,json=childDeviceId,proto3" json:"child_device_id,omitempty"`
	unknownFields  protoimpl.UnknownFields
	sizeCache      protoimpl.SizeCache
}

func (x *OmciMessages) Reset() {
	*x = OmciMessages{}
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[1]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *OmciMessages) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*OmciMessages) ProtoMessage() {}

func (x *OmciMessages) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[1]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use OmciMessages.ProtoReflect.Descriptor instead.
func (*OmciMessages) Descriptor() ([]byte, []int) {
	return file_voltha_protos_inter_adapter_proto_rawDescGZIP(), []int{1}
}

func (x *OmciMessages) GetMessages() [][]byte {
	if x != nil {
		return x.Messages
	}
	return nil
}

func (x *OmciMessages) GetConnectStatus() common.ConnectStatus_Types {
	if x != nil {
		return x.ConnectStatus
	}
	return common.ConnectStatus_Types(0)
}

func (x *OmciMessages) GetProxyAddress() *voltha.Device_ProxyAddress {
	if x != nil {
		return x.ProxyAddress
	}
	return nil
}

func (x *OmciMessages) GetParentDeviceId() string {
	if x != nil {
		return x.ParentDeviceId
	}
	return ""
}

func (x *OmciMessages) GetChildDeviceId() string {
	if x != nil {
		return x.ChildDeviceId
	}
	return ""
}

type TechProfileDownloadMessage struct {
	state          protoimpl.MessageState `protogen:"open.v1"`
	DeviceId       string                 `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
	UniId          uint32                 `protobuf:"varint,2,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
	TpInstancePath string                 `protobuf:"bytes,3,opt,name=tp_instance_path,json=tpInstancePath,proto3" json:"tp_instance_path,omitempty"`
	// Types that are valid to be assigned to TechTpInstance:
	//
	//	*TechProfileDownloadMessage_TpInstance
	//	*TechProfileDownloadMessage_EponTpInstance
	TechTpInstance isTechProfileDownloadMessage_TechTpInstance `protobuf_oneof:"tech_tp_instance"`
	unknownFields  protoimpl.UnknownFields
	sizeCache      protoimpl.SizeCache
}

func (x *TechProfileDownloadMessage) Reset() {
	*x = TechProfileDownloadMessage{}
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[2]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *TechProfileDownloadMessage) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*TechProfileDownloadMessage) ProtoMessage() {}

func (x *TechProfileDownloadMessage) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[2]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use TechProfileDownloadMessage.ProtoReflect.Descriptor instead.
func (*TechProfileDownloadMessage) Descriptor() ([]byte, []int) {
	return file_voltha_protos_inter_adapter_proto_rawDescGZIP(), []int{2}
}

func (x *TechProfileDownloadMessage) GetDeviceId() string {
	if x != nil {
		return x.DeviceId
	}
	return ""
}

func (x *TechProfileDownloadMessage) GetUniId() uint32 {
	if x != nil {
		return x.UniId
	}
	return 0
}

func (x *TechProfileDownloadMessage) GetTpInstancePath() string {
	if x != nil {
		return x.TpInstancePath
	}
	return ""
}

func (x *TechProfileDownloadMessage) GetTechTpInstance() isTechProfileDownloadMessage_TechTpInstance {
	if x != nil {
		return x.TechTpInstance
	}
	return nil
}

func (x *TechProfileDownloadMessage) GetTpInstance() *tech_profile.TechProfileInstance {
	if x != nil {
		if x, ok := x.TechTpInstance.(*TechProfileDownloadMessage_TpInstance); ok {
			return x.TpInstance
		}
	}
	return nil
}

func (x *TechProfileDownloadMessage) GetEponTpInstance() *tech_profile.EponTechProfileInstance {
	if x != nil {
		if x, ok := x.TechTpInstance.(*TechProfileDownloadMessage_EponTpInstance); ok {
			return x.EponTpInstance
		}
	}
	return nil
}

type isTechProfileDownloadMessage_TechTpInstance interface {
	isTechProfileDownloadMessage_TechTpInstance()
}

type TechProfileDownloadMessage_TpInstance struct {
	TpInstance *tech_profile.TechProfileInstance `protobuf:"bytes,4,opt,name=tp_instance,json=tpInstance,proto3,oneof"` // relevant for GPON, XGPON and XGS-PON technologies
}

type TechProfileDownloadMessage_EponTpInstance struct {
	EponTpInstance *tech_profile.EponTechProfileInstance `protobuf:"bytes,5,opt,name=epon_tp_instance,json=eponTpInstance,proto3,oneof"` // relevant for EPON technology
}

func (*TechProfileDownloadMessage_TpInstance) isTechProfileDownloadMessage_TechTpInstance() {}

func (*TechProfileDownloadMessage_EponTpInstance) isTechProfileDownloadMessage_TechTpInstance() {}

type DeleteGemPortMessage struct {
	state          protoimpl.MessageState `protogen:"open.v1"`
	DeviceId       string                 `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
	UniId          uint32                 `protobuf:"varint,2,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
	TpInstancePath string                 `protobuf:"bytes,3,opt,name=tp_instance_path,json=tpInstancePath,proto3" json:"tp_instance_path,omitempty"`
	GemPortId      uint32                 `protobuf:"varint,4,opt,name=gem_port_id,json=gemPortId,proto3" json:"gem_port_id,omitempty"`
	unknownFields  protoimpl.UnknownFields
	sizeCache      protoimpl.SizeCache
}

func (x *DeleteGemPortMessage) Reset() {
	*x = DeleteGemPortMessage{}
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[3]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *DeleteGemPortMessage) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*DeleteGemPortMessage) ProtoMessage() {}

func (x *DeleteGemPortMessage) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[3]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use DeleteGemPortMessage.ProtoReflect.Descriptor instead.
func (*DeleteGemPortMessage) Descriptor() ([]byte, []int) {
	return file_voltha_protos_inter_adapter_proto_rawDescGZIP(), []int{3}
}

func (x *DeleteGemPortMessage) GetDeviceId() string {
	if x != nil {
		return x.DeviceId
	}
	return ""
}

func (x *DeleteGemPortMessage) GetUniId() uint32 {
	if x != nil {
		return x.UniId
	}
	return 0
}

func (x *DeleteGemPortMessage) GetTpInstancePath() string {
	if x != nil {
		return x.TpInstancePath
	}
	return ""
}

func (x *DeleteGemPortMessage) GetGemPortId() uint32 {
	if x != nil {
		return x.GemPortId
	}
	return 0
}

type DeleteTcontMessage struct {
	state          protoimpl.MessageState `protogen:"open.v1"`
	DeviceId       string                 `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
	UniId          uint32                 `protobuf:"varint,2,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
	TpInstancePath string                 `protobuf:"bytes,3,opt,name=tp_instance_path,json=tpInstancePath,proto3" json:"tp_instance_path,omitempty"`
	AllocId        uint32                 `protobuf:"varint,4,opt,name=alloc_id,json=allocId,proto3" json:"alloc_id,omitempty"`
	unknownFields  protoimpl.UnknownFields
	sizeCache      protoimpl.SizeCache
}

func (x *DeleteTcontMessage) Reset() {
	*x = DeleteTcontMessage{}
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[4]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *DeleteTcontMessage) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*DeleteTcontMessage) ProtoMessage() {}

func (x *DeleteTcontMessage) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[4]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use DeleteTcontMessage.ProtoReflect.Descriptor instead.
func (*DeleteTcontMessage) Descriptor() ([]byte, []int) {
	return file_voltha_protos_inter_adapter_proto_rawDescGZIP(), []int{4}
}

func (x *DeleteTcontMessage) GetDeviceId() string {
	if x != nil {
		return x.DeviceId
	}
	return ""
}

func (x *DeleteTcontMessage) GetUniId() uint32 {
	if x != nil {
		return x.UniId
	}
	return 0
}

func (x *DeleteTcontMessage) GetTpInstancePath() string {
	if x != nil {
		return x.TpInstancePath
	}
	return ""
}

func (x *DeleteTcontMessage) GetAllocId() uint32 {
	if x != nil {
		return x.AllocId
	}
	return 0
}

type OnuIndicationMessage struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	DeviceId      string                 `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
	OnuIndication *openolt.OnuIndication `protobuf:"bytes,2,opt,name=onu_indication,json=onuIndication,proto3" json:"onu_indication,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

func (x *OnuIndicationMessage) Reset() {
	*x = OnuIndicationMessage{}
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[5]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *OnuIndicationMessage) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*OnuIndicationMessage) ProtoMessage() {}

func (x *OnuIndicationMessage) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[5]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use OnuIndicationMessage.ProtoReflect.Descriptor instead.
func (*OnuIndicationMessage) Descriptor() ([]byte, []int) {
	return file_voltha_protos_inter_adapter_proto_rawDescGZIP(), []int{5}
}

func (x *OnuIndicationMessage) GetDeviceId() string {
	if x != nil {
		return x.DeviceId
	}
	return ""
}

func (x *OnuIndicationMessage) GetOnuIndication() *openolt.OnuIndication {
	if x != nil {
		return x.OnuIndication
	}
	return nil
}

type TechProfileInstanceRequestMessage struct {
	state          protoimpl.MessageState `protogen:"open.v1"`
	DeviceId       string                 `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
	TpInstancePath string                 `protobuf:"bytes,2,opt,name=tp_instance_path,json=tpInstancePath,proto3" json:"tp_instance_path,omitempty"` // technology profile instance path
	ParentDeviceId string                 `protobuf:"bytes,3,opt,name=parent_device_id,json=parentDeviceId,proto3" json:"parent_device_id,omitempty"`
	ParentPonPort  uint32                 `protobuf:"varint,4,opt,name=parent_pon_port,json=parentPonPort,proto3" json:"parent_pon_port,omitempty"`
	OnuId          uint32                 `protobuf:"varint,5,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
	UniId          uint32                 `protobuf:"varint,6,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
	unknownFields  protoimpl.UnknownFields
	sizeCache      protoimpl.SizeCache
}

func (x *TechProfileInstanceRequestMessage) Reset() {
	*x = TechProfileInstanceRequestMessage{}
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[6]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *TechProfileInstanceRequestMessage) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*TechProfileInstanceRequestMessage) ProtoMessage() {}

func (x *TechProfileInstanceRequestMessage) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_inter_adapter_proto_msgTypes[6]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use TechProfileInstanceRequestMessage.ProtoReflect.Descriptor instead.
func (*TechProfileInstanceRequestMessage) Descriptor() ([]byte, []int) {
	return file_voltha_protos_inter_adapter_proto_rawDescGZIP(), []int{6}
}

func (x *TechProfileInstanceRequestMessage) GetDeviceId() string {
	if x != nil {
		return x.DeviceId
	}
	return ""
}

func (x *TechProfileInstanceRequestMessage) GetTpInstancePath() string {
	if x != nil {
		return x.TpInstancePath
	}
	return ""
}

func (x *TechProfileInstanceRequestMessage) GetParentDeviceId() string {
	if x != nil {
		return x.ParentDeviceId
	}
	return ""
}

func (x *TechProfileInstanceRequestMessage) GetParentPonPort() uint32 {
	if x != nil {
		return x.ParentPonPort
	}
	return 0
}

func (x *TechProfileInstanceRequestMessage) GetOnuId() uint32 {
	if x != nil {
		return x.OnuId
	}
	return 0
}

func (x *TechProfileInstanceRequestMessage) GetUniId() uint32 {
	if x != nil {
		return x.UniId
	}
	return 0
}

var File_voltha_protos_inter_adapter_proto protoreflect.FileDescriptor

const file_voltha_protos_inter_adapter_proto_rawDesc = "" +
	"\n" +
	"!voltha_protos/inter_adapter.proto\x12\rinter_adapter\x1a\x1avoltha_protos/common.proto\x1a\x1avoltha_protos/voltha.proto\x1a voltha_protos/tech_profile.proto\x1a\x1bvoltha_protos/openolt.proto\x1a\x1avoltha_protos/device.proto\"\xff\x01\n" +
	"\vOmciMessage\x12\x18\n" +
	"\amessage\x18\x01 \x01(\fR\amessage\x12B\n" +
	"\x0econnect_status\x18\x02 \x01(\x0e2\x1b.common.ConnectStatus.TypesR\rconnectStatus\x12@\n" +
	"\rproxy_address\x18\x03 \x01(\v2\x1b.device.Device.ProxyAddressR\fproxyAddress\x12(\n" +
	"\x10parent_device_id\x18\x04 \x01(\tR\x0eparentDeviceId\x12&\n" +
	"\x0fchild_device_id\x18\x05 \x01(\tR\rchildDeviceId\"\x82\x02\n" +
	"\fOmciMessages\x12\x1a\n" +
	"\bmessages\x18\x01 \x03(\fR\bmessages\x12B\n" +
	"\x0econnect_status\x18\x02 \x01(\x0e2\x1b.common.ConnectStatus.TypesR\rconnectStatus\x12@\n" +
	"\rproxy_address\x18\x03 \x01(\v2\x1b.device.Device.ProxyAddressR\fproxyAddress\x12(\n" +
	"\x10parent_device_id\x18\x04 \x01(\tR\x0eparentDeviceId\x12&\n" +
	"\x0fchild_device_id\x18\x05 \x01(\tR\rchildDeviceId\"\xa7\x02\n" +
	"\x1aTechProfileDownloadMessage\x12\x1b\n" +
	"\tdevice_id\x18\x01 \x01(\tR\bdeviceId\x12\x15\n" +
	"\x06uni_id\x18\x02 \x01(\rR\x05uniId\x12(\n" +
	"\x10tp_instance_path\x18\x03 \x01(\tR\x0etpInstancePath\x12D\n" +
	"\vtp_instance\x18\x04 \x01(\v2!.tech_profile.TechProfileInstanceH\x00R\n" +
	"tpInstance\x12Q\n" +
	"\x10epon_tp_instance\x18\x05 \x01(\v2%.tech_profile.EponTechProfileInstanceH\x00R\x0eeponTpInstanceB\x12\n" +
	"\x10tech_tp_instance\"\x94\x01\n" +
	"\x14DeleteGemPortMessage\x12\x1b\n" +
	"\tdevice_id\x18\x01 \x01(\tR\bdeviceId\x12\x15\n" +
	"\x06uni_id\x18\x02 \x01(\rR\x05uniId\x12(\n" +
	"\x10tp_instance_path\x18\x03 \x01(\tR\x0etpInstancePath\x12\x1e\n" +
	"\vgem_port_id\x18\x04 \x01(\rR\tgemPortId\"\x8d\x01\n" +
	"\x12DeleteTcontMessage\x12\x1b\n" +
	"\tdevice_id\x18\x01 \x01(\tR\bdeviceId\x12\x15\n" +
	"\x06uni_id\x18\x02 \x01(\rR\x05uniId\x12(\n" +
	"\x10tp_instance_path\x18\x03 \x01(\tR\x0etpInstancePath\x12\x19\n" +
	"\balloc_id\x18\x04 \x01(\rR\aallocId\"r\n" +
	"\x14OnuIndicationMessage\x12\x1b\n" +
	"\tdevice_id\x18\x01 \x01(\tR\bdeviceId\x12=\n" +
	"\x0eonu_indication\x18\x02 \x01(\v2\x16.openolt.OnuIndicationR\ronuIndication\"\xea\x01\n" +
	"!TechProfileInstanceRequestMessage\x12\x1b\n" +
	"\tdevice_id\x18\x01 \x01(\tR\bdeviceId\x12(\n" +
	"\x10tp_instance_path\x18\x02 \x01(\tR\x0etpInstancePath\x12(\n" +
	"\x10parent_device_id\x18\x03 \x01(\tR\x0eparentDeviceId\x12&\n" +
	"\x0fparent_pon_port\x18\x04 \x01(\rR\rparentPonPort\x12\x15\n" +
	"\x06onu_id\x18\x05 \x01(\rR\x05onuId\x12\x15\n" +
	"\x06uni_id\x18\x06 \x01(\rR\x05uniIdBZ\n" +
	"!org.opencord.voltha.inter_adapterZ5github.com/opencord/voltha-protos/v5/go/inter_adapterb\x06proto3"

var (
	file_voltha_protos_inter_adapter_proto_rawDescOnce sync.Once
	file_voltha_protos_inter_adapter_proto_rawDescData []byte
)

func file_voltha_protos_inter_adapter_proto_rawDescGZIP() []byte {
	file_voltha_protos_inter_adapter_proto_rawDescOnce.Do(func() {
		file_voltha_protos_inter_adapter_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_voltha_protos_inter_adapter_proto_rawDesc), len(file_voltha_protos_inter_adapter_proto_rawDesc)))
	})
	return file_voltha_protos_inter_adapter_proto_rawDescData
}

var file_voltha_protos_inter_adapter_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_voltha_protos_inter_adapter_proto_goTypes = []any{
	(*OmciMessage)(nil),                          // 0: inter_adapter.OmciMessage
	(*OmciMessages)(nil),                         // 1: inter_adapter.OmciMessages
	(*TechProfileDownloadMessage)(nil),           // 2: inter_adapter.TechProfileDownloadMessage
	(*DeleteGemPortMessage)(nil),                 // 3: inter_adapter.DeleteGemPortMessage
	(*DeleteTcontMessage)(nil),                   // 4: inter_adapter.DeleteTcontMessage
	(*OnuIndicationMessage)(nil),                 // 5: inter_adapter.OnuIndicationMessage
	(*TechProfileInstanceRequestMessage)(nil),    // 6: inter_adapter.TechProfileInstanceRequestMessage
	(common.ConnectStatus_Types)(0),              // 7: common.ConnectStatus.Types
	(*voltha.Device_ProxyAddress)(nil),           // 8: device.Device.ProxyAddress
	(*tech_profile.TechProfileInstance)(nil),     // 9: tech_profile.TechProfileInstance
	(*tech_profile.EponTechProfileInstance)(nil), // 10: tech_profile.EponTechProfileInstance
	(*openolt.OnuIndication)(nil),                // 11: openolt.OnuIndication
}
var file_voltha_protos_inter_adapter_proto_depIdxs = []int32{
	7,  // 0: inter_adapter.OmciMessage.connect_status:type_name -> common.ConnectStatus.Types
	8,  // 1: inter_adapter.OmciMessage.proxy_address:type_name -> device.Device.ProxyAddress
	7,  // 2: inter_adapter.OmciMessages.connect_status:type_name -> common.ConnectStatus.Types
	8,  // 3: inter_adapter.OmciMessages.proxy_address:type_name -> device.Device.ProxyAddress
	9,  // 4: inter_adapter.TechProfileDownloadMessage.tp_instance:type_name -> tech_profile.TechProfileInstance
	10, // 5: inter_adapter.TechProfileDownloadMessage.epon_tp_instance:type_name -> tech_profile.EponTechProfileInstance
	11, // 6: inter_adapter.OnuIndicationMessage.onu_indication:type_name -> openolt.OnuIndication
	7,  // [7:7] is the sub-list for method output_type
	7,  // [7:7] is the sub-list for method input_type
	7,  // [7:7] is the sub-list for extension type_name
	7,  // [7:7] is the sub-list for extension extendee
	0,  // [0:7] is the sub-list for field type_name
}

func init() { file_voltha_protos_inter_adapter_proto_init() }
func file_voltha_protos_inter_adapter_proto_init() {
	if File_voltha_protos_inter_adapter_proto != nil {
		return
	}
	file_voltha_protos_inter_adapter_proto_msgTypes[2].OneofWrappers = []any{
		(*TechProfileDownloadMessage_TpInstance)(nil),
		(*TechProfileDownloadMessage_EponTpInstance)(nil),
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: unsafe.Slice(unsafe.StringData(file_voltha_protos_inter_adapter_proto_rawDesc), len(file_voltha_protos_inter_adapter_proto_rawDesc)),
			NumEnums:      0,
			NumMessages:   7,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_voltha_protos_inter_adapter_proto_goTypes,
		DependencyIndexes: file_voltha_protos_inter_adapter_proto_depIdxs,
		MessageInfos:      file_voltha_protos_inter_adapter_proto_msgTypes,
	}.Build()
	File_voltha_protos_inter_adapter_proto = out.File
	file_voltha_protos_inter_adapter_proto_goTypes = nil
	file_voltha_protos_inter_adapter_proto_depIdxs = nil
}
