Browse Source

refactor: move ParserContext into detail

Sam Jaffe 1 year ago
parent
commit
9d20ad2dc9

+ 39 - 40
include/jvalidate/constraint.h

@@ -15,10 +15,9 @@
 #include <jvalidate/constraint/string_constraint.h>
 #include <jvalidate/constraint/string_constraint.h>
 
 
 #include <jvalidate/detail/expect.h>
 #include <jvalidate/detail/expect.h>
-#include <jvalidate/detail/reference.h>
+#include <jvalidate/detail/parser_context.h>
 #include <jvalidate/enum.h>
 #include <jvalidate/enum.h>
 #include <jvalidate/forward.h>
 #include <jvalidate/forward.h>
-#include <jvalidate/parser_context.h>
 
 
 namespace jvalidate {
 namespace jvalidate {
 template <Adapter A> class ConstraintFactory {
 template <Adapter A> class ConstraintFactory {
@@ -26,7 +25,7 @@ public:
   using pConstraint = std::unique_ptr<constraint::Constraint>;
   using pConstraint = std::unique_ptr<constraint::Constraint>;
   using Object = decltype(std::declval<A>().as_object());
   using Object = decltype(std::declval<A>().as_object());
 
 
-  using MakeConstraint = std::function<pConstraint(ParserContext<A> const &)>;
+  using MakeConstraint = std::function<pConstraint(detail::ParserContext<A> const &)>;
   using VersionedMakeConstraint = std::map<schema::Version, MakeConstraint, std::greater<>>;
   using VersionedMakeConstraint = std::map<schema::Version, MakeConstraint, std::greater<>>;
 
 
 private:
 private:
@@ -104,16 +103,16 @@ public:
 
 
   // SECTION: Untyped Constraints
   // SECTION: Untyped Constraints
 
 
-  static pConstraint warnUnimplemented(ParserContext<A> const & context) {
+  static pConstraint warnUnimplemented(detail::ParserContext<A> const & context) {
     std::cerr << "Unimplemented constraint " << context.where << "\n";
     std::cerr << "Unimplemented constraint " << context.where << "\n";
     return nullptr;
     return nullptr;
   }
   }
 
 
-  static pConstraint fatalUnimplemented(ParserContext<A> const & context) {
+  static pConstraint fatalUnimplemented(detail::ParserContext<A> const & context) {
     JVALIDATE_THROW(std::runtime_error, "Unimplemented constraint " << context.where);
     JVALIDATE_THROW(std::runtime_error, "Unimplemented constraint " << context.where);
   }
   }
 
 
-  static auto type(ParserContext<A> const & context) {
+  static auto type(detail::ParserContext<A> const & context) {
     static std::unordered_map<std::string_view, adapter::Type> const s_type_names{
     static std::unordered_map<std::string_view, adapter::Type> const s_type_names{
         {"null", adapter::Type::Null},       {"boolean", adapter::Type::Boolean},
         {"null", adapter::Type::Null},       {"boolean", adapter::Type::Boolean},
         {"integer", adapter::Type::Integer}, {"number", adapter::Type::Number},
         {"integer", adapter::Type::Integer}, {"number", adapter::Type::Number},
@@ -139,12 +138,12 @@ public:
     return std::make_unique<constraint::TypeConstraint>(types);
     return std::make_unique<constraint::TypeConstraint>(types);
   }
   }
 
 
-  static auto ifThenElse(ParserContext<A> const & context) {
+  static auto ifThenElse(detail::ParserContext<A> const & context) {
     return std::make_unique<constraint::ConditionalConstraint>(
     return std::make_unique<constraint::ConditionalConstraint>(
         context.node(), context.neighbor("then").node(), context.neighbor("else").node());
         context.node(), context.neighbor("then").node(), context.neighbor("else").node());
   }
   }
 
 
-  static auto isInEnumuration(ParserContext<A> const & context) {
+  static auto isInEnumuration(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Array);
     EXPECT(context.schema.type() == adapter::Type::Array);
 
 
     std::vector<std::unique_ptr<adapter::Const const>> rval;
     std::vector<std::unique_ptr<adapter::Const const>> rval;
@@ -155,11 +154,11 @@ public:
     return std::make_unique<constraint::EnumConstraint>(std::move(rval));
     return std::make_unique<constraint::EnumConstraint>(std::move(rval));
   }
   }
 
 
-  static auto isConstant(ParserContext<A> const & context) {
+  static auto isConstant(detail::ParserContext<A> const & context) {
     return std::make_unique<constraint::EnumConstraint>(context.schema.freeze());
     return std::make_unique<constraint::EnumConstraint>(context.schema.freeze());
   }
   }
 
 
-  static auto allOf(ParserContext<A> const & context) {
+  static auto allOf(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Array);
     EXPECT(context.schema.type() == adapter::Type::Array);
 
 
     std::vector<schema::Node const *> rval;
     std::vector<schema::Node const *> rval;
@@ -172,7 +171,7 @@ public:
     return std::make_unique<constraint::AllOfConstraint>(rval);
     return std::make_unique<constraint::AllOfConstraint>(rval);
   }
   }
 
 
-  static auto anyOf(ParserContext<A> const & context) {
+  static auto anyOf(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Array);
     EXPECT(context.schema.type() == adapter::Type::Array);
 
 
     std::vector<schema::Node const *> rval;
     std::vector<schema::Node const *> rval;
@@ -185,7 +184,7 @@ public:
     return std::make_unique<constraint::AnyOfConstraint>(rval);
     return std::make_unique<constraint::AnyOfConstraint>(rval);
   }
   }
 
 
-  static auto oneOf(ParserContext<A> const & context) {
+  static auto oneOf(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Array);
     EXPECT(context.schema.type() == adapter::Type::Array);
 
 
     std::vector<schema::Node const *> rval;
     std::vector<schema::Node const *> rval;
@@ -198,13 +197,13 @@ public:
     return std::make_unique<constraint::OneOfConstraint>(rval);
     return std::make_unique<constraint::OneOfConstraint>(rval);
   }
   }
 
 
-  static auto isNot(ParserContext<A> const & context) {
+  static auto isNot(detail::ParserContext<A> const & context) {
     return std::make_unique<constraint::NotConstraint>(context.node());
     return std::make_unique<constraint::NotConstraint>(context.node());
   }
   }
 
 
   // SECTION: Numeric Constraints
   // SECTION: Numeric Constraints
 
 
-  static auto minimum(ParserContext<A> const & context) {
+  static auto minimum(detail::ParserContext<A> const & context) {
     double value = context.schema.as_number();
     double value = context.schema.as_number();
     if (context.version < schema::Version::Draft06 &&
     if (context.version < schema::Version::Draft06 &&
         context.parent->contains("exclusiveMinimum")) {
         context.parent->contains("exclusiveMinimum")) {
@@ -215,12 +214,12 @@ public:
     return std::make_unique<constraint::MinimumConstraint>(value, false);
     return std::make_unique<constraint::MinimumConstraint>(value, false);
   }
   }
 
 
-  static pConstraint exclusiveMinimum(ParserContext<A> const & context) {
+  static pConstraint exclusiveMinimum(detail::ParserContext<A> const & context) {
     double value = context.schema.as_number();
     double value = context.schema.as_number();
     return std::make_unique<constraint::MinimumConstraint>(value, true);
     return std::make_unique<constraint::MinimumConstraint>(value, true);
   }
   }
 
 
-  static auto maximum(ParserContext<A> const & context) {
+  static auto maximum(detail::ParserContext<A> const & context) {
     double value = context.schema.as_number();
     double value = context.schema.as_number();
     if (context.version < schema::Version::Draft06 &&
     if (context.version < schema::Version::Draft06 &&
         context.parent->contains("exclusiveMaximum")) {
         context.parent->contains("exclusiveMaximum")) {
@@ -231,35 +230,35 @@ public:
     return std::make_unique<constraint::MaximumConstraint>(value, false);
     return std::make_unique<constraint::MaximumConstraint>(value, false);
   }
   }
 
 
-  static pConstraint exclusiveMaximum(ParserContext<A> const & context) {
+  static pConstraint exclusiveMaximum(detail::ParserContext<A> const & context) {
     double value = context.schema.as_number();
     double value = context.schema.as_number();
     return std::make_unique<constraint::MaximumConstraint>(value, true);
     return std::make_unique<constraint::MaximumConstraint>(value, true);
   }
   }
 
 
-  static auto multipleOf(ParserContext<A> const & context) {
+  static auto multipleOf(detail::ParserContext<A> const & context) {
     int64_t value = context.schema.as_integer();
     int64_t value = context.schema.as_integer();
     return std::make_unique<constraint::MultipleOfConstraint>(value);
     return std::make_unique<constraint::MultipleOfConstraint>(value);
   }
   }
 
 
   // SECTION: String Constraints
   // SECTION: String Constraints
 
 
-  static auto minLength(ParserContext<A> const & context) {
+  static auto minLength(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Integer);
     EXPECT(context.schema.type() == adapter::Type::Integer);
     return std::make_unique<constraint::MinLengthConstraint>(context.schema.as_integer());
     return std::make_unique<constraint::MinLengthConstraint>(context.schema.as_integer());
   }
   }
 
 
-  static auto maxLength(ParserContext<A> const & context) {
+  static auto maxLength(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Integer);
     EXPECT(context.schema.type() == adapter::Type::Integer);
     return std::make_unique<constraint::MaxLengthConstraint>(context.schema.as_integer());
     return std::make_unique<constraint::MaxLengthConstraint>(context.schema.as_integer());
   }
   }
 
 
-  static auto pattern(ParserContext<A> const & context) {
+  static auto pattern(detail::ParserContext<A> const & context) {
     return std::make_unique<constraint::PatternConstraint>(context.schema.as_string());
     return std::make_unique<constraint::PatternConstraint>(context.schema.as_string());
   }
   }
 
 
   // SECTION: Array Constraints
   // SECTION: Array Constraints
 
 
-  static auto contains(ParserContext<A> const & context) {
+  static auto contains(detail::ParserContext<A> const & context) {
     if (context.version < schema::Version::Draft2019_09) {
     if (context.version < schema::Version::Draft2019_09) {
       return std::make_unique<constraint::ContainsConstraint>(context.node());
       return std::make_unique<constraint::ContainsConstraint>(context.node());
     }
     }
@@ -276,17 +275,17 @@ public:
     return std::make_unique<constraint::ContainsConstraint>(context.node(), minimum, maximum);
     return std::make_unique<constraint::ContainsConstraint>(context.node(), minimum, maximum);
   }
   }
 
 
-  static auto minItems(ParserContext<A> const & context) {
+  static auto minItems(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Integer);
     EXPECT(context.schema.type() == adapter::Type::Integer);
     return std::make_unique<constraint::MinItemsConstraint>(context.schema.as_integer());
     return std::make_unique<constraint::MinItemsConstraint>(context.schema.as_integer());
   }
   }
 
 
-  static auto maxItems(ParserContext<A> const & context) {
+  static auto maxItems(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Integer);
     EXPECT(context.schema.type() == adapter::Type::Integer);
     return std::make_unique<constraint::MaxItemsConstraint>(context.schema.as_integer());
     return std::make_unique<constraint::MaxItemsConstraint>(context.schema.as_integer());
   }
   }
 
 
-  static auto prefixItems(ParserContext<A> const & context) {
+  static auto prefixItems(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Array);
     EXPECT(context.schema.type() == adapter::Type::Array);
 
 
     std::vector<schema::Node const *> rval;
     std::vector<schema::Node const *> rval;
@@ -299,7 +298,7 @@ public:
     return std::make_unique<constraint::TupleConstraint>(rval);
     return std::make_unique<constraint::TupleConstraint>(rval);
   }
   }
 
 
-  static pConstraint additionalItems(ParserContext<A> const & context) {
+  static pConstraint additionalItems(detail::ParserContext<A> const & context) {
     std::string const prefix =
     std::string const prefix =
         context.version >= schema::Version::Draft2020_12 ? "prefixItems" : "items";
         context.version >= schema::Version::Draft2020_12 ? "prefixItems" : "items";
 
 
@@ -318,7 +317,7 @@ public:
     return std::make_unique<C>(context.node(), start_after);
     return std::make_unique<C>(context.node(), start_after);
   }
   }
 
 
-  static pConstraint itemsTupleOrVector(ParserContext<A> const & context) {
+  static pConstraint itemsTupleOrVector(detail::ParserContext<A> const & context) {
     if (context.schema.type() == adapter::Type::Array) {
     if (context.schema.type() == adapter::Type::Array) {
       return prefixItems(context);
       return prefixItems(context);
     }
     }
@@ -326,11 +325,11 @@ public:
     return additionalItems(context);
     return additionalItems(context);
   }
   }
 
 
-  static auto unevaluatedItems(ParserContext<A> const & context) {
+  static auto unevaluatedItems(detail::ParserContext<A> const & context) {
     return std::make_unique<constraint::UnevaluatedItemsConstraint>(context.node());
     return std::make_unique<constraint::UnevaluatedItemsConstraint>(context.node());
   }
   }
 
 
-  static pConstraint uniqueItems(ParserContext<A> const & context) {
+  static pConstraint uniqueItems(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Boolean);
     EXPECT(context.schema.type() == adapter::Type::Boolean);
     if (not context.schema.as_boolean()) {
     if (not context.schema.as_boolean()) {
       return nullptr;
       return nullptr;
@@ -341,7 +340,7 @@ public:
 
 
   // SECTION: Object Constraints
   // SECTION: Object Constraints
 
 
-  static auto required(ParserContext<A> const & context) {
+  static auto required(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Array);
     EXPECT(context.schema.type() == adapter::Type::Array);
 
 
     std::unordered_set<std::string> rval;
     std::unordered_set<std::string> rval;
@@ -353,17 +352,17 @@ public:
     return std::make_unique<constraint::RequiredConstraint>(rval);
     return std::make_unique<constraint::RequiredConstraint>(rval);
   }
   }
 
 
-  static auto minProperties(ParserContext<A> const & context) {
+  static auto minProperties(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Integer);
     EXPECT(context.schema.type() == adapter::Type::Integer);
     return std::make_unique<constraint::MinPropertiesConstraint>(context.schema.as_integer());
     return std::make_unique<constraint::MinPropertiesConstraint>(context.schema.as_integer());
   }
   }
 
 
-  static auto maxProperties(ParserContext<A> const & context) {
+  static auto maxProperties(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Integer);
     EXPECT(context.schema.type() == adapter::Type::Integer);
     return std::make_unique<constraint::MaxPropertiesConstraint>(context.schema.as_integer());
     return std::make_unique<constraint::MaxPropertiesConstraint>(context.schema.as_integer());
   }
   }
 
 
-  static auto patternProperties(ParserContext<A> const & context) {
+  static auto patternProperties(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Object);
     EXPECT(context.schema.type() == adapter::Type::Object);
 
 
     std::vector<std::pair<std::string, schema::Node const *>> rval;
     std::vector<std::pair<std::string, schema::Node const *>> rval;
@@ -374,7 +373,7 @@ public:
     return std::make_unique<constraint::PatternPropertiesConstraint>(rval);
     return std::make_unique<constraint::PatternPropertiesConstraint>(rval);
   }
   }
 
 
-  static auto properties(ParserContext<A> const & context) {
+  static auto properties(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Object);
     EXPECT(context.schema.type() == adapter::Type::Object);
 
 
     std::map<std::string, schema::Node const *> rval;
     std::map<std::string, schema::Node const *> rval;
@@ -385,15 +384,15 @@ public:
     return std::make_unique<constraint::PropertiesConstraint>(rval);
     return std::make_unique<constraint::PropertiesConstraint>(rval);
   }
   }
 
 
-  static auto propertyNames(ParserContext<A> const & context) {
+  static auto propertyNames(detail::ParserContext<A> const & context) {
     return std::make_unique<constraint::PropertyNamesConstraint>(context.node());
     return std::make_unique<constraint::PropertyNamesConstraint>(context.node());
   }
   }
 
 
-  static auto unevaluatedProperties(ParserContext<A> const & context) {
+  static auto unevaluatedProperties(detail::ParserContext<A> const & context) {
     return std::make_unique<constraint::UnevaluatedPropertiesConstraint>(context.node());
     return std::make_unique<constraint::UnevaluatedPropertiesConstraint>(context.node());
   }
   }
 
 
-  static auto additionalProperties(ParserContext<A> const & context) {
+  static auto additionalProperties(detail::ParserContext<A> const & context) {
     std::unordered_set<std::string> properties;
     std::unordered_set<std::string> properties;
     std::vector<std::string> patterns;
     std::vector<std::string> patterns;
 
 
@@ -418,7 +417,7 @@ public:
     return std::make_unique<C>(context.node(), properties, patterns);
     return std::make_unique<C>(context.node(), properties, patterns);
   }
   }
 
 
-  static auto dependencies(ParserContext<A> const & context) {
+  static auto dependencies(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Object);
     EXPECT(context.schema.type() == adapter::Type::Object);
 
 
     std::map<std::string, schema::Node const *> schemas;
     std::map<std::string, schema::Node const *> schemas;
@@ -437,7 +436,7 @@ public:
     return std::make_unique<constraint::DependenciesConstraint>(schemas, required);
     return std::make_unique<constraint::DependenciesConstraint>(schemas, required);
   }
   }
 
 
-  static auto dependentSchemas(ParserContext<A> const & context) {
+  static auto dependentSchemas(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Object);
     EXPECT(context.schema.type() == adapter::Type::Object);
 
 
     std::map<std::string, schema::Node const *> rval;
     std::map<std::string, schema::Node const *> rval;
@@ -448,7 +447,7 @@ public:
     return std::make_unique<constraint::DependenciesConstraint>(rval);
     return std::make_unique<constraint::DependenciesConstraint>(rval);
   }
   }
 
 
-  static auto dependentRequired(ParserContext<A> const & context) {
+  static auto dependentRequired(detail::ParserContext<A> const & context) {
     EXPECT(context.schema.type() == adapter::Type::Object);
     EXPECT(context.schema.type() == adapter::Type::Object);
 
 
     std::map<std::string, std::unordered_set<std::string>> rval;
     std::map<std::string, std::unordered_set<std::string>> rval;

+ 2 - 2
include/jvalidate/parser_context.h

@@ -5,7 +5,7 @@
 #include <jvalidate/detail/reference.h>
 #include <jvalidate/detail/reference.h>
 #include <jvalidate/forward.h>
 #include <jvalidate/forward.h>
 
 
-namespace jvalidate {
+namespace jvalidate::detail {
 template <Adapter A> struct ParserContext {
 template <Adapter A> struct ParserContext {
   using Object = decltype(std::declval<A>().as_object());
   using Object = decltype(std::declval<A>().as_object());
   Schema & root;
   Schema & root;
@@ -14,7 +14,7 @@ template <Adapter A> struct ParserContext {
   std::optional<Object> parent = std::nullopt;
   std::optional<Object> parent = std::nullopt;
 
 
   schema::Version version;
   schema::Version version;
-  detail::Reference where = {};
+  Reference where = {};
   ConstraintFactory<A> const & factory;
   ConstraintFactory<A> const & factory;
 
 
   ParserContext child(A const & child, std::string const & key) const {
   ParserContext child(A const & child, std::string const & key) const {

+ 1 - 0
include/jvalidate/forward.h

@@ -137,5 +137,6 @@ namespace jvalidate {
 template <Adapter A> class ConstraintFactory;
 template <Adapter A> class ConstraintFactory;
 template <Adapter A, RegexEngine RE> class ValidationVisitor;
 template <Adapter A, RegexEngine RE> class ValidationVisitor;
 
 
+template <RegexEngine RE> class ValidatorT;
 class Validator;
 class Validator;
 }
 }

+ 13 - 11
include/jvalidate/schema.h

@@ -9,11 +9,11 @@
 #include <jvalidate/detail/anchor.h>
 #include <jvalidate/detail/anchor.h>
 #include <jvalidate/detail/expect.h>
 #include <jvalidate/detail/expect.h>
 #include <jvalidate/detail/on_block_exit.h>
 #include <jvalidate/detail/on_block_exit.h>
+#include <jvalidate/detail/parser_context.h>
 #include <jvalidate/detail/pointer.h>
 #include <jvalidate/detail/pointer.h>
 #include <jvalidate/detail/reference.h>
 #include <jvalidate/detail/reference.h>
 #include <jvalidate/enum.h>
 #include <jvalidate/enum.h>
 #include <jvalidate/forward.h>
 #include <jvalidate/forward.h>
-#include <jvalidate/parser_context.h>
 
 
 namespace jvalidate::schema {
 namespace jvalidate::schema {
 class Node {
 class Node {
@@ -34,7 +34,7 @@ protected:
 
 
 public:
 public:
   Node(bool rejects_all = false) : rejects_all_(rejects_all) {}
   Node(bool rejects_all = false) : rejects_all_(rejects_all) {}
-  template <Adapter A> Node(ParserContext<A> context);
+  template <Adapter A> Node(detail::ParserContext<A> context);
 
 
   bool is_pure_reference() const {
   bool is_pure_reference() const {
     return reference_ && constraints_.empty() && post_constraints_.empty() && not default_;
     return reference_ && constraints_.empty() && post_constraints_.empty() && not default_;
@@ -49,8 +49,8 @@ public:
   adapter::Const const * default_value() const { return default_.get(); }
   adapter::Const const * default_value() const { return default_.get(); }
 
 
 private:
 private:
-  template <Adapter A> detail::OnBlockExit resolve_anchor(ParserContext<A> & context);
-  template <Adapter A> bool resolve_reference(ParserContext<A> const & context);
+  template <Adapter A> detail::OnBlockExit resolve_anchor(detail::ParserContext<A> & context);
+  template <Adapter A> bool resolve_reference(detail::ParserContext<A> const & context);
 };
 };
 
 
 inline Version Node::schema_version(std::string_view url) {
 inline Version Node::schema_version(std::string_view url) {
@@ -97,7 +97,7 @@ namespace jvalidate {
 class Schema : public schema::Node {
 class Schema : public schema::Node {
 private:
 private:
   friend class schema::Node;
   friend class schema::Node;
-  template <Adapter A> friend class ParserContext;
+  template <Adapter A> friend class detail::ParserContext;
   struct DynamicRef {
   struct DynamicRef {
     template <typename F>
     template <typename F>
     DynamicRef(detail::Reference const & where, F const & reconstruct)
     DynamicRef(detail::Reference const & where, F const & reconstruct)
@@ -124,7 +124,7 @@ public:
 
 
   template <Adapter A>
   template <Adapter A>
   Schema(A const & json, schema::Version version, ConstraintFactory<A> const & factory = {})
   Schema(A const & json, schema::Version version, ConstraintFactory<A> const & factory = {})
-      : schema::Node(ParserContext<A>{
+      : schema::Node(detail::ParserContext<A>{
             .root = *this, .schema = json, .version = version, .factory = factory}) {}
             .root = *this, .schema = json, .version = version, .factory = factory}) {}
 
 
   template <typename JSON, typename... Args>
   template <typename JSON, typename... Args>
@@ -138,7 +138,7 @@ private:
   }
   }
 
 
   template <Adapter A>
   template <Adapter A>
-  void dynamic_anchor(detail::Anchor const & anchor, ParserContext<A> const & context) {
+  void dynamic_anchor(detail::Anchor const & anchor, detail::ParserContext<A> const & context) {
     dynamic_anchors_.try_emplace(anchor, context.where,
     dynamic_anchors_.try_emplace(anchor, context.where,
                                  [this, context]() { return fetch_schema(context); });
                                  [this, context]() { return fetch_schema(context); });
   }
   }
@@ -180,7 +180,7 @@ private:
     return it->second.reconstruct();
     return it->second.reconstruct();
   }
   }
 
 
-  template <Adapter A> schema::Node const * fetch_schema(ParserContext<A> const & context) {
+  template <Adapter A> schema::Node const * fetch_schema(detail::ParserContext<A> const & context) {
     adapter::Type const type = context.schema.type();
     adapter::Type const type = context.schema.type();
     if (type == adapter::Type::Boolean && context.version >= schema::Version::Draft06) {
     if (type == adapter::Type::Boolean && context.version >= schema::Version::Draft06) {
       return alias(context.where, context.schema.as_boolean() ? &accept_ : &reject_);
       return alias(context.where, context.schema.as_boolean() ? &accept_ : &reject_);
@@ -207,7 +207,9 @@ private:
     return alias(context.where, node);
     return alias(context.where, node);
   }
   }
 };
 };
+}
 
 
+namespace jvalidate::detail {
 template <Adapter A> schema::Node const * ParserContext<A>::node() const {
 template <Adapter A> schema::Node const * ParserContext<A>::node() const {
   return root.fetch_schema(*this);
   return root.fetch_schema(*this);
 }
 }
@@ -218,7 +220,7 @@ template <Adapter A> schema::Node const * ParserContext<A>::always() const {
 }
 }
 
 
 namespace jvalidate::schema {
 namespace jvalidate::schema {
-template <Adapter A> detail::OnBlockExit Node::resolve_anchor(ParserContext<A> & context) {
+template <Adapter A> detail::OnBlockExit Node::resolve_anchor(detail::ParserContext<A> & context) {
   auto const schema = context.schema.as_object();
   auto const schema = context.schema.as_object();
 
 
   // TODO(samjaffe): $recursiveAnchor, $dynamicAnchor, $recursiveRef, $dynamicRef
   // TODO(samjaffe): $recursiveAnchor, $dynamicAnchor, $recursiveRef, $dynamicRef
@@ -247,7 +249,7 @@ template <Adapter A> detail::OnBlockExit Node::resolve_anchor(ParserContext<A> &
   }
   }
 }
 }
 
 
-template <Adapter A> bool Node::resolve_reference(ParserContext<A> const & context) {
+template <Adapter A> bool Node::resolve_reference(detail::ParserContext<A> const & context) {
   auto const schema = context.schema.as_object();
   auto const schema = context.schema.as_object();
 
 
   if (schema.contains("$ref")) {
   if (schema.contains("$ref")) {
@@ -279,7 +281,7 @@ template <Adapter A> bool Node::resolve_reference(ParserContext<A> const & conte
   return false;
   return false;
 }
 }
 
 
-template <Adapter A> Node::Node(ParserContext<A> context) {
+template <Adapter A> Node::Node(detail::ParserContext<A> context) {
   EXPECT(context.schema.type() == adapter::Type::Object);
   EXPECT(context.schema.type() == adapter::Type::Object);
 
 
   auto const schema = context.schema.as_object();
   auto const schema = context.schema.as_object();