// Code generated by protoc-gen-go. DO NOT EDIT.
// source: lab_platform/stable_firmware_version.proto

package lab_platform

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

// StableFirmwareVersion is an association between a given ChromeOS version
// and a string uniquely identifying the firmware version.
// next tag: 3
type StableFirmwareVersion struct {
	Key                  *StableVersionKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
	Version              string            `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
	XXX_unrecognized     []byte            `json:"-"`
	XXX_sizecache        int32             `json:"-"`
}

func (m *StableFirmwareVersion) Reset()         { *m = StableFirmwareVersion{} }
func (m *StableFirmwareVersion) String() string { return proto.CompactTextString(m) }
func (*StableFirmwareVersion) ProtoMessage()    {}
func (*StableFirmwareVersion) Descriptor() ([]byte, []int) {
	return fileDescriptor_ac99b55efef69e10, []int{0}
}

func (m *StableFirmwareVersion) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_StableFirmwareVersion.Unmarshal(m, b)
}
func (m *StableFirmwareVersion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_StableFirmwareVersion.Marshal(b, m, deterministic)
}
func (m *StableFirmwareVersion) XXX_Merge(src proto.Message) {
	xxx_messageInfo_StableFirmwareVersion.Merge(m, src)
}
func (m *StableFirmwareVersion) XXX_Size() int {
	return xxx_messageInfo_StableFirmwareVersion.Size(m)
}
func (m *StableFirmwareVersion) XXX_DiscardUnknown() {
	xxx_messageInfo_StableFirmwareVersion.DiscardUnknown(m)
}

var xxx_messageInfo_StableFirmwareVersion proto.InternalMessageInfo

func (m *StableFirmwareVersion) GetKey() *StableVersionKey {
	if m != nil {
		return m.Key
	}
	return nil
}

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

func init() {
	proto.RegisterType((*StableFirmwareVersion)(nil), "lab_platform.StableFirmwareVersion")
}

func init() {
	proto.RegisterFile("lab_platform/stable_firmware_version.proto", fileDescriptor_ac99b55efef69e10)
}

var fileDescriptor_ac99b55efef69e10 = []byte{
	// 186 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0xca, 0x49, 0x4c, 0x8a,
	0x2f, 0xc8, 0x49, 0x2c, 0x49, 0xcb, 0x2f, 0xca, 0xd5, 0x2f, 0x2e, 0x49, 0x4c, 0xca, 0x49, 0x8d,
	0x4f, 0xcb, 0x2c, 0xca, 0x2d, 0x4f, 0x2c, 0x4a, 0x8d, 0x2f, 0x4b, 0x2d, 0x2a, 0xce, 0xcc, 0xcf,
	0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x41, 0x56, 0x2b, 0xa5, 0x8a, 0x4d, 0x27, 0x54,
	0x43, 0x7c, 0x76, 0x6a, 0x25, 0x44, 0x93, 0x52, 0x32, 0x97, 0x68, 0x30, 0x58, 0xce, 0x0d, 0x6a,
	0x68, 0x18, 0x44, 0x89, 0x90, 0x01, 0x17, 0x73, 0x76, 0x6a, 0xa5, 0x04, 0xa3, 0x02, 0xa3, 0x06,
	0xb7, 0x91, 0x9c, 0x1e, 0xb2, 0x69, 0x7a, 0x10, 0x1d, 0x50, 0x95, 0xde, 0xa9, 0x95, 0x41, 0x20,
	0xa5, 0x42, 0x12, 0x5c, 0xec, 0x50, 0xf3, 0x25, 0x98, 0x14, 0x18, 0x35, 0x38, 0x83, 0x60, 0x5c,
	0x27, 0x8b, 0x28, 0xb3, 0xf4, 0x7c, 0xbd, 0xe4, 0x8c, 0xa2, 0xfc, 0xdc, 0xcc, 0xd2, 0x5c, 0xbd,
	0xfc, 0xa2, 0x74, 0x7d, 0x18, 0x27, 0xbf, 0x58, 0x3f, 0x33, 0x2f, 0xad, 0x28, 0x51, 0x1f, 0xec,
	0x1c, 0xfd, 0xf4, 0x7c, 0x7d, 0x64, 0x9b, 0x92, 0xd8, 0xc0, 0xc2, 0xc6, 0x80, 0x00, 0x00, 0x00,
	0xff, 0xff, 0xdb, 0x57, 0x7f, 0x8f, 0x08, 0x01, 0x00, 0x00,
}
