11#include " JsonLdContextParser.hpp"
22
33namespace rdf4cpp ::parser::json_ld {
4- nonstd::expected<Context, ContextParser::error_type> ContextParser::parse_context (simdjson::ondemand::value local_context, Context const &active_context, std::string_view base_iri, bool override_protected, bool propagate ) {
4+ nonstd::expected<Context, ContextParser::error_type> ContextParser::parse_context (simdjson::ondemand::value local_context, params::ParseContextParams p ) {
55 // https://www.w3.org/TR/json-ld11-api/#context-processing-algorithm
66 // 1
7- nonstd::expected<Context, error_type> result{active_context};
7+ nonstd::expected<Context, error_type> result{p. active_context };
88 for (auto &t : result->terms ) {
99 t.needs_context_check = false ;
1010 }
@@ -170,9 +170,9 @@ namespace rdf4cpp::parser::json_ld {
170170 .active_context = *result,
171171 .term = term,
172172 .previous_terms = previous_terms,
173- .base_iri = base_iri,
173+ .base_iri = p. base_iri ,
174174 .is_protected = prot,
175- .override_protected = override_protected,
175+ .override_protected = p. override_protected ,
176176 });
177177 if (e.has_value ()) {
178178 result = nonstd::unexpected{e.value ()};
@@ -183,34 +183,36 @@ namespace rdf4cpp::parser::json_ld {
183183 return false ;
184184 };
185185
186+ auto handle_null = [&]() -> nonstd::expected<Context, error_type> {
187+ if (!p.override_protected ) {
188+ for (auto const &t : p.active_context .terms ) {
189+ if (t.is_protected ) {
190+ result = nonstd::unexpected{make_error (ParsingError::Type::BadSyntax, " invalid context nullification" )};
191+ return result;
192+ }
193+ }
194+ }
195+ return Context{
196+ .base_iri {original_base_iri},
197+ };
198+ };
199+
186200 if (local_context.type () == simdjson::ondemand::json_type::object) {
187201 // 2 & 3
188202 simdjson::ondemand::object const o = local_context.get_object ();
189203 auto [c, prop] = try_get_field<bool >(o, keyword_propagate);
190- bool p = propagate;
191- if (c == simdjson::SUCCESS ) {
192- p = prop;
193- }
194- if (!p && result->previous_context == nullptr ) {
195- result->previous_context = &active_context;
204+ bool const actual_propagate = c == simdjson::SUCCESS ? prop : p.propagate ;
205+ if (!actual_propagate && result->previous_context == nullptr ) {
206+ result->previous_context = &p.active_context ;
196207 }
197208 // error handling later
198209
199210 handle_ctx (o); // 4
200- } else if (local_context.is_scalar () && local_context.is_null ()) {
201- for (auto const &t : active_context.terms ) {
202- if (t.is_protected ) {
203- result = nonstd::unexpected{make_error (ParsingError::Type::BadSyntax, " invalid context nullification" )};
204- return result;
205- }
206- }
207- result = Context{
208- .base_iri {base_iri},
209- };
210- return result;
211+ } else if (local_context.is_scalar () && local_context.is_null ()) { // 5.1
212+ return handle_null ();
211213 } else {
212- if (!propagate && result->previous_context == nullptr ) {
213- result->previous_context = &active_context;
214+ if (!p. propagate && result->previous_context == nullptr ) {
215+ result->previous_context = &p. active_context ;
214216 }
215217 simdjson::ondemand::array a{};
216218 if (local_context.get (a) != simdjson::SUCCESS ) {
@@ -220,19 +222,15 @@ namespace rdf4cpp::parser::json_ld {
220222 for (auto v : a) {
221223 switch (v.type ()) {
222224 case simdjson::ondemand::json_type::null: // 5.1
225+ {
223226 v.is_null ();
224- if (!override_protected) {
225- for (auto const &t : active_context.terms ) {
226- if (t.is_protected ) {
227- result = nonstd::unexpected{make_error (ParsingError::Type::BadSyntax, " invalid context nullification" )};
228- return result;
229- }
230- }
227+ auto r = handle_null ();
228+ if (!r.has_value ()) {
229+ return r;
231230 }
232- result = Context{
233- .base_iri {base_iri},
234- };
231+ result = r;
235232 break ;
233+ }
236234 case simdjson::ondemand::json_type::object: // 5.4
237235 if (handle_ctx (v.get_object ())) {
238236 return result;
@@ -252,7 +250,11 @@ namespace rdf4cpp::parser::json_ld {
252250 if (result.has_value ()) {
253251 for (auto const &t : result->terms ) {
254252 if (t.needs_context_check && t.context .has_value ()) {
255- auto lc = parse_local_context (simdjson::padded_string_view{*t.context }, *result, base_iri, true );
253+ auto lc = parse_local_context (simdjson::padded_string_view{*t.context }, {
254+ .active_context = *result,
255+ .base_iri = p.base_iri ,
256+ .override_protected = true ,
257+ });
256258 if (!lc.has_value ()) {
257259 return nonstd::unexpected (make_error (ParsingError::Type::BadSyntax, std::format (" invalid scoped context ({})" , lc.error ().message )));
258260 }
@@ -457,7 +459,7 @@ namespace rdf4cpp::parser::json_ld {
457459 }
458460 static constexpr std::array invalid = {keyword_json, keyword_none, keyword_id, keyword_vocab};
459461 if (type->type == IRIMappingType::Keyword && !std::ranges::any_of (invalid, [&](std::string_view a) {
460- return a == v ;
462+ return a == type-> data ;
461463 })) {
462464 return make_error (ParsingError::Type::BadSyntax, " invalid type mapping (invalid keyword)" );
463465 }
@@ -555,7 +557,7 @@ namespace rdf4cpp::parser::json_ld {
555557 p.term .iri_mapping .data .append (std::string_view (p.term .key ).substr (colon_pos + 2 ));
556558 } else {
557559 p.term .iri_mapping .data = p.term .key ;
558- p.term .iri_mapping .type = std::string_view ( p.term .key ). substr ( 2 ) == " _:" ? IRIMappingType::BlankNode : IRIMappingType::IRI ;
560+ p.term .iri_mapping .type = p.term .key . starts_with ( " _:" ) ? IRIMappingType::BlankNode : IRIMappingType::IRI ;
559561 }
560562 }
561563 // 16
@@ -789,13 +791,13 @@ namespace rdf4cpp::parser::json_ld {
789791 p.term .parse_state = ParseState::Done;
790792 return std::nullopt ;
791793 }
792- nonstd::expected<Context, ContextParser::error_type> ContextParser::parse_local_context (simdjson::padded_string_view json, Context const &active_context, std::string_view base_iri, bool override_protected, bool propagate ) {
794+ nonstd::expected<Context, ContextParser::error_type> ContextParser::parse_local_context (simdjson::padded_string_view json, params::ParseContextParams p ) {
793795 simdjson::ondemand::parser parser{};
794796 simdjson::ondemand::document doc = parser.iterate(json);
795797 if (doc.is_scalar ()) {
796798 return nonstd::unexpected{make_error (ParsingError::Type::BadSyntax, doc.is_string () ? " remote context not supported" : " context free floating scalar" )};
797799 }
798- return parse_context (doc, active_context, base_iri, override_protected, propagate );
800+ return parse_context (doc, p );
799801 }
800802 nonstd::expected<IRIMapping, ContextParser::error_type> ContextParser::iri_expansion (Context const &active_context,
801803 std::optional<std::string_view> value,
@@ -901,6 +903,7 @@ namespace rdf4cpp::parser::json_ld {
901903 }
902904 // 9
903905 // no keyword, bn or valid iri, would have passed any further check
906+ // => not possible to result in a valid Node, ignore it
904907 return IRIMapping{std::string (" " ), IRIMappingType::None};
905908 }
906909} // namespace rdf4cpp::parser::json_ld
0 commit comments