001///////////////////////////////////////////////////////////////////////////////////////////////
002// checkstyle: Checks Java source code and other text files for adherence to a set of rules.
003// Copyright (C) 2001-2026 the original author or authors.
004//
005// This library is free software; you can redistribute it and/or
006// modify it under the terms of the GNU Lesser General Public
007// License as published by the Free Software Foundation; either
008// version 2.1 of the License, or (at your option) any later version.
009//
010// This library is distributed in the hope that it will be useful,
011// but WITHOUT ANY WARRANTY; without even the implied warranty of
012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013// Lesser General Public License for more details.
014//
015// You should have received a copy of the GNU Lesser General Public
016// License along with this library; if not, write to the Free Software
017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018///////////////////////////////////////////////////////////////////////////////////////////////
019
020package com.puppycrawl.tools.checkstyle.checks.indentation;
021
022import java.util.function.IntFunction;
023
024import com.puppycrawl.tools.checkstyle.api.DetailAST;
025
026/**
027 * Immutable view of everything an indentation handler needs from the surrounding
028 * {@code IndentationCheck}, so handlers do not hold a direct reference back to the check.
029 */
030public final class IndentationContext {
031
032    /** Message key for an indentation error. */
033    /* package */ static final String MSG_ERROR = "indentation.error";
034    /** Message key for a multi-level indentation error. */
035    /* package */ static final String MSG_ERROR_MULTI = "indentation.error.multi";
036    /** Message key for a child indentation error. */
037    /* package */ static final String MSG_CHILD_ERROR = "indentation.child.error";
038    /** Message key for a multi-level child indentation error. */
039    /* package */ static final String MSG_CHILD_ERROR_MULTI = "indentation.child.error.multi";
040
041    /** Basic offset property value. */
042    private final int basicOffset;
043    /** Brace adjustment property value. */
044    private final int braceAdjustment;
045    /** Case indent property value. */
046    private final int caseIndent;
047    /** Throws indent property value. */
048    private final int throwsIndent;
049    /** Array initialization indent property value. */
050    private final int arrayInitIndent;
051    /** Line wrapping indentation property value. */
052    private final int lineWrappingIndentation;
053    /** Force-strict-condition property value. */
054    private final boolean forceStrictCondition;
055    /** Tab width used for expanded-tabs column calculations. */
056    private final int indentationTabWidth;
057    /** Provides a source line by zero-based index. */
058    private final IntFunction<String> lineProvider;
059    /** Factory that creates handlers for AST nodes. */
060    private final HandlerFactory handlerFactory;
061    /** Shared line-wrapping handler used by expression handlers. */
062    private final LineWrappingHandler lineWrappingHandler;
063    /** Sink for indentation violations. */
064    private final IndentationLogger logger;
065
066    /**
067     * Construct a context with all values handlers need for one file.
068     *
069     * @param basicOffset             basic offset property
070     * @param braceAdjustment         brace adjustment property
071     * @param caseIndent              case indent property
072     * @param throwsIndent            throws indent property
073     * @param arrayInitIndent         array-init indent property
074     * @param lineWrappingIndentation line-wrapping indent property
075     * @param forceStrictCondition    force-strict-condition property
076     * @param indentationTabWidth     tab width for expanded-tabs math
077     * @param lineProvider            zero-based source line accessor
078     * @param handlerFactory          factory for AST handlers
079     * @param lineWrappingHandler     shared line-wrapping handler
080     * @param logger                  sink for violations
081     */
082    // -@cs[ParameterNumber] bundling ctor for a value-object context
083    /* package */ IndentationContext(int basicOffset, int braceAdjustment, int caseIndent,
084                       int throwsIndent,
085                       int arrayInitIndent, int lineWrappingIndentation,
086                       boolean forceStrictCondition, int indentationTabWidth,
087                       IntFunction<String> lineProvider, HandlerFactory handlerFactory,
088                       LineWrappingHandler lineWrappingHandler, IndentationLogger logger) {
089        this.basicOffset = basicOffset;
090        this.braceAdjustment = braceAdjustment;
091        this.caseIndent = caseIndent;
092        this.throwsIndent = throwsIndent;
093        this.arrayInitIndent = arrayInitIndent;
094        this.lineWrappingIndentation = lineWrappingIndentation;
095        this.forceStrictCondition = forceStrictCondition;
096        this.indentationTabWidth = indentationTabWidth;
097        this.lineProvider = lineProvider;
098        this.handlerFactory = handlerFactory;
099        this.lineWrappingHandler = lineWrappingHandler;
100        this.logger = logger;
101    }
102
103    /**
104     * Get the basic offset property.
105     *
106     * @return basic offset
107     */
108    /* package */ int getBasicOffset() {
109        return basicOffset;
110    }
111
112    /**
113     * Get the brace adjustment property.
114     *
115     * @return brace adjustment
116     */
117    /* package */ int getBraceAdjustment() {
118        return braceAdjustment;
119    }
120
121    /**
122     * Get the case indent property.
123     *
124     * @return case indent
125     */
126    /* package */ int getCaseIndent() {
127        return caseIndent;
128    }
129
130    /**
131     * Get the throws indent property.
132     *
133     * @return throws indent
134     */
135    /* package */ int getThrowsIndent() {
136        return throwsIndent;
137    }
138
139    /**
140     * Get the array-init indent property.
141     *
142     * @return array-init indent
143     */
144    /* package */ int getArrayInitIndent() {
145        return arrayInitIndent;
146    }
147
148    /**
149     * Get the line-wrapping indentation property.
150     *
151     * @return line-wrapping indent
152     */
153    /* package */ int getLineWrappingIndentation() {
154        return lineWrappingIndentation;
155    }
156
157    /**
158     * Get the force-strict-condition property.
159     *
160     * @return true when strict line-wrap indent is enforced
161     */
162    /* package */ boolean isForceStrictCondition() {
163        return forceStrictCondition;
164    }
165
166    /**
167     * Get the tab width used for expanded-tabs column math.
168     *
169     * @return tab width
170     */
171    /* package */ int getIndentationTabWidth() {
172        return indentationTabWidth;
173    }
174
175    /**
176     * Get a source line by zero-based index.
177     *
178     * @param lineIndex zero-based line index
179     * @return the source line
180     */
181    /* package */ String getLine(int lineIndex) {
182        return lineProvider.apply(lineIndex);
183    }
184
185    /**
186     * Get the shared handler factory.
187     *
188     * @return handler factory
189     */
190    /* package */ HandlerFactory getHandlerFactory() {
191        return handlerFactory;
192    }
193
194    /**
195     * Get the shared line-wrapping handler.
196     *
197     * @return line-wrapping handler
198     */
199    /* package */ LineWrappingHandler getLineWrappingHandler() {
200        return lineWrappingHandler;
201    }
202
203    /**
204     * Report an indentation violation for the given AST.
205     *
206     * @param ast the AST that caused the violation
207     * @param messageKey the message key
208     * @param args message arguments
209     */
210    /* package */ void indentationLog(DetailAST ast, String messageKey, Object... args) {
211        logger.log(ast, messageKey, args);
212    }
213
214}