// automatically generated by the FlatBuffers compiler, do not modify
import * as flatbuffers from 'flatbuffers';
export class Foo {
  constructor() {
    this.bb = null;
    this.bb_pos = 0;
  }
  __init(i, bb) {
    this.bb_pos = i;
    this.bb = bb;
    return this;
  }
  static getRootAsFoo(bb, obj) {
    return (obj || new Foo())
        .__init(bb.readInt32(bb.position()) + bb.position(), bb);
  }
  static getSizePrefixedRootAsFoo(bb, obj) {
    bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
    return (obj || new Foo())
        .__init(bb.readInt32(bb.position()) + bb.position(), bb);
  }
  strA(optionalEncoding) {
    const offset = this.bb.__offset(this.bb_pos, 4);
    return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) :
                    null;
  }
  strB(optionalEncoding) {
    const offset = this.bb.__offset(this.bb_pos, 6);
    return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) :
                    null;
  }
  static startFoo(builder) {
    builder.startObject(2);
  }
  static addStrA(builder, strAOffset) {
    builder.addFieldOffset(0, strAOffset, 0);
  }
  static addStrB(builder, strBOffset) {
    builder.addFieldOffset(1, strBOffset, 0);
  }
  static endFoo(builder) {
    const offset = builder.endObject();
    builder.requiredField(offset, 4);  // str_a
    builder.requiredField(offset, 6);  // str_b
    return offset;
  }
  static createFoo(builder, strAOffset, strBOffset) {
    Foo.startFoo(builder);
    Foo.addStrA(builder, strAOffset);
    Foo.addStrB(builder, strBOffset);
    return Foo.endFoo(builder);
  }
}
