org.unlaxer.PositionResolverImpl Maven / Gradle / Ivy
package org.unlaxer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.stream.Stream;
import org.unlaxer.Cursor.EndExclusiveCursor;
import org.unlaxer.Cursor.StartInclusiveCursor;
import org.unlaxer.Source.SourceKind;
public class PositionResolverImpl implements PositionResolver {
final NavigableMap lineNumberByIndex = new TreeMap<>();
final Map stringIndexByCodePointIndex = new HashMap<>();
final Map codePointIndexInLineByCodePointIndex = new HashMap<>();
final Map codePointIndexByStringIndex = new HashMap<>();
final List cursorRanges = new ArrayList<>();
final CursorRange cursorRange;
// final RootPositionResolver rootPositionResolver;
// public static RootPositionResolver createRootPositionResolver(int[] codePoints){
// return new PositionResolverImpl(codePoints, null, new CodePointOffset(0));
// }
//
// public static SubPositionResolver createSubPositionReslover(
// int[] codePoints,
// RootPositionResolver rootPositionResolver,
// CodePointOffset offsetFromRoot){
// return new PositionResolverImpl(codePoints, null, new CodePointOffset(0));
// }
PositionResolverImpl(int[] codePoints){
// RootPositionResolver rootPositionResolver,
// CodePointOffset offsetFromRoot) {
// boolean isRoot = rootPositionResolver == null ;
int codePointCount = codePoints.length;
// this.rootPositionResolver = isRoot ? this : rootPositionResolver;
LineNumber lineNumber = new LineNumber(0);
CodePointIndex startIndex = new CodePointIndex(0);
CodePointIndex previousStartIndex;
lineNumberByIndex.put(startIndex, lineNumber);
StringIndex stringIndex = new StringIndex(0);
CodePointIndex codePointIndex = new CodePointIndex(0);
CodePointIndexInLine codePointOffsetInline = new CodePointIndexInLine(0);
for (int i = 0; i < codePointCount; i++) {
codePointIndex = new CodePointIndex(i);
stringIndexByCodePointIndex.put(codePointIndex, stringIndex);
codePointIndexByStringIndex.put(stringIndex,codePointIndex);
codePointIndexInLineByCodePointIndex.put(codePointIndex, codePointOffsetInline);
int codePointAt = codePoints[i];
int adding = Character.isBmpCodePoint(codePointAt) ? 1:2;
stringIndex = stringIndex.newWithAdd(adding);
if(codePointAt == SymbolMap.lf.codes[0]) {
previousStartIndex = startIndex;
startIndex = new CodePointIndex(i+1);
cursorRanges.add(
CursorRange.of(
previousStartIndex,
startIndex,
CodePointOffset.ZERO,
SourceKind.subSource,
this
)
);
lineNumber = lineNumber.newWithIncrements();
lineNumberByIndex.put(startIndex, lineNumber);
codePointOffsetInline = new CodePointIndexInLine(0);
continue;
}else if(codePointAt == SymbolMap.cr.codes[0]) {
if(codePointCount-1!=i && codePoints[i+1] ==SymbolMap.lf.codes[0]) {
i++;
previousStartIndex = startIndex;
startIndex = new CodePointIndex(i+1);
cursorRanges.add(
CursorRange.of(
previousStartIndex,
startIndex,
CodePointOffset.ZERO,
SourceKind.subSource,
this
)
);
lineNumber = lineNumber.newWithIncrements();
lineNumberByIndex.put(startIndex, lineNumber);
stringIndex = stringIndex.newWithAdd(1);
stringIndexByCodePointIndex.put(codePointIndex.newWithAdd(1), stringIndex);
codePointIndexByStringIndex.put(stringIndex,codePointIndex.newWithAdd(1));
}else {
previousStartIndex = startIndex;
startIndex = new CodePointIndex(i+1);
cursorRanges.add(
CursorRange.of(
previousStartIndex,
startIndex,
CodePointOffset.ZERO,
SourceKind.subSource,
this
)
);
lineNumber = lineNumber.newWithIncrements();
lineNumberByIndex.put(startIndex, lineNumber);
}
codePointOffsetInline = new CodePointIndexInLine(0);
continue;
}
codePointOffsetInline = codePointOffsetInline.newWithIncrements();
}
StartInclusiveCursor start = new StartInclusiveCursorImpl(SourceKind.root,this);//.addPosition(offsetFromRoot);
CodePointIndex position = new CodePointIndex(codePointCount);//.newWithAdd(offsetFromRoot);
EndExclusiveCursor end = new EndExclusiveCursorImpl(SourceKind.root,this)
.setPosition(position);
cursorRange = new CursorRange(start, end);
codePointIndexInLineByCodePointIndex.put(position, new CodePointIndexInLine(0));
lineNumberByIndex.put(position, lineNumber);
if(cursorRanges.size()>0) {
CursorRange last = cursorRanges.get(cursorRanges.size()-1);
if(last.lessThan(codePointIndex) && startIndex.lessThan(position)) {
cursorRanges.add(
CursorRange.of(
startIndex,
position,
CodePointOffset.ZERO,
SourceKind.subSource,
this
)
);
}
}
}
@Override
public Size lineSize() {
return new Size(cursorRanges.size());
}
@Override
public Stream lines(Source root){
return cursorRanges.stream()
.map(root::subSource);
}
@Override
public StringIndex stringIndexInRootFrom(CodePointIndex codePointIndex) {
// if(rootPositionResolver == this) {
// return stringIndexByCodePointIndex.get(codePointIndexInSubSource);
// }
// return rootPositionResolver.stringIndexInRootFrom(codePointIndexInSubSource.newWithPlus(offsetFromRoot));
return stringIndexByCodePointIndex.get(codePointIndex);
}
@Override
public LineNumber lineNumberFrom(CodePointIndex codePointIndex) {
// return rootPositionResolver.lineNumberFrom(codePointIndex.newWithPlus(offsetFromRoot));
return lineNumberByIndex.floorEntry(codePointIndex).getValue();
}
// @Override
// public CodePointIndex codePointIndexFrom(StringIndex stringIndex) {
// return rootPositionResolver.codePointIndexFrom(stringIndex);
// }
@Override
public CursorRange rootCursorRange() {
return cursorRange;
}
@Override
public StringIndex subStringIndexFrom(CodePointIndex subCodePointIndex) {
return stringIndexByCodePointIndex.get(subCodePointIndex);
}
@Override
public CodePointIndex subCodePointIndexFrom(StringIndex subStringIndex) {
return codePointIndexByStringIndex.get(subStringIndex);
}
@Override
public CodePointIndexInLine codePointIndexInLineFrom(CodePointIndex codePointIndex) {
return codePointIndexInLineByCodePointIndex.get(codePointIndex);
}
@Override
public CodePointIndex rootCodePointIndexFrom(StringIndex stringIndex) {
return codePointIndexByStringIndex.get(stringIndex);
}
} © 2015 - 2025 Weber Informatics LLC | Privacy Policy