// Code generated by fidlgen; DO NOT EDIT.

package unionsandwich

import (
	_bindings "syscall/zx/fidl"
)

type SandwichUnionSize8Alignment4 struct {
	_      struct{}             `fidl:"s" fidl_size_v1:"40" fidl_alignment_v1:"8"`
	Before uint32               `fidl_offset_v1:"0"`
	Union  UnionSize8Alignment4 `fidl_offset_v1:"8"`
	After  uint32               `fidl_offset_v1:"32"`
}

var _mSandwichUnionSize8Alignment4 = _bindings.CreateLazyMarshaler(SandwichUnionSize8Alignment4{})

func (msg *SandwichUnionSize8Alignment4) Marshaler() _bindings.Marshaler {
	return _mSandwichUnionSize8Alignment4
}

type SandwichUnionSize12Alignment4 struct {
	_      struct{}              `fidl:"s" fidl_size_v1:"40" fidl_alignment_v1:"8"`
	Before uint32                `fidl_offset_v1:"0"`
	Union  UnionSize12Alignment4 `fidl_offset_v1:"8"`
	After  int32                 `fidl_offset_v1:"32"`
}

var _mSandwichUnionSize12Alignment4 = _bindings.CreateLazyMarshaler(SandwichUnionSize12Alignment4{})

func (msg *SandwichUnionSize12Alignment4) Marshaler() _bindings.Marshaler {
	return _mSandwichUnionSize12Alignment4
}

type StructSize16Alignment8 struct {
	_  struct{} `fidl:"s" fidl_size_v1:"16" fidl_alignment_v1:"8"`
	F1 uint64   `fidl_offset_v1:"0"`
	F2 uint64   `fidl_offset_v1:"8"`
}

var _mStructSize16Alignment8 = _bindings.CreateLazyMarshaler(StructSize16Alignment8{})

func (msg *StructSize16Alignment8) Marshaler() _bindings.Marshaler {
	return _mStructSize16Alignment8
}

type SandwichUnionSize24Alignment8 struct {
	_      struct{}              `fidl:"s" fidl_size_v1:"40" fidl_alignment_v1:"8"`
	Before uint32                `fidl_offset_v1:"0"`
	Union  UnionSize24Alignment8 `fidl_offset_v1:"8"`
	After  uint32                `fidl_offset_v1:"32"`
}

var _mSandwichUnionSize24Alignment8 = _bindings.CreateLazyMarshaler(SandwichUnionSize24Alignment8{})

func (msg *SandwichUnionSize24Alignment8) Marshaler() _bindings.Marshaler {
	return _mSandwichUnionSize24Alignment8
}

type SandwichUnionSize36Alignment4 struct {
	_      struct{}              `fidl:"s" fidl_size_v1:"40" fidl_alignment_v1:"8"`
	Before uint32                `fidl_offset_v1:"0"`
	Union  UnionSize36Alignment4 `fidl_offset_v1:"8"`
	After  uint32                `fidl_offset_v1:"32"`
}

var _mSandwichUnionSize36Alignment4 = _bindings.CreateLazyMarshaler(SandwichUnionSize36Alignment4{})

func (msg *SandwichUnionSize36Alignment4) Marshaler() _bindings.Marshaler {
	return _mSandwichUnionSize36Alignment4
}

type I_unionSize8Alignment4Tag uint64

const (
	UnionSize8Alignment4Variant = 1 // 0x00000001
)

type UnionSize8Alignment4 struct {
	I_unionSize8Alignment4Tag `fidl:"x!" fidl_size_v1:"24" fidl_alignment_v1:"8" fidl_resource:"false"`
	Variant                   uint32 `fidl_ordinal:"1"`
}

func (_m *UnionSize8Alignment4) reset() {
	switch _m.I_unionSize8Alignment4Tag {
	case 1:
		var _zeroed uint32
		_m.Variant = _zeroed
	}
}

func (_m *UnionSize8Alignment4) Which() I_unionSize8Alignment4Tag {
	return _m.I_unionSize8Alignment4Tag
}

func (_m *UnionSize8Alignment4) Ordinal() uint64 {
	return uint64(_m.I_unionSize8Alignment4Tag)
}

func (_m *UnionSize8Alignment4) SetVariant(variant uint32) {
	_m.reset()
	_m.I_unionSize8Alignment4Tag = UnionSize8Alignment4Variant
	_m.Variant = variant
}

func UnionSize8Alignment4WithVariant(variant uint32) UnionSize8Alignment4 {
	var _u UnionSize8Alignment4
	_u.SetVariant(variant)
	return _u
}

type I_unionSize12Alignment4Tag uint64

const (
	UnionSize12Alignment4Variant = 1 // 0x00000001
)

type UnionSize12Alignment4 struct {
	I_unionSize12Alignment4Tag `fidl:"x!" fidl_size_v1:"24" fidl_alignment_v1:"8" fidl_resource:"false"`
	Variant                    [6]uint8 `fidl_ordinal:"1"`
}

func (_m *UnionSize12Alignment4) reset() {
	switch _m.I_unionSize12Alignment4Tag {
	case 1:
		var _zeroed [6]uint8
		_m.Variant = _zeroed
	}
}

func (_m *UnionSize12Alignment4) Which() I_unionSize12Alignment4Tag {
	return _m.I_unionSize12Alignment4Tag
}

func (_m *UnionSize12Alignment4) Ordinal() uint64 {
	return uint64(_m.I_unionSize12Alignment4Tag)
}

func (_m *UnionSize12Alignment4) SetVariant(variant [6]uint8) {
	_m.reset()
	_m.I_unionSize12Alignment4Tag = UnionSize12Alignment4Variant
	_m.Variant = variant
}

func UnionSize12Alignment4WithVariant(variant [6]uint8) UnionSize12Alignment4 {
	var _u UnionSize12Alignment4
	_u.SetVariant(variant)
	return _u
}

type I_unionSize24Alignment8Tag uint64

const (
	UnionSize24Alignment8Variant = 1 // 0x00000001
)

type UnionSize24Alignment8 struct {
	I_unionSize24Alignment8Tag `fidl:"x!" fidl_size_v1:"24" fidl_alignment_v1:"8" fidl_resource:"false"`
	Variant                    StructSize16Alignment8 `fidl_ordinal:"1"`
}

func (_m *UnionSize24Alignment8) reset() {
	switch _m.I_unionSize24Alignment8Tag {
	case 1:
		var _zeroed StructSize16Alignment8
		_m.Variant = _zeroed
	}
}

func (_m *UnionSize24Alignment8) Which() I_unionSize24Alignment8Tag {
	return _m.I_unionSize24Alignment8Tag
}

func (_m *UnionSize24Alignment8) Ordinal() uint64 {
	return uint64(_m.I_unionSize24Alignment8Tag)
}

func (_m *UnionSize24Alignment8) SetVariant(variant StructSize16Alignment8) {
	_m.reset()
	_m.I_unionSize24Alignment8Tag = UnionSize24Alignment8Variant
	_m.Variant = variant
}

func UnionSize24Alignment8WithVariant(variant StructSize16Alignment8) UnionSize24Alignment8 {
	var _u UnionSize24Alignment8
	_u.SetVariant(variant)
	return _u
}

type I_unionSize36Alignment4Tag uint64

const (
	UnionSize36Alignment4Variant = 1 // 0x00000001
)

type UnionSize36Alignment4 struct {
	I_unionSize36Alignment4Tag `fidl:"x!" fidl_size_v1:"24" fidl_alignment_v1:"8" fidl_resource:"false"`
	Variant                    [32]uint8 `fidl_ordinal:"1"`
}

func (_m *UnionSize36Alignment4) reset() {
	switch _m.I_unionSize36Alignment4Tag {
	case 1:
		var _zeroed [32]uint8
		_m.Variant = _zeroed
	}
}

func (_m *UnionSize36Alignment4) Which() I_unionSize36Alignment4Tag {
	return _m.I_unionSize36Alignment4Tag
}

func (_m *UnionSize36Alignment4) Ordinal() uint64 {
	return uint64(_m.I_unionSize36Alignment4Tag)
}

func (_m *UnionSize36Alignment4) SetVariant(variant [32]uint8) {
	_m.reset()
	_m.I_unionSize36Alignment4Tag = UnionSize36Alignment4Variant
	_m.Variant = variant
}

func UnionSize36Alignment4WithVariant(variant [32]uint8) UnionSize36Alignment4 {
	var _u UnionSize36Alignment4
	_u.SetVariant(variant)
	return _u
}
