Add StatementDeclaration
[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.StatementDeclaration;
21 import org.opendaylight.yangtools.yang.model.api.meta.StatementSourceReference;
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 StatementDeclaration {
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 int hashCode() {
106         return Objects.hash(file(), line(), column());
107     }
108
109     @Override
110     public final boolean equals(final Object obj) {
111         if (this == obj) {
112             return true;
113         }
114         if (obj == null || !getClass().equals(obj.getClass())) {
115             return false;
116         }
117         final ExplicitStatement other = (ExplicitStatement) obj;
118         return line == other.line && column == other.column && Objects.equals(file, other.file);
119     }
120
121     @Override
122     protected final String file() {
123         return file;
124     }
125
126     @Override
127     protected final int line() {
128         return line;
129     }
130
131     @Override
132     protected final int column() {
133         return column;
134     }
135 }