private getValueCompletions()

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);
			}
		}

	}