// 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 {
	state         protoimpl.MessageState
	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 {
	mi := &file_test_test_import_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

func (x *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.state
			case 1:
				return &v.sizeCache
			case 2:
				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
}
