Repository: vscode
Issue: RFC: (Engineering) Introduce A Reflectable Deserialization Helper
Labels: editor-core,engineering

## Current State

We have several places where we validate/deserialize JSON.
Validation can fail with error messages, defaults need to be inserted and a JSON schema is also usually provided.

Here are some examples of how we do it currently:

* Language Configuration
    * Validation:
    https://github.com/microsoft/vscode/blob/0f4df3d63b33adc850f6908bcf9276c342da99f9/src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts#L167
    * JSON Schema:
    https://github.com/microsoft/vscode/blob/0f4df3d63b33adc850f6908bcf9276c342da99f9/src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts#L545
    * Defaults?

* Editor Settings
    * TypeScript-Type-Def:
    https://github.com/microsoft/vscode/blob/0f4df3d63b33adc850f6908bcf9276c342da99f9/src/vs/editor/common/config/editorOptions.ts#L2535
    * Validation:
    https://github.com/microsoft/vscode/blob/0f4df3d63b33adc850f6908bcf9276c342da99f9/src/vs/editor/common/config/editorOptions.ts#L2637
    * Default:
    https://github.com/microsoft/vscode/blob/0f4df3d63b33adc850f6908bcf9276c342da99f9/src/vs/editor/common/config/editorOptions.ts#L2570
    * JSON Schema:
    https://github.com/microsoft/vscode/blob/0f4df3d63b33adc850f6908bcf9276c342da99f9/src/vs/editor/common/config/editorOptions.ts#L2595
* Processing of `args` in commands

## Problem

The current style of doing JSON deserialization/validation is very verbose and inconsistent.
There is no guarantee that the JSON-Schema matches the validation (though sometimes this is done on purpose).

## Proposed Solution

I suggest to explore introducing a generic, descriptive deserialization helper that allows to specify the typescript type, the validation logic, the default value and human readable descriptions at a single place. The JSON schema can be derived from that.

The outcome should be an internal helper (not an external library) that is similar to [io-ts](https://www.puzzle.ch/de/blog/articles/2019/09/25/data-contracts-and-transformations-with-io-ts) or my own library [hediet/semantic-json](https://github.com/hediet/semantic-json#basic-usage) ([example](https://github.com/hediet/visualization/blob/master/visualization-bundle/src/visualizers/grid-visualizer/index.tsx#L65)).

In case of `editor.minimap.side`, the code should look like this:
```ts
const editorMinimap = objectDeserializer({
    properties: {
        ...
        side: property(enumDeserializer(['left', 'right']), {
            defaultValue: 'left',
            description: nls.localize('minimap.side', "Controls the side where to render the minimap.")
        })
        ...
    }
});

const editorSettings = objectDeserializer({
    properties: {
        ...
        minimap: editorMinimap
        ...
    }
});

assert.deepStrictEqual(flatten(objectDeserializer({ properties: { editor: editorSettings } })).getJSONSchema(), {
    ...
    "editor.minimap.side": {
        type: 'string',
        enum: ['left', 'right'],
        default: 'left',
        description: "Controls the side where to render the minimap."
        ...
    }
    ...
});

```

People interested in this might be:
@alexdima @connor4312 @aeschli

I'm open to explore this idea further if there is interest in this.