Push FIXMEs out
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / ir / IRKeyword.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.ir;
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.common.AbstractQName;
16
17 /**
18  * A YANG keyword, as defined, as defined by section 6.1.2 of both
19  * <a href="https://tools.ietf.org/html/rfc6020#section-6.1.2">RFC6020</a> and
20  * <a href="https://tools.ietf.org/html/rfc7950#section-6.1.2">RFC7950</a>. The two options are discerned by nullability
21  * of {@link #prefix()} method's return, as hinted by the ABNF for {@code node-identifier} -- and while a keyword is a
22  * semantically different construct, it shares the same value space.
23  *
24  * <p>
25  * Naming in this class prefers the formal ABNF specification and draws value-space and type-safety implications from
26  * that connection, rather than following the RFC-assigned names.
27  */
28 @Beta
29 public abstract class IRKeyword extends AbstractIRObject {
30     @Beta
31     public static final class Qualified extends IRKeyword {
32         private final @NonNull String prefix;
33
34         Qualified(final String prefix, final String localName) {
35             super(localName);
36             this.prefix = requireNonNull(prefix);
37         }
38
39         @Override
40         public @NonNull String prefix() {
41             return prefix;
42         }
43
44         @Override
45         public String asStringDeclaration() {
46             return prefix + ':' + identifier();
47         }
48
49         @Override
50         StringBuilder toYangFragment(final StringBuilder sb) {
51             return sb.append(prefix).append(':').append(identifier());
52         }
53     }
54
55     @Beta
56     public static final class Unqualified extends IRKeyword {
57         Unqualified(final String localName) {
58             super(localName);
59         }
60
61         @Override
62         public String prefix() {
63             return null;
64         }
65
66         @Override
67         public String asStringDeclaration() {
68             return identifier();
69         }
70
71         @Override
72         StringBuilder toYangFragment(final StringBuilder sb) {
73             return sb.append(identifier());
74         }
75     }
76
77     private final @NonNull String identifier;
78
79     IRKeyword(final String localName) {
80         this.identifier = requireNonNull(localName);
81     }
82
83     /**
84      * This keyword's 'identifier' part. This corresponds to what the RFCs refer to as {@code YANG keyword} or as
85      * {@code language extension keyword}.
86      *
87      * <p>
88      * Note the returned string is guaranteed to conform to rules of {@code identifier} ABNF and therefore
89      * is directly usable as a {@code localName} in an {@link AbstractQName}.
90      *
91      * @return This keyword's identifier part.
92      */
93     public final @NonNull String identifier() {
94         return identifier;
95     }
96
97     /**
98      * This keyword's 'prefix' part. This corresponds to {@code prefix identifier}. For {@code YANG keyword}s this is
99      * null. For language extension references this is the non-null prefix which references the YANG module defining
100      * the language extension.
101      *
102      * <p>
103      * Note the returned string, if non-null, is guaranteed to conform to rules of {@code identifier} ABNF and therefore
104      * is directly usable as a {@code localName} in an {@link AbstractQName}.
105      *
106      * @return This keyword's prefix, or null if this keyword references a YANG keyword.
107      */
108     public abstract @Nullable String prefix();
109
110     /**
111      * Helper method to re-create the string which was used to declared this keyword.
112      *
113      * @return Declaration string.
114      */
115     public abstract @NonNull String asStringDeclaration();
116 }