// Code generated by protoc-gen-go. DO NOT EDIT.
// source: extensions/base/base.proto

package base

import (
	proto "github.com/golang/protobuf/proto"
	protoapi "github.com/golang/protobuf/protoapi"
	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
	reflect "reflect"
)

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

type BaseMessage struct {
	Field                        *string  `protobuf:"bytes,1,opt,name=field" json:"field,omitempty"`
	XXX_NoUnkeyedLiteral         struct{} `json:"-"`
	proto.XXX_InternalExtensions `json:"-"`
	XXX_unrecognized             []byte `json:"-"`
	XXX_sizecache                int32  `json:"-"`
}

func (m *BaseMessage) ProtoReflect() protoreflect.Message {
	return xxx_ProtoFile_extensions_base_base_messageTypes[0].MessageOf(m)
}
func (m *BaseMessage) Reset()         { *m = BaseMessage{} }
func (m *BaseMessage) String() string { return proto.CompactTextString(m) }
func (*BaseMessage) ProtoMessage()    {}
func (*BaseMessage) Descriptor() ([]byte, []int) {
	return fileDescriptor_aebb28f8d5a04466_gzipped, []int{0}
}

var extRange_BaseMessage = []proto.ExtensionRange{
	{Start: 4, End: 9},
	{Start: 16, End: 536870911},
}

func (*BaseMessage) ExtensionRangeArray() []proto.ExtensionRange {
	return extRange_BaseMessage
}

func (m *BaseMessage) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_BaseMessage.Unmarshal(m, b)
}
func (m *BaseMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_BaseMessage.Marshal(b, m, deterministic)
}
func (m *BaseMessage) XXX_Merge(src proto.Message) {
	xxx_messageInfo_BaseMessage.Merge(m, src)
}
func (m *BaseMessage) XXX_Size() int {
	return xxx_messageInfo_BaseMessage.Size(m)
}
func (m *BaseMessage) XXX_DiscardUnknown() {
	xxx_messageInfo_BaseMessage.DiscardUnknown(m)
}

var xxx_messageInfo_BaseMessage proto.InternalMessageInfo

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

type MessageSetWireFormatMessage struct {
	XXX_NoUnkeyedLiteral         struct{} `json:"-"`
	proto.XXX_InternalExtensions `protobuf_messageset:"1" json:"-"`
	XXX_unrecognized             []byte `json:"-"`
	XXX_sizecache                int32  `json:"-"`
}

func (m *MessageSetWireFormatMessage) ProtoReflect() protoreflect.Message {
	return xxx_ProtoFile_extensions_base_base_messageTypes[1].MessageOf(m)
}
func (m *MessageSetWireFormatMessage) Reset()         { *m = MessageSetWireFormatMessage{} }
func (m *MessageSetWireFormatMessage) String() string { return proto.CompactTextString(m) }
func (*MessageSetWireFormatMessage) ProtoMessage()    {}
func (*MessageSetWireFormatMessage) Descriptor() ([]byte, []int) {
	return fileDescriptor_aebb28f8d5a04466_gzipped, []int{1}
}

var extRange_MessageSetWireFormatMessage = []proto.ExtensionRange{
	{Start: 100, End: 2147483646},
}

func (*MessageSetWireFormatMessage) ExtensionRangeArray() []proto.ExtensionRange {
	return extRange_MessageSetWireFormatMessage
}

func (m *MessageSetWireFormatMessage) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_MessageSetWireFormatMessage.Unmarshal(m, b)
}
func (m *MessageSetWireFormatMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_MessageSetWireFormatMessage.Marshal(b, m, deterministic)
}
func (m *MessageSetWireFormatMessage) XXX_Merge(src proto.Message) {
	xxx_messageInfo_MessageSetWireFormatMessage.Merge(m, src)
}
func (m *MessageSetWireFormatMessage) XXX_Size() int {
	return xxx_messageInfo_MessageSetWireFormatMessage.Size(m)
}
func (m *MessageSetWireFormatMessage) XXX_DiscardUnknown() {
	xxx_messageInfo_MessageSetWireFormatMessage.DiscardUnknown(m)
}

var xxx_messageInfo_MessageSetWireFormatMessage proto.InternalMessageInfo

func init() {
	proto.RegisterFile("extensions/base/base.proto", fileDescriptor_aebb28f8d5a04466_gzipped)
	proto.RegisterType((*BaseMessage)(nil), "goproto.protoc.extension.base.BaseMessage")
	proto.RegisterType((*MessageSetWireFormatMessage)(nil), "goproto.protoc.extension.base.MessageSetWireFormatMessage")
}

var fileDescriptor_aebb28f8d5a04466 = []byte{
	// 233 bytes of the wire-encoded FileDescriptorProto
	0x0a, 0x1a, 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, 0x4a, 0x5a,
	0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61,
	0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x32, 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 fileDescriptor_aebb28f8d5a04466_gzipped = protoapi.CompressGZIP(fileDescriptor_aebb28f8d5a04466)

const _ = protoimpl.EnforceVersion(protoimpl.Version - 0)

var ProtoFile_extensions_base_base protoreflect.FileDescriptor

var xxx_ProtoFile_extensions_base_base_messageTypes [2]protoimpl.MessageType
var xxx_ProtoFile_extensions_base_base_goTypes = []interface{}{
	(*BaseMessage)(nil),                 // 0: goproto.protoc.extension.base.BaseMessage
	(*MessageSetWireFormatMessage)(nil), // 1: goproto.protoc.extension.base.MessageSetWireFormatMessage
}
var xxx_ProtoFile_extensions_base_base_depIdxs = []int32{}

func init() {
	var messageTypes [2]protoreflect.MessageType
	ProtoFile_extensions_base_base = protoimpl.FileBuilder{
		RawDescriptor:      fileDescriptor_aebb28f8d5a04466,
		GoTypes:            xxx_ProtoFile_extensions_base_base_goTypes,
		DependencyIndexes:  xxx_ProtoFile_extensions_base_base_depIdxs,
		MessageOutputTypes: messageTypes[:],
	}.Init()
	messageGoTypes := xxx_ProtoFile_extensions_base_base_goTypes[0:][:2]
	for i, mt := range messageTypes[:] {
		xxx_ProtoFile_extensions_base_base_messageTypes[i].GoType = reflect.TypeOf(messageGoTypes[i])
		xxx_ProtoFile_extensions_base_base_messageTypes[i].PBType = mt
	}
	xxx_ProtoFile_extensions_base_base_goTypes = nil
	xxx_ProtoFile_extensions_base_base_depIdxs = nil
}
