<commit_before>import Foundation

public final class Parser {

  public var locale: String {
    didSet {
      if locale != oldValue {
        loadData()
      }
    }
  }

  var data = [String: Any]()
  var provider: Provider

  // MARK: - Initialization

  public init(locale: String = Config.defaultLocale) {
    self.locale = locale
    provider = Provider()
    loadData()
  }

  // MARK: - Parsing

  public func fetch(_ key: String) -> String {
    var parsed = ""

    guard let keyData = fetchRaw(key) else {
      return parsed
    }

    let subject = getSubject(key)

    if let value = keyData as? String {
      parsed = value
    } else if let array = keyData as? [String], let item = array.random() {
      parsed = item
    }

    if parsed.range(of: "#{") != nil {
      parsed = parse(parsed, forSubject: subject)
    }

    return parsed
  }

  public func fetchRaw(_ key: String) -> Any? {
    let parts = key.components(separatedBy: ".")

    guard let localeData = data[locale] as? [String: Any],
      var parsed = localeData["faker"] as? [String: Any],
      !parts.isEmpty else { return nil }

    var result: Any?

    for part in parts {
      guard let parsedPart = parsed[part] as? [String: Any] else {
        result = parsed[part]
        continue
      }

      parsed = parsedPart
      result = parsedPart
    }

    return result
  }

  func parse(_ template: String, forSubject subject: String) -> String {
    var text = ""
    let string = template as NSString
    var regex: NSRegularExpression

    do {
      try regex = NSRegularExpression(pattern: "(\\(?)#\\{([A-Za-z]+\\.)?([^\\}]+)\\}([^#]+)?",
                                      options: .caseInsensitive)
      let matches = regex.matches(in: string as String,
        options: .reportCompletion,
        range: NSMakeRange(0, string.length))

      guard !matches.isEmpty else {
        return template
      }

      for match in matches {
        if match.numberOfRanges < 4 {
          continue
        }

        let prefixRange = match.rangeAt(1)
        let subjectRange = match.rangeAt(2)
        let methodRange = match.rangeAt(3)
        let otherRange = match.rangeAt(4)

        if prefixRange.length > 0 {
          text += string.substring(with: prefixRange)
        }

        var subjectWithDot = subject + "."
<commit_msg>Fix range variables for swift 4<commit_after>import Foundation

public final class Parser {

  public var locale: String {
    didSet {
      if locale != oldValue {
        loadData()
      }
    }
  }

  var data = [String: Any]()
  var provider: Provider

  // MARK: - Initialization

  public init(locale: String = Config.defaultLocale) {
    self.locale = locale
    provider = Provider()
    loadData()
  }

  // MARK: - Parsing

  public func fetch(_ key: String) -> String {
    var parsed = ""

    guard let keyData = fetchRaw(key) else {
      return parsed
    }

    let subject = getSubject(key)

    if let value = keyData as? String {
      parsed = value
    } else if let array = keyData as? [String], let item = array.random() {
      parsed = item
    }

    if parsed.range(of: "#{") != nil {
      parsed = parse(parsed, forSubject: subject)
    }

    return parsed
  }

  public func fetchRaw(_ key: String) -> Any? {
    let parts = key.components(separatedBy: ".")

    guard let localeData = data[locale] as? [String: Any],
      var parsed = localeData["faker"] as? [String: Any],
      !parts.isEmpty else { return nil }

    var result: Any?

    for part in parts {
      guard let parsedPart = parsed[part] as? [String: Any] else {
        result = parsed[part]
        continue
      }

      parsed = parsedPart
      result = parsedPart
    }

    return result
  }

  func parse(_ template: String, forSubject subject: String) -> String {
    var text = ""
    let string = template as NSString
    var regex: NSRegularExpression

    do {
      try regex = NSRegularExpression(pattern: "(\\(?)#\\{([A-Za-z]+\\.)?([^\\}]+)\\}([^#]+)?",
                                      options: .caseInsensitive)
      let matches = regex.matches(in: string as String,
        options: .reportCompletion,
        range: NSMakeRange(0, string.length))

      guard !matches.isEmpty else {
        return template
      }

      for match in matches {
        if match.numberOfRanges < 4 {
          continue
        }

        let prefixRange = match.range(at: 1)
        let subjectRange = match.range(at: 2)
        let methodRange = match.range(at: 3)
        let otherRange = match.range(at: 4)

        if prefixRange.length > 0 {
          text += string.substring(with: prefixRange)
        }

        var subjectWithDot = subject + "."

{'fraction_non_alphanumeric': 0.11554800339847068, 'fraction_numerical': 0.0031860662701784196, 'mean_word_length': 2.0858453473132372, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1039175', 'n_tokens_mistral': 1425, 'n_tokens_neox': 1351, 'n_words': 413}