All Downloads are FREE. Search and download functionalities are using the official Maven repository.

caliban.parsing.SourceMapper.scala Maven / Gradle / Ivy

The newest version!
package caliban.parsing

import caliban.parsing.adt.LocationInfo
import fastparse.internal.Util

/**
 * Maps an index to the "friendly" version of an index based on the underlying source.
 */
trait SourceMapper extends Serializable {

  def getLocation(index: Int): LocationInfo

  def size: Option[Int] = None

}

object SourceMapper {

  /**
   * Implementation taken from https://github.com/lihaoyi/fastparse/blob/e334ca88b747fb3b6637ef6d76715ad66e048a6c/fastparse/src/fastparse/ParserInput.scala#L123-L131
   *
   * It is used to look up a line/column number pair given a raw index into a source string. The numbers are determined by
   * computing the number of newlines occurring between 0 and the current index.
   */
  private[parsing] case class DefaultSourceMapper(source: String) extends SourceMapper {
    private[this] lazy val lineNumberLookup = Util.lineNumberLookup(source)

    def getLocation(index: Int): LocationInfo = {
      val line = lineNumberLookup.indexWhere(_ > index) match {
        case -1 => lineNumberLookup.length - 1
        case n  => 0 max (n - 1)
      }

      val col = index - lineNumberLookup(line)
      LocationInfo(column = col + 1, line = line + 1)
    }

    override def size: Option[Int] = Some(source.length)
  }

  def apply(source: String): SourceMapper = DefaultSourceMapper(source)

  private case object EmptySourceMapper extends SourceMapper {
    def getLocation(index: Int): LocationInfo = LocationInfo.origin
  }

  val empty: SourceMapper = EmptySourceMapper
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy