diff --git a/lib/swift/Sources/TJSONProtocol.swift b/lib/swift/Sources/TJSONProtocol.swift
new file mode 100644
index 0000000..b1e41c7
--- /dev/null
+++ b/lib/swift/Sources/TJSONProtocol.swift
@@ -0,0 +1,1160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+
+/**
+    JSON protocol implementation for thrift.
+    This is a full-feature protocol supporting Write and Read.
+    Please see the C++ class header for a detailed description of the protocol's wire format
+    Adapted from netstd C# version
+ */
+public class TJSONProtocol: TProtocol {
+    static let Version: Int = 1
+
+    public var transport: TTransport
+
+    // Temporary buffer used by several methods
+    private var tempBuffer: [UInt8] = [0,0,0,0]
+    private var contextStack: JSONContextStack = JSONContextStack()
+    private var currentContext: JSONBaseContext?
+    private var context: JSONBaseContext {
+        get throws {
+            if (currentContext != nil) {
+                return currentContext!
+            }
+            throw TProtocolError(error: .depthLimit, message: "Current context is nil")
+        }
+    }
+
+    /**
+     Reader that manages a 1-byte buffer
+     */
+    private var optionalReader: LookaheadReader?
+    private var reader: LookaheadReader {
+        get throws {
+            if (optionalReader != nil) {
+                return optionalReader!
+            }
+            throw TProtocolError(error: .depthLimit, message: "Lookahead reader is nil")
+        }
+    }
+
+    // MARK: TJSONProtocol Constructor
+    public required init(on transport: TTransport) {
+        self.transport = transport
+        currentContext = JSONBaseContext(on: self)
+        optionalReader = LookaheadReader(on: self)
+    }
+
+    // MARK: TJSONProtocol helpers
+    /**
+     Push a new JSON context onto the context stack
+     */
+    func pushContext(_ context: JSONBaseContext) {
+        contextStack.push(context)
+        currentContext = context
+    }
+
+    /**
+     Pop current JSON context from the context stack
+     */
+    func popContext() {
+        _ = contextStack.pop()
+        currentContext = contextStack.isEmpty() ? JSONBaseContext(on: self) : contextStack.peek()
+    }
+
+    /**
+     Reset context stack to pristine state. Allows for reusal of the protocol even in cases where the protocol instance
+     was in an undefined state due to dangling/stale/obsolete contexts
+     */
+    func resetContext() {
+        contextStack.clear()
+        currentContext = JSONBaseContext(on: self)
+    }
+
+    /**
+     Read a byte that must match bytes[0]; otherwise an exception is thrown.
+     - bytes: Input bytes array
+     */
+    func readJsonSyntaxChar(bytes: [UInt8]) throws {
+        let ch: UInt8 = try reader.read()
+        if (ch != bytes[0]) {
+            throw TProtocolError(error: .invalidData, message: "Unexpected character: \(ch.asCharacter())")
+        }
+    }
+
+    /**
+     Write the bytes in array buffer as a JSON characters, escaping as needed
+     */
+    func writeJsonString(bytes: [UInt8]) throws {
+        try context.writeConditionalDelimiter()
+        try transport.writeJSONQuote()
+
+        let len: Int = bytes.count
+        for i in 0..<len {
+            if (bytes[i] & 0x00FF >= 0x30) {
+                if (bytes[i] == TJSONProtocolConstants.Backslash[0]) {
+                    try transport.writeJSONBackslash()
+                    try transport.writeJSONBackslash()
+                } else {
+                    try transport.write(data: Data(bytes: [bytes[i]], count: 1))
+                }
+            } else {
+                tempBuffer[0] = TJSONProtocolConstants.JsonCharTable[Int(bytes[i])]
+                if (tempBuffer[0] == 1) {
+                    try transport.write(data: Data(bytes: [bytes[i]], count: 1))
+                } else if (tempBuffer[0] > 1) {
+                    try transport.writeJSONBackslash()
+                    try transport.write(data: Data(bytes: [tempBuffer[0]], count: 1))
+                } else {
+                    try transport.writeJSONEscSequences()
+                    tempBuffer[0] = (bytes[i] >> 4).toHexChar()
+                    tempBuffer[1] = (bytes[i]).toHexChar()
+                    try transport.write(data: Data(bytes: [tempBuffer[0], tempBuffer[1]], count:2))
+                }
+            }
+        }
+        try transport.writeJSONQuote()
+    }
+
+    /**
+     Write out number as a JSON value. If the context dicates so, it will be wrapped in quotes to output as a JSON string.
+     */
+    func writeJsonInteger(num: Int64) throws {
+        try context.writeConditionalDelimiter()
+        let str: String = String(num)
+
+        let escapeNum: Bool = try context.escapeNumbers()
+        if (escapeNum) {
+            try transport.write(data: Data(bytes: TJSONProtocolConstants.Quote, count: TJSONProtocolConstants.Quote.count))
+        }
+
+        let strData: Data = str.data(using: .utf8)!
+        try transport.write(data: strData)
+
+        if (escapeNum) {
+            try transport.write(data: Data(bytes: TJSONProtocolConstants.Quote, count: TJSONProtocolConstants.Quote.count))
+        }
+    }
+
+    /**
+     Write out a double as a JSON value. If it is Nan or Infinity or if the context dictates escaping, write out as JSON string.
+     */
+    func writeJsonDouble(num: Double) throws {
+        try context.writeConditionalDelimiter()
+        let str = String(num)
+        var special = false
+
+        switch(str[0]) {
+        case "N", "I":
+            // Nan or Infinity
+            special = true
+        case "-":
+            if (str[1] == "I") {
+                // -Infinity
+                special = true
+            }
+        default:
+            special = false
+        }
+
+        let escapeNum = try context.escapeNumbers()
+        let escapeNumOrSpecial = special || escapeNum
+        if (escapeNumOrSpecial) {
+            try transport.writeJSONQuote()
+        }
+
+        if let strData = str.data(using: .utf8) {
+            try transport.write(data: strData)
+        } else {
+            throw TProtocolError(error: .invalidData, message: "Cannot convert double number to data bytes")
+        }
+
+        if (escapeNumOrSpecial) {
+            try transport.writeJSONQuote()
+        }
+    }
+
+    /**
+     Write out contents of byte array as a JSON string with base-64 encoded data
+     */
+    func writeJsonBase64(bytes: [UInt8]) throws {
+        try context.writeConditionalDelimiter()
+        try transport.writeJSONQuote()
+
+        var len = bytes.count
+        var off = 0
+        while (len >= 3) {
+            // Encode 3 bytes at a time
+            TBase64Utils.encode(src: bytes, srcOff: off, len: 3, dst: &tempBuffer, dstOff: 0)
+            try transport.write(data: Data(bytes: tempBuffer, count: 4))
+            off += 3
+            len -= 3
+        }
+
+        if (len > 0) {
+            // Encode remainder
+            TBase64Utils.encode(src: bytes, srcOff: off, len: len, dst: &tempBuffer, dstOff: 0)
+            try transport.write(data: Data(bytes: tempBuffer, count: len + 1))
+        }
+
+        try transport.writeJSONQuote()
+    }
+
+    func writeJsonObjectStart() throws {
+        try context.writeConditionalDelimiter()
+        try transport.writeJSONLeftBrace()
+        pushContext(JSONPairContext(on: self))
+    }
+
+    func writeJsonObjectEnd() throws {
+        popContext()
+        try transport.writeJSONRightBrace()
+    }
+
+    func writeJsonArrayStart() throws {
+        try context.writeConditionalDelimiter()
+        try transport.writeJSONLeftBracket()
+        pushContext(JSONListContext(on: self))
+    }
+
+    func writeJsonArrayEnd() throws {
+        popContext()
+        try transport.writeJSONRightBracket()
+    }
+
+    /**
+     Read in a JSON string, unescaping as appropriate. Skip reading from the context if skipContext is true.
+     */
+    func readJsonString(skipContext: Bool) throws -> [UInt8] {
+        var codeunits: [Character] = []
+
+        if (!skipContext) {
+            try context.readConditionalDelimiter()
+        }
+        try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote)
+
+        var dataBuffer = Data()
+        while (true) {
+            var ch: UInt8 = try reader.read()
+            if (ch == TJSONProtocolConstants.Quote[0]) {
+                break
+            }
+
+            // Escaped?
+            if (ch != TJSONProtocolConstants.EscSequences[0]) {
+                dataBuffer.append([ch], count: 1)
+                continue
+            }
+
+            // distinguish between \uXXXX and \?
+            ch = try reader.read()
+            if (ch != TJSONProtocolConstants.EscSequences[1]) { // control chars like \n
+                guard let off: Int = TJSONProtocolConstants.EscSequences.firstIndex(of: ch) else {
+                    throw TProtocolError(error: .invalidData, message: "Expected control char")
+                }
+                ch = TJSONProtocolConstants.EscapeCharValues[off]
+                dataBuffer.append([ch], count: 1)
+                continue
+            }
+
+            // It's \uXXXX
+            let tempData: Data = try transport.readAll(size: 4)
+            let wch = Int16( ((tempData[0]).toHexChar() << 12) +
+                             ((tempData[1]).toHexChar() << 8) +
+                             ((tempData[2]).toHexChar() << 4) +
+                             ((tempData[3]).toHexChar()) )
+            guard let wchScalar = UnicodeScalar(Int(wch)) else {
+                throw TProtocolError(error: .invalidData, message: "Expected Unicode character")
+            }
+
+            if (try wch.magnitude.isHighSurrogate()) {
+                if (codeunits.count > 0) {
+                    throw TProtocolError(error: .invalidData, message: "Exptected low surrogate char")
+                }
+                codeunits.append(Character(wchScalar))
+            } else if (try wch.magnitude.isLowSurrogate()) {
+                if (codeunits.count == 0) {
+                    throw TProtocolError(error: .invalidData, message: "Exptected high surrogate char")
+                }
+                codeunits.append(Character(wchScalar))
+                guard let codeunitsData = String(codeunits).data(using: .utf8) else {
+                    throw TProtocolError(error: .invalidData, message: "Codeunits cannot be converted to string bytes")
+                }
+                dataBuffer.append(codeunitsData)
+                codeunits.removeAll()
+            } else {
+                let bytesArray: [UInt8] = withUnsafeBytes(of: wch.bigEndian, Array.init)
+                dataBuffer.append(Data(bytes: bytesArray, count: bytesArray.count))
+            }
+         }
+
+        if (codeunits.count > 0) {
+            throw TProtocolError(error: .invalidData, message: "Expected low surrogate char")
+        }
+
+        let bytesResult: [UInt8] = dataBuffer.map { $0 }
+        return bytesResult
+    }
+
+    /**
+     Read in a sequence of characters that are all valid in JSON numbers. Does not do a complete regex check
+     to validate that this is actually a number.
+     */
+    func readJsonNumericChars() throws -> String {
+        var str = ""
+        while(true) {
+            // TODO: Workaround for primitive types with TJSONProtocol: think - how to rewrite into more easy from without exception
+            do {
+                let ch: UInt8 = try reader.peek()
+                if (!ch.isJsonNumeric()) {
+                    break
+                }
+                let c = try reader.read()
+                str.append(c.asCharacter())
+            } catch is TTransportError {
+                break
+            }
+            catch let error {
+                throw error
+            }
+        }
+        return str
+    }
+
+    /**
+     Read in a JSON number.  If the context dictates, read in enclosing quotes.
+     */
+    func readJsonInteger() throws -> Int64 {
+        try context.readConditionalDelimiter()
+        let escapeNum = try context.escapeNumbers()
+        if (escapeNum) {
+            try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote)
+        }
+
+        let str: String = try readJsonNumericChars()
+        if (escapeNum) {
+            try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote)
+        }
+
+        guard let result = Int64(str) else { throw TProtocolError(error: .invalidData, message: "Cannot convert \(str) to Int64") }
+        return result
+    }
+
+    /**
+     Read in a JSON double value. Throw if the value is not wrapped in quotes when expected or if wrapped in quotes when not expected.
+     */
+    func readJsonDouble() throws -> Double {
+        try context.readConditionalDelimiter()
+
+        let escapeNum = try context.escapeNumbers()
+        if (try reader.peek() == TJSONProtocolConstants.Quote[0]) {
+            let arr: [UInt8] = try readJsonString(skipContext: true)
+            if let str: String = String(data: Data(arr), encoding: .utf8),
+               let dub = Double(str) {
+                if (!escapeNum && !dub.isNaN && !dub.isInfinite) {
+                    throw TProtocolError(error: .invalidData, message: "Numeric data unexpectedly quoted")
+                }
+                return dub
+            } else {
+                throw TProtocolError(error: .invalidData, message: "Numeric data convertion to double failed")
+            }
+        }
+
+        if (escapeNum) {
+            try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote)
+        }
+
+        let str: String = try readJsonNumericChars()
+        if let dub = Double(str) {
+            return dub
+        } else {
+            throw TProtocolError(error: .invalidData, message: "Numeric data convertion to double failed")
+        }
+    }
+
+    /**
+     Read in a JSON string containing base-64 encoded data and decode it.
+     */
+    func readJsonBase64() throws -> [UInt8] {
+        var b = try readJsonString(skipContext: false)
+        var len = b.count
+        var off = 0
+        var size = 0
+
+        // Reduce len to ignore fill bytes
+        while( (len > 0) && (b[len - 1] == "=".asciiBytes()[0]) ) {
+            len -= 1
+        }
+
+        // Read & decode full byte triplets = 4 source bytes
+        while (len > 4) {
+            // Decode 4 bytes at a time
+            TBase64Utils.decode(src: b, srcOff: off, len: 4, dst: &b, dstOff: size) // Nb: decode in place
+            off += 4
+            len -= 4
+            size += 3
+        }
+
+        // Don't decode if we hit the end or got a single leftover byte
+        // (invalid base64 but legal for skip of reqular string exType)
+        if (len > 1) {
+            // Decode remainder
+            TBase64Utils.decode(src: b, srcOff: off, len: len, dst: &b, dstOff: size) // NB: decode in place
+            size += len - 1
+        }
+
+        let result: [UInt8] = Array(b[0..<size])
+        return result
+    }
+
+    func readJsonObjectStart() throws {
+        try context.readConditionalDelimiter()
+        try readJsonSyntaxChar(bytes: TJSONProtocolConstants.LeftBrace)
+        pushContext(JSONPairContext(on: self))
+    }
+
+    func readJsonObjectEnd() throws {
+        try readJsonSyntaxChar(bytes: TJSONProtocolConstants.RightBrace)
+        popContext()
+    }
+
+    func readJsonArrayStart() throws {
+        try context.readConditionalDelimiter()
+        try readJsonSyntaxChar(bytes: TJSONProtocolConstants.LeftBracket)
+        pushContext(JSONListContext(on: self))
+    }
+
+    func readJsonArrayEnd() throws {
+        try readJsonSyntaxChar(bytes: TJSONProtocolConstants.RightBracket)
+        popContext()
+    }
+
+    // MARK: - TProtocol
+    public func readMessageBegin() throws -> (String, TMessageType, Int32) {
+        resetContext()
+        try readJsonArrayStart()
+
+        let version = try readJsonInteger()
+        if (version != TJSONProtocol.Version) {
+            throw TProtocolError(error: .badVersion(expected: "\(TJSONProtocol.Version)", got: "\(version)"), message: "Bad version")
+        }
+
+        let buf = try readJsonString(skipContext: false)
+        guard let name = String(bytes: buf, encoding: .utf8) else {
+            throw TProtocolError(error: .invalidData, message: "Invalid message name")
+        }
+        guard let type = TMessageType(rawValue: Int32(try readJsonInteger())) else {
+            throw TProtocolError(error: .invalidData, message: "Invalid message type")
+        }
+        let seqID = try readJsonInteger()
+
+        return (name, type, Int32(seqID))
+    }
+
+    public func readMessageEnd() throws {
+        try readJsonArrayEnd()
+    }
+
+    public func readStructBegin() throws -> String {
+        try readJsonObjectStart()
+        return ""
+    }
+
+    public func readStructEnd() throws {
+        try readJsonObjectEnd()
+    }
+
+    public func readFieldBegin() throws -> (String, TType, Int32) {
+        let ch = try reader.peek()
+        if (ch == TJSONProtocolConstants.RightBrace[0]) {
+            return ("", TType.stop, 0)
+        }
+
+        let fieldID = try readJsonInteger()
+        try readJsonObjectStart()
+        let fieldName: [UInt8] = try readJsonString(skipContext: false)
+        let fieldType: TType = try TType.getTypeIdForTypeName(fieldName)
+        guard let name = String(bytes: fieldName, encoding: .utf8) else {
+            throw TProtocolError(error: .invalidData, message: "Invalid field name")
+        }
+        return (name, fieldType, Int32(fieldID))
+    }
+
+    public func readFieldEnd() throws {
+        try readJsonObjectEnd()
+    }
+
+    public func readMapBegin() throws -> (TType, TType, Int32) {
+        try readJsonArrayStart()
+        let keyTypeName = try readJsonString(skipContext: false)
+        let keyType = try TType.getTypeIdForTypeName(keyTypeName)
+
+        let valueTypeName = try readJsonString(skipContext: false)
+        let valueType = try TType.getTypeIdForTypeName(valueTypeName)
+
+        let count = try readJsonInteger()
+
+        try checkReadBytesAvailable(keyType: keyType, valueType: valueType, count: Int32(count))
+        try readJsonObjectStart()
+        return (keyType, valueType, Int32(count))
+    }
+
+    public func readMapEnd() throws {
+        try readJsonObjectEnd()
+        try readJsonArrayEnd()
+    }
+
+    public func readSetBegin() throws -> (TType, Int32) {
+        try readJsonArrayStart()
+
+        let elementTypeName = try readJsonString(skipContext: false)
+        let elementType = try TType.getTypeIdForTypeName(elementTypeName)
+
+        let count = try readJsonInteger()
+
+        try checkReadBytesAvailable(elementType, Int32(count))
+
+        return (elementType, Int32(count))
+    }
+
+    public func readSetEnd() throws {
+        try readJsonArrayEnd()
+    }
+
+    public func readListBegin() throws -> (TType, Int32) {
+        try readJsonArrayStart()
+
+        let elementTypeName = try readJsonString(skipContext: false)
+        let elementType = try TType.getTypeIdForTypeName(elementTypeName)
+
+        let count = try readJsonInteger()
+
+        try checkReadBytesAvailable(elementType, Int32(count))
+        return (elementType, Int32(count))
+    }
+
+    public func readListEnd() throws {
+        try readJsonArrayEnd()
+    }
+
+    public func read() throws -> String {
+        let buf = try readJsonString(skipContext: false)
+        guard let str = String(bytes: buf, encoding: .utf8) else {
+            throw TProtocolError(error: .invalidData, message: "Cannot convert bytes to string")
+        }
+        return str
+    }
+
+    public func read() throws -> Bool {
+        let intValue = try readJsonInteger()
+        return intValue == 0 ? false : true
+    }
+
+    public func read() throws -> UInt8 {
+        return UInt8(try readJsonInteger())
+    }
+
+    public func read() throws -> Int8 {
+        return Int8(try readJsonInteger())
+    }
+
+    public func read() throws -> Int16 {
+        return Int16(try readJsonInteger())
+    }
+
+    public func read() throws -> Int32 {
+        return Int32(try readJsonInteger())
+    }
+
+    public func read() throws -> Int64 {
+        return try readJsonInteger()
+    }
+
+    public func read() throws -> Double {
+        return try readJsonDouble()
+    }
+
+    public func read() throws -> Data {
+        let base64Bytes = try readJsonBase64()
+        return Data(bytes: base64Bytes, count: base64Bytes.count)
+    }
+
+    public func read() throws -> UUID {
+        let buf = try readJsonString(skipContext: false)
+        guard let id = String(bytes: buf, encoding: .utf8) else {
+            throw TProtocolError(error: .invalidData, message: "Cannot convert bytes to string")
+        }
+        guard let uuid =  UUID(uuidString: id) else {
+            throw TProtocolError(error: .invalidData, message: "Cannot convert string to uuid")
+        }
+        return uuid
+    }
+
+    public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws {
+        resetContext()
+        try writeJsonArrayStart()
+        try writeJsonInteger(num: Int64(TJSONProtocol.Version))
+
+        guard let nameData = name.data(using: .utf8) else {
+            throw TProtocolError(error: .invalidData, message: "Cannot convert message name to bytes data")
+        }
+        try writeJsonString(bytes: [UInt8] (nameData))
+
+        try writeJsonInteger(num: Int64(messageType.rawValue))
+        try writeJsonInteger(num: Int64(sequenceID))
+    }
+
+    public func writeMessageEnd() throws {
+        try writeJsonArrayEnd()
+    }
+
+    public func writeStructBegin(name: String) throws {
+        try writeJsonObjectStart()
+    }
+
+    public func writeStructEnd() throws {
+        try writeJsonObjectEnd()
+    }
+
+    public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws {
+        try writeJsonInteger(num: Int64(fieldID))
+
+        try writeJsonObjectStart()
+
+        let fieldTypeName = try fieldType.getTypeNameForTypeId()
+        try writeJsonString(bytes: fieldTypeName)
+    }
+
+    public func writeFieldStop() throws {
+        // Nop
+    }
+
+    public func writeFieldEnd() throws {
+        try writeJsonObjectEnd()
+    }
+
+    public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws {
+        try writeJsonArrayStart()
+
+        let mapKeyTypeName = try keyType.getTypeNameForTypeId()
+        try writeJsonString(bytes: mapKeyTypeName)
+
+        let mapValueTypeName = try valueType.getTypeNameForTypeId()
+        try writeJsonString(bytes: mapValueTypeName)
+
+        try writeJsonInteger(num: Int64(size))
+
+        try writeJsonObjectStart()
+    }
+
+    public func writeMapEnd() throws {
+        try writeJsonObjectEnd()
+        try writeJsonArrayEnd()
+    }
+
+    public func writeSetBegin(elementType: TType, size: Int32) throws {
+        try writeJsonArrayStart()
+
+        let elementTypeName = try elementType.getTypeNameForTypeId()
+        try writeJsonString(bytes: elementTypeName)
+
+        try writeJsonInteger(num: Int64(size))
+    }
+
+    public func writeSetEnd() throws {
+        try writeJsonArrayEnd()
+    }
+
+    public func writeListBegin(elementType: TType, size: Int32) throws {
+        try writeJsonArrayStart()
+
+        let elementTypeName = try elementType.getTypeNameForTypeId()
+        try writeJsonString(bytes: elementTypeName)
+
+        try writeJsonInteger(num: Int64(size))
+    }
+
+    public func writeListEnd() throws {
+        try writeJsonArrayEnd()
+    }
+
+    public func write(_ value: String) throws {
+        guard let strData = value.data(using: .utf8) else {
+            throw TProtocolError(error: .invalidData, message: "Cannot convert string value to bytes data")
+        }
+
+        try writeJsonString(bytes: [UInt8](strData))
+    }
+
+    public func write(_ value: Bool) throws {
+        try writeJsonInteger(num: value ? 1 : 0)
+    }
+
+    public func write(_ value: UInt8) throws {
+        try writeJsonInteger(num: Int64(value))
+    }
+
+    public func write(_ value: Int8) throws {
+        try writeJsonInteger(num: Int64(value))
+    }
+
+    public func write(_ value: Int16) throws {
+        try writeJsonInteger(num: Int64(value))
+    }
+
+    public func write(_ value: Int32) throws {
+        try writeJsonInteger(num: Int64(value))
+    }
+
+    public func write(_ value: Int64) throws {
+        try writeJsonInteger(num: value)
+    }
+
+    public func write(_ value: Double) throws {
+        try writeJsonDouble(num: value)
+    }
+
+    public func write(_ value: Data) throws {
+        try writeJsonBase64(bytes: [UInt8](value))
+    }
+
+    public func write(_ value: UUID) throws {
+        guard let strData = value.uuidString.data(using: .utf8) else {
+            throw TProtocolError(error: .invalidData, message: "Cannot convert UUID value to bytes data")
+        }
+
+        try writeJsonString(bytes: [UInt8](strData))
+    }
+
+    // MARK: - Private functions
+    private func checkReadBytesAvailable(keyType: TType, valueType: TType, count: Int32) throws {
+        let elmSize = try getMinSerializedSize(keyType) + getMinSerializedSize(valueType)
+        _ = count * elmSize
+        // TODO: implement checkReadBytesAvailable in TTransport
+        // transport.checkReadBytesAvailable(size: count * elmSize)
+    }
+
+    private func checkReadBytesAvailable(_ elementType: TType, _ count: Int32) throws {
+        let elmSize = try getMinSerializedSize(elementType)
+        _ = count * elmSize
+        // TODO: implement checkReadBytesAvailable in TTransport
+        // transport.checkReadBytesAvailable(size: count * elmSize)
+    }
+
+    private func getMinSerializedSize(_ type: TType) throws -> Int32  {
+        switch(type) {
+        case .stop, .void: return 0
+        case .bool, .i8, .i16, .i32, .i64, .double: return 1
+        case .string, .struct, .map, .set, .list: return 2 // empty object
+        default:
+            throw TProtocolError(error: .invalidData, message: "Invalid TType")
+        }
+    }
+
+    // MARK: - TJSONProtocol inner classes
+    /*
+     Base class for tracking JSON contexts that may require
+     inserting/reading additional JSON syntax characters
+     This base context does nothing
+     */
+    class JSONBaseContext {
+        var proto: TJSONProtocol
+
+        init(on proto: TJSONProtocol) {
+            self.proto = proto
+        }
+
+        func writeConditionalDelimiter() throws {
+        }
+
+        func readConditionalDelimiter() throws {
+        }
+
+        func escapeNumbers() -> Bool {
+            return false
+        }
+    }
+
+    /*
+     Context for JSON lists. will insert/read commas before each item except for the first one
+     */
+    class JSONListContext: JSONBaseContext {
+        private var first: Bool = true
+
+        override init(on proto: TJSONProtocol) {
+            super.init(on: proto)
+        }
+
+        override func writeConditionalDelimiter() throws {
+            if (first) {
+                first = false
+            } else {
+                try proto.transport.writeJSONComma()
+            }
+        }
+
+        override func readConditionalDelimiter() throws {
+            if (first) {
+                first = false
+            } else {
+                try proto.readJsonSyntaxChar(bytes: TJSONProtocolConstants.Comma)
+            }
+        }
+    }
+
+    /*
+     Context for JSON records. Will insert/read colons before the value portion of each record pair,
+     and commas before each key except the first. In addition, will indicate that numbers in the key position
+     need to be escaped in quotes (since JSON keys must be strings).
+     */
+    class JSONPairContext : JSONBaseContext {
+        private var colon: Bool = true
+        private var first: Bool = true
+
+        override init(on proto: TJSONProtocol) {
+            super.init(on: proto)
+        }
+
+        override func writeConditionalDelimiter() throws {
+            if (first) {
+                first = false
+                colon = true
+            } else {
+                if (colon) {
+                    try proto.transport.writeJSONColon()
+                } else {
+                    try proto.transport.writeJSONComma()
+                }
+                self.colon = !self.colon
+            }
+        }
+
+        override func readConditionalDelimiter() throws {
+            if (first) {
+                first = false
+                colon = true
+            } else {
+                try proto.readJsonSyntaxChar(bytes: colon ? TJSONProtocolConstants.Colon : TJSONProtocolConstants.Comma)
+                self.colon = !self.colon
+            }
+        }
+
+        override func escapeNumbers() -> Bool {
+            return colon
+        }
+    }
+
+    class JSONContextStack {
+        private var items: [JSONBaseContext] = []
+
+        func peek() -> JSONBaseContext {
+            guard let topElement = items.first else { fatalError("This stack is empty.") }
+            return topElement
+        }
+
+        func pop() -> JSONBaseContext {
+            return items.removeFirst()
+        }
+
+        func push(_ element: JSONBaseContext) {
+            items.insert(element, at: 0)
+        }
+
+        func clear() {
+            items.removeAll()
+        }
+
+        func isEmpty() -> Bool {
+            return items.count == 0
+        }
+    }
+
+    class LookaheadReader {
+        private var byteData: UInt8?
+        private var hasData: Bool = false
+        var proto: TJSONProtocol
+
+        init(on proto: TJSONProtocol) {
+            self.proto = proto
+        }
+
+        func read() throws -> UInt8 {
+            if (hasData) {
+                hasData = false
+            } else {
+                let data = try proto.transport.readAll(size: 1)
+                byteData = Array(data)[0]
+            }
+            if let byte = byteData {
+                return byte
+            }
+            throw TProtocolError(error: .invalidData, message: "Reader does not have data to read")
+        }
+
+        func peek() throws -> UInt8 {
+            if (!hasData) {
+                let data = try proto.transport.readAll(size: 1)
+                byteData = Array(data)[0]
+                hasData = true
+            }
+            if let byte = byteData {
+                return byte
+            }
+            throw TProtocolError(error: .invalidData, message: "Reader does not have data to peek")
+        }
+    }
+}
+
+// MARK: TJSONProtocolConstants
+/**
+ TJSONProtocol Constants properties/fields
+ */
+public struct TJSONProtocolConstants {
+    public static let Comma: [UInt8] = ",".asciiBytes()
+    public static let Colon: [UInt8] = ":".asciiBytes()
+    public static let LeftBrace: [UInt8] = "{".asciiBytes()
+    public static let RightBrace: [UInt8] = "}".asciiBytes()
+    public static let LeftBracket: [UInt8] = "[".asciiBytes()
+    public static let RightBracket: [UInt8] = "]".asciiBytes()
+    public static let Quote: [UInt8] = "\"".asciiBytes()
+    public static let Backslash: [UInt8] = "\\".asciiBytes()
+
+    public static let JsonCharTable: [UInt8] = [
+        0, 0, 0, 0, 0, 0, 0, 0, b, t, n, 0, f, r, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        1, 1, qt, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+    ]
+
+    // \b -> \u{0008}
+    // \f -> \u{000C}
+    public static let EscapeChars: [Character] = ["\"", "\\", "/", "\u{0008}", "\u{000C}", "\n", "\r", "\t" ]
+    public static let EscapeCharValues: [UInt8] = "\"\\/\u{0008}\u{000C}\n\r\t".asciiBytes()
+    public static let EscSequences: [UInt8] = "\\u00".asciiBytes()
+
+    public struct TypeNames {
+        public static let NameBool: [UInt8] = "tf".asciiBytes()
+        public static let NameByte: [UInt8] = "i8".asciiBytes()
+        public static let NameI16: [UInt8] = "i16".asciiBytes()
+        public static let NameI32: [UInt8] = "i32".asciiBytes()
+        public static let NameI64: [UInt8] = "i64".asciiBytes()
+        public static let NameDouble: [UInt8] = "dbl".asciiBytes()
+        public static let NameStruct: [UInt8] = "rec".asciiBytes()
+        public static let NameString: [UInt8] = "str".asciiBytes()
+        public static let NameMap: [UInt8] = "map".asciiBytes()
+        public static let NameList: [UInt8] = "lst".asciiBytes()
+        public static let NameSet: [UInt8] = "set".asciiBytes()
+    }
+
+    // MARK: private fields helpers
+    private static let b: UInt8 = "b".asciiBytes()[0]
+    private static let t: UInt8 = "t".asciiBytes()[0]
+    private static let n: UInt8 = "n".asciiBytes()[0]
+    private static let f: UInt8 = "f".asciiBytes()[0]
+    private static let r: UInt8 = "r".asciiBytes()[0]
+    private static let qt: UInt8 = "\"".asciiBytes()[0]
+}
+
+// MARK: Extensions
+extension String {
+    public func asciiBytes() -> [UInt8] {
+        var result: [UInt8] = []
+        for char in self {
+            result.append(char.asciiValue!)
+        }
+        return result
+    }
+
+    subscript(offset: Int) -> Character {
+        self[index(startIndex, offsetBy: offset)]
+    }
+}
+
+extension Character {
+    public func asciiByte() -> UInt8 {
+       return self.asciiValue!
+    }
+}
+
+extension UInt8 {
+    /**
+     Convert a byte containing a hex value to its corresponding hex character
+     */
+    public func toHexChar() -> UInt8 {
+        var value = self & 0x0F
+        if (value < 10) {
+            let zeroChar = Character("0").asciiValue!
+            return value + zeroChar
+        }
+        value -= 10
+        let aChar = Character("a").asciiValue!
+        return value + aChar
+    }
+
+    public func isJsonNumeric() -> Bool {
+        let numberBytes = "+-.0123456789Ee".asciiBytes()
+        if (numberBytes.contains(self)) {
+            return true
+        }
+        return false
+    }
+
+    public func asCharacter() -> Character {
+        let scalar = UnicodeScalar(self)
+        return Character(scalar)
+    }
+}
+
+extension UInt16 {
+    public func isHighSurrogate() throws -> Bool {
+        let wch = self
+        if let d800 = UInt16("D800", radix: 16),
+           let dbff = UInt16("DBFF", radix: 16) {
+            return wch >= d800 && wch <= dbff
+        } else {
+            throw TProtocolError(error: .invalidData, message: "isHighSurrogate failed")
+        }
+    }
+
+    public func isLowSurrogate() throws -> Bool{
+        let wch = self
+        if let dc00 = UInt16("DC00", radix: 16),
+           let dfff = UInt16("DFFF", radix: 16) {
+            return wch >= dc00 && wch <= dfff
+        } else {
+            throw TProtocolError(error: .invalidData, message: "isLowSurrogate failed")
+        }
+    }
+}
+
+extension TType {
+    public static func getTypeIdForTypeName(_ name: [UInt8]) throws -> TType {
+        var result = TType.stop
+        if (name.count > 1) {
+            switch(name[0]) {
+            case "t".asciiBytes()[0]:
+                result = TType.bool
+            case "i".asciiBytes()[0]:
+                switch(name[1]) {
+                case "8".asciiBytes()[0]:
+                    result = TType.i8
+                case "1".asciiBytes()[0]:
+                    result = TType.i16
+                case "3".asciiBytes()[0]:
+                    result = TType.i32
+                case "6".asciiBytes()[0]:
+                    result = TType.i64
+                default:
+                    result = TType.stop
+                }
+            case "d".asciiBytes()[0]:
+                result = TType.double
+            case "l".asciiBytes()[0]:
+                result = TType.list
+            case "m".asciiBytes()[0]:
+                result = TType.map
+            case "r".asciiBytes()[0]:
+                result = TType.struct
+            case "s".asciiBytes()[0]:
+                if (name[1] == "t".asciiBytes()[0]) {
+                    result = TType.string
+                } else if (name[1] == "e".asciiBytes()[0]) {
+                    result = TType.set
+                }
+            default:
+                result = TType.stop
+            }
+        }
+
+        if (result == TType.stop) {
+            throw TProtocolError(error: .notImplemented, message: "Unrecognized exType")
+        }
+
+        return result
+    }
+
+    public func getTypeNameForTypeId() throws -> [UInt8] {
+        let typeId = self
+        switch(typeId) {
+        case .bool:
+            return TJSONProtocolConstants.TypeNames.NameBool
+        case .i8:
+            return TJSONProtocolConstants.TypeNames.NameByte
+        case .i16:
+            return TJSONProtocolConstants.TypeNames.NameI16
+        case .i32:
+            return TJSONProtocolConstants.TypeNames.NameI32
+        case .i64:
+            return TJSONProtocolConstants.TypeNames.NameI64
+        case .double:
+            return TJSONProtocolConstants.TypeNames.NameDouble
+        case .string:
+            return TJSONProtocolConstants.TypeNames.NameString
+        case .struct:
+            return TJSONProtocolConstants.TypeNames.NameStruct
+        case .map:
+            return TJSONProtocolConstants.TypeNames.NameMap
+        case .set:
+            return TJSONProtocolConstants.TypeNames.NameSet
+        case .list:
+            return TJSONProtocolConstants.TypeNames.NameList
+        default:
+            throw TProtocolError(error: .invalidData, message: "TypeId: \(typeId) does not have mapping Name")
+        }
+    }
+}
+
+extension TTransport {
+    func writeJSONColon() throws {
+        try self.write(data: Data(bytes: TJSONProtocolConstants.Colon, count: TJSONProtocolConstants.Colon.count))
+    }
+
+    func writeJSONComma() throws {
+        try self.write(data: Data(bytes: TJSONProtocolConstants.Comma, count: TJSONProtocolConstants.Comma.count))
+    }
+
+    func writeJSONQuote() throws {
+        try self.write(data: Data(bytes: TJSONProtocolConstants.Quote, count: TJSONProtocolConstants.Quote.count))
+    }
+
+    func writeJSONBackslash() throws {
+        try self.write(data: Data(bytes: TJSONProtocolConstants.Backslash, count: TJSONProtocolConstants.Backslash.count))
+    }
+
+    func writeJSONEscSequences() throws {
+        try self.write(data: Data(bytes: TJSONProtocolConstants.EscSequences, count: TJSONProtocolConstants.EscSequences.count))
+    }
+
+    func writeJSONLeftBrace() throws {
+        try self.write(data: Data(bytes: TJSONProtocolConstants.LeftBrace, count: TJSONProtocolConstants.LeftBrace.count))
+    }
+
+    func writeJSONRightBrace() throws {
+        try self.write(data: Data(bytes: TJSONProtocolConstants.RightBrace, count: TJSONProtocolConstants.RightBrace.count))
+    }
+
+    func writeJSONLeftBracket() throws {
+        try self.write(data: Data(bytes: TJSONProtocolConstants.LeftBracket, count: TJSONProtocolConstants.LeftBracket.count))
+    }
+
+    func writeJSONRightBracket() throws {
+        try self.write(data: Data(bytes: TJSONProtocolConstants.RightBracket, count: TJSONProtocolConstants.RightBracket.count))
+    }
+}
