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

package voltha

import (
	openflow_13 "github.com/opencord/voltha-protos/v5/go/openflow_13"
	_ "google.golang.org/genproto/googleapis/api/annotations"
	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 LogicalPortId struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// unique id of logical device
	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	// id of the port on the logical device
	PortId        string `protobuf:"bytes,2,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*LogicalPortId) ProtoMessage() {}

func (x *LogicalPortId) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_logical_device_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 LogicalPortId.ProtoReflect.Descriptor instead.
func (*LogicalPortId) Descriptor() ([]byte, []int) {
	return file_voltha_protos_logical_device_proto_rawDescGZIP(), []int{0}
}

func (x *LogicalPortId) GetId() string {
	if x != nil {
		return x.Id
	}
	return ""
}

func (x *LogicalPortId) GetPortId() string {
	if x != nil {
		return x.PortId
	}
	return ""
}

type LogicalPort struct {
	state         protoimpl.MessageState    `protogen:"open.v1"`
	Id            string                    `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	OfpPort       *openflow_13.OfpPort      `protobuf:"bytes,2,opt,name=ofp_port,json=ofpPort,proto3" json:"ofp_port,omitempty"`
	DeviceId      string                    `protobuf:"bytes,3,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
	DevicePortNo  uint32                    `protobuf:"varint,4,opt,name=device_port_no,json=devicePortNo,proto3" json:"device_port_no,omitempty"`
	RootPort      bool                      `protobuf:"varint,5,opt,name=root_port,json=rootPort,proto3" json:"root_port,omitempty"`
	OfpPortStats  *openflow_13.OfpPortStats `protobuf:"bytes,6,opt,name=ofp_port_stats,json=ofpPortStats,proto3" json:"ofp_port_stats,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*LogicalPort) ProtoMessage() {}

func (x *LogicalPort) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_logical_device_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 LogicalPort.ProtoReflect.Descriptor instead.
func (*LogicalPort) Descriptor() ([]byte, []int) {
	return file_voltha_protos_logical_device_proto_rawDescGZIP(), []int{1}
}

func (x *LogicalPort) GetId() string {
	if x != nil {
		return x.Id
	}
	return ""
}

func (x *LogicalPort) GetOfpPort() *openflow_13.OfpPort {
	if x != nil {
		return x.OfpPort
	}
	return nil
}

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

func (x *LogicalPort) GetDevicePortNo() uint32 {
	if x != nil {
		return x.DevicePortNo
	}
	return 0
}

func (x *LogicalPort) GetRootPort() bool {
	if x != nil {
		return x.RootPort
	}
	return false
}

func (x *LogicalPort) GetOfpPortStats() *openflow_13.OfpPortStats {
	if x != nil {
		return x.OfpPortStats
	}
	return nil
}

type LogicalPorts struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Items         []*LogicalPort         `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*LogicalPorts) ProtoMessage() {}

func (x *LogicalPorts) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_logical_device_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 LogicalPorts.ProtoReflect.Descriptor instead.
func (*LogicalPorts) Descriptor() ([]byte, []int) {
	return file_voltha_protos_logical_device_proto_rawDescGZIP(), []int{2}
}

func (x *LogicalPorts) GetItems() []*LogicalPort {
	if x != nil {
		return x.Items
	}
	return nil
}

type LogicalDevice struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// unique id of logical device
	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	// unique datapath id for the logical device (used by the SDN controller)
	DatapathId uint64 `protobuf:"varint,2,opt,name=datapath_id,json=datapathId,proto3" json:"datapath_id,omitempty"`
	// device description
	Desc *openflow_13.OfpDesc `protobuf:"bytes,3,opt,name=desc,proto3" json:"desc,omitempty"`
	// device features
	SwitchFeatures *openflow_13.OfpSwitchFeatures `protobuf:"bytes,4,opt,name=switch_features,json=switchFeatures,proto3" json:"switch_features,omitempty"`
	// name of the root device anchoring logical device
	RootDeviceId  string `protobuf:"bytes,5,opt,name=root_device_id,json=rootDeviceId,proto3" json:"root_device_id,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*LogicalDevice) ProtoMessage() {}

func (x *LogicalDevice) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_logical_device_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 LogicalDevice.ProtoReflect.Descriptor instead.
func (*LogicalDevice) Descriptor() ([]byte, []int) {
	return file_voltha_protos_logical_device_proto_rawDescGZIP(), []int{3}
}

func (x *LogicalDevice) GetId() string {
	if x != nil {
		return x.Id
	}
	return ""
}

func (x *LogicalDevice) GetDatapathId() uint64 {
	if x != nil {
		return x.DatapathId
	}
	return 0
}

func (x *LogicalDevice) GetDesc() *openflow_13.OfpDesc {
	if x != nil {
		return x.Desc
	}
	return nil
}

func (x *LogicalDevice) GetSwitchFeatures() *openflow_13.OfpSwitchFeatures {
	if x != nil {
		return x.SwitchFeatures
	}
	return nil
}

func (x *LogicalDevice) GetRootDeviceId() string {
	if x != nil {
		return x.RootDeviceId
	}
	return ""
}

type LogicalDevices struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Items         []*LogicalDevice       `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*LogicalDevices) ProtoMessage() {}

func (x *LogicalDevices) ProtoReflect() protoreflect.Message {
	mi := &file_voltha_protos_logical_device_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 LogicalDevices.ProtoReflect.Descriptor instead.
func (*LogicalDevices) Descriptor() ([]byte, []int) {
	return file_voltha_protos_logical_device_proto_rawDescGZIP(), []int{4}
}

func (x *LogicalDevices) GetItems() []*LogicalDevice {
	if x != nil {
		return x.Items
	}
	return nil
}

var File_voltha_protos_logical_device_proto protoreflect.FileDescriptor

const file_voltha_protos_logical_device_proto_rawDesc = "" +
	"\n" +
	"\"voltha_protos/logical_device.proto\x12\x0elogical_device\x1a\x1cgoogle/api/annotations.proto\x1a\x1fvoltha_protos/openflow_13.proto\"8\n" +
	"\rLogicalPortId\x12\x0e\n" +
	"\x02id\x18\x01 \x01(\tR\x02id\x12\x17\n" +
	"\aport_id\x18\x02 \x01(\tR\x06portId\"\xf2\x01\n" +
	"\vLogicalPort\x12\x0e\n" +
	"\x02id\x18\x01 \x01(\tR\x02id\x120\n" +
	"\bofp_port\x18\x02 \x01(\v2\x15.openflow_13.ofp_portR\aofpPort\x12\x1b\n" +
	"\tdevice_id\x18\x03 \x01(\tR\bdeviceId\x12$\n" +
	"\x0edevice_port_no\x18\x04 \x01(\rR\fdevicePortNo\x12\x1b\n" +
	"\troot_port\x18\x05 \x01(\bR\brootPort\x12A\n" +
	"\x0eofp_port_stats\x18\x06 \x01(\v2\x1b.openflow_13.ofp_port_statsR\fofpPortStats\"A\n" +
	"\fLogicalPorts\x121\n" +
	"\x05items\x18\x01 \x03(\v2\x1b.logical_device.LogicalPortR\x05items\"\xdc\x01\n" +
	"\rLogicalDevice\x12\x0e\n" +
	"\x02id\x18\x01 \x01(\tR\x02id\x12\x1f\n" +
	"\vdatapath_id\x18\x02 \x01(\x04R\n" +
	"datapathId\x12)\n" +
	"\x04desc\x18\x03 \x01(\v2\x15.openflow_13.ofp_descR\x04desc\x12I\n" +
	"\x0fswitch_features\x18\x04 \x01(\v2 .openflow_13.ofp_switch_featuresR\x0eswitchFeatures\x12$\n" +
	"\x0eroot_device_id\x18\x05 \x01(\tR\frootDeviceId\"E\n" +
	"\x0eLogicalDevices\x123\n" +
	"\x05items\x18\x01 \x03(\v2\x1d.logical_device.LogicalDeviceR\x05itemsBe\n" +
	"\"org.opencord.voltha.logical_deviceB\x0fOFLogicalDeviceZ.github.com/opencord/voltha-protos/v5/go/volthab\x06proto3"

var (
	file_voltha_protos_logical_device_proto_rawDescOnce sync.Once
	file_voltha_protos_logical_device_proto_rawDescData []byte
)

func file_voltha_protos_logical_device_proto_rawDescGZIP() []byte {
	file_voltha_protos_logical_device_proto_rawDescOnce.Do(func() {
		file_voltha_protos_logical_device_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_voltha_protos_logical_device_proto_rawDesc), len(file_voltha_protos_logical_device_proto_rawDesc)))
	})
	return file_voltha_protos_logical_device_proto_rawDescData
}

var file_voltha_protos_logical_device_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_voltha_protos_logical_device_proto_goTypes = []any{
	(*LogicalPortId)(nil),                 // 0: logical_device.LogicalPortId
	(*LogicalPort)(nil),                   // 1: logical_device.LogicalPort
	(*LogicalPorts)(nil),                  // 2: logical_device.LogicalPorts
	(*LogicalDevice)(nil),                 // 3: logical_device.LogicalDevice
	(*LogicalDevices)(nil),                // 4: logical_device.LogicalDevices
	(*openflow_13.OfpPort)(nil),           // 5: openflow_13.ofp_port
	(*openflow_13.OfpPortStats)(nil),      // 6: openflow_13.ofp_port_stats
	(*openflow_13.OfpDesc)(nil),           // 7: openflow_13.ofp_desc
	(*openflow_13.OfpSwitchFeatures)(nil), // 8: openflow_13.ofp_switch_features
}
var file_voltha_protos_logical_device_proto_depIdxs = []int32{
	5, // 0: logical_device.LogicalPort.ofp_port:type_name -> openflow_13.ofp_port
	6, // 1: logical_device.LogicalPort.ofp_port_stats:type_name -> openflow_13.ofp_port_stats
	1, // 2: logical_device.LogicalPorts.items:type_name -> logical_device.LogicalPort
	7, // 3: logical_device.LogicalDevice.desc:type_name -> openflow_13.ofp_desc
	8, // 4: logical_device.LogicalDevice.switch_features:type_name -> openflow_13.ofp_switch_features
	3, // 5: logical_device.LogicalDevices.items:type_name -> logical_device.LogicalDevice
	6, // [6:6] is the sub-list for method output_type
	6, // [6:6] is the sub-list for method input_type
	6, // [6:6] is the sub-list for extension type_name
	6, // [6:6] is the sub-list for extension extendee
	0, // [0:6] is the sub-list for field type_name
}

func init() { file_voltha_protos_logical_device_proto_init() }
func file_voltha_protos_logical_device_proto_init() {
	if File_voltha_protos_logical_device_proto != nil {
		return
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: unsafe.Slice(unsafe.StringData(file_voltha_protos_logical_device_proto_rawDesc), len(file_voltha_protos_logical_device_proto_rawDesc)),
			NumEnums:      0,
			NumMessages:   5,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_voltha_protos_logical_device_proto_goTypes,
		DependencyIndexes: file_voltha_protos_logical_device_proto_depIdxs,
		MessageInfos:      file_voltha_protos_logical_device_proto_msgTypes,
	}.Build()
	File_voltha_protos_logical_device_proto = out.File
	file_voltha_protos_logical_device_proto_goTypes = nil
	file_voltha_protos_logical_device_proto_depIdxs = nil
}
