// Code generated by protoc-gen-go. DO NOT EDIT.
// source: test/custom_results/graphics/machine_id.proto

package graphics

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

// Uniquely identifies a machine.
type MachineId struct {
	Value                string   `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_MachineId proto.InternalMessageInfo

func (m *MachineId) GetValue() string {
	if m != nil {
		return m.Value
	}
	return ""
}

func init() {
	proto.RegisterType((*MachineId)(nil), "test.custom_results.graphics.MachineId")
}

func init() {
	proto.RegisterFile("test/custom_results/graphics/machine_id.proto", fileDescriptor_5996ccb5ae9e4bd1)
}

var fileDescriptor_5996ccb5ae9e4bd1 = []byte{
	// 152 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2d, 0x49, 0x2d, 0x2e,
	0xd1, 0x4f, 0x2e, 0x2d, 0x2e, 0xc9, 0xcf, 0x8d, 0x2f, 0x4a, 0x2d, 0x2e, 0xcd, 0x29, 0x29, 0xd6,
	0x4f, 0x2f, 0x4a, 0x2c, 0xc8, 0xc8, 0x4c, 0x2e, 0xd6, 0xcf, 0x4d, 0x4c, 0xce, 0xc8, 0xcc, 0x4b,
	0x8d, 0xcf, 0x4c, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x01, 0x29, 0xd7, 0x43, 0x55,
	0xae, 0x07, 0x53, 0xae, 0xa4, 0xc8, 0xc5, 0xe9, 0x0b, 0xd1, 0xe1, 0x99, 0x22, 0x24, 0xc2, 0xc5,
	0x5a, 0x96, 0x98, 0x53, 0x9a, 0x2a, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x19, 0x04, 0xe1, 0x38, 0x79,
	0x44, 0xb9, 0xa5, 0xe7, 0xeb, 0x25, 0x67, 0x14, 0xe5, 0xe7, 0x66, 0x96, 0xe6, 0xea, 0xe5, 0x17,
	0xa5, 0xeb, 0xc3, 0x38, 0xf9, 0xc5, 0xfa, 0x99, 0x79, 0x69, 0x45, 0x89, 0xfa, 0x60, 0xab, 0xf4,
	0xd3, 0xf3, 0xf5, 0xf1, 0xb9, 0x2d, 0x89, 0x0d, 0xac, 0xcc, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff,
	0x3c, 0xbf, 0x38, 0x47, 0xc2, 0x00, 0x00, 0x00,
}
