// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Messages in this file are used to test wire encoding order.

// Code generated by protoc-gen-go. DO NOT EDIT.
// source: internal/testprotos/order/order.proto

package order

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

type Message struct {
	state   protoimpl.MessageState `protogen:"open.v1"`
	Field_2 *string                `protobuf:"bytes,2,opt,name=field_2,json=field2" json:"field_2,omitempty"`
	Field_1 *string                `protobuf:"bytes,1,opt,name=field_1,json=field1" json:"field_1,omitempty"`
	// Types that are valid to be assigned to Oneof_1:
	//
	//	*Message_Field_10
	Oneof_1         isMessage_Oneof_1 `protobuf_oneof:"oneof_1"`
	Field_20        *string           `protobuf:"bytes,20,opt,name=field_20,json=field20" json:"field_20,omitempty"`
	extensionFields protoimpl.ExtensionFields
	unknownFields   protoimpl.UnknownFields
	sizeCache       protoimpl.SizeCache
}

func (x *Message) Reset() {
	*x = Message{}
	mi := &file_internal_testprotos_order_order_proto_msgTypes[0]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

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

func (*Message) ProtoMessage() {}

func (x *Message) ProtoReflect() protoreflect.Message {
	mi := &file_internal_testprotos_order_order_proto_msgTypes[0]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

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

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

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

func (x *Message) GetOneof_1() isMessage_Oneof_1 {
	if x != nil {
		return x.Oneof_1
	}
	return nil
}

func (x *Message) GetField_10() string {
	if x != nil {
		if x, ok := x.Oneof_1.(*Message_Field_10); ok {
			return x.Field_10
		}
	}
	return ""
}

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

type isMessage_Oneof_1 interface {
	isMessage_Oneof_1()
}

type Message_Field_10 struct {
	Field_10 string `protobuf:"bytes,10,opt,name=field_10,json=field10,oneof"`
}

func (*Message_Field_10) isMessage_Oneof_1() {}

var file_internal_testprotos_order_order_proto_extTypes = []protoimpl.ExtensionInfo{
	{
		ExtendedType:  (*Message)(nil),
		ExtensionType: (*string)(nil),
		Field:         30,
		Name:          "goproto.proto.order.field_30",
		Tag:           "bytes,30,opt,name=field_30",
		Filename:      "internal/testprotos/order/order.proto",
	},
	{
		ExtendedType:  (*Message)(nil),
		ExtensionType: (*string)(nil),
		Field:         31,
		Name:          "goproto.proto.order.field_31",
		Tag:           "bytes,31,opt,name=field_31",
		Filename:      "internal/testprotos/order/order.proto",
	},
	{
		ExtendedType:  (*Message)(nil),
		ExtensionType: (*string)(nil),
		Field:         32,
		Name:          "goproto.proto.order.field_32",
		Tag:           "bytes,32,opt,name=field_32",
		Filename:      "internal/testprotos/order/order.proto",
	},
}

// Extension fields to Message.
var (
	// optional string field_30 = 30;
	E_Field_30 = &file_internal_testprotos_order_order_proto_extTypes[0]
	// optional string field_31 = 31;
	E_Field_31 = &file_internal_testprotos_order_order_proto_extTypes[1]
	// optional string field_32 = 32;
	E_Field_32 = &file_internal_testprotos_order_order_proto_extTypes[2]
)

var File_internal_testprotos_order_order_proto protoreflect.FileDescriptor

const file_internal_testprotos_order_order_proto_rawDesc = "\n%internal/testprotos/order/order.protogoproto.proto.order\"\x84\nMessage\nfield_2 (	Rfield2\nfield_1 (	Rfield1\nfield_10\n (	H\x00Rfield10\nfield_20 (	Rfield20*)B	\noneof_1:7\nfield_30.goproto.proto.order.Message (	Rfield30:7\nfield_31.goproto.proto.order.Message (	Rfield31:7\nfield_32.goproto.proto.order.Message  (	Rfield32B6Z4google.golang.org/protobuf/internal/testprotos/order"

var (
	file_internal_testprotos_order_order_proto_rawDescOnce sync.Once
	file_internal_testprotos_order_order_proto_rawDescData = file_internal_testprotos_order_order_proto_rawDesc
)

func file_internal_testprotos_order_order_proto_rawDescGZIP() []byte {
	file_internal_testprotos_order_order_proto_rawDescOnce.Do(func() {
		file_internal_testprotos_order_order_proto_rawDescData = string(protoimpl.X.CompressGZIP([]byte(file_internal_testprotos_order_order_proto_rawDescData)))
	})
	return []byte(file_internal_testprotos_order_order_proto_rawDescData)
}

var file_internal_testprotos_order_order_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_internal_testprotos_order_order_proto_goTypes = []any{
	(*Message)(nil), // 0: goproto.proto.order.Message
}
var file_internal_testprotos_order_order_proto_depIdxs = []int32{
	0, // 0: goproto.proto.order.field_30:extendee -> goproto.proto.order.Message
	0, // 1: goproto.proto.order.field_31:extendee -> goproto.proto.order.Message
	0, // 2: goproto.proto.order.field_32:extendee -> goproto.proto.order.Message
	3, // [3:3] is the sub-list for method output_type
	3, // [3:3] is the sub-list for method input_type
	3, // [3:3] is the sub-list for extension type_name
	0, // [0:3] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_internal_testprotos_order_order_proto_init() }
func file_internal_testprotos_order_order_proto_init() {
	if File_internal_testprotos_order_order_proto != nil {
		return
	}
	file_internal_testprotos_order_order_proto_msgTypes[0].OneofWrappers = []any{
		(*Message_Field_10)(nil),
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: []byte(file_internal_testprotos_order_order_proto_rawDesc),
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 3,
			NumServices:   0,
		},
		GoTypes:           file_internal_testprotos_order_order_proto_goTypes,
		DependencyIndexes: file_internal_testprotos_order_order_proto_depIdxs,
		MessageInfos:      file_internal_testprotos_order_order_proto_msgTypes,
		ExtensionInfos:    file_internal_testprotos_order_order_proto_extTypes,
	}.Build()
	File_internal_testprotos_order_order_proto = out.File
	file_internal_testprotos_order_order_proto_goTypes = nil
	file_internal_testprotos_order_order_proto_depIdxs = nil
}
