in src/services/jsonCompletion.ts [419:498]
private getValueCompletions(schema: SchemaService.ResolvedSchema, doc: Parser.JSONDocument, node: ASTNode | undefined, offset: number, document: TextDocument, collector: CompletionsCollector, types: { [type: string]: boolean }): void {
let offsetForSeparator = offset;
let parentKey: string | undefined = undefined;
let valueNode: ASTNode | undefined = undefined;
if (node && (node.type === 'string' || node.type === 'number' || node.type === 'boolean' || node.type === 'null')) {
offsetForSeparator = node.offset + node.length;
valueNode = node;
node = node.parent;
}
if (!node) {
this.addSchemaValueCompletions(schema.schema, '', collector, types);
return;
}
if ((node.type === 'property') && offset > (node.colonOffset || 0)) {
const valueNode = node.valueNode;
if (valueNode && offset > (valueNode.offset + valueNode.length)) {
return; // we are past the value node
}
parentKey = node.keyNode.value;
node = node.parent;
}
if (node && (parentKey !== undefined || node.type === 'array')) {
const separatorAfter = this.evaluateSeparatorAfter(document, offsetForSeparator);
const matchingSchemas = doc.getMatchingSchemas(schema.schema, node.offset, valueNode);
for (const s of matchingSchemas) {
if (s.node === node && !s.inverted && s.schema) {
if (node.type === 'array' && s.schema.items) {
if (Array.isArray(s.schema.items)) {
const index = this.findItemAtOffset(node, document, offset);
if (index < s.schema.items.length) {
this.addSchemaValueCompletions(s.schema.items[index], separatorAfter, collector, types);
}
} else {
this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types);
}
}
if (parentKey !== undefined) {
let propertyMatched = false;
if (s.schema.properties) {
const propertySchema = s.schema.properties[parentKey];
if (propertySchema) {
propertyMatched = true;
this.addSchemaValueCompletions(propertySchema, separatorAfter, collector, types);
}
}
if (s.schema.patternProperties && !propertyMatched) {
for (const pattern of Object.keys(s.schema.patternProperties)) {
const regex = extendedRegExp(pattern);
if (regex?.test(parentKey)) {
propertyMatched = true;
const propertySchema = s.schema.patternProperties[pattern];
this.addSchemaValueCompletions(propertySchema, separatorAfter, collector, types);
}
}
}
if (s.schema.additionalProperties && !propertyMatched) {
const propertySchema = s.schema.additionalProperties;
this.addSchemaValueCompletions(propertySchema, separatorAfter, collector, types);
}
}
}
}
if (parentKey === '$schema' && !node.parent) {
this.addDollarSchemaCompletions(separatorAfter, collector);
}
if (types['boolean']) {
this.addBooleanValueCompletion(true, separatorAfter, collector);
this.addBooleanValueCompletion(false, separatorAfter, collector);
}
if (types['null']) {
this.addNullValueCompletion(separatorAfter, collector);
}
}
}