<commit_before>package wdl.transforms.base.linking.expression.values

import cats.syntax.traverse._
import cats.syntax.validated._
import cats.instances.list._
import common.validation.ErrorOr
import common.validation.ErrorOr._
import common.validation.ErrorOr.ErrorOr
import common.validation.Validation._
import wom.format.MemorySize
import wdl.model.draft3.elements.ExpressionElement._
import wdl.model.draft3.graph.expression.{EvaluatedValue, ForCommandInstantiationOptions, ValueEvaluator}
import wdl.model.draft3.graph.expression.ValueEvaluator.ops._
import wdl.shared.transforms.evaluation.values.EngineFunctions
import wdl4s.parser.MemoryUnit
import wom.expression.IoFunctionSet
import wom.types._
import wom.values.WomArray.WomArrayLike
import wom.values.{WomArray, WomBoolean, WomFloat, WomInteger, WomMap, WomObject, WomOptionalValue, WomPair, WomSingleFile, WomString, WomValue}
import wom.types.coercion.ops._
import wom.types.coercion.defaults._
import wom.types.coercion.WomTypeCoercer
import spray.json._
import wdl.model.draft3.elements.ExpressionElement
import wdl.shared.FileSizeLimitationConfig
import wdl.shared.model.expression.ValueEvaluation
import wom.CommandSetupSideEffectFile

import scala.concurrent.duration._
import scala.concurrent.Await
import scala.util.Try

object EngineFunctionEvaluators {
  private val fileSizeLimitationConfig = FileSizeLimitationConfig.fileSizeLimitationConfig

  implicit val stdoutFunctionEvaluator: ValueEvaluator[StdoutElement.type] = new ValueEvaluator[StdoutElement.type] {
    override def evaluateValue(a: StdoutElement.type,
                               inputs: Map[String, WomValue],
                               ioFunctionSet: IoFunctionSet,
                               forCommandInstantiationOptions: Option[ForCommandInstantiationOptions])
                              (implicit expressionValueEvaluator: ValueEvaluator[ExpressionElement]): ErrorOr[EvaluatedValue[WomSingleFile]] =
      EvaluatedValue(WomSingleFile(ioFunctionSet.pathFunctions.stdout), Seq.empty).validNel
  }

  implicit val stderrFunctionEvaluator: ValueEvaluator[StderrElement.type] = new ValueEvaluator[StderrElement.type] {
    override def evaluateValue(a: StderrElement.type,
                               inputs: Map[String, WomValue],
                               ioFunctionSet: IoFunctionSet,
                               forCommandInstantiationOptions: Option[ForCommandInstantiationOptions])
                              (implicit expressionValueEvaluator: ValueEvaluator[ExpressionElement]): ErrorOr[EvaluatedValue[WomSingleFile]] =
      EvaluatedValue(WomSingleFile(ioFunctionSet.pathFunctions.stderr), Seq.empty).validNel
  }

  private val ReadWaitTimeout = 60.seconds
  private def readFile(fileToRead: WomSingleFile, ioFunctionSet: IoFunctionSet, sizeLimit: Int) = {
    Try(Await.result(ioFunctionSet.readFile(fileToRead.value, Option(sizeLimit), failOnOverflow = true), ReadWaitTimeout))
  }

  implicit val readLinesFunctionEvaluator: ValueEvaluator[ReadLines] = new ValueEvaluator[ReadLines] {
    override def evaluateValue(a: ReadLines,
                               inputs: Map[String, WomValue],
                               ioFunctionSet: IoFunctionSet,
                               forCommandInstantiationOptions: Option[ForCommandInstantiationOptions])
                              (implicit expressionValueEvaluator: ValueEvaluator[ExpressionElement]): ErrorOr[EvaluatedValue[WomArray]] = {
      processValidatedSingleValue[WomSingleFile, WomArray](a.param.evaluateValue(inputs, ioFunctionSet, forCommandInstantiationOptions)) { fileToRead =>
        val tryResult = for {
          //validate
          read <- readFile(fileToRead, ioFunctionSet, fileSizeLimitationConfig.readLinesLimit)
          lines = read.split(System.lineSeparator)
        } yield EvaluatedValue(WomArray(lines map WomString.apply), Seq.empty)
        tryResult.toErrorOr.contextualizeErrors(s"""read_lines("${fileToRead.value}")""")
      }
    }
  }
<commit_msg>Saving changes before adding conditional.<commit_after>package wdl.transforms.base.linking.expression.values

import cats.syntax.traverse._
import cats.syntax.validated._
import cats.instances.list._
import common.validation.ErrorOr
import common.validation.ErrorOr._
import common.validation.ErrorOr.ErrorOr
import common.validation.Validation._
import wom.format.MemorySize
import wdl.model.draft3.elements.ExpressionElement._
import wdl.model.draft3.graph.expression.{EvaluatedValue, ForCommandInstantiationOptions, ValueEvaluator}
import wdl.model.draft3.graph.expression.ValueEvaluator.ops._
import wdl.shared.transforms.evaluation.values.EngineFunctions
import wdl4s.parser.MemoryUnit
import wom.expression.IoFunctionSet
import wom.types._
import wom.values.WomArray.WomArrayLike
import wom.values.{WomArray, WomBoolean, WomFloat, WomInteger, WomMap, WomObject, WomOptionalValue, WomPair, WomSingleFile, WomString, WomValue}
import wom.types.coercion.ops._
import wom.types.coercion.defaults._
import wom.types.coercion.WomTypeCoercer
import spray.json._
import wdl.model.draft3.elements.ExpressionElement
import wdl.shared.FileSizeLimitationConfig
import wdl.shared.model.expression.ValueEvaluation
import wom.CommandSetupSideEffectFile

import scala.concurrent.duration._
import scala.concurrent.Await
import scala.util.Try

object EngineFunctionEvaluators {
  private val fileSizeLimitationConfig = FileSizeLimitationConfig.fileSizeLimitationConfig

  implicit val stdoutFunctionEvaluator: ValueEvaluator[StdoutElement.type] = new ValueEvaluator[StdoutElement.type] {
    override def evaluateValue(a: StdoutElement.type,
                               inputs: Map[String, WomValue],
                               ioFunctionSet: IoFunctionSet,
                               forCommandInstantiationOptions: Option[ForCommandInstantiationOptions])
                              (implicit expressionValueEvaluator: ValueEvaluator[ExpressionElement]): ErrorOr[EvaluatedValue[WomSingleFile]] =
      EvaluatedValue(WomSingleFile(ioFunctionSet.pathFunctions.stdout), Seq.empty).validNel
  }

  implicit val stderrFunctionEvaluator: ValueEvaluator[StderrElement.type] = new ValueEvaluator[StderrElement.type] {
    override def evaluateValue(a: StderrElement.type,
                               inputs: Map[String, WomValue],
                               ioFunctionSet: IoFunctionSet,
                               forCommandInstantiationOptions: Option[ForCommandInstantiationOptions])
                              (implicit expressionValueEvaluator: ValueEvaluator[ExpressionElement]): ErrorOr[EvaluatedValue[WomSingleFile]] =
      EvaluatedValue(WomSingleFile(ioFunctionSet.pathFunctions.stderr), Seq.empty).validNel
  }

  private val ReadWaitTimeout = 60.seconds
  private def readFile(fileToRead: WomSingleFile, ioFunctionSet: IoFunctionSet, sizeLimit: Int) = {
    Try(Await.result(ioFunctionSet.readFile(fileToRead.value, Option(sizeLimit), failOnOverflow = true), ReadWaitTimeout))
  }

  implicit val readLinesFunctionEvaluator: ValueEvaluator[ReadLines] = new ValueEvaluator[ReadLines] {
    override def evaluateValue(a: ReadLines,
                               inputs: Map[String, WomValue],
                               ioFunctionSet: IoFunctionSet,
                               forCommandInstantiationOptions: Option[ForCommandInstantiationOptions])
                              (implicit expressionValueEvaluator: ValueEvaluator[ExpressionElement]): ErrorOr[EvaluatedValue[WomArray]] = {
      processValidatedSingleValue[WomSingleFile, WomArray](a.param.evaluateValue(inputs, ioFunctionSet, forCommandInstantiationOptions)) { fileToRead =>
        val tryResult = for {
          //validate
          read: String <- readFile(fileToRead, ioFunctionSet, fileSizeLimitationConfig.readLinesLimit)
          // Write a conditional statement here for empty String; if empty, do not split.
          lines = read.split(System.lineSeparator)
        } yield EvaluatedValue(WomArray(lines map WomString.apply), Seq.empty)
        tryResult.toErrorOr.contextualizeErrors(s"""read_lines("${fileToRead.value}")""")
      }
    }
  }

{'fraction_non_alphanumeric': 0.07954545454545454, 'fraction_numerical': 0.001710654936461388, 'mean_word_length': 3.8489336492890995, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3442887', 'n_tokens_mistral': 2251, 'n_tokens_neox': 2226, 'n_words': 380}