// Copyright 2024 The Go 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.
// source: cmd/protoc-gen-go/testdata/enumprefix/enumprefix.proto

package enumprefix

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	_ "google.golang.org/protobuf/types/gofeaturespb"
	reflect "reflect"
	unsafe "unsafe"
)

type Strip int32

const (
	Strip_ZERO Strip = 0
	Strip_ONE  Strip = 1
)

// Enum value maps for Strip.
var (
	Strip_name = map[int32]string{
		0: "STRIP_ZERO",
		1: "STRIP_ONE",
	}
	Strip_value = map[string]int32{
		"STRIP_ZERO": 0,
		"STRIP_ONE":  1,
	}
)

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

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

func (Strip) Descriptor() protoreflect.EnumDescriptor {
	return file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_enumTypes[0].Descriptor()
}

func (Strip) Type() protoreflect.EnumType {
	return &file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_enumTypes[0]
}

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

type Both int32

const (
	Both_ZERO Both = 0
	Both_ONE  Both = 1
)

// Old (prefixed) names for Both enum values.
const (
	Both_BOTH_ZERO Both = Both_ZERO
	Both_BOTH_ONE  Both = Both_ONE
)

// Enum value maps for Both.
var (
	Both_name = map[int32]string{
		0: "BOTH_ZERO",
		1: "BOTH_ONE",
	}
	Both_value = map[string]int32{
		"BOTH_ZERO": 0,
		"BOTH_ONE":  1,
	}
)

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

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

func (Both) Descriptor() protoreflect.EnumDescriptor {
	return file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_enumTypes[1].Descriptor()
}

func (Both) Type() protoreflect.EnumType {
	return &file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_enumTypes[1]
}

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

type BothNoPrefix int32

const (
	BothNoPrefix_ZERO BothNoPrefix = 0
	BothNoPrefix_ONE  BothNoPrefix = 1
)

// Enum value maps for BothNoPrefix.
var (
	BothNoPrefix_name = map[int32]string{
		0: "ZERO",
		1: "ONE",
	}
	BothNoPrefix_value = map[string]int32{
		"ZERO": 0,
		"ONE":  1,
	}
)

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

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

func (BothNoPrefix) Descriptor() protoreflect.EnumDescriptor {
	return file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_enumTypes[2].Descriptor()
}

func (BothNoPrefix) Type() protoreflect.EnumType {
	return &file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_enumTypes[2]
}

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

type BothButOne int32

const (
	BothButOne_ZERO             BothButOne = 0
	BothButOne_BOTH_BUT_ONE_ONE BothButOne = 1
)

// Old (prefixed) names for BothButOne enum values.
const (
	BothButOne_BOTH_BUT_ONE_ZERO BothButOne = BothButOne_ZERO
)

// Enum value maps for BothButOne.
var (
	BothButOne_name = map[int32]string{
		0: "BOTH_BUT_ONE_ZERO",
		1: "BOTH_BUT_ONE_ONE",
	}
	BothButOne_value = map[string]int32{
		"BOTH_BUT_ONE_ZERO": 0,
		"BOTH_BUT_ONE_ONE":  1,
	}
)

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

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

func (BothButOne) Descriptor() protoreflect.EnumDescriptor {
	return file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_enumTypes[3].Descriptor()
}

func (BothButOne) Type() protoreflect.EnumType {
	return &file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_enumTypes[3]
}

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

var File_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto protoreflect.FileDescriptor

const file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_rawDesc = "\n6cmd/protoc-gen-go/testdata/enumprefix/enumprefix.protogoproto.protoc.enumprefix!google/protobuf/go_features.proto*&\nStrip\n\nSTRIP_ZERO\x00\r\n	STRIP_ONE*,\nBoth\r\n	BOTH_ZERO\x00\nBOTH_ONE:\xd2>**\nBothNoPrefix\nZERO\x00\nONE:\xd2>*K\n\nBothButOne\nBOTH_BUT_ONE_ZERO\x00\nBOTH_BUT_ONE_ONE\xd2>:\xd2>BJZ@google.golang.org/protobuf/cmd/protoc-gen-go/testdata/enumprefix\x92\xd2>beditionsp\xe9"

var file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
var file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_goTypes = []any{
	(Strip)(0),        // 0: goproto.protoc.enumprefix.Strip
	(Both)(0),         // 1: goproto.protoc.enumprefix.Both
	(BothNoPrefix)(0), // 2: goproto.protoc.enumprefix.BothNoPrefix
	(BothButOne)(0),   // 3: goproto.protoc.enumprefix.BothButOne
}
var file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_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_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_init() }
func file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_init() {
	if File_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto != nil {
		return
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: unsafe.Slice(unsafe.StringData(file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_rawDesc), len(file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_rawDesc)),
			NumEnums:      4,
			NumMessages:   0,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_goTypes,
		DependencyIndexes: file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_depIdxs,
		EnumInfos:         file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_enumTypes,
	}.Build()
	File_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto = out.File
	file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_goTypes = nil
	file_cmd_protoc_gen_go_testdata_enumprefix_enumprefix_proto_depIdxs = nil
}
