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

package nopackage

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoregistry "google.golang.org/protobuf/reflect/protoregistry"
	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 Enum int32

const (
	Enum_ZERO Enum = 0
)

// Deprecated: Use Enum.Type.Values instead.
var Enum_name = map[int32]string{
	0: "ZERO",
}

// Deprecated: Use Enum.Type.Values instead.
var Enum_value = map[string]int32{
	"ZERO": 0,
}

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

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

func (Enum) Descriptor() protoreflect.EnumDescriptor {
	return file_nopackage_nopackage_proto_enumTypes[0].Descriptor()
}

// Deprecated: Use Descriptor instead.
func (Enum) Type() protoreflect.EnumType {
	return file_nopackage_nopackage_proto_enumTypes[0]
}

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

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

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

type Message struct {
	StringField          *string                 `protobuf:"bytes,1,opt,name=string_field,json=stringField" json:"string_field,omitempty"`
	EnumField            *Enum                   `protobuf:"varint,2,opt,name=enum_field,json=enumField,enum=Enum,def=0" json:"enum_field,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
	XXX_unrecognized     protoimpl.UnknownFields `json:"-"`
	XXX_sizecache        protoimpl.SizeCache     `json:"-"`
}

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

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

func (*Message) ProtoMessage() {}

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

func (m *Message) XXX_Methods() *protoiface.Methods {
	return file_nopackage_nopackage_proto_msgTypes[0].Methods()
}

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

const Default_Message_EnumField Enum = Enum_ZERO

func (x *Message) GetStringField() string {
	if x != nil && x.StringField != nil {
		return *x.StringField
	}
	return ""
}

func (x *Message) GetEnumField() Enum {
	if x != nil && x.EnumField != nil {
		return *x.EnumField
	}
	return Default_Message_EnumField
}

var File_nopackage_nopackage_proto protoreflect.FileDescriptor

var file_nopackage_nopackage_proto_rawDesc = []byte{
	0x0a, 0x19, 0x6e, 0x6f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2f, 0x6e, 0x6f, 0x70, 0x61,
	0x63, 0x6b, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x58, 0x0a, 0x07, 0x4d,
	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
	0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x74,
	0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2a, 0x0a, 0x0a, 0x65, 0x6e, 0x75,
	0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x05, 0x2e,
	0x45, 0x6e, 0x75, 0x6d, 0x3a, 0x04, 0x5a, 0x45, 0x52, 0x4f, 0x52, 0x09, 0x65, 0x6e, 0x75, 0x6d,
	0x46, 0x69, 0x65, 0x6c, 0x64, 0x2a, 0x10, 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x08, 0x0a,
	0x04, 0x5a, 0x45, 0x52, 0x4f, 0x10, 0x00,
}

var (
	file_nopackage_nopackage_proto_rawDescOnce sync.Once
	file_nopackage_nopackage_proto_rawDescData = file_nopackage_nopackage_proto_rawDesc
)

func file_nopackage_nopackage_proto_rawDescGZIP() []byte {
	file_nopackage_nopackage_proto_rawDescOnce.Do(func() {
		file_nopackage_nopackage_proto_rawDescData = protoimpl.X.CompressGZIP(file_nopackage_nopackage_proto_rawDescData)
	})
	return file_nopackage_nopackage_proto_rawDescData
}

var file_nopackage_nopackage_proto_enumTypes = make([]protoreflect.EnumType, 1)
var file_nopackage_nopackage_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_nopackage_nopackage_proto_goTypes = []interface{}{
	(Enum)(0),       // 0: Enum
	(*Message)(nil), // 1: Message
}
var file_nopackage_nopackage_proto_depIdxs = []int32{
	0, // Message.enum_field:type_name -> Enum
}

func init() { file_nopackage_nopackage_proto_init() }
func file_nopackage_nopackage_proto_init() {
	if File_nopackage_nopackage_proto != nil {
		return
	}
	File_nopackage_nopackage_proto = protoimpl.FileBuilder{
		RawDescriptor:      file_nopackage_nopackage_proto_rawDesc,
		GoTypes:            file_nopackage_nopackage_proto_goTypes,
		DependencyIndexes:  file_nopackage_nopackage_proto_depIdxs,
		EnumOutputTypes:    file_nopackage_nopackage_proto_enumTypes,
		MessageOutputTypes: file_nopackage_nopackage_proto_msgTypes,
		FilesRegistry:      protoregistry.GlobalFiles,
		TypesRegistry:      protoregistry.GlobalTypes,
	}.Init()
	file_nopackage_nopackage_proto_rawDesc = nil
	file_nopackage_nopackage_proto_goTypes = nil
	file_nopackage_nopackage_proto_depIdxs = nil
}
