import { assertNever } from "../util/assertNever" ; export enum ContainsBehavior { strict = 0 , extended = 1 , enclosed = 2 } /**
 * A span representing the character indexes that are contained by a JSONToken.
 */ export class Span { public static readonly empty : Span = new Span ( 0 , 0 ) ; constructor ( private _startIndex , private _length ) { } public static fromStartAndAfterEnd ( startIndex , afterEndIndex ) { return new Span ( startIndex , afterEndIndex - startIndex ) ; } /**
     * Get the start index of this span.
     */ public get startIndex ( ) : number { return this . _startIndex ; } /**
     * Get the length of this span.
     */ public get length ( ) : number { return this . _length ; } /**
     * Get the last index of this span.
     */ public get endIndex ( ) : number { return this . _startIndex + ( this . _length > 0 ? this . _length - 1 : 0 ) ; } /**
     * Get the index directly after this span.
     *
     * If this span started at 3 and had a length of 4 ([3,7)), then the after
     * end index would be 7.
     */ public get afterEndIndex ( ) : number { return this . _startIndex + this . _length ; } /**
     * Determine if the provided index is contained by this span.
     *
     * If this span started at 3 and had a length of 4, i.e. [3, 7), then all
     * indexes between 3 and 6 (inclusive) would be contained. 2 and 7 would
     * not be contained.
     *
     * If includeAfterEndIndex=true, then 3-7 inclusive would be contained.
     */ public contains ( index , containsBehavior ) { switch ( containsBehavior ) { case ContainsBehavior . strict : return this . _startIndex <= index && index <= this . endIndex ; case ContainsBehavior . extended : return this . _startIndex <= index && index <= this . afterEndIndex ; case ContainsBehavior . enclosed : return this . _startIndex + 1 <= index && index <= this . endIndex ; default : assertNever ( containsBehavior ) ; } } /**
     * Create a new span that is a union of this Span and the provided Span.
     * If the provided Span is undefined, then this Span will be returned.
     */ public union ( rhs ) { let result ; if ( ! ! rhs ) { let minStart = Math . min ( this . startIndex , rhs . startIndex ) ; let maxAfterEndIndex = Math . max ( this . afterEndIndex , rhs . afterEndIndex ) ; result = new Span ( minStart , maxAfterEndIndex - minStart ) ; } else { result = this ; } return result ; } /**
     * Create a new span that is a union of the given spans.
     * If both are undefined, undefined will be returned
     */ public static union ( lhs , rhs ) { if ( lhs ) { return lhs . union ( rhs ) ; } else if ( rhs ) { return rhs ; } else { return undefined ; } } /**
     * Create a new span that is the intersection of this and a given span.
     * If the provided span is undefined, or they do no intersect, undefined will be returned
     */ public intersect ( rhs ) { if ( ! ! rhs ) { let lhs = this ; if ( rhs . startIndex < this . startIndex ) { [ lhs , rhs ] = [ rhs , lhs ] ; } let start = rhs . startIndex ; let afterEnd = ( lhs . afterEndIndex < rhs . afterEndIndex ) ? lhs . afterEndIndex : rhs . afterEndIndex ; if ( afterEnd >= start ) { return new Span ( start , afterEnd - start ) ; } else { return undefined ; } } return undefined ; } /**
     * Create a new span that is the intersection of the given spans.
     * If either is undefined, or they do no intersect, undefined will be returned
     */ public static intersect ( lhs , rhs ) { if ( lhs ) { return lhs . intersect ( rhs ) ; } else { return undefined ; } } public translate ( movement ) { return movement === 0 ? this : new Span ( this . _startIndex + movement , this . _length ) ; } public toString ( ) { return `[${ this . startIndex }, ${ this . afterEndIndex })` ; } public extendLeft ( extendLeft ) { return new Span ( this . startIndex - extendLeft , this . length + extendLeft ) ; } public extendRight ( extendRight ) { return new Span ( this . startIndex , this . length + extendRight ) ; } public getText ( text , offsetIndex ? ) { const start = this . startIndex + ( offsetIndex ?? 0 ) ; return text . slice ( start , start + this . length ) ; } }