/**
 * Copyright 2024 Beijing Baolande Software Corporation
 *
 * 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.
 *
 * Runtime Library Exception to the Apache 2.0 License:
 *
 * As an exception, if you use this Software to compile your source code and
 * portions of this Software are embedded into the binary product as a result,
 * you may redistribute such product without providing attribution as would
 * otherwise be required by Sections 4(a), 4(b) and 4(d) of the License.
 */

package redis_sdk.client.api

public interface ResponseBuilder<T> {
    func build(message: RedisMessage): T
}

public class ResponseBuilderHelper {
    /**
     * 解构Option<RedisMessage>
     */
    public static func getRedisMessageOrThrow(message: Option<RedisMessage>, messageType: RedisMessageType): RedisMessage {
        if (let Some(redisMessage) <- message) {
            return redisMessage
        } else {
            throw RedisException("Incompatible type, nil message, expected ${messageType}")
        }
    }

    /**
     * 判断ArrayList是否嵌套ArraysRedisMessage
     */
    public static func isArraysFirstElement(children: ArrayList<RedisMessage>): Bool {
        if (children.size > 0) {
            let firstElement = children.get(0)
            if (let Some(firstElement) <- firstElement) {
                if (let Some(child) <- (firstElement as ArraysRedisMessage)) {
                    return true
                }
            }
        }

        return false
    }

    /**
     * 从HashMap<String, Any>中获取值
     */
    public static func getValueFromMap<T>(data: HashMap<String, Any>, keyName: String): T {
        try {
            return (data.get(keyName).getOrThrow() as T).getOrThrow()
        } catch (ex: Exception) {
            throw RedisException("Failure to obtain ${keyName}: ${ex.message}", ex)
        }
    }

    /**
     * 从HashMap<String, Any>中获取值
     */
    public static func getNillableValueFromMap<T>(data: HashMap<String, Any>, keyName: String): ?T {
        try {
            if (let Some(value) <- data.get(keyName)) {
                return (value as T).getOrThrow()
            } else {
                return None
            }
        } catch (ex: Exception) {
            throw RedisException("Failure to obtain ${keyName}: ${ex.message}", ex)
        }
    }

    /**
     * 解析为简单类型:Int64、String、Boolean、Float64
     */
    public static func unwrapToSimpleType<T>(redisMessage: RedisMessage): T {
        if (let Some(integerMessage) <- (redisMessage as IntegerRedisMessage)) {
            if (let Some(value) <- (integerMessage.getValue() as T)) {
                return value
            }
        } else if (let Some(stringMessage) <- (redisMessage as StringRedisMessage)) {
            if (let Some(value) <- (stringMessage.getValue() as T)) {
                return value
            }
        } else if (let Some(bulkStringMesage) <- (redisMessage as BulkStringRedisMessage)) {
            let bulkStringMesageVal = bulkStringMesage.getStringValue()
            if (let Some(bulkStringMesageVal) <- bulkStringMesageVal) {
                if (let Some(value) <- (bulkStringMesageVal as T)) {
                    return value
                } else if (let Some(v) <- (1.1f64 as T)) {
                    return (Float64.parse(bulkStringMesageVal) as T).getOrThrow()
                }
            } else {
                throw RedisException("Incompatible type, nil/null BulkString is not the expect type")
            }
        } else if (let Some(boolMessage) <- (redisMessage as BooleanRedisMessage)) {
            if (let Some(value) <- (boolMessage.getValue() as T)) {
                return value
            }
        } else if (let Some(dobuleMessage) <- (redisMessage as DoubleRedisMessage)) {
            if (let Some(value) <- (dobuleMessage.getValue() as T)) {
                return value
            }
        } else if (let Some(bigNumberMessage) <- (redisMessage as BigNumberRedisMessage)) {
            if (let Some(value) <- (bigNumberMessage.getValue() as T)) {
                return value
            }
        } else if (let Some(errorMesage) <- (redisMessage as ErrorRedisMessage)) {
            throw RedisException(errorMesage.getValue())
        }

        throw RedisException("Incompatible type, ${redisMessage.getType()} is not the expect type")
    }

    /**
     * 解析为允许None值的简单类型:Int64、String、Boolean、Float64
     */
    public static func unwrapToNillableSimpleType<T>(redisMessage: RedisMessage): ?T {
        if (let Some(integerMessage) <- (redisMessage as IntegerRedisMessage)) {
            if (let Some(value) <- (integerMessage.getValue() as T)) {
                return value
            }
        } else if (let Some(stringMessage) <- (redisMessage as StringRedisMessage)) {
            if (let Some(value) <- (stringMessage.getValue() as T)) {
                return value
            }
        } else if (let Some(bulkStringMesage) <- (redisMessage as BulkStringRedisMessage)) {
            let bulkStringMesageVal = bulkStringMesage.getStringValue()
            if (let Some(bulkStringMesageVal) <- bulkStringMesageVal) {
                if (let Some(value) <- (bulkStringMesageVal as T)) {
                    return value
                } else if (let Some(v) <- (1.1f64 as T)) {
                    return Float64.parse(bulkStringMesageVal) as T
                }
            } else {
                if (let Some(test) <- ("abc" as T)) {
                    return None<T>
                } else if (let Some(v) <- (1.1f64 as T)) {
                    return None<T>
                } else if (let Some(test) <- (1 as T)) {
                    return None<T>
                } else {
                    throw RedisException("Incompatible type, ${redisMessage.getType()} is not the expect type")
                }

                throw RedisException("Incompatible type, nil/null BulkString is not the expect type")
            }
        } else if (let Some(nullMessage) <- (redisMessage as NullRedisMessage)) {
            return None<T>
        } else if (let Some(boolMessage) <- (redisMessage as BooleanRedisMessage)) {
            if (let Some(value) <- (boolMessage.getValue() as T)) {
                return value
            }
        } else if (let Some(dobuleMessage) <- (redisMessage as DoubleRedisMessage)) {
            if (let Some(value) <- (dobuleMessage.getValue() as T)) {
                return value
            }
        } else if (let Some(bigNumberMessage) <- (redisMessage as BigNumberRedisMessage)) {
            if (let Some(value) <- (bigNumberMessage.getValue() as T)) {
                return value
            }
        } else if (let Some(errorMesage) <- (redisMessage as ErrorRedisMessage)) {
            throw RedisException(errorMesage.getValue())
        }

        throw RedisException("Incompatible type, ${redisMessage.getType()} is not the expect type")
    }

    public static func unwrapToNillableAnySimpleType(redisMessage: RedisMessage): ?Any {
        if (let Some(integerMessage) <- (redisMessage as IntegerRedisMessage)) {
            return integerMessage.getValue()
        } else if (let Some(stringMessage) <- (redisMessage as StringRedisMessage)) {
            return stringMessage.getValue()
        } else if (let Some(bulkStringMesage) <- (redisMessage as BulkStringRedisMessage)) {
            if (let Some(bulkStringMesage) <- bulkStringMesage.getStringValue()) {
                return bulkStringMesage
            } else {
                return None
            }
        } else if (let Some(nullMessage) <- (redisMessage as NullRedisMessage)) {
            return None
        } else if (let Some(boolMessage) <- (redisMessage as BooleanRedisMessage)) {
            return boolMessage.getValue()
        } else if (let Some(dobuleMessage) <- (redisMessage as DoubleRedisMessage)) {
            return dobuleMessage.getValue()
        } else if (let Some(bigNumberMessage) <- (redisMessage as BigNumberRedisMessage)) {
            return bigNumberMessage.getValue()
        } else if (let Some(errorMesage) <- (redisMessage as ErrorRedisMessage)) {
            throw RedisException(errorMesage.getValue())
        }
        throw RedisException("Incompatible type, ${redisMessage.getType()} is not the expect type")
    }
}

public class StringResponseBuilder <: ResponseBuilder<String> {
    public func build(message: RedisMessage): String {
        if (let Some(message) <- (message as StringRedisMessage)) {
            return message.getValue()
        } else if (let Some(message) <- (message as BulkStringRedisMessage)) {
            if (let Some(value) <- message.getStringValue()) {
                return value
            } else {
                throw RedisException("Nil Reply")
            }
        } else if (let Some(message) <- (message as VerbatimRedisMessage)) {
            if (message.getEncoding() == "txt") {
                return message.getStringContent()
            } else {
                return message.getEncoding() + ":" + message.getStringContent()
            }
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class AggressiveObjectObjectBuilder <: ResponseBuilder<?Any> {
    public func build(message: RedisMessage): ?Any {
        if (let Some(item) <- (message as ArraysRedisMessage)) {
            if (let Some(arraysMessage) <- item.getValue()) {
                if (arraysMessage.isEmpty()) {
                    return HashMap<String, String>()
                }
                if (let Some(item) <- ((arraysMessage.get(0) as MapRedisMessage))) {
                    let list: ArrayList<KeyValueMessagePair> = ResponseBuilderFactory
                        .listOfKeyValueBuilder
                        .build(message)
                    var runningScriptMap: HashMap<String, Any> = HashMap<String, Any>()
                    var resultMap = HashMap<String, ?Any>()
                    for (kv in list) {
                        resultMap.add(
                            ResponseBuilderFactory.stringBuilder.build(kv.getKey()),
                            this.build(kv.getValue())
                        )
                    }
                    return resultMap
                } else {
                    var resultArrays = ArrayList<?Any>()
                    for (obj in arraysMessage) {
                        resultArrays.add(this.build(obj))
                    }
                    return resultArrays
                }
            }
        } else {
            return ResponseBuilderHelper.unwrapToNillableAnySimpleType(message)
        }
    }
}

public class ByteArrayResponseBuilder <: ResponseBuilder<Array<Byte>> {
    public func build(message: RedisMessage): Array<Byte> {
        if (let Some(message) <- (message as BulkStringRedisMessage)) {
            if (let Some(messgeByte) <- message.getByteArray()) {
                return messgeByte
            }
            throw RedisException("Incompatible type, nil/null BulkString is not the expect type")
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }
        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class ListOfBoolBuilder <: ResponseBuilder<ArrayList<Bool>> {
    public func build(message: RedisMessage): ArrayList<Bool> {
        let response = ResponseBuilderFactory.listOfIntegerBuilder.build(message)
        let result = ArrayList<Bool>()
        for (item in response) {
            match (item) {
                case 1 => result.add(true)
                case _ => result.add(false)
            }
        }
        return result
    }
}

public class NillableStringResponseBuilder <: ResponseBuilder<?String> {
    public func build(message: RedisMessage): ?String {
        if (let Some(message) <- (message as StringRedisMessage)) {
            return message.getValue()
        } else if (let Some(message) <- (message as BulkStringRedisMessage)) {
            return message.getStringValue()
        } else if (let Some(nullMessage) <- (message as NullRedisMessage)) {
            return None<String>
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class NillableByteArrayResponseBuilder <: ResponseBuilder<?Array<Byte>> {
    public func build(message: RedisMessage): ?Array<Byte> {
        if (let Some(message) <- (message as BulkStringRedisMessage)) {
            return message.getByteArray()
        } else if (let Some(nullMessage) <- (message as NullRedisMessage)) {
            return None<Array<Byte>>
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class IntegerResponseBuilder <: ResponseBuilder<Int64> {
    public func build(message: RedisMessage): Int64 {
        if (let Some(message) <- (message as IntegerRedisMessage)) {
            return message.getValue()
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class DoubleResponseBuilder <: ResponseBuilder<Float64> {
    public func build(message: RedisMessage): Float64 {
        if (let Some(message) <- (message as DoubleRedisMessage)) {
            return message.getValue()
        } else if (let Some(message) <- (message as BulkStringRedisMessage)) {
            if (let Some(value) <- message.getStringValue()) {
                return Float64.parse(value)
            }

            throw RedisException("Incompatible type, nil/null BulkString is not the expect type")
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class NillableDoubleResponseBuilder <: ResponseBuilder<?Float64> {
    public func build(message: RedisMessage): ?Float64 {
        if (let Some(message) <- (message as NullRedisMessage)) {
            return None
        }

        if (let Some(message) <- (message as DoubleRedisMessage)) {
            return message.getValue()
        } else if (let Some(message) <- (message as BulkStringRedisMessage)) {
            if (let Some(value) <- message.getStringValue()) {
                return Float64.parse(value)
            } else {
                return None
            }
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class NillableIntegerResponseBuilder <: ResponseBuilder<?Int64> {
    public func build(message: RedisMessage): ?Int64 {
        if (let Some(message) <- (message as NullRedisMessage)) {
            return None
        }

        if (let Some(message) <- (message as IntegerRedisMessage)) {
            return message.getValue()
        } else if (let Some(message) <- (message as BulkStringRedisMessage)) {
            if (message.isNull()) {
                return None
            } else {
                throw RedisException("Incompatible type, null/nil BULK_STRINGS is not the expect type")
            }
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class BoolResponseBuilder <: ResponseBuilder<Bool> {
    public func build(message: RedisMessage): Bool {
        if (let Some(message) <- (message as IntegerRedisMessage)) {
            let responseCode = message.getValue()
            match (responseCode) {
                case 0 => return false
                case 1 => return true
                case _ => throw RedisException("Invalid response ${responseCode} for bool response")
            }
        } else if (let Some(message) <- (message as BooleanRedisMessage)) {
            return message.getValue()
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class ArrayResponseBuilder<T> <: ResponseBuilder<Array<T>> {
    public func build(message: RedisMessage): Array<T> {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let results = ArrayList<T>()
            if (message.isNull()) {
                return results.toArray()
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                processChildren(children, results)
            }

            return results.toArray()
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }

    protected static func processChildren(children: ArrayList<RedisMessage>, results: ArrayList<T>) {
        for (child in children) {
            let unwrapedValue = ResponseBuilderHelper.unwrapToSimpleType<T>(child)
            results.add(unwrapedValue)
        }
    }
}

public class NillableArrayOfResponseBuilder<T> <: ResponseBuilder<?Array<T>> {
    public func build(message: RedisMessage): ?Array<T> {
        if (let Some(message) <- (message as NullRedisMessage)) {
            return None
        }

        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let results = ArrayList<T>()
            if (message.isNull()) {
                return None
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                processChildren(children, results)
            }

            return results.toArray()
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }

    protected static func processChildren(children: ArrayList<RedisMessage>, results: ArrayList<T>) {
        for (child in children) {
            let unwrapedValue = ResponseBuilderHelper.unwrapToSimpleType<T>(child)
            results.add(unwrapedValue)
        }
    }
}

public class SetOfResponseBuilder<T> <: ResponseBuilder<HashSet<T>> where T <: Hashable & Equatable<T> {
    public func build(message: RedisMessage): HashSet<T> {
        if (let Some(message) <- (message as SetRedisMessage)) {
            let results = HashSet<T>()
            let children = message.getValue()
            processChildren(children, results)
            return results
        }

        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let results = HashSet<T>()
            if (message.isNull()) {
                return results
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                processChildren(children, results)
            }

            return results
        } else if (let Some(message) <- (message as MapRedisMessage)) {
            let results = HashSet<T>()
            if (message.isEmpty()) {
                return results
            }
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }

    protected static func processChildren(children: ArrayList<RedisMessage>, results: HashSet<T>) {
        for (child in children) {
            let unwrapedValue = ResponseBuilderHelper.unwrapToSimpleType<T>(child)
            results.add(unwrapedValue)
        }
    }
}

public class ArrayOfNillableResponseBuilder<T> <: ResponseBuilder<Array<?T>> {
    public func build(message: RedisMessage): Array<?T> {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let results = ArrayList<?T>()
            if (message.isNull()) {
                return results.toArray()
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                processChildren(children, results)
            }

            return results.toArray()
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }

    protected static func processChildren(children: ArrayList<RedisMessage>, results: ArrayList<?T>) {
        for (child in children) {
            let unwrapedValue = ResponseBuilderHelper.unwrapToNillableSimpleType<T>(child)
            results.add(unwrapedValue)
        }
    }
}

public class NillableListResponseBuilder<T> <: ResponseBuilder<?ArrayList<T>> {
    public func build(message: RedisMessage): ?ArrayList<T> {
        if (let Some(message) <- (message as NullRedisMessage)) {
            return None
        }

        if (let Some(message) <- (message as BulkStringRedisMessage)) {
            if (message.isNull()) {
                return None
            }
        }

        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let results = ArrayList<T>()
            if (message.isNull()) {
                return None
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                processChildren(children, results)
            }

            return results
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }

    protected static func processChildren(children: ArrayList<RedisMessage>, results: ArrayList<T>) {
        for (child in children) {
            let unwrapedValue = ResponseBuilderHelper.unwrapToSimpleType<T>(child)
            results.add(unwrapedValue)
        }
    }
}

public class ListResponseBuilder<T> <: ResponseBuilder<ArrayList<T>> {
    public func build(message: RedisMessage): ArrayList<T> {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let results = ArrayList<T>()
            if (message.isNull() || message.getSize() == 0) {
                return results
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                ArrayResponseBuilder.processChildren(children, results)
            }

            return results
        } else if (let Some(message) <- (message as SetRedisMessage)) {
            let results = ArrayList<T>()
            if (message.getSize() == 0) {
                return results
            }

            let children = message.getValue()
            ArrayResponseBuilder.processChildren(children, results)

            return results
        } else if (let Some(message) <- (message as MapRedisMessage)) {
            let results = ArrayList<T>()
            if (message.isEmpty()) {
                return results
            }
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class ListOfNillableResponseBuilder<T> <: ResponseBuilder<ArrayList<?T>> {
    public func build(message: RedisMessage): ArrayList<?T> {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let results = ArrayList<?T>()
            if (message.isNull()) {
                return results
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                ArrayOfNillableResponseBuilder.processChildren(children, results)
            }

            return results
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class TupleOfStringAndArrayResponseBuilder<T> <: ResponseBuilder<(String, Array<T>)> {
    public func build(message: RedisMessage): (String, Array<T>) {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let results = ArrayList<T>()
            let children = message.getValue()
            if (let Some(children) <- children) {
                if (children.size != 2) {
                    throw RedisException(
                        "Incompatible type, wrong size of ArraysRedisMessage, expect 2 but ${children.size}")
                }

                var key = ""
                let bulkStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(0),
                    RedisMessageType.BULK_STRINGS
                )
                if (let Some(keyMesage) <- (bulkStringMessage as BulkStringRedisMessage)) {
                    if (let Some(content) <- keyMesage.getStringValue()) {
                        key = content
                    } else {
                        throw RedisException("Incompatible type, key is nil")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected first message's type: ${RedisMessageType.BULK_STRINGS}, but ${bulkStringMessage.getType()}"
                    )
                }

                let arrayMessage = ResponseBuilderHelper.getRedisMessageOrThrow(children.get(1), RedisMessageType.ARRAYS
                )
                if (let Some(arrayMessage) <- (arrayMessage as ArraysRedisMessage)) {
                    let children = arrayMessage.getValue()
                    if (let Some(children) <- children) {
                        ArrayResponseBuilder.processChildren(children, results)
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected second message's type: ${RedisMessageType.ARRAYS}, but ${bulkStringMessage.getType()}"
                    )
                }

                return (key, results.toArray())
            }

            throw RedisException("Incompatible type, null arrays is not the expect type")
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class NillableTupleOfStringAndListResponseBuilder<T> <: ResponseBuilder<?(String, ArrayList<T>)> {
    public func build(message: RedisMessage): ?(String, ArrayList<T>) {
        if (let Some(message) <- (message as NullRedisMessage)) {
            return None
        }

        if (let Some(message) <- (message as ArraysRedisMessage)) {
            if (message.isNull()) {
                return None
            }
            return TupleOfStringAndListResponseBuilder<T>().build(message)
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class TupleOfStringAndTupleListResponseBuilder <: ResponseBuilder<(String, ArrayList<(String, Float64)>)> {
    public func build(message: RedisMessage): (String, ArrayList<(String, Float64)>) {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let children = message.getValue()
            if (let Some(children) <- children) {
                if (children.size != 2) {
                    throw RedisException(
                        "Incompatible type, wrong size of ArraysRedisMessage, expect 2 but ${children.size}")
                }

                var key = ""
                let bulkStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(0),
                    RedisMessageType.BULK_STRINGS
                )
                if (let Some(keyMesage) <- (bulkStringMessage as BulkStringRedisMessage)) {
                    if (let Some(content) <- keyMesage.getStringValue()) {
                        key = content
                    } else {
                        throw RedisException("Incompatible type, key is nil")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected first message's type: ${RedisMessageType.BULK_STRINGS}, but ${bulkStringMessage.getType()}"
                    )
                }

                let arrayMessage = ResponseBuilderHelper.getRedisMessageOrThrow(children.get(1), RedisMessageType.ARRAYS
                )
                let results = ResponseBuilderFactory.listOfStringDoubleTupleBuilder.build(arrayMessage)

                return (key, results)
            }

            throw RedisException("Incompatible type, null arrays is not the expect type")
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class TupleOfStringAndListResponseBuilder<T> <: ResponseBuilder<(String, ArrayList<T>)> {
    public func build(message: RedisMessage): (String, ArrayList<T>) {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let results = ArrayList<T>()
            let children = message.getValue()
            if (let Some(children) <- children) {
                if (children.size != 2) {
                    throw RedisException(
                        "Incompatible type, wrong size of ArraysRedisMessage, expect 2 but ${children.size}")
                }

                var key = ""
                let bulkStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(0),
                    RedisMessageType.BULK_STRINGS
                )
                if (let Some(keyMesage) <- (bulkStringMessage as BulkStringRedisMessage)) {
                    if (let Some(content) <- keyMesage.getStringValue()) {
                        key = content
                    } else {
                        throw RedisException("Incompatible type, key is nil")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected first message's type: ${RedisMessageType.BULK_STRINGS}, but ${bulkStringMessage.getType()}"
                    )
                }

                let arrayMessage = ResponseBuilderHelper.getRedisMessageOrThrow(children.get(1), RedisMessageType.ARRAYS
                )
                if (let Some(arrayMessage) <- (arrayMessage as ArraysRedisMessage)) {
                    let children = arrayMessage.getValue()
                    if (let Some(children) <- children) {
                        ArrayResponseBuilder.processChildren(children, results)
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected second message's type: ${RedisMessageType.ARRAYS}, but ${bulkStringMessage.getType()}"
                    )
                }

                return (key, results)
            }

            throw RedisException("Incompatible type, null arrays is not the expect type")
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class NillableTupleOfStringAndStringDoubleResponseBuilder <: ResponseBuilder<?(String, (String, Float64))> {
    public func build(message: RedisMessage): ?(String, (String, Float64)) {
        if (let Some(message) <- (message as NullRedisMessage)) {
            return None
        }

        if (let Some(message) <- (message as ArraysRedisMessage)) {
            if (message.isNull()) {
                return None
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                if (children.size != 3) {
                    throw RedisException(
                        "Incompatible type, wrong size of ArraysRedisMessage, expect 3 but ${children.size}")
                }

                var key = ""
                var bulkStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(0),
                    RedisMessageType.BULK_STRINGS
                )
                if (let Some(keyMesage) <- (bulkStringMessage as BulkStringRedisMessage)) {
                    if (let Some(content) <- keyMesage.getStringValue()) {
                        key = content
                    } else {
                        throw RedisException("Incompatible type, key is nil")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected first message's type: ${RedisMessageType.BULK_STRINGS}, but ${bulkStringMessage.getType()}"
                    )
                }

                var value1 = ""
                bulkStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(1),
                    RedisMessageType.BULK_STRINGS
                )
                if (let Some(valueMessage) <- (bulkStringMessage as BulkStringRedisMessage)) {
                    if (let Some(content) <- valueMessage.getStringValue()) {
                        value1 = content
                    } else {
                        throw RedisException("Incompatible type, value1 is nil")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected first message's type: ${RedisMessageType.BULK_STRINGS}, but ${bulkStringMessage.getType()}"
                    )
                }

                if (let Some(value) <- children.get(2)) {
                    if (let Some(value) <- (value as DoubleRedisMessage)) {
                        return (key, (value1, value.getValue()))
                    } else if (let Some(value) <- (value as BulkStringRedisMessage)) {
                        if (let Some(content) <- value.getStringValue()) {
                            return (key, (value1, Float64.parse(content)))
                        } else {
                            throw RedisException("Incompatible type, value1 is nil")
                        }
                    } else {
                        throw RedisException(
                            "Incompatible type, expected first message's type: ${RedisMessageType.BULK_STRINGS} or ${RedisMessageType.DOUBLES}, but ${bulkStringMessage.getType()}"
                        )
                    }
                }
            }
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class NillableTupleOfStringAndStringDoubleListResponseBuilder <: ResponseBuilder<?(String, ArrayList<(String, 
    Float64)>)> {
    public func build(message: RedisMessage): ?(String, ArrayList<(String, Float64)>) {
        if (let Some(message) <- (message as NullRedisMessage)) {
            return None
        }

        if (let Some(message) <- (message as ArraysRedisMessage)) {
            if (message.isNull()) {
                return None
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                if (children.size != 2) {
                    throw RedisException(
                        "Incompatible type, wrong size of ArraysRedisMessage, expect 2 but ${children.size}")
                }

                var key = ""
                let bulkStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(0),
                    RedisMessageType.BULK_STRINGS
                )
                if (let Some(keyMesage) <- (bulkStringMessage as BulkStringRedisMessage)) {
                    if (let Some(content) <- keyMesage.getStringValue()) {
                        key = content
                    } else {
                        throw RedisException("Incompatible type, key is nil")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected first message's type: ${RedisMessageType.BULK_STRINGS}, but ${bulkStringMessage.getType()}"
                    )
                }

                let arrayMessage = ResponseBuilderHelper.getRedisMessageOrThrow(children.get(1), RedisMessageType.ARRAYS
                )
                if (let Some(arrayMessage) <- (arrayMessage as ArraysRedisMessage)) {
                    let results = ResponseBuilderFactory.listOfStringDoubleTupleBuilder.build(arrayMessage)
                    return (key, results)
                } else if (let Some(message) <- (message as ErrorRedisMessage)) {
                    throw RedisException(message.getValue())
                } else {
                    throw RedisException(
                        "Incompatible type, expected second message's type: ${RedisMessageType.ARRAYS}, but ${bulkStringMessage.getType()}"
                    )
                }
            }
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class TupleOfStringAndStringPairListResponseBuilder <: ResponseBuilder<(String, ArrayList<(String, String)>)> {
    public func build(message: RedisMessage): (String, ArrayList<(String, String)>) {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let children = message.getValue()
            if (let Some(children) <- children) {
                if (children.size != 2) {
                    throw RedisException(
                        "Incompatible type, wrong size of ArraysRedisMessage, expect 2 but ${children.size}")
                }

                var key = ""
                let bulkStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(0),
                    RedisMessageType.BULK_STRINGS
                )
                if (let Some(keyMesage) <- (bulkStringMessage as BulkStringRedisMessage)) {
                    if (let Some(content) <- keyMesage.getStringValue()) {
                        key = content
                    } else {
                        throw RedisException("Incompatible type, key is nil")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected first message's type: ${RedisMessageType.BULK_STRINGS}, but ${bulkStringMessage.getType()}"
                    )
                }

                let arrayMessage = ResponseBuilderHelper.getRedisMessageOrThrow(children.get(1), RedisMessageType.ARRAYS
                )
                if (let Some(arrayMessage) <- (arrayMessage as ArraysRedisMessage)) {
                    let results = ResponseBuilderFactory.listOfStringTupleBuilder.build(arrayMessage)
                    return (key, results)
                } else if (let Some(message) <- (message as ErrorRedisMessage)) {
                    throw RedisException(message.getValue())
                } else {
                    throw RedisException(
                        "Incompatible type, expected second message's type: ${RedisMessageType.ARRAYS}, but ${bulkStringMessage.getType()}"
                    )
                }
            }

            throw RedisException("Incompatible type, null arrays is not the expect type")
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class NillableIntegerDoubleTupleResponseBuilder <: ResponseBuilder<?(Int64, Float64)> {
    public func build(message: RedisMessage): ?(Int64, Float64) {
        if (let Some(message) <- (message as NullRedisMessage)) {
            return None
        }

        if (let Some(message) <- (message as ArraysRedisMessage)) {
            if (message.isNull()) {
                return None
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                if (children.size == 0) {
                    return None
                }
                if (children.size != 2) {
                    throw RedisException(
                        "Incompatible type, wrong size of ArraysRedisMessage, expect 2 but ${children.size}")
                }

                var key = 0
                let bulkStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(0),
                    RedisMessageType.INTEGERS
                )
                if (let Some(keyMesage) <- (bulkStringMessage as IntegerRedisMessage)) {
                    key = keyMesage.getValue()
                } else {
                    throw RedisException(
                        "Incompatible type, expected first message's type: ${RedisMessageType.INTEGERS}, but ${bulkStringMessage.getType()}"
                    )
                }

                let valueDoubleMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(1),
                    RedisMessageType.DOUBLES
                )
                if (let Some(valueMessage) <- (valueDoubleMessage as DoubleRedisMessage)) {
                    return (key, valueMessage.getValue())
                } else if (let Some(valueMessage) <- (valueDoubleMessage as BulkStringRedisMessage)) {
                    if (let Some(value) <- valueMessage.getStringValue()) {
                        return (key, Float64.parse(value))
                    } else {
                        throw RedisException("Incompatible type, nil double message")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected second message's type: ${RedisMessageType.DOUBLES}, but ${valueDoubleMessage.getType()}"
                    )
                }
            }

            throw RedisException("Incompatible type, null arrays is not the expect type")
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class NillableStringDoubleTupleResponseBuilder <: ResponseBuilder<?(String, Float64)> {
    public func build(message: RedisMessage): ?(String, Float64) {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            if (message.isNull()) {
                return None
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                if (children.size == 0) {
                    return None
                }
                if (children.size != 2) {
                    throw RedisException(
                        "Incompatible type, wrong size of ArraysRedisMessage, expect 2 but ${children.size}")
                }

                var key = ""
                let bulkStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(0),
                    RedisMessageType.BULK_STRINGS
                )
                if (let Some(keyMesage) <- (bulkStringMessage as BulkStringRedisMessage)) {
                    if (let Some(content) <- keyMesage.getStringValue()) {
                        key = content
                    } else {
                        throw RedisException("Incompatible type, key is nil")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected first message's type: ${RedisMessageType.BULK_STRINGS}, but ${bulkStringMessage.getType()}"
                    )
                }

                let valueDoubleMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(1),
                    RedisMessageType.DOUBLES
                )
                if (let Some(valueMessage) <- (valueDoubleMessage as DoubleRedisMessage)) {
                    return (key, valueMessage.getValue())
                } else if (let Some(valueMessage) <- (valueDoubleMessage as BulkStringRedisMessage)) {
                    if (let Some(value) <- valueMessage.getStringValue()) {
                        return (key, Float64.parse(value))
                    } else {
                        throw RedisException("Incompatible type, nil double message")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected second message's type: ${RedisMessageType.DOUBLES}, but ${valueDoubleMessage.getType()}"
                    )
                }
            }

            throw RedisException("Incompatible type, null arrays is not the expect type")
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class StringDoubleTupleResponseBuilder <: ResponseBuilder<(String, Float64)> {
    public func build(message: RedisMessage): (String, Float64) {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let children = message.getValue()
            if (let Some(children) <- children) {
                if (children.size != 2) {
                    throw RedisException(
                        "Incompatible type, wrong size of ArraysRedisMessage, expect 2 but ${children.size}")
                }

                var key = ""
                let bulkStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(0),
                    RedisMessageType.BULK_STRINGS
                )
                if (let Some(keyMesage) <- (bulkStringMessage as BulkStringRedisMessage)) {
                    if (let Some(content) <- keyMesage.getStringValue()) {
                        key = content
                    } else {
                        throw RedisException("Incompatible type, key is nil")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected first message's type: ${RedisMessageType.BULK_STRINGS}, but ${bulkStringMessage.getType()}"
                    )
                }

                let valueDoubleMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(1),
                    RedisMessageType.DOUBLES
                )
                if (let Some(valueMessage) <- (valueDoubleMessage as DoubleRedisMessage)) {
                    return (key, valueMessage.getValue())
                } else if (let Some(valueMessage) <- (valueDoubleMessage as BulkStringRedisMessage)) {
                    if (let Some(value) <- valueMessage.getStringValue()) {
                        return (key, Float64.parse(value))
                    } else {
                        throw RedisException("Incompatible type, nil double message")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected second message's type: ${RedisMessageType.DOUBLES}, but ${valueDoubleMessage.getType()}"
                    )
                }
            }

            throw RedisException("Incompatible type, null arrays is not the expect type")
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class NillableStringTupleResponseBuilder <: ResponseBuilder<?(String, String)> {
    public func build(message: RedisMessage): ?(String, String) {
        if (let Some(message) <- (message as NullRedisMessage)) {
            return None
        }

        if (let Some(message) <- (message as ArraysRedisMessage)) {
            if (message.isNull()) {
                return None
            }

            return ResponseBuilderFactory.stringTupleBuilder.build(message)
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class StringTupleResponseBuilder <: ResponseBuilder<(String, String)> {
    public func build(message: RedisMessage): (String, String) {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let children = message.getValue()
            if (let Some(children) <- children) {
                if (children.size != 2) {
                    throw RedisException(
                        "Incompatible type, wrong size of ArraysRedisMessage, expect 2 but ${children.size}")
                }

                var key = ""
                let bulkStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(0),
                    RedisMessageType.BULK_STRINGS
                )
                if (let Some(keyMesage) <- (bulkStringMessage as BulkStringRedisMessage)) {
                    if (let Some(content) <- keyMesage.getStringValue()) {
                        key = content
                    } else {
                        throw RedisException("Incompatible type, key is nil")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected first message's type: ${RedisMessageType.BULK_STRINGS}, but ${bulkStringMessage.getType()}"
                    )
                }

                var value = ""
                let valueStringMessage = ResponseBuilderHelper.getRedisMessageOrThrow(
                    children.get(1),
                    RedisMessageType.BULK_STRINGS
                )
                if (let Some(valueMessage) <- (valueStringMessage as BulkStringRedisMessage)) {
                    if (let Some(content) <- valueMessage.getStringValue()) {
                        value = content
                    } else {
                        throw RedisException("Incompatible type, key is nil")
                    }
                } else {
                    throw RedisException(
                        "Incompatible type, expected second message's type: ${RedisMessageType.BULK_STRINGS}, but ${bulkStringMessage.getType()}"
                    )
                }

                return (key, value)
            }

            throw RedisException("Incompatible type, null arrays is not the expect type")
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, ${message.getType()} is not the expect type")
    }
}

public class ListOfStringTupleResponseBuilder <: ResponseBuilder<ArrayList<(String, String)>> {
    public func build(message: RedisMessage): ArrayList<(String, String)> {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let results = ArrayList<(String, String)>()
            if (message.isNull() || message.getSize() == 0) {
                return results
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                if (ResponseBuilderHelper.isArraysFirstElement(children)) {
                    // RESP 3
                    for (child in children) {
                        let (x, y) = ResponseBuilderFactory.stringTupleBuilder.build(child)
                        results.add((x, y))
                    }
                } else {
                    // RESP 2
                    var index = 0
                    while (index + 1 < children.size) {
                        let keyMessage = children[index]
                        let valueMessage = children[index + 1]
                        let key = ResponseBuilderHelper.unwrapToSimpleType<String>(keyMessage)
                        let value = ResponseBuilderHelper.unwrapToSimpleType<String>(valueMessage)

                        results.add((key, value))
                        index = index + 2
                    }
                }
            }

            return results
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class ListOfStringDoubleTupleResponseBuilder <: ResponseBuilder<ArrayList<(String, Float64)>> {
    public func build(message: RedisMessage): ArrayList<(String, Float64)> {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let results = ArrayList<(String, Float64)>()
            if (message.isNull() || message.getSize() == 0) {
                return results
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                if (ResponseBuilderHelper.isArraysFirstElement(children)) {
                    // RESP 3
                    for (child in children) {
                        let (x, y) = ResponseBuilderFactory.stringDoubleTupleBuilder.build(child)
                        results.add((x, y))
                    }
                } else {
                    // RESP 2
                    // Redis 6.0的返回值,Resp3缺少List,也会进入
                    var index = 0
                    while (index + 1 < children.size) {
                        let keyMessage = children[index]
                        let valueMessage = children[index + 1]
                        let key = ResponseBuilderHelper.unwrapToSimpleType<String>(keyMessage)
                        let value = ResponseBuilderHelper.unwrapToSimpleType<Float64>(valueMessage)

                        results.add((key, value))
                        index = index + 2
                    }
                }
            }

            return results
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Unsupported message type: ${message.getType()}")
    }
}

public class PrimitiveMapResponseBuilder<V> <: ResponseBuilder<HashMap<String, V>> {
    public func build(message: RedisMessage): HashMap<String, V> {
        let results = HashMap<String, V>()
        let keyValues = ResponseBuilderFactory.listOfKeyValueBuilder.build(message)
        processEntries(keyValues, results)
        return results
    }

    protected static func processEntries(children: ArrayList<KeyValueMessagePair>, results: HashMap<String, V>) {
        for (keyValue in children) {
            let keyMessage = keyValue.getKey()
            let valueMessage = keyValue.getValue()
            let key = ResponseBuilderFactory.stringBuilder.build(keyMessage)
            let value = unwrapValue(valueMessage)

            results.add(key, value)
        }
    }

    private static func unwrapValue(valueMessage: RedisMessage): V {
        if (!valueMessage.isCollection()) {
            let unwrapedValue = ResponseBuilderHelper.unwrapToSimpleType<V>(valueMessage)
            return unwrapedValue
        }

        throw RedisException("Incompatible type, ${valueMessage.getType()} is not the expect type")
    }
}

public class ListOfKeyValueResponseBuilder <: ResponseBuilder<ArrayList<KeyValueMessagePair>> {
    public func build(message: RedisMessage): ArrayList<KeyValueMessagePair> {
        if (let Some(message) <- (message as ArraysRedisMessage)) {
            let keyValueMessages = ArrayList<KeyValueMessagePair>()
            if (message.isNull() || message.getSize() == 0) {
                return keyValueMessages
            }

            let children = message.getValue()
            if (let Some(children) <- children) {
                if (children.size % 2 != 0) {
                    throw RedisException(
                        "Incompatible type, could not convert to map from list which has odd number entries")
                }

                var index = 0
                while (index + 1 < children.size) {
                    let keyMessage = children[index]
                    let valueMessage = children[index + 1]
                    let keyValueMessage = KeyValueMessagePair(keyMessage, valueMessage)
                    keyValueMessages.add(keyValueMessage)
                    index = index + 2
                }
            }

            return keyValueMessages
        } else if (let Some(mapMessage) <- (message as MapRedisMessage)) {
            return mapMessage.getValue()
        } else if (let Some(message) <- (message as ErrorRedisMessage)) {
            throw RedisException(message.getValue())
        }

        throw RedisException("Incompatible type, could not convert ${message.getType()} to map")
    }
}

public class ResponseBuilderFactory {
    public static let stringBuilder = StringResponseBuilder()
    public static let objectBuilder = AggressiveObjectObjectBuilder()
    public static let byteArrayBuilder = ByteArrayResponseBuilder()
    public static let nillableStringBuilder = NillableStringResponseBuilder()
    public static let nillableByteArrayBuilder = NillableByteArrayResponseBuilder()
    public static let integerBuilder = IntegerResponseBuilder()
    public static let nillableIntegerBuilder = NillableIntegerResponseBuilder()
    public static let nillableDoubleBuilder = NillableDoubleResponseBuilder()
    public static let doubleBuilder = DoubleResponseBuilder()
    public static let boolBuilder = BoolResponseBuilder()
    public static let arrayOfNillableStringBuilder = ArrayOfNillableResponseBuilder<String>()
    public static let setOfStringBuilder = SetOfResponseBuilder<String>()
    public static let listOfStringBuilder = ListResponseBuilder<String>()
    public static let listOfIntegerBuilder = ListResponseBuilder<Int64>()
    public static let listOfDoubleBuilder = ListResponseBuilder<Float64>()
    public static let listOfBoolBuilder = ListOfBoolBuilder()
    public static let nillableListOfIntegerBuilder = NillableListResponseBuilder<Int64>()
    public static let nillableListOfStringBuilder = NillableListResponseBuilder<String>()
    public static let listOfNillableStringBuilder = ListOfNillableResponseBuilder<String>()
    public static let listOfNillableIntegerBuilder = ListOfNillableResponseBuilder<Int64>()
    public static let listOfNillableDoubleBuilder = ListOfNillableResponseBuilder<Float64>()
    public static let tupleOfStringAndListResponseBuilder = TupleOfStringAndListResponseBuilder<String>()
    public static let tupleOfStringAndTupleListResponseBuilder = TupleOfStringAndTupleListResponseBuilder()
    public static let nillableTupleOfStringAndListResponseBuilder = NillableTupleOfStringAndListResponseBuilder<String>(
    )
    public static let tupleOfStringAndStringPairListBuilder = TupleOfStringAndStringPairListResponseBuilder()
    public static let nillableTupleOfStringAndStringDoubleListBuilder = NillableTupleOfStringAndStringDoubleListResponseBuilder(
    )
    public static let nillableTupleOfStringAndStringDoubleBuilder = NillableTupleOfStringAndStringDoubleResponseBuilder(
    )
    public static let stringTupleBuilder = StringTupleResponseBuilder()
    public static let nillableStringTupleBuilder = NillableStringTupleResponseBuilder()
    public static let stringDoubleTupleBuilder = StringDoubleTupleResponseBuilder()
    public static let nillableStringDoubleTupleBuilder = NillableStringDoubleTupleResponseBuilder()
    public static let nillableIntegerDoubleTupleBuilder = NillableIntegerDoubleTupleResponseBuilder()
    public static let listOfStringTupleBuilder = ListOfStringTupleResponseBuilder()
    public static let listOfStringDoubleTupleBuilder = ListOfStringDoubleTupleResponseBuilder()
    public static let stringToStringMapBuilder = PrimitiveMapResponseBuilder<String>()
    public static let stringToIntegerMapBuilder = PrimitiveMapResponseBuilder<Int64>()
    public static let listOfKeyValueBuilder = ListOfKeyValueResponseBuilder()
    public static let listOfAnyBuilder = ListOfAnyResponseBuilder()
    public static let mapOfAnyBuilder = MapOfAnyResponseBuilder()
    public static let mapOfNillableAnyBuilder = MapOfNillableAnyResponseBuilder()
    public static let jsonRespBuilder = JsonRespBuilder()
}