import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseStatus;
import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseTypeWithBody;
import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUnits;
-import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUnknownTypeWithBody;
import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUserOrdered;
import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseYinValue;
import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.stringFromNode;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
-
import java.net.URI;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
-
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.Set;
import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Argument_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Base_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Yang_version_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParserBaseListener;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.util.BaseTypes;
import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
import org.opendaylight.yangtools.yang.parser.builder.api.ExtensionBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
import org.opendaylight.yangtools.yang.parser.builder.impl.AnyXmlBuilder;
import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilderImpl;
+import org.opendaylight.yangtools.yang.parser.util.YangParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class YangParserListenerImpl extends YangParserBaseListener {
- private static final Logger LOGGER = LoggerFactory.getLogger(YangParserListenerImpl.class);
+ private static final Logger LOG = LoggerFactory.getLogger(YangParserListenerImpl.class);
+ private static final Splitter SLASH_SPLITTER = Splitter.on('/').omitEmptyStrings();
private static final Splitter COLON_SPLITTER = Splitter.on(':');
private static final String AUGMENT_STR = "augment";
- private final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+ private static final String IMPORT_STR = "import";
+ private static final String UNION_STR = "union";
+ private static final String UNKNOWN_NODE_STR = "unknown-node";
+
+ /**
+ * Date Format is not thread-safe so we cannot make constant from it.
+ */
+ private final DateFormat revisionFormat = new SimpleDateFormat("yyyy-MM-dd");
private final SchemaPathStack stack = new SchemaPathStack();
+ private final Map<String, NavigableMap<Date, URI>> namespaceContext;
private final String sourcePath;
- private QName moduleQName = new QName(null, new Date(0L), null, "dummy");
+ private QName moduleQName = QName.create(null, new Date(0L), "dummy");
private ModuleBuilder moduleBuilder;
private String moduleName;
private int augmentOrder;
+ private String yangModelPrefix;
- public YangParserListenerImpl(final String sourcePath) {
+ public YangParserListenerImpl(final Map<String, NavigableMap<Date, URI>> namespaceContext, final String sourcePath) {
+ this.namespaceContext = namespaceContext;
this.sourcePath = sourcePath;
}
+ /**
+ * Create a new instance.
+ *
+ * FIXME: the resulting type needs to be extracted, such that we can reuse
+ * the "BaseListener" aspect, which need not be exposed to the user. Maybe
+ * factor out a base class into repo.spi?
+ *
+ * @param namespaceContext namespaceContext
+ * @param sourcePath sourcePath
+ * @param walker walker
+ * @param tree tree
+ * @return new instance of YangParserListenerImpl
+ */
+ public static YangParserListenerImpl create(final Map<String, NavigableMap<Date, URI>> namespaceContext,
+ final String sourcePath, final ParseTreeWalker walker, final ParseTree tree) {
+ final YangParserListenerImpl ret = new YangParserListenerImpl(namespaceContext, sourcePath);
+ walker.walk(ret, tree);
+ return ret;
+ }
+
@Override
public void enterModule_stmt(final YangParser.Module_stmtContext ctx) {
moduleName = stringFromNode(ctx);
- LOGGER.trace("entering module {}", moduleName);
+ LOG.trace("entering module {}", moduleName);
enterLog("module", moduleName, 0);
stack.push();
String description = null;
String reference = null;
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Description_stmtContext) {
description = stringFromNode(child);
} else if (child instanceof Reference_stmtContext) {
@Override
public void enterSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
moduleName = stringFromNode(ctx);
- LOGGER.trace("entering submodule {}", moduleName);
+ LOG.trace("entering submodule {}", moduleName);
enterLog("submodule", moduleName, 0);
stack.push();
String description = null;
String reference = null;
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Description_stmtContext) {
description = stringFromNode(child);
} else if (child instanceof Reference_stmtContext) {
@Override
public void enterBelongs_to_stmt(final YangParser.Belongs_to_stmtContext ctx) {
- moduleBuilder.setBelongsTo(stringFromNode(ctx));
+ final String belongsTo = stringFromNode(ctx);
+ final NavigableMap<Date, URI> context = namespaceContext.get(belongsTo);
+ final Map.Entry<Date, URI> entry = context.firstEntry();
+ // TODO
+ // Submodule will contain namespace and revision from module to which it
+ // belongs. If there are multiple modules with same name and different
+ // revisions, it will has revision from the newest one.
+ this.moduleQName = QName.create(entry.getValue(), entry.getKey(), moduleQName.getLocalName());
+ moduleBuilder.setQNameModule(moduleQName.getModule());
+ moduleBuilder.setBelongsTo(belongsTo);
+ for (int i = 0; i < ctx.getChildCount(); ++i) {
+ final ParseTree treeNode = ctx.getChild(i);
+ if (treeNode instanceof Prefix_stmtContext) {
+ yangModelPrefix = stringFromNode(treeNode);
+ moduleBuilder.setPrefix(yangModelPrefix);
+ setLog("prefix", yangModelPrefix);
+ }
+ }
}
@Override
if (treeNode instanceof Namespace_stmtContext) {
final String namespaceStr = stringFromNode(treeNode);
final URI namespace = URI.create(namespaceStr);
- this.moduleQName = new QName(namespace, moduleQName.getRevision(), moduleQName.getPrefix(), moduleQName.getLocalName());
+ this.moduleQName = QName.create(namespace, moduleQName.getRevision(), moduleQName.getLocalName());
moduleBuilder.setQNameModule(moduleQName.getModule());
setLog("namespace", namespaceStr);
} else if (treeNode instanceof Prefix_stmtContext) {
- final String yangModelPrefix = stringFromNode(treeNode);
- this.moduleQName = new QName(moduleQName.getNamespace(), moduleQName.getRevision(), yangModelPrefix, moduleQName.getLocalName());
+ yangModelPrefix = stringFromNode(treeNode);
+ this.moduleQName = QName.create(moduleQName.getModule(), moduleQName.getLocalName());
moduleBuilder.setPrefix(yangModelPrefix);
setLog("prefix", yangModelPrefix);
} else if (treeNode instanceof Yang_version_stmtContext) {
public void enterMeta_stmts(final YangParser.Meta_stmtsContext ctx) {
enterLog("meta_stmt", "", ctx.getStart().getLine());
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Organization_stmtContext) {
final String organization = stringFromNode(child);
moduleBuilder.setOrganization(organization);
private void updateRevisionForRevisionStatement(final ParseTree treeNode) {
final String revisionDateStr = stringFromNode(treeNode);
try {
- final Date revisionDate = SIMPLE_DATE_FORMAT.parse(revisionDateStr);
+ final Date revisionDate = revisionFormat.parse(revisionDateStr);
if ((revisionDate != null) && (this.moduleQName.getRevision().compareTo(revisionDate) < 0)) {
- this.moduleQName = new QName(moduleQName.getNamespace(), revisionDate, moduleQName.getPrefix(), moduleQName.getLocalName());
+ this.moduleQName = QName.create(moduleQName.getNamespace(), revisionDate, moduleQName.getLocalName());
moduleBuilder.setQNameModule(moduleQName.getModule());
setLog("revision", revisionDate.toString());
for (int i = 0; i < treeNode.getChildCount(); ++i) {
- ParseTree child = treeNode.getChild(i);
+ final ParseTree child = treeNode.getChild(i);
if (child instanceof Reference_stmtContext) {
moduleBuilder.setReference(stringFromNode(child));
}
}
}
- } catch (ParseException e) {
- final String message = "Failed to parse revision string: " + revisionDateStr;
- LOGGER.warn(message);
+ } catch (final ParseException e) {
+ LOG.warn("Failed to parse revision string: {}", revisionDateStr, e);
}
}
public void enterImport_stmt(final Import_stmtContext ctx) {
final int line = ctx.getStart().getLine();
final String importName = stringFromNode(ctx);
- enterLog("import", importName, line);
+ enterLog(IMPORT_STR, importName, line);
String importPrefix = null;
Date importRevision = null;
final ParseTree treeNode = ctx.getChild(i);
if (treeNode instanceof Prefix_stmtContext) {
importPrefix = stringFromNode(treeNode);
- }
- if (treeNode instanceof Revision_date_stmtContext) {
- String importRevisionStr = stringFromNode(treeNode);
+ } else if (treeNode instanceof Revision_date_stmtContext) {
+ final String importRevisionStr = stringFromNode(treeNode);
try {
- importRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
- } catch (ParseException e) {
- LOGGER.warn("Failed to parse import revision-date at line " + line + ": " + importRevisionStr);
+ importRevision = revisionFormat.parse(importRevisionStr);
+ } catch (final ParseException e) {
+ LOG.warn("Failed to parse import revision-date at line {}: {}", line, importRevisionStr, e);
}
}
}
moduleBuilder.addModuleImport(importName, importRevision, importPrefix);
- setLog("import", "(" + importName + "; " + importRevision + "; " + importPrefix + ")");
+ LOG.trace("setting import ({}; {}; {})", importName, importRevision, importPrefix);
}
@Override
public void exitImport_stmt(final Import_stmtContext ctx) {
- exitLog("import");
+ exitLog(IMPORT_STR);
+ }
+
+ @Override
+ public void enterInclude_stmt(final YangParser.Include_stmtContext ctx) {
+ final int line = ctx.getStart().getLine();
+ final String includeName = stringFromNode(ctx);
+ enterLog(IMPORT_STR, includeName, line);
+
+ Date includeRevision = null;
+ for (int i = 0; i < ctx.getChildCount(); i++) {
+ final ParseTree treeNode = ctx.getChild(i);
+ if (treeNode instanceof Revision_date_stmtContext) {
+ final String importRevisionStr = stringFromNode(treeNode);
+ try {
+ includeRevision = revisionFormat.parse(importRevisionStr);
+ } catch (final ParseException e) {
+ LOG.warn("Failed to parse import revision-date at line {}: {}", line, importRevisionStr, e);
+ }
+ }
+ }
+ moduleBuilder.addInclude(includeName, includeRevision);
+ }
+
+ @Override
+ public void exitInclude_stmt(final YangParser.Include_stmtContext ctx) {
+ exitLog("include");
}
@Override
enterLog(AUGMENT_STR, augmentPath, line);
stack.push();
- AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
+ final SchemaPath targetPath = parseXPathString(augmentPath, line);
+ final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath,
+ augmentOrder++);
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Description_stmtContext) {
builder.setDescription(stringFromNode(child));
} else if (child instanceof Reference_stmtContext) {
final int line = ctx.getStart().getLine();
final String extName = stringFromNode(ctx);
enterLog("extension", extName, line);
- QName qname = QName.create(moduleQName, extName);
- SchemaPath path = stack.addNodeToPath(qname);
+ final QName qname = QName.create(moduleQName, extName);
+ final SchemaPath path = stack.addNodeToPath(qname);
- ExtensionBuilder builder = moduleBuilder.addExtension(qname, line, path);
+ final ExtensionBuilder builder = moduleBuilder.addExtension(qname, line, path);
parseSchemaNodeArgs(ctx, builder);
String argument = null;
boolean yin = false;
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Argument_stmtContext) {
argument = stringFromNode(child);
yin = parseYinValue((Argument_stmtContext) child);
final int line = ctx.getStart().getLine();
final String typedefName = stringFromNode(ctx);
enterLog("typedef", typedefName, line);
- QName typedefQName = QName.create(moduleQName, typedefName);
- SchemaPath path = stack.addNodeToPath(typedefQName);
+ final QName typedefQName = QName.create(moduleQName, typedefName);
+ final SchemaPath path = stack.addNodeToPath(typedefQName);
- TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName, path);
+ final TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName, path);
parseSchemaNodeArgs(ctx, builder);
builder.setUnits(parseUnits(ctx));
builder.setDefaultValue(parseDefault(ctx));
final String typeName = stringFromNode(ctx);
enterLog("type", typeName, line);
- final QName typeQName = parseQName(typeName);
+ final QName typeQName = parseQName(typeName, line);
TypeDefinition<?> type;
Type_body_stmtsContext typeBody = null;
} else {
QName qname;
switch (typeName) {
- case "union":
- qname = BaseTypes.UNION_QNAME;
- stack.addNodeToPath(qname);
- UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, moduleQName.getModule());
- Builder parent = moduleBuilder.getActualNode();
- unionBuilder.setParent(parent);
+ case UNION_STR:
+ stack.addNodeToPath(BaseTypes.UNION_QNAME);
+ final UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, moduleQName.getModule());
+ final Builder parentBuilder = moduleBuilder.getActualNode();
+ unionBuilder.setParent(parentBuilder);
moduleBuilder.enterNode(unionBuilder);
break;
case "identityref":
qname = BaseTypes.IDENTITYREF_QNAME;
- SchemaPath path = stack.addNodeToPath(qname);
+ final SchemaPath path = stack.addNodeToPath(qname);
moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
break;
default:
- type = parseTypeWithBody(typeName, typeBody, stack.currentSchemaPath(), moduleQName, moduleBuilder.getActualNode());
+ type = parseTypeWithBody(typeName, typeBody, stack.currentSchemaPath(), moduleQName,
+ moduleBuilder.getActualNode());
moduleBuilder.setType(type);
stack.addNodeToPath(type.getQName());
}
}
} else {
- type = parseUnknownTypeWithBody(typeQName, typeBody, stack.currentSchemaPath(), moduleQName, moduleBuilder.getActualNode());
- // add parent node of this type statement to dirty nodes
- moduleBuilder.markActualNodeDirty();
- moduleBuilder.setType(type);
- stack.addNodeToPath(type.getQName());
+ final TypeAwareBuilder parent = (TypeAwareBuilder) moduleBuilder.getActualNode();
+ if (typeBody == null) {
+ parent.setTypeQName(typeQName);
+ moduleBuilder.markActualNodeDirty();
+ } else {
+ ParserListenerUtils.parseUnknownTypeWithBody(typeBody, parent, typeQName, moduleBuilder, moduleQName,
+ stack.currentSchemaPath());
+ }
+ stack.addNodeToPath(QName.create(moduleQName.getModule(), typeQName.getLocalName()));
}
-
}
- private QName parseQName(final String typeName) {
- final QName typeQName;
- if (typeName.indexOf(':') != -1) {
- final Iterator<String> split = COLON_SPLITTER.split(typeName).iterator();
+ /**
+ * Method transforms string representation of yang element (i.e. leaf name,
+ * container name etc.) into QName. The namespace of QName is assigned from
+ * parent module same as revision date of module. If String qname parameter
+ * contains ":" the string is evaluated as prefix:name of element. In this
+ * case method will look into import map and extract correct ModuleImport.
+ * If such import is not present in import map the method will throw
+ * {@link YangParseException} <br>
+ * If ModuleImport is present but the value of namespace in ModuleImport is
+ * <code>null</code> the method will throw {@link YangParseException}
+ *
+ * @param qnameString
+ * QName value as String
+ * @param line
+ * line in Yang model document where QName occur.
+ * @return transformed string qname parameter as QName structure.
+ *
+ * @throws YangParseException
+ */
+ private QName parseQName(final String qnameString, final int line) {
+ final QName qname;
+ if (qnameString.indexOf(':') == -1) {
+ qname = QName.create(moduleQName, qnameString);
+ } else {
+ final Iterator<String> split = COLON_SPLITTER.split(qnameString).iterator();
final String prefix = split.next();
final String name = split.next();
- if (prefix.equals(moduleQName.getPrefix())) {
- typeQName = QName.create(moduleQName, name);
+ if (prefix.equals(moduleBuilder.getPrefix())) {
+ qname = QName.create(moduleQName, name);
} else {
- typeQName = new QName(null, null, prefix, name);
+ final ModuleImport imp = moduleBuilder.getImport(prefix);
+ if (imp == null) {
+ LOG.debug("Error in module {} at line {}: No import found with prefix {}", moduleName, line, prefix);
+ throw new YangParseException(moduleName, line, "Error in module " + moduleName
+ + " No import found with prefix " + prefix + " not found.");
+ }
+ Date revision = imp.getRevision();
+ final NavigableMap<Date, URI> namespaces = namespaceContext.get(imp.getModuleName());
+ if (namespaces == null) {
+ throw new YangParseException(moduleName, line, String.format("Imported module %s not found",
+ imp.getModuleName()));
+ }
+ URI namespace;
+ if (revision == null) {
+ revision = namespaces.lastEntry().getKey();
+ namespace = namespaces.lastEntry().getValue();
+ } else {
+ // FIXME: this lookup does not look right, as we will end up
+ // with
+ // a qname which does not have a namespace. At any rate we
+ // should arrive at a QNameModule!
+ namespace = namespaces.get(revision);
+ }
+
+ final QNameModule mod = QNameModule.cachedReference(QNameModule.create(namespace, revision));
+ qname = QName.create(mod, name);
}
- } else {
- typeQName = QName.create(moduleQName, typeName);
}
- return typeQName;
+ return qname;
}
@Override
public void exitType_stmt(final YangParser.Type_stmtContext ctx) {
final String typeName = stringFromNode(ctx);
- if ("union".equals(typeName)) {
+ if (UNION_STR.equals(typeName)) {
moduleBuilder.exitNode();
}
exitLog("type", stack.removeNodeFromPath());
final int line = ctx.getStart().getLine();
final String groupName = stringFromNode(ctx);
enterLog("grouping", groupName, line);
- QName groupQName = QName.create(moduleQName, groupName);
- SchemaPath path = stack.addNodeToPath(groupQName);
+ final QName groupQName = QName.create(moduleQName, groupName);
+ final SchemaPath path = stack.addNodeToPath(groupQName);
- GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName, path);
+ final GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName, path);
parseSchemaNodeArgs(ctx, builder);
moduleBuilder.enterNode(builder);
final String containerName = stringFromNode(ctx);
enterLog("container", containerName, line);
- QName containerQName = QName.create(moduleQName, containerName);
- SchemaPath path = stack.addNodeToPath(containerQName);
+ final QName containerQName = QName.create(moduleQName, containerName);
+ final SchemaPath path = stack.addNodeToPath(containerQName);
- ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
+ final ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
parseSchemaNodeArgs(ctx, builder);
parseConstraints(ctx, builder.getConstraints());
builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
final String leafName = stringFromNode(ctx);
enterLog("leaf", leafName, line);
- QName leafQName = QName.create(moduleQName, leafName);
- SchemaPath path = stack.addNodeToPath(leafQName);
+ final QName leafQName = QName.create(moduleQName, leafName);
+ final SchemaPath path = stack.addNodeToPath(leafQName);
- LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, path);
+ final LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, path);
parseSchemaNodeArgs(ctx, builder);
parseConstraints(ctx, builder.getConstraints());
builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
String defaultStr = null;
String unitsStr = null;
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Default_stmtContext) {
defaultStr = stringFromNode(child);
} else if (child instanceof Units_stmtContext) {
public void enterUses_stmt(final YangParser.Uses_stmtContext ctx) {
final int line = ctx.getStart().getLine();
final String groupingPathStr = stringFromNode(ctx);
+ final SchemaPath groupingPath = parseXPathString(groupingPathStr, line);
enterLog("uses", groupingPathStr, line);
- UsesNodeBuilder builder = moduleBuilder.addUsesNode(line, groupingPathStr);
+ final UsesNodeBuilder builder = moduleBuilder.addUsesNode(line, groupingPath);
moduleBuilder.enterNode(builder);
}
enterLog(AUGMENT_STR, augmentPath, line);
stack.push();
- AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
+ final SchemaPath targetPath = parseXPathString(augmentPath, line);
+ final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath,
+ augmentOrder++);
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Description_stmtContext) {
builder.setDescription(stringFromNode(child));
} else if (child instanceof Reference_stmtContext) {
final String refineString = stringFromNode(ctx);
enterLog("refine", refineString, ctx.getStart().getLine());
- RefineHolderImpl refine = parseRefine(ctx, moduleName);
+ final RefineHolderImpl refine = parseRefine(ctx, moduleName);
moduleBuilder.addRefine(refine);
moduleBuilder.enterNode(refine);
}
final int line = ctx.getStart().getLine();
final String leafListName = stringFromNode(ctx);
enterLog("leaf-list", leafListName, line);
- QName leafListQName = QName.create(moduleQName, leafListName);
- SchemaPath path = stack.addNodeToPath(leafListQName);
+ final QName leafListQName = QName.create(moduleQName, leafListName);
+ final SchemaPath path = stack.addNodeToPath(leafListQName);
- LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, path);
+ final LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
final String listName = stringFromNode(ctx);
enterLog("list", listName, line);
- QName listQName = QName.create(moduleQName, listName);
- SchemaPath path = stack.addNodeToPath(listQName);
+ final QName listQName = QName.create(moduleQName, listName);
+ final SchemaPath path = stack.addNodeToPath(listQName);
- ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, path);
+ final ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
for (int i = 0; i < ctx.getChildCount(); ++i) {
- ParseTree childNode = ctx.getChild(i);
+ final ParseTree childNode = ctx.getChild(i);
if (childNode instanceof Ordered_by_stmtContext) {
final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;
final boolean userOrdered = parseUserOrdered(orderedBy);
builder.setUserOrdered(userOrdered);
} else if (childNode instanceof Key_stmtContext) {
- List<String> key = createListKey((Key_stmtContext) childNode);
+ final Set<String> key = createListKey((Key_stmtContext) childNode);
builder.setKeys(key);
+ } else if (childNode instanceof YangParser.Identifier_stmtContext
+ && UNION_STR.equals(childNode.getChild(0).toString())) {
+ throw new YangParseException(moduleName, line, "Union statement is not allowed inside a list statement");
}
}
}
final String anyXmlName = stringFromNode(ctx);
enterLog("anyxml", anyXmlName, line);
- QName anyXmlQName = QName.create(moduleQName, anyXmlName);
- SchemaPath path = stack.addNodeToPath(anyXmlQName);
+ final QName anyXmlQName = QName.create(moduleQName, anyXmlName);
+ final SchemaPath path = stack.addNodeToPath(anyXmlQName);
- AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, path);
+ final AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
final String choiceName = stringFromNode(ctx);
enterLog("choice", choiceName, line);
- QName choiceQName = QName.create(moduleQName, choiceName);
- SchemaPath path = stack.addNodeToPath(choiceQName);
+ final QName choiceQName = QName.create(moduleQName, choiceName);
+ final SchemaPath path = stack.addNodeToPath(choiceQName);
- ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName, path);
+ final ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
// set 'default' case
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Default_stmtContext) {
- String defaultCase = stringFromNode(child);
+ final String defaultCase = stringFromNode(child);
builder.setDefaultCase(defaultCase);
break;
}
final String caseName = stringFromNode(ctx);
enterLog("case", caseName, line);
- QName caseQName = QName.create(moduleQName, caseName);
- SchemaPath path = stack.addNodeToPath(caseQName);
+ final QName caseQName = QName.create(moduleQName, caseName);
+ final SchemaPath path = stack.addNodeToPath(caseQName);
- ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName, path);
+ final ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
final String notificationName = stringFromNode(ctx);
enterLog("notification", notificationName, line);
- QName notificationQName = QName.create(moduleQName, notificationName);
- SchemaPath path = stack.addNodeToPath(notificationQName);
+ final QName notificationQName = QName.create(moduleQName, notificationName);
+ final SchemaPath path = stack.addNodeToPath(notificationQName);
- NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName, path);
+ final NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
@Override
public void exitIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("unknown-node", stack.removeNodeFromPath());
- }
-
- @Override public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
- handleUnknownNode(ctx.getStart().getLine(), ctx);
- }
-
- @Override public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
- moduleBuilder.exitNode();
- exitLog("unknown-node", stack.removeNodeFromPath());
+ exitLog(UNKNOWN_NODE_STR, stack.removeNodeFromPath());
}
- @Override public void enterUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
- handleUnknownNode(ctx.getStart().getLine(), ctx);
- }
-
- @Override public void exitUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
- moduleBuilder.exitNode();
- exitLog("unknown-node", stack.removeNodeFromPath());
- }
-
- @Override public void enterUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
+ @Override
+ public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
handleUnknownNode(ctx.getStart().getLine(), ctx);
}
- @Override public void exitUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
+ @Override
+ public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
moduleBuilder.exitNode();
- exitLog("unknown-node", stack.removeNodeFromPath());
+ exitLog(UNKNOWN_NODE_STR, stack.removeNodeFromPath());
}
@Override
final String rpcName = stringFromNode(ctx);
enterLog("rpc", rpcName, line);
- QName rpcQName = QName.create(moduleQName, rpcName);
- SchemaPath path = stack.addNodeToPath(rpcQName);
+ final QName rpcQName = QName.create(moduleQName, rpcName);
+ final SchemaPath path = stack.addNodeToPath(rpcQName);
- RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName, path);
+ final RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName, path);
moduleBuilder.enterNode(rpcBuilder);
-
parseSchemaNodeArgs(ctx, rpcBuilder);
}
final String input = "input";
enterLog(input, input, line);
- QName rpcQName = QName.create(moduleQName, input);
- SchemaPath path = stack.addNodeToPath(rpcQName);
+ final QName rpcQName = QName.create(moduleQName, input);
+ final SchemaPath path = stack.addNodeToPath(rpcQName);
- ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
+ final ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
moduleBuilder.enterNode(builder);
builder.setConfiguration(true);
final String output = "output";
enterLog(output, output, line);
- QName rpcQName = QName.create(moduleQName, output);
- SchemaPath path = stack.addNodeToPath(rpcQName);
+ final QName rpcQName = QName.create(moduleQName, output);
+ final SchemaPath path = stack.addNodeToPath(rpcQName);
- ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
+ final ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
moduleBuilder.enterNode(builder);
builder.setConfiguration(true);
final String featureName = stringFromNode(ctx);
enterLog("feature", featureName, line);
- QName featureQName = QName.create(moduleQName, featureName);
- SchemaPath path = stack.addNodeToPath(featureQName);
+ final QName featureQName = QName.create(moduleQName, featureName);
+ final SchemaPath path = stack.addNodeToPath(featureQName);
- FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName, path);
+ final FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName, path);
moduleBuilder.enterNode(featureBuilder);
parseSchemaNodeArgs(ctx, featureBuilder);
@Override
public void enterDeviation_stmt(final YangParser.Deviation_stmtContext ctx) {
final int line = ctx.getStart().getLine();
- final String targetPath = stringFromNode(ctx);
- enterLog("deviation", targetPath, line);
+ final String targetPathStr = stringFromNode(ctx);
+ if (!targetPathStr.startsWith("/")) {
+ throw new YangParseException(moduleName, line,
+ "Deviation argument string must be an absolute schema node identifier.");
+ }
+ enterLog("deviation", targetPathStr, line);
String reference = null;
String deviate = null;
- DeviationBuilder builder = moduleBuilder.addDeviation(line, targetPath);
+
+ final SchemaPath targetPath = parseXPathString(targetPathStr, line);
+ final DeviationBuilder builder = moduleBuilder.addDeviation(line, targetPath);
moduleBuilder.enterNode(builder);
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Reference_stmtContext) {
reference = stringFromNode(child);
} else if (child instanceof Deviate_not_supported_stmtContext) {
builder.setDeviate(deviate);
}
+ public SchemaPath parseXPathString(final String xpathString, final int line) {
+ final boolean absolute = !xpathString.isEmpty() && xpathString.charAt(0) == '/';
+
+ final List<QName> path = new ArrayList<>();
+ for (final String pathElement : SLASH_SPLITTER.split(xpathString)) {
+ final Iterator<String> it = COLON_SPLITTER.split(pathElement).iterator();
+ final String s = it.next();
+ if (it.hasNext()) {
+ path.add(parseQName(pathElement, line));
+ } else {
+ path.add(QName.create(moduleQName, s));
+ }
+ }
+ return SchemaPath.create(path, absolute);
+ }
+
@Override
public void exitDeviation_stmt(final YangParser.Deviation_stmtContext ctx) {
moduleBuilder.exitNode();
enterLog("identity", identityName, line);
final QName identityQName = QName.create(moduleQName, identityName);
- SchemaPath path = stack.addNodeToPath(identityQName);
+ final SchemaPath path = stack.addNodeToPath(identityQName);
- IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, line, path);
+ final IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, line, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Base_stmtContext) {
- String baseIdentityName = stringFromNode(child);
+ final String baseIdentityName = stringFromNode(child);
builder.setBaseIdentityName(baseIdentityName);
}
}
return moduleBuilder;
}
- private void enterLog(final String p1, final String p2, final int line) {
- LOGGER.trace("entering {} {} ({})", p1, p2, line);
+ private static void enterLog(final String p1, final String p2, final int line) {
+ LOG.trace("entering {} {} ({})", p1, p2, line);
}
- private void exitLog(final String p1) {
- LOGGER.trace("exiting {}", p1);
+ private static void exitLog(final String p1) {
+ LOG.trace("exiting {}", p1);
}
- private void exitLog(final String p1, final QName p2) {
- LOGGER.trace("exiting {} {}", p1, p2.getLocalName());
+ private static void exitLog(final String p1, final QName p2) {
+ LOG.trace("exiting {} {}", p1, p2.getLocalName());
}
- private void setLog(final String p1, final String p2) {
- LOGGER.trace("setting {} {}", p1, p2);
+ private static void setLog(final String p1, final String p2) {
+ LOG.trace("setting {} {}", p1, p2);
}
private void handleUnknownNode(final int line, final ParseTree ctx) {
final String nodeParameter = stringFromNode(ctx);
- enterLog("unknown-node", nodeParameter, line);
+ enterLog(UNKNOWN_NODE_STR, nodeParameter, line);
final String nodeTypeStr = ctx.getChild(0).getText();
- final Iterator<String> splittedElement = COLON_SPLITTER.split(nodeTypeStr).iterator();
- final String e0 = splittedElement.next();
- final QName nodeType;
- if (splittedElement.hasNext()) {
- nodeType = new QName(moduleQName.getNamespace(), moduleQName.getRevision(), e0, splittedElement.next());
- } else {
- nodeType = QName.create(moduleQName, e0);
- }
+ final QName nodeType = parseQName(nodeTypeStr, line);
- QName qname;
+ QName qname = null;
try {
- if (!Strings.isNullOrEmpty(nodeParameter)) {
+ // FIXME: rewrite whole method to handle unknown nodes properly.
+ // This should be bugfix for bug
+ // https://bugs.opendaylight.org/show_bug.cgi?id=1539
+ // After this fix bug
+ // https://bugs.opendaylight.org/show_bug.cgi?id=1538 MUST be fixed
+ // since
+ // they are dependent!!!
+ if (Strings.isNullOrEmpty(nodeParameter)) {
+ qname = nodeType;
+ } else {
final Iterable<String> splittedName = COLON_SPLITTER.split(nodeParameter);
final Iterator<String> it = splittedName.iterator();
-
if (Iterables.size(splittedName) == 2) {
- qname = new QName(null, null, it.next(), it.next());
+ qname = parseQName(nodeParameter, line);
} else {
qname = QName.create(moduleQName, it.next());
}
- } else {
- qname = nodeType;
}
- } catch (IllegalArgumentException e) {
+ } catch (IllegalArgumentException | YangParseException ex) {
qname = nodeType;
}
- SchemaPath path = stack.addNodeToPath(qname);
- UnknownSchemaNodeBuilderImpl builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
+ final SchemaPath path = stack.addNodeToPath(qname);
+
+ final UnknownSchemaNodeBuilderImpl builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
builder.setNodeType(nodeType);
builder.setNodeParameter(nodeParameter);
-
parseSchemaNodeArgs(ctx, builder);
moduleBuilder.enterNode(builder);
}