// Copyright 2020 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/issue780_oneof_conflict/test.proto

package issue780_oneof_conflict

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

type Foo struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// Types that are valid to be assigned to Bar:
	//
	//	*Foo_GetBar
	Bar           isFoo_Bar `protobuf_oneof:"bar"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

func (x *Foo) Reset() {
	*x = Foo{}
	mi := &file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_msgTypes[0]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

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

func (*Foo) ProtoMessage() {}

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

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

func (x *Foo) GetBar() isFoo_Bar {
	if x != nil {
		return x.Bar
	}
	return nil
}

func (x *Foo) GetGetBar() string {
	if x != nil {
		if x, ok := x.Bar.(*Foo_GetBar); ok {
			return x.GetBar
		}
	}
	return ""
}

type isFoo_Bar interface {
	isFoo_Bar()
}

type Foo_GetBar struct {
	GetBar string `protobuf:"bytes,1,opt,name=get_bar,json=getBar,oneof"`
}

func (*Foo_GetBar) isFoo_Bar() {}

var File_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto protoreflect.FileDescriptor

const file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_rawDesc = "" +
	"\n" +
	"=cmd/protoc-gen-go/testdata/issue780_oneof_conflict/test.proto\x12\toneoftest\"'\n" +
	"\x03Foo\x12\x19\n" +
	"\aget_bar\x18\x01 \x01(\tH\x00R\x06getBarB\x05\n" +
	"\x03barBOZMgoogle.golang.org/protobuf/cmd/protoc-gen-go/testdata/issue780_oneof_conflict"

var (
	file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_rawDescOnce sync.Once
	file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_rawDescData []byte
)

func file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_rawDescGZIP() []byte {
	file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_rawDescOnce.Do(func() {
		file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_rawDesc), len(file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_rawDesc)))
	})
	return file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_rawDescData
}

var file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_goTypes = []any{
	(*Foo)(nil), // 0: oneoftest.Foo
}
var file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_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_issue780_oneof_conflict_test_proto_init() }
func file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_init() {
	if File_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto != nil {
		return
	}
	file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_msgTypes[0].OneofWrappers = []any{
		(*Foo_GetBar)(nil),
	}
	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_issue780_oneof_conflict_test_proto_rawDesc), len(file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_rawDesc)),
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_goTypes,
		DependencyIndexes: file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_depIdxs,
		MessageInfos:      file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_msgTypes,
	}.Build()
	File_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto = out.File
	file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_goTypes = nil
	file_cmd_protoc_gen_go_testdata_issue780_oneof_conflict_test_proto_depIdxs = nil
}
