// automatically generated by the FlatBuffers compiler, do not modify
// swiftlint:disable all
// swiftformat:disable all

public struct BytesCount: NativeStruct, Verifiable, FlatbuffersInitializable, NativeObject {

  static func validateVersion() { FlatBuffersVersion_22_9_29() }

  private var _x: Int64

  public init(_ bb: ByteBuffer, o: Int32) {
    let _accessor = Struct(bb: bb, position: o)
    _x = _accessor.readBuffer(of: Int64.self, at: 0)
  }

  public init(x: Int64) {
    _x = x
  }

  public init() {
    _x = 0
  }

  public init(_ _t: inout BytesCount_Mutable) {
    _x = _t.x
  }

  public var x: Int64 { _x }

  public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
    try verifier.inBuffer(position: position, of: BytesCount.self)
  }
}

extension BytesCount: Encodable {

  enum CodingKeys: String, CodingKey {
    case x = "x"
  }
  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    if x != 0 {
      try container.encodeIfPresent(x, forKey: .x)
    }
  }
}

public struct BytesCount_Mutable: FlatBufferObject {

  static func validateVersion() { FlatBuffersVersion_22_9_29() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Struct

  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }

  public var x: Int64 { return _accessor.readBuffer(of: Int64.self, at: 0) }
  @discardableResult public func mutate(x: Int64) -> Bool { return _accessor.mutate(x, index: 0) }
  

  public mutating func unpack() -> BytesCount {
    return BytesCount(&self)
  }
  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout BytesCount?) -> Offset {
    guard var obj = obj else { return Offset() }
    return pack(&builder, obj: &obj)
  }

  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout BytesCount) -> Offset {
    return builder.create(struct: obj)
  }
}

public struct InternalMessage: FlatBufferObject, Verifiable, ObjectAPIPacker {

  static func validateVersion() { FlatBuffersVersion_22_9_29() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Table

  public static func getRootAsInternalMessage(bb: ByteBuffer) -> InternalMessage { return InternalMessage(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }

  private init(_ t: Table) { _accessor = t }
  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }

  private enum VTOFFSET: VOffset {
    case str = 4
    var v: Int32 { Int32(self.rawValue) }
    var p: VOffset { self.rawValue }
  }

  public var str: String? { let o = _accessor.offset(VTOFFSET.str.v); return o == 0 ? nil : _accessor.string(at: o) }
  public var strSegmentArray: [UInt8]? { return _accessor.getVector(at: VTOFFSET.str.v) }
  public static func startInternalMessage(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
  public static func add(str: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: str, at: VTOFFSET.str.p) }
  public static func endInternalMessage(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
  public static func createInternalMessage(
    _ fbb: inout FlatBufferBuilder,
    strOffset str: Offset = Offset()
  ) -> Offset {
    let __start = InternalMessage.startInternalMessage(&fbb)
    InternalMessage.add(str: str, &fbb)
    return InternalMessage.endInternalMessage(&fbb, start: __start)
  }
  

  public mutating func unpack() -> InternalMessageT {
    return InternalMessageT(&self)
  }
  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout InternalMessageT?) -> Offset {
    guard var obj = obj else { return Offset() }
    return pack(&builder, obj: &obj)
  }

  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout InternalMessageT) -> Offset {
    let __str: Offset
    if let s = obj.str {
      __str = builder.create(string: s)
    } else {
      __str = Offset()
    }

    let __root = InternalMessage.startInternalMessage(&builder)
    InternalMessage.add(str: __str, &builder)
    return InternalMessage.endInternalMessage(&builder, start: __root)
  }

  public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
    var _v = try verifier.visitTable(at: position)
    try _v.visit(field: VTOFFSET.str.p, fieldName: "str", required: false, type: ForwardOffset<String>.self)
    _v.finish()
  }
}

extension InternalMessage: Encodable {

  enum CodingKeys: String, CodingKey {
    case str = "str"
  }
  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encodeIfPresent(str, forKey: .str)
  }
}

public class InternalMessageT: NativeObject {

  public var str: String?

  public init(_ _t: inout InternalMessage) {
    str = _t.str
  }

  public init() {
  }

  public func serialize() -> ByteBuffer { return serialize(type: InternalMessage.self) }

}
public struct Message: FlatBufferObject, Verifiable, ObjectAPIPacker {

  static func validateVersion() { FlatBuffersVersion_22_9_29() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Table

  public static func getRootAsMessage(bb: ByteBuffer) -> Message { return Message(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }

  private init(_ t: Table) { _accessor = t }
  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }

  private enum VTOFFSET: VOffset {
    case id = 4
    case position = 6
    case pointer = 8
    var v: Int32 { Int32(self.rawValue) }
    var p: VOffset { self.rawValue }
  }

  public var id: Int64 { let o = _accessor.offset(VTOFFSET.id.v); return o == 0 ? 0 : _accessor.readBuffer(of: Int64.self, at: o) }
  @discardableResult public func mutate(id: Int64) -> Bool {let o = _accessor.offset(VTOFFSET.id.v);  return _accessor.mutate(id, index: o) }
  public var position: BytesCount! { let o = _accessor.offset(VTOFFSET.position.v); return _accessor.readBuffer(of: BytesCount.self, at: o) }
  public var mutablePosition: BytesCount_Mutable! { let o = _accessor.offset(VTOFFSET.position.v); return BytesCount_Mutable(_accessor.bb, o: o + _accessor.postion) }
  public var pointer: InternalMessage! { let o = _accessor.offset(VTOFFSET.pointer.v); return InternalMessage(_accessor.bb, o: _accessor.indirect(o + _accessor.postion)) }
  public static func startMessage(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 3) }
  public static func add(id: Int64, _ fbb: inout FlatBufferBuilder) { fbb.add(element: id, def: 0, at: VTOFFSET.id.p) }
  public static func add(position: BytesCount?, _ fbb: inout FlatBufferBuilder) { guard let position = position else { return }; fbb.create(struct: position, position: VTOFFSET.position.p) }
  public static func add(pointer: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: pointer, at: VTOFFSET.pointer.p) }
  public static func endMessage(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); fbb.require(table: end, fields: [6, 8]); return end }
  public static func createMessage(
    _ fbb: inout FlatBufferBuilder,
    id: Int64 = 0,
    position: BytesCount,
    pointerOffset pointer: Offset
  ) -> Offset {
    let __start = Message.startMessage(&fbb)
    Message.add(id: id, &fbb)
    Message.add(position: position, &fbb)
    Message.add(pointer: pointer, &fbb)
    return Message.endMessage(&fbb, start: __start)
  }
  

  public mutating func unpack() -> MessageT {
    return MessageT(&self)
  }
  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout MessageT?) -> Offset {
    guard var obj = obj else { return Offset() }
    return pack(&builder, obj: &obj)
  }

  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout MessageT) -> Offset {
    let __pointer = InternalMessage.pack(&builder, obj: &obj.pointer)
    let __root = Message.startMessage(&builder)
    Message.add(id: obj.id, &builder)
    Message.add(position: obj.position, &builder)
    Message.add(pointer: __pointer, &builder)
    return Message.endMessage(&builder, start: __root)
  }

  public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
    var _v = try verifier.visitTable(at: position)
    try _v.visit(field: VTOFFSET.id.p, fieldName: "id", required: false, type: Int64.self)
    try _v.visit(field: VTOFFSET.position.p, fieldName: "position", required: true, type: BytesCount.self)
    try _v.visit(field: VTOFFSET.pointer.p, fieldName: "pointer", required: true, type: ForwardOffset<InternalMessage>.self)
    _v.finish()
  }
}

extension Message: Encodable {

  enum CodingKeys: String, CodingKey {
    case id = "id"
    case position = "position"
    case pointer = "pointer"
  }
  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    if id != 0 {
      try container.encodeIfPresent(id, forKey: .id)
    }
    try container.encodeIfPresent(position, forKey: .position)
    try container.encodeIfPresent(pointer, forKey: .pointer)
  }
}

public class MessageT: NativeObject {

  public var id: Int64
  public var position: BytesCount
  public var pointer: InternalMessageT

  public init(_ _t: inout Message) {
    id = _t.id
    position = _t.position
    var __pointer = _t.pointer
    pointer = __pointer!.unpack()
  }

  public init() {
    id = 0
    position = BytesCount()
    pointer = InternalMessageT()
  }

  public func serialize() -> ByteBuffer { return serialize(type: Message.self) }

}
