// Code generated by fidlgen; DO NOT EDIT.

package nullable

import (
	_zx "syscall/zx"
	_bindings "syscall/zx/fidl"
)

type StructWithNullableString struct {
	_   struct{} `fidl:"s" fidl_size_v1:"16" fidl_alignment_v1:"8"`
	Val *string  `fidl_offset_v1:"0" fidl_bounds:""`
}

var _mStructWithNullableString = _bindings.CreateLazyMarshaler(StructWithNullableString{})

func (msg *StructWithNullableString) Marshaler() _bindings.Marshaler {
	return _mStructWithNullableString
}

type StructWithNullableVector struct {
	_   struct{} `fidl:"s" fidl_size_v1:"16" fidl_alignment_v1:"8"`
	Val *[]int32 `fidl_offset_v1:"0" fidl_bounds:""`
}

var _mStructWithNullableVector = _bindings.CreateLazyMarshaler(StructWithNullableVector{})

func (msg *StructWithNullableVector) Marshaler() _bindings.Marshaler {
	return _mStructWithNullableVector
}

type StructWithNullableHandle struct {
	_   struct{} `fidl:"s" fidl_size_v1:"4" fidl_alignment_v1:"4"`
	Val _zx.VMO  `fidl_offset_v1:"0" fidl_handle_subtype:"3" fidl_handle_rights:"2147483648" fidl_bounds:"1"`
}

var _mStructWithNullableHandle = _bindings.CreateLazyMarshaler(StructWithNullableHandle{})

func (msg *StructWithNullableHandle) Marshaler() _bindings.Marshaler {
	return _mStructWithNullableHandle
}

type StructWithNullableProtocol struct {
	_   struct{}                       `fidl:"s" fidl_size_v1:"4" fidl_alignment_v1:"4"`
	Val SimpleProtocolWithCtxInterface `fidl_offset_v1:"0" fidl_handle_subtype:"4"`
}

var _mStructWithNullableProtocol = _bindings.CreateLazyMarshaler(StructWithNullableProtocol{})

func (msg *StructWithNullableProtocol) Marshaler() _bindings.Marshaler {
	return _mStructWithNullableProtocol
}

type StructWithNullableRequest struct {
	_   struct{}                              `fidl:"s" fidl_size_v1:"4" fidl_alignment_v1:"4"`
	Val SimpleProtocolWithCtxInterfaceRequest `fidl_offset_v1:"0" fidl_handle_subtype:"4" fidl_bounds:"1"`
}

var _mStructWithNullableRequest = _bindings.CreateLazyMarshaler(StructWithNullableRequest{})

func (msg *StructWithNullableRequest) Marshaler() _bindings.Marshaler {
	return _mStructWithNullableRequest
}

type Int32Wrapper struct {
	_   struct{} `fidl:"s" fidl_size_v1:"4" fidl_alignment_v1:"4"`
	Val int32    `fidl_offset_v1:"0"`
}

var _mInt32Wrapper = _bindings.CreateLazyMarshaler(Int32Wrapper{})

func (msg *Int32Wrapper) Marshaler() _bindings.Marshaler {
	return _mInt32Wrapper
}

type StructWithNullableStruct struct {
	_   struct{}      `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	Val *Int32Wrapper `fidl_offset_v1:"0"`
}

var _mStructWithNullableStruct = _bindings.CreateLazyMarshaler(StructWithNullableStruct{})

func (msg *StructWithNullableStruct) Marshaler() _bindings.Marshaler {
	return _mStructWithNullableStruct
}

type StructWithNullableUnion struct {
	_   struct{}     `fidl:"s" fidl_size_v1:"24" fidl_alignment_v1:"8"`
	Val *SimpleUnion `fidl_offset_v1:"0"`
}

var _mStructWithNullableUnion = _bindings.CreateLazyMarshaler(StructWithNullableUnion{})

func (msg *StructWithNullableUnion) Marshaler() _bindings.Marshaler {
	return _mStructWithNullableUnion
}

type simpleProtocolWithCtxAddRequest struct {
	_ struct{} `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	A int32    `fidl_offset_v1:"0"`
	B int32    `fidl_offset_v1:"4"`
}

var _msimpleProtocolWithCtxAddRequest = _bindings.CreateLazyMarshaler(simpleProtocolWithCtxAddRequest{})

func (msg *simpleProtocolWithCtxAddRequest) Marshaler() _bindings.Marshaler {
	return _msimpleProtocolWithCtxAddRequest
}

type simpleProtocolWithCtxAddResponse struct {
	_   struct{} `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	Sum int32    `fidl_offset_v1:"0"`
}

var _msimpleProtocolWithCtxAddResponse = _bindings.CreateLazyMarshaler(simpleProtocolWithCtxAddResponse{})

func (msg *simpleProtocolWithCtxAddResponse) Marshaler() _bindings.Marshaler {
	return _msimpleProtocolWithCtxAddResponse
}

type I_simpleUnionTag uint64

const (
	SimpleUnionA = 1 // 0x00000001
	SimpleUnionB = 2 // 0x00000002
)

type SimpleUnion struct {
	I_simpleUnionTag `fidl:"x!" fidl_size_v1:"24" fidl_alignment_v1:"8" fidl_resource:"false"`
	A                int32   `fidl_ordinal:"1"`
	B                float32 `fidl_ordinal:"2"`
}

func (_m *SimpleUnion) reset() {
	switch _m.I_simpleUnionTag {
	case 1:
		var _zeroed int32
		_m.A = _zeroed
	case 2:
		var _zeroed float32
		_m.B = _zeroed
	}
}

func (_m *SimpleUnion) Which() I_simpleUnionTag {
	return _m.I_simpleUnionTag
}

func (_m *SimpleUnion) Ordinal() uint64 {
	return uint64(_m.I_simpleUnionTag)
}

func (_m *SimpleUnion) SetA(a int32) {
	_m.reset()
	_m.I_simpleUnionTag = SimpleUnionA
	_m.A = a
}

func SimpleUnionWithA(a int32) SimpleUnion {
	var _u SimpleUnion
	_u.SetA(a)
	return _u
}

func (_m *SimpleUnion) SetB(b float32) {
	_m.reset()
	_m.I_simpleUnionTag = SimpleUnionB
	_m.B = b
}

func SimpleUnionWithB(b float32) SimpleUnion {
	var _u SimpleUnion
	_u.SetB(b)
	return _u
}

const (
	SimpleProtocolAddOrdinal uint64 = 0x113010d7832f175d
)

type SimpleProtocolWithCtxInterface _bindings.ChannelProxy

func (p *SimpleProtocolWithCtxInterface) Add(ctx_ _bindings.Context, a int32, b int32) (int32, error) {
	req_ := &simpleProtocolWithCtxAddRequest{
		A: a,
		B: b,
	}
	resp_ := &simpleProtocolWithCtxAddResponse{}
	err_ := ((*_bindings.ChannelProxy)(p)).Call(SimpleProtocolAddOrdinal, req_, resp_)
	return resp_.Sum, err_
}

type SimpleProtocolWithCtx interface {
	Add(ctx_ _bindings.Context, a int32, b int32) (int32, error)
}

type SimpleProtocolWithCtxTransitionalBase struct{}

type SimpleProtocolWithCtxInterfaceRequest _bindings.InterfaceRequest

func NewSimpleProtocolWithCtxInterfaceRequest() (SimpleProtocolWithCtxInterfaceRequest, *SimpleProtocolWithCtxInterface, error) {
	req, cli, err := _bindings.NewInterfaceRequest()
	return SimpleProtocolWithCtxInterfaceRequest(req), (*SimpleProtocolWithCtxInterface)(cli), err
}

type SimpleProtocolWithCtxStub struct {
	Impl SimpleProtocolWithCtx
}

func (s_ *SimpleProtocolWithCtxStub) Dispatch(args_ _bindings.DispatchArgs) (_bindings.Message, bool, error) {
	switch args_.Ordinal {
	case SimpleProtocolAddOrdinal:
		in_ := simpleProtocolWithCtxAddRequest{}
		marshalerCtx, ok := _bindings.GetMarshalerContext(args_.Ctx)
		if !ok {
			return nil, false, _bindings.ErrMissingMarshalerContext
		}
		if _, _, err_ := _bindings.UnmarshalWithContext2(marshalerCtx, args_.Bytes, args_.HandleInfos, &in_); err_ != nil {
			return nil, false, err_
		}
		sum, err_ := s_.Impl.Add(args_.Ctx, in_.A, in_.B)
		out_ := simpleProtocolWithCtxAddResponse{}
		out_.Sum = sum
		return &out_, true, err_
	}
	return nil, false, _bindings.ErrUnknownOrdinal
}

type SimpleProtocolEventProxy _bindings.ChannelProxy
