diff --git a/swift/Sources/FlatBuffers/ByteBuffer.swift b/swift/Sources/FlatBuffers/ByteBuffer.swift
index 46ae1c5..7df41a7 100644
--- a/swift/Sources/FlatBuffers/ByteBuffer.swift
+++ b/swift/Sources/FlatBuffers/ByteBuffer.swift
@@ -1,345 +1,398 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import Foundation
 
 public struct ByteBuffer {
-    
-    /// Storage is a container that would hold the memory pointer to solve the issue of
-    /// deallocating the memory that was held by (memory: UnsafeMutableRawPointer)
-    @usableFromInline final class Storage {
-        // This storage doesn't own the memory, therefore, we won't deallocate on deinit.
-        private let unowned: Bool
-        /// pointer to the start of the buffer object in memory
-        var memory: UnsafeMutableRawPointer
-        /// Capacity of UInt8 the buffer can hold
-        var capacity: Int
-        
-        init(count: Int, alignment: Int) {
-            memory = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: alignment)
-            capacity = count
-            unowned = false
-        }
 
-        init(memory: UnsafeMutableRawPointer, capacity: Int, unowned: Bool) {
-            self.memory = memory
-            self.capacity = capacity
-            self.unowned = unowned
-        }
-        
-        deinit {
-            if !unowned {
-              memory.deallocate()
-            }
-        }
-        
-        func copy(from ptr: UnsafeRawPointer, count: Int) {
-            assert(!unowned, "copy should NOT be called on a buffer that is built by assumingMemoryBound")
-            memory.copyMemory(from: ptr, byteCount: count)
-        }
-        
-        func initialize(for size: Int) {
-            assert(!unowned, "initalize should NOT be called on a buffer that is built by assumingMemoryBound")
-            memset(memory, 0, size)
-        }
-        
-        /// Reallocates the buffer incase the object to be written doesnt fit in the current buffer
-        /// - Parameter size: Size of the current object
-        @usableFromInline internal func reallocate(_ size: Int, writerSize: Int, alignment: Int) {
-            let currentWritingIndex = capacity &- writerSize
-            while capacity <= writerSize &+ size {
-                capacity = capacity << 1
-            }
-            
-            /// solution take from Apple-NIO
-            capacity = capacity.convertToPowerofTwo
-            
-            let newData = UnsafeMutableRawPointer.allocate(byteCount: capacity, alignment: alignment)
-            memset(newData, 0, capacity &- writerSize)
-            memcpy(newData.advanced(by: capacity &- writerSize), memory.advanced(by: currentWritingIndex), writerSize)
-            memory.deallocate()
-            memory = newData
-        }
-    }
-    
-    @usableFromInline var _storage: Storage
-    
-    /// The size of the elements written to the buffer + their paddings
-    private var _writerSize: Int = 0
-    /// Aliginment of the current  memory being written to the buffer
-    internal var alignment = 1
-    /// Current Index which is being used to write to the buffer, it is written from the end to the start of the buffer
-    internal var writerIndex: Int { return _storage.capacity &- _writerSize }
+  /// Storage is a container that would hold the memory pointer to solve the issue of
+  /// deallocating the memory that was held by (memory: UnsafeMutableRawPointer)
+  @usableFromInline
+  final class Storage {
+    // This storage doesn't own the memory, therefore, we won't deallocate on deinit.
+    private let unowned: Bool
+    /// pointer to the start of the buffer object in memory
+    var memory: UnsafeMutableRawPointer
+    /// Capacity of UInt8 the buffer can hold
+    var capacity: Int
 
-    /// Reader is the position of the current Writer Index (capacity - size)
-    public var reader: Int { return writerIndex }
-    /// Current size of the buffer
-    public var size: UOffset { return UOffset(_writerSize) }
-    /// Public Pointer to the buffer object in memory. This should NOT be modified for any reason
-    public var memory: UnsafeMutableRawPointer { return _storage.memory }
-    /// Current capacity for the buffer
-    public var capacity: Int { return _storage.capacity }
-
-    /// Constructor that creates a Flatbuffer object from a UInt8
-    /// - Parameter bytes: Array of UInt8
-    public init(bytes: [UInt8]) {
-        var b = bytes
-        _storage = Storage(count: bytes.count, alignment: alignment)
-        _writerSize = _storage.capacity
-        b.withUnsafeMutableBytes { bufferPointer in
-            self._storage.copy(from: bufferPointer.baseAddress!, count: bytes.count)
-        }
+    init(count: Int, alignment: Int) {
+      memory = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: alignment)
+      capacity = count
+      unowned = false
     }
 
-    /// Constructor that creates a Flatbuffer from the Swift Data type object
-    /// - Parameter data: Swift data Object
-    public init(data: Data) {
-        var b = data
-        _storage = Storage(count: data.count, alignment: alignment)
-        _writerSize = _storage.capacity
-        b.withUnsafeMutableBytes { bufferPointer in
-            self._storage.copy(from: bufferPointer.baseAddress!, count: data.count)
-        }
+    init(memory: UnsafeMutableRawPointer, capacity: Int, unowned: Bool) {
+      self.memory = memory
+      self.capacity = capacity
+      self.unowned = unowned
     }
 
-    /// Constructor that creates a Flatbuffer instance with a size
-    /// - Parameter size: Length of the buffer
-    init(initialSize size: Int) {
-        let size = size.convertToPowerofTwo
-        _storage = Storage(count: size, alignment: alignment)
-        _storage.initialize(for: size)
-    }
-  
-    #if swift(>=5.0)
-    /// Constructor that creates a Flatbuffer object from a ContiguousBytes
-    /// - Parameters:
-    ///   - contiguousBytes: Binary stripe to use as the buffer
-    ///   - count: amount of readable bytes
-    public init<Bytes: ContiguousBytes>(
-        contiguousBytes: Bytes,
-        count: Int
-    ) {
-        _storage = Storage(count: count, alignment: alignment)
-        _writerSize = _storage.capacity
-        contiguousBytes.withUnsafeBytes { buf in
-            _storage.copy(from: buf.baseAddress!, count: buf.count)
-        }
-    }
-    #endif
-    
-    /// Constructor that creates a Flatbuffer from unsafe memory region without copying
-    /// - Parameter assumingMemoryBound: The unsafe memory region
-    /// - Parameter capacity: The size of the given memory region
-    public init(assumingMemoryBound memory: UnsafeMutableRawPointer, capacity: Int) {
-        _storage = Storage(memory: memory, capacity: capacity, unowned: true)
-        _writerSize = capacity
+    deinit {
+      if !unowned {
+        memory.deallocate()
+      }
     }
 
-    /// Creates a copy of the buffer that's being built by calling sizedBuffer
-    /// - Parameters:
-    ///   - memory: Current memory of the buffer
-    ///   - count: count of bytes
-    internal init(memory: UnsafeMutableRawPointer, count: Int) {
-        _storage = Storage(count: count, alignment: alignment)
-        _storage.copy(from: memory, count: count)
-        _writerSize = _storage.capacity
+    func copy(from ptr: UnsafeRawPointer, count: Int) {
+      assert(
+        !unowned,
+        "copy should NOT be called on a buffer that is built by assumingMemoryBound")
+      memory.copyMemory(from: ptr, byteCount: count)
     }
 
-    /// Creates a copy of the existing flatbuffer, by copying it to a different memory.
-    /// - Parameters:
-    ///   - memory: Current memory of the buffer
-    ///   - count: count of bytes
-    ///   - removeBytes: Removes a number of bytes from the current size
-    internal init(memory: UnsafeMutableRawPointer, count: Int, removing removeBytes: Int) {
-        _storage = Storage(count: count, alignment: alignment)
-        _storage.copy(from: memory, count: count)
-        _writerSize = removeBytes
+    func initialize(for size: Int) {
+      assert(
+        !unowned,
+        "initalize should NOT be called on a buffer that is built by assumingMemoryBound")
+      memset(memory, 0, size)
     }
 
-    /// Fills the buffer with padding by adding to the writersize
-    /// - Parameter padding: Amount of padding between two to be serialized objects
-    @usableFromInline mutating func fill(padding: Int) {
-        assert(padding >= 0, "Fill should be larger than or equal to zero")
-        ensureSpace(size: padding)
-        _writerSize = _writerSize &+ (MemoryLayout<UInt8>.size &* padding)
-    }
-    
-    ///Adds an array of type Scalar to the buffer memory
-    /// - Parameter elements: An array of Scalars
-    @usableFromInline mutating func push<T: Scalar>(elements: [T]) {
-        let size = elements.count &* MemoryLayout<T>.size
-        ensureSpace(size: size)
-        elements.reversed().forEach { (s) in
-            push(value: s, len: MemoryLayout.size(ofValue: s))
-        }
-    }
+    /// Reallocates the buffer incase the object to be written doesnt fit in the current buffer
+    /// - Parameter size: Size of the current object
+    @usableFromInline
+    internal func reallocate(_ size: Int, writerSize: Int, alignment: Int) {
+      let currentWritingIndex = capacity &- writerSize
+      while capacity <= writerSize &+ size {
+        capacity = capacity << 1
+      }
 
-    /// A custom type of structs that are padded according to the flatbuffer padding,
-    /// - Parameters:
-    ///   - value: Pointer to the object in memory
-    ///   - size: Size of Value being written to the buffer
-    @available(*, deprecated, message: "0.9.0 will be removing the following method. Regenerate the code")
-    @usableFromInline mutating func push(struct value: UnsafeMutableRawPointer, size: Int) {
-        ensureSpace(size: size)
-        memcpy(_storage.memory.advanced(by: writerIndex &- size), value, size)
-        defer { value.deallocate() }
-        _writerSize = _writerSize &+ size
-    }
-    
-    /// Prepares the buffer to receive a struct of certian size.
-    /// The alignment of the memory is already handled since we already called preAlign
-    /// - Parameter size: size of the struct
-    @usableFromInline mutating func prepareBufferToReceiveStruct(of size: Int) {
-        ensureSpace(size: size)
-        _writerSize = _writerSize &+ size
-    }
-    
-    /// Reverse the input direction to the buffer, since `FlatBuffers` uses a back to front, following method will take current `writerIndex`
-    /// and writes front to back into the buffer, respecting the padding & the alignment
-    /// - Parameters:
-    ///   - value: value of type Scalar
-    ///   - position: position relative to the `writerIndex`
-    ///   - len: length of the value in terms of bytes
-    @usableFromInline mutating func reversePush<T: Scalar>(value: T, position: Int, len: Int) {
-        var v = value
-        memcpy(_storage.memory.advanced(by: writerIndex &+ position), &v, len)
-    }
+      /// solution take from Apple-NIO
+      capacity = capacity.convertToPowerofTwo
 
-    /// Adds an object of type Scalar into the buffer
-    /// - Parameters:
-    ///   - value: Object  that will be written to the buffer
-    ///   - len: Offset to subtract from the WriterIndex
-    @usableFromInline mutating func push<T: Scalar>(value: T, len: Int) {
-        ensureSpace(size: len)
-        var v = value
-        memcpy(_storage.memory.advanced(by: writerIndex &- len), &v, len)
-        _writerSize = _writerSize &+ len
+      let newData = UnsafeMutableRawPointer.allocate(byteCount: capacity, alignment: alignment)
+      memset(newData, 0, capacity &- writerSize)
+      memcpy(
+        newData.advanced(by: capacity &- writerSize),
+        memory.advanced(by: currentWritingIndex),
+        writerSize)
+      memory.deallocate()
+      memory = newData
     }
+  }
 
-    /// Adds a string to the buffer using swift.utf8 object
-    /// - Parameter str: String that will be added to the buffer
-    /// - Parameter len: length of the string
-    @usableFromInline mutating func push(string str: String, len: Int) {
-        ensureSpace(size: len)
-        if str.utf8.withContiguousStorageIfAvailable({ self.push(bytes: $0, len: len) }) != nil {
-        } else {
-            let utf8View = str.utf8
-            for c in utf8View.reversed() {
-                push(value: c, len: 1)
-            }
-        }
-    }
+  @usableFromInline var _storage: Storage
 
-    /// Writes a string to Bytebuffer using UTF8View
-    /// - Parameters:
-    ///   - bytes: Pointer to the view
-    ///   - len: Size of string
-    @usableFromInline mutating internal func push(bytes: UnsafeBufferPointer<String.UTF8View.Element>, len: Int) -> Bool {
-        memcpy(_storage.memory.advanced(by: writerIndex &- len), UnsafeRawPointer(bytes.baseAddress!), len)
-        _writerSize = _writerSize &+ len
-        return true
-    }
+  /// The size of the elements written to the buffer + their paddings
+  private var _writerSize: Int = 0
+  /// Aliginment of the current  memory being written to the buffer
+  internal var alignment = 1
+  /// Current Index which is being used to write to the buffer, it is written from the end to the start of the buffer
+  internal var writerIndex: Int { _storage.capacity &- _writerSize }
 
-    /// Write stores an object into the buffer directly or indirectly.
-    ///
-    /// Direct: ignores the capacity of buffer which would mean we are referring to the direct point in memory
-    /// indirect: takes into respect the current capacity of the buffer (capacity - index), writing to the buffer from the end
-    /// - Parameters:
-    ///   - value: Value that needs to be written to the buffer
-    ///   - index: index to write to
-    ///   - direct: Should take into consideration the capacity of the buffer
-    func write<T>(value: T, index: Int, direct: Bool = false) {
-        var index = index
-        if !direct {
-            index = _storage.capacity &- index
-        }
-        assert(index < _storage.capacity, "Write index is out of writing bound")
-        assert(index >= 0, "Writer index should be above zero")
-        _storage.memory.storeBytes(of: value, toByteOffset: index, as: T.self)
-    }
+  /// Reader is the position of the current Writer Index (capacity - size)
+  public var reader: Int { writerIndex }
+  /// Current size of the buffer
+  public var size: UOffset { UOffset(_writerSize) }
+  /// Public Pointer to the buffer object in memory. This should NOT be modified for any reason
+  public var memory: UnsafeMutableRawPointer { _storage.memory }
+  /// Current capacity for the buffer
+  public var capacity: Int { _storage.capacity }
 
-    /// Makes sure that buffer has enouch space for each of the objects that will be written into it
-    /// - Parameter size: size of object
-    @discardableResult
-    @usableFromInline mutating func ensureSpace(size: Int) -> Int {
-        if size &+ _writerSize > _storage.capacity {
-            _storage.reallocate(size, writerSize: _writerSize, alignment: alignment)
-        }
-        assert(size < FlatBufferMaxSize, "Buffer can't grow beyond 2 Gigabytes")
-        return size
+  /// Constructor that creates a Flatbuffer object from a UInt8
+  /// - Parameter bytes: Array of UInt8
+  public init(bytes: [UInt8]) {
+    var b = bytes
+    _storage = Storage(count: bytes.count, alignment: alignment)
+    _writerSize = _storage.capacity
+    b.withUnsafeMutableBytes { bufferPointer in
+      self._storage.copy(from: bufferPointer.baseAddress!, count: bytes.count)
     }
-    
-    /// pops the written VTable if it's already written into the buffer
-    /// - Parameter size: size of the `VTable`
-    @usableFromInline mutating internal func pop(_ size: Int) {
-        assert((_writerSize &- size) > 0, "New size should NOT be a negative number")
-        memset(_storage.memory.advanced(by: writerIndex), 0, _writerSize &- size)
-        _writerSize = size
-    }
-    
-    /// Clears the current size of the buffer
-    mutating public func clearSize() {
-        _writerSize = 0
-    }
+  }
 
-    /// Clears the current instance of the buffer, replacing it with new memory
-    mutating public func clear() {
-        _writerSize = 0
-        alignment = 1
-        _storage.initialize(for: _storage.capacity)
+  /// Constructor that creates a Flatbuffer from the Swift Data type object
+  /// - Parameter data: Swift data Object
+  public init(data: Data) {
+    var b = data
+    _storage = Storage(count: data.count, alignment: alignment)
+    _writerSize = _storage.capacity
+    b.withUnsafeMutableBytes { bufferPointer in
+      self._storage.copy(from: bufferPointer.baseAddress!, count: data.count)
     }
-    
-    /// Reads an object from the buffer
-    /// - Parameters:
-    ///   - def: Type of the object
-    ///   - position: the index of the object in the buffer
-    public func read<T>(def: T.Type, position: Int) -> T {
-        assert(position + MemoryLayout<T>.size <= _storage.capacity, "Reading out of bounds is illegal")
-        return _storage.memory.advanced(by: position).load(as: T.self)
-    }
+  }
 
-    /// Reads a slice from the memory assuming a type of T
-    /// - Parameters:
-    ///   - index: index of the object to be read from the buffer
-    ///   - count: count of bytes in memory
-    public func readSlice<T>(index: Int32,
-                             count: Int32) -> [T] {
-        let _index = Int(index)
-        let _count = Int(count)
-        assert(_index + _count <= _storage.capacity, "Reading out of bounds is illegal")
-        let start = _storage.memory.advanced(by: _index).assumingMemoryBound(to: T.self)
-        let array = UnsafeBufferPointer(start: start, count: _count)
-        return Array(array)
-    }
+  /// Constructor that creates a Flatbuffer instance with a size
+  /// - Parameter size: Length of the buffer
+  init(initialSize size: Int) {
+    let size = size.convertToPowerofTwo
+    _storage = Storage(count: size, alignment: alignment)
+    _storage.initialize(for: size)
+  }
 
-    /// Reads a string from the buffer and encodes it to a swift string
-    /// - Parameters:
-    ///   - index: index of the string in the buffer
-    ///   - count: length of the string
-    ///   - type: Encoding of the string
-    public func readString(at index: Int32,
-                           count: Int32,
-                           type: String.Encoding = .utf8) -> String? {
-        let _index = Int(index)
-        let _count = Int(count)
-        assert(_index + _count <= _storage.capacity, "Reading out of bounds is illegal")
-        let start = _storage.memory.advanced(by: _index).assumingMemoryBound(to: UInt8.self)
-        let bufprt = UnsafeBufferPointer(start: start, count: _count)
-        return String(bytes: Array(bufprt), encoding: type)
+  #if swift(>=5.0)
+  /// Constructor that creates a Flatbuffer object from a ContiguousBytes
+  /// - Parameters:
+  ///   - contiguousBytes: Binary stripe to use as the buffer
+  ///   - count: amount of readable bytes
+  public init<Bytes: ContiguousBytes>(
+    contiguousBytes: Bytes,
+    count: Int)
+  {
+    _storage = Storage(count: count, alignment: alignment)
+    _writerSize = _storage.capacity
+    contiguousBytes.withUnsafeBytes { buf in
+      _storage.copy(from: buf.baseAddress!, count: buf.count)
     }
+  }
+  #endif
 
-    /// Creates a new Flatbuffer object that's duplicated from the current one
-    /// - Parameter removeBytes: the amount of bytes to remove from the current Size
-    public func duplicate(removing removeBytes: Int = 0) -> ByteBuffer {
-        assert(removeBytes > 0, "Can NOT remove negative bytes")
-        assert(removeBytes < _storage.capacity, "Can NOT remove more bytes than the ones allocated")
-        return ByteBuffer(memory: _storage.memory, count: _storage.capacity, removing: _writerSize &- removeBytes)
+  /// Constructor that creates a Flatbuffer from unsafe memory region without copying
+  /// - Parameter assumingMemoryBound: The unsafe memory region
+  /// - Parameter capacity: The size of the given memory region
+  public init(assumingMemoryBound memory: UnsafeMutableRawPointer, capacity: Int) {
+    _storage = Storage(memory: memory, capacity: capacity, unowned: true)
+    _writerSize = capacity
+  }
+
+  /// Creates a copy of the buffer that's being built by calling sizedBuffer
+  /// - Parameters:
+  ///   - memory: Current memory of the buffer
+  ///   - count: count of bytes
+  internal init(memory: UnsafeMutableRawPointer, count: Int) {
+    _storage = Storage(count: count, alignment: alignment)
+    _storage.copy(from: memory, count: count)
+    _writerSize = _storage.capacity
+  }
+
+  /// Creates a copy of the existing flatbuffer, by copying it to a different memory.
+  /// - Parameters:
+  ///   - memory: Current memory of the buffer
+  ///   - count: count of bytes
+  ///   - removeBytes: Removes a number of bytes from the current size
+  internal init(memory: UnsafeMutableRawPointer, count: Int, removing removeBytes: Int) {
+    _storage = Storage(count: count, alignment: alignment)
+    _storage.copy(from: memory, count: count)
+    _writerSize = removeBytes
+  }
+
+  /// Fills the buffer with padding by adding to the writersize
+  /// - Parameter padding: Amount of padding between two to be serialized objects
+  @usableFromInline
+  mutating func fill(padding: Int) {
+    assert(padding >= 0, "Fill should be larger than or equal to zero")
+    ensureSpace(size: padding)
+    _writerSize = _writerSize &+ (MemoryLayout<UInt8>.size &* padding)
+  }
+
+  ///Adds an array of type Scalar to the buffer memory
+  /// - Parameter elements: An array of Scalars
+  @usableFromInline
+  mutating func push<T: Scalar>(elements: [T]) {
+    let size = elements.count &* MemoryLayout<T>.size
+    ensureSpace(size: size)
+    elements.reversed().forEach { s in
+      push(value: s, len: MemoryLayout.size(ofValue: s))
     }
+  }
+
+  /// A custom type of structs that are padded according to the flatbuffer padding,
+  /// - Parameters:
+  ///   - value: Pointer to the object in memory
+  ///   - size: Size of Value being written to the buffer
+  @available(
+    *,
+    deprecated,
+    message: "0.9.0 will be removing the following method. Regenerate the code")
+  @usableFromInline
+  mutating func push(struct value: UnsafeMutableRawPointer, size: Int) {
+    ensureSpace(size: size)
+    memcpy(_storage.memory.advanced(by: writerIndex &- size), value, size)
+    defer { value.deallocate() }
+    _writerSize = _writerSize &+ size
+  }
+
+  /// Prepares the buffer to receive a struct of certian size.
+  /// The alignment of the memory is already handled since we already called preAlign
+  /// - Parameter size: size of the struct
+  @usableFromInline
+  mutating func prepareBufferToReceiveStruct(of size: Int) {
+    ensureSpace(size: size)
+    _writerSize = _writerSize &+ size
+  }
+
+  /// Reverse the input direction to the buffer, since `FlatBuffers` uses a back to front, following method will take current `writerIndex`
+  /// and writes front to back into the buffer, respecting the padding & the alignment
+  /// - Parameters:
+  ///   - value: value of type Scalar
+  ///   - position: position relative to the `writerIndex`
+  ///   - len: length of the value in terms of bytes
+  @usableFromInline
+  mutating func reversePush<T: Scalar>(value: T, position: Int, len: Int) {
+    var v = value
+    memcpy(_storage.memory.advanced(by: writerIndex &+ position), &v, len)
+  }
+
+  /// Adds an object of type Scalar into the buffer
+  /// - Parameters:
+  ///   - value: Object  that will be written to the buffer
+  ///   - len: Offset to subtract from the WriterIndex
+  @usableFromInline
+  mutating func push<T: Scalar>(value: T, len: Int) {
+    ensureSpace(size: len)
+    var v = value
+    memcpy(_storage.memory.advanced(by: writerIndex &- len), &v, len)
+    _writerSize = _writerSize &+ len
+  }
+
+  /// Adds a string to the buffer using swift.utf8 object
+  /// - Parameter str: String that will be added to the buffer
+  /// - Parameter len: length of the string
+  @usableFromInline
+  mutating func push(string str: String, len: Int) {
+    ensureSpace(size: len)
+    if str.utf8.withContiguousStorageIfAvailable({ self.push(bytes: $0, len: len) }) != nil {
+    } else {
+      let utf8View = str.utf8
+      for c in utf8View.reversed() {
+        push(value: c, len: 1)
+      }
+    }
+  }
+
+  /// Writes a string to Bytebuffer using UTF8View
+  /// - Parameters:
+  ///   - bytes: Pointer to the view
+  ///   - len: Size of string
+  @usableFromInline
+  mutating internal func push(
+    bytes: UnsafeBufferPointer<String.UTF8View.Element>,
+    len: Int) -> Bool
+  {
+    memcpy(
+      _storage.memory.advanced(by: writerIndex &- len),
+      UnsafeRawPointer(bytes.baseAddress!),
+      len)
+    _writerSize = _writerSize &+ len
+    return true
+  }
+
+  /// Write stores an object into the buffer directly or indirectly.
+  ///
+  /// Direct: ignores the capacity of buffer which would mean we are referring to the direct point in memory
+  /// indirect: takes into respect the current capacity of the buffer (capacity - index), writing to the buffer from the end
+  /// - Parameters:
+  ///   - value: Value that needs to be written to the buffer
+  ///   - index: index to write to
+  ///   - direct: Should take into consideration the capacity of the buffer
+  func write<T>(value: T, index: Int, direct: Bool = false) {
+    var index = index
+    if !direct {
+      index = _storage.capacity &- index
+    }
+    assert(index < _storage.capacity, "Write index is out of writing bound")
+    assert(index >= 0, "Writer index should be above zero")
+    _storage.memory.storeBytes(of: value, toByteOffset: index, as: T.self)
+  }
+
+  /// Makes sure that buffer has enouch space for each of the objects that will be written into it
+  /// - Parameter size: size of object
+  @discardableResult
+  @usableFromInline
+  mutating func ensureSpace(size: Int) -> Int {
+    if size &+ _writerSize > _storage.capacity {
+      _storage.reallocate(size, writerSize: _writerSize, alignment: alignment)
+    }
+    assert(size < FlatBufferMaxSize, "Buffer can't grow beyond 2 Gigabytes")
+    return size
+  }
+
+  /// pops the written VTable if it's already written into the buffer
+  /// - Parameter size: size of the `VTable`
+  @usableFromInline
+  mutating internal func pop(_ size: Int) {
+    assert((_writerSize &- size) > 0, "New size should NOT be a negative number")
+    memset(_storage.memory.advanced(by: writerIndex), 0, _writerSize &- size)
+    _writerSize = size
+  }
+
+  /// Clears the current size of the buffer
+  mutating public func clearSize() {
+    _writerSize = 0
+  }
+
+  /// Clears the current instance of the buffer, replacing it with new memory
+  mutating public func clear() {
+    _writerSize = 0
+    alignment = 1
+    _storage.initialize(for: _storage.capacity)
+  }
+
+  /// Reads an object from the buffer
+  /// - Parameters:
+  ///   - def: Type of the object
+  ///   - position: the index of the object in the buffer
+  public func read<T>(def: T.Type, position: Int) -> T {
+    assert(
+      position + MemoryLayout<T>.size <= _storage.capacity,
+      "Reading out of bounds is illegal")
+    return _storage.memory.advanced(by: position).load(as: T.self)
+  }
+
+  /// Reads a slice from the memory assuming a type of T
+  /// - Parameters:
+  ///   - index: index of the object to be read from the buffer
+  ///   - count: count of bytes in memory
+  public func readSlice<T>(
+    index: Int32,
+    count: Int32) -> [T]
+  {
+    let _index = Int(index)
+    let _count = Int(count)
+    assert(_index + _count <= _storage.capacity, "Reading out of bounds is illegal")
+    let start = _storage.memory.advanced(by: _index).assumingMemoryBound(to: T.self)
+    let array = UnsafeBufferPointer(start: start, count: _count)
+    return Array(array)
+  }
+
+  /// Reads a string from the buffer and encodes it to a swift string
+  /// - Parameters:
+  ///   - index: index of the string in the buffer
+  ///   - count: length of the string
+  ///   - type: Encoding of the string
+  public func readString(
+    at index: Int32,
+    count: Int32,
+    type: String.Encoding = .utf8) -> String?
+  {
+    let _index = Int(index)
+    let _count = Int(count)
+    assert(_index + _count <= _storage.capacity, "Reading out of bounds is illegal")
+    let start = _storage.memory.advanced(by: _index).assumingMemoryBound(to: UInt8.self)
+    let bufprt = UnsafeBufferPointer(start: start, count: _count)
+    return String(bytes: Array(bufprt), encoding: type)
+  }
+
+  /// Creates a new Flatbuffer object that's duplicated from the current one
+  /// - Parameter removeBytes: the amount of bytes to remove from the current Size
+  public func duplicate(removing removeBytes: Int = 0) -> ByteBuffer {
+    assert(removeBytes > 0, "Can NOT remove negative bytes")
+    assert(removeBytes < _storage.capacity, "Can NOT remove more bytes than the ones allocated")
+    return ByteBuffer(
+      memory: _storage.memory,
+      count: _storage.capacity,
+      removing: _writerSize &- removeBytes)
+  }
 }
 
 extension ByteBuffer: CustomDebugStringConvertible {
 
-    public var debugDescription: String {
-        """
-        buffer located at: \(_storage.memory), with capacity of \(_storage.capacity)
-        { writerSize: \(_writerSize), readerSize: \(reader), writerIndex: \(writerIndex) }
-        """
-    }
+  public var debugDescription: String {
+    """
+    buffer located at: \(_storage.memory), with capacity of \(_storage.capacity)
+    { writerSize: \(_writerSize), readerSize: \(reader), writerIndex: \(writerIndex) }
+    """
+  }
 }
diff --git a/swift/Sources/FlatBuffers/Constants.swift b/swift/Sources/FlatBuffers/Constants.swift
index 2b55250..ac541d9 100644
--- a/swift/Sources/FlatBuffers/Constants.swift
+++ b/swift/Sources/FlatBuffers/Constants.swift
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 #if os(Linux)
 import CoreFoundation
 #else
@@ -20,77 +36,77 @@
 ///
 /// Scalar is used to confirm all the numbers that can be represented in a FlatBuffer. It's used to write/read from the buffer.
 public protocol Scalar: Equatable {
-    associatedtype NumericValue
-    var convertedEndian: NumericValue { get }
+  associatedtype NumericValue
+  var convertedEndian: NumericValue { get }
 }
 
 extension Scalar where Self: FixedWidthInteger {
-    /// Converts the value from BigEndian to LittleEndian
-    ///
-    /// Converts values to little endian on machines that work with BigEndian, however this is NOT TESTED yet.
-    public var convertedEndian: NumericValue {
-        return self as! Self.NumericValue
-    }
+  /// Converts the value from BigEndian to LittleEndian
+  ///
+  /// Converts values to little endian on machines that work with BigEndian, however this is NOT TESTED yet.
+  public var convertedEndian: NumericValue {
+    self as! Self.NumericValue
+  }
 }
 
 extension Double: Scalar {
-    public typealias NumericValue = UInt64
-    
-    public var convertedEndian: UInt64 {
-        return self.bitPattern.littleEndian
-    }
+  public typealias NumericValue = UInt64
+
+  public var convertedEndian: UInt64 {
+    bitPattern.littleEndian
+  }
 }
 
 extension Float32: Scalar {
-    public typealias NumericValue = UInt32
-    
-    public var convertedEndian: UInt32 {
-        return self.bitPattern.littleEndian
-    }
+  public typealias NumericValue = UInt32
+
+  public var convertedEndian: UInt32 {
+    bitPattern.littleEndian
+  }
 }
 
 extension Bool: Scalar {
-    public var convertedEndian: UInt8 {
-        return self == true ? 1 : 0
-    }
-    
-    public typealias NumericValue = UInt8
+  public var convertedEndian: UInt8 {
+    self == true ? 1 : 0
+  }
+
+  public typealias NumericValue = UInt8
 }
 
 extension Int: Scalar {
-    public typealias NumericValue = Int
+  public typealias NumericValue = Int
 }
 
 extension Int8: Scalar {
-    public typealias NumericValue = Int8
+  public typealias NumericValue = Int8
 }
 
 extension Int16: Scalar {
-    public typealias NumericValue = Int16
+  public typealias NumericValue = Int16
 }
 
 extension Int32: Scalar {
-    public typealias NumericValue = Int32
+  public typealias NumericValue = Int32
 }
 
 extension Int64: Scalar {
-    public typealias NumericValue = Int64
+  public typealias NumericValue = Int64
 }
 
 extension UInt8: Scalar {
-    public typealias NumericValue = UInt8
+  public typealias NumericValue = UInt8
 }
 
 extension UInt16: Scalar {
-    public typealias NumericValue = UInt16
+  public typealias NumericValue = UInt16
 }
 
 extension UInt32: Scalar {
-    public typealias NumericValue = UInt32
+  public typealias NumericValue = UInt32
 }
 
 extension UInt64: Scalar {
-    public typealias NumericValue = UInt64
+  public typealias NumericValue = UInt64
 }
 
 public func FlatBuffersVersion_1_12_0() {}
diff --git a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift
index cfdb20c..71fcab0 100644
--- a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift
+++ b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift
@@ -1,602 +1,645 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import Foundation
 
 public struct FlatBufferBuilder {
-    
-    /// Storage for the Vtables used in the buffer are stored in here, so they would be written later in EndTable
-    @usableFromInline internal var _vtableStorage = VTableStorage()
-    
-    /// Reference Vtables that were already written to the buffer
-    private var _vtables: [UOffset] = []
-    /// Flatbuffer data will be written into
-    private var _bb: ByteBuffer
-    /// A check if the buffer is being written into by a different table
-    private var isNested = false
-    /// Dictonary that stores a map of all the strings that were written to the buffer
-    private var stringOffsetMap: [String: Offset<String>] = [:]
-    /// A check to see if finish(::) was ever called to retreive data object
-    private var finished = false
-    /// A check to see if the buffer should serialize Default values
-    private var serializeDefaults: Bool
-    
-    /// Current alignment for the buffer
-    var _minAlignment: Int = 0 {
-        didSet {
-            _bb.alignment = _minAlignment
-        }
+
+  /// Storage for the Vtables used in the buffer are stored in here, so they would be written later in EndTable
+  @usableFromInline internal var _vtableStorage = VTableStorage()
+
+  /// Reference Vtables that were already written to the buffer
+  private var _vtables: [UOffset] = []
+  /// Flatbuffer data will be written into
+  private var _bb: ByteBuffer
+  /// A check if the buffer is being written into by a different table
+  private var isNested = false
+  /// Dictonary that stores a map of all the strings that were written to the buffer
+  private var stringOffsetMap: [String: Offset<String>] = [:]
+  /// A check to see if finish(::) was ever called to retreive data object
+  private var finished = false
+  /// A check to see if the buffer should serialize Default values
+  private var serializeDefaults: Bool
+
+  /// Current alignment for the buffer
+  var _minAlignment: Int = 0 {
+    didSet {
+      _bb.alignment = _minAlignment
     }
-    
-    /// Gives a read access to the buffer's size
-    public var size: UOffset { return _bb.size }
-    /// Data representation of the buffer
-    public var data: Data {
-        assert(finished, "Data shouldn't be called before finish()")
-        return Data(bytes: _bb.memory.advanced(by: _bb.writerIndex),
-                    count: _bb.capacity &- _bb.writerIndex)
+  }
+
+  /// Gives a read access to the buffer's size
+  public var size: UOffset { _bb.size }
+  /// Data representation of the buffer
+  public var data: Data {
+    assert(finished, "Data shouldn't be called before finish()")
+    return Data(
+      bytes: _bb.memory.advanced(by: _bb.writerIndex),
+      count: _bb.capacity &- _bb.writerIndex)
+  }
+  /// Get's the fully sized buffer stored in memory
+  public var fullSizedByteArray: [UInt8] {
+    let ptr = UnsafeBufferPointer(
+      start: _bb.memory.assumingMemoryBound(to: UInt8.self),
+      count: _bb.capacity)
+    return Array(ptr)
+  }
+  /// Returns the written size of the buffer
+  public var sizedByteArray: [UInt8] {
+    assert(finished, "Data shouldn't be called before finish()")
+    let cp = _bb.capacity &- _bb.writerIndex
+    let start = _bb.memory.advanced(by: _bb.writerIndex)
+      .bindMemory(to: UInt8.self, capacity: cp)
+
+    let ptr = UnsafeBufferPointer(start: start, count: cp)
+    return Array(ptr)
+  }
+  /// Returns the buffer
+  public var buffer: ByteBuffer { _bb }
+
+  /// Returns A sized Buffer from the readable bytes
+  public var sizedBuffer: ByteBuffer {
+    assert(finished, "Data shouldn't be called before finish()")
+    return ByteBuffer(memory: _bb.memory.advanced(by: _bb.reader), count: Int(_bb.size))
+  }
+
+  // MARK: - Init
+
+  /// initialize the buffer with a size
+  /// - Parameters:
+  ///   - initialSize: Initial size for the buffer
+  ///   - force: Allows default to be serialized into the buffer
+  public init(initialSize: Int32 = 1024, serializeDefaults force: Bool = false) {
+    assert(initialSize > 0, "Size should be greater than zero!")
+    guard isLitteEndian else {
+      fatalError("Reading/Writing a buffer in big endian machine is not supported on swift")
     }
-    /// Get's the fully sized buffer stored in memory
-    public var fullSizedByteArray: [UInt8] {
-        let ptr = UnsafeBufferPointer(start: _bb.memory.assumingMemoryBound(to: UInt8.self),
-                                      count: _bb.capacity)
-        return Array(ptr)
+    serializeDefaults = force
+    _bb = ByteBuffer(initialSize: Int(initialSize))
+  }
+
+  /// Clears the buffer and the builder from it's data
+  mutating public func clear() {
+    _minAlignment = 0
+    isNested = false
+    stringOffsetMap = [:]
+    _vtables = []
+    _vtableStorage.clear()
+    _bb.clear()
+  }
+
+  // MARK: - Create Tables
+
+  /// Checks if the required fields were serialized into the buffer
+  /// - Parameters:
+  ///   - table: offset for the table
+  ///   - fields: Array of all the important fields to be serialized
+  mutating public func require(table: Offset<UOffset>, fields: [Int32]) {
+    for field in fields {
+      let start = _bb.capacity &- Int(table.o)
+      let startTable = start &- Int(_bb.read(def: Int32.self, position: start))
+      let isOkay = _bb.read(def: VOffset.self, position: startTable &+ Int(field)) != 0
+      assert(isOkay, "Flatbuffers requires the following field")
     }
-    /// Returns the written size of the buffer
-    public var sizedByteArray: [UInt8] {
-        assert(finished, "Data shouldn't be called before finish()")
-        let cp = _bb.capacity &- _bb.writerIndex
-        let start = _bb.memory.advanced(by: _bb.writerIndex)
-            .bindMemory(to: UInt8.self, capacity: cp)
-        
-        let ptr = UnsafeBufferPointer(start: start, count: cp)
-        return Array(ptr)
-    }
-    /// Returns the buffer
-    public var buffer: ByteBuffer { return _bb }
-    
-    /// Returns A sized Buffer from the readable bytes
-    public var sizedBuffer: ByteBuffer {
-        assert(finished, "Data shouldn't be called before finish()")
-        return ByteBuffer(memory: _bb.memory.advanced(by: _bb.reader), count: Int(_bb.size))
-    }
-    
-    // MARK: - Init
-    
-    /// initialize the buffer with a size
-    /// - Parameters:
-    ///   - initialSize: Initial size for the buffer
-    ///   - force: Allows default to be serialized into the buffer
-    public init(initialSize: Int32 = 1024, serializeDefaults force: Bool = false) {
-        assert(initialSize > 0, "Size should be greater than zero!")
-        guard isLitteEndian else {
-            fatalError("Reading/Writing a buffer in big endian machine is not supported on swift")
-        }
-        serializeDefaults = force
-        _bb = ByteBuffer(initialSize: Int(initialSize))
-    }
-    
-    /// Clears the buffer and the builder from it's data
-    mutating public func clear() {
-        _minAlignment = 0
-        isNested = false
-        stringOffsetMap = [:]
-        _vtables = []
-        _vtableStorage.clear()
-        _bb.clear()
+  }
+
+  /// Finished the buffer by adding the file id and then calling finish
+  /// - Parameters:
+  ///   - offset: Offset of the table
+  ///   - fileId: Takes the fileId
+  ///   - prefix: if false it wont add the size of the buffer
+  mutating public func finish<T>(offset: Offset<T>, fileId: String, addPrefix prefix: Bool = false) {
+    let size = MemoryLayout<UOffset>.size
+    preAlign(len: size &+ (prefix ? size : 0) &+ FileIdLength, alignment: _minAlignment)
+    assert(fileId.count == FileIdLength, "Flatbuffers requires file id to be 4")
+    _bb.push(string: fileId, len: 4)
+    finish(offset: offset, addPrefix: prefix)
+  }
+
+  /// Finished the buffer by adding the file id, offset, and prefix to it.
+  /// - Parameters:
+  ///   - offset: Offset of the table
+  ///   - prefix: if false it wont add the size of the buffer
+  mutating public func finish<T>(offset: Offset<T>, addPrefix prefix: Bool = false) {
+    notNested()
+    let size = MemoryLayout<UOffset>.size
+    preAlign(len: size &+ (prefix ? size : 0), alignment: _minAlignment)
+    push(element: refer(to: offset.o))
+    if prefix { push(element: _bb.size) }
+    _vtableStorage.clear()
+    finished = true
+  }
+
+  /// starttable will let the builder know, that a new object is being serialized.
+  ///
+  /// The function will fatalerror if called while there is another object being serialized
+  /// - Parameter numOfFields: Number of elements to be written to the buffer
+  mutating public func startTable(with numOfFields: Int) -> UOffset {
+    notNested()
+    isNested = true
+    _vtableStorage.start(count: numOfFields)
+    return _bb.size
+  }
+
+  /// Endtable will let the builder know that the object that's written to it is completed
+  ///
+  /// This would be called after all the elements are serialized, it will add the vtable into the buffer.
+  /// it will fatalError in case the object is called without starttable, or the object has exceeded  the limit of
+  ///  2GB,
+  /// - Parameter startOffset:Start point of the object written
+  /// - returns: The root of the table
+  mutating public func endTable(at startOffset: UOffset)  -> UOffset {
+    assert(isNested, "Calling endtable without calling starttable")
+    let sizeofVoffset = MemoryLayout<VOffset>.size
+    let vTableOffset = push(element: SOffset(0))
+
+    let tableObjectSize = vTableOffset &- startOffset
+    assert(tableObjectSize < 0x10000, "Buffer can't grow beyond 2 Gigabytes")
+    let _max = Int(_vtableStorage.maxOffset) &+ sizeofVoffset
+
+    _bb.fill(padding: _max)
+    _bb.write(
+      value: VOffset(tableObjectSize),
+      index: _bb.writerIndex &+ sizeofVoffset,
+      direct: true)
+    _bb.write(value: VOffset(_max), index: _bb.writerIndex, direct: true)
+
+    var itr = 0
+    while itr < _vtableStorage.writtenIndex {
+      let loaded = _vtableStorage.load(at: itr)
+      itr = itr &+ _vtableStorage.size
+      guard loaded.offset != 0 else { continue }
+      let _index = (_bb.writerIndex &+ Int(loaded.position))
+      _bb.write(value: VOffset(vTableOffset &- loaded.offset), index: _index, direct: true)
     }
 
-    // MARK: - Create Tables
-    
-    /// Checks if the required fields were serialized into the buffer
-    /// - Parameters:
-    ///   - table: offset for the table
-    ///   - fields: Array of all the important fields to be serialized
-    mutating public func require(table: Offset<UOffset>, fields: [Int32]) {
-        for field in fields {
-            let start = _bb.capacity &- Int(table.o)
-            let startTable = start &- Int(_bb.read(def: Int32.self, position: start))
-            let isOkay = _bb.read(def: VOffset.self, position: startTable &+ Int(field)) != 0
-            assert(isOkay, "Flatbuffers requires the following field")
-        }
-    }
-    
-    /// Finished the buffer by adding the file id and then calling finish
-    /// - Parameters:
-    ///   - offset: Offset of the table
-    ///   - fileId: Takes the fileId
-    ///   - prefix: if false it wont add the size of the buffer
-    mutating public func finish<T>(offset: Offset<T>, fileId: String, addPrefix prefix: Bool = false) {
-        let size = MemoryLayout<UOffset>.size
-        preAlign(len: size &+ (prefix ? size : 0) &+ FileIdLength, alignment: _minAlignment)
-        assert(fileId.count == FileIdLength, "Flatbuffers requires file id to be 4")
-        _bb.push(string: fileId, len: 4)
-        finish(offset: offset, addPrefix: prefix)
-    }
-    
-    /// Finished the buffer by adding the file id, offset, and prefix to it.
-    /// - Parameters:
-    ///   - offset: Offset of the table
-    ///   - prefix: if false it wont add the size of the buffer
-    mutating public func finish<T>(offset: Offset<T>, addPrefix prefix: Bool = false) {
-        notNested()
-        let size = MemoryLayout<UOffset>.size
-        preAlign(len: size &+ (prefix ? size : 0), alignment: _minAlignment)
-        push(element: refer(to: offset.o))
-        if prefix { push(element: _bb.size) }
-        _vtableStorage.clear()
-        finished = true
-    }
-    
-    /// starttable will let the builder know, that a new object is being serialized.
-    ///
-    /// The function will fatalerror if called while there is another object being serialized
-    /// - Parameter numOfFields: Number of elements to be written to the buffer
-    mutating public func startTable(with numOfFields: Int) -> UOffset {
-        notNested()
-        isNested = true
-        _vtableStorage.start(count: numOfFields)
-        return _bb.size
-    }
-    
-    /// Endtable will let the builder know that the object that's written to it is completed
-    ///
-    /// This would be called after all the elements are serialized, it will add the vtable into the buffer.
-    /// it will fatalError in case the object is called without starttable, or the object has exceeded  the limit of
-    ///  2GB,
-    /// - Parameter startOffset:Start point of the object written
-    /// - returns: The root of the table
-    mutating public func endTable(at startOffset: UOffset)  -> UOffset {
-        assert(isNested, "Calling endtable without calling starttable")
-        let sizeofVoffset = MemoryLayout<VOffset>.size
-        let vTableOffset = push(element: SOffset(0))
-        
-        let tableObjectSize = vTableOffset &- startOffset
-        assert(tableObjectSize < 0x10000, "Buffer can't grow beyond 2 Gigabytes")
-        let _max = Int(_vtableStorage.maxOffset) &+ sizeofVoffset
-        
-        _bb.fill(padding: _max)
-        _bb.write(value: VOffset(tableObjectSize), index: _bb.writerIndex &+ sizeofVoffset, direct: true)
-        _bb.write(value: VOffset(_max), index: _bb.writerIndex, direct: true)
-        
-        var itr = 0
-        while itr < _vtableStorage.writtenIndex {
-            let loaded = _vtableStorage.load(at: itr)
-            itr = itr &+ _vtableStorage.size
-            guard loaded.offset != 0 else { continue }
-            let _index = (_bb.writerIndex &+ Int(loaded.position))
-            _bb.write(value: VOffset(vTableOffset &- loaded.offset), index: _index, direct: true)
-        }
-        
-        _vtableStorage.clear()
-        let vt_use = _bb.size
-        
-        var isAlreadyAdded: Int?
-        
-        let vt2 = _bb.memory.advanced(by: _bb.writerIndex)
-        let len2 = vt2.load(fromByteOffset: 0, as: Int16.self)
+    _vtableStorage.clear()
+    let vt_use = _bb.size
 
-        for table in _vtables {
-            let position = _bb.capacity &- Int(table)
-            let vt1 = _bb.memory.advanced(by: position)
-            let len1 = _bb.read(def: Int16.self, position: position)
-            if (len2 != len1 || 0 != memcmp(vt1, vt2, Int(len2))) { continue }
-            
-            isAlreadyAdded = Int(table)
-            break
-        }
-        
-        if let offset = isAlreadyAdded {
-            let vTableOff = Int(vTableOffset)
-            let space = _bb.capacity &- vTableOff
-            _bb.write(value: Int32(offset &- vTableOff), index: space, direct: true)
-            _bb.pop(_bb.capacity &- space)
-        } else {
-            _bb.write(value: Int32(vt_use &- vTableOffset), index: Int(vTableOffset))
-            _vtables.append(_bb.size)
-        }
-        isNested = false
-        return vTableOffset
-    }
-    
-    // MARK: - Builds Buffer
-    
-    /// asserts to see if the object is not nested
-    @usableFromInline mutating internal func notNested()  {
-        assert(!isNested, "Object serialization must not be nested")
-    }
-    
-    /// Changes the minimuim alignment of the buffer
-    /// - Parameter size: size of the current alignment
-    @usableFromInline mutating internal func minAlignment(size: Int) {
-        if size > _minAlignment {
-            _minAlignment = size
-        }
-    }
-    
-    /// Gets the padding for the current element
-    /// - Parameters:
-    ///   - bufSize: Current size of the buffer + the offset of the object to be written
-    ///   - elementSize: Element size
-    @usableFromInline mutating internal func padding(bufSize: UInt32, elementSize: UInt32) -> UInt32 {
-        ((~bufSize) &+ 1) & (elementSize - 1)
-    }
-    
-    /// Prealigns the buffer before writting a new object into the buffer
-    /// - Parameters:
-    ///   - len:Length of the object
-    ///   - alignment: Alignment type
-    @usableFromInline mutating internal func preAlign(len: Int, alignment: Int) {
-        minAlignment(size: alignment)
-        _bb.fill(padding: Int(padding(bufSize: _bb.size &+ UOffset(len), elementSize: UOffset(alignment))))
-    }
-    
-    /// Prealigns the buffer before writting a new object into the buffer
-    /// - Parameters:
-    ///   - len: Length of the object
-    ///   - type: Type of the object to be written
-    @usableFromInline mutating internal func preAlign<T: Scalar>(len: Int, type: T.Type) {
-        preAlign(len: len, alignment: MemoryLayout<T>.size)
-    }
-    
-    /// Refers to an object that's written in the buffer
-    /// - Parameter off: the objects index value
-    @usableFromInline mutating internal func refer(to off: UOffset) -> UOffset {
-        let size = MemoryLayout<UOffset>.size
-        preAlign(len: size, alignment: size)
-        return _bb.size &- off &+ UInt32(size)
-    }
-    
-    /// Tracks the elements written into the buffer
-    /// - Parameters:
-    ///   - offset: The offset of the element witten
-    ///   - position: The position of the element
-    @usableFromInline mutating internal func track(offset: UOffset, at position: VOffset) {
-        _vtableStorage.add(loc: FieldLoc(offset: offset, position: position))
+    var isAlreadyAdded: Int?
+
+    let vt2 = _bb.memory.advanced(by: _bb.writerIndex)
+    let len2 = vt2.load(fromByteOffset: 0, as: Int16.self)
+
+    for table in _vtables {
+      let position = _bb.capacity &- Int(table)
+      let vt1 = _bb.memory.advanced(by: position)
+      let len1 = _bb.read(def: Int16.self, position: position)
+      if len2 != len1 || 0 != memcmp(vt1, vt2, Int(len2)) { continue }
+
+      isAlreadyAdded = Int(table)
+      break
     }
 
-    // MARK: - Vectors
-    
-    /// Starts a vector of length and Element size
-    mutating public func startVector(_ len: Int, elementSize: Int) {
-        notNested()
-        isNested = true
-        preAlign(len: len &* elementSize, type: UOffset.self)
-        preAlign(len: len &* elementSize, alignment: elementSize)
+    if let offset = isAlreadyAdded {
+      let vTableOff = Int(vTableOffset)
+      let space = _bb.capacity &- vTableOff
+      _bb.write(value: Int32(offset &- vTableOff), index: space, direct: true)
+      _bb.pop(_bb.capacity &- space)
+    } else {
+      _bb.write(value: Int32(vt_use &- vTableOffset), index: Int(vTableOffset))
+      _vtables.append(_bb.size)
     }
-    
-    /// Ends the vector of at length
-    ///
-    /// The current function will fatalError if startVector is called before serializing the vector
-    /// - Parameter len: Length of the buffer
-    mutating public func endVector(len: Int) -> UOffset {
-        assert(isNested, "Calling endVector without calling startVector")
-        isNested = false
-        return push(element: Int32(len))
-    }
-    
-    /// Creates a vector of type Scalar in the buffer
-    /// - Parameter elements: elements to be written into the buffer
-    /// - returns: Offset of the vector
-    mutating public func createVector<T: Scalar>(_ elements: [T]) -> Offset<UOffset> {
-        return createVector(elements, size: elements.count)
-    }
-    
-    ///  Creates a vector of type Scalar in the buffer
-    /// - Parameter elements: Elements to be written into the buffer
-    /// - Parameter size: Count of elements
-    /// - returns: Offset of the vector
-    mutating public func createVector<T: Scalar>(_ elements: [T], size: Int) -> Offset<UOffset> {
-        let size = size
-        startVector(size, elementSize: MemoryLayout<T>.size)
-        _bb.push(elements: elements)
-        return Offset(offset: endVector(len: size))
-    }
-    
-    /// Creates a vector of type Enums in the buffer
-    /// - Parameter elements: elements to be written into the buffer
-    /// - returns: Offset of the vector
-    mutating public func createVector<T: Enum>(_ elements: [T]) -> Offset<UOffset> {
-        return createVector(elements, size: elements.count)
-    }
-    
-    ///  Creates a vector of type Enums in the buffer
-    /// - Parameter elements: Elements to be written into the buffer
-    /// - Parameter size: Count of elements
-    /// - returns: Offset of the vector
-    mutating public func createVector<T: Enum>(_ elements: [T], size: Int) -> Offset<UOffset> {
-        let size = size
-        startVector(size, elementSize: T.byteSize)
-        for e in elements.reversed() {
-            _bb.push(value: e.value, len: T.byteSize)
-        }
-        return Offset(offset: endVector(len: size))
-    }
-    
-    /// Creates a vector of type Offsets  in the buffer
-    /// - Parameter offsets:Array of offsets of type T
-    /// - returns: Offset of the vector
-    mutating public func createVector<T>(ofOffsets offsets: [Offset<T>]) -> Offset<UOffset> {
-        createVector(ofOffsets: offsets, len: offsets.count)
-    }
-    
-    ///  Creates a vector of type Offsets  in the buffer
-    /// - Parameter elements: Array of offsets of type T
-    /// - Parameter size: Count of elements
-    /// - returns: Offset of the vector
-    mutating public func createVector<T>(ofOffsets offsets: [Offset<T>], len: Int) -> Offset<UOffset> {
-        startVector(len, elementSize: MemoryLayout<Offset<T>>.size)
-        for o in offsets.reversed() {
-            push(element: o)
-        }
-        return Offset(offset: endVector(len: len))
-    }
-    
-    /// Creates a vector of Strings
-    /// - Parameter str: a vector of strings that will be written into the buffer
-    /// - returns: Offset of the vector
-    mutating public func createVector(ofStrings str: [String]) -> Offset<UOffset> {
-        var offsets: [Offset<String>] = []
-        for s in str {
-            offsets.append(create(string: s))
-        }
-        return createVector(ofOffsets: offsets)
-    }
-    
-    /// Creates a vector of Flatbuffer structs.
-    ///
-    /// The function takes a Type to know what size it is, and alignment
-    /// - Parameters:
-    ///   - structs: An array of UnsafeMutableRawPointer
-    ///   - type: Type of the struct being written
-    /// - returns: Offset of the vector
-    @available(*, deprecated, message: "0.9.0 will be removing the following method. Regenerate the code")
-    mutating public func createVector<T: Readable>(structs: [UnsafeMutableRawPointer],
-                                          type: T.Type) -> Offset<UOffset> {
-        startVector(structs.count &* T.size, elementSize: T.alignment)
-        for i in structs.reversed() {
-            create(struct: i, type: T.self)
-        }
-        return Offset(offset: endVector(len: structs.count))
-    }
-    
-    /// Starts a vector of struct that considers the size and alignment of the struct
-    /// - Parameters:
-    ///   - count: number of elements to be written
-    ///   - size: size of struct
-    ///   - alignment: alignment of the struct
-    mutating public func startVectorOfStructs(count: Int, size: Int, alignment: Int) {
-        startVector(count &* size, elementSize: alignment)
-    }
-    
-    /// Ends the vector of structs and writtens the current offset
-    /// - Parameter count: number of written elements
-    /// - Returns: Offset of type UOffset
-    mutating public func endVectorOfStructs(count: Int) -> Offset<UOffset> {
-        return Offset<UOffset>(offset: endVector(len: count))
-    }
+    isNested = false
+    return vTableOffset
+  }
 
-    // MARK: - Inserting Structs
-    
-    /// Writes a Flatbuffer struct into the buffer
-    /// - Parameters:
-    ///   - s: Flatbuffer struct
-    ///   - type: Type of the element to be serialized
-    /// - returns: Offset of the Object
-    @available(*, deprecated, message: "0.9.0 will be removing the following method. Regenerate the code")
-    @discardableResult
-    mutating public func create<T: Readable>(struct s: UnsafeMutableRawPointer,
-                                    type: T.Type) -> Offset<UOffset> {
-        let size = T.size
-        preAlign(len: size, alignment: T.alignment)
-        _bb.push(struct: s, size: size)
-        return Offset(offset: _bb.size)
+  // MARK: - Builds Buffer
+
+  /// asserts to see if the object is not nested
+  @usableFromInline
+  mutating internal func notNested()  {
+    assert(!isNested, "Object serialization must not be nested")
+  }
+
+  /// Changes the minimuim alignment of the buffer
+  /// - Parameter size: size of the current alignment
+  @usableFromInline
+  mutating internal func minAlignment(size: Int) {
+    if size > _minAlignment {
+      _minAlignment = size
     }
-    
-    /// prepares the ByteBuffer to receive a struct of size and alignment
-    /// - Parameters:
-    ///   - size: size of written struct
-    ///   - alignment: alignment of written struct
-    mutating public func createStructOf(size: Int, alignment: Int) {
-        preAlign(len: size, alignment: alignment)
-        _bb.prepareBufferToReceiveStruct(of: size)
+  }
+
+  /// Gets the padding for the current element
+  /// - Parameters:
+  ///   - bufSize: Current size of the buffer + the offset of the object to be written
+  ///   - elementSize: Element size
+  @usableFromInline
+  mutating internal func padding(bufSize: UInt32, elementSize: UInt32) -> UInt32 {
+    ((~bufSize) &+ 1) & (elementSize - 1)
+  }
+
+  /// Prealigns the buffer before writting a new object into the buffer
+  /// - Parameters:
+  ///   - len:Length of the object
+  ///   - alignment: Alignment type
+  @usableFromInline
+  mutating internal func preAlign(len: Int, alignment: Int) {
+    minAlignment(size: alignment)
+    _bb.fill(padding: Int(padding(
+      bufSize: _bb.size &+ UOffset(len),
+      elementSize: UOffset(alignment))))
+  }
+
+  /// Prealigns the buffer before writting a new object into the buffer
+  /// - Parameters:
+  ///   - len: Length of the object
+  ///   - type: Type of the object to be written
+  @usableFromInline
+  mutating internal func preAlign<T: Scalar>(len: Int, type: T.Type) {
+    preAlign(len: len, alignment: MemoryLayout<T>.size)
+  }
+
+  /// Refers to an object that's written in the buffer
+  /// - Parameter off: the objects index value
+  @usableFromInline
+  mutating internal func refer(to off: UOffset) -> UOffset {
+    let size = MemoryLayout<UOffset>.size
+    preAlign(len: size, alignment: size)
+    return _bb.size &- off &+ UInt32(size)
+  }
+
+  /// Tracks the elements written into the buffer
+  /// - Parameters:
+  ///   - offset: The offset of the element witten
+  ///   - position: The position of the element
+  @usableFromInline
+  mutating internal func track(offset: UOffset, at position: VOffset) {
+    _vtableStorage.add(loc: FieldLoc(offset: offset, position: position))
+  }
+
+  // MARK: - Vectors
+
+  /// Starts a vector of length and Element size
+  mutating public func startVector(_ len: Int, elementSize: Int) {
+    notNested()
+    isNested = true
+    preAlign(len: len &* elementSize, type: UOffset.self)
+    preAlign(len: len &* elementSize, alignment: elementSize)
+  }
+
+  /// Ends the vector of at length
+  ///
+  /// The current function will fatalError if startVector is called before serializing the vector
+  /// - Parameter len: Length of the buffer
+  mutating public func endVector(len: Int) -> UOffset {
+    assert(isNested, "Calling endVector without calling startVector")
+    isNested = false
+    return push(element: Int32(len))
+  }
+
+  /// Creates a vector of type Scalar in the buffer
+  /// - Parameter elements: elements to be written into the buffer
+  /// - returns: Offset of the vector
+  mutating public func createVector<T: Scalar>(_ elements: [T]) -> Offset<UOffset> {
+    createVector(elements, size: elements.count)
+  }
+
+  ///  Creates a vector of type Scalar in the buffer
+  /// - Parameter elements: Elements to be written into the buffer
+  /// - Parameter size: Count of elements
+  /// - returns: Offset of the vector
+  mutating public func createVector<T: Scalar>(_ elements: [T], size: Int) -> Offset<UOffset> {
+    let size = size
+    startVector(size, elementSize: MemoryLayout<T>.size)
+    _bb.push(elements: elements)
+    return Offset(offset: endVector(len: size))
+  }
+
+  /// Creates a vector of type Enums in the buffer
+  /// - Parameter elements: elements to be written into the buffer
+  /// - returns: Offset of the vector
+  mutating public func createVector<T: Enum>(_ elements: [T]) -> Offset<UOffset> {
+    createVector(elements, size: elements.count)
+  }
+
+  ///  Creates a vector of type Enums in the buffer
+  /// - Parameter elements: Elements to be written into the buffer
+  /// - Parameter size: Count of elements
+  /// - returns: Offset of the vector
+  mutating public func createVector<T: Enum>(_ elements: [T], size: Int) -> Offset<UOffset> {
+    let size = size
+    startVector(size, elementSize: T.byteSize)
+    for e in elements.reversed() {
+      _bb.push(value: e.value, len: T.byteSize)
     }
-    
-    /// Adds scalars front to back instead of the default behavior of the normal add
-    /// - Parameters:
-    ///   - v: element of type Scalar
-    ///   - postion: position relative to the `writerIndex`
-    mutating public func reverseAdd<T: Scalar>(v: T, postion: Int) {
-        _bb.reversePush(value: v,
-                        position: postion,
-                        len: MemoryLayout<T>.size)
+    return Offset(offset: endVector(len: size))
+  }
+
+  /// Creates a vector of type Offsets  in the buffer
+  /// - Parameter offsets:Array of offsets of type T
+  /// - returns: Offset of the vector
+  mutating public func createVector<T>(ofOffsets offsets: [Offset<T>]) -> Offset<UOffset> {
+    createVector(ofOffsets: offsets, len: offsets.count)
+  }
+
+  ///  Creates a vector of type Offsets  in the buffer
+  /// - Parameter elements: Array of offsets of type T
+  /// - Parameter size: Count of elements
+  /// - returns: Offset of the vector
+  mutating public func createVector<T>(ofOffsets offsets: [Offset<T>], len: Int) -> Offset<UOffset> {
+    startVector(len, elementSize: MemoryLayout<Offset<T>>.size)
+    for o in offsets.reversed() {
+      push(element: o)
     }
-    
-    /// Ends the struct and returns the current buffer size
-    /// - Returns: Offset of type UOffset
-    @discardableResult
-    public func endStruct() -> Offset<UOffset> {
-        return Offset(offset: _bb.size)
+    return Offset(offset: endVector(len: len))
+  }
+
+  /// Creates a vector of Strings
+  /// - Parameter str: a vector of strings that will be written into the buffer
+  /// - returns: Offset of the vector
+  mutating public func createVector(ofStrings str: [String]) -> Offset<UOffset> {
+    var offsets: [Offset<String>] = []
+    for s in str {
+      offsets.append(create(string: s))
     }
-    
-    /// Adds the offset of a struct into the vTable
-    ///
-    /// The function fatalErrors if we pass an offset that is out of range
-    /// - Parameter o: offset
-    mutating public func add(structOffset o: VOffset) {
-        _vtableStorage.add(loc: FieldLoc(offset: _bb.size, position: VOffset(o)))
+    return createVector(ofOffsets: offsets)
+  }
+
+  /// Creates a vector of Flatbuffer structs.
+  ///
+  /// The function takes a Type to know what size it is, and alignment
+  /// - Parameters:
+  ///   - structs: An array of UnsafeMutableRawPointer
+  ///   - type: Type of the struct being written
+  /// - returns: Offset of the vector
+  @available(
+    *,
+    deprecated,
+    message: "0.9.0 will be removing the following method. Regenerate the code")
+  mutating public func createVector<T: Readable>(
+    structs: [UnsafeMutableRawPointer],
+    type: T.Type) -> Offset<UOffset>
+  {
+    startVector(structs.count &* T.size, elementSize: T.alignment)
+    for i in structs.reversed() {
+      create(struct: i, type: T.self)
     }
-    
-    // MARK: - Inserting Strings
-    
-    /// Insets a string into the buffer using UTF8
-    /// - Parameter str: String to be serialized
-    /// - returns: The strings offset in the buffer
-    mutating public func create(string str: String?) -> Offset<String> {
-        guard let str = str else { return Offset() }
-        let len = str.utf8.count
-        notNested()
-        preAlign(len: len &+ 1, type: UOffset.self)
-        _bb.fill(padding: 1)
-        _bb.push(string: str, len: len)
-        push(element: UOffset(len))
-        return Offset(offset: _bb.size)
+    return Offset(offset: endVector(len: structs.count))
+  }
+
+  /// Starts a vector of struct that considers the size and alignment of the struct
+  /// - Parameters:
+  ///   - count: number of elements to be written
+  ///   - size: size of struct
+  ///   - alignment: alignment of the struct
+  mutating public func startVectorOfStructs(count: Int, size: Int, alignment: Int) {
+    startVector(count &* size, elementSize: alignment)
+  }
+
+  /// Ends the vector of structs and writtens the current offset
+  /// - Parameter count: number of written elements
+  /// - Returns: Offset of type UOffset
+  mutating public func endVectorOfStructs(count: Int) -> Offset<UOffset> {
+    Offset<UOffset>(offset: endVector(len: count))
+  }
+
+  // MARK: - Inserting Structs
+
+  /// Writes a Flatbuffer struct into the buffer
+  /// - Parameters:
+  ///   - s: Flatbuffer struct
+  ///   - type: Type of the element to be serialized
+  /// - returns: Offset of the Object
+  @available(
+    *,
+    deprecated,
+    message: "0.9.0 will be removing the following method. Regenerate the code")
+  @discardableResult
+  mutating public func create<T: Readable>(
+    struct s: UnsafeMutableRawPointer,
+    type: T.Type) -> Offset<UOffset>
+  {
+    let size = T.size
+    preAlign(len: size, alignment: T.alignment)
+    _bb.push(struct: s, size: size)
+    return Offset(offset: _bb.size)
+  }
+
+  /// prepares the ByteBuffer to receive a struct of size and alignment
+  /// - Parameters:
+  ///   - size: size of written struct
+  ///   - alignment: alignment of written struct
+  mutating public func createStructOf(size: Int, alignment: Int) {
+    preAlign(len: size, alignment: alignment)
+    _bb.prepareBufferToReceiveStruct(of: size)
+  }
+
+  /// Adds scalars front to back instead of the default behavior of the normal add
+  /// - Parameters:
+  ///   - v: element of type Scalar
+  ///   - postion: position relative to the `writerIndex`
+  mutating public func reverseAdd<T: Scalar>(v: T, postion: Int) {
+    _bb.reversePush(
+      value: v,
+      position: postion,
+      len: MemoryLayout<T>.size)
+  }
+
+  /// Ends the struct and returns the current buffer size
+  /// - Returns: Offset of type UOffset
+  @discardableResult
+  public func endStruct() -> Offset<UOffset> {
+    Offset(offset: _bb.size)
+  }
+
+  /// Adds the offset of a struct into the vTable
+  ///
+  /// The function fatalErrors if we pass an offset that is out of range
+  /// - Parameter o: offset
+  mutating public func add(structOffset o: VOffset) {
+    _vtableStorage.add(loc: FieldLoc(offset: _bb.size, position: VOffset(o)))
+  }
+
+  // MARK: - Inserting Strings
+
+  /// Insets a string into the buffer using UTF8
+  /// - Parameter str: String to be serialized
+  /// - returns: The strings offset in the buffer
+  mutating public func create(string str: String?) -> Offset<String> {
+    guard let str = str else { return Offset() }
+    let len = str.utf8.count
+    notNested()
+    preAlign(len: len &+ 1, type: UOffset.self)
+    _bb.fill(padding: 1)
+    _bb.push(string: str, len: len)
+    push(element: UOffset(len))
+    return Offset(offset: _bb.size)
+  }
+
+  /// Inserts a shared string to the buffer
+  ///
+  /// The function checks the stringOffsetmap if it's seen a similar string before
+  /// - Parameter str: String to be serialized
+  /// - returns: The strings offset in the buffer
+  mutating public func createShared(string str: String?) -> Offset<String> {
+    guard let str = str else { return Offset() }
+    if let offset = stringOffsetMap[str] {
+      return offset
     }
-    
-    /// Inserts a shared string to the buffer
-    ///
-    /// The function checks the stringOffsetmap if it's seen a similar string before
-    /// - Parameter str: String to be serialized
-    /// - returns: The strings offset in the buffer
-    mutating public func createShared(string str: String?) -> Offset<String> {
-        guard let str = str else { return Offset() }
-        if let offset = stringOffsetMap[str] {
-            return offset
-        }
-        let offset = create(string: str)
-        stringOffsetMap[str] = offset
-        return offset
-    }
-    
-    // MARK: - Inseting offsets
-    
-    /// Adds the offset of an object into the buffer
-    /// - Parameters:
-    ///   - offset: Offset of another object to be written
-    ///   - position: The  predefined position of the object
-    mutating public func add<T>(offset: Offset<T>, at position: VOffset) {
-        if offset.isEmpty { return }
-        add(element: refer(to: offset.o), def: 0, at: position)
-    }
-    
-    /// Pushes a value of type offset into the buffer
-    /// - Parameter o: Offset
-    /// - returns: Position of the offset
-    @discardableResult
-    mutating public func push<T>(element o: Offset<T>) -> UOffset {
-        push(element: refer(to: o.o))
-    }
-    
-    // MARK: - Inserting Scalars to Buffer
-    
-    /// Adds a value into the buffer of type Scalar
-    ///
-    /// - Parameters:
-    ///   - element: Element to insert
-    ///   - def: Default value for that element
-    ///   - position: The predefined position of the element
-    mutating public func add<T: Scalar>(element: T, def: T, at position: VOffset) {
-        if (element == def && !serializeDefaults) { return }
-        track(offset: push(element: element), at: position)
-    }
-        
-    /// Adds a value into the buffer of type optional Scalar
-    /// - Parameters:
-    ///   - element: Optional element of type scalar
-    ///   - position: The predefined position of the element
-    mutating public func add<T: Scalar>(element: T?, at position: VOffset) {
-        guard let element = element else { return }
-        track(offset: push(element: element), at: position)
-    }
-        
-    /// Pushes the values into the buffer
-    /// - Parameter element: Element to insert
-    /// - returns: Postion of the Element
-    @discardableResult
-    mutating public func push<T: Scalar>(element: T) -> UOffset {
-        let size = MemoryLayout<T>.size
-        preAlign(len: size,
-                 alignment: size)
-        _bb.push(value: element, len: size)
-        return _bb.size
-    }
-    
+    let offset = create(string: str)
+    stringOffsetMap[str] = offset
+    return offset
+  }
+
+  // MARK: - Inseting offsets
+
+  /// Adds the offset of an object into the buffer
+  /// - Parameters:
+  ///   - offset: Offset of another object to be written
+  ///   - position: The  predefined position of the object
+  mutating public func add<T>(offset: Offset<T>, at position: VOffset) {
+    if offset.isEmpty { return }
+    add(element: refer(to: offset.o), def: 0, at: position)
+  }
+
+  /// Pushes a value of type offset into the buffer
+  /// - Parameter o: Offset
+  /// - returns: Position of the offset
+  @discardableResult
+  mutating public func push<T>(element o: Offset<T>) -> UOffset {
+    push(element: refer(to: o.o))
+  }
+
+  // MARK: - Inserting Scalars to Buffer
+
+  /// Adds a value into the buffer of type Scalar
+  ///
+  /// - Parameters:
+  ///   - element: Element to insert
+  ///   - def: Default value for that element
+  ///   - position: The predefined position of the element
+  mutating public func add<T: Scalar>(element: T, def: T, at position: VOffset) {
+    if element == def && !serializeDefaults { return }
+    track(offset: push(element: element), at: position)
+  }
+
+  /// Adds a value into the buffer of type optional Scalar
+  /// - Parameters:
+  ///   - element: Optional element of type scalar
+  ///   - position: The predefined position of the element
+  mutating public func add<T: Scalar>(element: T?, at position: VOffset) {
+    guard let element = element else { return }
+    track(offset: push(element: element), at: position)
+  }
+
+  /// Pushes the values into the buffer
+  /// - Parameter element: Element to insert
+  /// - returns: Postion of the Element
+  @discardableResult
+  mutating public func push<T: Scalar>(element: T) -> UOffset {
+    let size = MemoryLayout<T>.size
+    preAlign(
+      len: size,
+      alignment: size)
+    _bb.push(value: element, len: size)
+    return _bb.size
+  }
+
 }
 
 extension FlatBufferBuilder: CustomDebugStringConvertible {
-    
-    public var debugDescription: String {
-        """
-        buffer debug:
-        \(_bb)
-        builder debug:
-        { finished: \(finished), serializeDefaults: \(serializeDefaults), isNested: \(isNested) }
-        """
+
+  public var debugDescription: String {
+    """
+    buffer debug:
+    \(_bb)
+    builder debug:
+    { finished: \(finished), serializeDefaults: \(serializeDefaults), isNested: \(isNested) }
+    """
+  }
+
+  /// VTableStorage is a class to contain the VTable buffer that would be serialized into buffer
+  @usableFromInline
+  internal class VTableStorage {
+    /// Memory check since deallocating each time we want to clear would be expensive
+    /// and memory leaks would happen if we dont deallocate the first allocated memory.
+    /// memory is promised to be available before adding `FieldLoc`
+    private var memoryInUse = false
+    /// Size of FieldLoc in memory
+    let size = MemoryLayout<FieldLoc>.stride
+    /// Memeory buffer
+    var memory: UnsafeMutableRawBufferPointer!
+    /// Capacity of the current buffer
+    var capacity: Int = 0
+    /// Maximuim offset written to the class
+    var maxOffset: VOffset = 0
+    /// number of fields written into the buffer
+    var numOfFields: Int = 0
+    /// Last written Index
+    var writtenIndex: Int = 0
+    /// the amount of added elements into the buffer
+    var addedElements: Int { capacity - (numOfFields &* size) }
+
+    /// Creates the memory to store the buffer in
+    init() {
+      memory = UnsafeMutableRawBufferPointer.allocate(byteCount: 0, alignment: 0)
     }
 
-    /// VTableStorage is a class to contain the VTable buffer that would be serialized into buffer
-    @usableFromInline internal class VTableStorage {
-        /// Memory check since deallocating each time we want to clear would be expensive
-        /// and memory leaks would happen if we dont deallocate the first allocated memory.
-        /// memory is promised to be available before adding `FieldLoc`
-        private var memoryInUse = false
-        /// Size of FieldLoc in memory
-        let size = MemoryLayout<FieldLoc>.stride
-        /// Memeory buffer
-        var memory: UnsafeMutableRawBufferPointer!
-        /// Capacity of the current buffer
-        var capacity: Int = 0
-        /// Maximuim offset written to the class
-        var maxOffset: VOffset = 0
-        /// number of fields written into the buffer
-        var numOfFields: Int = 0
-        /// Last written Index
-        var writtenIndex: Int = 0
-        /// the amount of added elements into the buffer
-        var addedElements: Int { return capacity - (numOfFields &* size) }
-        
-        /// Creates the memory to store the buffer in
-        init() {
-            memory = UnsafeMutableRawBufferPointer.allocate(byteCount: 0, alignment: 0)
-        }
-        
-        deinit {
-            memory.deallocate()
-        }
-        
-        /// Builds a buffer with byte count of fieldloc.size * count of field numbers
-        /// - Parameter count: number of fields to be written
-        func start(count: Int) {
-            assert(count >= 0, "number of fields should NOT be negative")
-            let capacity = count &* size
-            ensure(space: capacity)
-        }
-        
-        /// Adds a FieldLoc into the buffer, which would track how many have been written,
-        /// and max offset
-        /// - Parameter loc: Location of encoded element
-        func add(loc: FieldLoc) {
-            memory.baseAddress?.advanced(by: writtenIndex).storeBytes(of: loc, as: FieldLoc.self)
-            writtenIndex = writtenIndex &+ size
-            numOfFields = numOfFields &+ 1
-            maxOffset = max(loc.position, maxOffset)
-        }
-        
-        /// Clears the data stored related to the encoded buffer
-        func clear() {
-            maxOffset = 0
-            numOfFields = 0
-            writtenIndex = 0
-        }
-        
-        /// Ensure that the buffer has enough space instead of recreating the buffer each time.
-        /// - Parameter space: space required for the new vtable
-        func ensure(space: Int) {
-            guard space &+ writtenIndex > capacity else { return }
-            memory.deallocate()
-            memory = UnsafeMutableRawBufferPointer.allocate(byteCount: space, alignment: size)
-            capacity = space
-        }
+    deinit {
+      memory.deallocate()
+    }
 
-        /// Loads an object of type `FieldLoc` from buffer memory
-        /// - Parameter index: index of element
-        /// - Returns: a FieldLoc at index
-        func load(at index: Int) -> FieldLoc {
-            return memory.load(fromByteOffset: index, as: FieldLoc.self)
-        }
-        
+    /// Builds a buffer with byte count of fieldloc.size * count of field numbers
+    /// - Parameter count: number of fields to be written
+    func start(count: Int) {
+      assert(count >= 0, "number of fields should NOT be negative")
+      let capacity = count &* size
+      ensure(space: capacity)
     }
-    
-    internal struct FieldLoc {
-        var offset: UOffset
-        var position: VOffset
+
+    /// Adds a FieldLoc into the buffer, which would track how many have been written,
+    /// and max offset
+    /// - Parameter loc: Location of encoded element
+    func add(loc: FieldLoc) {
+      memory.baseAddress?.advanced(by: writtenIndex).storeBytes(of: loc, as: FieldLoc.self)
+      writtenIndex = writtenIndex &+ size
+      numOfFields = numOfFields &+ 1
+      maxOffset = max(loc.position, maxOffset)
     }
 
+    /// Clears the data stored related to the encoded buffer
+    func clear() {
+      maxOffset = 0
+      numOfFields = 0
+      writtenIndex = 0
+    }
+
+    /// Ensure that the buffer has enough space instead of recreating the buffer each time.
+    /// - Parameter space: space required for the new vtable
+    func ensure(space: Int) {
+      guard space &+ writtenIndex > capacity else { return }
+      memory.deallocate()
+      memory = UnsafeMutableRawBufferPointer.allocate(byteCount: space, alignment: size)
+      capacity = space
+    }
+
+    /// Loads an object of type `FieldLoc` from buffer memory
+    /// - Parameter index: index of element
+    /// - Returns: a FieldLoc at index
+    func load(at index: Int) -> FieldLoc {
+      memory.load(fromByteOffset: index, as: FieldLoc.self)
+    }
+
+  }
+
+  internal struct FieldLoc {
+    var offset: UOffset
+    var position: VOffset
+  }
+
 }
diff --git a/swift/Sources/FlatBuffers/FlatBufferObject.swift b/swift/Sources/FlatBuffers/FlatBufferObject.swift
index 52ca396..7536c40 100644
--- a/swift/Sources/FlatBuffers/FlatBufferObject.swift
+++ b/swift/Sources/FlatBuffers/FlatBufferObject.swift
@@ -1,15 +1,31 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import Foundation
 
 /// FlatbufferObject structures all the Flatbuffers objects
 public protocol FlatBufferObject {
-    var __buffer: ByteBuffer! { get }
-    init(_ bb: ByteBuffer, o: Int32)
+  var __buffer: ByteBuffer! { get }
+  init(_ bb: ByteBuffer, o: Int32)
 }
 
 public protocol ObjectAPI {
-    associatedtype T
-    static func pack(_ builder: inout FlatBufferBuilder, obj: inout T) -> Offset<UOffset>
-    mutating func unpack() -> T
+  associatedtype T
+  static func pack(_ builder: inout FlatBufferBuilder, obj: inout T) -> Offset<UOffset>
+  mutating func unpack() -> T
 }
 
 /// Readable is structures all the Flatbuffers structs
@@ -17,12 +33,12 @@
 /// Readable is a procotol that each Flatbuffer struct should confirm to since
 /// FlatBufferBuilder would require a Type to both create(struct:) and createVector(structs:) functions
 public protocol Readable: FlatBufferObject {
-    static var size: Int { get }
-    static var alignment: Int { get }
+  static var size: Int { get }
+  static var alignment: Int { get }
 }
 
 public protocol Enum {
-    associatedtype T: Scalar
-    static var byteSize: Int { get }
-    var value: T { get }
+  associatedtype T: Scalar
+  static var byteSize: Int { get }
+  var value: T { get }
 }
diff --git a/swift/Sources/FlatBuffers/FlatBuffersUtils.swift b/swift/Sources/FlatBuffers/FlatBuffersUtils.swift
index 6838f86..507ef67 100644
--- a/swift/Sources/FlatBuffers/FlatBuffersUtils.swift
+++ b/swift/Sources/FlatBuffers/FlatBuffersUtils.swift
@@ -1,16 +1,32 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import Foundation
 
 public final class FlatBuffersUtils {
-    
-    /// Gets the size of the prefix
-    /// - Parameter bb: Flatbuffer object
-    public static func getSizePrefix(bb: ByteBuffer) -> Int32 {
-        return bb.read(def: Int32.self, position: bb.reader)
-    }
-    
-    /// Removes the prefix by duplicating the Flatbuffer
-    /// - Parameter bb: Flatbuffer object
-    public static func removeSizePrefix(bb: ByteBuffer) -> ByteBuffer {
-        return bb.duplicate(removing: MemoryLayout<Int32>.size)
-    }
+
+  /// Gets the size of the prefix
+  /// - Parameter bb: Flatbuffer object
+  public static func getSizePrefix(bb: ByteBuffer) -> Int32 {
+    bb.read(def: Int32.self, position: bb.reader)
+  }
+
+  /// Removes the prefix by duplicating the Flatbuffer
+  /// - Parameter bb: Flatbuffer object
+  public static func removeSizePrefix(bb: ByteBuffer) -> ByteBuffer {
+    bb.duplicate(removing: MemoryLayout<Int32>.size)
+  }
 }
diff --git a/swift/Sources/FlatBuffers/Int+extension.swift b/swift/Sources/FlatBuffers/Int+extension.swift
index e52bdab..ed68ca0 100644
--- a/swift/Sources/FlatBuffers/Int+extension.swift
+++ b/swift/Sources/FlatBuffers/Int+extension.swift
@@ -1,31 +1,47 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import Foundation
 
 extension Int {
-    
-    /// Moves the current int into the nearest power of two
-    ///
-    /// This is used since the UnsafeMutableRawPointer will face issues when writing/reading
-    /// if the buffer alignment exceeds that actual size of the buffer
-    var convertToPowerofTwo: Int {
-        guard self > 0 else { return 1 }
-        var n = UOffset(self)
-        
-        #if arch(arm) || arch(i386)
-        let max = UInt32(Int.max)
-        #else
-        let max = UInt32.max
-        #endif
-        
-        n -= 1
-        n |= n >> 1
-        n |= n >> 2
-        n |= n >> 4
-        n |= n >> 8
-        n |= n >> 16
-        if n != max {
-            n += 1
-        }
 
-        return Int(n)
+  /// Moves the current int into the nearest power of two
+  ///
+  /// This is used since the UnsafeMutableRawPointer will face issues when writing/reading
+  /// if the buffer alignment exceeds that actual size of the buffer
+  var convertToPowerofTwo: Int {
+    guard self > 0 else { return 1 }
+    var n = UOffset(self)
+
+    #if arch(arm) || arch(i386)
+    let max = UInt32(Int.max)
+    #else
+    let max = UInt32.max
+    #endif
+
+    n -= 1
+    n |= n >> 1
+    n |= n >> 2
+    n |= n >> 4
+    n |= n >> 8
+    n |= n >> 16
+    if n != max {
+      n += 1
     }
+
+    return Int(n)
+  }
 }
diff --git a/swift/Sources/FlatBuffers/Message.swift b/swift/Sources/FlatBuffers/Message.swift
index 590d3d7..d1db357 100644
--- a/swift/Sources/FlatBuffers/Message.swift
+++ b/swift/Sources/FlatBuffers/Message.swift
@@ -1,41 +1,59 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 public protocol FlatBufferGRPCMessage {
-    
-    /// Raw pointer which would be pointing to the beginning of the readable bytes
-    var rawPointer: UnsafeMutableRawPointer { get }
-    
-    /// Size of readable bytes in the buffer
-    var size: Int { get }
-    
-    init(byteBuffer: ByteBuffer)
+
+  /// Raw pointer which would be pointing to the beginning of the readable bytes
+  var rawPointer: UnsafeMutableRawPointer { get }
+
+  /// Size of readable bytes in the buffer
+  var size: Int { get }
+
+  init(byteBuffer: ByteBuffer)
 }
 
 /// Message is a wrapper around Buffers to to able to send Flatbuffers `Buffers` through the
 /// GRPC library
 public final class Message<T: FlatBufferObject>: FlatBufferGRPCMessage {
-    internal var buffer: ByteBuffer
-    
-    /// Returns the an object of type T that would be  read from the buffer
-    public var object: T {
-        T.init(buffer, o: Int32(buffer.read(def: UOffset.self, position: buffer.reader)) + Int32(buffer.reader))
-    }
-    
-    public var rawPointer: UnsafeMutableRawPointer { return buffer.memory.advanced(by: buffer.reader) }
-    
-    public var size: Int { return Int(buffer.size) }
-    
-    /// Initializes the message with the type Flatbuffer.Bytebuffer that is transmitted over
-    /// GRPC
-    /// - Parameter byteBuffer: Flatbuffer ByteBuffer object
-    public init(byteBuffer: ByteBuffer) {
-        buffer = byteBuffer
-    }
-    
-    /// Initializes the message by copying the buffer to the message to be sent.
-    /// from the builder
-    /// - Parameter builder: FlatbufferBuilder that has the bytes created in
-    /// - Note: Use  `builder.finish(offset)` before passing the builder without prefixing anything to it
-    public init(builder: inout FlatBufferBuilder) {
-        buffer = builder.sizedBuffer
-        builder.clear()
-    }
+  internal var buffer: ByteBuffer
+
+  /// Returns the an object of type T that would be  read from the buffer
+  public var object: T {
+    T.init(
+      buffer,
+      o: Int32(buffer.read(def: UOffset.self, position: buffer.reader)) + Int32(buffer.reader))
+  }
+
+  public var rawPointer: UnsafeMutableRawPointer { buffer.memory.advanced(by: buffer.reader) }
+
+  public var size: Int { Int(buffer.size) }
+
+  /// Initializes the message with the type Flatbuffer.Bytebuffer that is transmitted over
+  /// GRPC
+  /// - Parameter byteBuffer: Flatbuffer ByteBuffer object
+  public init(byteBuffer: ByteBuffer) {
+    buffer = byteBuffer
+  }
+
+  /// Initializes the message by copying the buffer to the message to be sent.
+  /// from the builder
+  /// - Parameter builder: FlatbufferBuilder that has the bytes created in
+  /// - Note: Use  `builder.finish(offset)` before passing the builder without prefixing anything to it
+  public init(builder: inout FlatBufferBuilder) {
+    buffer = builder.sizedBuffer
+    builder.clear()
+  }
 }
diff --git a/swift/Sources/FlatBuffers/Mutable.swift b/swift/Sources/FlatBuffers/Mutable.swift
index 90c1d8b..adcaa1f 100644
--- a/swift/Sources/FlatBuffers/Mutable.swift
+++ b/swift/Sources/FlatBuffers/Mutable.swift
@@ -1,67 +1,83 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import Foundation
 
 /// Mutable is a protocol that allows us to mutate Scalar values within the buffer
 public protocol Mutable {
-    /// makes Flatbuffer accessed within the Protocol
-    var bb: ByteBuffer { get }
-    /// makes position of the table/struct  accessed within the Protocol
-    var postion: Int32 { get }
+  /// makes Flatbuffer accessed within the Protocol
+  var bb: ByteBuffer { get }
+  /// makes position of the table/struct  accessed within the Protocol
+  var postion: Int32 { get }
 }
 
 extension Mutable {
-    
-    /// Mutates the memory in the buffer, this is only called from the access function of table and structs
-    /// - Parameters:
-    ///   - value: New value to be inserted to the buffer
-    ///   - index: index of the Element
-    func mutate<T: Scalar>(value: T, o: Int32) -> Bool {
-        guard o != 0 else { return false }
-        bb.write(value: value, index: Int(o), direct: true)
-        return true
-    }
+
+  /// Mutates the memory in the buffer, this is only called from the access function of table and structs
+  /// - Parameters:
+  ///   - value: New value to be inserted to the buffer
+  ///   - index: index of the Element
+  func mutate<T: Scalar>(value: T, o: Int32) -> Bool {
+    guard o != 0 else { return false }
+    bb.write(value: value, index: Int(o), direct: true)
+    return true
+  }
 }
 
 extension Mutable where Self == Table {
-    
-    /// Mutates a value by calling mutate with respect to the position in the table
-    /// - Parameters:
-    ///   - value: New value to be inserted to the buffer
-    ///   - index: index of the Element
-    public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
-        guard index != 0 else { return false }
-        return mutate(value: value, o: index + postion)
-    }
-    
-    /// Directly mutates the element by calling mutate
-    ///
-    /// Mutates the Element at index ignoring the current position by calling mutate
-    /// - Parameters:
-    ///   - value: New value to be inserted to the buffer
-    ///   - index: index of the Element
-    public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
-        return mutate(value: value, o: index)
-    }
+
+  /// Mutates a value by calling mutate with respect to the position in the table
+  /// - Parameters:
+  ///   - value: New value to be inserted to the buffer
+  ///   - index: index of the Element
+  public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
+    guard index != 0 else { return false }
+    return mutate(value: value, o: index + postion)
+  }
+
+  /// Directly mutates the element by calling mutate
+  ///
+  /// Mutates the Element at index ignoring the current position by calling mutate
+  /// - Parameters:
+  ///   - value: New value to be inserted to the buffer
+  ///   - index: index of the Element
+  public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
+    mutate(value: value, o: index)
+  }
 }
 
 extension Mutable where Self == Struct {
-    
-    /// Mutates a value by calling mutate with respect to the position in the struct
-    /// - Parameters:
-    ///   - value: New value to be inserted to the buffer
-    ///   - index: index of the Element
-    public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
-        return mutate(value: value, o: index + postion)
-    }
-    
-    /// Directly mutates the element by calling mutate
-    ///
-    /// Mutates the Element at index ignoring the current position by calling mutate
-    /// - Parameters:
-    ///   - value: New value to be inserted to the buffer
-    ///   - index: index of the Element
-    public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
-        return mutate(value: value, o: index)
-    }
+
+  /// Mutates a value by calling mutate with respect to the position in the struct
+  /// - Parameters:
+  ///   - value: New value to be inserted to the buffer
+  ///   - index: index of the Element
+  public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
+    mutate(value: value, o: index + postion)
+  }
+
+  /// Directly mutates the element by calling mutate
+  ///
+  /// Mutates the Element at index ignoring the current position by calling mutate
+  /// - Parameters:
+  ///   - value: New value to be inserted to the buffer
+  ///   - index: index of the Element
+  public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
+    mutate(value: value, o: index)
+  }
 }
 
 extension Struct: Mutable {}
diff --git a/swift/Sources/FlatBuffers/NativeTable.swift b/swift/Sources/FlatBuffers/NativeTable.swift
index 057b376..5c844c1 100644
--- a/swift/Sources/FlatBuffers/NativeTable.swift
+++ b/swift/Sources/FlatBuffers/NativeTable.swift
@@ -1,29 +1,45 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import Foundation
 
 public protocol NativeTable {}
 
 extension NativeTable {
-    
-    /// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly th
-    /// - Parameter type: Type of the Flatbuffer object
-    /// - Returns: returns the encoded sized ByteBuffer
-    public func serialize<T: ObjectAPI>(type: T.Type) -> ByteBuffer where T.T == Self {
-        var builder = FlatBufferBuilder(initialSize: 1024)
-        return serialize(builder: &builder, type: type.self)
-    }
-    
-    /// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly.
-    ///
-    /// - Parameters:
-    ///   - builder: A FlatBufferBuilder
-    ///   - type: Type of the Flatbuffer object
-    /// - Returns: returns the encoded sized ByteBuffer
-    /// - Note: The `serialize(builder:type)` can be considered as a function that allows you to create smaller builder instead of the default `1024`.
-    ///  It can be considered less expensive in terms of memory allocation
-    public func serialize<T: ObjectAPI>(builder: inout FlatBufferBuilder, type: T.Type) -> ByteBuffer where T.T == Self {
-        var s = self
-        let root = type.pack(&builder, obj: &s)
-        builder.finish(offset: root)
-        return builder.sizedBuffer
-    }
+
+  /// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly th
+  /// - Parameter type: Type of the Flatbuffer object
+  /// - Returns: returns the encoded sized ByteBuffer
+  public func serialize<T: ObjectAPI>(type: T.Type) -> ByteBuffer where T.T == Self {
+    var builder = FlatBufferBuilder(initialSize: 1024)
+    return serialize(builder: &builder, type: type.self)
+  }
+
+  /// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly.
+  ///
+  /// - Parameters:
+  ///   - builder: A FlatBufferBuilder
+  ///   - type: Type of the Flatbuffer object
+  /// - Returns: returns the encoded sized ByteBuffer
+  /// - Note: The `serialize(builder:type)` can be considered as a function that allows you to create smaller builder instead of the default `1024`.
+  ///  It can be considered less expensive in terms of memory allocation
+  public func serialize<T: ObjectAPI>(builder: inout FlatBufferBuilder, type: T.Type) -> ByteBuffer where T.T == Self {
+    var s = self
+    let root = type.pack(&builder, obj: &s)
+    builder.finish(offset: root)
+    return builder.sizedBuffer
+  }
 }
diff --git a/swift/Sources/FlatBuffers/Offset.swift b/swift/Sources/FlatBuffers/Offset.swift
index cdb0227..4b42b04 100644
--- a/swift/Sources/FlatBuffers/Offset.swift
+++ b/swift/Sources/FlatBuffers/Offset.swift
@@ -1,12 +1,28 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import Foundation
 
 /// Offset object for all the Objects that are written into the buffer
 public struct Offset<T> {
-    /// Offset of the object in the buffer
-    public var o: UOffset
-    /// Returns false if the offset is equal to zero
-    public var isEmpty: Bool { return o == 0 }
-    
-    public init(offset: UOffset) { o = offset }
-    public init() { o = 0 }
+  /// Offset of the object in the buffer
+  public var o: UOffset
+  /// Returns false if the offset is equal to zero
+  public var isEmpty: Bool { o == 0 }
+
+  public init(offset: UOffset) { o = offset }
+  public init() { o = 0 }
 }
diff --git a/swift/Sources/FlatBuffers/Struct.swift b/swift/Sources/FlatBuffers/Struct.swift
index 88e3a41..73b3295 100644
--- a/swift/Sources/FlatBuffers/Struct.swift
+++ b/swift/Sources/FlatBuffers/Struct.swift
@@ -1,16 +1,32 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import Foundation
 
 public struct Struct {
-    public private(set) var bb: ByteBuffer
-    public private(set) var postion: Int32
-    
-    public init(bb: ByteBuffer, position: Int32 = 0) {
-        self.bb = bb
-        self.postion = position
-    }
-    
-    public func readBuffer<T: Scalar>(of type: T.Type, at o: Int32) -> T {
-        let r = bb.read(def: T.self, position: Int(o + postion))
-        return r
-    }
+  public private(set) var bb: ByteBuffer
+  public private(set) var postion: Int32
+
+  public init(bb: ByteBuffer, position: Int32 = 0) {
+    self.bb = bb
+    postion = position
+  }
+
+  public func readBuffer<T: Scalar>(of type: T.Type, at o: Int32) -> T {
+    let r = bb.read(def: T.self, position: Int(o + postion))
+    return r
+  }
 }
diff --git a/swift/Sources/FlatBuffers/Table.swift b/swift/Sources/FlatBuffers/Table.swift
index 0f783bf..451398c 100644
--- a/swift/Sources/FlatBuffers/Table.swift
+++ b/swift/Sources/FlatBuffers/Table.swift
@@ -1,144 +1,166 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import Foundation
 
 public struct Table {
-    public private(set) var bb: ByteBuffer
-    public private(set) var postion: Int32
-    
-    public init(bb: ByteBuffer, position: Int32 = 0) {
-        guard isLitteEndian else {
-            fatalError("Reading/Writing a buffer in big endian machine is not supported on swift")
-        }
-        self.bb = bb
-        self.postion = position
-    }
-    
-    public func offset(_ o: Int32) -> Int32 {
-        let vtable = postion - bb.read(def: Int32.self, position: Int(postion))
-        return o < bb.read(def: VOffset.self, position: Int(vtable)) ? Int32(bb.read(def: Int16.self, position: Int(vtable + o))) : 0
-    }
-    
-    public func indirect(_ o: Int32) -> Int32 { return o + bb.read(def: Int32.self, position: Int(o)) }
+  public private(set) var bb: ByteBuffer
+  public private(set) var postion: Int32
 
-    /// String reads from the buffer with respect to position of the current table.
-    /// - Parameter offset: Offset of the string
-    public func string(at offset: Int32) -> String? {
-        return directString(at: offset + postion)
+  public init(bb: ByteBuffer, position: Int32 = 0) {
+    guard isLitteEndian else {
+      fatalError("Reading/Writing a buffer in big endian machine is not supported on swift")
     }
-    
-    /// Direct string reads from the buffer disregarding the position of the table.
-    /// It would be preferable to use string unless the current position of the table is not needed
-    /// - Parameter offset: Offset of the string
-    public func directString(at offset: Int32) -> String? {
-         var offset = offset
-         offset += bb.read(def: Int32.self, position: Int(offset))
-         let count = bb.read(def: Int32.self, position: Int(offset))
-         let position = offset + Int32(MemoryLayout<Int32>.size)
-         return bb.readString(at: position, count: count)
-    }
-    
-    /// Reads from the buffer with respect to the position in the table.
-    /// - Parameters:
-    ///   - type: Type of Scalar that needs to be read from the buffer
-    ///   - o: Offset of the Element
-    public func readBuffer<T: Scalar>(of type: T.Type, at o: Int32) -> T {
-        return directRead(of: T.self, offset: o + postion)
-    }
-    
-    /// Reads from the buffer disregarding the position of the table.
-    /// It would be used when reading from an
-    ///   ```
-    ///   let offset = __t.offset(10)
-    ///   //Only used when the we already know what is the
-    ///   // position in the table since __t.vector(at:)
-    ///   // returns the index with respect to the position
-    ///   __t.directRead(of: Byte.self,
-    ///                  offset: __t.vector(at: offset) + index * 1)
-    ///   ```
-    /// - Parameters:
-    ///   - type: Type of Scalar that needs to be read from the buffer
-    ///   - o: Offset of the Element
-    public func directRead<T: Scalar>(of type: T.Type, offset o: Int32) -> T {
-        let r = bb.read(def: T.self, position: Int(o))
-        return r
-    }
-    
-    public func union<T: FlatBufferObject>(_ o: Int32) -> T {
-        let o = o + postion
-        return directUnion(o)
-    }
+    self.bb = bb
+    postion = position
+  }
 
-    public func directUnion<T: FlatBufferObject>(_ o: Int32) -> T {
-        return T.init(bb, o: o + bb.read(def: Int32.self, position: Int(o)))
-    }
-    
-    public func getVector<T>(at off: Int32) -> [T]? {
-        let o = offset(off)
-        guard o != 0 else { return nil }
-        return bb.readSlice(index: vector(at: o), count: vector(count: o))
-    }
-    
-    /// Vector count gets the count of Elements within the array
-    /// - Parameter o: start offset of the vector
-    /// - returns: Count of elements
-    public func vector(count o: Int32) -> Int32 {
-        var o = o
-        o += postion
-        o += bb.read(def: Int32.self, position: Int(o))
-        return bb.read(def: Int32.self, position: Int(o))
-    }
-    
-    /// Vector start index in the buffer
-    /// - Parameter o:start offset of the vector
-    /// - returns: the start index of the vector
-    public func vector(at o: Int32) -> Int32 {
-        var o = o
-        o += postion
-        return o + bb.read(def: Int32.self, position: Int(o)) + 4
-    }
+  public func offset(_ o: Int32) -> Int32 {
+    let vtable = postion - bb.read(def: Int32.self, position: Int(postion))
+    return o < bb.read(def: VOffset.self, position: Int(vtable)) ? Int32(bb.read(
+      def: Int16.self,
+      position: Int(vtable + o))) : 0
+  }
+
+  public func indirect(_ o: Int32) -> Int32 { o + bb.read(def: Int32.self, position: Int(o)) }
+
+  /// String reads from the buffer with respect to position of the current table.
+  /// - Parameter offset: Offset of the string
+  public func string(at offset: Int32) -> String? {
+    directString(at: offset + postion)
+  }
+
+  /// Direct string reads from the buffer disregarding the position of the table.
+  /// It would be preferable to use string unless the current position of the table is not needed
+  /// - Parameter offset: Offset of the string
+  public func directString(at offset: Int32) -> String? {
+    var offset = offset
+    offset += bb.read(def: Int32.self, position: Int(offset))
+    let count = bb.read(def: Int32.self, position: Int(offset))
+    let position = offset + Int32(MemoryLayout<Int32>.size)
+    return bb.readString(at: position, count: count)
+  }
+
+  /// Reads from the buffer with respect to the position in the table.
+  /// - Parameters:
+  ///   - type: Type of Scalar that needs to be read from the buffer
+  ///   - o: Offset of the Element
+  public func readBuffer<T: Scalar>(of type: T.Type, at o: Int32) -> T {
+    directRead(of: T.self, offset: o + postion)
+  }
+
+  /// Reads from the buffer disregarding the position of the table.
+  /// It would be used when reading from an
+  ///   ```
+  ///   let offset = __t.offset(10)
+  ///   //Only used when the we already know what is the
+  ///   // position in the table since __t.vector(at:)
+  ///   // returns the index with respect to the position
+  ///   __t.directRead(of: Byte.self,
+  ///                  offset: __t.vector(at: offset) + index * 1)
+  ///   ```
+  /// - Parameters:
+  ///   - type: Type of Scalar that needs to be read from the buffer
+  ///   - o: Offset of the Element
+  public func directRead<T: Scalar>(of type: T.Type, offset o: Int32) -> T {
+    let r = bb.read(def: T.self, position: Int(o))
+    return r
+  }
+
+  public func union<T: FlatBufferObject>(_ o: Int32) -> T {
+    let o = o + postion
+    return directUnion(o)
+  }
+
+  public func directUnion<T: FlatBufferObject>(_ o: Int32) -> T {
+    T.init(bb, o: o + bb.read(def: Int32.self, position: Int(o)))
+  }
+
+  public func getVector<T>(at off: Int32) -> [T]? {
+    let o = offset(off)
+    guard o != 0 else { return nil }
+    return bb.readSlice(index: vector(at: o), count: vector(count: o))
+  }
+
+  /// Vector count gets the count of Elements within the array
+  /// - Parameter o: start offset of the vector
+  /// - returns: Count of elements
+  public func vector(count o: Int32) -> Int32 {
+    var o = o
+    o += postion
+    o += bb.read(def: Int32.self, position: Int(o))
+    return bb.read(def: Int32.self, position: Int(o))
+  }
+
+  /// Vector start index in the buffer
+  /// - Parameter o:start offset of the vector
+  /// - returns: the start index of the vector
+  public func vector(at o: Int32) -> Int32 {
+    var o = o
+    o += postion
+    return o + bb.read(def: Int32.self, position: Int(o)) + 4
+  }
 }
 
 extension Table {
-    
-    static public func indirect(_ o: Int32, _ fbb: ByteBuffer) -> Int32 { return o + fbb.read(def: Int32.self, position: Int(o)) }
-    
-    static public func offset(_ o: Int32, vOffset: Int32, fbb: ByteBuffer) -> Int32 {
-        let vTable = Int32(fbb.capacity) - o
-        return vTable + Int32(fbb.read(def: Int16.self, position: Int(vTable + vOffset - fbb.read(def: Int32.self, position: Int(vTable)))))
+
+  static public func indirect(_ o: Int32, _ fbb: ByteBuffer) -> Int32 { o + fbb.read(
+    def: Int32.self,
+    position: Int(o)) }
+
+  static public func offset(_ o: Int32, vOffset: Int32, fbb: ByteBuffer) -> Int32 {
+    let vTable = Int32(fbb.capacity) - o
+    return vTable + Int32(fbb.read(
+      def: Int16.self,
+      position: Int(vTable + vOffset - fbb.read(def: Int32.self, position: Int(vTable)))))
+  }
+
+  static public func compare(_ off1: Int32, _ off2: Int32, fbb: ByteBuffer) -> Int32 {
+    let memorySize = Int32(MemoryLayout<Int32>.size)
+    let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1))
+    let _off2 = off2 + fbb.read(def: Int32.self, position: Int(off2))
+    let len1 = fbb.read(def: Int32.self, position: Int(_off1))
+    let len2 = fbb.read(def: Int32.self, position: Int(_off2))
+    let startPos1 = _off1 + memorySize
+    let startPos2 = _off2 + memorySize
+    let minValue = min(len1, len2)
+    for i in 0...minValue {
+      let b1 = fbb.read(def: Int8.self, position: Int(i + startPos1))
+      let b2 = fbb.read(def: Int8.self, position: Int(i + startPos2))
+      if b1 != b2 {
+        return Int32(b2 - b1)
+      }
     }
-    
-    static public func compare(_ off1: Int32, _ off2: Int32, fbb: ByteBuffer) -> Int32 {
-        let memorySize = Int32(MemoryLayout<Int32>.size)
-        let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1))
-        let _off2 = off2 + fbb.read(def: Int32.self, position: Int(off2))
-        let len1 = fbb.read(def: Int32.self, position: Int(_off1))
-        let len2 = fbb.read(def: Int32.self, position: Int(_off2))
-        let startPos1 = _off1 + memorySize
-        let startPos2 = _off2 + memorySize
-        let minValue = min(len1, len2)
-        for i in 0...minValue {
-            let b1 = fbb.read(def: Int8.self, position: Int(i + startPos1))
-            let b2 = fbb.read(def: Int8.self, position: Int(i + startPos2))
-            if b1 != b2 {
-                return Int32(b2 - b1)
-            }
-        }
-        return len1 - len2
+    return len1 - len2
+  }
+
+  static public func compare(_ off1: Int32, _ key: [Byte], fbb: ByteBuffer) -> Int32 {
+    let memorySize = Int32(MemoryLayout<Int32>.size)
+    let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1))
+    let len1 = fbb.read(def: Int32.self, position: Int(_off1))
+    let len2 = Int32(key.count)
+    let startPos1 = _off1 + memorySize
+    let minValue = min(len1, len2)
+    for i in 0..<minValue {
+      let b = fbb.read(def: Int8.self, position: Int(i + startPos1))
+      let byte = key[Int(i)]
+      if b != byte {
+        return Int32(b - Int8(byte))
+      }
     }
-    
-    static public func compare(_ off1: Int32, _ key: [Byte], fbb: ByteBuffer) -> Int32 {
-        let memorySize = Int32(MemoryLayout<Int32>.size)
-        let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1))
-        let len1 = fbb.read(def: Int32.self, position: Int(_off1))
-        let len2 = Int32(key.count)
-        let startPos1 = _off1 + memorySize
-        let minValue = min(len1, len2)
-        for i in 0..<minValue {
-            let b = fbb.read(def: Int8.self, position: Int(i + startPos1))
-            let byte = key[Int(i)]
-            if b != byte {
-                return Int32(b - Int8(byte))
-            }
-        }
-        return len1 - len2
-    }
+    return len1 - len2
+  }
 }
