// automatically generated by the FlatBuffers compiler, do not modify

package MyGame.Example;

import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;

@SuppressWarnings("unused")
public final class TypeAliases extends Table {
  public static void ValidateVersion() { Constants.FLATBUFFERS_22_10_25(); }
  public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb) { return getRootAsTypeAliases(_bb, new TypeAliases()); }
  public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb, TypeAliases obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
  public TypeAliases __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public byte i8() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; }
  public boolean mutateI8(byte i8) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, i8); return true; } else { return false; } }
  public int u8() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 0; }
  public boolean mutateU8(int u8) { int o = __offset(6); if (o != 0) { bb.put(o + bb_pos, (byte) u8); return true; } else { return false; } }
  public short i16() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) : 0; }
  public boolean mutateI16(short i16) { int o = __offset(8); if (o != 0) { bb.putShort(o + bb_pos, i16); return true; } else { return false; } }
  public int u16() { int o = __offset(10); return o != 0 ? bb.getShort(o + bb_pos) & 0xFFFF : 0; }
  public boolean mutateU16(int u16) { int o = __offset(10); if (o != 0) { bb.putShort(o + bb_pos, (short) u16); return true; } else { return false; } }
  public int i32() { int o = __offset(12); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
  public boolean mutateI32(int i32) { int o = __offset(12); if (o != 0) { bb.putInt(o + bb_pos, i32); return true; } else { return false; } }
  public long u32() { int o = __offset(14); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
  public boolean mutateU32(long u32) { int o = __offset(14); if (o != 0) { bb.putInt(o + bb_pos, (int) u32); return true; } else { return false; } }
  public long i64() { int o = __offset(16); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
  public boolean mutateI64(long i64) { int o = __offset(16); if (o != 0) { bb.putLong(o + bb_pos, i64); return true; } else { return false; } }
  public long u64() { int o = __offset(18); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
  public boolean mutateU64(long u64) { int o = __offset(18); if (o != 0) { bb.putLong(o + bb_pos, u64); return true; } else { return false; } }
  public float f32() { int o = __offset(20); return o != 0 ? bb.getFloat(o + bb_pos) : 0.0f; }
  public boolean mutateF32(float f32) { int o = __offset(20); if (o != 0) { bb.putFloat(o + bb_pos, f32); return true; } else { return false; } }
  public double f64() { int o = __offset(22); return o != 0 ? bb.getDouble(o + bb_pos) : 0.0; }
  public boolean mutateF64(double f64) { int o = __offset(22); if (o != 0) { bb.putDouble(o + bb_pos, f64); return true; } else { return false; } }
  public byte v8(int j) { int o = __offset(24); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; }
  public int v8Length() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
  public ByteVector v8Vector() { return v8Vector(new ByteVector()); }
  public ByteVector v8Vector(ByteVector obj) { int o = __offset(24); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer v8AsByteBuffer() { return __vector_as_bytebuffer(24, 1); }
  public ByteBuffer v8InByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 24, 1); }
  public boolean mutateV8(int j, byte v8) { int o = __offset(24); if (o != 0) { bb.put(__vector(o) + j * 1, v8); return true; } else { return false; } }
  public double vf64(int j) { int o = __offset(26); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
  public int vf64Length() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }
  public DoubleVector vf64Vector() { return vf64Vector(new DoubleVector()); }
  public DoubleVector vf64Vector(DoubleVector obj) { int o = __offset(26); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
  public ByteBuffer vf64AsByteBuffer() { return __vector_as_bytebuffer(26, 8); }
  public ByteBuffer vf64InByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 26, 8); }
  public boolean mutateVf64(int j, double vf64) { int o = __offset(26); if (o != 0) { bb.putDouble(__vector(o) + j * 8, vf64); return true; } else { return false; } }

  public static int createTypeAliases(FlatBufferBuilder builder,
      byte i8,
      int u8,
      short i16,
      int u16,
      int i32,
      long u32,
      long i64,
      long u64,
      float f32,
      double f64,
      int v8Offset,
      int vf64Offset) {
    builder.startTable(12);
    TypeAliases.addF64(builder, f64);
    TypeAliases.addU64(builder, u64);
    TypeAliases.addI64(builder, i64);
    TypeAliases.addVf64(builder, vf64Offset);
    TypeAliases.addV8(builder, v8Offset);
    TypeAliases.addF32(builder, f32);
    TypeAliases.addU32(builder, u32);
    TypeAliases.addI32(builder, i32);
    TypeAliases.addU16(builder, u16);
    TypeAliases.addI16(builder, i16);
    TypeAliases.addU8(builder, u8);
    TypeAliases.addI8(builder, i8);
    return TypeAliases.endTypeAliases(builder);
  }

  public static void startTypeAliases(FlatBufferBuilder builder) { builder.startTable(12); }
  public static void addI8(FlatBufferBuilder builder, byte i8) { builder.addByte(0, i8, 0); }
  public static void addU8(FlatBufferBuilder builder, int u8) { builder.addByte(1, (byte) u8, (byte) 0); }
  public static void addI16(FlatBufferBuilder builder, short i16) { builder.addShort(2, i16, 0); }
  public static void addU16(FlatBufferBuilder builder, int u16) { builder.addShort(3, (short) u16, (short) 0); }
  public static void addI32(FlatBufferBuilder builder, int i32) { builder.addInt(4, i32, 0); }
  public static void addU32(FlatBufferBuilder builder, long u32) { builder.addInt(5, (int) u32, (int) 0L); }
  public static void addI64(FlatBufferBuilder builder, long i64) { builder.addLong(6, i64, 0L); }
  public static void addU64(FlatBufferBuilder builder, long u64) { builder.addLong(7, u64, 0L); }
  public static void addF32(FlatBufferBuilder builder, float f32) { builder.addFloat(8, f32, 0.0f); }
  public static void addF64(FlatBufferBuilder builder, double f64) { builder.addDouble(9, f64, 0.0); }
  public static void addV8(FlatBufferBuilder builder, int v8Offset) { builder.addOffset(10, v8Offset, 0); }
  public static int createV8Vector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); }
  public static int createV8Vector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); }
  public static void startV8Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
  public static void addVf64(FlatBufferBuilder builder, int vf64Offset) { builder.addOffset(11, vf64Offset, 0); }
  public static int createVf64Vector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); }
  public static void startVf64Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
  public static int endTypeAliases(FlatBufferBuilder builder) {
    int o = builder.endTable();
    return o;
  }

  public static final class Vector extends BaseVector {
    public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }

    public TypeAliases get(int j) { return get(new TypeAliases(), j); }
    public TypeAliases get(TypeAliases obj, int j) {  return obj.__assign(__indirect(__element(j), bb), bb); }
  }
  public TypeAliasesT unpack() {
    TypeAliasesT _o = new TypeAliasesT();
    unpackTo(_o);
    return _o;
  }
  public void unpackTo(TypeAliasesT _o) {
    byte _oI8 = i8();
    _o.setI8(_oI8);
    int _oU8 = u8();
    _o.setU8(_oU8);
    short _oI16 = i16();
    _o.setI16(_oI16);
    int _oU16 = u16();
    _o.setU16(_oU16);
    int _oI32 = i32();
    _o.setI32(_oI32);
    long _oU32 = u32();
    _o.setU32(_oU32);
    long _oI64 = i64();
    _o.setI64(_oI64);
    long _oU64 = u64();
    _o.setU64(_oU64);
    float _oF32 = f32();
    _o.setF32(_oF32);
    double _oF64 = f64();
    _o.setF64(_oF64);
    byte[] _oV8 = new byte[v8Length()];
    for (int _j = 0; _j < v8Length(); ++_j) {_oV8[_j] = v8(_j);}
    _o.setV8(_oV8);
    double[] _oVf64 = new double[vf64Length()];
    for (int _j = 0; _j < vf64Length(); ++_j) {_oVf64[_j] = vf64(_j);}
    _o.setVf64(_oVf64);
  }
  public static int pack(FlatBufferBuilder builder, TypeAliasesT _o) {
    if (_o == null) return 0;
    int _v8 = 0;
    if (_o.getV8() != null) {
      _v8 = createV8Vector(builder, _o.getV8());
    }
    int _vf64 = 0;
    if (_o.getVf64() != null) {
      _vf64 = createVf64Vector(builder, _o.getVf64());
    }
    return createTypeAliases(
      builder,
      _o.getI8(),
      _o.getU8(),
      _o.getI16(),
      _o.getU16(),
      _o.getI32(),
      _o.getU32(),
      _o.getI64(),
      _o.getU64(),
      _o.getF32(),
      _o.getF64(),
      _v8,
      _vf64);
  }
}

