// <auto-generated>
//  automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>

namespace NamespaceA
{

using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;

public struct SecondTableInA : IFlatbufferObject
{
  private Table __p;
  public ByteBuffer ByteBuffer { get { return __p.bb; } }
  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_24_3_25(); }
  public static SecondTableInA GetRootAsSecondTableInA(ByteBuffer _bb) { return GetRootAsSecondTableInA(_bb, new SecondTableInA()); }
  public static SecondTableInA GetRootAsSecondTableInA(ByteBuffer _bb, SecondTableInA obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
  public SecondTableInA __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public NamespaceC.TableInC? ReferToC { get { int o = __p.__offset(4); return o != 0 ? (NamespaceC.TableInC?)(new NamespaceC.TableInC()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }

  public static Offset<NamespaceA.SecondTableInA> CreateSecondTableInA(FlatBufferBuilder builder,
      Offset<NamespaceC.TableInC> refer_to_cOffset = default(Offset<NamespaceC.TableInC>)) {
    builder.StartTable(1);
    SecondTableInA.AddReferToC(builder, refer_to_cOffset);
    return SecondTableInA.EndSecondTableInA(builder);
  }

  public static void StartSecondTableInA(FlatBufferBuilder builder) { builder.StartTable(1); }
  public static void AddReferToC(FlatBufferBuilder builder, Offset<NamespaceC.TableInC> referToCOffset) { builder.AddOffset(0, referToCOffset.Value, 0); }
  public static Offset<NamespaceA.SecondTableInA> EndSecondTableInA(FlatBufferBuilder builder) {
    int o = builder.EndTable();
    return new Offset<NamespaceA.SecondTableInA>(o);
  }
  public SecondTableInAT UnPack() {
    var _o = new SecondTableInAT();
    this.UnPackTo(_o);
    return _o;
  }
  public void UnPackTo(SecondTableInAT _o) {
    _o.ReferToC = this.ReferToC.HasValue ? this.ReferToC.Value.UnPack() : null;
  }
  public static Offset<NamespaceA.SecondTableInA> Pack(FlatBufferBuilder builder, SecondTableInAT _o) {
    if (_o == null) return default(Offset<NamespaceA.SecondTableInA>);
    var _refer_to_c = _o.ReferToC == null ? default(Offset<NamespaceC.TableInC>) : NamespaceC.TableInC.Pack(builder, _o.ReferToC);
    return CreateSecondTableInA(
      builder,
      _refer_to_c);
  }
}

public class SecondTableInAT
{
  [Newtonsoft.Json.JsonProperty("refer_to_c")]
  public NamespaceC.TableInCT ReferToC { get; set; }

  public SecondTableInAT() {
    this.ReferToC = null;
  }
}


static public class SecondTableInAVerify
{
  static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
  {
    return verifier.VerifyTableStart(tablePos)
      && verifier.VerifyTable(tablePos, 4 /*ReferToC*/, NamespaceC.TableInCVerify.Verify, false)
      && verifier.VerifyTableEnd(tablePos);
  }
}

}
