package p.studio.compiler.pbs.semantics;

import p.studio.compiler.pbs.semantics.PbsFlowSemanticSupport.ExprUse;
import p.studio.compiler.pbs.semantics.PbsFlowSemanticSupport.Model;
import p.studio.compiler.pbs.semantics.PbsFlowSemanticSupport.Scope;
import p.studio.compiler.pbs.semantics.PbsFlowSemanticSupport.TypeView;
import p.studio.compiler.source.diagnostics.DiagnosticSink;

final class PbsFlowExpressionContext {
    private final Scope scope;
    private final TypeView expectedType;
    private final TypeView returnType;
    private final String resultErrorName;
    private final TypeView receiverType;
    private final Model model;
    private final DiagnosticSink diagnostics;
    private final ExprUse use;
    private final boolean valueContext;
    private final PbsFlowExpressionAnalyzer.BlockAnalyzer blockAnalyzer;

    PbsFlowExpressionContext(
            final Scope scope,
            final TypeView expectedType,
            final TypeView returnType,
            final String resultErrorName,
            final TypeView receiverType,
            final Model model,
            final DiagnosticSink diagnostics,
            final ExprUse use,
            final boolean valueContext,
            final PbsFlowExpressionAnalyzer.BlockAnalyzer blockAnalyzer) {
        this.scope = scope;
        this.expectedType = expectedType;
        this.returnType = returnType;
        this.resultErrorName = resultErrorName;
        this.receiverType = receiverType;
        this.model = model;
        this.diagnostics = diagnostics;
        this.use = use;
        this.valueContext = valueContext;
        this.blockAnalyzer = blockAnalyzer;
    }

    Scope scope() {
        return scope;
    }

    TypeView expectedType() {
        return expectedType;
    }

    TypeView returnType() {
        return returnType;
    }

    String resultErrorName() {
        return resultErrorName;
    }

    TypeView receiverType() {
        return receiverType;
    }

    Model model() {
        return model;
    }

    DiagnosticSink diagnostics() {
        return diagnostics;
    }

    ExprUse use() {
        return use;
    }

    boolean valueContext() {
        return valueContext;
    }

    PbsFlowExpressionAnalyzer.BlockAnalyzer blockAnalyzer() {
        return blockAnalyzer;
    }

    PbsFlowExpressionContext withExpectedType(final TypeView nextExpectedType) {
        return new PbsFlowExpressionContext(
                scope,
                nextExpectedType,
                returnType,
                resultErrorName,
                receiverType,
                model,
                diagnostics,
                use,
                valueContext,
                blockAnalyzer);
    }

    PbsFlowExpressionContext withUse(final ExprUse nextUse) {
        return new PbsFlowExpressionContext(
                scope,
                expectedType,
                returnType,
                resultErrorName,
                receiverType,
                model,
                diagnostics,
                nextUse,
                valueContext,
                blockAnalyzer);
    }

    PbsFlowExpressionContext withValueContext(final boolean nextValueContext) {
        return new PbsFlowExpressionContext(
                scope,
                expectedType,
                returnType,
                resultErrorName,
                receiverType,
                model,
                diagnostics,
                use,
                nextValueContext,
                blockAnalyzer);
    }
}
