// Code generated by protoc-gen-go. DO NOT EDIT.
// source: lab/license.proto

package lab

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

// Next Tag: 3
type LicenseType int32

const (
	LicenseType_LICENSE_TYPE_UNSPECIFIED LicenseType = 0
	// Microsoft Windows 10 Professional Desktop Operating System.
	// Contact the Chrome OS Parallels team for license specifics.
	LicenseType_LICENSE_TYPE_WINDOWS_10_PRO LicenseType = 1
	// Microsoft Office Standard.
	// Contact the Chrome OS Parallels team for license specifics.
	LicenseType_LICENSE_TYPE_MS_OFFICE_STANDARD LicenseType = 2
)

var LicenseType_name = map[int32]string{
	0: "LICENSE_TYPE_UNSPECIFIED",
	1: "LICENSE_TYPE_WINDOWS_10_PRO",
	2: "LICENSE_TYPE_MS_OFFICE_STANDARD",
}

var LicenseType_value = map[string]int32{
	"LICENSE_TYPE_UNSPECIFIED":        0,
	"LICENSE_TYPE_WINDOWS_10_PRO":     1,
	"LICENSE_TYPE_MS_OFFICE_STANDARD": 2,
}

func (x LicenseType) String() string {
	return proto.EnumName(LicenseType_name, int32(x))
}

func (LicenseType) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_1f03ce9038f3d539, []int{0}
}

// Represents a Software License assigned to a device.
// Next Tag: 3
type License struct {
	Type LicenseType `protobuf:"varint,1,opt,name=type,proto3,enum=lab.LicenseType" json:"type,omitempty"`
	// An optional string to uniquely identify the license that was assigned,
	// for tracking purposes.
	Identifier           string   `protobuf:"bytes,2,opt,name=identifier,proto3" json:"identifier,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_License proto.InternalMessageInfo

func (m *License) GetType() LicenseType {
	if m != nil {
		return m.Type
	}
	return LicenseType_LICENSE_TYPE_UNSPECIFIED
}

func (m *License) GetIdentifier() string {
	if m != nil {
		return m.Identifier
	}
	return ""
}

func init() {
	proto.RegisterEnum("lab.LicenseType", LicenseType_name, LicenseType_value)
	proto.RegisterType((*License)(nil), "lab.License")
}

func init() { proto.RegisterFile("lab/license.proto", fileDescriptor_1f03ce9038f3d539) }

var fileDescriptor_1f03ce9038f3d539 = []byte{
	// 237 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xcc, 0x49, 0x4c, 0xd2,
	0xcf, 0xc9, 0x4c, 0x4e, 0xcd, 0x2b, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xce,
	0x49, 0x4c, 0x52, 0xf2, 0xe7, 0x62, 0xf7, 0x81, 0x88, 0x0a, 0xa9, 0x70, 0xb1, 0x94, 0x54, 0x16,
	0xa4, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x19, 0x09, 0xe8, 0xe5, 0x24, 0x26, 0xe9, 0x41, 0xe5,
	0x42, 0x2a, 0x0b, 0x52, 0x83, 0xc0, 0xb2, 0x42, 0x72, 0x5c, 0x5c, 0x99, 0x29, 0xa9, 0x79, 0x25,
	0x99, 0x69, 0x99, 0xa9, 0x45, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x48, 0x22, 0x5a, 0x85,
	0x5c, 0xdc, 0x48, 0x9a, 0x84, 0x64, 0xb8, 0x24, 0x7c, 0x3c, 0x9d, 0x5d, 0xfd, 0x82, 0x5d, 0xe3,
	0x43, 0x22, 0x03, 0x5c, 0xe3, 0x43, 0xfd, 0x82, 0x03, 0x5c, 0x9d, 0x3d, 0xdd, 0x3c, 0x5d, 0x5d,
	0x04, 0x18, 0x84, 0xe4, 0xb9, 0xa4, 0x51, 0x64, 0xc3, 0x3d, 0xfd, 0x5c, 0xfc, 0xc3, 0x83, 0xe3,
	0x0d, 0x0d, 0xe2, 0x03, 0x82, 0xfc, 0x05, 0x18, 0x85, 0x94, 0xb9, 0xe4, 0x51, 0x14, 0xf8, 0x06,
	0xc7, 0xfb, 0xbb, 0xb9, 0x79, 0x3a, 0xbb, 0xc6, 0x07, 0x87, 0x38, 0xfa, 0xb9, 0x38, 0x06, 0xb9,
	0x08, 0x30, 0x39, 0xe9, 0x47, 0xe9, 0xa6, 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, 0x2f, 0xeb, 0xa7, 0xe7, 0xeb, 0xe7, 0x24, 0x26, 0x25, 0xb1, 0x81, 0x79, 0xc6, 0x80,
	0x00, 0x00, 0x00, 0xff, 0xff, 0x15, 0xde, 0xc6, 0xd9, 0x15, 0x01, 0x00, 0x00,
}
