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

package lab_platform

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	chromiumos "go.chromium.org/chromiumos/infra/proto/go/chromiumos"
	device "go.chromium.org/chromiumos/infra/proto/go/device"
	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

// Next Tag: 3
type StableVersionKey struct {
	ModelId              *device.ModelId         `protobuf:"bytes,1,opt,name=model_id,json=modelId,proto3" json:"model_id,omitempty"`
	BuildTarget          *chromiumos.BuildTarget `protobuf:"bytes,2,opt,name=build_target,json=buildTarget,proto3" json:"build_target,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
	XXX_unrecognized     []byte                  `json:"-"`
	XXX_sizecache        int32                   `json:"-"`
}

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

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

var xxx_messageInfo_StableVersionKey proto.InternalMessageInfo

func (m *StableVersionKey) GetModelId() *device.ModelId {
	if m != nil {
		return m.ModelId
	}
	return nil
}

func (m *StableVersionKey) GetBuildTarget() *chromiumos.BuildTarget {
	if m != nil {
		return m.BuildTarget
	}
	return nil
}

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

func init() {
	proto.RegisterFile("lab_platform/stable_version_key.proto", fileDescriptor_1db3312af92a27ab)
}

var fileDescriptor_1db3312af92a27ab = []byte{
	// 218 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x8f, 0xb1, 0x4b, 0xc6, 0x30,
	0x10, 0xc5, 0xf9, 0x1c, 0x54, 0xf2, 0x7d, 0xa0, 0x14, 0xa4, 0xa5, 0x93, 0x08, 0x82, 0x38, 0x24,
	0xa0, 0x20, 0xe2, 0xd8, 0x4d, 0xc4, 0xa5, 0x8a, 0x83, 0x4b, 0x48, 0x9a, 0x6b, 0x0c, 0x26, 0xbd,
	0x92, 0xa6, 0x85, 0xfa, 0xd7, 0x4b, 0x13, 0xb4, 0xdd, 0xee, 0xde, 0xfb, 0xdd, 0xe3, 0x1d, 0xb9,
	0xb6, 0x42, 0xf2, 0xde, 0x8a, 0xd0, 0xa2, 0x77, 0x6c, 0x08, 0x42, 0x5a, 0xe0, 0x13, 0xf8, 0xc1,
	0x60, 0xc7, 0xbf, 0x61, 0xa6, 0xbd, 0xc7, 0x80, 0xd9, 0x61, 0x8b, 0x95, 0x79, 0xf3, 0xe5, 0xd1,
	0x99, 0xd1, 0xe1, 0xc0, 0x1a, 0x74, 0x0e, 0xbb, 0x84, 0x95, 0x17, 0x0a, 0x26, 0xd3, 0x00, 0x73,
	0xa8, 0xc0, 0x72, 0xa3, 0x92, 0x7c, 0xf5, 0x43, 0xce, 0xdf, 0x62, 0xf2, 0x47, 0x0a, 0x7e, 0x81,
	0x39, 0xbb, 0x25, 0xa7, 0x7f, 0x54, 0xb1, 0xbb, 0xdc, 0xdd, 0xec, 0xef, 0xce, 0x68, 0xba, 0xa6,
	0xaf, 0x8b, 0xfe, 0xac, 0xea, 0x13, 0x97, 0x86, 0xec, 0x89, 0x1c, 0xe4, 0x68, 0xac, 0xe2, 0x41,
	0x78, 0x0d, 0xa1, 0x38, 0x8a, 0x7c, 0x4e, 0xd7, 0x1a, 0xb4, 0x5a, 0xfc, 0xf7, 0x68, 0xd7, 0x7b,
	0xb9, 0x2e, 0xd5, 0xe3, 0xe7, 0x83, 0xc6, 0x7f, 0x92, 0xa2, 0xd7, 0x6c, 0xd3, 0xde, 0x74, 0xad,
	0x17, 0x2c, 0xb6, 0x64, 0x1a, 0xd9, 0xf6, 0x4b, 0x79, 0x1c, 0xe5, 0xfb, 0xdf, 0x00, 0x00, 0x00,
	0xff, 0xff, 0xa0, 0xf1, 0xa8, 0x98, 0x23, 0x01, 0x00, 0x00,
}
