2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.extension;
10 import static com.google.common.base.Verify.verify;
11 import static com.google.common.base.Verify.verifyNotNull;
12 import static java.util.Objects.requireNonNull;
14 import com.google.common.collect.ImmutableList;
15 import java.util.ArrayDeque;
16 import java.util.Deque;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.yangtools.yang.common.QName;
19 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
20 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
21 import org.opendaylight.yangtools.yang.model.api.Status;
22 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
23 import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentEffectiveStatement;
24 import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionEffectiveStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement;
26 import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
27 import org.opendaylight.yangtools.yang.model.api.stmt.YinElementEffectiveStatement;
28 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveStatement.DefaultArgument;
29 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.DocumentedNodeMixin;
31 final class ExtensionEffectiveStatementImpl extends DefaultArgument<QName, ExtensionStatement>
32 implements ExtensionDefinition, ExtensionEffectiveStatement, DocumentedNodeMixin<QName, ExtensionStatement> {
33 private static final class RecursionDetector extends ThreadLocal<Deque<ExtensionEffectiveStatementImpl>> {
34 boolean check(final ExtensionEffectiveStatementImpl current) {
35 final Deque<ExtensionEffectiveStatementImpl> stack = get();
37 for (ExtensionEffectiveStatementImpl s : stack) {
46 void push(final ExtensionEffectiveStatementImpl current) {
47 Deque<ExtensionEffectiveStatementImpl> stack = get();
49 stack = new ArrayDeque<>(1);
57 Deque<ExtensionEffectiveStatementImpl> stack = get();
59 if (stack.isEmpty()) {
65 private static final RecursionDetector TOSTRING_DETECTOR = new RecursionDetector();
67 private final @NonNull SchemaPath path;
69 private volatile Object substatements;
71 ExtensionEffectiveStatementImpl(final ExtensionStatement declared, final SchemaPath path) {
73 this.path = requireNonNull(path);
77 public QName getQName() {
83 public SchemaPath getPath() {
88 public String getArgument() {
89 return findFirstEffectiveSubstatementArgument(ArgumentEffectiveStatement.class)
90 .map(QName::getLocalName)
95 public boolean isYinElement() {
96 return findFirstEffectiveSubstatement(ArgumentEffectiveStatement.class)
97 .flatMap(arg -> arg.findFirstEffectiveSubstatementArgument(YinElementEffectiveStatement.class))
98 .orElse(Boolean.FALSE)
103 public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
104 final Object local = verifyNotNull(substatements, "Substatements are not yet initialized");
105 return unmaskList(local);
109 public Status getStatus() {
110 return findFirstEffectiveSubstatementArgument(StatusEffectiveStatement.class).orElse(Status.CURRENT);
114 public ExtensionEffectiveStatement asEffectiveStatement() {
119 public String toString() {
120 if (TOSTRING_DETECTOR.check(this)) {
121 return recursedToString();
124 TOSTRING_DETECTOR.push(this);
126 return ExtensionEffectiveStatementImpl.class.getSimpleName() + "["
127 + "argument=" + getArgument()
128 + ", qname=" + getQName()
129 + ", schemaPath=" + path
130 + ", yin=" + isYinElement()
131 + ", extensionSchemaNodes=" + getUnknownSchemaNodes()
134 TOSTRING_DETECTOR.pop();
138 void setSubstatements(final ImmutableList<? extends EffectiveStatement<?, ?>> newSubstatements) {
139 verify(substatements == null, "Substatements already initialized");
140 substatements = maskList(newSubstatements);
143 private String recursedToString() {
144 return ExtensionEffectiveStatementImpl.class.getSimpleName() + "["
145 + "argument=" + getArgument()
146 + ", qname=" + getQName()
147 + ", schemaPath=" + path
148 + ", yin=" + isYinElement()