public String parse(Function<String, String> propertyMapping) {
        init();
        boolean inPrepare = false;

        char[] expression = new char[128];
        int expressionPos = 0;

        while (next()) {
            if (isPrepare()) {
                inPrepare = true;
            } else if (inPrepare && isPrepareEnd()) {
                inPrepare = false;
                setParsed(propertyMapping.apply(new String(expression, 0, expressionPos)).toCharArray());
                expressionPos = 0;
            } else if (inPrepare) {
                if (expression.length <= expressionPos) {
                    expression = Arrays.copyOf(expression, (int)(expression.length * 1.5));
                }
                expression[expressionPos++] = symbol;
            } else if (!isPreparing()) {
                setParsed(symbol);
            }
        }

        if (isPrepareEnd() && expressionPos > 0) {
            setParsed(propertyMapping.apply(new String(expression, 0, expressionPos)).toCharArray());
        } else {
            setParsed(symbol);
        }

        return new String(newArr, 0, len);
    }
@Test
    public void testLarge() {
        String str = "";
        for (int i = 0; i < 1000; i++) {
            str += "test-" + i;
        }
        String result = TemplateParser.parse("test-${name}", Collections.singletonMap("name", str));

        Assert.assertEquals(result, "test-" + str);
    }