use of org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext in project sts4 by spring-projects.
the class SchemaBasedYamlASTReconciler method checkRequiredProperties.
private void checkRequiredProperties(Node parent, MappingNode map, YType type, Map<String, YTypedProperty> beanProperties, DynamicSchemaContext dc) {
Set<String> foundProps = NodeUtil.getScalarKeys(map);
boolean allPropertiesKnown = beanProperties.keySet().containsAll(foundProps);
// Don't check for missing properties if some properties look like they might be spelled incorrectly.
if (allPropertiesKnown) {
// Check for missing required properties:
List<YTypedProperty> missingProps = beanProperties.values().stream().filter(YTypedProperty::isRequired).filter(prop -> !foundProps.contains(prop.getName())).collect(CollectorUtil.toImmutableList());
Set<String> missingPropNames = missingProps.stream().map(YTypedProperty::getName).collect(Collectors.toCollection(TreeSet::new));
if (!missingPropNames.isEmpty()) {
String message;
if (missingPropNames.size() == 1) {
// slightly more specific message when only one missing property
String missing = missingPropNames.stream().findFirst().get();
message = "Property '" + missing + "' is required for '" + type + "'";
} else {
message = "Properties " + missingPropNames + " are required for '" + type + "'";
}
SchemaBasedSnippetGenerator snippetProvider = new SchemaBasedSnippetGenerator(typeUtil, SnippetBuilder::gimped);
Snippet snippet = snippetProvider.getSnippet(missingProps);
problems.accept(YamlSchemaProblems.missingProperties(message, dc, missingPropNames, snippet.getSnippet(), snippet.getPlaceHolder(1).getOffset(), parent, map, quickfixes.MISSING_PROP_FIX));
}
}
}
use of org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext in project sts4 by spring-projects.
the class ConcourseModel method addExtraInsertion.
private YValueHint addExtraInsertion(YValueHint h, DynamicSchemaContext dc) {
return new BasicYValueHint(h.getValue(), h.getLabel()).setExtraInsertion(() -> {
String resourceTypeName = h.getValue();
AbstractType sourceType = (AbstractType) resourceTypes.getSourceType(resourceTypeName);
if (sourceType != null && getParentPropertyNode("source", dc) == null) {
// don't auto insert what's already there!
List<YTypedProperty> requiredProps = sourceType.getProperties().stream().filter(p -> p.isRequired()).collect(Collectors.toList());
if (!requiredProps.isEmpty()) {
SnippetBuilder snippet = snippetBuilderFactory.get();
snippet.text("\nsource:");
for (YTypedProperty p : requiredProps) {
snippet.text("\n " + p.getName() + ": ");
snippet.placeHolder();
}
return snippet.toString();
}
}
return null;
});
}
use of org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext in project sts4 by spring-projects.
the class BoshCommandCloudConfigProviderTest method getStuff2.
@Test
public void getStuff2() throws Exception {
DynamicSchemaContext dc = Mockito.mock(DynamicSchemaContext.class);
provider.readWith(() -> "azs:\n" + "- cloud_properties:\n" + " datacenters:\n" + " - clusters:\n" + " - AppFabric: {}\n" + " name: z1\n" + "- cloud_properties:\n" + " datacenters:\n" + " - clusters:\n" + " - AppFabric: {}\n" + " name: z2\n" + "- cloud_properties:\n" + " datacenters:\n" + " - clusters:\n" + " - AppFabric: {}\n" + " name: z3\n" + "compilation:\n" + " az: z1\n" + " network: default-nw\n" + " reuse_compilation_vms: true\n" + " vm_type: default\n" + " workers: 5\n" + "disk_types:\n" + "- disk_size: 3000\n" + " name: default-dsk\n" + "- disk_size: 50000\n" + " name: large-dsk\n" + "networks:\n" + "- name: default-nw\n" + " subnets:\n" + " - azs:\n" + " - z1\n" + " - z2\n" + " - z3\n" + " cloud_properties:\n" + " name: VLAN 40 - AF\n" + " dns:\n" + " - 10.192.2.10\n" + " - 8.8.8.8\n" + " gateway: 10.194.4.1\n" + " range: 10.194.4.0/23\n" + " reserved:\n" + " - 10.194.4.1-10.194.4.34\n" + " - 10.194.4.40-10.194.5.255\n" + " type: manual\n" + "vm_extensions:\n" + "- cloud_properties: {}\n" + " name: fake-vmx-1\n" + "- cloud_properties: {}\n" + " name: fake-vmx-2\n" + "vm_types:\n" + "- cloud_properties:\n" + " cpu: 2\n" + " disk: 3240\n" + " ram: 1024\n" + " name: default-vm\n" + "- cloud_properties:\n" + " cpu: 2\n" + " disk: 30240\n" + " ram: 4096\n" + " name: large-vm\n");
CloudConfigModel cloudConfig = provider.getModel(dc);
assertEquals(ImmutableMultiset.of("default-vm", "large-vm"), cloudConfig.getVMTypes());
assertEquals(ImmutableMultiset.of("default-nw"), cloudConfig.getNetworkNames());
assertEquals(ImmutableMultiset.of("default-dsk", "large-dsk"), cloudConfig.getDiskTypes());
assertEquals(ImmutableMultiset.of("fake-vmx-1", "fake-vmx-2"), cloudConfig.getVMExtensions());
assertEquals(ImmutableMultiset.of("z1", "z2", "z3"), cloudConfig.getAvailabilityZones());
}
use of org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext in project sts4 by spring-projects.
the class YTypeAssistContext method getKeyCompletions.
public List<ICompletionProposal> getKeyCompletions(YamlDocument doc, SNode node, int offset, String query) throws Exception {
int queryOffset = offset - query.length();
DynamicSchemaContext dynamicCtxt = getSchemaContext();
List<YTypedProperty> allProperties = typeUtil.getProperties(type);
if (CollectionUtil.hasElements(allProperties)) {
List<List<YTypedProperty>> tieredProperties = sortIntoTiers(allProperties);
Set<String> definedProps = dynamicCtxt.getDefinedProperties();
List<ICompletionProposal> proposals = new ArrayList<>();
boolean suggestDeprecated = typeUtil.suggestDeprecatedProperties();
YamlIndentUtil indenter = new YamlIndentUtil(doc);
for (List<YTypedProperty> thisTier : tieredProperties) {
List<YTypedProperty> undefinedProps = thisTier.stream().filter(p -> !definedProps.contains(p.getName()) && (suggestDeprecated || !p.isDeprecated())).collect(Collectors.toList());
if (!undefinedProps.isEmpty()) {
for (YTypedProperty p : undefinedProps) {
String name = p.getName();
double score = FuzzyMatcher.matchScore(query, name);
if (score != 0) {
TypeBasedSnippetProvider snippetProvider = typeUtil.getSnippetProvider();
DocumentEdits edits;
if (snippetProvider != null) {
// Generate edits from snippet
Snippet snippet = snippetProvider.getSnippet(p);
edits = createEditFromSnippet(doc, node, offset, query, indenter, snippet);
} else {
// Generate edits the old-fashioned way
edits = new DocumentEdits(doc.getDocument());
YType YType = p.getType();
edits.delete(queryOffset, query);
int referenceIndent = doc.getColumn(queryOffset);
boolean needNewline = node.getNodeType() == SNodeType.KEY;
StringBuilder snippet = new StringBuilder();
if (needNewline) {
snippet.append("\n");
referenceIndent = YamlIndentUtil.getNewChildKeyIndent(node);
} else if (queryOffset > 0 && !Character.isWhitespace(doc.getChar(queryOffset - 1))) {
// See https://www.pivotaltracker.com/story/show/137722057
snippet.append(" ");
referenceIndent++;
}
snippet.append(p.getName());
snippet.append(":");
snippet.append(appendTextFor(YType));
edits.insert(queryOffset, indenter.applyIndentation(snippet.toString(), referenceIndent));
}
ICompletionProposal completion = completionFactory().beanProperty(doc.getDocument(), contextPath.toPropString(), getType(), query, p, score, edits, typeUtil);
if (p.isDeprecated() && completion instanceof ScoreableProposal) {
completion.deemphasize(DEEMP_DEPRECATION);
}
proposals.add(completion);
}
}
}
// We should only move on to the next tier if all required properties in this tier are defined.
if (undefinedProps.stream().anyMatch(p -> p.isRequired())) {
// stop here, take no more from next tier!
return proposals;
}
}
return proposals;
}
return Collections.emptyList();
}
use of org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext in project sts4 by spring-projects.
the class SchemaBasedYamlASTReconciler method reconcile.
private void reconcile(YamlFileAST ast, YamlPath path, Node parent, Node node, YType _type) {
// IDocument doc = ast.getDocument();
if (_type != null && !skipReconciling(node)) {
DynamicSchemaContext schemaContext = new ASTDynamicSchemaContext(ast, path, node);
YType type = typeUtil.inferMoreSpecificType(_type, schemaContext);
if (typeCollector != null) {
typeCollector.accept(node, type);
}
checkConstraints(parent, node, type, schemaContext);
switch(getNodeId(node)) {
case mapping:
MappingNode map = (MappingNode) node;
checkForDuplicateKeys(map);
if (typeUtil.isMap(type)) {
for (NodeTuple entry : map.getValue()) {
String key = NodeUtil.asScalar(entry.getKeyNode());
reconcile(ast, keyAt(path, key), map, entry.getKeyNode(), typeUtil.getKeyType(type));
reconcile(ast, valueAt(path, key), map, entry.getValueNode(), typeUtil.getDomainType(type));
}
} else if (typeUtil.isBean(type)) {
Map<String, YTypedProperty> beanProperties = typeUtil.getPropertiesMap(type);
checkRequiredProperties(parent, map, type, beanProperties, schemaContext);
for (NodeTuple entry : map.getValue()) {
Node keyNode = entry.getKeyNode();
String key = NodeUtil.asScalar(keyNode);
if (key == null) {
expectScalar(node);
} else {
YTypedProperty prop = beanProperties.get(key);
if (prop == null) {
unknownBeanProperty(keyNode, type, key);
} else {
if (prop.isDeprecated()) {
String msg = prop.getDeprecationMessage();
if (StringUtil.hasText(msg)) {
problems.accept(YamlSchemaProblems.deprecatedProperty(msg, keyNode));
} else {
problems.accept(YamlSchemaProblems.deprecatedProperty(keyNode, type, prop));
}
}
reconcile(ast, valueAt(path, key), map, entry.getValueNode(), prop.getType());
}
}
}
} else {
expectTypeButFoundMap(type, node);
}
break;
case sequence:
SequenceNode seq = (SequenceNode) node;
if (typeUtil.isSequencable(type)) {
for (int i = 0; i < seq.getValue().size(); i++) {
Node el = seq.getValue().get(i);
reconcile(ast, valueAt(path, i), seq, el, typeUtil.getDomainType(type));
}
} else {
expectTypeButFoundSequence(type, node);
}
break;
case scalar:
if (typeUtil.isAtomic(type)) {
SchemaContextAware<ValueParser> parserProvider = typeUtil.getValueParser(type);
if (parserProvider != null) {
// Take care not to execute parserProvider early just to check how long it should be delayed.
delayedConstraints.add(() -> {
parserProvider.safeWithContext(schemaContext).ifPresent(parser -> {
if (parser.longRunning()) {
slowDelayedConstraints.add(() -> {
parse(ast, node, type, parser);
});
} else {
parse(ast, node, type, parser);
}
});
});
}
} else {
expectTypeButFoundScalar(type, node);
}
break;
default:
}
}
}
Aggregations