X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fimpl%2FYangParserImpl.java;h=c50aa3344f2cb877493c826bdc68904209ffc5ea;hb=553d41d63445d1e7d72e08bee39927dcd1ad8e4b;hp=7948158f4dee6b277493d8d2451395d3ee6b3d19;hpb=1c6811475b33129127a9e1e32bdccb199ea92afd;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java index 7948158f4d..c50aa3344f 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java @@ -18,7 +18,6 @@ import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.reso import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.base.Splitter; import com.google.common.collect.HashBiMap; import com.google.common.io.ByteSource; import java.io.File; @@ -47,11 +46,17 @@ import org.opendaylight.yangtools.antlrv4.code.gen.YangParser; import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.YangContext; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; import org.opendaylight.yangtools.yang.model.api.ModuleImport; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser; import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException; @@ -87,7 +92,6 @@ import org.slf4j.LoggerFactory; @Immutable public final class YangParserImpl implements YangContextParser { private static final Logger LOG = LoggerFactory.getLogger(YangParserImpl.class); - private static final Splitter COLON_SPLITTER = Splitter.on(':'); private static final YangParserImpl INSTANCE = new YangParserImpl(); public static YangParserImpl getInstance() { @@ -709,6 +713,7 @@ public final class YangParserImpl implements YangContextParser { resolveUsesForNodes(modules); resolveAugments(modules); resolveIdentities(modules); + checkChoiceCasesForDuplicityQNames(modules); // build final Map result = new LinkedHashMap<>(); @@ -967,6 +972,7 @@ public final class YangParserImpl implements YangContextParser { "Error in module {} at line {}: Unsupported augment target: {}. Augmentation process skipped.", module.getName(), augment.getLine(), potentialTargetNode); augment.setResolved(true); + augment.setUnsupportedTarget(true); return true; } } else { @@ -1022,7 +1028,8 @@ public final class YangParserImpl implements YangContextParser { } } - private void resolveIdentity(final ModuleBuilder module, final IdentitySchemaNodeBuilder identity) { + private void resolveIdentity(final ModuleBuilder module, + final IdentitySchemaNodeBuilder identity) { final String baseIdentityName = identity.getBaseIdentityName(); if (baseIdentityName != null) { IdentitySchemaNodeBuilder result = null; @@ -1030,15 +1037,34 @@ public final class YangParserImpl implements YangContextParser { final int line = identity.getLine(); String[] splittedBase = baseIdentityName.split(":"); if (splittedBase.length > 2) { - throw new YangParseException(module.getName(), line, "Failed to parse identityref base: " - + baseIdentityName); + throw new YangParseException(module.getName(), line, + "Failed to parse identityref base: " + + baseIdentityName); } String prefix = splittedBase[0]; String name = splittedBase[1]; - ModuleBuilder dependentModule = BuilderUtils.getModuleByPrefix(module, prefix); - result = BuilderUtils.findIdentity(dependentModule.getAddedIdentities(), name); + + if (prefix.equals(module.getPrefix()) + && name.equals(identity.getQName().getLocalName())) { + throw new YangParseException(module.getName(), + identity.getLine(), + "Failed to parse base, identity name equals base identity name: " + + baseIdentityName); + } + + ModuleBuilder dependentModule = BuilderUtils.getModuleByPrefix( + module, prefix); + result = BuilderUtils.findIdentity( + dependentModule.getAddedIdentities(), name); } else { - result = BuilderUtils.findIdentity(module.getAddedIdentities(), baseIdentityName); + if (baseIdentityName.equals(identity.getQName().getLocalName())) { + throw new YangParseException(module.getName(), + identity.getLine(), + "Failed to parse base, identity name equals base identity name: " + + baseIdentityName); + } + result = BuilderUtils.findIdentity(module.getAddedIdentities(), + baseIdentityName); } identity.setBaseIdentity(result); } @@ -1223,4 +1249,73 @@ public final class YangParserImpl implements YangContextParser { return null; } + + /** + * Traverse through modules and check if choice has choice cases with the + * same qname. + * + * @param modules + * all loaded modules + */ + private void checkChoiceCasesForDuplicityQNames(final Map> modules) { + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry childEntry : entry.getValue().entrySet()) { + final ModuleBuilder moduleBuilder = childEntry.getValue(); + final Module module = moduleBuilder.build(); + final List allChoicesFromModule = getChoicesFrom(module); + + for (ChoiceNode choiceNode : allChoicesFromModule) { + findDuplicityNodesIn(choiceNode, module, moduleBuilder, modules); + } + } + } + } + + private void findDuplicityNodesIn(final ChoiceNode choiceNode, final Module module, final ModuleBuilder moduleBuilder, + final Map> modules) { + final Set duplicityTestSet = new HashSet(); + + for (ChoiceCaseNode choiceCaseNode : choiceNode.getCases()) { + + for (DataSchemaNode childSchemaNode : choiceCaseNode.getChildNodes()) { + if (!duplicityTestSet.add(childSchemaNode.getQName())) { + final Optional schemaNodeBuilder = BuilderUtils.findSchemaNodeInModule(childSchemaNode.getPath(), moduleBuilder); + final String nameOfSchemaNode = childSchemaNode.getQName().getLocalName(); + int lineOfSchemaNode = 0; + + if (schemaNodeBuilder.isPresent()) { + lineOfSchemaNode = schemaNodeBuilder.get().getLine(); + } + throw new YangParseException(module.getName(), lineOfSchemaNode, + String.format("Choice has two nodes case with same qnames - %s", nameOfSchemaNode)); + } + } + } + } + + private List getChoicesFrom(final Module module) { + final List allChoices = new ArrayList(); + + for (DataSchemaNode dataSchemaNode : module.getChildNodes()) { + findChoicesIn(dataSchemaNode, allChoices); + } + return allChoices; + } + + private void findChoicesIn(final SchemaNode schemaNode, final Collection choiceNodes) { + if (schemaNode instanceof ContainerSchemaNode) { + final ContainerSchemaNode contSchemaNode = (ContainerSchemaNode) schemaNode; + for (DataSchemaNode dataSchemaNode : contSchemaNode.getChildNodes()) { + findChoicesIn(dataSchemaNode, choiceNodes); + } + } else if (schemaNode instanceof ListSchemaNode) { + final ListSchemaNode listSchemaNode = (ListSchemaNode) schemaNode; + for (DataSchemaNode dataSchemaNode : listSchemaNode.getChildNodes()) { + findChoicesIn(dataSchemaNode, choiceNodes); + } + } else if (schemaNode instanceof ChoiceNode) { + choiceNodes.add((ChoiceNode) schemaNode); + } + } + }