// gpu_driver_versions.proto schema

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.36.6
// 	protoc        v3.21.12
// source: gpu_driver_versions.proto

package pb

import (
	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)
)

// Represents a supported host driver version for vGPU.
type HostDriverVersion struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Version       string                 `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` // more metadata about host driver versions.
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*HostDriverVersion) ProtoMessage() {}

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

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

// Represents all the information about a GPU driver version.
// It contains the GPU driver version label (e.g., "default", "latest"), and the GPU driver version that is associated with that label.
type DriverVersion struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// GPU driver version label.
	Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"`
	// The driver version that is associated with this label.
	Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
	// List of supported host driver versions for vGPU.
	SupportedHostVersions []*HostDriverVersion `protobuf:"bytes,3,rep,name=supported_host_versions,json=supportedHostVersions,proto3" json:"supported_host_versions,omitempty"` // more metadata about the driver version.
	unknownFields         protoimpl.UnknownFields
	sizeCache             protoimpl.SizeCache
}

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

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

func (*DriverVersion) ProtoMessage() {}

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

func (x *DriverVersion) GetLabel() string {
	if x != nil {
		return x.Label
	}
	return ""
}

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

func (x *DriverVersion) GetSupportedHostVersions() []*HostDriverVersion {
	if x != nil {
		return x.SupportedHostVersions
	}
	return nil
}

// Represents the information about a GPU device.
type GPUDevice struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// GPU type.
	GpuType string `protobuf:"bytes,1,opt,name=gpu_type,json=gpuType,proto3" json:"gpu_type,omitempty"`
	// Indicates if GPU device is virtual
	IsVgpu        bool `protobuf:"varint,2,opt,name=is_vgpu,json=isVgpu,proto3" json:"is_vgpu,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*GPUDevice) ProtoMessage() {}

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

func (x *GPUDevice) GetGpuType() string {
	if x != nil {
		return x.GpuType
	}
	return ""
}

func (x *GPUDevice) GetIsVgpu() bool {
	if x != nil {
		return x.IsVgpu
	}
	return false
}

// Represents GPU driver version information for a specific GPU type, mapping from GPU type to GPU driver version information.
type GPUDriverVersionInfo struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// Encapsulated GPU device info
	GpuDevice *GPUDevice `protobuf:"bytes,1,opt,name=gpu_device,json=gpuDevice,proto3" json:"gpu_device,omitempty"`
	// A repeated field to hold list of GPU driver versions with the associated labels that are built by cos.
	// it is something like: <{"latest","535.129.11"}, ...>
	SupportedDriverVersions []*DriverVersion `protobuf:"bytes,2,rep,name=supported_driver_versions,json=supportedDriverVersions,proto3" json:"supported_driver_versions,omitempty"`
	unknownFields           protoimpl.UnknownFields
	sizeCache               protoimpl.SizeCache
}

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

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

func (*GPUDriverVersionInfo) ProtoMessage() {}

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

func (x *GPUDriverVersionInfo) GetGpuDevice() *GPUDevice {
	if x != nil {
		return x.GpuDevice
	}
	return nil
}

func (x *GPUDriverVersionInfo) GetSupportedDriverVersions() []*DriverVersion {
	if x != nil {
		return x.SupportedDriverVersions
	}
	return nil
}

// Represents a list of GPU driver version information.
type GPUDriverVersionInfoList struct {
	state                protoimpl.MessageState  `protogen:"open.v1"`
	GpuDriverVersionInfo []*GPUDriverVersionInfo `protobuf:"bytes,1,rep,name=gpu_driver_version_info,json=gpuDriverVersionInfo,proto3" json:"gpu_driver_version_info,omitempty"`
	unknownFields        protoimpl.UnknownFields
	sizeCache            protoimpl.SizeCache
}

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

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

func (*GPUDriverVersionInfoList) ProtoMessage() {}

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

func (x *GPUDriverVersionInfoList) GetGpuDriverVersionInfo() []*GPUDriverVersionInfo {
	if x != nil {
		return x.GpuDriverVersionInfo
	}
	return nil
}

var File_gpu_driver_versions_proto protoreflect.FileDescriptor

const file_gpu_driver_versions_proto_rawDesc = "" +
	"\n" +
	"\x19gpu_driver_versions.proto\x12\x02pb\"-\n" +
	"\x11HostDriverVersion\x12\x18\n" +
	"\aversion\x18\x01 \x01(\tR\aversion\"\x8e\x01\n" +
	"\rDriverVersion\x12\x14\n" +
	"\x05label\x18\x01 \x01(\tR\x05label\x12\x18\n" +
	"\aversion\x18\x02 \x01(\tR\aversion\x12M\n" +
	"\x17supported_host_versions\x18\x03 \x03(\v2\x15.pb.HostDriverVersionR\x15supportedHostVersions\"?\n" +
	"\tGPUDevice\x12\x19\n" +
	"\bgpu_type\x18\x01 \x01(\tR\agpuType\x12\x17\n" +
	"\ais_vgpu\x18\x02 \x01(\bR\x06isVgpu\"\x93\x01\n" +
	"\x14GPUDriverVersionInfo\x12,\n" +
	"\n" +
	"gpu_device\x18\x01 \x01(\v2\r.pb.GPUDeviceR\tgpuDevice\x12M\n" +
	"\x19supported_driver_versions\x18\x02 \x03(\v2\x11.pb.DriverVersionR\x17supportedDriverVersions\"k\n" +
	"\x18GPUDriverVersionInfoList\x12O\n" +
	"\x17gpu_driver_version_info\x18\x01 \x03(\v2\x18.pb.GPUDriverVersionInfoR\x14gpuDriverVersionInfoB\x06Z\x04.;pbb\x06proto3"

var (
	file_gpu_driver_versions_proto_rawDescOnce sync.Once
	file_gpu_driver_versions_proto_rawDescData []byte
)

func file_gpu_driver_versions_proto_rawDescGZIP() []byte {
	file_gpu_driver_versions_proto_rawDescOnce.Do(func() {
		file_gpu_driver_versions_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_gpu_driver_versions_proto_rawDesc), len(file_gpu_driver_versions_proto_rawDesc)))
	})
	return file_gpu_driver_versions_proto_rawDescData
}

var file_gpu_driver_versions_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_gpu_driver_versions_proto_goTypes = []any{
	(*HostDriverVersion)(nil),        // 0: pb.HostDriverVersion
	(*DriverVersion)(nil),            // 1: pb.DriverVersion
	(*GPUDevice)(nil),                // 2: pb.GPUDevice
	(*GPUDriverVersionInfo)(nil),     // 3: pb.GPUDriverVersionInfo
	(*GPUDriverVersionInfoList)(nil), // 4: pb.GPUDriverVersionInfoList
}
var file_gpu_driver_versions_proto_depIdxs = []int32{
	0, // 0: pb.DriverVersion.supported_host_versions:type_name -> pb.HostDriverVersion
	2, // 1: pb.GPUDriverVersionInfo.gpu_device:type_name -> pb.GPUDevice
	1, // 2: pb.GPUDriverVersionInfo.supported_driver_versions:type_name -> pb.DriverVersion
	3, // 3: pb.GPUDriverVersionInfoList.gpu_driver_version_info:type_name -> pb.GPUDriverVersionInfo
	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_gpu_driver_versions_proto_init() }
func file_gpu_driver_versions_proto_init() {
	if File_gpu_driver_versions_proto != nil {
		return
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: unsafe.Slice(unsafe.StringData(file_gpu_driver_versions_proto_rawDesc), len(file_gpu_driver_versions_proto_rawDesc)),
			NumEnums:      0,
			NumMessages:   5,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_gpu_driver_versions_proto_goTypes,
		DependencyIndexes: file_gpu_driver_versions_proto_depIdxs,
		MessageInfos:      file_gpu_driver_versions_proto_msgTypes,
	}.Build()
	File_gpu_driver_versions_proto = out.File
	file_gpu_driver_versions_proto_goTypes = nil
	file_gpu_driver_versions_proto_depIdxs = nil
}
