Populate parser/ hierarchy
[yangtools.git] / parser / yang-parser-spi / src / main / java / org / opendaylight / yangtools / yang / parser / spi / source / ExplicitStatement.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  * Copyright (c) 2021 PANTHEON.tech, s.r.o.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9 package org.opendaylight.yangtools.yang.parser.spi.source;
10
11 import static com.google.common.base.Preconditions.checkArgument;
12 import static com.google.common.base.Verify.verifyNotNull;
13
14 import com.google.common.annotations.Beta;
15 import java.util.Objects;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.yangtools.yang.model.api.meta.DeclarationInFile;
19 import org.opendaylight.yangtools.yang.model.api.meta.DeclarationInText;
20 import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference;
21 import org.opendaylight.yangtools.yang.model.api.meta.StatementOrigin;
22
23 /**
24  * Reference of statement source present in textual source format. Utility implementation
25  * of {@link StatementSourceReference} for textual sources, this is preferred {@link StatementSourceReference}
26  * for implementations of YANG / YIN statement stream sources.
27  *
28  * <p>
29  * To create source reference use one of this static factories:
30  * <ul>
31  *   <li>{@link #atPosition(String, int, int)} - provides most specific reference of statement location, this is most
32  *       preferred since it provides most context to debug YANG model.</li>
33  *   <li>{@link #atPosition(int, int)}- provides location in text without knowing the name of the text file.</li>
34  *   <li>{@link #inFile(String)}- provides a source name.</li>
35  * </ul>
36  */
37 @Beta
38 public abstract class ExplicitStatement extends StatementSourceReference implements DeclarationReference {
39     private static final class InFile extends ExplicitStatement implements DeclarationInFile {
40         InFile(final String fileName) {
41             super(fileName, -1, -1);
42             checkArgument(!fileName.isEmpty(), "Invalid empty file name");
43         }
44
45         @Override
46         public String fileName() {
47             return verifyNotNull(file());
48         }
49     }
50
51     private static class InText extends ExplicitStatement implements DeclarationInText {
52         InText(final String file, final int line, final int column) {
53             super(file, line, column);
54             checkArgument(line > 0, "Invalid start line %s", line);
55             checkArgument(column > 0, "Invalid start column %s", column);
56         }
57
58         @Override
59         public int startLine() {
60             return line();
61         }
62
63         @Override
64         public int startColumn() {
65             return column();
66         }
67     }
68
69     private static final class InTextFile extends InText implements DeclarationInFile {
70         InTextFile(final String fileName, final int line, final int column) {
71             super(fileName, line, column);
72             checkArgument(!fileName.isEmpty(), "Invalid empty file name");
73         }
74
75         @Override
76         public String fileName() {
77             return verifyNotNull(file());
78         }
79     }
80
81     private final String file;
82     private final int line;
83     private final int column;
84
85     ExplicitStatement(final String file, final int line, final int column) {
86         this.file = file;
87         this.line = line;
88         this.column = column;
89     }
90
91     public static @NonNull ExplicitStatement atPosition(final int line, final int column) {
92         return new InText(null, line, column);
93     }
94
95     public static @NonNull ExplicitStatement atPosition(final @Nullable String fileName, final int line,
96             final int column) {
97         return fileName == null ? atPosition(line, column) : new InTextFile(fileName, line, column);
98     }
99
100     public static @NonNull ExplicitStatement inFile(final @NonNull String fileName) {
101         return new InFile(fileName);
102     }
103
104     @Override
105     public final StatementOrigin statementOrigin() {
106         return StatementOrigin.DECLARATION;
107     }
108
109     @Override
110     public final DeclarationReference declarationReference() {
111         return this;
112     }
113
114     @Override
115     public final String toHumanReadable() {
116         final StringBuilder sb = new StringBuilder();
117         sb.append(file != null ? file : "<UNKNOWN>");
118         if (line > 0) {
119             sb.append(':').append(line);
120         }
121         if (column > 0) {
122             sb.append(':').append(column);
123         }
124         return sb.toString();
125     }
126
127     @Override
128     public final int hashCode() {
129         return Objects.hash(file(), line(), column());
130     }
131
132     @Override
133     public final boolean equals(final Object obj) {
134         if (this == obj) {
135             return true;
136         }
137         if (obj == null || !getClass().equals(obj.getClass())) {
138             return false;
139         }
140         final ExplicitStatement other = (ExplicitStatement) obj;
141         return line == other.line && column == other.column && Objects.equals(file, other.file);
142     }
143
144     @Override
145     public final String toString() {
146         return toHumanReadable();
147     }
148
149     final String file() {
150         return file;
151     }
152
153     final int line() {
154         return line;
155     }
156
157     final int column() {
158         return column;
159     }
160 }