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

package extra

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

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// 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 ExtraMessage struct {
	Data                 []byte   `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

type xxx_ExtraMessage struct{ m *ExtraMessage }

func (m *ExtraMessage) ProtoReflect() protoreflect.Message {
	return xxx_ExtraMessage{m}
}
func (m xxx_ExtraMessage) Type() protoreflect.MessageType {
	return xxx_Extra_ProtoFile_MessageTypes[0].Type
}
func (m xxx_ExtraMessage) KnownFields() protoreflect.KnownFields {
	return xxx_Extra_ProtoFile_MessageTypes[0].KnownFieldsOf(m.m)
}
func (m xxx_ExtraMessage) UnknownFields() protoreflect.UnknownFields {
	return xxx_Extra_ProtoFile_MessageTypes[0].UnknownFieldsOf(m.m)
}
func (m xxx_ExtraMessage) Interface() protoreflect.ProtoMessage {
	return m.m
}
func (m xxx_ExtraMessage) ProtoMutable() {}

func (m *ExtraMessage) Reset()         { *m = ExtraMessage{} }
func (m *ExtraMessage) String() string { return proto.CompactTextString(m) }
func (*ExtraMessage) ProtoMessage()    {}
func (*ExtraMessage) Descriptor() ([]byte, []int) {
	return fileDescriptor_496c2a5e9c1e8739, []int{0}
}

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

var xxx_messageInfo_ExtraMessage proto.InternalMessageInfo

func (m *ExtraMessage) GetData() []byte {
	if m != nil {
		return m.Data
	}
	return nil
}

func init() {
	proto.RegisterType((*ExtraMessage)(nil), "goproto.protoc.extension.extra.ExtraMessage")
}

func init() { proto.RegisterFile("extensions/extra/extra.proto", fileDescriptor_496c2a5e9c1e8739) }

var fileDescriptor_496c2a5e9c1e8739 = []byte{
	// 149 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x49, 0xad, 0x28, 0x49,
	0xcd, 0x2b, 0xce, 0xcc, 0xcf, 0x2b, 0xd6, 0x4f, 0xad, 0x28, 0x29, 0x4a, 0x84, 0x90, 0x7a, 0x05,
	0x45, 0xf9, 0x25, 0xf9, 0x42, 0x72, 0xe9, 0xf9, 0x60, 0x06, 0x84, 0x9b, 0xac, 0x07, 0x57, 0xac,
	0x07, 0x56, 0xa5, 0xa4, 0xc4, 0xc5, 0xe3, 0x0a, 0x62, 0xf8, 0xa6, 0x16, 0x17, 0x27, 0xa6, 0xa7,
	0x0a, 0x09, 0x71, 0xb1, 0xa4, 0x24, 0x96, 0x24, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x04, 0x81,
	0xd9, 0x4e, 0xde, 0x51, 0x9e, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa,
	0xe9, 0xf9, 0x39, 0x89, 0x79, 0xe9, 0xfa, 0x60, 0xf3, 0x92, 0x4a, 0xd3, 0xf4, 0xcb, 0x8c, 0xf4,
	0x93, 0x73, 0x53, 0x20, 0xfc, 0x64, 0xdd, 0xf4, 0xd4, 0x3c, 0xdd, 0xf4, 0x7c, 0xfd, 0x92, 0xd4,
	0xe2, 0x12, 0x90, 0x5e, 0x7d, 0x74, 0xc7, 0x01, 0x02, 0x00, 0x00, 0xff, 0xff, 0xcb, 0xfb, 0x31,
	0xfc, 0xaf, 0x00, 0x00, 0x00,
}

func init() {
	xxx_Extra_ProtoFile_FileDesc.Messages = xxx_Extra_ProtoFile_MessageDescs[0:1]
	var err error
	Extra_ProtoFile, err = prototype.NewFile(&xxx_Extra_ProtoFile_FileDesc)
	if err != nil {
		panic(err)
	}
}

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

var Extra_ProtoFile protoreflect.FileDescriptor

var xxx_Extra_ProtoFile_FileDesc = prototype.File{
	Syntax:  protoreflect.Proto2,
	Path:    "extensions/extra/extra.proto",
	Package: "goproto.protoc.extension.extra",
}
var xxx_Extra_ProtoFile_MessageTypes = [1]protoimpl.MessageType{
	{Type: prototype.GoMessage(
		xxx_Extra_ProtoFile_MessageDescs[0].Reference(),
		func(protoreflect.MessageType) protoreflect.ProtoMessage {
			return new(ExtraMessage)
		},
	)},
}
var xxx_Extra_ProtoFile_MessageDescs = [1]prototype.Message{
	{
		Name: "ExtraMessage",
		Fields: []prototype.Field{
			{
				Name:        "data",
				Number:      1,
				Cardinality: protoreflect.Optional,
				Kind:        protoreflect.BytesKind,
				JSONName:    "data",
			},
		},
	},
}
