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

@_implementationOnly import FlatBuffers

internal struct Message: FlatBufferObject, Verifiable, ObjectAPIPacker {

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

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

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

  internal var internalMessage: String? { let o = _accessor.offset(VTOFFSET.internalMessage.v); return o == 0 ? nil : _accessor.string(at: o) }
  internal var internalMessageSegmentArray: [UInt8]? { return _accessor.getVector(at: VTOFFSET.internalMessage.v) }
  internal static func startMessage(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
  internal static func add(internalMessage: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: internalMessage, at: VTOFFSET.internalMessage.p) }
  internal static func endMessage(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
  internal static func createMessage(
    _ fbb: inout FlatBufferBuilder,
    internalMessageOffset internalMessage: Offset = Offset()
  ) -> Offset {
    let __start = Message.startMessage(&fbb)
    Message.add(internalMessage: internalMessage, &fbb)
    return Message.endMessage(&fbb, start: __start)
  }
  

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

  internal static func pack(_ builder: inout FlatBufferBuilder, obj: inout MessageT) -> Offset {
    let __internalMessage: Offset
    if let s = obj.internalMessage {
      __internalMessage = builder.create(string: s)
    } else {
      __internalMessage = Offset()
    }

    let __root = Message.startMessage(&builder)
    Message.add(internalMessage: __internalMessage, &builder)
    return Message.endMessage(&builder, start: __root)
  }

  internal 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.internalMessage.p, fieldName: "internalMessage", required: false, type: ForwardOffset<String>.self)
    _v.finish()
  }
}

extension Message: Encodable {

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

internal class MessageT: NativeObject {

  internal var internalMessage: String?

  internal init(_ _t: inout Message) {
    internalMessage = _t.internalMessage
  }

  internal init() {
  }

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

}
