// 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: internal/testprotos/examples/ext/extexample.proto

package ext

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 Concert struct {
	state                    protoimpl.MessageState `protogen:"opaque.v1"`
	xxx_hidden_HeadlinerName *string                `protobuf:"bytes,1,opt,name=headliner_name,json=headlinerName"`
	XXX_raceDetectHookData   protoimpl.RaceDetectHookData
	XXX_presence             [1]uint32
	extensionFields          protoimpl.ExtensionFields
	unknownFields            protoimpl.UnknownFields
	sizeCache                protoimpl.SizeCache
}

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

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

func (*Concert) ProtoMessage() {}

func (x *Concert) ProtoReflect() protoreflect.Message {
	mi := &file_internal_testprotos_examples_ext_extexample_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)
}

func (x *Concert) GetHeadlinerName() string {
	if x != nil {
		if x.xxx_hidden_HeadlinerName != nil {
			return *x.xxx_hidden_HeadlinerName
		}
		return ""
	}
	return ""
}

func (x *Concert) SetHeadlinerName(v string) {
	x.xxx_hidden_HeadlinerName = &v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 1)
}

func (x *Concert) HasHeadlinerName() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 0)
}

func (x *Concert) ClearHeadlinerName() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0)
	x.xxx_hidden_HeadlinerName = nil
}

type Concert_builder struct {
	_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.

	HeadlinerName *string
}

func (b0 Concert_builder) Build() *Concert {
	m0 := &Concert{}
	b, x := &b0, m0
	_, _ = b, x
	if b.HeadlinerName != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 1)
		x.xxx_hidden_HeadlinerName = b.HeadlinerName
	}
	return m0
}

var file_internal_testprotos_examples_ext_extexample_proto_extTypes = []protoimpl.ExtensionInfo{
	{
		ExtendedType:  (*Concert)(nil),
		ExtensionType: (*int32)(nil),
		Field:         123,
		Name:          "goproto.proto.test.promo_id",
		Tag:           "varint,123,opt,name=promo_id",
		Filename:      "internal/testprotos/examples/ext/extexample.proto",
	},
}

// Extension fields to Concert.
var (
	// optional int32 promo_id = 123;
	E_PromoId = &file_internal_testprotos_examples_ext_extexample_proto_extTypes[0]
)

var File_internal_testprotos_examples_ext_extexample_proto protoreflect.FileDescriptor

const file_internal_testprotos_examples_ext_extexample_proto_rawDesc = "\n1internal/testprotos/examples/ext/extexample.protogoproto.proto.test!google/protobuf/go_features.proto\"7\nConcert%\nheadliner_name (	R\rheadlinerName*d\xc8:6\npromo_id.goproto.proto.test.Concert{ (RpromoIdBEZ;google.golang.org/protobuf/internal/testprotos/examples/ext\x92\xd2>beditionsp\xe8"

var file_internal_testprotos_examples_ext_extexample_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_internal_testprotos_examples_ext_extexample_proto_goTypes = []any{
	(*Concert)(nil), // 0: goproto.proto.test.Concert
}
var file_internal_testprotos_examples_ext_extexample_proto_depIdxs = []int32{
	0, // 0: goproto.proto.test.promo_id:extendee -> goproto.proto.test.Concert
	1, // [1:1] is the sub-list for method output_type
	1, // [1:1] is the sub-list for method input_type
	1, // [1:1] is the sub-list for extension type_name
	0, // [0:1] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_internal_testprotos_examples_ext_extexample_proto_init() }
func file_internal_testprotos_examples_ext_extexample_proto_init() {
	if File_internal_testprotos_examples_ext_extexample_proto != nil {
		return
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_testprotos_examples_ext_extexample_proto_rawDesc), len(file_internal_testprotos_examples_ext_extexample_proto_rawDesc)),
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 1,
			NumServices:   0,
		},
		GoTypes:           file_internal_testprotos_examples_ext_extexample_proto_goTypes,
		DependencyIndexes: file_internal_testprotos_examples_ext_extexample_proto_depIdxs,
		MessageInfos:      file_internal_testprotos_examples_ext_extexample_proto_msgTypes,
		ExtensionInfos:    file_internal_testprotos_examples_ext_extexample_proto_extTypes,
	}.Build()
	File_internal_testprotos_examples_ext_extexample_proto = out.File
	file_internal_testprotos_examples_ext_extexample_proto_goTypes = nil
	file_internal_testprotos_examples_ext_extexample_proto_depIdxs = nil
}
