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.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.NavigableMap;
import java.util.Set;
-import java.util.TreeMap;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
+/**
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
+ */
+@Deprecated
public final class YangParserListenerImpl extends YangParserBaseListener {
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, TreeMap<Date, URI>> namespaceContext;
+ private final Map<String, NavigableMap<Date, URI>> namespaceContext;
private final String sourcePath;
private QName moduleQName = QName.create(null, new Date(0L), "dummy");
private ModuleBuilder moduleBuilder;
private int augmentOrder;
private String yangModelPrefix;
- public YangParserListenerImpl(final Map<String, TreeMap<Date, URI>> namespaceContext, final String sourcePath) {
+ public YangParserListenerImpl(final Map<String, NavigableMap<Date, URI>> namespaceContext, final String sourcePath) {
this.namespaceContext = namespaceContext;
this.sourcePath = sourcePath;
}
* the "BaseListener" aspect, which need not be exposed to the user. Maybe
* factor out a base class into repo.spi?
*
- * @param namespaceContext
- * @param sourcePath
- * @param walker
- * @param tree
+ * @param namespaceContext namespaceContext
+ * @param sourcePath sourcePath
+ * @param walker walker
+ * @param tree tree
* @return new instance of YangParserListenerImpl
*/
- public static YangParserListenerImpl create(final Map<String, TreeMap<Date, URI>> namespaceContext,
+ 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);
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) {
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) {
final String belongsTo = stringFromNode(ctx);
- TreeMap<Date, URI> context = namespaceContext.get(belongsTo);
+ 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
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 = 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) {
+ } 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;
if (treeNode instanceof Prefix_stmtContext) {
importPrefix = stringFromNode(treeNode);
} else if (treeNode instanceof Revision_date_stmtContext) {
- String importRevisionStr = stringFromNode(treeNode);
+ final String importRevisionStr = stringFromNode(treeNode);
try {
- importRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
- } catch (ParseException e) {
+ importRevision = revisionFormat.parse(importRevisionStr);
+ } catch (final ParseException e) {
LOG.warn("Failed to parse import revision-date at line {}: {}", line, importRevisionStr, e);
}
}
@Override
public void exitImport_stmt(final Import_stmtContext ctx) {
- exitLog("import");
+ exitLog(IMPORT_STR);
}
@Override
- public void enterInclude_stmt(YangParser.Include_stmtContext ctx) {
+ public void enterInclude_stmt(final YangParser.Include_stmtContext ctx) {
final int line = ctx.getStart().getLine();
final String includeName = stringFromNode(ctx);
- enterLog("import", includeName, line);
+ enterLog(IMPORT_STR, includeName, line);
Date includeRevision = null;
for (int i = 0; i < ctx.getChildCount(); i++) {
if (treeNode instanceof Revision_date_stmtContext) {
final String importRevisionStr = stringFromNode(treeNode);
try {
- includeRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
- } catch (ParseException e) {
+ 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(YangParser.Include_stmtContext ctx) {
+ @Override
+ public void exitInclude_stmt(final YangParser.Include_stmtContext ctx) {
exitLog("include");
}
stack.push();
final SchemaPath targetPath = parseXPathString(augmentPath, line);
- final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath, augmentOrder++);
+ 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) {
} else {
QName qname;
switch (typeName) {
- case "union":
- qname = BaseTypes.UNION_QNAME;
- stack.addNodeToPath(qname);
+ case UNION_STR:
+ stack.addNodeToPath(BaseTypes.UNION_QNAME);
final UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, moduleQName.getModule());
- final Builder parent = moduleBuilder.getActualNode();
- unionBuilder.setParent(parent);
+ final Builder parentBuilder = moduleBuilder.getActualNode();
+ unionBuilder.setParent(parentBuilder);
moduleBuilder.enterNode(unionBuilder);
break;
case "identityref":
parent.setTypeQName(typeQName);
moduleBuilder.markActualNodeDirty();
} else {
- ParserListenerUtils.parseUnknownTypeWithBody(typeBody, parent, typeQName, moduleBuilder,
- moduleQName, stack.currentSchemaPath());
+ ParserListenerUtils.parseUnknownTypeWithBody(typeBody, parent, typeQName, moduleBuilder, moduleQName,
+ stack.currentSchemaPath());
}
stack.addNodeToPath(QName.create(moduleQName.getModule(), typeQName.getLocalName()));
}
}
/**
- * 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}
+ * 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.
+ * @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
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.");
+ + " No import found with prefix " + prefix + " not found.");
}
Date revision = imp.getRevision();
- TreeMap<Date, URI> namespaces = namespaceContext.get(imp.getModuleName());
+ 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()));
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!
+ // 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));
+ final QNameModule mod = QNameModule.create(namespace, revision).intern();
qname = QName.create(mod, name);
}
}
@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());
stack.push();
final SchemaPath targetPath = parseXPathString(augmentPath, line);
- final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath, augmentOrder++);
+ final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath,
+ augmentOrder++);
for (int i = 0; i < ctx.getChildCount(); i++) {
final ParseTree child = ctx.getChild(i);
} else if (childNode instanceof Key_stmtContext) {
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");
}
}
}
@Override
public void exitIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("unknown-node", stack.removeNodeFromPath());
+ exitLog(UNKNOWN_NODE_STR, stack.removeNodeFromPath());
}
- @Override public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
+ @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) {
+ @Override
+ public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
moduleBuilder.exitNode();
- exitLog("unknown-node", stack.removeNodeFromPath());
+ exitLog(UNKNOWN_NODE_STR, stack.removeNodeFromPath());
}
@Override
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) {
final boolean absolute = !xpathString.isEmpty() && xpathString.charAt(0) == '/';
final List<QName> path = new ArrayList<>();
- for (String pathElement : SLASH_SPLITTER.split(xpathString)) {
+ 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()) {
for (int i = 0; i < ctx.getChildCount(); i++) {
final ParseTree child = ctx.getChild(i);
if (child instanceof Base_stmtContext) {
- String baseIdentityName = stringFromNode(child);
+ final String baseIdentityName = stringFromNode(child);
builder.setBaseIdentityName(baseIdentityName);
}
}
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 QName nodeType = parseQName(nodeTypeStr, line);
QName qname = null;
try {
- //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
+ // 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;