0
# High-Level Parsing
1
2
The GherkinParser provides the main entry point for parsing Gherkin feature files into structured data formats. It supports multiple input sources and configurable output options through a builder pattern.
3
4
## Capabilities
5
6
### GherkinParser Creation
7
8
Create and configure a GherkinParser instance using the builder pattern.
9
10
```java { .api }
11
/**
12
* Create a new GherkinParser builder
13
* @return Builder instance for configuration
14
*/
15
public static GherkinParser.Builder builder();
16
17
/**
18
* Builder for configuring GherkinParser options
19
*/
20
public static final class Builder {
21
/**
22
* Configure whether to include source information in output
23
* @param includeSource true to include source data (default: true)
24
* @return this builder for chaining
25
*/
26
public Builder includeSource(boolean includeSource);
27
28
/**
29
* Configure whether to include GherkinDocument AST in output
30
* @param includeGherkinDocument true to include AST (default: true)
31
* @return this builder for chaining
32
*/
33
public Builder includeGherkinDocument(boolean includeGherkinDocument);
34
35
/**
36
* Configure whether to include compiled Pickles in output
37
* @param includePickles true to include pickles (default: true)
38
* @return this builder for chaining
39
*/
40
public Builder includePickles(boolean includePickles);
41
42
/**
43
* Set custom ID generator for element identification
44
* @param idGenerator custom ID generator implementation
45
* @return this builder for chaining
46
*/
47
public Builder idGenerator(IdGenerator idGenerator);
48
49
/**
50
* Build the configured GherkinParser instance
51
* @return configured parser ready for use
52
*/
53
public GherkinParser build();
54
}
55
```
56
57
### File Parsing
58
59
Parse Gherkin content from various sources including files, streams, and byte arrays.
60
61
```java { .api }
62
/**
63
* Parse a Gherkin feature file from filesystem path
64
* @param source Path to the .feature file
65
* @return Stream of Envelope messages containing parse results
66
* @throws IOException if file cannot be read
67
*/
68
public Stream<Envelope> parse(Path source) throws IOException;
69
70
/**
71
* Parse Gherkin content from InputStream
72
* @param uri URI identifier for the source (used in messages)
73
* @param source InputStream containing Gherkin content
74
* @return Stream of Envelope messages containing parse results
75
* @throws IOException if stream cannot be read
76
*/
77
public Stream<Envelope> parse(String uri, InputStream source) throws IOException;
78
79
/**
80
* Parse Gherkin content from byte array
81
* @param uri URI identifier for the source (used in messages)
82
* @param source byte array containing Gherkin content
83
* @return Stream of Envelope messages containing parse results
84
*/
85
public Stream<Envelope> parse(String uri, byte[] source);
86
87
/**
88
* Parse Gherkin content from existing Envelope message
89
* @param envelope Envelope containing Source message with Gherkin content
90
* @return Stream of Envelope messages containing parse results
91
*/
92
public Stream<Envelope> parse(Envelope envelope);
93
```
94
95
**Usage Examples:**
96
97
```java
98
// Parse from file path
99
GherkinParser parser = GherkinParser.builder().build();
100
Stream<Envelope> messages = parser.parse(Paths.get("features/login.feature"));
101
102
// Parse from string content
103
String gherkinContent = """
104
Feature: User Login
105
Scenario: Valid credentials
106
Given a user exists
107
When they enter valid credentials
108
Then they should be logged in
109
""";
110
Stream<Envelope> messages = parser.parse("test.feature",
111
gherkinContent.getBytes(StandardCharsets.UTF_8));
112
113
// Configure parser options
114
GherkinParser customParser = GherkinParser.builder()
115
.includeSource(false) // Skip source in output
116
.includePickles(true) // Include executable pickles
117
.idGenerator(() -> "custom-id") // Use custom ID generation
118
.build();
119
```
120
121
### Message Processing
122
123
Process the stream of Envelope messages returned by parsing operations.
124
125
```java { .api }
126
// Core message types returned in Envelope stream
127
interface Envelope {
128
Optional<Source> getSource(); // Original source content
129
Optional<GherkinDocument> getGherkinDocument(); // Parsed AST
130
Optional<Pickle> getPickle(); // Executable scenario
131
Optional<ParseError> getParseError(); // Parse error details
132
}
133
134
interface GherkinDocument {
135
String getUri();
136
Optional<Feature> getFeature();
137
List<Comment> getComments();
138
}
139
140
interface Pickle {
141
String getId();
142
String getUri();
143
String getName();
144
String getLanguage();
145
List<PickleStep> getSteps();
146
List<PickleTag> getTags();
147
List<String> getAstNodeIds();
148
}
149
```
150
151
**Message Processing Examples:**
152
153
```java
154
// Process all message types
155
parser.parse(featureFile).forEach(envelope -> {
156
// Handle source information
157
envelope.getSource().ifPresent(source ->
158
System.out.println("Parsing: " + source.getUri()));
159
160
// Handle parsed AST
161
envelope.getGherkinDocument().ifPresent(doc -> {
162
doc.getFeature().ifPresent(feature ->
163
System.out.println("Feature: " + feature.getName()));
164
});
165
166
// Handle executable scenarios
167
envelope.getPickle().ifPresent(pickle -> {
168
System.out.println("Scenario: " + pickle.getName());
169
pickle.getSteps().forEach(step ->
170
System.out.println(" " + step.getText()));
171
});
172
173
// Handle parse errors
174
envelope.getParseError().ifPresent(error ->
175
System.err.println("Parse error: " + error.getMessage()));
176
});
177
178
// Collect only pickles for test execution
179
List<Pickle> scenarios = parser.parse(featureFile)
180
.map(Envelope::getPickle)
181
.filter(Optional::isPresent)
182
.map(Optional::get)
183
.collect(Collectors.toList());
184
185
// Extract feature metadata
186
Optional<Feature> feature = parser.parse(featureFile)
187
.map(Envelope::getGherkinDocument)
188
.filter(Optional::isPresent)
189
.map(Optional::get)
190
.map(GherkinDocument::getFeature)
191
.filter(Optional::isPresent)
192
.map(Optional::get)
193
.findFirst();
194
```
195
196
### Error Handling
197
198
Handle parsing errors and exceptions during Gherkin processing.
199
200
```java { .api }
201
// Exception types thrown by the parser (package-private but visible to users)
202
ParserException.NoSuchLanguageException // Unsupported language code
203
ParserException.UnexpectedTokenException // Syntax errors in Gherkin
204
ParserException.UnexpectedEOFException // Premature end of file
205
ParserException.CompositeParserException // Multiple parsing errors
206
ParserException.AstBuilderException // AST construction failures
207
GherkinException // General processing errors
208
```
209
210
**Error Handling Examples:**
211
212
```java
213
import io.cucumber.gherkin.ParserException;
214
import io.cucumber.gherkin.GherkinException;
215
216
try {
217
Stream<Envelope> messages = parser.parse(featureFile);
218
219
// Check for parse errors in the stream
220
List<ParseError> errors = messages
221
.map(Envelope::getParseError)
222
.filter(Optional::isPresent)
223
.map(Optional::get)
224
.collect(Collectors.toList());
225
226
if (!errors.isEmpty()) {
227
errors.forEach(error ->
228
System.err.println("Parse error at " +
229
error.getSource().getLocation().getLine() + ": " +
230
error.getMessage()));
231
}
232
233
} catch (ParserException.NoSuchLanguageException e) {
234
System.err.println("Unsupported language in feature file: " + e.getMessage());
235
236
} catch (ParserException.UnexpectedTokenException e) {
237
System.err.println("Syntax error in Gherkin at line " +
238
e.location.getLine() + ": " + e.getMessage());
239
System.err.println("Expected: " + String.join(", ", e.expectedTokenTypes));
240
241
} catch (ParserException.CompositeParserException e) {
242
System.err.println("Multiple parsing errors found:");
243
e.errors.forEach(error ->
244
System.err.println(" - " + error.getMessage()));
245
246
} catch (GherkinException e) {
247
System.err.println("General parsing error: " + e.getMessage());
248
if (e.getCause() != null) {
249
System.err.println("Caused by: " + e.getCause().getMessage());
250
}
251
252
} catch (IOException e) {
253
System.err.println("Failed to read feature file: " + e.getMessage());
254
}
255
```
256
257
**Language Error Example:**
258
259
```java
260
// This will throw NoSuchLanguageException
261
String invalidLanguageFeature = """
262
# language: xyz-invalid
263
Feature: Test
264
Scenario: Example
265
Given something
266
""";
267
268
try {
269
parser.parse("test.feature", invalidLanguageFeature.getBytes());
270
} catch (ParserException.NoSuchLanguageException e) {
271
System.err.println("Language 'xyz-invalid' is not supported");
272
273
// Show available languages
274
GherkinDialectProvider provider = new GherkinDialectProvider();
275
System.out.println("Available languages: " + provider.getLanguages());
276
}
277
```