// 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 supports virtualization
	SupportsVgpu  bool `protobuf:"varint,2,opt,name=supports_vgpu,json=supportsVgpu,proto3" json:"supports_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) GetSupportsVgpu() bool {
	if x != nil {
		return x.SupportsVgpu
	}
	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\"K\n" +
	"\tGPUDevice\x12\x19\n" +
	"\bgpu_type\x18\x01 \x01(\tR\agpuType\x12#\n" +
	"\rsupports_vgpu\x18\x02 \x01(\bR\fsupportsVgpu\"\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
}
