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

package proto2

import (
	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"
)

// 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 Message struct {
	I32                  *int32   `protobuf:"varint,1,opt,name=i32" json:"i32,omitempty"`
	M                    *Message `protobuf:"bytes,2,opt,name=m" json:"m,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

type xxx_Message struct{ m *Message }

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

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

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

var xxx_messageInfo_Message proto.InternalMessageInfo

func (m *Message) GetI32() int32 {
	if m != nil && m.I32 != nil {
		return *m.I32
	}
	return 0
}

func (m *Message) GetM() *Message {
	if m != nil {
		return m.M
	}
	return nil
}

func init() {
	proto.RegisterFile("proto2/proto2.proto", fileDescriptor_d756bbe8817c03c1)
	proto.RegisterType((*Message)(nil), "goproto.protoc.proto2.Message")
}

var fileDescriptor_d756bbe8817c03c1 = []byte{
	// 152 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2e, 0x28, 0xca, 0x2f,
	0xc9, 0x37, 0xd2, 0x87, 0x50, 0x7a, 0x60, 0x4a, 0x48, 0x34, 0x3d, 0x1f, 0xcc, 0x80, 0x70, 0x93,
	0x21, 0x94, 0x91, 0x92, 0x27, 0x17, 0xbb, 0x6f, 0x6a, 0x71, 0x71, 0x62, 0x7a, 0xaa, 0x90, 0x00,
	0x17, 0x73, 0xa6, 0xb1, 0x91, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0x88, 0x29, 0xa4, 0xc3,
	0xc5, 0x98, 0x2b, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xa7, 0x87, 0x55, 0xbf, 0x1e, 0x54,
	0x73, 0x10, 0x63, 0xae, 0x93, 0x63, 0x94, 0x7d, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72,
	0x7e, 0xae, 0x7e, 0x7a, 0x7e, 0x4e, 0x62, 0x5e, 0x3a, 0xc4, 0x0d, 0x49, 0xa5, 0x69, 0xfa, 0x65,
	0x46, 0xfa, 0xc9, 0xb9, 0x29, 0x10, 0x7e, 0xb2, 0x6e, 0x7a, 0x6a, 0x9e, 0x6e, 0x7a, 0xbe, 0x7e,
	0x49, 0x6a, 0x71, 0x49, 0x4a, 0x62, 0x49, 0x22, 0xd4, 0xa9, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff,
	0x85, 0x42, 0x0d, 0x5f, 0xba, 0x00, 0x00, 0x00,
}

func init() {
	xxx_Proto2_ProtoFile_FileDesc.Messages = xxx_Proto2_ProtoFile_MessageDescs[0:1]
	xxx_Proto2_ProtoFile_MessageDescs[0].Fields[1].MessageType = xxx_Proto2_ProtoFile_MessageTypes[0].Type
	var err error
	Proto2_ProtoFile, err = prototype.NewFile(&xxx_Proto2_ProtoFile_FileDesc)
	if err != nil {
		panic(err)
	}
}

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

var Proto2_ProtoFile protoreflect.FileDescriptor

var xxx_Proto2_ProtoFile_FileDesc = prototype.File{
	Syntax:  protoreflect.Proto2,
	Path:    "proto2/proto2.proto",
	Package: "goproto.protoc.proto2",
}
var xxx_Proto2_ProtoFile_MessageTypes = [1]protoimpl.MessageType{
	{Type: prototype.GoMessage(
		xxx_Proto2_ProtoFile_MessageDescs[0].Reference(),
		func(protoreflect.MessageType) protoreflect.ProtoMessage {
			return new(Message)
		},
	)},
}
var xxx_Proto2_ProtoFile_MessageDescs = [1]prototype.Message{
	{
		Name: "Message",
		Fields: []prototype.Field{
			{
				Name:        "i32",
				Number:      1,
				Cardinality: protoreflect.Optional,
				Kind:        protoreflect.Int32Kind,
				JSONName:    "i32",
			},
			{
				Name:        "m",
				Number:      2,
				Cardinality: protoreflect.Optional,
				Kind:        protoreflect.MessageKind,
				JSONName:    "m",
			},
		},
	},
}
