// Code generated by protoc-gen-go. DO NOT EDIT.
// source: lab_platform/dut_state.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

// DutState defines the structure of the file used to cache variable DUT
// information on the drone.
type DutState struct {
	// OS and/or fw versions installed on the DUT, e.g.
	// {"cros-version":"terra-release/R75-12105.108.0"}.
	// Used to construct variable bot dimensions.
	ProvisionableLabels map[string]string `protobuf:"bytes,2,rep,name=provisionable_labels,proto3" json:"provisionable_labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
	// Variable DUT attributes, e.g.
	// {"job_repo_url":"http://devserver_ip:8082/static/terra-release/R75-12105.108.0/autotest/packages"}.
	// Are fed into the Autotest harness via the host info file.
	ProvisionableAttributes map[string]string `protobuf:"bytes,3,rep,name=provisionable_attributes,proto3" json:"provisionable_attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
	XXX_NoUnkeyedLiteral    struct{}          `json:"-"`
	XXX_unrecognized        []byte            `json:"-"`
	XXX_sizecache           int32             `json:"-"`
}

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

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

var xxx_messageInfo_DutState proto.InternalMessageInfo

func (m *DutState) GetProvisionableLabels() map[string]string {
	if m != nil {
		return m.ProvisionableLabels
	}
	return nil
}

func (m *DutState) GetProvisionableAttributes() map[string]string {
	if m != nil {
		return m.ProvisionableAttributes
	}
	return nil
}

func init() {
	proto.RegisterType((*DutState)(nil), "lab_platform.DutState")
	proto.RegisterMapType((map[string]string)(nil), "lab_platform.DutState.ProvisionableAttributesEntry")
	proto.RegisterMapType((map[string]string)(nil), "lab_platform.DutState.ProvisionableLabelsEntry")
}

func init() { proto.RegisterFile("lab_platform/dut_state.proto", fileDescriptor_5e0c46a52ec0fb7d) }

var fileDescriptor_5e0c46a52ec0fb7d = []byte{
	// 248 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xc9, 0x49, 0x4c, 0x8a,
	0x2f, 0xc8, 0x49, 0x2c, 0x49, 0xcb, 0x2f, 0xca, 0xd5, 0x4f, 0x29, 0x2d, 0x89, 0x2f, 0x2e, 0x49,
	0x2c, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x41, 0x96, 0x55, 0xfa, 0xc2, 0xc4,
	0xc5, 0xe1, 0x52, 0x5a, 0x12, 0x0c, 0x52, 0x20, 0x94, 0xcc, 0x25, 0x52, 0x50, 0x94, 0x5f, 0x96,
	0x59, 0x9c, 0x99, 0x9f, 0x97, 0x98, 0x94, 0x93, 0x1a, 0x9f, 0x93, 0x98, 0x94, 0x9a, 0x53, 0x2c,
	0xc1, 0xa4, 0xc0, 0xac, 0xc1, 0x6d, 0xa4, 0xaf, 0x87, 0xac, 0x53, 0x0f, 0xa6, 0x4b, 0x2f, 0x00,
	0x59, 0x8b, 0x0f, 0x58, 0x87, 0x6b, 0x5e, 0x49, 0x51, 0x65, 0x10, 0x56, 0xc3, 0x84, 0xf2, 0xb9,
	0x24, 0x50, 0xc5, 0x13, 0x4b, 0x4a, 0x8a, 0x32, 0x93, 0x4a, 0x4b, 0x52, 0x8b, 0x25, 0x98, 0xc1,
	0x16, 0x19, 0x13, 0x63, 0x91, 0x23, 0x5c, 0x17, 0xc4, 0x32, 0x9c, 0x86, 0x4a, 0xb9, 0x71, 0x49,
	0xe0, 0x72, 0xa2, 0x90, 0x00, 0x17, 0x73, 0x76, 0x6a, 0xa5, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67,
	0x10, 0x88, 0x29, 0x24, 0xc2, 0xc5, 0x5a, 0x96, 0x98, 0x53, 0x9a, 0x2a, 0xc1, 0x04, 0x16, 0x83,
	0x70, 0xac, 0x98, 0x2c, 0x18, 0xa5, 0xbc, 0xb8, 0x64, 0xf0, 0xb9, 0x80, 0x14, 0xb3, 0x9c, 0x2c,
	0xa2, 0xcc, 0xd2, 0xf3, 0xf5, 0x92, 0x33, 0x8a, 0xf2, 0x73, 0x33, 0x4b, 0x73, 0xf5, 0xf2, 0x8b,
	0xd2, 0xf5, 0x61, 0x9c, 0xfc, 0x62, 0xfd, 0xcc, 0xbc, 0xb4, 0xa2, 0x44, 0x7d, 0x70, 0x74, 0xe9,
	0xa7, 0xe7, 0xeb, 0x23, 0x87, 0x46, 0x12, 0x1b, 0x58, 0xd8, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff,
	0x23, 0xe8, 0x59, 0xdb, 0xe5, 0x01, 0x00, 0x00,
}
