// Code generated by fidlgen; DO NOT EDIT.

package arrays

import (
	_bindings "syscall/zx/fidl"
)

type StructSmallArray struct {
	_ struct{}  `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"4"`
	A [2]uint32 `fidl_offset_v1:"0"`
}

var _mStructSmallArray = _bindings.CreateLazyMarshaler(StructSmallArray{})

func (msg *StructSmallArray) Marshaler() _bindings.Marshaler {
	return _mStructSmallArray
}

type StructLargeArray struct {
	_ struct{}    `fidl:"s" fidl_size_v1:"400" fidl_alignment_v1:"4"`
	A [100]uint32 `fidl_offset_v1:"0"`
}

var _mStructLargeArray = _bindings.CreateLazyMarshaler(StructLargeArray{})

func (msg *StructLargeArray) Marshaler() _bindings.Marshaler {
	return _mStructLargeArray
}

type I_unionSmallArrayTag uint64

const (
	UnionSmallArrayA = 1 // 0x00000001
)

type UnionSmallArray struct {
	I_unionSmallArrayTag `fidl:"x!" fidl_size_v1:"24" fidl_alignment_v1:"8" fidl_resource:"false"`
	A                    [2]uint32 `fidl_ordinal:"1"`
}

func (_m *UnionSmallArray) reset() {
	switch _m.I_unionSmallArrayTag {
	case 1:
		var _zeroed [2]uint32
		_m.A = _zeroed
	}
}

func (_m *UnionSmallArray) Which() I_unionSmallArrayTag {
	return _m.I_unionSmallArrayTag
}

func (_m *UnionSmallArray) Ordinal() uint64 {
	return uint64(_m.I_unionSmallArrayTag)
}

func (_m *UnionSmallArray) SetA(a [2]uint32) {
	_m.reset()
	_m.I_unionSmallArrayTag = UnionSmallArrayA
	_m.A = a
}

func UnionSmallArrayWithA(a [2]uint32) UnionSmallArray {
	var _u UnionSmallArray
	_u.SetA(a)
	return _u
}

type I_unionLargeArrayTag uint64

const (
	UnionLargeArrayA = 1 // 0x00000001
)

type UnionLargeArray struct {
	I_unionLargeArrayTag `fidl:"x!" fidl_size_v1:"24" fidl_alignment_v1:"8" fidl_resource:"false"`
	A                    [100]uint32 `fidl_ordinal:"1"`
}

func (_m *UnionLargeArray) reset() {
	switch _m.I_unionLargeArrayTag {
	case 1:
		var _zeroed [100]uint32
		_m.A = _zeroed
	}
}

func (_m *UnionLargeArray) Which() I_unionLargeArrayTag {
	return _m.I_unionLargeArrayTag
}

func (_m *UnionLargeArray) Ordinal() uint64 {
	return uint64(_m.I_unionLargeArrayTag)
}

func (_m *UnionLargeArray) SetA(a [100]uint32) {
	_m.reset()
	_m.I_unionLargeArrayTag = UnionLargeArrayA
	_m.A = a
}

func UnionLargeArrayWithA(a [100]uint32) UnionLargeArray {
	var _u UnionLargeArray
	_u.SetA(a)
	return _u
}

type TableSmallArray struct {
	_             struct{} `fidl:"t" fidl_size_v1:"16" fidl_alignment_v1:"8" fidl_resource:"false"`
	I_unknownData interface{}
	A             [2]uint32 `fidl_ordinal:"1"`
	APresent      bool
}

func (u *TableSmallArray) SetA(a [2]uint32) {
	u.A = a
	u.APresent = true
}

func (u *TableSmallArray) GetA() [2]uint32 {
	return u.A
}

func (u *TableSmallArray) GetAWithDefault(_default [2]uint32) [2]uint32 {
	if !u.HasA() {
		return _default
	}
	return u.A
}

func (u *TableSmallArray) HasA() bool {
	return u.APresent
}

func (u *TableSmallArray) ClearA() {
	u.APresent = false
}

func (u *TableSmallArray) HasUnknownData() bool {
	return u.I_unknownData != nil
}

func (u *TableSmallArray) GetUnknownData() map[uint64]_bindings.UnknownData {
	return u.I_unknownData.(map[uint64]_bindings.UnknownData)
}

type TableLargeArray struct {
	_             struct{} `fidl:"t" fidl_size_v1:"16" fidl_alignment_v1:"8" fidl_resource:"false"`
	I_unknownData interface{}
	A             [100]uint32 `fidl_ordinal:"1"`
	APresent      bool
}

func (u *TableLargeArray) SetA(a [100]uint32) {
	u.A = a
	u.APresent = true
}

func (u *TableLargeArray) GetA() [100]uint32 {
	return u.A
}

func (u *TableLargeArray) GetAWithDefault(_default [100]uint32) [100]uint32 {
	if !u.HasA() {
		return _default
	}
	return u.A
}

func (u *TableLargeArray) HasA() bool {
	return u.APresent
}

func (u *TableLargeArray) ClearA() {
	u.APresent = false
}

func (u *TableLargeArray) HasUnknownData() bool {
	return u.I_unknownData != nil
}

func (u *TableLargeArray) GetUnknownData() map[uint64]_bindings.UnknownData {
	return u.I_unknownData.(map[uint64]_bindings.UnknownData)
}
