# Powderhouse Validation
This is a draft of the validation design that was discussed this week. This is part of the outcome of issues raised in #2458.
Powderhouse validation is intended to make the easy stuff easy and predictable, and be able to extend what is easy, with decent performance. This is accomplished with several moving parts, with the expectation that the CLI author will only need to know about the extension methods (likely later extension properties) that appear in their IntelliSense.
We also want to:
- Maintain isolation between the CLI tree and the pipeline to enforce the core/subsystem boundary
- Allow usage of validation without using the pipeline
- Make simple things simple for the CLI author
- Allow new validators to be fairly simple without requiring an understanding of the pipeline or validation orchestration
- Allow
ValueConditions (validatable conditions for symbol data) to be used for other by other subsystems - Allow validation between symbols and at a command level for inclusive/exclusive sets
- Provide consistent diagnostic messages, without allocation when there are no failures
- Continue to provide an anonymous validator for those scenarios we cannot predict
Annotation collections
Annotation collections are expected to be added to the annotation system.
Currently AnnotationIds identify single values. If that value is not found in the default provider (strongly typed weak table), additional providers are queried until the first value is found.
Annotation collections also use an AnnotationId to identify values. However, each provider may include a collection of values and the returned value is a collection of all those values.
The two known use cases are ValueConditions and examples.
ValueCondition
Validation determines whether expectations about the values supplied for symbols are met. Those expectations can also drive completions and contribute to rich help. Thus, the definition of what should be validated (such as a range) is held in ValueCondition and the annotation collection for the value condition annotation Id derive from the abstract class ValueCondition.
Extension methods
CLI authors will rarely if ever create ValueConditions. Instead extension methods on symbol allow syntax like:
myOption.AddRange(1,5);
ValidationSubsystem
A ValidationSubsystem is held by the pipeline and called to perform validation. It holds a set of validators.
Validators
Validators derive from the abstract Validator class and perform validation. Validators have a name for debugging, and a set of ValueConditon types that they can validate.
Flow (with pipeline)
- The CLI author calls extension methods
- The extension methods add to the
ValueConditiondata in the default annotation provider (strongly typed weak table) - After the CLI tree is created, the CLI author's code creates a pipeline and uses it and the CLI tree to parse the end user's command line entry
- If nothing terminates processing prior to validation, the pipeline calls the
ValidationSubsystem - The
ValidationSubsystemcreates a dictionary of specificValueConditiontypes from the registered validators. Validators may be registered for more than one type, but noValueConditiontype can have more than one validator registered - The
ValidationSubsystemiterates through symbols in the order:- Options and arguments of the leaf command
- The leaf command
- Options and arguments of the leaf's parent
- The leaf's parent's command
- And so on to the root command
- For each symbol
- All
ValueConditionannotations for the symbol are retrieved - For each
ValueCondition- The appropriate validator is retrieved
- If no validator is found, and the
ValueConditionrequires a validator, a validation diagnostic of a missing validator is created - If a validator is found, it's validation is run and a validation diagnostic created on failure
- All