// Copyright 2018 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/extensions/base/base.proto

package base

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

type BaseMessage struct {
	state           protoimpl.MessageState `protogen:"open.v1"`
	Field           *string                `protobuf:"bytes,1,opt,name=field" json:"field,omitempty"`
	extensionFields protoimpl.ExtensionFields
	unknownFields   protoimpl.UnknownFields
	sizeCache       protoimpl.SizeCache
}

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

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

func (*BaseMessage) ProtoMessage() {}

func (x *BaseMessage) ProtoReflect() protoreflect.Message {
	mi := &file_cmd_protoc_gen_go_testdata_extensions_base_base_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 BaseMessage.ProtoReflect.Descriptor instead.
func (*BaseMessage) Descriptor() ([]byte, []int) {
	return file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDescGZIP(), []int{0}
}

func (x *BaseMessage) GetField() string {
	if x != nil && x.Field != nil {
		return *x.Field
	}
	return ""
}

type MessageSetWireFormatMessage struct {
	state           protoimpl.MessageState `protogen:"open.v1"`
	extensionFields protoimpl.ExtensionFields
	unknownFields   protoimpl.UnknownFields
	sizeCache       protoimpl.SizeCache
}

func (x *MessageSetWireFormatMessage) Reset() {
	*x = MessageSetWireFormatMessage{}
	mi := &file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_msgTypes[1]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

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

func (*MessageSetWireFormatMessage) ProtoMessage() {}

func (x *MessageSetWireFormatMessage) ProtoReflect() protoreflect.Message {
	mi := &file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_msgTypes[1]
	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 MessageSetWireFormatMessage.ProtoReflect.Descriptor instead.
func (*MessageSetWireFormatMessage) Descriptor() ([]byte, []int) {
	return file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDescGZIP(), []int{1}
}

var File_cmd_protoc_gen_go_testdata_extensions_base_base_proto protoreflect.FileDescriptor

var file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDesc = string([]byte{
	0x0a, 0x35, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e,
	0x2d, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x65, 0x78, 0x74,
	0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x62, 0x61, 0x73,
	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
	0x6e, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x22, 0x33, 0x0a, 0x0b, 0x42, 0x61, 0x73, 0x65, 0x4d, 0x65,
	0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01,
	0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2a, 0x04, 0x08, 0x04, 0x10,
	0x0a, 0x2a, 0x08, 0x08, 0x10, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x2b, 0x0a, 0x1b, 0x4d,
	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x57, 0x69, 0x72, 0x65, 0x46, 0x6f, 0x72,
	0x6d, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2a, 0x08, 0x08, 0x64, 0x10, 0xff,
	0xff, 0xff, 0xff, 0x07, 0x3a, 0x02, 0x08, 0x01, 0x42, 0x47, 0x5a, 0x45, 0x67, 0x6f, 0x6f, 0x67,
	0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72,
	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
	0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74,
	0x61, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x62, 0x61, 0x73,
	0x65,
})

var (
	file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDescOnce sync.Once
	file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDescData []byte
)

func file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDescGZIP() []byte {
	file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDescOnce.Do(func() {
		file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDesc), len(file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDesc)))
	})
	return file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDescData
}

var file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_goTypes = []any{
	(*BaseMessage)(nil),                 // 0: goproto.protoc.extension.base.BaseMessage
	(*MessageSetWireFormatMessage)(nil), // 1: goproto.protoc.extension.base.MessageSetWireFormatMessage
}
var file_cmd_protoc_gen_go_testdata_extensions_base_base_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_extensions_base_base_proto_init() }
func file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_init() {
	if File_cmd_protoc_gen_go_testdata_extensions_base_base_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_extensions_base_base_proto_rawDesc), len(file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_rawDesc)),
			NumEnums:      0,
			NumMessages:   2,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_goTypes,
		DependencyIndexes: file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_depIdxs,
		MessageInfos:      file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_msgTypes,
	}.Build()
	File_cmd_protoc_gen_go_testdata_extensions_base_base_proto = out.File
	file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_goTypes = nil
	file_cmd_protoc_gen_go_testdata_extensions_base_base_proto_depIdxs = nil
}
