mutating func visit()

in Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraph.swift [809:924]


      mutating func visit(record: BitcodeElement.Record) throws {
        guard let kind = RecordID(rawValue: record.id) else {
          throw ReadError.unknownRecord
        }
        
        var malformedError: ReadError {.init(forMalformed: kind)}
        
        func stringIndex(field i: Int) throws -> Int {
          let u = record.fields[i]
          guard u < UInt64(internedStringTable.count) else {
            throw malformedError
          }
          return Int(u)
        }
        func internedString(field i: Int) throws -> InternedString {
          try InternedString(deserializedIndex: stringIndex(field: i))
        }
        func nonemptyInternedString(field i: Int) throws -> InternedString? {
          let s = try internedString(field: i)
          return s.isEmpty ? nil : s
        }
        func dependencyKey(kindCodeField: Int,
                           declAspectField: Int,
                           contextField: Int,
                           identifierField: Int
        ) throws -> DependencyKey {
          let kindCode = record.fields[kindCodeField]
          guard let declAspect = DependencyKey.DeclAspect(record.fields[declAspectField])
          else {
            throw malformedError
          }
          let context = try internedString(field: contextField)
          let identifier = try internedString(field: identifierField)
          let designator = try DependencyKey.Designator(
            kindCode: kindCode, context: context, name: identifier,
            internedStringTable: internedStringTable, fileSystem: fileSystem)
          return DependencyKey(aspect: declAspect, designator: designator)
        }

        switch kind {
        case .metadata:
          // If we've already read metadata, this is an unexpected duplicate.
          guard self.majorVersion == nil, self.minorVersion == nil, self.compilerVersionString == nil else {
            throw ReadError.unexpectedMetadataRecord
          }
          guard record.fields.count == 3,
                case .blob(let compilerVersionBlob) = record.payload
          else { throw malformedError }

          self.majorVersion = record.fields[0]
          self.minorVersion = record.fields[1]
          let stringCount = record.fields[2]
          internedStringTable.reserveCapacity(Int(stringCount))
          self.compilerVersionString = String(decoding: compilerVersionBlob, as: UTF8.self)
        case .moduleDepGraphNode:
           guard record.fields.count == 6
          else {
            throw malformedError
          }
          let key = try dependencyKey(kindCodeField: 0,
                                      declAspectField: 1,
                                      contextField: 2,
                                      identifierField: 3)
          let depSourceFileOrNone = try nonemptyInternedString(field: 4)
          let defLoc: DefinitionLocation = try depSourceFileOrNone.map {
            internedFile -> DefinitionLocation in
            let pathString = internedFile.lookup(in: internedStringTable)
            let pathHandle = try VirtualPath.intern(path: pathString)
            guard let source =  DependencySource(ifAppropriateFor: pathHandle,
                             internedString: internedFile)
            else {
              throw ReadError.unknownDependencySourceExtension
            }
            return .known(source)
          }
          ?? .unknown
          let fingerprint = try nonemptyInternedString(field: 5)
          self.finalize(node: Node(key: key,
                                   fingerprint: fingerprint,
                                   definitionLocation: defLoc))
        case .dependsOnNode:
          guard record.fields.count == 4
          else {
            throw malformedError
          }
          self.currentDefKey = try dependencyKey(
            kindCodeField: 0,
            declAspectField: 1,
            contextField: 2,
            identifierField: 3)
        case .useIDNode:
          guard let key = self.currentDefKey,
                  record.fields.count == 1 else {
            throw malformedError
          }
          self.nodeUses.append( (key, Int(record.fields[0])) )
        case .externalDepNode:
          guard record.fields.count == 2
          else {
            throw malformedError
          }
          let path = try internedString(field: 0)
          let fingerprint = try nonemptyInternedString(field: 1)
          fingerprintedExternalDependencies.insert(
            FingerprintedExternalDependency(
              ExternalDependency(fileName: path, internedStringTable),
              fingerprint))
        case .identifierNode:
          guard record.fields.count == 0,
                case .blob(let identifierBlob) = record.payload
          else {
            throw malformedError
          }
          _ = (String(decoding: identifierBlob, as: UTF8.self)).intern(in: internedStringTable)
        }
      }