func (protocol *HumanReadableJsonProtocol) parseStruct(fieldsList Array, request interface{}) error {
	if object, ok := toJsonCheck(request); ok {
		// fmt.Println("ReadStructBegin", object)
		for key, value := range object {
			// fmt.Println("ReadFieldBegin")

			// Get the information of the field (type, name, etc)
			fieldInfo := fieldsList.findInJsonArray(nameKey, key)
			if fieldInfo == nil {
				// Field doesn't exist
				return errors.New("Unexpected key " + key)
			}

			// Get the Thrift Type of the field
			fieldType, err := protocol.StringToTypeId(fieldInfo.getStringVal(typeIdKey))
			if err != nil {
				return err
			}

			// Add the name, type and key (1:, 2:, 3:, etc) to params
			protocol.add(key, fieldType, fieldInfo.getDefaultInt16Val(keyKey, 0))

			// fmt.Println(key, fieldType, fieldInfo.GetInt16Val(keyKey))

			// Recursively parse the field
			err = protocol.parse(fieldInfo, value, typeIdKey, typeKey)
			if err != nil {
				return err
			}
			// fmt.Println("ReadFieldEnd")
		}

		// Finish parsing struct
		protocol.add("", thrift.TType(thrift.STOP), int16(-1))
		// fmt.Println("ReadStructEnd")
		return nil
	} else {
		return errors.New(fmt.Sprintf("Expected Json Object got %t", request))
	}
}
func (protocol *HumanReadableJsonProtocol) StringToTypeId(fieldType string) (thrift.TType, error) {
	switch fieldType {
	case "bool":
		return thrift.TType(thrift.BOOL), nil
	case "i8":
		return thrift.TType(thrift.BYTE), nil
	case "i16":
		return thrift.TType(thrift.I16), nil
	case "i32":
		return thrift.TType(thrift.I32), nil
	case "i64":
		return thrift.TType(thrift.I64), nil
	case "double":
		return thrift.TType(thrift.DOUBLE), nil
	case "string":
		return thrift.TType(thrift.STRING), nil
	case "struct", "union", "exception":
		return thrift.TType(thrift.STRUCT), nil
	case "map":
		return thrift.TType(thrift.MAP), nil
	case "set":
		return thrift.TType(thrift.SET), nil
	case "list":
		return thrift.TType(thrift.LIST), nil
	}

	e := fmt.Errorf("Unknown type identifier: %s", fieldType)
	return thrift.TType(thrift.STOP), thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, e)
}
func (protocol *HumanReadableJsonProtocol) ReadMessageBegin() (string, thrift.TMessageType, int32, error) {
	// Read all data and parse out the JSON object
	var data []byte
	data, err := ioutil.ReadAll(protocol.trans)
	if err != nil && err != io.EOF && err.Error() != "EOF" { // Uggh thrift wraps it inside its own error
		return "", thrift.INVALID_TMESSAGE_TYPE, 0, thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, err)
	}

	protocol.request, err = NewJson(data)
	if err != nil {
		return "", thrift.INVALID_TMESSAGE_TYPE, 0, thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, err)
	}

	// Get the method info corresponding to method being called
	name := protocol.request.getDefaultStringVal(methodKey, "")
	methodInfo, methodInfoErr := protocol.getMethodInfo(protocol.service, name)
	// Type Id tells whether it is a request (CALL) or response (REPLY) or error (EXCEPTION)
	// Seq Id == 0 for CALL and 1 for REPLY, EXCEPTION always
	typeId, seqId := protocol.getMessageTypeAndSeq(methodInfo)

	if protocol.request.hasKey(argumentsKey) {
		/** CALL */

		if methodInfoErr != nil {
			// Method not found, STOP processing and send back up,
			// Generated code will send an error saying "Unknown function"
			protocol.add("", thrift.TType(thrift.STOP), int16(-1))
			return name, typeId, seqId, nil
		}

		// Parse out the arguments struct
		// Send it the arguments struct in both the method metadata and the request
		protocol.err = protocol.parseStruct(methodInfo.getArrayVal(argumentsKey), protocol.request.getJsonVal(argumentsKey))
	} else if protocol.request.hasKey(resultKey) {
		/** REPLY */

		if methodInfoErr != nil {
			// Method not found, STOP processing and send back up,
			// Generated code will send an error saying "Unknown function"
			protocol.add("", thrift.TType(thrift.STOP), int16(-1))
			return name, typeId, seqId, nil
		}

		result := protocol.request.getJsonVal(resultKey)

		// The result will either have "success" or the name of the error that was thrown
		if result.hasKey(successKey) {
			// Figure out the return type
			returnType, err := protocol.StringToTypeId(methodInfo.getStringVal(returnTypeIdKey))
			if err != nil {
				protocol.err = err
			} else {
				// Add a field with the returnType
				protocol.add("", returnType, int16(0))
				// Parse the result
				protocol.err = protocol.parse(methodInfo, result[successKey], returnTypeIdKey, returnTypeKey)
				// Finish parsing
				protocol.add("", thrift.TType(thrift.STOP), int16(-1))
			}
		} else if len(result) == 0 {
			// There was nothing in result. The return type is void
			protocol.add("", thrift.TType(thrift.STOP), int16(-1))
		} else {
			// There was an error, get the error variable name
			var errName string
			for key, _ := range result {
				errName = key
				break
			}

			errInfo := methodInfo.getArrayVal(exceptionsKey).findInJsonArray(nameKey, errName)
			if errInfo == nil {
				// Error doesn't exist in the Thrift definition
				return "", thrift.INVALID_TMESSAGE_TYPE, 0, thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, errors.New("Unable to parse result"))
			}
			// Begin Parsing Error (which is just a struct)
			protocol.add(errName, thrift.TType(thrift.STRUCT), errInfo.getDefaultInt16Val(keyKey, 1))
			// Parse Error
			protocol.err = protocol.parse(errInfo, result.getJsonVal(errName), typeIdKey, typeKey)
			// Finish Parsing error
			protocol.add("", thrift.TType(thrift.STOP), int16(-1))
		}

	} else if protocol.request.hasKey(exceptionKey) {
		// Error other than one defined in the method signature. It will have a string and an int32
		// Add String field
		protocol.add("", thrift.TType(thrift.STRING), int16(1))
		// Parse string
		protocol.add(protocol.request.getJsonVal(exceptionKey).getDefaultStringVal(messageKey, ""))
		// Add int32
		protocol.add("", thrift.TType(thrift.I32), int16(2))
		// Parse int32
		protocol.add(protocol.request.getJsonVal(exceptionKey).getDefaultInt32Val(typeKey, thrift.UNKNOWN_APPLICATION_EXCEPTION))
		// Finish Parsing
		protocol.add("", thrift.TType(thrift.STOP), int16(-1))

	} else {
		// Don't recognize what kind of message this is
		return "", thrift.INVALID_TMESSAGE_TYPE, 0, thrift.NewTProtocolExceptionWithType(thrift.INVALID_MESSAGE_TYPE_EXCEPTION, errors.New("Invalid type"))
	}

	// fmt.Println(protocol.params)

	return name, typeId, seqId, nil
}