private String toLiteralTermExpression(Field field, TypeReference resultType, Literal literal, Function<VariableLiteral, String> variableExpressionGenerator, Tracer tracer) {
        tracer = tracer.dive("literal term instanceOf");
        if (literal instanceof NullLiteral) {
            tracer = tracer.dive("null literal instanceOf");
            return tracer + "null";
        } else if (literal instanceof BooleanLiteral) {
            tracer = tracer.dive("boolean literal instanceOf");
            return tracer + Boolean.toString(((BooleanLiteral) literal).getValue());
        } else if (literal instanceof NumericLiteral) {
            tracer = tracer.dive("numeric literal instanceOf");
            final String numberString = ((NumericLiteral) literal).getNumber().toString();
            if (resultType.isIntegerTypeReference()) {
                final IntegerTypeReference integerTypeReference = resultType.asIntegerTypeReference().orElseThrow(FreemarkerException::new);
                if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT && integerTypeReference.getSizeInBits() >= 32) {
                    tracer = tracer.dive("uint >= 32bit");
                    return tracer + numberString + "L";
                } else if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
                    tracer = tracer.dive("int > 32bit");
                    return tracer + numberString + "L";
                }
            } else if (resultType.isFloatTypeReference()) {
                final FloatTypeReference floatTypeReference = resultType.asFloatTypeReference().orElseThrow(FreemarkerException::new);
                if (floatTypeReference.getSizeInBits() <= 32) {
                    tracer = tracer.dive("float < 32bit");
                    return tracer + numberString + "F";
                }
            }
            return tracer + numberString;
        } else if (literal instanceof HexadecimalLiteral) {
            tracer = tracer.dive("hexadecimal literal instanceOf");
            final String hexString = ((HexadecimalLiteral) literal).getHexString();
            if (resultType.isIntegerTypeReference()) {
                final IntegerTypeReference integerTypeReference = resultType.asIntegerTypeReference().orElseThrow(FreemarkerException::new);
                if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT && integerTypeReference.getSizeInBits() >= 32) {
                    tracer = tracer.dive("uint >= 32bit");
                    return tracer + hexString + "L";
                } else if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
                    tracer = tracer.dive("int > 32bit");
                    return tracer + hexString + "L";
                }
            }
            return tracer + hexString;
        } else if (literal instanceof StringLiteral) {
            tracer = tracer.dive("string literal instanceOf");
            return tracer + "\"" + ((StringLiteral) literal).getValue() + "\"";
        } else if (literal instanceof VariableLiteral) {
            tracer = tracer.dive("variable literal instanceOf");
            VariableLiteral variableLiteral = (VariableLiteral) literal;
            if ("curPos".equals(((VariableLiteral) literal).getName())) {
                return "(readBuffer.getPos() - startPos)";
            }
            // If this literal references an Enum type, then we have to output it differently.
            if (getTypeDefinitions().get(variableLiteral.getName()) instanceof EnumTypeDefinition) {
                tracer = tracer.dive("enum definition instanceOf");
                VariableLiteral enumDefinitionChild = variableLiteral.getChild()
                    .orElseThrow(() -> new FreemarkerException("enum definitions should have childs"));
                return tracer + variableLiteral.getName() + "." + enumDefinitionChild.getName() +
                    enumDefinitionChild.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
            } else {
                return tracer + variableExpressionGenerator.apply(variableLiteral);
            }
        } else {
            throw new FreemarkerException("Unsupported Literal type " + literal.getClass().getName());
        }
    }
@param field               this generally only is needed in order to access field attributes such as encoding etc.
@param resultType          the type the resulting expression should have
@param term                the term representing the expression
@param serializerArguments any serializer arguments, which could be referenced in expressions (Needed for getting the type)
@return Java code which does the things defined in 'term'
code-generation/language-cs/src/main/java/org/apache/plc4x/language/cs/CsLanguageTemplateHelper.java