5b9edf3206bed452f54fd7d973e189692008ad0d
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / AbstractDeclaredEffectiveStatement.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.Beta;
13 import org.eclipse.jdt.annotation.NonNull;
14 import org.eclipse.jdt.annotation.Nullable;
15 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
16 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
17 import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
18
19 /**
20  * Base stateless superclass for statements which (logically) always have an associated {@link DeclaredStatement}. This
21  * is notably not true for all {@code case} statements, some of which may actually be implied.
22  *
23  * <p>
24  * Note implementations are not strictly required to make the declared statement available, they are free to throw
25  * {@link UnsupportedOperationException} from {@link #getDeclared()}, rendering any services relying on declared
26  * statement to be not available.
27  *
28  * @param <A> Argument type ({@link Void} if statement does not have argument.)
29  * @param <D> Class representing declared version of this statement.
30  */
31 @Beta
32 public abstract class AbstractDeclaredEffectiveStatement<A, D extends DeclaredStatement<A>>
33         extends AbstractEffectiveStatement<A, D> {
34     @Override
35     public final StatementSource getStatementSource() {
36         return StatementSource.DECLARATION;
37     }
38
39     @Override
40     public final StatementDefinition statementDefinition() {
41         return getDeclared().statementDefinition();
42     }
43
44     @Override
45     public abstract @NonNull D getDeclared();
46
47     /**
48      * A stateful version of {@link AbstractDeclaredEffectiveStatement}, which holds (and requires) a declared
49      * statement.
50      *
51      * @param <A> Argument type ({@link Void} if statement does not have argument.)
52      * @param <D> Class representing declared version of this statement.
53      */
54     public abstract static class Default<A, D extends DeclaredStatement<A>>
55             extends AbstractDeclaredEffectiveStatement<A, D> {
56         private final @NonNull D declared;
57
58         protected Default(final D declared) {
59             this.declared = requireNonNull(declared);
60         }
61
62         @Override
63         public final D getDeclared() {
64             return declared;
65         }
66     }
67
68     /**
69      * An extra building block on top of {@link Default}, which is wiring {@link #argument()} to the declared statement.
70      * This is mostly useful for arguments that are not subject to inference transformation -- for example Strings in
71      * {@code description}, etc. This explicitly is not true of statements which underwent namespace binding via
72      * {@code uses} or similar.
73      *
74      * @param <A> Argument type ({@link Void} if statement does not have argument.)
75      * @param <D> Class representing declared version of this statement.
76      */
77     public abstract static class DefaultArgument<A, D extends DeclaredStatement<A>> extends Default<A, D> {
78         protected DefaultArgument(final D declared) {
79             super(declared);
80         }
81
82         @Override
83         public final @Nullable A argument() {
84             return getDeclared().argument();
85         }
86     }
87 }