// Copyright 2023 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.33.0
// 	protoc        v3.21.7
// source: go.chromium.org/luci/cv/internal/gerrit/storage.proto

package gerrit

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)
)

// Whom identifies one or a group of Gerrit users involved in the code review
// workflow.
type Whom int32

const (
	Whom_NONE Whom = 0
	// CL owner.
	Whom_OWNER Whom = 1
	// CL Reviewers
	Whom_REVIEWERS Whom = 2
	// Who have voted on the CQ label.
	Whom_CQ_VOTERS Whom = 3
	// Uploader of the patchset that triggered a "New Patchset" Run.
	Whom_PS_UPLOADER Whom = 4
)

// Enum value maps for Whom.
var (
	Whom_name = map[int32]string{
		0: "NONE",
		1: "OWNER",
		2: "REVIEWERS",
		3: "CQ_VOTERS",
		4: "PS_UPLOADER",
	}
	Whom_value = map[string]int32{
		"NONE":        0,
		"OWNER":       1,
		"REVIEWERS":   2,
		"CQ_VOTERS":   3,
		"PS_UPLOADER": 4,
	}
)

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

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

func (Whom) Descriptor() protoreflect.EnumDescriptor {
	return file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_enumTypes[0].Descriptor()
}

func (Whom) Type() protoreflect.EnumType {
	return &file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_enumTypes[0]
}

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

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

var File_go_chromium_org_luci_cv_internal_gerrit_storage_proto protoreflect.FileDescriptor

var file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_rawDesc = []byte{
	0x0a, 0x35, 0x67, 0x6f, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x2e, 0x6f, 0x72,
	0x67, 0x2f, 0x6c, 0x75, 0x63, 0x69, 0x2f, 0x63, 0x76, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
	0x61, 0x6c, 0x2f, 0x67, 0x65, 0x72, 0x72, 0x69, 0x74, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x63, 0x76, 0x2e, 0x69, 0x6e, 0x74, 0x65,
	0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x67, 0x65, 0x72, 0x72, 0x69, 0x74, 0x2a, 0x4a, 0x0a, 0x04, 0x57,
	0x68, 0x6f, 0x6d, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a,
	0x05, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x45, 0x56, 0x49,
	0x45, 0x57, 0x45, 0x52, 0x53, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x51, 0x5f, 0x56, 0x4f,
	0x54, 0x45, 0x52, 0x53, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x53, 0x5f, 0x55, 0x50, 0x4c,
	0x4f, 0x41, 0x44, 0x45, 0x52, 0x10, 0x04, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x6f, 0x2e, 0x63, 0x68,
	0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x6c, 0x75, 0x63, 0x69, 0x2f,
	0x63, 0x76, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x72, 0x72,
	0x69, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_rawDescOnce sync.Once
	file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_rawDescData = file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_rawDesc
)

func file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_rawDescGZIP() []byte {
	file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_rawDescOnce.Do(func() {
		file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_rawDescData = protoimpl.X.CompressGZIP(file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_rawDescData)
	})
	return file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_rawDescData
}

var file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_goTypes = []interface{}{
	(Whom)(0), // 0: cv.internal.gerrit.Whom
}
var file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_depIdxs = []int32{
	0, // [0:0] is the sub-list for method output_type
	0, // [0:0] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_init() }
func file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_init() {
	if File_go_chromium_org_luci_cv_internal_gerrit_storage_proto != nil {
		return
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_rawDesc,
			NumEnums:      1,
			NumMessages:   0,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_goTypes,
		DependencyIndexes: file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_depIdxs,
		EnumInfos:         file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_enumTypes,
	}.Build()
	File_go_chromium_org_luci_cv_internal_gerrit_storage_proto = out.File
	file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_rawDesc = nil
	file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_goTypes = nil
	file_go_chromium_org_luci_cv_internal_gerrit_storage_proto_depIdxs = nil
}
