import { Mark } from 'vega-lite/build/src/mark' ; import { QueryConfig } from './config' ; import { checkEncoding } from './constraint/encoding' ; import { checkSpec } from './constraint/spec' ; import { WildcardIndex } from './wildcardindex' ; import { SpecQueryModel } from './model' ; import { Property , ENCODING_TOPLEVEL_PROPS , ENCODING_NESTED_PROPS } from './property' ; import { PropIndex } from './propindex' ; import { Wildcard } from './wildcard' ; import { Schema } from './schema' ; import { isValueQuery , isDisabledAutoCountQuery } from './query/encoding' ; const ENUMERATOR_INDEX = new PropIndex < EnumeratorFactory > ( ) ; export interface Enumerator { ( answerSets , specM ) : SpecQueryModel [ ] ; } export function getEnumerator ( prop ) { return ENUMERATOR_INDEX . get ( prop ) ; } export interface EnumeratorFactory { ( wildcardIndex , schema , opt ) : Enumerator ; } ENUMERATOR_INDEX . set ( 'mark' , ( wildcardIndex , schema , opt ) : Enumerator => { return ( answerSet , specM ) => { const markWildcard = specM . getMark ( ) as Wildcard < Mark > ; markWildcard . enum . forEach ( ( mark ) => { specM . setMark ( mark ) ; const violatedSpecConstraint = checkSpec ( 'mark' , wildcardIndex . mark , specM , schema , opt ) ; if ( ! violatedSpecConstraint ) { answerSet . push ( specM . duplicate ( ) ) ; } } ) ; specM . resetMark ( ) ; return answerSet ; } ; } ) ; ENCODING_TOPLEVEL_PROPS . forEach ( ( prop ) => { ENUMERATOR_INDEX . set ( prop , EncodingPropertyGeneratorFactory ( prop ) ) ; } ) ; ENCODING_NESTED_PROPS . forEach ( ( nestedProp ) => { ENUMERATOR_INDEX . set ( nestedProp , EncodingPropertyGeneratorFactory ( nestedProp ) ) ; } ) ; param prop return export function EncodingPropertyGeneratorFactory ( prop ) { return return ( wildcardIndex , schema , opt ) : Enumerator => { return ( answerSet , specM ) => { const indices = wildcardIndex . encodingIndicesByProperty . get ( prop ) ; function enumerate ( jobIndex ) { if ( jobIndex === indices . length ) { answerSet . push ( specM . duplicate ( ) ) ; return ; } const index = indices [ jobIndex ] ; const wildcard = wildcardIndex . encodings [ index ] . get ( prop ) ; const encQ = specM . getEncodingQueryByIndex ( index ) ; const propWildcard = specM . getEncodingProperty ( index , prop ) ; if ( isValueQuery ( encQ ) || isDisabledAutoCountQuery ( encQ ) || ! propWildcard ) { enumerate ( jobIndex + 1 ) ; } else { wildcard . enum . forEach ( ( propVal ) => { if ( propVal === null ) { propVal = undefined ; } specM . setEncodingProperty ( index , prop , propVal , wildcard ) ; const violatedEncodingConstraint = checkEncoding ( prop , wildcard , index , specM , schema , opt ) ; if ( violatedEncodingConstraint ) { return ; } const violatedSpecConstraint = checkSpec ( prop , wildcard , specM , schema , opt ) ; if ( violatedSpecConstraint ) { return ; } enumerate ( jobIndex + 1 ) ; } ) ; specM . resetEncodingProperty ( index , prop , wildcard ) ; } } enumerate ( 0 ) ; return answerSet ; } ; } ; }