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

package voltha

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	anypb "google.golang.org/protobuf/types/known/anypb"
	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 AdapterConfig struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// Custom (vendor-specific) configuration attributes
	AdditionalConfig *anypb.Any `protobuf:"bytes,64,opt,name=additional_config,json=additionalConfig,proto3" json:"additional_config,omitempty"`
	unknownFields    protoimpl.UnknownFields
	sizeCache        protoimpl.SizeCache
}

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

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

func (*AdapterConfig) ProtoMessage() {}

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

func (x *AdapterConfig) GetAdditionalConfig() *anypb.Any {
	if x != nil {
		return x.AdditionalConfig
	}
	return nil
}

// Adapter (software plugin)
type Adapter struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// the adapter ID has to be unique,
	// it will be generated as Type + CurrentReplica
	Id      string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	Vendor  string `protobuf:"bytes,2,opt,name=vendor,proto3" json:"vendor,omitempty"`
	Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`
	// Adapter configuration
	Config *AdapterConfig `protobuf:"bytes,16,opt,name=config,proto3" json:"config,omitempty"`
	// Custom descriptors and custom configuration
	AdditionalDescription *anypb.Any `protobuf:"bytes,64,opt,name=additional_description,json=additionalDescription,proto3" json:"additional_description,omitempty"`
	LogicalDeviceIds      []string   `protobuf:"bytes,4,rep,name=logical_device_ids,json=logicalDeviceIds,proto3" json:"logical_device_ids,omitempty"` // Logical devices "owned"
	// timestamp when the adapter last sent a message to the core
	LastCommunication int64  `protobuf:"varint,5,opt,name=last_communication,json=lastCommunication,proto3" json:"last_communication,omitempty"`
	CurrentReplica    int32  `protobuf:"varint,6,opt,name=currentReplica,proto3" json:"currentReplica,omitempty"`
	TotalReplicas     int32  `protobuf:"varint,7,opt,name=totalReplicas,proto3" json:"totalReplicas,omitempty"`
	Endpoint          string `protobuf:"bytes,8,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
	// all replicas of the same adapter will have the same type
	// it is used to associate a device to an adapter
	Type          string `protobuf:"bytes,9,opt,name=type,proto3" json:"type,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*Adapter) ProtoMessage() {}

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

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

func (x *Adapter) GetVendor() string {
	if x != nil {
		return x.Vendor
	}
	return ""
}

func (x *Adapter) GetVersion() string {
	if x != nil {
		return x.Version
	}
	return ""
}

func (x *Adapter) GetConfig() *AdapterConfig {
	if x != nil {
		return x.Config
	}
	return nil
}

func (x *Adapter) GetAdditionalDescription() *anypb.Any {
	if x != nil {
		return x.AdditionalDescription
	}
	return nil
}

func (x *Adapter) GetLogicalDeviceIds() []string {
	if x != nil {
		return x.LogicalDeviceIds
	}
	return nil
}

func (x *Adapter) GetLastCommunication() int64 {
	if x != nil {
		return x.LastCommunication
	}
	return 0
}

func (x *Adapter) GetCurrentReplica() int32 {
	if x != nil {
		return x.CurrentReplica
	}
	return 0
}

func (x *Adapter) GetTotalReplicas() int32 {
	if x != nil {
		return x.TotalReplicas
	}
	return 0
}

func (x *Adapter) GetEndpoint() string {
	if x != nil {
		return x.Endpoint
	}
	return ""
}

func (x *Adapter) GetType() string {
	if x != nil {
		return x.Type
	}
	return ""
}

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

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

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

func (*Adapters) ProtoMessage() {}

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

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

var File_voltha_protos_adapter_proto protoreflect.FileDescriptor

const file_voltha_protos_adapter_proto_rawDesc = "" +
	"\n" +
	"\x1bvoltha_protos/adapter.proto\x12\aadapter\x1a\x19google/protobuf/any.proto\"R\n" +
	"\rAdapterConfig\x12A\n" +
	"\x11additional_config\x18@ \x01(\v2\x14.google.protobuf.AnyR\x10additionalConfig\"\xa3\x03\n" +
	"\aAdapter\x12\x0e\n" +
	"\x02id\x18\x01 \x01(\tR\x02id\x12\x16\n" +
	"\x06vendor\x18\x02 \x01(\tR\x06vendor\x12\x18\n" +
	"\aversion\x18\x03 \x01(\tR\aversion\x12.\n" +
	"\x06config\x18\x10 \x01(\v2\x16.adapter.AdapterConfigR\x06config\x12K\n" +
	"\x16additional_description\x18@ \x01(\v2\x14.google.protobuf.AnyR\x15additionalDescription\x12,\n" +
	"\x12logical_device_ids\x18\x04 \x03(\tR\x10logicalDeviceIds\x12-\n" +
	"\x12last_communication\x18\x05 \x01(\x03R\x11lastCommunication\x12&\n" +
	"\x0ecurrentReplica\x18\x06 \x01(\x05R\x0ecurrentReplica\x12$\n" +
	"\rtotalReplicas\x18\a \x01(\x05R\rtotalReplicas\x12\x1a\n" +
	"\bendpoint\x18\b \x01(\tR\bendpoint\x12\x12\n" +
	"\x04type\x18\t \x01(\tR\x04type\"2\n" +
	"\bAdapters\x12&\n" +
	"\x05items\x18\x01 \x03(\v2\x10.adapter.AdapterR\x05itemsB\\\n" +
	"\x1borg.opencord.voltha.adapterB\rVolthaAdapterZ.github.com/opencord/voltha-protos/v5/go/volthab\x06proto3"

var (
	file_voltha_protos_adapter_proto_rawDescOnce sync.Once
	file_voltha_protos_adapter_proto_rawDescData []byte
)

func file_voltha_protos_adapter_proto_rawDescGZIP() []byte {
	file_voltha_protos_adapter_proto_rawDescOnce.Do(func() {
		file_voltha_protos_adapter_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_voltha_protos_adapter_proto_rawDesc), len(file_voltha_protos_adapter_proto_rawDesc)))
	})
	return file_voltha_protos_adapter_proto_rawDescData
}

var file_voltha_protos_adapter_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_voltha_protos_adapter_proto_goTypes = []any{
	(*AdapterConfig)(nil), // 0: adapter.AdapterConfig
	(*Adapter)(nil),       // 1: adapter.Adapter
	(*Adapters)(nil),      // 2: adapter.Adapters
	(*anypb.Any)(nil),     // 3: google.protobuf.Any
}
var file_voltha_protos_adapter_proto_depIdxs = []int32{
	3, // 0: adapter.AdapterConfig.additional_config:type_name -> google.protobuf.Any
	0, // 1: adapter.Adapter.config:type_name -> adapter.AdapterConfig
	3, // 2: adapter.Adapter.additional_description:type_name -> google.protobuf.Any
	1, // 3: adapter.Adapters.items:type_name -> adapter.Adapter
	4, // [4:4] is the sub-list for method output_type
	4, // [4:4] is the sub-list for method input_type
	4, // [4:4] is the sub-list for extension type_name
	4, // [4:4] is the sub-list for extension extendee
	0, // [0:4] is the sub-list for field type_name
}

func init() { file_voltha_protos_adapter_proto_init() }
func file_voltha_protos_adapter_proto_init() {
	if File_voltha_protos_adapter_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_adapter_proto_rawDesc), len(file_voltha_protos_adapter_proto_rawDesc)),
			NumEnums:      0,
			NumMessages:   3,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_voltha_protos_adapter_proto_goTypes,
		DependencyIndexes: file_voltha_protos_adapter_proto_depIdxs,
		MessageInfos:      file_voltha_protos_adapter_proto_msgTypes,
	}.Build()
	File_voltha_protos_adapter_proto = out.File
	file_voltha_protos_adapter_proto_goTypes = nil
	file_voltha_protos_adapter_proto_depIdxs = nil
}
