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%2Fstmt%2Frfc6020%2Feffective%2FExtensionEffectiveStatementImpl.java;h=94e8e546833524b384071fd004a54abccdd4d72a;hb=07a461a735316f15f9a78455e1c1c3caf91b2a3e;hp=efb543a82392dfcd397cffa66bf6df0da89ecc46;hpb=acb7eceffb4730d12b1bd01a4d586335d65cf898;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtensionEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtensionEffectiveStatementImpl.java index efb543a823..94e8e54683 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtensionEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtensionEffectiveStatementImpl.java @@ -8,7 +8,9 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; import com.google.common.collect.ImmutableList; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Deque; import java.util.List; import java.util.Objects; import org.opendaylight.yangtools.yang.common.QName; @@ -21,6 +23,40 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; public class ExtensionEffectiveStatementImpl extends AbstractEffectiveDocumentedNode implements ExtensionDefinition { + private static final class RecursionDetector extends ThreadLocal> { + boolean check(final ExtensionEffectiveStatementImpl current) { + final Deque stack = get(); + if (stack != null) { + for (ExtensionEffectiveStatementImpl s : stack) { + if (s == current) { + return true; + } + } + } + return false; + } + + void push(final ExtensionEffectiveStatementImpl current) { + Deque stack = get(); + if (stack == null) { + stack = new ArrayDeque<>(1); + set(stack); + } + + stack.push(current); + } + + void pop() { + Deque stack = get(); + stack.pop(); + if (stack.isEmpty()) { + remove(); + } + } + } + + private static final RecursionDetector TOSTRING_DETECTOR = new RecursionDetector(); + private final QName qname; private final String argument; private final SchemaPath schemaPath; @@ -34,12 +70,10 @@ public class ExtensionEffectiveStatementImpl extends AbstractEffectiveDocumented this.qname = ctx.getStatementArgument(); this.schemaPath = ctx.getSchemaPath().get(); - // initSubstatementCollections - List unknownNodesInit = new ArrayList<>(); - for (EffectiveStatement effectiveStatement : effectiveSubstatements()) { - if (effectiveStatement instanceof UnknownSchemaNode) { - UnknownSchemaNode unknownNode = (UnknownSchemaNode) effectiveStatement; - unknownNodesInit.add(unknownNode); + final List unknownNodesInit = new ArrayList<>(); + for (EffectiveStatement unknownNode : effectiveSubstatements()) { + if (unknownNode instanceof UnknownSchemaNode) { + unknownNodesInit.add((UnknownSchemaNode) unknownNode); } } this.unknownNodes = ImmutableList.copyOf(unknownNodesInit); @@ -113,14 +147,32 @@ public class ExtensionEffectiveStatementImpl extends AbstractEffectiveDocumented @Override public String toString() { - StringBuilder sb = new StringBuilder(ExtensionEffectiveStatementImpl.class.getSimpleName()); - sb.append("["); - sb.append("argument=").append(argument); - sb.append(", qname=").append(qname); - sb.append(", schemaPath=").append(schemaPath); - sb.append(", extensionSchemaNodes=").append(unknownNodes); - sb.append(", yin=").append(yin); - sb.append("]"); - return sb.toString(); + if (TOSTRING_DETECTOR.check(this)) { + return recursedToString(); + } + + TOSTRING_DETECTOR.push(this); + try { + StringBuilder sb = new StringBuilder(ExtensionEffectiveStatementImpl.class.getSimpleName()); + sb.append("["); + sb.append("argument=").append(argument); + sb.append(", qname=").append(qname); + sb.append(", schemaPath=").append(schemaPath); + sb.append(", extensionSchemaNodes=").append(unknownNodes); + sb.append(", yin=").append(yin); + sb.append("]"); + return sb.toString(); + } finally { + TOSTRING_DETECTOR.pop(); + } + } + + private String recursedToString() { + return ExtensionEffectiveStatementImpl.class.getSimpleName() + "[" + + "argument=" + argument + + ", qname=" + qname + + ", schemaPath=" + schemaPath + + ", yin=" + yin + + " ]"; } }