func (protoParser *ProtoParser) popVariableCall(framework FrameworkStatement, prefix string) (string, error) {
	var buffer bytes.Buffer
	if len(framework.unNamedAttributes) != 1 {
		errMessage := fmt.Sprintf("Unexpected error in function pop")
		return "", protoParser.NewProtoError(errMessage, framework.pos)
	}
	buffer.WriteString("$" + framework.unNamedAttributes[0].lit + "\n")
	return buffer.String(), nil
}
popVariable generate WarpScript line for a Native Variable statement
package tsl
import (
	"bytes"
	"fmt"
	"strings"
)
const (
	sampleAggregator = "mean"
	sampleAuto       = "30"
	sampleShiftSpan  = "0"
)
var toWarpScript = [...]string{
	RENAME:           "RENAME",
	RENAMEBY:         "RENAME",
	SETLABELFROMNAME: "RENAME",
	SHIFT:            "TIMESHIFT",
	SHRINK:           "SHRINK",
	TIMESCALE:        "TIMESCALE",
	TIMECLIP:         "TIMECLIP",
	TIMEMODULO:       "TIMEMODULO FLATTEN",
	TIMESPLIT:        "TIMESPLIT FLATTEN",
	STORE:            "UPDATE",
	RESETS:           "FALSE RESETS",
	DAY:              "'UTC' mapper.day",
	MINUTE:           "'UTC' mapper.minute",
	HOUR:             "'UTC' mapper.hour",
	MONTH:            "'UTC' mapper.month",
	WEEKDAY:          "'UTC' mapper.weekday",
	MAXWITH:          "mapper.max.x",
	MINWITH:          "mapper.min.x",
	YEAR:             "'UTC' mapper.year",
	STDDEV:           "TRUE mapper.sd",
	STDVAR:           "TRUE mapper.var",
	TIMESTAMP:        "mapper.tick",
	LN:               "e mapper.log",
	LOG2:             "2 mapper.log",
	LOG10:            "10 mapper.log",
	LOGN:             "mapper.log",
	BOTTOMNBY:        "SORTBY",
	SORTBY:           "SORTBY",
	SORTDESCBY:       "SORTBY REVERSE",
	TOPNBY:           "SORTBY REVERSE",
	BOTTOMN:          "SORTBY",
	SORT:             "SORTBY",
	SORTDESC:         "SORTBY REVERSE",
	TOPN:             "SORTBY REVERSE",
	EQUAL:            "eq",
	GREATEROREQUAL:   "ge",
	GREATERTHAN:      "gt",
	LESSOREQUAL:      "le",
	LESSTHAN:         "lt",
	NOTEQUAL:         "ne",
	MEAN:             "mean",
}
func (protoParser *ProtoParser) GenerateWarpScript(instructions []Instruction, allowAuthenticate bool) (string, error) {
	var buffer bytes.Buffer
	buffer.WriteString("NOW 'now' STORE\n")
	buffer.WriteString("\n")
	if allowAuthenticate {
		for _, instruction := range instructions {
			if instruction.hasSelect && instruction.connectStatement.token != "" {
				buffer.WriteString("'" + instruction.connectStatement.token + "' AUTHENTICATE")
				buffer.WriteString("\n")
				buffer.WriteString("'stack.maxops.hard' STACKATTRIBUTE DUP <% ISNULL ! %> <% MAXOPS %> <% DROP %> IFTE")
				buffer.WriteString("\n")
				buffer.WriteString("'fetch.limit.hard' STACKATTRIBUTE DUP <% ISNULL ! %> <% LIMIT %> <% DROP %> IFTE")
				buffer.WriteString("\n")
				break
			}
		}
	}
	for _, instruction := range instructions {
		warpScript, err := protoParser.processWarpScriptInstruction(instruction, "")
		if err != nil {
			return "", err
		}
		buffer.WriteString(warpScript)
		buffer.WriteString("\n")
	}
	return buffer.String(), nil
}
func (protoParser *ProtoParser) processWarpScriptInstruction(instruction Instruction, prefix string) (string, error) {
	var buffer bytes.Buffer
	if instruction.isMeta && !(instruction.hasSelect && instruction.selectStatement.isVariable) {
		val, err := protoParser.getMeta(instruction.selectStatement, instruction.connectStatement.token)
		if err != nil {
			return "", err
		}
		return val, nil
	}
	if instruction.hasSelect {
		buffer.WriteString(prefix)
		if len(instruction.createStatement.createSeries) > 0 {
			create, err := protoParser.getCreateSeries(instruction.createStatement, prefix)
			if err != nil {
				return "", nil
			}
			buffer.WriteString(create)
		} else {
			if instruction.selectStatement.isVariable {
				buffer.WriteString("")
			} else {
				fetch, err := protoParser.getFetch(instruction.selectStatement, instruction.connectStatement.token, prefix)
				if err != nil {
					return "", nil
				}
				buffer.WriteString(fetch)
			}
		}
		buffer.WriteString("\n")
		op, err := protoParser.getFrameworksOp(instruction.selectStatement, prefix)
		if err != nil {
			return "", err
		}
		buffer.WriteString(op)
	} else if instruction.isGlobalOperator {
		gOp, err := protoParser.writeGlobalOperators(instruction.globalOperator, prefix, instruction.selectStatement)
		if err != nil {
			return "", err
		}
		buffer.WriteString(gOp)
	}
	return buffer.String(), nil
}
func (protoParser *ProtoParser) writeGlobalOperators(gOp GlobalOperator, prefix string, selectStatement SelectStatement) (string, error) {
	var buffer bytes.Buffer
	buffer.WriteString(prefix)
	if gOp.group.lit != "" {
		message := "TSL doesn't allow " + gOp.group.tokenType.String() + "methods"
		return "", protoParser.NewProtoError(message, gOp.pos)
	}
	if gOp.isIgnoring {
		buffer.WriteString("[] 'operatorLabels' STORE\n")
		buffer.WriteString(prefix)
	}
	buffer.WriteString("[ \n")
	for _, gOpInstruction := range gOp.instructions {
		warpScript, err := protoParser.processWarpScriptInstruction(*gOpInstruction, prefix+"  ")
		if err != nil {
			return "", err
		}
		buffer.WriteString(warpScript)
		if gOp.isIgnoring {
			buffer.WriteString(prefix + "  ")
			buffer.WriteString("DUP  <% DROP LABELS KEYLIST %> LMAP $operatorLabels APPEND 'operatorLabels' STORE\n")
		}
	}
	if gOp.isIgnoring {
		buffer.WriteString(prefix + "  ")
		buffer.WriteString("$operatorLabels FLATTEN UNIQUE \n")
		if len(gOp.ignoring) > 0 {
			labelsIgnoring := protoParser.getLabelsListString(gOp.ignoring)
			buffer.WriteString(prefix + "  ")
			buffer.WriteString("->SET ")
			buffer.WriteString(labelsIgnoring)
			buffer.WriteString(" ->SET DIFFERENCE SET-> \n")
		}
	} else {
		buffer.WriteString(prefix + "  ")
		labels := protoParser.getLabelsListString(gOp.labels)
		buffer.WriteString(labels + " \n")
	}
	buffer.WriteString(prefix + "  ")
	operator := "op."
	switch gOp.operator {
	case EQUAL, GREATEROREQUAL, GREATERTHAN, LESSOREQUAL, LESSTHAN, NOTEQUAL:
		operator += toWarpScript[gOp.operator]
	default:
		operator += gOp.operator.String()
	}
	buffer.WriteString(operator + " \n")
	buffer.WriteString(prefix)
	buffer.WriteString("] \n")
	buffer.WriteString(prefix)
	buffer.WriteString("APPLY \n")
	op, err := protoParser.getFrameworksOp(selectStatement, prefix)
	if err != nil {
		return "", err
	}
	buffer.WriteString(op)
	return buffer.String(), nil
}
func (protoParser *ProtoParser) getFrameworksOp(selectStatement SelectStatement, prefix string) (string, error) {
	var buffer bytes.Buffer
	var sampleSpan string
	for _, framework := range selectStatement.frameworks {
		buffer.WriteString(prefix)
		switch framework.operator {
		case SAMPLEBY, SAMPLE:
			var bucketize string
			var err error
			bucketize, sampleSpan, err = protoParser.getBucketize(selectStatement, framework, prefix)
			if err != nil {
				return "", err
			}
			buffer.WriteString(bucketize)
			buffer.WriteString("\n")
		case ABS, ADDSERIES, ANDL, CEIL, COUNT, DAY, DELTA, DIVSERIES, EQUAL, FLOOR, GREATERTHAN, GREATEROREQUAL, LESSTHAN, LESSOREQUAL,
			LN, LOG2, LOG10, LOGN, HOUR, MAX, MAXWITH, MEAN, MEDIAN, MIN, MINWITH, MINUTE, MONTH, MULSERIES, NOTEQUAL, ORL, RATE, STDDEV, STDVAR, SUBSERIES,
			ROUND, SQRT, SUM, TIMESTAMP, WEEKDAY, YEAR, JOIN, PERCENTILE, CUMULATIVE, WINDOW, FINITE, TOBOOLEAN, TODOUBLE, TOLONG, TOSTRING:
			buffer.WriteString(protoParser.getMapper(framework, sampleSpan))
			buffer.WriteString("\n")
		case NATIVEVARIABLE:
			pop, err := protoParser.popVariableCall(framework, prefix)
			if err != nil {
				return "", err
			}
			buffer.WriteString(pop)
			buffer.WriteString("\n")
		case QUANTIZE:
			quantize, err := protoParser.quantize(framework, prefix)
			if err != nil {
				return "", err
			}
			buffer.WriteString(quantize)
			buffer.WriteString("\n")
		case SHIFT, RESETS, TIMESCALE, TIMECLIP, TIMEMODULO, TIMESPLIT, SHRINK:
			buffer.WriteString(protoParser.operators(framework))
			buffer.WriteString("\n")
		case KEEPLASTVALUES, KEEPFIRSTVALUES:
			keepValues, err := protoParser.parseKeepValues(framework)
			if err != nil {
				return "", err
			}
			buffer.WriteString(keepValues)
			buffer.WriteString("\n")
		case RENAME, STORE:
			buffer.WriteString(protoParser.nValuesOperators(framework))
			buffer.WriteString("\n")
		case RENAMETEMPLATE:
			renameTemplate, err := protoParser.renameTemplate(framework)
			if err != nil {
				return "", err
			}
			buffer.WriteString(renameTemplate)
			buffer.WriteString("\n")
		case FILTERBYLABELS, FILTERBYNAME, FILTERBYLASTVALUE:
			filter, err := protoParser.filterWarpScript(framework)
			if err != nil {
				return "", err
			}
			buffer.WriteString(filter)
			buffer.WriteString("\n")
		case FILTERWITHOUTLABELS:
			filter, err := protoParser.filterWithoutLabelsWarpScript(framework)
			if err != nil {
				return "", err
			}
			buffer.WriteString(filter)
			buffer.WriteString("\n")
		case ADDNAMESUFFIX:
			framework.operator = RENAME
			value := framework.unNamedAttributes[0]
			if value.tokenType == NATIVEVARIABLE {
				value.lit = value.lit + " '%2B' SWAP + "
			} else {
				value.lit = "%2B" + value.lit
			}
			framework.unNamedAttributes[0] = value
			buffer.WriteString(protoParser.nValuesOperators(framework))
			buffer.WriteString("\n")
		case ADDNAMEPREFIX:
			name, err := protoParser.addNamePrefix(framework)
			if err != nil {
				return "", err
			}
			buffer.WriteString(name)
			buffer.WriteString("\n")
		case SETLABELFROMNAME:
			rename, err := protoParser.setLabelFromName(framework)
			if err != nil {
				return "", err
			}
			buffer.WriteString(rename)
			buffer.WriteString("\n")
		case RENAMEBY:
			rename, err := protoParser.renameBy(framework)
			if err != nil {
				return "", err
			}
			buffer.WriteString(rename)
			buffer.WriteString("\n")
		case REMOVELABELS:
			remove, err := protoParser.removeLabels(framework)
			if err != nil {
				return "", err
			}
			buffer.WriteString(remove)
			buffer.WriteString("\n")
		case RENAMELABELKEY:
			rename, err := protoParser.renameLabelKey(framework)
			if err != nil {
				return "", err
			}
			buffer.WriteString(rename)
			buffer.WriteString("\n")
		case RENAMELABELVALUE:
			rename, err := protoParser.renameLabelValue(framework)
			if err != nil {
				return "", err
			}
			buffer.WriteString(rename)
			buffer.WriteString("\n")
		case CUMULATIVESUM:
			framework.attributes[MapperPre] = InternalField{lit: "max.tick.sliding.window", tokenType: INTEGER}
			framework.attributes[MapperPost] = InternalField{lit: "0", tokenType: INTEGER}
			framework.operator = SUM
			buffer.WriteString(protoParser.getMapper(framework, sampleSpan))
			buffer.WriteString("\n")
		case BOTTOMNBY, SORTBY, SORTDESCBY, TOPNBY, BOTTOMN, SORT, SORTDESC, TOPN:
			opBy, err := protoParser.operatorBy(framework, true)
			if err != nil {
				return "", err
			}
			buffer.WriteString(opBy)
			buffer.WriteString("\n")
		case GROUPBY, GROUP, GROUPWITHOUT:
			buffer.WriteString(protoParser.getReducer(framework, prefix))
			buffer.WriteString("\n")
		}
	}
	return buffer.String(), nil
}