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

package NamespaceA;

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

@SuppressWarnings("unused")
public final class TableInFirstNS extends Table {
  public static void ValidateVersion() { Constants.FLATBUFFERS_24_3_7(); }
  public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb) { return getRootAsTableInFirstNS(_bb, new TableInFirstNS()); }
  public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS 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 TableInFirstNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public NamespaceA.NamespaceB.TableInNestedNS fooTable() { return fooTable(new NamespaceA.NamespaceB.TableInNestedNS()); }
  public NamespaceA.NamespaceB.TableInNestedNS fooTable(NamespaceA.NamespaceB.TableInNestedNS obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
  public byte fooEnum() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) : 0; }
  public boolean mutateFooEnum(byte foo_enum) { int o = __offset(6); if (o != 0) { bb.put(o + bb_pos, foo_enum); return true; } else { return false; } }
  public byte fooUnionType() { int o = __offset(8); return o != 0 ? bb.get(o + bb_pos) : 0; }
  public Table fooUnion(Table obj) { int o = __offset(10); return o != 0 ? __union(obj, o + bb_pos) : null; }
  public NamespaceA.NamespaceB.StructInNestedNS fooStruct() { return fooStruct(new NamespaceA.NamespaceB.StructInNestedNS()); }
  public NamespaceA.NamespaceB.StructInNestedNS fooStruct(NamespaceA.NamespaceB.StructInNestedNS obj) { int o = __offset(12); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }

  public static void startTableInFirstNS(FlatBufferBuilder builder) { builder.startTable(5); }
  public static void addFooTable(FlatBufferBuilder builder, int fooTableOffset) { builder.addOffset(0, fooTableOffset, 0); }
  public static void addFooEnum(FlatBufferBuilder builder, byte fooEnum) { builder.addByte(1, fooEnum, 0); }
  public static void addFooUnionType(FlatBufferBuilder builder, byte fooUnionType) { builder.addByte(2, fooUnionType, 0); }
  public static void addFooUnion(FlatBufferBuilder builder, int fooUnionOffset) { builder.addOffset(3, fooUnionOffset, 0); }
  public static void addFooStruct(FlatBufferBuilder builder, int fooStructOffset) { builder.addStruct(4, fooStructOffset, 0); }
  public static int endTableInFirstNS(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 TableInFirstNS get(int j) { return get(new TableInFirstNS(), j); }
    public TableInFirstNS get(TableInFirstNS obj, int j) {  return obj.__assign(__indirect(__element(j), bb), bb); }
  }
  public TableInFirstNST unpack() {
    TableInFirstNST _o = new TableInFirstNST();
    unpackTo(_o);
    return _o;
  }
  public void unpackTo(TableInFirstNST _o) {
    if (fooTable() != null) _o.setFooTable(fooTable().unpack());
    else _o.setFooTable(null);
    byte _oFooEnum = fooEnum();
    _o.setFooEnum(_oFooEnum);
    NamespaceA.NamespaceB.UnionInNestedNSUnion _oFooUnion = new NamespaceA.NamespaceB.UnionInNestedNSUnion();
    byte _oFooUnionType = fooUnionType();
    _oFooUnion.setType(_oFooUnionType);
    Table _oFooUnionValue;
    switch (_oFooUnionType) {
      case NamespaceA.NamespaceB.UnionInNestedNS.TableInNestedNS:
        _oFooUnionValue = fooUnion(new NamespaceA.NamespaceB.TableInNestedNS());
        _oFooUnion.setValue(_oFooUnionValue != null ? ((NamespaceA.NamespaceB.TableInNestedNS) _oFooUnionValue).unpack() : null);
        break;
      default: break;
    }
    _o.setFooUnion(_oFooUnion);
    if (fooStruct() != null) fooStruct().unpackTo(_o.getFooStruct());
    else _o.setFooStruct(null);
  }
  public static int pack(FlatBufferBuilder builder, TableInFirstNST _o) {
    if (_o == null) return 0;
    int _foo_table = _o.getFooTable() == null ? 0 : NamespaceA.NamespaceB.TableInNestedNS.pack(builder, _o.getFooTable());
    byte _fooUnionType = _o.getFooUnion() == null ? NamespaceA.NamespaceB.UnionInNestedNS.NONE : _o.getFooUnion().getType();
    int _fooUnion = _o.getFooUnion() == null ? 0 : NamespaceA.NamespaceB.UnionInNestedNSUnion.pack(builder, _o.getFooUnion());
    startTableInFirstNS(builder);
    addFooTable(builder, _foo_table);
    addFooEnum(builder, _o.getFooEnum());
    addFooUnionType(builder, _fooUnionType);
    addFooUnion(builder, _fooUnion);
    addFooStruct(builder, NamespaceA.NamespaceB.StructInNestedNS.pack(builder, _o.getFooStruct()));
    return endTableInFirstNS(builder);
  }
}

