#pragma once #include #include #include #include #include #include #include namespace jvalidate::detail { template class ReferenceManager; template struct ParserContext { using Object = decltype(std::declval().as_object()); Schema & root; A schema; Vocabulary const * vocab; ReferenceManager & ref; std::optional parent = std::nullopt; Reference where; Reference dynamic_where; /** * @brief Obtain the ParserContext for an arbitrary schema location, * preserving the general context members of the root Schema, Vocabulary, * and ReferenceManager. * * @param new_schema The new schema JSON adapter * @param new_loc The json pointer to this new_schema relative to its document * root. * @param new_dyn The json pointer to this new_schema using dynamic reference * rules. * @param parent The parent of this schema, if that parent is an Object. */ ParserContext rebind(A const & new_schema, Reference const & new_loc, Reference const & new_dyn, std::optional parent = std::nullopt) const { return {root, new_schema, vocab, ref, parent, new_loc, new_dyn}; } /** * @brief Obtain the ParserContext for the child schema of the current * location. Will set the parent context, which is used by some constraints * like "contains" or "if". * * @param child The new child schema * @param key The object-key to the new schema */ ParserContext child(A const & child, std::string const & key) const { return rebind(child, where / key, dynamic_where / key, schema.as_object()); } /** * @brief Obtain the ParserContext for the child schema of the current * location. Will clear the parent schema context. * * @param child The new child schema * @param key The array-index to the new schema */ ParserContext child(A const & child, size_t index) const { return rebind(child, where / index, dynamic_where / index); } /** * @brief Obtain the ParserContext for the a child schema with the same parent * as this context. Called when generating {@see ConditionalConstraint}. * * @param key The object-key to the new schema */ ParserContext neighbor(std::string const & key) const { EXPECT(parent.has_value()); return rebind((*parent)[key], where.parent() / key, dynamic_where.parent() / key, parent); } schema::Node const * node() const; schema::Node const * always() const; schema::Node const * fixed_schema(bool accept) const; }; }