private getSchemaLessValueCompletions()

in src/services/jsonCompletion.ts [341:416]


	private getSchemaLessValueCompletions(doc: Parser.JSONDocument, node: ASTNode | undefined, offset: number, document: TextDocument, collector: CompletionsCollector): void {
		let offsetForSeparator = offset;
		if (node && (node.type === 'string' || node.type === 'number' || node.type === 'boolean' || node.type === 'null')) {
			offsetForSeparator = node.offset + node.length;
			node = node.parent;
		}

		if (!node) {
			collector.add({
				kind: this.getSuggestionKind('object'),
				label: 'Empty object',
				insertText: this.getInsertTextForValue({}, ''),
				insertTextFormat: InsertTextFormat.Snippet,
				documentation: ''
			});
			collector.add({
				kind: this.getSuggestionKind('array'),
				label: 'Empty array',
				insertText: this.getInsertTextForValue([], ''),
				insertTextFormat: InsertTextFormat.Snippet,
				documentation: ''
			});
			return;
		}
		const separatorAfter = this.evaluateSeparatorAfter(document, offsetForSeparator);
		const collectSuggestionsForValues = (value: ASTNode) => {
			if (value.parent && !Parser.contains(value.parent, offset, true)) {
				collector.add({
					kind: this.getSuggestionKind(value.type),
					label: this.getLabelTextForMatchingNode(value, document),
					insertText: this.getInsertTextForMatchingNode(value, document, separatorAfter),
					insertTextFormat: InsertTextFormat.Snippet, documentation: ''
				});
			}
			if (value.type === 'boolean') {
				this.addBooleanValueCompletion(!value.value, separatorAfter, collector);
			}
		};

		if (node.type === 'property') {
			if (offset > (node.colonOffset || 0)) {

				const valueNode = node.valueNode;
				if (valueNode && (offset > (valueNode.offset + valueNode.length) || valueNode.type === 'object' || valueNode.type === 'array')) {
					return;
				}
				// suggest values at the same key
				const parentKey = node.keyNode.value;
				doc.visit(n => {
					if (n.type === 'property' && n.keyNode.value === parentKey && n.valueNode) {
						collectSuggestionsForValues(n.valueNode);
					}
					return true;
				});
				if (parentKey === '$schema' && node.parent && !node.parent.parent) {
					this.addDollarSchemaCompletions(separatorAfter, collector);
				}
			}
		}
		if (node.type === 'array') {
			if (node.parent && node.parent.type === 'property') {

				// suggest items of an array at the same key
				const parentKey = node.parent.keyNode.value;
				doc.visit((n) => {
					if (n.type === 'property' && n.keyNode.value === parentKey && n.valueNode && n.valueNode.type === 'array') {
						n.valueNode.items.forEach(collectSuggestionsForValues);
					}
					return true;
				});
			} else {
				// suggest items in the same array
				node.items.forEach(collectSuggestionsForValues);
			}
		}
	}