Protobuf sources
Below you will find the Protocol Buffers definitions for the Jelly-RDF, Jelly-Patch, and Jelly-SPARQL formats, along with the Jelly gRPC streaming protocol. The original files are hosted on GitHub and all releases can be found here.
Human-readable reference for these definitions can be found here.
The following code is licensed under the Apache License, Version 2.0.
rdf.proto
syntax = "proto3";
package eu.ostrzyciel.jelly.core.proto.v1;
// Jelly RDF serialization with Protocol Buffers.
// Specification document:
// https://w3id.org/jelly/1.2.0/specification/serialization
// Protocol version: 1.2.0
//
// A Jelly-RDF stream is a sequence of RdfStreamFrame messages. The contents
// of the frames use one of two layouts, depending on the protocol version:
//
// - Column layout (version 3, Jelly-RDF 1.2.x): the statements of a frame
// are stored column by column in an RdfColumnBatch.
// - Row layout (versions 1 and 2, Jelly-RDF 1.0.x and 1.1.x): a frame is a
// list of RdfStreamRow messages. The messages used only by this layout
// are in the "Row layout" section at the end of this file.
//
// Comments starting with "If row layout:" or "If column layout:" apply only
// to streams in that layout.
// ---------------------------------------------------------------------------
// RDF terms
// ---------------------------------------------------------------------------
// RDF IRI, encoded as a prefix and a name from the lookup tables. The IRI is
// the prefix followed by the name.
message RdfIri {
// 1-based identifier of the prefix in the prefix lookup.
// 0 means "the same prefix as in the previous IRI", or no prefix in the
// first IRI. Which IRI is the previous one depends on the layout.
uint32 prefix_id = 1;
// 1-based identifier of the name in the name lookup.
// 0 means "the name_id of the previous IRI + 1", or 1 in the first IRI.
uint32 name_id = 2;
}
// Version of RDF that a stream conforms to, following the version labels of
// RDF 1.2 Concepts:
// https://www.w3.org/TR/rdf12-concepts/#defined-version-labels
enum RdfVersion {
// Unspecified. Each format that uses this enum defines how to interpret it.
RDF_VERSION_UNSPECIFIED = 0;
// RDF 1.1 (version label "1.1"): no triple terms, no base directions.
RDF_VERSION_1_1 = 1;
// RDF 1.2 Basic (version label "1.2-basic"): base directions are allowed,
// triple terms are not.
RDF_VERSION_1_2_BASIC = 2;
// RDF 1.2 (version label "1.2"): base directions and triple terms are
// allowed.
RDF_VERSION_1_2 = 3;
}
// Initial text direction of a language-tagged string (RDF 1.2).
enum RdfBaseDirection {
// No base direction: an ordinary language-tagged string (rdf:langString).
RDF_BASE_DIRECTION_UNSPECIFIED = 0;
// Left-to-right ("ltr"): a directional language-tagged string
// (rdf:dirLangString).
RDF_BASE_DIRECTION_LTR = 1;
// Right-to-left ("rtl"): a directional language-tagged string
// (rdf:dirLangString).
RDF_BASE_DIRECTION_RTL = 2;
}
// RDF literal
message RdfLiteral {
// The lexical form of the literal.
string lex = 1;
// Literal kind – at most one of these fields may be set.
// If none is set, the literal is a simple literal (xsd:string).
oneof literalKind {
// Language tag of a language-tagged string.
string langtag = 2;
// 1-based identifier of the datatype in the datatype lookup.
// 0 is invalid (in contrast to prefix_id and name_id in RdfIri).
// If column layout: must not refer to rdf:langString or
// rdf:dirLangString.
uint32 datatype = 3;
}
// Base direction of a language-tagged string (RDF 1.2).
// If column layout: may be set only if langtag is set.
// If row layout: must not be set.
RdfBaseDirection direction = 4;
}
// RDF 1.2 triple term. All three positions must be set, and only the object
// may be a nested triple term. The field numbers are the same as in
// RdfTriple.
//
// Used by the column layout and by Jelly-SPARQL.
message RdfTripleTerm {
// Subject
oneof subject {
// IRI
RdfIri s_iri = 1;
// Blank node
string s_bnode = 2;
}
// Predicate
RdfIri p_iri = 5;
// Object
oneof object {
// IRI
RdfIri o_iri = 9;
// Blank node
string o_bnode = 10;
// Literal
RdfLiteral o_literal = 11;
// Nested triple term
RdfTripleTerm o_triple_term = 12;
}
}
// ---------------------------------------------------------------------------
// Lookup tables
// ---------------------------------------------------------------------------
// Packed entries of a lookup table (name, prefix, or datatype): the values of
// a run of consecutive identifiers.
//
// Used by the column layout and by Jelly-SPARQL.
message RdfLookupEntryPacked {
// 1-based identifier of the first value.
// 0 means "the identifier after the last value of the previous entry of
// the same lookup table", or 1 in the first entry of the table.
uint32 id = 1;
// Values of the entries (UTF-8 encoded), for consecutive identifiers
// starting at id.
repeated string values = 2;
}
// ---------------------------------------------------------------------------
// Stream options
// ---------------------------------------------------------------------------
// RDF stream options
//
// If row layout: the options may occur again later in the stream, but must
// be identical to the first occurrence.
// If column layout: a later frame may restate the options, which empties the
// lookup tables. This makes streams concatenable. physical_type, stream_type,
// and version must stay the same.
message RdfStreamOptions {
// Name of the stream (completely optional).
// This may be used for, e.g., topic names in a pub/sub system.
string stream_name = 1;
// Type of the stream (required).
// If row layout: TRIPLES, QUADS, or GRAPHS.
// If column layout: TRIPLES or QUADS.
PhysicalStreamType physical_type = 2;
// If row layout: whether the stream may contain generalized triples,
// quads, or datasets.
// If column layout: must not be set.
bool generalized_statements = 3;
// If row layout: whether the stream may contain RDF-star statements.
// If column layout: must not be set – use rdf_version instead.
bool rdf_star = 4;
// If column layout: whether the stream is one RDF graph or dataset, or a
// stream of RDF Messages. Defaults to RDF_STREAM_TYPE_FLAT.
// If row layout: must not be set.
RdfStreamType stream_type = 5;
// If column layout: version of RDF whose terms may occur in the stream.
// Unspecified (the default) means that no version is announced, and the
// stream may contain any RDF 1.2 term.
// If row layout: must not be set.
RdfVersion rdf_version = 6;
// Maximum size of the name lookup table (required).
// If row layout: must be >= 8.
// If column layout: must be >= 128.
uint32 max_name_table_size = 9;
// Maximum size of the prefix lookup table
// (required if the prefix lookup is used)
uint32 max_prefix_table_size = 10;
// Maximum size of the datatype lookup table
// (required if datatype literals are used)
uint32 max_datatype_table_size = 11;
// If row layout: logical (RDF-STaX-based) stream type. In contrast to the
// physical type, this field is entirely optional.
// If column layout: must not be set – use stream_type instead.
LogicalStreamType logical_type = 14;
// Protocol version (required)
// For Jelly-RDF 1.0.x the value must be 1 (row layout).
// For Jelly-RDF 1.1.x the value must be 2 (row layout).
// For Jelly-RDF 1.2.x the value must be 3 (column layout).
// For custom extensions, the value must be 10000 or higher.
uint32 version = 15;
}
// Physical stream type: whether the stream contains triples or quads.
enum PhysicalStreamType {
// Unspecified stream type – invalid
PHYSICAL_STREAM_TYPE_UNSPECIFIED = 0;
// RDF triples
PHYSICAL_STREAM_TYPE_TRIPLES = 1;
// RDF quads
PHYSICAL_STREAM_TYPE_QUADS = 2;
// RDF triples grouped in graphs.
// If column layout: invalid.
PHYSICAL_STREAM_TYPE_GRAPHS = 3;
}
// Type of an RDF stream. Not used in the row layout.
enum RdfStreamType {
// The entire stream is one RDF graph (TRIPLES) or one RDF dataset (QUADS).
// This is the default.
// buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX
RDF_STREAM_TYPE_FLAT = 0;
// The stream is a sequence of RDF Messages, each an RDF graph or dataset:
// https://w3c-cg.github.io/rsp/spec/messages
// The messages are delimited by RdfColumnBatch.message_lengths.
RDF_STREAM_TYPE_MESSAGES = 1;
}
// ---------------------------------------------------------------------------
// Stream frame
// ---------------------------------------------------------------------------
// RDF stream frame – base message for RDF streams.
message RdfStreamFrame {
// Stream rows.
// If row layout: the contents of the frame.
// If column layout: either empty, or exactly one row with the stream
// options.
repeated RdfStreamRow rows = 1;
// If column layout: the contents of the frame.
// If row layout: must not be set.
RdfColumnBatch columns = 2;
// Arbitrary metadata
// The keys are UTF-8 encoded strings, the values are byte arrays.
// This may be used by implementations in any way they see fit.
// The metadata does not affect the RDF data in any way, treat it
// as comments in a text file.
map<string, bytes> metadata = 15;
}
// ---------------------------------------------------------------------------
// Column layout
// ---------------------------------------------------------------------------
// The contents of a frame in the column layout: a batch of statements, and
// the lookup entries and namespace declarations they need.
//
// Each statement is made up of the cells at the same position in the
// subjects, predicates, objects, and graphs columns.
message RdfColumnBatch {
// Number of statements in the batch. At most 2^27 - 1.
uint32 row_count = 1;
// Entries of the name lookup table.
repeated RdfLookupEntryPacked names = 2;
// Entries of the prefix lookup table.
//
// Note: the prefixes in the lookup table can be arbitrary strings, and are
// NOT meant to be user-facing. They are only used for IRI compression.
// To transmit user-facing namespace declarations, use `namespaces`.
repeated RdfLookupEntryPacked prefixes = 3;
// Entries of the datatype lookup table.
repeated RdfLookupEntryPacked datatypes = 4;
// Namespace declarations.
repeated RdfNamespaceDeclaration namespaces = 5;
// Subjects: IRIs or blank nodes. No cell may be unbound.
RdfColumn subjects = 6;
// Predicates: IRIs. No cell may be unbound.
RdfColumn predicates = 7;
// Objects: IRIs, blank nodes, literals, or triple terms. No cell may be
// unbound.
RdfColumn objects = 8;
// Graph names: IRIs or blank nodes. An unbound cell is the default graph.
// Only valid if the physical type is QUADS. If not set, all statements of
// the batch are in the default graph.
RdfColumn graphs = 9;
// Message boundaries: each value adds that many more statements to the
// current RDF Message, and then ends it.
// Only valid in streams of type RDF_STREAM_TYPE_MESSAGES.
repeated uint32 message_lengths = 15;
}
// Explicit namespace declaration
//
// This is a hint to the consumer that the given IRI (namespace) may be
// associated with a short name, like in Turtle syntax:
// PREFIX ex: <http://example.org/>
//
// This is a purely cosmetic feature, not part of the RDF data. It has nothing
// in common with the prefix lookup table. A declaration stays in effect until
// the same name is declared again.
message RdfNamespaceDeclaration {
// Short name of the namespace (e.g., "ex")
// Do NOT include the colon.
string name = 1;
// IRI of the namespace (e.g., "http://example.org/")
RdfIri value = 2;
}
// ---------------------------------------------------------------------------
// Columns
// ---------------------------------------------------------------------------
// Column of RDF terms: the cells of one statement position (Jelly-RDF) or one
// variable (Jelly-SPARQL) across all rows of a batch, in row order. A cell is
// either an RDF term or unbound.
//
// Each run of consecutive equal terms is stored once, as a run value, and
// unbound cells are not stored. The run values are split by type into
// separate lists. `kinds` gives the type of each run value, and `layouts`
// gives the runs of repeated values and of unbound cells.
//
// Used by the column layout and by Jelly-SPARQL.
message RdfColumn {
// Type of each run value, 2 bits per value, four values per byte, starting
// from the least significant bits: 0 = IRI, 1 = literal, 2 = blank node,
// 3 = triple term.
// Should be empty if all run values are of one type.
bytes kinds = 1;
// Sequence layout: where the run values repeat, and where the unbound cells
// are. Each entry is a token (skip << 5) | (kind << 4) | len_code, and a
// len_code of 15 is followed by an extension varint.
// Empty if every cell is bound and no value repeats.
repeated uint32 layouts = 2;
// Name identifiers of the IRIs, in row order.
// 0 means "previous name_id + 1", or 1 in the first IRI of the column.
repeated uint32 name_ids = 3;
// Prefix identifiers of the IRIs: none (no prefix), one (the same prefix
// for all IRIs), or one per IRI.
// 0 means "the same prefix as the previous IRI", or no prefix in the first
// IRI of the column.
repeated uint32 prefix_ids = 4;
// Lexical forms of the literals, in row order.
repeated string lex_values = 5;
// Literal kinds of the literals: none (all are simple literals), one (the
// same kind for all literals), or one per literal.
// 0 – simple literal (xsd:string)
// odd v – literal with the datatype (v + 1) / 2 of the datatype
// lookup
// even v > 0 – language-tagged string with the language tag
// langtags[v / 2 - 1]
repeated uint32 literal_kinds = 6;
// Language tags referred to by literal_kinds.
repeated string langtags = 7;
// Base directions of the language tags (RdfBaseDirection values), parallel
// to langtags. Empty means no base direction for any tag.
repeated uint32 langtag_directions = 8;
// Labels of the blank nodes, in row order.
repeated string bnodes = 9;
// Triple terms, in row order. The IRIs inside the triple terms are
// inferred separately from name_ids and prefix_ids.
repeated RdfTripleTerm triple_terms = 10;
}
// ---------------------------------------------------------------------------
// Row layout (Jelly-RDF 1.0.x and 1.1.x)
//
// The messages below are not used in the column layout. They are also used by
// Jelly-Patch.
// ---------------------------------------------------------------------------
// Empty message indicating the default RDF graph.
//
// Not used in the column layout.
message RdfDefaultGraph {}
// RDF triple
//
// For each term (subject, predicate, object), the fields are repeated for
// performance reasons. This is to avoid the need for boxing each term in a
// separate message.
//
// Note: this message allows for representing generalized RDF triples (for
// example, with literals as predicates). Whether this is used in the stream
// is determined by the stream options (see RdfStreamOptions).
//
// If no field in a given oneof is set, the term is interpreted as a repeated
// term – the same as the term in the same position in the previous triple.
// In the first triple of the stream, all terms must be set.
// All terms must also be set in quoted triples (RDF-star).
//
// Not used in the column layout.
message RdfTriple {
// Triple subject
oneof subject {
// IRI
RdfIri s_iri = 1;
// Blank node
string s_bnode = 2;
// Literal
// Only valid in a generalized RDF stream.
RdfLiteral s_literal = 3;
// RDF-star quoted triple
RdfTriple s_triple_term = 4;
}
// Triple predicate
oneof predicate {
// IRI
RdfIri p_iri = 5;
// Blank node
// Only valid in a generalized RDF stream.
string p_bnode = 6;
// Literal
// Only valid in a generalized RDF stream.
RdfLiteral p_literal = 7;
// RDF-star quoted triple
RdfTriple p_triple_term = 8;
}
// Triple object
oneof object {
// IRI
RdfIri o_iri = 9;
// Blank node
string o_bnode = 10;
// Literal
RdfLiteral o_literal = 11;
// RDF-star quoted triple
RdfTriple o_triple_term = 12;
}
}
// RDF quad
//
// Fields 1–12 are repeated from RdfTriple for performance reasons.
//
// Similarly to RdfTriple, this message allows for representing generalized
// RDF quads (for example, with literals as predicates). Whether this is used
// in the stream is determined by the stream options (see RdfStreamOptions).
//
// If no field in a given oneof is set, the term is interpreted as a repeated
// term – the same as the term in the same position in the previous quad.
// In the first quad of the stream, all terms must be set.
//
// Not used in the column layout.
message RdfQuad {
// Quad subject
oneof subject {
// IRI
RdfIri s_iri = 1;
// Blank node
string s_bnode = 2;
// Literal
// Only valid in a generalized RDF stream.
RdfLiteral s_literal = 3;
// RDF-star quoted triple
RdfTriple s_triple_term = 4;
}
// Quad predicate
oneof predicate {
// IRI
RdfIri p_iri = 5;
// Blank node
// Only valid in a generalized RDF stream.
string p_bnode = 6;
// Literal
// Only valid in a generalized RDF stream.
RdfLiteral p_literal = 7;
// RDF-star quoted triple
RdfTriple p_triple_term = 8;
}
// Quad object
oneof object {
// IRI
RdfIri o_iri = 9;
// Blank node
string o_bnode = 10;
// Literal
RdfLiteral o_literal = 11;
// RDF-star quoted triple
RdfTriple o_triple_term = 12;
}
// Quad graph
oneof graph {
// IRI
RdfIri g_iri = 13;
// Blank node
string g_bnode = 14;
// Default graph
RdfDefaultGraph g_default_graph = 15;
// Literal – only valid for generalized RDF streams
RdfLiteral g_literal = 16;
}
}
// Start of a graph in a GRAPHS stream
//
// In contrast to RdfQuad, setting the graph oneof to some value
// is always required. No repeated terms are allowed.
//
// Not used in the column layout.
message RdfGraphStart {
oneof graph {
// IRI
RdfIri g_iri = 1;
// Blank node
string g_bnode = 2;
// Default graph
RdfDefaultGraph g_default_graph = 3;
// Literal – only valid for generalized RDF streams
RdfLiteral g_literal = 4;
}
}
// End of a graph in a GRAPHS stream
//
// Not used in the column layout.
message RdfGraphEnd {}
// Entry in the name lookup table
//
// Not used in the column layout.
message RdfNameEntry {
// 1-based identifier
// If id=0, it should be interpreted as previous_id + 1.
// If id=0 appears in the first RdfNameEntry of the stream, it should be
// interpreted as 1.
uint32 id = 1;
// Value of the name (UTF-8 encoded)
string value = 2;
}
// Entry in the prefix lookup table
//
// Note: the prefixes in the lookup table can be arbitrary strings, and are
// NOT meant to be user-facing. They are only used for IRI compression.
// To transmit user-facing namespace declarations for cosmetic purposes, use
// RdfNamespaceDeclaration.
//
// Not used in the column layout.
message RdfPrefixEntry {
// 1-based identifier
// If id=0, it should be interpreted as previous_id + 1.
// If id=0 appears in the first RdfPrefixEntry of the stream, it should be
// interpreted as 1.
uint32 id = 1;
// Value of the prefix (UTF-8 encoded)
string value = 2;
}
// Entry in the datatype lookup table
//
// Not used in the column layout.
message RdfDatatypeEntry {
// 1-based identifier
// If id=0, it should be interpreted as previous_id + 1.
// If id=0 appears in the first RdfDatatypeEntry of the stream, it should be
// interpreted as 1.
uint32 id = 1;
// Value of the datatype (UTF-8 encoded)
string value = 2;
}
// Logical stream type, according to the RDF Stream Taxonomy (RDF-STaX).
// If column layout: not used – use RdfStreamType instead.
//
// Type 0 is reserved for the unspecified stream type.
// The rest of the type numbers follow the taxonomical structure of RDF-STaX.
// For example: 1 is a subtype of 0, 13 and 23 are subtypes of 3,
// 114 is a subtype of 14, etc.
//
// Types 1–4 correspond to the four base concrete stream types. Their
// subtypes can be in most cases simply processed in the same way as
// the base types.
// Therefore, implementations can take the modulo 10 of the stream
// type to determine the base type of the stream and use this information
// to select the appropriate processing logic.
//
// RDF-STaX version: 1.1.2
// https://w3id.org/stax/1.1.2
//
// Not used in the column layout.
enum LogicalStreamType {
// Unspecified stream type – invalid
LOGICAL_STREAM_TYPE_UNSPECIFIED = 0;
// Flat RDF triple stream
// https://w3id.org/stax/ontology#flatTripleStream
LOGICAL_STREAM_TYPE_FLAT_TRIPLES = 1;
// Flat RDF quad stream
// https://w3id.org/stax/ontology#flatQuadStream
LOGICAL_STREAM_TYPE_FLAT_QUADS = 2;
// RDF graph stream
// https://w3id.org/stax/ontology#graphStream
LOGICAL_STREAM_TYPE_GRAPHS = 3;
// RDF dataset stream
// https://w3id.org/stax/ontology#datasetStream
LOGICAL_STREAM_TYPE_DATASETS = 4;
// RDF subject graph stream (subtype of RDF graph stream)
// https://w3id.org/stax/ontology#subjectGraphStream
LOGICAL_STREAM_TYPE_SUBJECT_GRAPHS = 13;
// RDF named graph stream (subtype of RDF dataset stream)
// https://w3id.org/stax/ontology#namedGraphStream
LOGICAL_STREAM_TYPE_NAMED_GRAPHS = 14;
// RDF timestamped named graph stream (subtype of RDF dataset stream)
// https://w3id.org/stax/ontology#timestampedNamedGraphStream
LOGICAL_STREAM_TYPE_TIMESTAMPED_NAMED_GRAPHS = 114;
}
// RDF stream row
//
// If row layout: one element of a frame.
// If column layout: only the `options` field may be set.
message RdfStreamRow {
// Exactly one of these fields must be set.
oneof row {
// Stream options. Must occur at the start of the stream.
RdfStreamOptions options = 1;
// RDF triple statement.
// Valid in streams of physical type TRIPLES or GRAPHS.
RdfTriple triple = 2;
// RDF quad statement.
// Only valid in streams of physical type QUADS.
RdfQuad quad = 3;
// Graph boundary: ends the currently transmitted graph and starts a new one
// Only valid in streams of physical type GRAPHS.
RdfGraphStart graph_start = 4;
// Explicit end of a graph.
// Signals the consumer that the transmitted graph is complete.
// Only valid in streams of physical type GRAPHS.
RdfGraphEnd graph_end = 5;
// Explicit namespace declaration.
RdfNamespaceDeclaration namespace = 6;
// Entry in the name lookup table.
RdfNameEntry name = 9;
// Entry in the prefix lookup table.
RdfPrefixEntry prefix = 10;
// Entry in the datatype lookup table.
RdfDatatypeEntry datatype = 11;
}
}
sparql.proto
syntax = "proto3";
package eu.ostrzyciel.jelly.core.proto.v1.sparql;
// Jelly-SPARQL: binary serialization for SPARQL query results
// (solution sequences and boolean ASK results), based on the Jelly-RDF term
// encoding (rdf.proto).
// Specification document:
// https://w3id.org/jelly/1.2.0/specification/sparql
// Protocol version: 1.0.0
//
// The results are transmitted as a stream of frames. Each frame contains a
// batch of solutions (rows) in a columnar layout: one column per variable.
// The columns (RdfColumn) and their sequence layout encoding are defined in
// rdf.proto, and shared with the column layout of Jelly-RDF.
//
// The first frame has the header: stream options and the variable names, one
// per column. The stream ends with a trailer, which says whether the result
// set is complete.
//
// By default, a stream contains one result set (SPARQL_STREAM_TYPE_FLAT). A
// stream of type SPARQL_STREAM_TYPE_PUNCTUATED contains a sequence of result
// sets instead, each ended by a trailer.
import "rdf.proto";
// Stream options for SPARQL result streams.
message SparqlResultsOptions {
// Name of the stream (completely optional).
// This may be used for, e.g., topic names in a pub/sub system.
string stream_name = 1;
// Type of the stream: one result set, or a sequence of result sets.
// Defaults to SPARQL_STREAM_TYPE_FLAT.
SparqlStreamType stream_type = 2;
// Version of RDF whose terms may occur in the stream.
// RDF_VERSION_1_1 – no triple terms, no base directions
// RDF_VERSION_1_2_BASIC – base directions, no triple terms
// RDF_VERSION_1_2 – base directions and triple terms
// Unspecified (the default) means that no version is announced: the stream
// may contain any RDF 1.2 term.
RdfVersion rdf_version = 5;
// Maximum size of the name lookup table
// (required, must be >= 128)
uint32 max_name_table_size = 9;
// Maximum size of the prefix lookup table
// (required if the prefix lookup is used)
uint32 max_prefix_table_size = 10;
// Maximum size of the datatype lookup table
// (required if datatype literals are used)
uint32 max_datatype_table_size = 11;
// Protocol version (required)
// For Jelly-SPARQL 1.0.x, the value must be 1.
// For custom extensions, the value must be 10000 or higher.
uint32 version = 15;
}
// Type of a SPARQL result stream.
enum SparqlStreamType {
// The entire stream is a single result set. This is the default.
// buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX
SPARQL_STREAM_TYPE_FLAT = 0;
// The stream is a sequence of result sets, each ended by a frame with a
// trailer. The lookup tables are kept from one result set to the next.
SPARQL_STREAM_TYPE_PUNCTUATED = 1;
}
// Boolean result of a SPARQL ASK query.
message SparqlAskResult {
// The boolean value of the result.
bool value = 1;
}
// End-of-result-set marker, saying whether the result set is complete.
// Producers must write it in the last frame of every result set, unless they
// cannot write anything more at all (for example, because the process died).
message SparqlResultsTrailer {
// Empty (the default) means the result set is complete.
// A non-empty value is a human-readable explanation of why the producer
// could not complete the result set (e.g., query failure mid-evaluation).
string error = 1;
}
// SPARQL results frame – base message of a SPARQL result stream.
// A frame contains a batch of rows (solutions).
message SparqlResultsFrame {
// Stream options.
// Must be set in the first frame of the stream. May be set again in a
// later frame, which empties the lookup tables.
SparqlResultsOptions options = 1;
// Result set header: the names of the variables, in projection (SELECT
// clause) order, without the leading "?" or "$".
// Set in the first frame of a result set with a solution sequence, and in
// a frame that contains the options.
repeated string variables = 2;
// Number of rows (solutions) in this frame. At most 2^27 - 1.
uint32 row_count = 3;
// Entries in the name lookup table.
repeated RdfLookupEntryPacked names = 4;
// Entries in the prefix lookup table.
//
// Note: the prefixes in the lookup table can be arbitrary strings, and are
// NOT meant to be user-facing. They are only used for IRI compression.
repeated RdfLookupEntryPacked prefixes = 5;
// Entries in the datatype lookup table.
repeated RdfLookupEntryPacked datatypes = 6;
// Columns, one per variable, in the order of `variables`, or none.
repeated RdfColumn columns = 7;
// Boolean (ASK) result.
// If set, the result set is a boolean result instead of a solution
// sequence. A boolean result is always the only frame of its result set.
SparqlAskResult ask_result = 8;
// End-of-result-set marker. See SparqlResultsTrailer.
SparqlResultsTrailer trailer = 9;
// Arbitrary metadata
// The keys are UTF-8 encoded strings, the values are byte arrays.
// The metadata does not affect the result data in any way, treat it
// as comments in a text file.
//
// Well-known keys (their values must be valid UTF-8):
// link – zero or more IRIs separated by LF (U+000A), describing the
// result set as a whole (not the frame). Corresponds to head.link
// in the SPARQL Query Results JSON format.
//
// All other keys may be used by implementations in any way they see fit,
// and their values are arbitrary bytes.
map<string, bytes> metadata = 15;
}
patch.proto
syntax = "proto3";
package eu.ostrzyciel.jelly.core.proto.v1.patch;
// EXPERIMENTAL FEATURE -- the API and format may change.
// RDF Patch implementation based on Jelly
// RDF Patch spec: https://afs.github.io/rdf-delta/rdf-patch.html
// Jelly-Patch spec: https://w3id.org/jelly/1.1.0/specification/patch
import "rdf.proto";
message RdfPatchTransactionStart {}
message RdfPatchTransactionCommit {}
message RdfPatchTransactionAbort {}
message RdfPatchNamespace {
// Short name of the namespace (e.g., "ex")
// Do NOT include the colon.
string name = 1;
// IRI of the namespace (e.g., "http://example.org/").
// Optional in the "prefix delete" (PD) operation,
// but required in the "prefix add" (PA) operation.
RdfIri value = 2;
// Graph name for the namespace declaration.
//
// This is required for the statement type QUADS, and disallowed for
// the statement type TRIPLES.
//
// This is used to achieve full 1:1 replication in systems that associate
// namespaces with specific graphs (e.g., Apache Jena).
//
// Repeated term compression IS supported for this field.
// The repeated terms are shared between the namespace and statement rows.
oneof graph {
// IRI
RdfIri g_iri = 3;
// Blank node
string g_bnode = 4;
// Default graph
RdfDefaultGraph g_default_graph = 5;
// Literal – only valid for generalized RDF streams
RdfLiteral g_literal = 6;
}
}
// Metadata header for RDF Patch.
// Header rows must occur at the start of the patch frame.
message RdfPatchHeader {
// Header key (required)
string key = 1;
// Header value (required)
// Repeated term compression is not supported for header values.
// This oneof must always be set to a valid RDF term.
oneof value {
// IRI
RdfIri h_iri = 2;
// Blank node
string h_bnode = 3;
// Literal
RdfLiteral h_literal = 4;
// RDF-star quoted triple
RdfTriple h_triple_term = 5;
}
}
message RdfPatchPunctuation {}
// RDF Patch stream options
message RdfPatchOptions {
// Type of statements in the stream (required)
PatchStatementType statement_type = 1;
// Type of the stream (required)
PatchStreamType stream_type = 2;
// Whether the stream may contain generalized triples, quads, or datasets
bool generalized_statements = 3;
// Whether the stream may contain RDF-star statements
bool rdf_star = 4;
// Maximum size of the name lookup table
// (required, must be >= 8)
uint32 max_name_table_size = 9;
// Maximum size of the prefix lookup table
// (required if the prefix lookup is used)
uint32 max_prefix_table_size = 10;
// Maximum size of the datatype lookup table
// (required if datatype literals are used)
uint32 max_datatype_table_size = 11;
// Protocol version (required)
// For Jelly-Patch 1.0.x (based on Jelly-RDF 1.1.x), the value must be 1.
// For custom extensions, the value must be 10000 or higher.
uint32 version = 15;
}
// Type of statements in the stream.
// This determines whether the statements are interpreted as triples or quads.
enum PatchStatementType {
// Unspecified stream type – invalid
PATCH_STATEMENT_TYPE_UNSPECIFIED = 0;
// RDF triples
PATCH_STATEMENT_TYPE_TRIPLES = 1;
// RDF quads
PATCH_STATEMENT_TYPE_QUADS = 2;
}
// Type of the stream.
// This determines whether each RdfPatchFrame is a complete patch by itself,
// or part of a larger patch.
enum PatchStreamType {
// Unspecified stream type – invalid
PATCH_STREAM_TYPE_UNSPECIFIED = 0;
// Each RdfPatchFrame is a complete patch.
// In this case, transactions cannot span multiple frames.
PATCH_STREAM_TYPE_FRAME = 1;
// Entire stream is a single patch.
// Transactions may span multiple frames.
PATCH_STREAM_TYPE_FLAT = 2;
// Stream contains multiple patches separated by punctuation marks.
// Patches and transactions may span multiple frames.
// Each frame must contain at most one patch.
PATCH_STREAM_TYPE_PUNCTUATED = 3;
}
// A row in an RDF Patch stream
message RdfPatchRow {
oneof row {
// Stream options. Must be the first row in the stream.
RdfPatchOptions options = 1;
// Add a triple/quad statement (A)
RdfQuad statement_add = 2;
// Delete a triple/quad statement (D)
RdfQuad statement_delete = 3;
// Add a namespace/prefix declaration (PA)
RdfPatchNamespace namespace_add = 4;
// Delete a namespace/prefix declaration (PD)
RdfPatchNamespace namespace_delete = 5;
// Transaction start (TX)
RdfPatchTransactionStart transaction_start = 6;
// Transaction commit (TC)
RdfPatchTransactionCommit transaction_commit = 7;
// Transaction abort (TA)
RdfPatchTransactionAbort transaction_abort = 8;
// Entry in the name lookup table.
RdfNameEntry name = 11;
// Entry in the prefix lookup table.
RdfPrefixEntry prefix = 12;
// Entry in the datatype lookup table.
RdfDatatypeEntry datatype = 13;
// Header entry (H)
RdfPatchHeader header = 14;
// Punctuation mark, only used in stream type PUNCTUATED
// Indicates the end of a patch.
RdfPatchPunctuation punctuation = 15;
}
}
// A batch of RDF patch rows.
message RdfPatchFrame {
// Patch rows
repeated RdfPatchRow rows = 1;
}
grpc.proto
syntax = "proto3";
package eu.ostrzyciel.jelly.core.proto.v1;
// Jelly gRPC streaming protocol.
// Specification document: https://w3id.org/jelly/1.0.0/specification/streaming
// Protocol version: 1.0.0
import "rdf.proto";
// Subscribe command sent by the client to the server.
message RdfStreamSubscribe {
// The topic to which the client wants to subscribe (UTF-8 encoded).
string topic = 1;
// Optional: the stream options requested by the client.
// The server should respond with a stream that matches these options.
// In case that is not possible, the server must respond with the
// INVALID_ARGUMENT error.
RdfStreamOptions requested_options = 2;
}
// Acknowledgement of receiving a stream sent by the server to the client.
message RdfStreamReceived {}
// Pub/Sub service for RDF streams, to be implemented by the server.
service RdfStreamService {
// Subscribe to an RDF stream.
rpc SubscribeRdf(RdfStreamSubscribe) returns (stream RdfStreamFrame);
// Publish an RDF stream.
// In case the server cannot process the stream, it must respond with
// the INVALID_ARGUMENT error.
rpc PublishRdf(stream RdfStreamFrame) returns (RdfStreamReceived);
}