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;
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;
@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() {
if (targetModule == null) {
Module result = findModuleFromContext(context, module, prefix, 0);
targetModule = new ModuleBuilder(result);
- TreeMap<Date, ModuleBuilder> map = modules.get(prefix);
+ TreeMap<Date, ModuleBuilder> map = modules.get(targetModule.getNamespace());
if (map == null) {
map = new TreeMap<>();
map.put(targetModule.getRevision(), targetModule);
resolveUsesForNodes(modules);
resolveAugments(modules);
resolveIdentities(modules);
+ checkChoiceCasesForDuplicityQNames(modules);
// build
final Map<ModuleBuilder, Module> result = new LinkedHashMap<>();
"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 {
}
}
- 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;
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);
}
ModuleBuilder module = BuilderUtils.getParentModule(usesNode);
final GroupingBuilder targetGroupingBuilder = GroupingUtils.getTargetGroupingFromModules(usesNode, modules,
module);
- if (targetGroupingBuilder == null) {
- throw new YangParseException(module.getName(), usesNode.getLine(), "Referenced grouping '"
- + usesNode.getGroupingPath() + "' not found.");
- }
usesNode.setGrouping(targetGroupingBuilder);
}
}
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<URI, TreeMap<Date, ModuleBuilder>> modules) {
+ for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+ for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
+ final ModuleBuilder moduleBuilder = childEntry.getValue();
+ final Module module = moduleBuilder.build();
+ final List<ChoiceNode> 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<URI, TreeMap<Date, ModuleBuilder>> modules) {
+ final Set<QName> duplicityTestSet = new HashSet<QName>();
+
+ for (ChoiceCaseNode choiceCaseNode : choiceNode.getCases()) {
+
+ for (DataSchemaNode childSchemaNode : choiceCaseNode.getChildNodes()) {
+ if (!duplicityTestSet.add(childSchemaNode.getQName())) {
+ final Optional<SchemaNodeBuilder> 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<ChoiceNode> getChoicesFrom(final Module module) {
+ final List<ChoiceNode> allChoices = new ArrayList<ChoiceNode>();
+
+ for (DataSchemaNode dataSchemaNode : module.getChildNodes()) {
+ findChoicesIn(dataSchemaNode, allChoices);
+ }
+ return allChoices;
+ }
+
+ private void findChoicesIn(final SchemaNode schemaNode, final Collection<ChoiceNode> 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);
+ }
+ }
+
}