2 * Copyright (c) 2017 Pantheon Technologies, s.r.o. 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;
13 import com.google.common.collect.ImmutableList;
14 import java.util.IdentityHashMap;
16 import java.util.stream.Stream;
17 import org.opendaylight.yangtools.openconfig.model.api.OpenConfigStatements;
18 import org.opendaylight.yangtools.yang.common.QName;
19 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
20 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
21 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
22 import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
23 import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionEffectiveStatement;
24 import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.YinElementStatement;
26 import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace;
27 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractQNameStatementSupport;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
29 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementDefinitionNamespace;
30 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
31 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
32 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
33 import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
35 public final class ExtensionStatementSupport
36 extends AbstractQNameStatementSupport<ExtensionStatement, ExtensionEffectiveStatement> {
37 private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(YangStmtMapping
39 .addOptional(YangStmtMapping.ARGUMENT)
40 .addOptional(YangStmtMapping.DESCRIPTION)
41 .addOptional(YangStmtMapping.REFERENCE)
42 .addOptional(YangStmtMapping.STATUS)
44 private static final ExtensionStatementSupport INSTANCE = new ExtensionStatementSupport();
45 private static final ThreadLocal<Map<Current<?, ?>, ExtensionEffectiveStatementImpl>> TL_BUILDERS =
48 private ExtensionStatementSupport() {
49 super(YangStmtMapping.EXTENSION, StatementPolicy.reject());
52 public static ExtensionStatementSupport getInstance() {
57 public QName parseArgumentValue(final StmtContext<?,?,?> ctx, final String value) {
58 return StmtContextUtils.parseIdentifier(ctx, value);
62 public void onStatementDefinitionDeclared(
63 final Mutable<QName, ExtensionStatement, ExtensionEffectiveStatement> stmt) {
64 super.onStatementDefinitionDeclared(stmt);
66 QName stmtName = stmt.getArgument();
67 if (OpenConfigStatements.OPENCONFIG_VERSION.getStatementName().isEqualWithoutRevision(stmtName)) {
68 stmtName = stmtName.withoutRevision();
71 stmt.addContext(ExtensionNamespace.class, stmtName, stmt);
73 final StmtContext<QName, ?, ?> argument = StmtContextUtils.findFirstDeclaredSubstatement(stmt,
74 ArgumentStatement.class);
75 final StmtContext<Boolean, ?, ?> yinElement = StmtContextUtils.findFirstDeclaredSubstatement(stmt,
76 YinElementStatement.class);
78 stmt.addToNs(StatementDefinitionNamespace.class, stmt.argument(),
79 new UnrecognizedStatementSupport(new ModelDefinedStatementDefinition(stmt.getArgument(),
80 argument != null ? argument.argument() : null, yinElement != null && yinElement.getArgument())));
84 protected SubstatementValidator getSubstatementValidator() {
85 return SUBSTATEMENT_VALIDATOR;
89 protected ExtensionStatement createDeclared(final StmtContext<QName, ExtensionStatement, ?> ctx,
90 final ImmutableList<? extends DeclaredStatement<?>> substatements) {
91 return new RegularExtensionStatement(ctx.getArgument(), substatements);
95 protected ExtensionStatement createEmptyDeclared(final StmtContext<QName, ExtensionStatement, ?> ctx) {
96 return new EmptyExtensionStatement(ctx.getArgument());
100 public ExtensionEffectiveStatement createEffective(final Current<QName, ExtensionStatement> stmt,
101 final Stream<? extends StmtContext<?, ?, ?>> declaredSubstatements,
102 final Stream<? extends StmtContext<?, ?, ?>> effectiveSubstatements) {
103 Map<Current<?, ?>, ExtensionEffectiveStatementImpl> tl = TL_BUILDERS.get();
105 tl = new IdentityHashMap<>();
109 final ExtensionEffectiveStatementImpl existing = tl.get(stmt);
110 if (existing != null) {
111 // Implies non-empty map, no cleanup necessary
116 final ExtensionEffectiveStatementImpl created = new ExtensionEffectiveStatementImpl(stmt.declared(),
117 stmt.optionalPath());
118 verify(tl.put(stmt, created) == null);
120 return super.createEffective(stmt, declaredSubstatements, effectiveSubstatements);
122 verify(tl.remove(stmt) == created);
126 TL_BUILDERS.remove();
132 protected ExtensionEffectiveStatement createEffective(final Current<QName, ExtensionStatement> stmt,
133 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
134 final ExtensionEffectiveStatementImpl ret = verifyNotNull(verifyNotNull(TL_BUILDERS.get(),
135 "Statement build state not initialized").get(stmt), "No build state found for %s", stmt);
136 ret.setSubstatements(substatements);