Skip to content

Commit fe41aea

Browse files
committed
Address review: ATN v4 guard, startRuleIndex by name, test hardening
- Assert ATN serialization version 4 for both lexer and parser to enforce antlr4ng compatibility contract - Resolve startRuleIndex by looking up "root" rule name instead of hardcoding 0 - Fix MockRestChannel.bytesOutput() to return real BytesStreamOutput - Document nullable elements in literalNames/symbolicNames Javadoc - Rename test methods to follow testXxx() convention per ppl/plugin modules Signed-off-by: Eric Wei <mengwei.eric@gmail.com>
1 parent c838750 commit fe41aea

4 files changed

Lines changed: 47 additions & 17 deletions

File tree

plugin/src/test/java/org/opensearch/sql/plugin/rest/RestPPLGrammarActionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ public XContentBuilder newBuilder(
241241

242242
@Override
243243
public BytesStreamOutput bytesOutput() {
244-
return null;
244+
return new BytesStreamOutput();
245245
}
246246
}
247247
}

ppl/src/main/java/org/opensearch/sql/ppl/autocomplete/GrammarBundle.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,15 @@ public class GrammarBundle {
4444
/** Start rule index (0 = root rule). */
4545
private int startRuleIndex;
4646

47-
/** Literal token names indexed by token type (e.g. "'search'", "'|'"). */
47+
/**
48+
* Literal token names indexed by token type (e.g. "'search'", "'|'"). Elements may be null for
49+
* tokens with no literal form; clients must handle sparse arrays.
50+
*/
4851
@NonNull private String[] literalNames;
4952

50-
/** Symbolic token names indexed by token type (e.g. "SEARCH", "PIPE"). */
53+
/**
54+
* Symbolic token names indexed by token type (e.g. "SEARCH", "PIPE"). Elements may be null for
55+
* tokens with no symbolic name; clients must handle sparse arrays.
56+
*/
5157
@NonNull private String[] symbolicNames;
5258
}

ppl/src/main/java/org/opensearch/sql/ppl/autocomplete/PPLGrammarBundleBuilder.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.nio.charset.StandardCharsets;
99
import java.security.MessageDigest;
1010
import java.security.NoSuchAlgorithmException;
11+
import java.util.Arrays;
1112
import org.antlr.v4.runtime.CharStreams;
1213
import org.antlr.v4.runtime.CommonTokenStream;
1314
import org.antlr.v4.runtime.Vocabulary;
@@ -48,12 +49,17 @@ public GrammarBundle build() {
4849
.parserRuleNames(parser.getRuleNames())
4950
.channelNames(lexer.getChannelNames())
5051
.modeNames(lexer.getModeNames())
51-
.startRuleIndex(0)
52+
.startRuleIndex(resolveStartRuleIndex(parser.getRuleNames()))
5253
.literalNames(literalNames)
5354
.symbolicNames(symbolicNames)
5455
.build();
5556
}
5657

58+
private static int resolveStartRuleIndex(String[] ruleNames) {
59+
int idx = Arrays.asList(ruleNames).indexOf("root");
60+
return Math.max(idx, 0);
61+
}
62+
5763
private static String computeGrammarHash(int[] lexerATN, int[] parserATN) {
5864
try {
5965
MessageDigest digest = MessageDigest.getInstance("SHA-256");

ppl/src/test/java/org/opensearch/sql/ppl/autocomplete/PPLGrammarBundleBuilderTest.java

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
public class PPLGrammarBundleBuilderTest {
1616

17+
private static final int EXPECTED_ATN_SERIALIZATION_VERSION = 4;
18+
1719
private static GrammarBundle bundle;
1820

1921
@BeforeClass
@@ -22,17 +24,17 @@ public static void buildBundle() {
2224
}
2325

2426
@Test
25-
public void bundleIsNotNull() {
27+
public void testBuildBundleNotNull() {
2628
assertNotNull(bundle);
2729
}
2830

2931
@Test
30-
public void bundleVersionIsSet() {
32+
public void testBuildBundleVersionIsSet() {
3133
assertEquals("1.0", bundle.getBundleVersion());
3234
}
3335

3436
@Test
35-
public void antlrVersionIsSet() {
37+
public void testBuildAntlrVersionIsSet() {
3638
String version = bundle.getAntlrVersion();
3739
assertNotNull("antlrVersion should not be null", version);
3840
assertTrue(
@@ -41,64 +43,80 @@ public void antlrVersionIsSet() {
4143
}
4244

4345
@Test
44-
public void grammarHashHasExpectedFormat() {
46+
public void testBuildGrammarHashHasSha256Format() {
4547
String hash = bundle.getGrammarHash();
4648
assertNotNull(hash);
4749
assertTrue("grammarHash should start with 'sha256:'", hash.startsWith("sha256:"));
4850
assertEquals("grammarHash should be 71 chars (sha256: + 64 hex)", 71, hash.length());
4951
}
5052

5153
@Test
52-
public void startRuleIndexIsZero() {
54+
public void testBuildStartRuleIndexIsZero() {
5355
assertEquals(0, bundle.getStartRuleIndex());
5456
}
5557

5658
@Test
57-
public void lexerATNIsNonEmpty() {
59+
public void testBuildLexerATNIsNonEmpty() {
5860
assertNotNull(bundle.getLexerSerializedATN());
5961
assertTrue(bundle.getLexerSerializedATN().length > 0);
6062
}
6163

6264
@Test
63-
public void parserATNIsNonEmpty() {
65+
public void testBuildLexerATNIsSerializationVersion4() {
66+
assertEquals(
67+
"Lexer ATN must be serialization version 4 for antlr4ng compatibility",
68+
EXPECTED_ATN_SERIALIZATION_VERSION,
69+
bundle.getLexerSerializedATN()[0]);
70+
}
71+
72+
@Test
73+
public void testBuildParserATNIsNonEmpty() {
6474
assertNotNull(bundle.getParserSerializedATN());
6575
assertTrue(bundle.getParserSerializedATN().length > 0);
6676
}
6777

6878
@Test
69-
public void lexerRuleNamesAreNonEmpty() {
79+
public void testBuildParserATNIsSerializationVersion4() {
80+
assertEquals(
81+
"Parser ATN must be serialization version 4 for antlr4ng compatibility",
82+
EXPECTED_ATN_SERIALIZATION_VERSION,
83+
bundle.getParserSerializedATN()[0]);
84+
}
85+
86+
@Test
87+
public void testBuildLexerRuleNamesAreNonEmpty() {
7088
assertNotNull(bundle.getLexerRuleNames());
7189
assertTrue(bundle.getLexerRuleNames().length > 0);
7290
}
7391

7492
@Test
75-
public void parserRuleNamesAreNonEmpty() {
93+
public void testBuildParserRuleNamesAreNonEmpty() {
7694
assertNotNull(bundle.getParserRuleNames());
7795
assertTrue(bundle.getParserRuleNames().length > 0);
7896
}
7997

8098
@Test
81-
public void channelNamesAreNonEmpty() {
99+
public void testBuildChannelNamesAreNonEmpty() {
82100
assertNotNull(bundle.getChannelNames());
83101
assertTrue(bundle.getChannelNames().length > 0);
84102
}
85103

86104
@Test
87-
public void modeNamesAreNonEmpty() {
105+
public void testBuildModeNamesAreNonEmpty() {
88106
assertNotNull(bundle.getModeNames());
89107
assertTrue(bundle.getModeNames().length > 0);
90108
}
91109

92110
@Test
93-
public void vocabularyIsNonEmpty() {
111+
public void testBuildVocabularyIsNonEmpty() {
94112
assertNotNull(bundle.getLiteralNames());
95113
assertNotNull(bundle.getSymbolicNames());
96114
assertTrue(bundle.getLiteralNames().length > 0);
97115
assertTrue(bundle.getSymbolicNames().length > 0);
98116
}
99117

100118
@Test
101-
public void buildIsDeterministic() {
119+
public void testBuildIsDeterministic() {
102120
GrammarBundle second = new PPLGrammarBundleBuilder().build();
103121
assertEquals(
104122
"Two builds of the same grammar should produce the same hash",

0 commit comments

Comments
 (0)