// Copyright 2024 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/lazy/lazy_hybrid/lazy_tree.hybrid.proto

//go:build protoopaque

package lazy_hybrid

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

type Node struct {
	state               protoimpl.MessageState `protogen:"opaque.v1"`
	xxx_hidden_Nested   *Node                  `protobuf:"bytes,99,opt,name=nested"`
	xxx_hidden_Int32    int32                  `protobuf:"varint,1,opt,name=int32"`
	xxx_hidden_Int64    int64                  `protobuf:"varint,2,opt,name=int64"`
	xxx_hidden_Uint32   uint32                 `protobuf:"varint,3,opt,name=uint32"`
	xxx_hidden_Uint64   uint64                 `protobuf:"varint,4,opt,name=uint64"`
	xxx_hidden_Sint32   int32                  `protobuf:"zigzag32,5,opt,name=sint32"`
	xxx_hidden_Sint64   int64                  `protobuf:"zigzag64,6,opt,name=sint64"`
	xxx_hidden_Fixed32  uint32                 `protobuf:"fixed32,7,opt,name=fixed32"`
	xxx_hidden_Fixed64  uint64                 `protobuf:"fixed64,8,opt,name=fixed64"`
	xxx_hidden_Sfixed32 int32                  `protobuf:"fixed32,9,opt,name=sfixed32"`
	xxx_hidden_Sfixed64 int64                  `protobuf:"fixed64,10,opt,name=sfixed64"`
	xxx_hidden_Float    float32                `protobuf:"fixed32,11,opt,name=float"`
	xxx_hidden_Double   float64                `protobuf:"fixed64,12,opt,name=double"`
	xxx_hidden_Bool     bool                   `protobuf:"varint,13,opt,name=bool"`
	xxx_hidden_String_  *string                `protobuf:"bytes,14,opt,name=string"`
	xxx_hidden_Bytes    []byte                 `protobuf:"bytes,15,opt,name=bytes"`
	// Deprecated: Do not use. This will be deleted in the near future.
	XXX_lazyUnmarshalInfo  protoimpl.LazyUnmarshalInfo
	XXX_raceDetectHookData protoimpl.RaceDetectHookData
	XXX_presence           [1]uint32
	unknownFields          protoimpl.UnknownFields
	sizeCache              protoimpl.SizeCache
}

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

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

func (*Node) ProtoMessage() {}

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

func (x *Node) GetNested() *Node {
	if x != nil {
		if protoimpl.X.Present(&(x.XXX_presence[0]), 0) {
			if protoimpl.X.AtomicCheckPointerIsNil(&x.xxx_hidden_Nested) {
				protoimpl.X.UnmarshalField(x, 99)
			}
			var rv *Node
			protoimpl.X.AtomicLoadPointer(protoimpl.Pointer(&x.xxx_hidden_Nested), protoimpl.Pointer(&rv))
			return rv
		}
	}
	return nil
}

func (x *Node) GetInt32() int32 {
	if x != nil {
		return x.xxx_hidden_Int32
	}
	return 0
}

func (x *Node) GetInt64() int64 {
	if x != nil {
		return x.xxx_hidden_Int64
	}
	return 0
}

func (x *Node) GetUint32() uint32 {
	if x != nil {
		return x.xxx_hidden_Uint32
	}
	return 0
}

func (x *Node) GetUint64() uint64 {
	if x != nil {
		return x.xxx_hidden_Uint64
	}
	return 0
}

func (x *Node) GetSint32() int32 {
	if x != nil {
		return x.xxx_hidden_Sint32
	}
	return 0
}

func (x *Node) GetSint64() int64 {
	if x != nil {
		return x.xxx_hidden_Sint64
	}
	return 0
}

func (x *Node) GetFixed32() uint32 {
	if x != nil {
		return x.xxx_hidden_Fixed32
	}
	return 0
}

func (x *Node) GetFixed64() uint64 {
	if x != nil {
		return x.xxx_hidden_Fixed64
	}
	return 0
}

func (x *Node) GetSfixed32() int32 {
	if x != nil {
		return x.xxx_hidden_Sfixed32
	}
	return 0
}

func (x *Node) GetSfixed64() int64 {
	if x != nil {
		return x.xxx_hidden_Sfixed64
	}
	return 0
}

func (x *Node) GetFloat() float32 {
	if x != nil {
		return x.xxx_hidden_Float
	}
	return 0
}

func (x *Node) GetDouble() float64 {
	if x != nil {
		return x.xxx_hidden_Double
	}
	return 0
}

func (x *Node) GetBool() bool {
	if x != nil {
		return x.xxx_hidden_Bool
	}
	return false
}

func (x *Node) GetString() string {
	if x != nil {
		if x.xxx_hidden_String_ != nil {
			return *x.xxx_hidden_String_
		}
		return ""
	}
	return ""
}

func (x *Node) GetBytes() []byte {
	if x != nil {
		return x.xxx_hidden_Bytes
	}
	return nil
}

func (x *Node) SetNested(v *Node) {
	protoimpl.X.AtomicSetPointer(&x.xxx_hidden_Nested, v)
	if v == nil {
		protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0)
	} else {
		protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 16)
	}
}

func (x *Node) SetInt32(v int32) {
	x.xxx_hidden_Int32 = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 1, 16)
}

func (x *Node) SetInt64(v int64) {
	x.xxx_hidden_Int64 = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 2, 16)
}

func (x *Node) SetUint32(v uint32) {
	x.xxx_hidden_Uint32 = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 3, 16)
}

func (x *Node) SetUint64(v uint64) {
	x.xxx_hidden_Uint64 = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 4, 16)
}

func (x *Node) SetSint32(v int32) {
	x.xxx_hidden_Sint32 = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 5, 16)
}

func (x *Node) SetSint64(v int64) {
	x.xxx_hidden_Sint64 = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 6, 16)
}

func (x *Node) SetFixed32(v uint32) {
	x.xxx_hidden_Fixed32 = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 7, 16)
}

func (x *Node) SetFixed64(v uint64) {
	x.xxx_hidden_Fixed64 = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 8, 16)
}

func (x *Node) SetSfixed32(v int32) {
	x.xxx_hidden_Sfixed32 = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 9, 16)
}

func (x *Node) SetSfixed64(v int64) {
	x.xxx_hidden_Sfixed64 = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 10, 16)
}

func (x *Node) SetFloat(v float32) {
	x.xxx_hidden_Float = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 11, 16)
}

func (x *Node) SetDouble(v float64) {
	x.xxx_hidden_Double = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 12, 16)
}

func (x *Node) SetBool(v bool) {
	x.xxx_hidden_Bool = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 13, 16)
}

func (x *Node) SetString(v string) {
	x.xxx_hidden_String_ = &v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 14, 16)
}

func (x *Node) SetBytes(v []byte) {
	if v == nil {
		v = []byte{}
	}
	x.xxx_hidden_Bytes = v
	protoimpl.X.SetPresent(&(x.XXX_presence[0]), 15, 16)
}

func (x *Node) HasNested() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 0)
}

func (x *Node) HasInt32() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 1)
}

func (x *Node) HasInt64() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 2)
}

func (x *Node) HasUint32() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 3)
}

func (x *Node) HasUint64() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 4)
}

func (x *Node) HasSint32() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 5)
}

func (x *Node) HasSint64() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 6)
}

func (x *Node) HasFixed32() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 7)
}

func (x *Node) HasFixed64() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 8)
}

func (x *Node) HasSfixed32() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 9)
}

func (x *Node) HasSfixed64() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 10)
}

func (x *Node) HasFloat() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 11)
}

func (x *Node) HasDouble() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 12)
}

func (x *Node) HasBool() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 13)
}

func (x *Node) HasString() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 14)
}

func (x *Node) HasBytes() bool {
	if x == nil {
		return false
	}
	return protoimpl.X.Present(&(x.XXX_presence[0]), 15)
}

func (x *Node) ClearNested() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0)
	protoimpl.X.AtomicSetPointer(&x.xxx_hidden_Nested, (*Node)(nil))
}

func (x *Node) ClearInt32() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 1)
	x.xxx_hidden_Int32 = 0
}

func (x *Node) ClearInt64() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 2)
	x.xxx_hidden_Int64 = 0
}

func (x *Node) ClearUint32() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 3)
	x.xxx_hidden_Uint32 = 0
}

func (x *Node) ClearUint64() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 4)
	x.xxx_hidden_Uint64 = 0
}

func (x *Node) ClearSint32() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 5)
	x.xxx_hidden_Sint32 = 0
}

func (x *Node) ClearSint64() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 6)
	x.xxx_hidden_Sint64 = 0
}

func (x *Node) ClearFixed32() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 7)
	x.xxx_hidden_Fixed32 = 0
}

func (x *Node) ClearFixed64() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 8)
	x.xxx_hidden_Fixed64 = 0
}

func (x *Node) ClearSfixed32() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 9)
	x.xxx_hidden_Sfixed32 = 0
}

func (x *Node) ClearSfixed64() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 10)
	x.xxx_hidden_Sfixed64 = 0
}

func (x *Node) ClearFloat() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 11)
	x.xxx_hidden_Float = 0
}

func (x *Node) ClearDouble() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 12)
	x.xxx_hidden_Double = 0
}

func (x *Node) ClearBool() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 13)
	x.xxx_hidden_Bool = false
}

func (x *Node) ClearString() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 14)
	x.xxx_hidden_String_ = nil
}

func (x *Node) ClearBytes() {
	protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 15)
	x.xxx_hidden_Bytes = nil
}

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

	Nested   *Node
	Int32    *int32
	Int64    *int64
	Uint32   *uint32
	Uint64   *uint64
	Sint32   *int32
	Sint64   *int64
	Fixed32  *uint32
	Fixed64  *uint64
	Sfixed32 *int32
	Sfixed64 *int64
	Float    *float32
	Double   *float64
	Bool     *bool
	String   *string
	Bytes    []byte
}

func (b0 Node_builder) Build() *Node {
	m0 := &Node{}
	b, x := &b0, m0
	_, _ = b, x
	if b.Nested != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 16)
		x.xxx_hidden_Nested = b.Nested
	}
	if b.Int32 != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 1, 16)
		x.xxx_hidden_Int32 = *b.Int32
	}
	if b.Int64 != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 2, 16)
		x.xxx_hidden_Int64 = *b.Int64
	}
	if b.Uint32 != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 3, 16)
		x.xxx_hidden_Uint32 = *b.Uint32
	}
	if b.Uint64 != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 4, 16)
		x.xxx_hidden_Uint64 = *b.Uint64
	}
	if b.Sint32 != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 5, 16)
		x.xxx_hidden_Sint32 = *b.Sint32
	}
	if b.Sint64 != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 6, 16)
		x.xxx_hidden_Sint64 = *b.Sint64
	}
	if b.Fixed32 != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 7, 16)
		x.xxx_hidden_Fixed32 = *b.Fixed32
	}
	if b.Fixed64 != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 8, 16)
		x.xxx_hidden_Fixed64 = *b.Fixed64
	}
	if b.Sfixed32 != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 9, 16)
		x.xxx_hidden_Sfixed32 = *b.Sfixed32
	}
	if b.Sfixed64 != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 10, 16)
		x.xxx_hidden_Sfixed64 = *b.Sfixed64
	}
	if b.Float != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 11, 16)
		x.xxx_hidden_Float = *b.Float
	}
	if b.Double != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 12, 16)
		x.xxx_hidden_Double = *b.Double
	}
	if b.Bool != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 13, 16)
		x.xxx_hidden_Bool = *b.Bool
	}
	if b.String != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 14, 16)
		x.xxx_hidden_String_ = b.String
	}
	if b.Bytes != nil {
		protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 15, 16)
		x.xxx_hidden_Bytes = b.Bytes
	}
	return m0
}

var File_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto protoreflect.FileDescriptor

const file_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto_rawDesc = "\n;internal/testprotos/lazy/lazy_hybrid/lazy_tree.hybrid.protohybrid.lazy_tree!google/protobuf/go_features.proto\"\xa2\nNode2\nnestedc (2.hybrid.lazy_tree.NodeB(Rnested\nint32 (Rint32\nint64 (Rint64\nuint32 (\rRuint32\nuint64 (Ruint64\nsint32 (Rsint32\nsint64 (Rsint64\nfixed32 (Rfixed32\nfixed64 (Rfixed64\nsfixed32	 (Rsfixed32\nsfixed64\n (Rsfixed64\nfloat (Rfloat\ndouble (Rdouble\nbool\r (Rbool\nstring (	Rstring\nbytes (RbytesBIZ?google.golang.org/protobuf/internal/testprotos/lazy/lazy_hybrid\x92\xd2>beditionsp\xe8"

var file_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto_goTypes = []any{
	(*Node)(nil), // 0: hybrid.lazy_tree.Node
}
var file_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto_depIdxs = []int32{
	0, // 0: hybrid.lazy_tree.Node.nested:type_name -> hybrid.lazy_tree.Node
	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_lazy_lazy_hybrid_lazy_tree_hybrid_proto_init() }
func file_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto_init() {
	if File_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto != nil {
		return
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: []byte(file_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto_rawDesc),
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto_goTypes,
		DependencyIndexes: file_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto_depIdxs,
		MessageInfos:      file_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto_msgTypes,
	}.Build()
	File_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto = out.File
	file_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto_goTypes = nil
	file_internal_testprotos_lazy_lazy_hybrid_lazy_tree_hybrid_proto_depIdxs = nil
}
