Refactor deviation statement implementations
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / AbstractDeclaredStatement.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 com.google.common.collect.ImmutableList;
14 import java.util.Collection;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
18 import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
19 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
20
21 /**
22  * An abstract base class for {@link DeclaredStatement} implementations. This is a direct competition to
23  * {@link org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement}, providing lower-footprint
24  * implementations.
25  */
26 @Beta
27 public abstract class AbstractDeclaredStatement<A> extends AbstractModelStatement<A> implements DeclaredStatement<A> {
28     protected AbstractDeclaredStatement() {
29     }
30
31     @Override
32     public final StatementSource getStatementSource() {
33         return StatementSource.DECLARATION;
34     }
35
36     @Override
37     public Collection<? extends DeclaredStatement<?>> declaredSubstatements() {
38         // Default to reduce load on subclasses and keep the number of implementations down
39         return ImmutableList.of();
40     }
41
42     /**
43      * Utility method for recovering singleton lists squashed by {@link #maskList(ImmutableList)}.
44      *
45      * @param masked list to unmask
46      * @return Unmasked list
47      * @throws NullPointerException if masked is null
48      * @throws ClassCastException if masked object does not match DeclaredStatement
49      */
50     @SuppressWarnings({ "rawtypes", "unchecked" })
51     protected static final @NonNull ImmutableList<? extends DeclaredStatement<?>> unmaskList(
52             final @NonNull Object masked) {
53         return (ImmutableList) unmaskList(masked, DeclaredStatement.class);
54     }
55
56     public abstract static class WithRawArgument<A> extends AbstractDeclaredStatement<A> {
57         private final String rawArgument;
58
59         protected WithRawArgument(final StmtContext<A, ?, ?> context) {
60             rawArgument = context.rawStatementArgument();
61         }
62
63         @Override
64         public final String rawArgument() {
65             return rawArgument;
66         }
67     }
68
69     public abstract static class WithQNameArgument extends AbstractDeclaredStatement<QName> {
70         public abstract static class WithSubstatements extends WithQNameArgument {
71             private final @NonNull Object substatements;
72
73             protected WithSubstatements(final QName argument,
74                     final ImmutableList<? extends DeclaredStatement<?>> substatements) {
75                 super(argument);
76                 this.substatements = maskList(substatements);
77             }
78
79             @Override
80             public final Collection<? extends DeclaredStatement<?>> declaredSubstatements() {
81                 return unmaskList(substatements);
82             }
83         }
84
85         private final QName argument;
86
87         protected WithQNameArgument(final QName argument) {
88             this.argument = requireNonNull(argument);
89         }
90
91         @Override
92         public final @NonNull QName argument() {
93             return argument;
94         }
95
96         @Override
97         public final String rawArgument() {
98             return argument.getLocalName();
99         }
100     }
101
102     public abstract static class WithRawStringArgument extends WithRawArgument<String> {
103         public abstract static class WithSubstatements extends WithRawStringArgument {
104             private final @NonNull Object substatements;
105
106             protected WithSubstatements(final StmtContext<String, ?, ?> context,
107                     final ImmutableList<? extends DeclaredStatement<?>> substatements) {
108                 super(context);
109                 this.substatements = maskList(substatements);
110             }
111
112             @Override
113             public final Collection<? extends DeclaredStatement<?>> declaredSubstatements() {
114                 return unmaskList(substatements);
115             }
116         }
117
118         protected WithRawStringArgument(final StmtContext<String, ?, ?> context) {
119             super(context);
120         }
121
122         @Override
123         public final String argument() {
124             return rawArgument();
125         }
126     }
127
128     public abstract static class WithArgument<A> extends WithRawArgument<A> {
129         public abstract static class WithSubstatements<A> extends WithArgument<A> {
130             private final @NonNull Object substatements;
131
132             protected WithSubstatements(final StmtContext<A, ?, ?> context,
133                     final ImmutableList<? extends DeclaredStatement<?>> substatements) {
134                 super(context);
135                 this.substatements = maskList(substatements);
136             }
137
138             @Override
139             public final Collection<? extends DeclaredStatement<?>> declaredSubstatements() {
140                 return unmaskList(substatements);
141             }
142         }
143
144         private final A argument;
145
146         protected WithArgument(final StmtContext<A, ?, ?> context) {
147             super(context);
148             argument = context.getStatementArgument();
149         }
150
151         @Override
152         public final A argument() {
153             return argument;
154         }
155     }
156
157     public abstract static class ArgumentToString<A> extends AbstractDeclaredStatement<A> {
158         public abstract static class WithSubstatements<A> extends ArgumentToString<A> {
159             private final @NonNull Object substatements;
160
161             protected WithSubstatements(final A argument,
162                     final ImmutableList<? extends DeclaredStatement<?>> substatements) {
163                 super(argument);
164                 this.substatements = maskList(substatements);
165             }
166
167             @Override
168             public final Collection<? extends DeclaredStatement<?>> declaredSubstatements() {
169                 return unmaskList(substatements);
170             }
171         }
172
173         private final @NonNull A argument;
174
175         protected ArgumentToString(final A argument) {
176             this.argument = requireNonNull(argument);
177         }
178
179         @Override
180         public final @NonNull A argument() {
181             return argument;
182         }
183
184         @Override
185         public final String rawArgument() {
186             return argument.toString();
187         }
188     }
189 }