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

package test

import (
	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
	protoregistry "github.com/golang/protobuf/v2/reflect/protoregistry"
	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
	sync "sync"
)

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

type WeakImportMessage struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (x *WeakImportMessage) Reset() {
	*x = WeakImportMessage{}
}

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

func (*WeakImportMessage) ProtoMessage() {}

func (x *WeakImportMessage) ProtoReflect() protoreflect.Message {
	return xxx_File_test_test_weak_proto_messageTypes[0].MessageOf(x)
}

// Deprecated: Use WeakImportMessage.ProtoReflect.Type instead.
func (*WeakImportMessage) Descriptor() ([]byte, []int) {
	return xxx_File_test_test_weak_proto_rawDescGZIP(), []int{0}
}

var File_test_test_weak_proto protoreflect.FileDescriptor

var xxx_File_test_test_weak_proto_rawDesc = []byte{
	0x0a, 0x14, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x77, 0x65, 0x61, 0x6b,
	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x22, 0x13, 0x0a, 0x11, 0x57, 0x65,
	0x61, 0x6b, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42,
	0x38, 0x5a, 0x36, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72,
	0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74,
}

var (
	xxx_File_test_test_weak_proto_rawDesc_once sync.Once
	xxx_File_test_test_weak_proto_rawDesc_data = xxx_File_test_test_weak_proto_rawDesc
)

func xxx_File_test_test_weak_proto_rawDescGZIP() []byte {
	xxx_File_test_test_weak_proto_rawDesc_once.Do(func() {
		xxx_File_test_test_weak_proto_rawDesc_data = protoimpl.X.CompressGZIP(xxx_File_test_test_weak_proto_rawDesc_data)
	})
	return xxx_File_test_test_weak_proto_rawDesc_data
}

var xxx_File_test_test_weak_proto_messageTypes = make([]protoimpl.MessageType, 1)
var xxx_File_test_test_weak_proto_goTypes = []interface{}{
	(*WeakImportMessage)(nil), // 0: goproto.proto.test.WeakImportMessage
}
var xxx_File_test_test_weak_proto_depIdxs = []int32{}

func init() { xxx_File_test_test_weak_proto_init() }
func xxx_File_test_test_weak_proto_init() {
	if File_test_test_weak_proto != nil {
		return
	}
	File_test_test_weak_proto = protoimpl.FileBuilder{
		RawDescriptor:      xxx_File_test_test_weak_proto_rawDesc,
		GoTypes:            xxx_File_test_test_weak_proto_goTypes,
		DependencyIndexes:  xxx_File_test_test_weak_proto_depIdxs,
		MessageOutputTypes: xxx_File_test_test_weak_proto_messageTypes,
		FilesRegistry:      protoregistry.GlobalFiles,
		TypesRegistry:      protoregistry.GlobalTypes,
	}.Init()
	xxx_File_test_test_weak_proto_rawDesc = nil
	xxx_File_test_test_weak_proto_goTypes = nil
	xxx_File_test_test_weak_proto_depIdxs = nil
}
