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
029 * the check.
030 */
031public final class IndentationContext {
032
033    /** Message key for an indentation error. */
034    /* package */ static final String MSG_ERROR = "indentation.error";
035    /** Message key for a multi-level indentation error. */
036    /* package */ static final String MSG_ERROR_MULTI = "indentation.error.multi";
037    /** Message key for a child indentation error. */
038    /* package */ static final String MSG_CHILD_ERROR = "indentation.child.error";
039    /** Message key for a multi-level child indentation error. */
040    /* package */ static final String MSG_CHILD_ERROR_MULTI = "indentation.child.error.multi";
041
042    /** Basic offset property value. */
043    private final int basicOffset;
044    /** Brace adjustment property value. */
045    private final int braceAdjustment;
046    /** Case indent property value. */
047    private final int caseIndent;
048    /** Throws indent property value. */
049    private final int throwsIndent;
050    /** Array initialization indent property value. */
051    private final int arrayInitIndent;
052    /** Line wrapping indentation property value. */
053    private final int lineWrappingIndentation;
054    /** Force-strict-condition property value. */
055    private final boolean forceStrictCondition;
056    /** Tab width used for expanded-tabs column calculations. */
057    private final int indentationTabWidth;
058    /** Provides a source line by zero-based index. */
059    private final IntFunction<String> lineProvider;
060    /** Factory that creates handlers for AST nodes. */
061    private final HandlerFactory handlerFactory;
062    /** Shared line-wrapping handler used by expression handlers. */
063    private final LineWrappingHandler lineWrappingHandler;
064    /** Sink for indentation violations. */
065    private final IndentationLogger logger;
066
067    /**
068     * Construct a context with all values handlers need for one file.
069     *
070     * @param basicOffset             basic offset property
071     * @param braceAdjustment         brace adjustment property
072     * @param caseIndent              case indent property
073     * @param throwsIndent            throws indent property
074     * @param arrayInitIndent         array-init indent property
075     * @param lineWrappingIndentation line-wrapping indent property
076     * @param forceStrictCondition    force-strict-condition property
077     * @param indentationTabWidth     tab width for expanded-tabs math
078     * @param lineProvider            zero-based source line accessor
079     * @param handlerFactory          factory for AST handlers
080     * @param lineWrappingHandler     shared line-wrapping handler
081     * @param logger                  sink for violations
082     */
083    // -@cs[ParameterNumber] bundling ctor for a value-object context
084    /* package */ IndentationContext(int basicOffset, int braceAdjustment, int caseIndent,
085                       int throwsIndent,
086                       int arrayInitIndent, int lineWrappingIndentation,
087                       boolean forceStrictCondition, int indentationTabWidth,
088                       IntFunction<String> lineProvider, HandlerFactory handlerFactory,
089                       LineWrappingHandler lineWrappingHandler, IndentationLogger logger) {
090        this.basicOffset = basicOffset;
091        this.braceAdjustment = braceAdjustment;
092        this.caseIndent = caseIndent;
093        this.throwsIndent = throwsIndent;
094        this.arrayInitIndent = arrayInitIndent;
095        this.lineWrappingIndentation = lineWrappingIndentation;
096        this.forceStrictCondition = forceStrictCondition;
097        this.indentationTabWidth = indentationTabWidth;
098        this.lineProvider = lineProvider;
099        this.handlerFactory = handlerFactory;
100        this.lineWrappingHandler = lineWrappingHandler;
101        this.logger = logger;
102    }
103
104    /**
105     * Get the basic offset property.
106     *
107     * @return basic offset
108     */
109    /* package */ int getBasicOffset() {
110        return basicOffset;
111    }
112
113    /**
114     * Get the brace adjustment property.
115     *
116     * @return brace adjustment
117     */
118    /* package */ int getBraceAdjustment() {
119        return braceAdjustment;
120    }
121
122    /**
123     * Get the case indent property.
124     *
125     * @return case indent
126     */
127    /* package */ int getCaseIndent() {
128        return caseIndent;
129    }
130
131    /**
132     * Get the throws indent property.
133     *
134     * @return throws indent
135     */
136    /* package */ int getThrowsIndent() {
137        return throwsIndent;
138    }
139
140    /**
141     * Get the array-init indent property.
142     *
143     * @return array-init indent
144     */
145    /* package */ int getArrayInitIndent() {
146        return arrayInitIndent;
147    }
148
149    /**
150     * Get the line-wrapping indentation property.
151     *
152     * @return line-wrapping indent
153     */
154    /* package */ int getLineWrappingIndentation() {
155        return lineWrappingIndentation;
156    }
157
158    /**
159     * Get the force-strict-condition property.
160     *
161     * @return true when strict line-wrap indent is enforced
162     */
163    /* package */ boolean isForceStrictCondition() {
164        return forceStrictCondition;
165    }
166
167    /**
168     * Get the tab width used for expanded-tabs column math.
169     *
170     * @return tab width
171     */
172    /* package */ int getIndentationTabWidth() {
173        return indentationTabWidth;
174    }
175
176    /**
177     * Get a source line by zero-based index.
178     *
179     * @param lineIndex zero-based line index
180     * @return the source line
181     */
182    /* package */ String getLine(int lineIndex) {
183        return lineProvider.apply(lineIndex);
184    }
185
186    /**
187     * Get the shared handler factory.
188     *
189     * @return handler factory
190     */
191    /* package */ HandlerFactory getHandlerFactory() {
192        return handlerFactory;
193    }
194
195    /**
196     * Get the shared line-wrapping handler.
197     *
198     * @return line-wrapping handler
199     */
200    /* package */ LineWrappingHandler getLineWrappingHandler() {
201        return lineWrappingHandler;
202    }
203
204    /**
205     * Report an indentation violation for the given AST.
206     *
207     * @param ast the AST that caused the violation
208     * @param messageKey the message key
209     * @param args message arguments
210     */
211    /* package */ void indentationLog(DetailAST ast, String messageKey, Object... args) {
212        logger.log(ast, messageKey, args);
213    }
214
215}