// 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.

// Code generated by protoc-gen-go. DO NOT EDIT.
// source: internal/testprotos/messageset/messagesetpb/messagesetpb_hybrid/message_set.hybrid.proto

//go:build !protoopaque

package messagesetpb_hybrid

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	_ "google.golang.org/protobuf/types/gofeaturespb"
	reflect "reflect"
	unsafe "unsafe"
)

type MessageSet struct {
	state           protoimpl.MessageState `protogen:"hybrid.v1"`
	extensionFields protoimpl.ExtensionFields
	unknownFields   protoimpl.UnknownFields
	sizeCache       protoimpl.SizeCache
}

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

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

func (*MessageSet) ProtoMessage() {}

func (x *MessageSet) ProtoReflect() protoreflect.Message {
	mi := &file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_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)
}

type MessageSet_builder struct {
	_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.

}

func (b0 MessageSet_builder) Build() *MessageSet {
	m0 := &MessageSet{}
	b, x := &b0, m0
	_, _ = b, x
	return m0
}

type MessageSetContainer struct {
	state         protoimpl.MessageState `protogen:"hybrid.v1"`
	MessageSet    *MessageSet            `protobuf:"bytes,1,opt,name=message_set,json=messageSet" json:"message_set,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

func (x *MessageSetContainer) Reset() {
	*x = MessageSetContainer{}
	mi := &file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_msgTypes[1]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

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

func (*MessageSetContainer) ProtoMessage() {}

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

func (x *MessageSetContainer) GetMessageSet() *MessageSet {
	if x != nil {
		return x.MessageSet
	}
	return nil
}

func (x *MessageSetContainer) SetMessageSet(v *MessageSet) {
	x.MessageSet = v
}

func (x *MessageSetContainer) HasMessageSet() bool {
	if x == nil {
		return false
	}
	return x.MessageSet != nil
}

func (x *MessageSetContainer) ClearMessageSet() {
	x.MessageSet = nil
}

type MessageSetContainer_builder struct {
	_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.

	MessageSet *MessageSet
}

func (b0 MessageSetContainer_builder) Build() *MessageSetContainer {
	m0 := &MessageSetContainer{}
	b, x := &b0, m0
	_, _ = b, x
	x.MessageSet = b.MessageSet
	return m0
}

var File_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto protoreflect.FileDescriptor

const file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_rawDesc = "" +
	"\n" +
	"Xinternal/testprotos/messageset/messagesetpb/messagesetpb_hybrid/message_set.hybrid.proto\x12\x1fhybrid.goproto.proto.messageset\x1a!google/protobuf/go_features.proto\"\x1a\n" +
	"\n" +
	"MessageSet*\b\b\x04\x10\xff\xff\xff\xff\a:\x02\b\x01\"c\n" +
	"\x13MessageSetContainer\x12L\n" +
	"\vmessage_set\x18\x01 \x01(\v2+.hybrid.goproto.proto.messageset.MessageSetR\n" +
	"messageSetBdZZgoogle.golang.org/protobuf/internal/testprotos/messageset/messagesetpb/messagesetpb_hybrid\x92\x03\x05\xd2>\x02\x10\x02b\beditionsp\xe8\a"

var file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_goTypes = []any{
	(*MessageSet)(nil),          // 0: hybrid.goproto.proto.messageset.MessageSet
	(*MessageSetContainer)(nil), // 1: hybrid.goproto.proto.messageset.MessageSetContainer
}
var file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_depIdxs = []int32{
	0, // 0: hybrid.goproto.proto.messageset.MessageSetContainer.message_set:type_name -> hybrid.goproto.proto.messageset.MessageSet
	1, // [1:1] is the sub-list for method output_type
	1, // [1:1] is the sub-list for method input_type
	1, // [1:1] is the sub-list for extension type_name
	1, // [1:1] is the sub-list for extension extendee
	0, // [0:1] is the sub-list for field type_name
}

func init() {
	file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_init()
}
func file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_init() {
	if File_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto != nil {
		return
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_rawDesc), len(file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_rawDesc)),
			NumEnums:      0,
			NumMessages:   2,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_goTypes,
		DependencyIndexes: file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_depIdxs,
		MessageInfos:      file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_msgTypes,
	}.Build()
	File_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto = out.File
	file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_goTypes = nil
	file_internal_testprotos_messageset_messagesetpb_messagesetpb_hybrid_message_set_hybrid_proto_depIdxs = nil
}
