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

package test

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

const (
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 0)
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(0 - protoimpl.MinVersion)
)

type ImportEnum int32

const (
	ImportEnum_IMPORT_ZERO ImportEnum = 0
)

var ImportEnum_name = map[int32]string{
	0: "IMPORT_ZERO",
}

var ImportEnum_value = map[string]int32{
	"IMPORT_ZERO": 0,
}

func (x ImportEnum) Enum() *ImportEnum {
	p := new(ImportEnum)
	*p = x
	return p
}

func (x ImportEnum) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (ImportEnum) Descriptor() protoreflect.EnumDescriptor {
	return file_test_test_import_proto_enumTypes[0].EnumDescriptor
}

func (x ImportEnum) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Do not use.
func (x *ImportEnum) UnmarshalJSON(b []byte) error {
	num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
	if err != nil {
		return err
	}
	*x = ImportEnum(num)
	return nil
}

// Deprecated: Use ImportEnum.Type instead.
func (ImportEnum) EnumDescriptor() ([]byte, []int) {
	return file_test_test_import_proto_rawDescGZIP(), []int{0}
}

type ImportMessage struct {
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields
}

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

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

func (*ImportMessage) ProtoMessage() {}

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

func (m *ImportMessage) XXX_Methods() *protoiface.Methods {
	return file_test_test_import_proto_msgTypes[0].Methods()
}

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

var File_test_test_import_proto protoreflect.FileDescriptor

var file_test_test_import_proto_rawDesc = []byte{
	0x0a, 0x16, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x6d, 0x70, 0x6f,
	0x72, 0x74, 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, 0x0f, 0x0a, 0x0d,
	0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2a, 0x1d, 0x0a,
	0x0a, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0f, 0x0a, 0x0b, 0x49,
	0x4d, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x10, 0x00, 0x42, 0x35, 0x5a, 0x33,
	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, 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 (
	file_test_test_import_proto_rawDescOnce sync.Once
	file_test_test_import_proto_rawDescData = file_test_test_import_proto_rawDesc
)

func file_test_test_import_proto_rawDescGZIP() []byte {
	file_test_test_import_proto_rawDescOnce.Do(func() {
		file_test_test_import_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_test_import_proto_rawDescData)
	})
	return file_test_test_import_proto_rawDescData
}

var file_test_test_import_proto_enumTypes = make([]prototype.Enum, 1)
var file_test_test_import_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_test_test_import_proto_goTypes = []interface{}{
	(ImportEnum)(0),       // 0: goproto.proto.test.ImportEnum
	(*ImportMessage)(nil), // 1: goproto.proto.test.ImportMessage
}
var file_test_test_import_proto_depIdxs = []int32{
	0, // starting offset of method output_type sub-list
	0, // starting offset of method input_type sub-list
	0, // starting offset of extension type_name sub-list
	0, // starting offset of extension extendee sub-list
	0, // starting offset of field type_name sub-list
}

func init() { file_test_test_import_proto_init() }
func file_test_test_import_proto_init() {
	if File_test_test_import_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_test_test_import_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ImportMessage); i {
			case 0:
				return &v.sizeCache
			case 1:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			RawDescriptor: file_test_test_import_proto_rawDesc,
			NumEnums:      1,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_test_test_import_proto_goTypes,
		DependencyIndexes: file_test_test_import_proto_depIdxs,
		MessageInfos:      file_test_test_import_proto_msgTypes,
	}.Build()
	File_test_test_import_proto = out.File
	file_test_test_import_proto_enumTypes = out.Enums
	file_test_test_import_proto_rawDesc = nil
	file_test_test_import_proto_goTypes = nil
	file_test_test_import_proto_depIdxs = nil
}
