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

/**
 * @const
 * @namespace
 */
var NamespaceA = NamespaceA || {};

/**
 * @const
 * @namespace
 */
NamespaceA.NamespaceB = NamespaceA.NamespaceB || {};

/**
 * @const
 * @namespace
 */
var NamespaceC = NamespaceC || {};

/**
 * @constructor
 */
NamespaceA.TableInFirstNS = function() {
  /**
   * @type {flatbuffers.ByteBuffer}
   */
  this.bb = null;

  /**
   * @type {number}
   */
  this.bb_pos = 0;
};

/**
 * @param {number} i
 * @param {flatbuffers.ByteBuffer} bb
 * @returns {NamespaceA.TableInFirstNS}
 */
NamespaceA.TableInFirstNS.prototype.__init = function(i, bb) {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @param {flatbuffers.ByteBuffer} bb
 * @param {NamespaceA.TableInFirstNS=} obj
 * @returns {NamespaceA.TableInFirstNS}
 */
NamespaceA.TableInFirstNS.getRootAsTableInFirstNS = function(bb, obj) {
  return (obj || new NamespaceA.TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
 * @returns {NamespaceA.NamespaceB.TableInNestedNS}
 */
NamespaceA.TableInFirstNS.prototype.fooTable = function(obj) {
  var offset = this.bb.__offset(this.bb_pos, 4);
  return offset ? (obj || new NamespaceA.NamespaceB.TableInNestedNS).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};

/**
 * @returns {NamespaceA.NamespaceB.EnumInNestedNS}
 */
NamespaceA.TableInFirstNS.prototype.fooEnum = function() {
  var offset = this.bb.__offset(this.bb_pos, 6);
  return offset ? /** @type {NamespaceA.NamespaceB.EnumInNestedNS} */ (this.bb.readInt8(this.bb_pos + offset)) : NamespaceA.NamespaceB.EnumInNestedNS.A;
};

/**
 * @param {NamespaceA.NamespaceB.EnumInNestedNS} value
 * @returns {boolean}
 */
NamespaceA.TableInFirstNS.prototype.mutate_foo_enum = function(value) {
  var offset = this.bb.__offset(this.bb_pos, 6)

  if (offset === 0) {
    return false;
  }

  this.bb.writeInt8(this.bb_pos + offset, value);
  return true;
}

/**
 * @param {NamespaceA.NamespaceB.StructInNestedNS=} obj
 * @returns {NamespaceA.NamespaceB.StructInNestedNS}
 */
NamespaceA.TableInFirstNS.prototype.fooStruct = function(obj) {
  var offset = this.bb.__offset(this.bb_pos, 8);
  return offset ? (obj || new NamespaceA.NamespaceB.StructInNestedNS).__init(this.bb_pos + offset, this.bb) : null;
};

/**
 * @param {flatbuffers.Builder} builder
 */
NamespaceA.TableInFirstNS.startTableInFirstNS = function(builder) {
  builder.startObject(3);
};

/**
 * @param {flatbuffers.Builder} builder
 * @param {flatbuffers.Offset} fooTableOffset
 */
NamespaceA.TableInFirstNS.addFooTable = function(builder, fooTableOffset) {
  builder.addFieldOffset(0, fooTableOffset, 0);
};

/**
 * @param {flatbuffers.Builder} builder
 * @param {NamespaceA.NamespaceB.EnumInNestedNS} fooEnum
 */
NamespaceA.TableInFirstNS.addFooEnum = function(builder, fooEnum) {
  builder.addFieldInt8(1, fooEnum, NamespaceA.NamespaceB.EnumInNestedNS.A);
};

/**
 * @param {flatbuffers.Builder} builder
 * @param {flatbuffers.Offset} fooStructOffset
 */
NamespaceA.TableInFirstNS.addFooStruct = function(builder, fooStructOffset) {
  builder.addFieldStruct(2, fooStructOffset, 0);
};

/**
 * @param {flatbuffers.Builder} builder
 * @returns {flatbuffers.Offset}
 */
NamespaceA.TableInFirstNS.endTableInFirstNS = function(builder) {
  var offset = builder.endObject();
  return offset;
};

/**
 * @constructor
 */
NamespaceC.TableInC = function() {
  /**
   * @type {flatbuffers.ByteBuffer}
   */
  this.bb = null;

  /**
   * @type {number}
   */
  this.bb_pos = 0;
};

/**
 * @param {number} i
 * @param {flatbuffers.ByteBuffer} bb
 * @returns {NamespaceC.TableInC}
 */
NamespaceC.TableInC.prototype.__init = function(i, bb) {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @param {flatbuffers.ByteBuffer} bb
 * @param {NamespaceC.TableInC=} obj
 * @returns {NamespaceC.TableInC}
 */
NamespaceC.TableInC.getRootAsTableInC = function(bb, obj) {
  return (obj || new NamespaceC.TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param {NamespaceA.TableInFirstNS=} obj
 * @returns {NamespaceA.TableInFirstNS}
 */
NamespaceC.TableInC.prototype.referToA1 = function(obj) {
  var offset = this.bb.__offset(this.bb_pos, 4);
  return offset ? (obj || new NamespaceA.TableInFirstNS).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};

/**
 * @param {NamespaceA.SecondTableInA=} obj
 * @returns {NamespaceA.SecondTableInA}
 */
NamespaceC.TableInC.prototype.referToA2 = function(obj) {
  var offset = this.bb.__offset(this.bb_pos, 6);
  return offset ? (obj || new NamespaceA.SecondTableInA).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};

/**
 * @param {flatbuffers.Builder} builder
 */
NamespaceC.TableInC.startTableInC = function(builder) {
  builder.startObject(2);
};

/**
 * @param {flatbuffers.Builder} builder
 * @param {flatbuffers.Offset} referToA1Offset
 */
NamespaceC.TableInC.addReferToA1 = function(builder, referToA1Offset) {
  builder.addFieldOffset(0, referToA1Offset, 0);
};

/**
 * @param {flatbuffers.Builder} builder
 * @param {flatbuffers.Offset} referToA2Offset
 */
NamespaceC.TableInC.addReferToA2 = function(builder, referToA2Offset) {
  builder.addFieldOffset(1, referToA2Offset, 0);
};

/**
 * @param {flatbuffers.Builder} builder
 * @returns {flatbuffers.Offset}
 */
NamespaceC.TableInC.endTableInC = function(builder) {
  var offset = builder.endObject();
  return offset;
};

/**
 * @constructor
 */
NamespaceA.SecondTableInA = function() {
  /**
   * @type {flatbuffers.ByteBuffer}
   */
  this.bb = null;

  /**
   * @type {number}
   */
  this.bb_pos = 0;
};

/**
 * @param {number} i
 * @param {flatbuffers.ByteBuffer} bb
 * @returns {NamespaceA.SecondTableInA}
 */
NamespaceA.SecondTableInA.prototype.__init = function(i, bb) {
  this.bb_pos = i;
  this.bb = bb;
  return this;
};

/**
 * @param {flatbuffers.ByteBuffer} bb
 * @param {NamespaceA.SecondTableInA=} obj
 * @returns {NamespaceA.SecondTableInA}
 */
NamespaceA.SecondTableInA.getRootAsSecondTableInA = function(bb, obj) {
  return (obj || new NamespaceA.SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};

/**
 * @param {NamespaceC.TableInC=} obj
 * @returns {NamespaceC.TableInC}
 */
NamespaceA.SecondTableInA.prototype.referToC = function(obj) {
  var offset = this.bb.__offset(this.bb_pos, 4);
  return offset ? (obj || new NamespaceC.TableInC).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};

/**
 * @param {flatbuffers.Builder} builder
 */
NamespaceA.SecondTableInA.startSecondTableInA = function(builder) {
  builder.startObject(1);
};

/**
 * @param {flatbuffers.Builder} builder
 * @param {flatbuffers.Offset} referToCOffset
 */
NamespaceA.SecondTableInA.addReferToC = function(builder, referToCOffset) {
  builder.addFieldOffset(0, referToCOffset, 0);
};

/**
 * @param {flatbuffers.Builder} builder
 * @returns {flatbuffers.Offset}
 */
NamespaceA.SecondTableInA.endSecondTableInA = function(builder) {
  var offset = builder.endObject();
  return offset;
};

// Exports for Node.js and RequireJS
this.NamespaceA = NamespaceA;
this.NamespaceC = NamespaceC;
