// Code generated by the FlatBuffers compiler. DO NOT EDIT.

package order

import (
	flatbuffers "github.com/google/flatbuffers/go"

	Pizza "Pizza"
)

type FoodT struct {
	Pizza     *Pizza.PizzaT `json:"pizza"`
	PizzaTest *Pizza.PizzaT `json:"pizza_test"`
}

func (t *FoodT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
	if t == nil {
		return 0
	}
	pizzaOffset := t.Pizza.Pack(builder)
	pizzaTestOffset := t.PizzaTest.Pack(builder)
	FoodStart(builder)
	FoodAddPizza(builder, pizzaOffset)
	FoodAddPizzaTest(builder, pizzaTestOffset)
	return FoodEnd(builder)
}

func (rcv *Food) UnPackTo(t *FoodT) {
	t.Pizza = rcv.Pizza(nil).UnPack()
	t.PizzaTest = rcv.PizzaTest(nil).UnPack()
}

func (rcv *Food) UnPack() *FoodT {
	if rcv == nil {
		return nil
	}
	t := &FoodT{}
	rcv.UnPackTo(t)
	return t
}

type Food struct {
	_tab flatbuffers.Table
}

func GetRootAsFood(buf []byte, offset flatbuffers.UOffsetT) *Food {
	n := flatbuffers.GetUOffsetT(buf[offset:])
	x := &Food{}
	x.Init(buf, n+offset)
	return x
}

func GetSizePrefixedRootAsFood(buf []byte, offset flatbuffers.UOffsetT) *Food {
	n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
	x := &Food{}
	x.Init(buf, n+offset+flatbuffers.SizeUint32)
	return x
}

func (rcv *Food) Init(buf []byte, i flatbuffers.UOffsetT) {
	rcv._tab.Bytes = buf
	rcv._tab.Pos = i
}

func (rcv *Food) Table() flatbuffers.Table {
	return rcv._tab
}

func (rcv *Food) Pizza(obj *Pizza.Pizza) *Pizza.Pizza {
	o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
	if o != 0 {
		x := rcv._tab.Indirect(o + rcv._tab.Pos)
		if obj == nil {
			obj = new(Pizza.Pizza)
		}
		obj.Init(rcv._tab.Bytes, x)
		return obj
	}
	return nil
}

func (rcv *Food) PizzaTest(obj *Pizza.Pizza) *Pizza.Pizza {
	o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
	if o != 0 {
		x := rcv._tab.Indirect(o + rcv._tab.Pos)
		if obj == nil {
			obj = new(Pizza.Pizza)
		}
		obj.Init(rcv._tab.Bytes, x)
		return obj
	}
	return nil
}

func FoodStart(builder *flatbuffers.Builder) {
	builder.StartObject(2)
}
func FoodAddPizza(builder *flatbuffers.Builder, pizza flatbuffers.UOffsetT) {
	builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(pizza), 0)
}
func FoodAddPizzaTest(builder *flatbuffers.Builder, pizzaTest flatbuffers.UOffsetT) {
	builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(pizzaTest), 0)
}
func FoodEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
	return builder.EndObject()
}
