package io.vertx.codetrans;

import com.sun.source.tree.LambdaExpressionTree;
import io.vertx.codegen.type.ApiTypeInfo;
import io.vertx.codegen.type.ClassTypeInfo;
import io.vertx.codegen.type.EnumTypeInfo;
import io.vertx.codegen.type.ParameterizedTypeInfo;
import io.vertx.codegen.type.TypeInfo;
import io.vertx.codetrans.expression.ApiModel;
import io.vertx.codetrans.expression.ApiTypeModel;
import io.vertx.codetrans.expression.AsyncResultModel;
import io.vertx.codetrans.expression.BinaryExpressionModel;
import io.vertx.codetrans.expression.DataObjectClassModel;
import io.vertx.codetrans.expression.EnumExpressionModel;
import io.vertx.codetrans.expression.EnumFieldExpressionModel;
import io.vertx.codetrans.expression.ExpressionModel;
import io.vertx.codetrans.expression.JsonArrayClassModel;
import io.vertx.codetrans.expression.JsonObjectClassModel;
import io.vertx.codetrans.expression.StringLiteralModel;
import io.vertx.codetrans.expression.VariableScope;
import io.vertx.codetrans.expression.IdentifierModel;
import io.vertx.codetrans.expression.ThisModel;
import io.vertx.codetrans.statement.StatementModel;

import java.util.function.Consumer;

Author:Julien Viet
/** * @author <a href="mailto:julien@julienviet.com">Julien Viet</a> */
public interface CodeBuilder { CodeWriter newWriter(); String render(RunnableCompilationUnit unit, RenderMode renderMode); default ExpressionModel combine(ExpressionModel left, String op, ExpressionModel right) { return new BinaryExpressionModel(this, left, op, right); } default ExpressionModel asyncResult(String identifier, TypeInfo type) { return new AsyncResultModel(this, identifier, type); } ExpressionModel asyncResultHandler(LambdaExpressionTree.BodyKind bodyKind, ParameterizedTypeInfo resultType, String resultName, CodeModel body, CodeModel succeededBody, CodeModel failedBody); default DataObjectClassModel dataObjectClass(ClassTypeInfo type) { return new DataObjectClassModel(this, type); } default ApiTypeModel apiType(ApiTypeInfo type) { return new ApiTypeModel(this, type); } default ApiModel api(ExpressionModel expr) { return new ApiModel(this, expr); } default EnumExpressionModel enumType(EnumTypeInfo type) { return new EnumExpressionModel(this, type); } default ExpressionModel toDataObjectValue(EnumFieldExpressionModel enumField) { return enumField; } default ExpressionModel identifier(String name, VariableScope scope) { return new IdentifierModel(this, name, scope); } StatementModel variableDecl(VariableScope scope, TypeInfo type, String name, ExpressionModel initializer); StatementModel enhancedForLoop(String variableName, ExpressionModel expression, StatementModel body); StatementModel forLoop(StatementModel initializer, ExpressionModel condition, ExpressionModel update, StatementModel body); StatementModel sequenceForLoop(String variableName, ExpressionModel fromValue, ExpressionModel toValue, StatementModel body); default JsonObjectClassModel jsonObjectClassModel() { return new JsonObjectClassModel(this); } default JsonArrayClassModel jsonArrayClassModel() { return new JsonArrayClassModel(this); } default ExpressionModel jsonArrayEncoder(ExpressionModel expression) { return render(writer -> { writer.renderJsonArrayToString(expression); }); } default ExpressionModel jsonObjectEncoder(ExpressionModel expression) { return render(writer -> { writer.renderJsonObjectToString(expression); }); } // default ExpressionModel thisModel() { return new ThisModel(this); } default ExpressionModel forConditionalExpression(ExpressionModel condition, ExpressionModel trueExpression, ExpressionModel falseExpression) { return render((renderer) -> { renderer.renderConditionalExpression(condition, trueExpression, falseExpression); }); } default ExpressionModel forAssign(ExpressionModel variable, ExpressionModel expression) { return render((renderer) -> { renderer.renderAssign(variable, expression); }); } default ExpressionModel render(Consumer<CodeWriter> c) { CodeBuilder builder = this; return new ExpressionModel(builder) { @Override public void render(CodeWriter writer) { c.accept(writer); } }; } }