This is a streaming parser for VCF. It validates record structure strictly but is deliberately lenient about the quality of metadata declarations — see Validation: strict vs. lenient below.
The main parser class (VcfParser) is responsible for reading all metadata and initial position data. Then actual handling of each position line is delegated to an implementation of VcfLineParser.
Check out VcfParserTest.java for a quick and dirty view of it in action.
MemoryMappedVcfLineParser is an implementation of VcfLineParser that reads everything into memory.
VCF version support: ##fileformat accepts any VCFv<major>.<minor> at or above 4.0; the parser does not
hard-code a version ceiling. It was written against, and its reserved INFO/FORMAT/ALT/structural-variant definitions
reflect, VCF 4.1/4.2. Later versions generally parse correctly too — an unrecognized reserved key or Number value is
stored as a plain string rather than rejected — but version-specific features introduced after 4.2 (e.g.
percent-encoding, local alleles) are not specially interpreted.
The parser draws a deliberate line between the structure of a VCF record, which it validates strictly, and the quality of metadata declarations, which it validates leniently.
Strict — throws VcfFormatException. The parser rejects a file whose structure or mandatory record fields are
invalid:
- A missing, duplicate, or non-first
##fileformat; a version below theVCFv4.0floor; any line other than a##metadata line before the#CHROMheader; or a#-prefixed line after it (VCF has no comment syntax). - A missing
#CHROMheader, wrong fixed column names, a missingFORMATcolumn when samples are present, or duplicate sample names. - A data line with the wrong number of tab-separated columns.
- An empty mandatory fixed field (the missing value must be
.), an emptyCHROM, or a negativePOS. - Invalid
REF/ALTbases; anALTmissing value (.) combined with a real allele; whitespace where the spec forbids it (CHROM,ID,FILTER,INFO); a duplicate identifier within a singleIDfield; aFILTERof0orPASScombined with other filters; or aFORMATin whichGTis present but not the first sub-field. - A sample with more sub-fields than its
FORMATdeclares (trailing sub-fields may be dropped, but not added). - An invalid genotype passed to
VcfGenotype, a malformed or out-of-rangeGTallele index looked up throughMemoryMappedVcfDataStore, or a failed conversion when a typed value is requested. - A key or value set through
BaseMetadata's,VcfSample's, orVcfMetadata's mutators (e.g. aDescription, a sample'sGTvalue, or an##assemblyline) containing a line terminator.
These checks run when a VcfPosition is constructed (including by the parser). Its setters and the mutable lists
returned by its accessors (e.g. getAltBases(), getFilters()) do not re-run them, to support transformation
pipelines that mutate a position in place; call VcfPosition.validate() after such mutations to re-check validity —
this also re-normalizes a lone PASS or . FILTER value left by such a mutation, matching construction.
Lenient — logs a warning and keeps parsing. Malformed metadata declarations (##INFO, ##FORMAT, ##contig,
##FILTER, ##ALT, ...) warn rather than throw, and the declaration is still stored:
- A missing or invalid
Number,Type, orDescription; an unquotedDescription; orType=Flagwith aNumberother than0. An unparseableTypeleaves the metadata's typenull. - A header/metadata sample-count mismatch, or a sample named in the header but absent from the metadata.
- The writer's consistency checks (a value that does not match its declared type, a record referring to undeclared
FILTER/INFO/FORMATmetadata, a missing or extra sample sub-field, and similar).
Typed metadata accessors (e.g. InfoMetadata.getType() and getNumber()) are annotated @Nullable and return null
when the corresponding metadata was malformed.
<dependencies>
...
<dependency>
<groupId>org.pharmgkb</groupId>
<artifactId>vcf-parser</artifactId>
<version>0.3.1</version>
</dependency>
...
</dependencies>You can download jars from the Central Maven Repository.