export function activateDaffodilDebug()

in src/adapter/activateDaffodilDebug.ts [214:562]


export function activateDaffodilDebug(
  context: vscode.ExtensionContext,
  factory?: vscode.DebugAdapterDescriptorFactory
) {
  setupViews(context)

  context.subscriptions.push(
    vscode.commands.registerCommand(
      'extension.dfdl-debug.runEditorContents',
      (resource: vscode.Uri) => {
        createDebugRunFileConfigs(resource, 'run', undefined)
      }
    ),
    vscode.commands.registerCommand(
      'extension.dfdl-debug.debugEditorContents',
      (resource: vscode.Uri) => {
        createDebugRunFileConfigs(resource, 'debug', undefined)
      }
    ),
    vscode.commands.registerCommand(
      'extension.dfdl-debug.debugLastEditorContents',
      (resource: vscode.Uri) => {
        createDebugRunFileConfigs(resource, 'debug', undefined, true)
      }
    ),
    vscode.commands.registerCommand(
      'extension.dfdl-debug.appendTDML',
      async (resource: vscode.Uri) => {
        let targetResource = resource

        if (!targetResource && vscode.window.activeTextEditor) {
          targetResource = vscode.window.activeTextEditor.document.uri
        }
        if (targetResource) {
          appendTestCase(getTmpTDMLFilePath(), targetResource.fsPath)
            .then((appendedBuffer) => {
              fs.writeFileSync(targetResource.fsPath, xmlFormat(appendedBuffer))
            })
            .catch((reason) => {
              // Not sure if we need to do something different/more here
              console.log(reason)
            })
        }
      }
    ),
    vscode.commands.registerCommand(
      'extension.dfdl-debug.executeTDML',
      (resource: vscode.Uri) => {
        createDebugRunFileConfigs(resource, 'run', 'execute')
      }
    ),
    vscode.commands.registerCommand(
      'extension.dfdl-debug.copyTDML',
      async (_) => {
        // Ask for destination path
        // Copy file in /tmp to destination path
        // TDMLConfig.path should not be used here because that only matters when sending to the server
        // We could make it so that if someone wants to specify the path and set the action to 'copy', but
        //   that doesn't make a whole lot of sense.
        let targetResource = await vscode.commands.executeCommand(
          'extension.dfdl-debug.getValidatedTDMLCopyPath'
        )

        // Is there a better way of error checking this?
        if (targetResource) {
          copyTestCase(
            getTmpTDMLFilePath(),
            targetResource as unknown as string
          )
            .then((copiedBuffer) => {
              fs.writeFileSync(
                targetResource as unknown as string,
                xmlFormat(copiedBuffer)
              )
            })
            .catch((reason) => {
              // Not sure if we need to do something different/more here
              console.log(reason)
            })
        }

        // fs.copyFile(
        //   getTmpTDMLFilePath(),
        //   targetResource as unknown as string,
        //   (_) => {}
        // )
      }
    ),
    vscode.commands.registerCommand(
      'extension.dfdl-debug.toggleFormatting',
      (_) => {
        const ds = vscode.debug.activeDebugSession
        if (ds) {
          ds.customRequest('toggleFormatting')
        }
      }
    ),
    vscode.commands.registerCommand(
      'extension.dfdl-debug.getSchemaName',
      async (fileRequested = null) => {
        // Open native file explorer to allow user to select data file from anywhere on their machine
        return await getFile(
          fileRequested,
          'Select DFDL schema to debug',
          'Select DFDL schema to debug'
        )
      }
    ),
    vscode.commands.registerCommand(
      'extension.dfdl-debug.getDataName',
      async (fileRequested = null) => {
        // Open native file explorer to allow user to select data file from anywhere on their machine
        return await getFile(
          fileRequested,
          'Select input data file to debug',
          'Select input data file to debug'
        )
      }
    ),
    vscode.commands.registerCommand('extension.dfdl-debug.showLogs', () => {
      outputChannel.show(true)
    })
  )

  context.subscriptions.push(
    vscode.commands.registerCommand(
      'extension.dfdl-debug.getValidatedTDMLPath',
      async (fileRequested = null) => {
        // Open native file explorer to allow user to select data file from anywhere on their machine
        return await getFile(
          fileRequested,
          'Select TDML File',
          'Select TDML File'
        )
      }
    )
  )

  context.subscriptions.push(
    vscode.commands.registerCommand(
      'extension.dfdl-debug.getValidatedTDMLCopyPath',
      async (fileRequested = null) => {
        // Open native file explorer to allow user to select data file from anywhere on their machine
        if (fileRequested && fs.existsSync(fileRequested)) {
          return fileRequested
        } else if (fileRequested && !fs.existsSync(fileRequested)) {
          return ''
        } else {
          return await showTDMLSaveDialog(
            fileRequested,
            'Save TDML File',
            'Save TDML File'
          )
        }
      }
    )
  )

  context.subscriptions.push(
    vscode.commands.registerCommand(
      'extension.dfdl-debug.getTDMLName',
      async (_) => {
        return await vscode.window
          .showInputBox({
            prompt: 'Test Case Name: ',
            value: 'Default Test Case',
          })
          .then((value) => {
            return value
          })
      }
    )
  )

  context.subscriptions.push(
    vscode.commands.registerCommand(
      'extension.dfdl-debug.getTDMLDescription',
      async (_) => {
        return await vscode.window
          .showInputBox({
            prompt: 'Test Case Description: ',
            value: 'Generated by DFDL VSCode Extension',
          })
          .then((value) => {
            return value
          })
      }
    )
  )

  context.subscriptions.push(
    vscode.commands.registerCommand(
      'extension.dfdl-debug.getTDMLPath',
      async (_) => {
        return await vscode.window
          .showInputBox({
            prompt: 'TDML File: ',
            value: '${workspaceFolder}/infoset.tdml',
          })
          .then((value) => {
            return value
          })
      }
    )
  )

  // register a configuration provider for 'dfdl' debug type
  const provider = new DaffodilConfigurationProvider(context)
  context.subscriptions.push(
    // register a configuration provider for 'dfdl' debug type
    vscode.debug.registerDebugConfigurationProvider('dfdl', provider),
    // register a dynamic configuration provider for 'dfdl' debug type
    vscode.debug.registerDebugConfigurationProvider(
      'dfdl',
      {
        provideDebugConfigurations(
          folder: WorkspaceFolder | undefined
        ): ProviderResult<DebugConfiguration[]> {
          if (!vscode.workspace.workspaceFolders) {
            return [
              getConfig({
                name: 'Daffodil Launch',
                request: 'launch',
                type: 'dfdl',
                schema: {
                  path: '${file}',
                  rootName: null,
                  rootNamespace: null,
                },
                data: '${command:AskForDataName}',
                debugServer: false,
                infosetFormat: 'xml',
                infosetOutput: {
                  type: 'file',
                  path: '${file}-infoset.xml',
                },
              }),
            ]
          }

          let targetResource = vscode.window.activeTextEditor
            ? vscode.window.activeTextEditor.document.uri
            : vscode.workspace.workspaceFolders[0].uri
          let infosetFile = `${
            path.basename(targetResource.fsPath).split('.')[0]
          }-infoset.xml`

          return [
            getConfig({
              name: 'Daffodil Launch',
              request: 'launch',
              type: 'dfdl',
              schema: {
                path: '${file}',
                rootName: null,
                rootNamespace: null,
              },
              data: '${command:AskForDataName}',
              debugServer: false,
              infosetFormat: 'xml',
              infosetOutput: {
                type: 'file',
                path: '${workspaceFolder}/' + infosetFile,
              },
            }),
          ]
        },
      },
      vscode.DebugConfigurationProviderTriggerKind.Dynamic
    )
  )

  if (!factory) {
    factory = new InlineDebugAdapterFactory(context)
  }
  context.subscriptions.push(
    vscode.debug.registerDebugAdapterDescriptorFactory('dfdl', factory)
  )
  if ('dispose' in factory) {
    context.subscriptions.push(factory as vscode.Disposable)
  }

  context.subscriptions.push(
    // override VS Code's default implementation of the debug hover
    vscode.languages.registerEvaluatableExpressionProvider('xml', {
      provideEvaluatableExpression(
        document: vscode.TextDocument,
        position: vscode.Position
      ): vscode.ProviderResult<vscode.EvaluatableExpression> {
        const wordRange = document.getWordRangeAtPosition(position)
        return wordRange
          ? new vscode.EvaluatableExpression(wordRange)
          : undefined
      },
    }),
    // override VS Code's default implementation of the "inline values" feature"
    vscode.languages.registerInlineValuesProvider('xml', {
      provideInlineValues(
        document: vscode.TextDocument,
        viewport: vscode.Range,
        context: vscode.InlineValueContext
      ): vscode.ProviderResult<vscode.InlineValue[]> {
        const allValues: vscode.InlineValue[] = []

        for (
          let l = viewport.start.line;
          l <= context.stoppedLocation.end.line;
          l++
        ) {
          const line = document.lineAt(l)
          var regExp = /local_[ifso]/gi // match variables of the form local_i, local_f, Local_i, LOCAL_S...
          do {
            var m = regExp.exec(line.text)
            if (m) {
              const varName = m[0]
              const varRange = new vscode.Range(
                l,
                m.index,
                l,
                m.index + varName.length
              )

              // value found via variable lookup
              allValues.push(
                new vscode.InlineValueVariableLookup(varRange, varName, false)
              )
            }
          } while (m)
        }

        return allValues
      },
    })
  )

  context.subscriptions.push(
    vscode.debug.onDidReceiveDebugSessionCustomEvent(handleDebugEvent)
  )

  dfdlLang.activate(context)
  dfdlExt.activate(context)
  infoset.activate(context)
  dataEditClient.activate(context)
  launchWizard.activate(context)
  tdmlEditor.activate(context)
  rootCompletion.activate(context)

  daffodilDebugErrors.activate()
}