// Code generated by protoc-gen-go. DO NOT EDIT.
// source: chromiumos/sign_image.proto

package chromiumos

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

type SignerType int32

const (
	SignerType_SIGNER_UNSPECIFIED SignerType = 0
	SignerType_SIGNER_PRODUCTION  SignerType = 1
	SignerType_SIGNER_STAGING     SignerType = 2
	SignerType_SIGNER_DEV         SignerType = 3
)

var SignerType_name = map[int32]string{
	0: "SIGNER_UNSPECIFIED",
	1: "SIGNER_PRODUCTION",
	2: "SIGNER_STAGING",
	3: "SIGNER_DEV",
}

var SignerType_value = map[string]int32{
	"SIGNER_UNSPECIFIED": 0,
	"SIGNER_PRODUCTION":  1,
	"SIGNER_STAGING":     2,
	"SIGNER_DEV":         3,
}

func (x SignerType) String() string {
	return proto.EnumName(SignerType_name, int32(x))
}

func (SignerType) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_415e76f10086cda5, []int{0}
}

// The target for the image.
// These names are assigned to target in the signing instructions file.
type Cr50Instructions_Target int32

const (
	Cr50Instructions_UNSPECIFIED       Cr50Instructions_Target = 0
	Cr50Instructions_PREPVT            Cr50Instructions_Target = 1
	Cr50Instructions_RELEASE_CANDIDATE Cr50Instructions_Target = 2
	Cr50Instructions_NODE_LOCKED       Cr50Instructions_Target = 3
	Cr50Instructions_GENERAL_RELEASE   Cr50Instructions_Target = 4
)

var Cr50Instructions_Target_name = map[int32]string{
	0: "UNSPECIFIED",
	1: "PREPVT",
	2: "RELEASE_CANDIDATE",
	3: "NODE_LOCKED",
	4: "GENERAL_RELEASE",
}

var Cr50Instructions_Target_value = map[string]int32{
	"UNSPECIFIED":       0,
	"PREPVT":            1,
	"RELEASE_CANDIDATE": 2,
	"NODE_LOCKED":       3,
	"GENERAL_RELEASE":   4,
}

func (x Cr50Instructions_Target) String() string {
	return proto.EnumName(Cr50Instructions_Target_name, int32(x))
}

func (Cr50Instructions_Target) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_415e76f10086cda5, []int{0, 0}
}

type Cr50Instructions struct {
	Target Cr50Instructions_Target `protobuf:"varint,1,opt,name=target,proto3,enum=chromiumos.Cr50Instructions_Target" json:"target,omitempty"`
	// Device ID for NODE_LOCKED.  (Format: '%08x-%08x'.)
	DeviceId             string   `protobuf:"bytes,2,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_Cr50Instructions proto.InternalMessageInfo

func (m *Cr50Instructions) GetTarget() Cr50Instructions_Target {
	if m != nil {
		return m.Target
	}
	return Cr50Instructions_UNSPECIFIED
}

func (m *Cr50Instructions) GetDeviceId() string {
	if m != nil {
		return m.DeviceId
	}
	return ""
}

func init() {
	proto.RegisterEnum("chromiumos.SignerType", SignerType_name, SignerType_value)
	proto.RegisterEnum("chromiumos.Cr50Instructions_Target", Cr50Instructions_Target_name, Cr50Instructions_Target_value)
	proto.RegisterType((*Cr50Instructions)(nil), "chromiumos.Cr50Instructions")
}

func init() { proto.RegisterFile("chromiumos/sign_image.proto", fileDescriptor_415e76f10086cda5) }

var fileDescriptor_415e76f10086cda5 = []byte{
	// 310 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0x4d, 0x4b, 0xf3, 0x40,
	0x14, 0x46, 0xdf, 0xb4, 0x2f, 0xc1, 0x5e, 0xa1, 0x9d, 0x8e, 0x54, 0x0a, 0xdd, 0x94, 0xba, 0x29,
	0x2e, 0x12, 0xf1, 0x6b, 0xe3, 0x2a, 0x66, 0xc6, 0x30, 0x58, 0x26, 0x61, 0x92, 0x76, 0xe1, 0x66,
	0xe8, 0x47, 0x1c, 0x67, 0xd1, 0x4c, 0x99, 0xa4, 0x82, 0xff, 0xd2, 0x9f, 0x24, 0xb6, 0xc1, 0x56,
	0xb7, 0xe7, 0x9e, 0x87, 0x0b, 0x07, 0x06, 0xcb, 0x37, 0x6b, 0xd6, 0x7a, 0xbb, 0x36, 0xa5, 0x5f,
	0x6a, 0x55, 0x48, 0xbd, 0x9e, 0xab, 0xdc, 0xdb, 0x58, 0x53, 0x19, 0x0c, 0x87, 0xe3, 0xe8, 0xd3,
	0x01, 0x14, 0xda, 0xbb, 0x2b, 0x56, 0x94, 0x95, 0xdd, 0x2e, 0x2b, 0x6d, 0x8a, 0x12, 0x3f, 0x80,
	0x5b, 0xcd, 0xad, 0xca, 0xab, 0xbe, 0x33, 0x74, 0xc6, 0xed, 0xeb, 0x0b, 0xef, 0xb0, 0xf0, 0xfe,
	0xda, 0x5e, 0xb6, 0x53, 0x45, 0x3d, 0xc1, 0x03, 0x68, 0xad, 0xf2, 0x77, 0xbd, 0xcc, 0xa5, 0x5e,
	0xf5, 0x1b, 0x43, 0x67, 0xdc, 0x12, 0x27, 0x7b, 0xc0, 0x56, 0xa3, 0x05, 0xb8, 0x7b, 0x1d, 0x77,
	0xe0, 0x74, 0xca, 0xd3, 0x84, 0x86, 0xec, 0x89, 0x51, 0x82, 0xfe, 0x61, 0x00, 0x37, 0x11, 0x34,
	0x99, 0x65, 0xc8, 0xc1, 0x3d, 0xe8, 0x0a, 0x3a, 0xa1, 0x41, 0x4a, 0x65, 0x18, 0x70, 0xc2, 0x48,
	0x90, 0x51, 0xd4, 0xf8, 0xde, 0xf0, 0x98, 0x50, 0x39, 0x89, 0xc3, 0x67, 0x4a, 0x50, 0x13, 0x9f,
	0x41, 0x27, 0xa2, 0x9c, 0x8a, 0x60, 0x22, 0x6b, 0x1f, 0xfd, 0xbf, 0x94, 0x00, 0xa9, 0x56, 0x45,
	0x6e, 0xb3, 0x8f, 0x4d, 0x8e, 0xcf, 0x01, 0xa7, 0x2c, 0xe2, 0x54, 0xc8, 0xdf, 0xef, 0x7a, 0xd0,
	0xad, 0x79, 0x22, 0x62, 0x32, 0x0d, 0x33, 0x16, 0x73, 0xe4, 0x60, 0x0c, 0xed, 0x1a, 0xa7, 0x59,
	0x10, 0x31, 0x1e, 0xa1, 0x06, 0x6e, 0x03, 0xd4, 0x8c, 0xd0, 0x19, 0x6a, 0x3e, 0xde, 0xbf, 0xdc,
	0x2a, 0xf3, 0x93, 0xc4, 0x33, 0x56, 0xf9, 0x47, 0xb9, 0x75, 0xf1, 0x6a, 0xe7, 0xfe, 0xae, 0xb4,
	0xaf, 0xcc, 0xd1, 0x65, 0xe1, 0xee, 0xe0, 0xcd, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0x21,
	0x8e, 0xda, 0x9d, 0x01, 0x00, 0x00,
}
