/* * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.css; import com.google.common.base.Preconditions; /** * Aids in the creation of source code locations. A builder can be used for * creating a single {@link SourceCodeLocation}. * */ public class SourceCodeLocationBuilder { private SourceCode sourceCode; private int beginCharacterIndex; private int beginLineNumber; private int beginIndexInLine; private int endCharacterIndex; private int endLineNumber; private int endIndexInLine; /** * {@code null} until the location gets created. After that, none of the set * methods should be called, only {@link #getSourceCodeLocation()} should be * called. */ private SourceCodeLocation sourceCodeLocation = null; public SourceCodeLocationBuilder() { // We initialize to a unknown location. sourceCode = null; beginCharacterIndex = -1; beginLineNumber = 0; beginIndexInLine = 0; endCharacterIndex = -1; endLineNumber = 0; endIndexInLine = 0; } private void checkLocationIsNotAlreadyCreated() { Preconditions.checkState(sourceCodeLocation == null, "You cannot set " + "source code location properties after the object was created."); } public SourceCodeLocationBuilder setSourceCode(SourceCode newSourceCode) { checkLocationIsNotAlreadyCreated(); Preconditions.checkNotNull(newSourceCode); this.sourceCode = newSourceCode; return this; } public boolean hasSourceCode() { return this.sourceCode != null; } public SourceCodeLocationBuilder setBeginLocation(int characterIndex, int lineNumber, int indexInLine) { checkLocationIsNotAlreadyCreated(); Preconditions.checkArgument(characterIndex >= 0, "The passed location is not valid."); Preconditions.checkArgument(lineNumber >= 1, "The passed location is not valid."); Preconditions.checkArgument(indexInLine >= 1, "The passed location is not valid."); this.beginCharacterIndex = characterIndex; this.beginLineNumber = lineNumber; this.beginIndexInLine = indexInLine; return this; } public SourceCodeLocationBuilder setBeginLocation(SourceCodeLocation.SourceCodePoint begin) { checkLocationIsNotAlreadyCreated(); Preconditions.checkNotNull(begin); setBeginLocation(begin.getCharacterIndex(), begin.getLineNumber(), begin.getIndexInLine()); return this; } public boolean hasBeginLocation() { return this.beginCharacterIndex != -1; } public SourceCodeLocationBuilder setEndLocation(int characterIndex, int lineNumber, int indexInLine) { checkLocationIsNotAlreadyCreated(); Preconditions.checkArgument(characterIndex >= 0, "The passed characterIndex is not valid."); Preconditions.checkArgument(lineNumber >= 1, "The passed lineNumber is not valid."); Preconditions.checkArgument(indexInLine >= 1, "The passed indexInLine is not valid."); this.endCharacterIndex = characterIndex; this.endLineNumber = lineNumber; this.endIndexInLine = indexInLine; return this; } public SourceCodeLocationBuilder setEndLocation(SourceCodeLocation.SourceCodePoint end) { checkLocationIsNotAlreadyCreated(); Preconditions.checkNotNull(end); setEndLocation(end.getCharacterIndex(), end.getLineNumber(), end.getIndexInLine()); return this; } public SourceCodeLocationBuilder setLocation(int characterIndex, int lineNumber, int indexInLine) { checkLocationIsNotAlreadyCreated(); setBeginLocation(characterIndex, lineNumber, indexInLine); setEndLocation(characterIndex, lineNumber, indexInLine); return this; } public SourceCodeLocation getSourceCodeLocation() { if (sourceCodeLocation != null) { return sourceCodeLocation; } Preconditions.checkState(sourceCode != null, "You should specify a source code object"); Preconditions.checkState( (beginCharacterIndex >= 0 && endCharacterIndex >= 0) || (beginCharacterIndex == -1 && endCharacterIndex == -1), "Both the start and the end locations must be set."); Preconditions.checkState(hasSourceCode() || !hasBeginLocation(), "Must specify the source code if you specify a location."); try { sourceCodeLocation = new SourceCodeLocation(sourceCode, beginCharacterIndex, beginLineNumber, beginIndexInLine, endCharacterIndex, endLineNumber, endIndexInLine); } catch (IllegalArgumentException e) { throw new IllegalArgumentException( String.format( "with sourceCode = %s, beginCharacterIndex = %d, " + "beginLineNumber = %d, beginIndexInLine = %d, " + "endCharacterIndex = %d, endLineNumber = %d, " + "endIndexInLine = %d", sourceCode.getFileContents(), beginCharacterIndex, beginLineNumber, beginIndexInLine, endCharacterIndex, endLineNumber, endIndexInLine), e); } return sourceCodeLocation; } }