// Code generated by protoc-gen-go. DO NOT EDIT.
// source: test_platform/skylab_local_state/host_info.proto

package skylab_local_state

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

// AutotestHostInfo defines the structure of the host info file which is used
// to pass host information to Autotest and receive host information
// changes from Autotest.
type AutotestHostInfo struct {
	Attributes           map[string]string `protobuf:"bytes,1,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
	Labels               []string          `protobuf:"bytes,2,rep,name=labels,proto3" json:"labels,omitempty"`
	SerializerVersion    int32             `protobuf:"varint,3,opt,name=serializer_version,proto3" json:"serializer_version,omitempty"`
	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
	XXX_unrecognized     []byte            `json:"-"`
	XXX_sizecache        int32             `json:"-"`
}

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

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

var xxx_messageInfo_AutotestHostInfo proto.InternalMessageInfo

func (m *AutotestHostInfo) GetAttributes() map[string]string {
	if m != nil {
		return m.Attributes
	}
	return nil
}

func (m *AutotestHostInfo) GetLabels() []string {
	if m != nil {
		return m.Labels
	}
	return nil
}

func (m *AutotestHostInfo) GetSerializerVersion() int32 {
	if m != nil {
		return m.SerializerVersion
	}
	return 0
}

func init() {
	proto.RegisterType((*AutotestHostInfo)(nil), "test_platform.skylab_local_state.AutotestHostInfo")
	proto.RegisterMapType((map[string]string)(nil), "test_platform.skylab_local_state.AutotestHostInfo.AttributesEntry")
}

func init() {
	proto.RegisterFile("test_platform/skylab_local_state/host_info.proto", fileDescriptor_e94630bed0fc00e0)
}

var fileDescriptor_e94630bed0fc00e0 = []byte{
	// 264 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x90, 0xcf, 0x4b, 0xfb, 0x40,
	0x10, 0xc5, 0xd9, 0x84, 0x16, 0xba, 0xdf, 0xc3, 0xb7, 0x2c, 0x22, 0xc1, 0x53, 0xf0, 0x94, 0xd3,
	0xae, 0xe8, 0x45, 0x04, 0x0f, 0x2d, 0x08, 0x2a, 0x9e, 0x72, 0xf4, 0x12, 0x36, 0x65, 0x93, 0x2e,
	0xdd, 0xec, 0x94, 0x99, 0x49, 0x21, 0xfe, 0xef, 0x82, 0x34, 0xfe, 0x40, 0xab, 0xd0, 0xdb, 0xbc,
	0x99, 0xf7, 0x3e, 0x03, 0x4f, 0x5e, 0xb0, 0x23, 0xae, 0xb6, 0xc1, 0x72, 0x03, 0xd8, 0x19, 0xda,
	0x0c, 0xc1, 0xd6, 0x55, 0x80, 0x95, 0x0d, 0x15, 0xb1, 0x65, 0x67, 0xd6, 0x40, 0x5c, 0xf9, 0xd8,
	0x80, 0xde, 0x22, 0x30, 0xa8, 0xfc, 0x47, 0x42, 0xff, 0x4e, 0x9c, 0xbf, 0x0a, 0x39, 0x5f, 0xf4,
	0x0c, 0x7b, 0xe3, 0x3d, 0x10, 0x3f, 0xc4, 0x06, 0x54, 0x2d, 0xa5, 0x65, 0x46, 0x5f, 0xf7, 0xec,
	0x28, 0x13, 0x79, 0x5a, 0xfc, 0xbb, 0x5c, 0xea, 0x63, 0x2c, 0x7d, 0xc8, 0xd1, 0x8b, 0x2f, 0xc8,
	0x5d, 0x64, 0x1c, 0xca, 0x6f, 0x54, 0x75, 0x2a, 0xa7, 0xc1, 0xd6, 0x2e, 0x50, 0x96, 0xe4, 0x69,
	0x31, 0x2b, 0x3f, 0x94, 0xd2, 0x52, 0x91, 0x43, 0x6f, 0x83, 0x7f, 0x71, 0x58, 0xed, 0x1c, 0x92,
	0x87, 0x98, 0xa5, 0xb9, 0x28, 0x26, 0xe5, 0x1f, 0x97, 0xb3, 0x5b, 0xf9, 0xff, 0xe0, 0x8d, 0x9a,
	0xcb, 0x74, 0xe3, 0x86, 0x4c, 0xe4, 0xa2, 0x98, 0x95, 0xfb, 0x51, 0x9d, 0xc8, 0xc9, 0xce, 0x86,
	0xde, 0x65, 0xc9, 0xb8, 0x7b, 0x17, 0x37, 0xc9, 0xb5, 0x58, 0x3e, 0x3d, 0x3f, 0xb6, 0xa0, 0x57,
	0x6b, 0x84, 0xce, 0xf7, 0x9d, 0x06, 0x6c, 0xcd, 0xa7, 0x00, 0x32, 0x3e, 0x36, 0x68, 0xcd, 0xd8,
	0xa5, 0x69, 0xc1, 0x1c, 0xeb, 0xbf, 0x9e, 0x8e, 0xd6, 0xab, 0xb7, 0x00, 0x00, 0x00, 0xff, 0xff,
	0x10, 0x81, 0x1b, 0xa7, 0xaa, 0x01, 0x00, 0x00,
}
