diff --git a/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/processor/YangProcessor.java b/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/processor/YangProcessor.java index 38141d4c..23fb698f 100644 --- a/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/processor/YangProcessor.java +++ b/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/processor/YangProcessor.java @@ -2,6 +2,7 @@ import static com.google.common.collect.Lists.newArrayList; +import java.util.ArrayList; import java.util.List; import org.eclipse.emf.common.notify.Adapter; @@ -93,14 +94,18 @@ protected ProcessedDataModel processInternal(List modules, List< var evalCtx = new FeatureEvaluationContext(includedFeatures, excludedFeatures); ProcessedDataModel processedModel = new ProcessedDataModel(); collectResourceErrors(modules.get(0), processedModel); - + List deviations = new ArrayList<>(); + List augments = new ArrayList<>(); modules.forEach((module) -> module.eAllContents().forEachRemaining((ele) -> { if (ele instanceof Deviate) { - processDeviate((Deviate) ele, module, processedModel); + deviations.add((Deviate) ele); } else if (ele instanceof Augment) { - processAugment((Augment) ele, module, evalCtx); + augments.add((Augment) ele); } })); + + deviations.forEach(dev -> processDeviate(dev, processedModel)); + augments.forEach(augm -> processAugment(augm, evalCtx)); modules.forEach((module) -> { String prefix = null; @@ -128,11 +133,13 @@ private void collectResourceErrors(AbstractModule entryModule, ProcessedDataMode * min-elements, must, type, unique, units. Properties 'must' and 'unique' are * 0..n */ - protected void processDeviate(Deviate deviate, AbstractModule module, ProcessedDataModel processedModel) { + protected void processDeviate(Deviate deviate, ProcessedDataModel processedModel) { + var moduleFileName = moduleFileName(deviate); var deviation = (Deviation) deviate.eContainer(); SchemaNode targetNode = deviation.getReference().getSchemaNode(); + if (targetNode == null || targetNode.eIsProxy()) { - processedModel.addProcessorError(moduleFileName(module), deviation.getReference(), + processedModel.addProcessorError(moduleFileName, deviation.getReference(), "Deviation target node not found"); return; } @@ -147,7 +154,7 @@ protected void processDeviate(Deviate deviate, AbstractModule module, ProcessedD .filter(child -> child.eClass() == statement.eClass()).findFirst(); if (existingProperty.isPresent()) { error = true; - processedModel.addProcessorError(moduleFileName(module), statement, + processedModel.addProcessorError(moduleFileName, statement, "the \"" + YangNameUtils.getYangName(statement) + "\" property already exists in node \"" + nodeQName(targetNode) + "\""); } @@ -166,7 +173,7 @@ protected void processDeviate(Deviate deviate, AbstractModule module, ProcessedD if (existingProperty.isPresent()) { targetNode.getSubstatements().remove(existingProperty.get()); } else { - processedModel.addProcessorError(moduleFileName(module), statement, + processedModel.addProcessorError(moduleFileName, statement, "the \"" + YangNameUtils.getYangName(statement) + "\" property does not exist in node \"" + nodeQName(targetNode) + "\""); } @@ -185,7 +192,7 @@ protected void processDeviate(Deviate deviate, AbstractModule module, ProcessedD // config could be inherited from parent or be default = true targetNode.getSubstatements().add(ProcessorUtility.copyEObject(statement)); } else { - processedModel.addProcessorError(moduleFileName(module), statement, + processedModel.addProcessorError(moduleFileName, statement, "the \"" + YangNameUtils.getYangName(statement) + "\" property does not exist in node \"" + nodeQName(targetNode) + "\""); } @@ -195,7 +202,7 @@ protected void processDeviate(Deviate deviate, AbstractModule module, ProcessedD case "not-supported": if (targetNode.eContainer() == null) { if (!Objects.equal("not-supported", DeviationAdapter.find(targetNode))) { - processedModel.addProcessorError(moduleFileName(module), deviation.getReference(), + processedModel.addProcessorError(moduleFileName, deviation.getReference(), "Deviation target node has no parent."); } break; @@ -209,8 +216,8 @@ protected void processDeviate(Deviate deviate, AbstractModule module, ProcessedD } } - protected String moduleFileName(AbstractModule module) { - return module.eResource().getURI().lastSegment(); + protected String moduleFileName(EObject eObj) { + return eObj.eResource().getURI().lastSegment(); } protected String nodeQName(SchemaNode node) { @@ -249,14 +256,14 @@ protected boolean matchingArguments(Statement candidate, Statement objToMatch) { return true; } - protected void processAugment(Augment augment, AbstractModule module, FeatureEvaluationContext evalCtx) { + protected void processAugment(Augment augment, FeatureEvaluationContext evalCtx) { List ifFeatures = ProcessorUtility.findIfFeatures(augment); boolean featuresMatch = ProcessorUtility.checkIfFeatures(ifFeatures, evalCtx); // disabled by feature if (!featuresMatch) { return; } - var globalModuleId = ProcessorUtility.moduleIdentifier(module); + var globalModuleId = ProcessorUtility.moduleIdentifier(augment); augment.getSubstatements().stream().filter(sub -> !(sub instanceof IfFeature)).forEach((subStatement) -> { // TODO check what can be added diff --git a/yang-lsp/io.typefox.yang/src/test/java/io/typefox/yang/tests/processor/DeviationTest.xtend b/yang-lsp/io.typefox.yang/src/test/java/io/typefox/yang/tests/processor/DeviationTest.xtend index 8469b824..6d78c1ad 100644 --- a/yang-lsp/io.typefox.yang/src/test/java/io/typefox/yang/tests/processor/DeviationTest.xtend +++ b/yang-lsp/io.typefox.yang/src/test/java/io/typefox/yang/tests/processor/DeviationTest.xtend @@ -6,6 +6,7 @@ import io.typefox.yang.tests.AbstractYangTest import org.junit.Test import static org.junit.Assert.assertEquals +import io.typefox.yang.processor.DataTreeSerializer class DeviationTest extends AbstractYangTest { @@ -303,11 +304,45 @@ class DeviationTest extends AbstractYangTest { val processor = new YangProcessor() val processedData = processor.process(#[mainModule], null, null) assertEquals(2, processedData.messages.size) - assertEquals( - "__synthetic0.yang:15:9 Error: mismatched input 'le' expecting '}'", + assertEquals("__synthetic0.yang:15:9 Error: mismatched input 'le' expecting '}'", processedData.messages.head.toString) - assertEquals( - "__synthetic0.yang:19:9 Error: missing EOF at 'container'", - processedData.messages.get(1).toString) + assertEquals("__synthetic0.yang:19:9 Error: missing EOF at 'container'", processedData.messages.get(1).toString) + } + + @Test + def void testDeviateAugmentedNode() { + + val mainModule = ''' + module base-test-module { + yang-version 1.1; + namespace yang:base-test-module; + prefix btm; + + container system { + leaf simple-leaf { + type string; + } + } + + augment "/btm:system" { + container encrypted-private-key { + leaf encrypted-key { + type string; + } + } + } + + deviation "/system/encrypted-private-key" { + deviate not-supported; + } + } + '''.loadWithSyntaxErrors().root + val processor = new YangProcessor() + val processedData = processor.process(#[mainModule], null, null) + assertEquals(''' + module: base-test-module + +--rw system + +--rw simple-leaf? string + '''.toString, new DataTreeSerializer().serialize(processedData.modules.get(0)).toString) } }