// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.25.0-devel
// 	protoc        v3.6.1
// source: chromiumos/sign_image.proto

package chromiumos

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

type SignerType int32

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

// Enum value maps for SignerType.
var (
	SignerType_name = map[int32]string{
		0: "SIGNER_UNSPECIFIED",
		1: "SIGNER_PRODUCTION",
		2: "SIGNER_STAGING",
		3: "SIGNER_DEV",
	}
	SignerType_value = map[string]int32{
		"SIGNER_UNSPECIFIED": 0,
		"SIGNER_PRODUCTION":  1,
		"SIGNER_STAGING":     2,
		"SIGNER_DEV":         3,
	}
)

func (x SignerType) Enum() *SignerType {
	p := new(SignerType)
	*p = x
	return p
}

func (x SignerType) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (SignerType) Descriptor() protoreflect.EnumDescriptor {
	return file_chromiumos_sign_image_proto_enumTypes[0].Descriptor()
}

func (SignerType) Type() protoreflect.EnumType {
	return &file_chromiumos_sign_image_proto_enumTypes[0]
}

func (x SignerType) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use SignerType.Descriptor instead.
func (SignerType) EnumDescriptor() ([]byte, []int) {
	return file_chromiumos_sign_image_proto_rawDescGZIP(), []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
)

// Enum value maps for Cr50Instructions_Target.
var (
	Cr50Instructions_Target_name = map[int32]string{
		0: "UNSPECIFIED",
		1: "PREPVT",
		2: "RELEASE_CANDIDATE",
		3: "NODE_LOCKED",
		4: "GENERAL_RELEASE",
	}
	Cr50Instructions_Target_value = map[string]int32{
		"UNSPECIFIED":       0,
		"PREPVT":            1,
		"RELEASE_CANDIDATE": 2,
		"NODE_LOCKED":       3,
		"GENERAL_RELEASE":   4,
	}
)

func (x Cr50Instructions_Target) Enum() *Cr50Instructions_Target {
	p := new(Cr50Instructions_Target)
	*p = x
	return p
}

func (x Cr50Instructions_Target) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (Cr50Instructions_Target) Descriptor() protoreflect.EnumDescriptor {
	return file_chromiumos_sign_image_proto_enumTypes[1].Descriptor()
}

func (Cr50Instructions_Target) Type() protoreflect.EnumType {
	return &file_chromiumos_sign_image_proto_enumTypes[1]
}

func (x Cr50Instructions_Target) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use Cr50Instructions_Target.Descriptor instead.
func (Cr50Instructions_Target) EnumDescriptor() ([]byte, []int) {
	return file_chromiumos_sign_image_proto_rawDescGZIP(), []int{0, 0}
}

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

const (
	GscInstructions_UNSPECIFIED       GscInstructions_Target = 0
	GscInstructions_PREPVT            GscInstructions_Target = 1
	GscInstructions_RELEASE_CANDIDATE GscInstructions_Target = 2
	GscInstructions_NODE_LOCKED       GscInstructions_Target = 3
	GscInstructions_GENERAL_RELEASE   GscInstructions_Target = 4
)

// Enum value maps for GscInstructions_Target.
var (
	GscInstructions_Target_name = map[int32]string{
		0: "UNSPECIFIED",
		1: "PREPVT",
		2: "RELEASE_CANDIDATE",
		3: "NODE_LOCKED",
		4: "GENERAL_RELEASE",
	}
	GscInstructions_Target_value = map[string]int32{
		"UNSPECIFIED":       0,
		"PREPVT":            1,
		"RELEASE_CANDIDATE": 2,
		"NODE_LOCKED":       3,
		"GENERAL_RELEASE":   4,
	}
)

func (x GscInstructions_Target) Enum() *GscInstructions_Target {
	p := new(GscInstructions_Target)
	*p = x
	return p
}

func (x GscInstructions_Target) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (GscInstructions_Target) Descriptor() protoreflect.EnumDescriptor {
	return file_chromiumos_sign_image_proto_enumTypes[2].Descriptor()
}

func (GscInstructions_Target) Type() protoreflect.EnumType {
	return &file_chromiumos_sign_image_proto_enumTypes[2]
}

func (x GscInstructions_Target) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use GscInstructions_Target.Descriptor instead.
func (GscInstructions_Target) EnumDescriptor() ([]byte, []int) {
	return file_chromiumos_sign_image_proto_rawDescGZIP(), []int{1, 0}
}

// TODO(b:173049030) Obsolete, will be removed when GSC signing is extended to
// Dauntless.
type Cr50Instructions struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	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"`
}

func (x *Cr50Instructions) Reset() {
	*x = Cr50Instructions{}
	if protoimpl.UnsafeEnabled {
		mi := &file_chromiumos_sign_image_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Cr50Instructions) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Cr50Instructions) ProtoMessage() {}

func (x *Cr50Instructions) ProtoReflect() protoreflect.Message {
	mi := &file_chromiumos_sign_image_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Cr50Instructions.ProtoReflect.Descriptor instead.
func (*Cr50Instructions) Descriptor() ([]byte, []int) {
	return file_chromiumos_sign_image_proto_rawDescGZIP(), []int{0}
}

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

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

type GscInstructions struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Target GscInstructions_Target `protobuf:"varint,1,opt,name=target,proto3,enum=chromiumos.GscInstructions_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"`
}

func (x *GscInstructions) Reset() {
	*x = GscInstructions{}
	if protoimpl.UnsafeEnabled {
		mi := &file_chromiumos_sign_image_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *GscInstructions) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*GscInstructions) ProtoMessage() {}

func (x *GscInstructions) ProtoReflect() protoreflect.Message {
	mi := &file_chromiumos_sign_image_proto_msgTypes[1]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use GscInstructions.ProtoReflect.Descriptor instead.
func (*GscInstructions) Descriptor() ([]byte, []int) {
	return file_chromiumos_sign_image_proto_rawDescGZIP(), []int{1}
}

func (x *GscInstructions) GetTarget() GscInstructions_Target {
	if x != nil {
		return x.Target
	}
	return GscInstructions_UNSPECIFIED
}

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

var File_chromiumos_sign_image_proto protoreflect.FileDescriptor

var file_chromiumos_sign_image_proto_rawDesc = []byte{
	0x0a, 0x1b, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2f, 0x73, 0x69, 0x67,
	0x6e, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x63,
	0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x22, 0xd0, 0x01, 0x0a, 0x10, 0x43, 0x72,
	0x35, 0x30, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3b,
	0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23,
	0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2e, 0x43, 0x72, 0x35, 0x30,
	0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x54, 0x61, 0x72,
	0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64,
	0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
	0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x22, 0x62, 0x0a, 0x06, 0x54, 0x61, 0x72, 0x67,
	0x65, 0x74, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
	0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x52, 0x45, 0x50, 0x56, 0x54, 0x10, 0x01, 0x12,
	0x15, 0x0a, 0x11, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x44, 0x49,
	0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4c,
	0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x47, 0x45, 0x4e, 0x45, 0x52,
	0x41, 0x4c, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x10, 0x04, 0x22, 0xce, 0x01, 0x0a,
	0x0f, 0x47, 0x73, 0x63, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
	0x12, 0x3a, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
	0x32, 0x22, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2e, 0x47, 0x73,
	0x63, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x54, 0x61,
	0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09,
	0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
	0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x22, 0x62, 0x0a, 0x06, 0x54, 0x61, 0x72,
	0x67, 0x65, 0x74, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
	0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x52, 0x45, 0x50, 0x56, 0x54, 0x10, 0x01,
	0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x44,
	0x49, 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x4f, 0x44, 0x45, 0x5f,
	0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x47, 0x45, 0x4e, 0x45,
	0x52, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x10, 0x04, 0x2a, 0x5f, 0x0a,
	0x0a, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x53,
	0x49, 0x47, 0x4e, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
	0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x52, 0x5f, 0x50, 0x52,
	0x4f, 0x44, 0x55, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49,
	0x47, 0x4e, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0e,
	0x0a, 0x0a, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x52, 0x5f, 0x44, 0x45, 0x56, 0x10, 0x03, 0x42, 0x36,
	0x5a, 0x34, 0x67, 0x6f, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x2e, 0x6f, 0x72,
	0x67, 0x2f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2f, 0x69, 0x6e, 0x66,
	0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x63, 0x68, 0x72, 0x6f,
	0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_chromiumos_sign_image_proto_rawDescOnce sync.Once
	file_chromiumos_sign_image_proto_rawDescData = file_chromiumos_sign_image_proto_rawDesc
)

func file_chromiumos_sign_image_proto_rawDescGZIP() []byte {
	file_chromiumos_sign_image_proto_rawDescOnce.Do(func() {
		file_chromiumos_sign_image_proto_rawDescData = protoimpl.X.CompressGZIP(file_chromiumos_sign_image_proto_rawDescData)
	})
	return file_chromiumos_sign_image_proto_rawDescData
}

var file_chromiumos_sign_image_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
var file_chromiumos_sign_image_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_chromiumos_sign_image_proto_goTypes = []interface{}{
	(SignerType)(0),              // 0: chromiumos.SignerType
	(Cr50Instructions_Target)(0), // 1: chromiumos.Cr50Instructions.Target
	(GscInstructions_Target)(0),  // 2: chromiumos.GscInstructions.Target
	(*Cr50Instructions)(nil),     // 3: chromiumos.Cr50Instructions
	(*GscInstructions)(nil),      // 4: chromiumos.GscInstructions
}
var file_chromiumos_sign_image_proto_depIdxs = []int32{
	1, // 0: chromiumos.Cr50Instructions.target:type_name -> chromiumos.Cr50Instructions.Target
	2, // 1: chromiumos.GscInstructions.target:type_name -> chromiumos.GscInstructions.Target
	2, // [2:2] is the sub-list for method output_type
	2, // [2:2] is the sub-list for method input_type
	2, // [2:2] is the sub-list for extension type_name
	2, // [2:2] is the sub-list for extension extendee
	0, // [0:2] is the sub-list for field type_name
}

func init() { file_chromiumos_sign_image_proto_init() }
func file_chromiumos_sign_image_proto_init() {
	if File_chromiumos_sign_image_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_chromiumos_sign_image_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Cr50Instructions); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_chromiumos_sign_image_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*GscInstructions); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_chromiumos_sign_image_proto_rawDesc,
			NumEnums:      3,
			NumMessages:   2,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_chromiumos_sign_image_proto_goTypes,
		DependencyIndexes: file_chromiumos_sign_image_proto_depIdxs,
		EnumInfos:         file_chromiumos_sign_image_proto_enumTypes,
		MessageInfos:      file_chromiumos_sign_image_proto_msgTypes,
	}.Build()
	File_chromiumos_sign_image_proto = out.File
	file_chromiumos_sign_image_proto_rawDesc = nil
	file_chromiumos_sign_image_proto_goTypes = nil
	file_chromiumos_sign_image_proto_depIdxs = nil
}
