@@ -421,28 +421,32 @@ auto walk_additional_properties(
421421 const std::vector<Documentation::PathSegment> &base_path,
422422 std::vector<Documentation::Row> &rows,
423423 const sourcemeta::core::SchemaFrame &frame,
424- const sourcemeta::core::JSON &root, VisitedSchemas &visited) -> void;
424+ const sourcemeta::core::JSON &root, VisitedSchemas &visited,
425+ std::size_t &next_identifier) -> void;
425426
426427auto walk_unevaluated_properties (
427428 const sourcemeta::core::JSON &schema,
428429 const std::vector<Documentation::PathSegment> &base_path,
429430 std::vector<Documentation::Row> &rows,
430431 const sourcemeta::core::SchemaFrame &frame,
431- const sourcemeta::core::JSON &root, VisitedSchemas &visited) -> void;
432+ const sourcemeta::core::JSON &root, VisitedSchemas &visited,
433+ std::size_t &next_identifier) -> void;
432434
433435auto walk_unevaluated_items (
434436 const sourcemeta::core::JSON &schema,
435437 const std::vector<Documentation::PathSegment> &base_path,
436438 std::vector<Documentation::Row> &rows,
437439 const sourcemeta::core::SchemaFrame &frame,
438- const sourcemeta::core::JSON &root, VisitedSchemas &visited) -> void;
440+ const sourcemeta::core::JSON &root, VisitedSchemas &visited,
441+ std::size_t &next_identifier) -> void;
439442
440443auto walk_pattern_properties (
441444 const sourcemeta::core::JSON &schema,
442445 const std::vector<Documentation::PathSegment> &base_path,
443446 std::vector<Documentation::Row> &rows,
444447 const sourcemeta::core::SchemaFrame &frame,
445- const sourcemeta::core::JSON &root, VisitedSchemas &visited) -> void;
448+ const sourcemeta::core::JSON &root, VisitedSchemas &visited,
449+ std::size_t &next_identifier) -> void;
446450
447451auto resolve_ref (const sourcemeta::core::JSON &schema,
448452 const sourcemeta::core::SchemaFrame &frame,
@@ -469,9 +473,10 @@ auto emit_row(const sourcemeta::core::JSON &schema,
469473 std::vector<Documentation::PathSegment> path,
470474 std::vector<Documentation::Row> &rows,
471475 const sourcemeta::core::SchemaFrame &frame,
472- const sourcemeta::core::JSON &root, const VisitedSchemas &visited)
473- -> void {
476+ const sourcemeta::core::JSON &root, const VisitedSchemas &visited,
477+ std:: size_t &next_identifier) -> void {
474478 Documentation::Row row;
479+ row.identifier = next_identifier++;
475480 row.path = std::move (path);
476481 row.modifiers = modifiers_of (schema);
477482 row.type .expression = type_expression_of (schema, frame, root, visited);
@@ -486,7 +491,8 @@ auto walk_properties(const sourcemeta::core::JSON &schema,
486491 std::vector<Documentation::Row> &rows,
487492 const sourcemeta::core::SchemaFrame &frame,
488493 const sourcemeta::core::JSON &root,
489- VisitedSchemas &visited) -> void {
494+ VisitedSchemas &visited, std::size_t &next_identifier)
495+ -> void {
490496 if (!schema.is_object () || !schema.defines (" properties" ) ||
491497 !schema.at (" properties" ).is_object ()) {
492498 return ;
@@ -498,6 +504,7 @@ auto walk_properties(const sourcemeta::core::JSON &schema,
498504 path.push_back (
499505 {.type = Documentation::PathType::Literal, .value = entry.first });
500506 Documentation::Row row;
507+ row.identifier = next_identifier++;
501508 row.path = path;
502509 row.modifiers = modifiers_of (resolved);
503510 row.type .expression = type_expression_of (resolved, frame, root, visited);
@@ -510,11 +517,15 @@ auto walk_properties(const sourcemeta::core::JSON &schema,
510517 if (resolved.is_object () && resolved.defines (" type" ) &&
511518 resolved.at (" type" ).is_string () &&
512519 resolved.at (" type" ).to_string () == " object" ) {
513- visited.emplace (&resolved, std::size_t {0 });
514- walk_properties (resolved, path, rows, frame, root, visited);
515- walk_pattern_properties (resolved, path, rows, frame, root, visited);
516- walk_additional_properties (resolved, path, rows, frame, root, visited);
517- walk_unevaluated_properties (resolved, path, rows, frame, root, visited);
520+ visited.emplace (&resolved, rows.back ().identifier );
521+ walk_properties (resolved, path, rows, frame, root, visited,
522+ next_identifier);
523+ walk_pattern_properties (resolved, path, rows, frame, root, visited,
524+ next_identifier);
525+ walk_additional_properties (resolved, path, rows, frame, root, visited,
526+ next_identifier);
527+ walk_unevaluated_properties (resolved, path, rows, frame, root, visited,
528+ next_identifier);
518529 visited.erase (&resolved);
519530 }
520531 }
@@ -525,7 +536,8 @@ auto walk_additional_properties(
525536 const std::vector<Documentation::PathSegment> &base_path,
526537 std::vector<Documentation::Row> &rows,
527538 const sourcemeta::core::SchemaFrame &frame,
528- const sourcemeta::core::JSON &root, VisitedSchemas &visited) -> void {
539+ const sourcemeta::core::JSON &root, VisitedSchemas &visited,
540+ std::size_t &next_identifier) -> void {
529541 if (!schema.is_object () || !schema.defines (" additionalProperties" ) ||
530542 !schema.at (" additionalProperties" ).is_object ()) {
531543 return ;
@@ -534,15 +546,16 @@ auto walk_additional_properties(
534546 auto path{base_path};
535547 path.push_back ({.type = Documentation::PathType::Wildcard, .value = " *" });
536548 emit_row (schema.at (" additionalProperties" ), std::move (path), rows, frame,
537- root, visited);
549+ root, visited, next_identifier );
538550}
539551
540552auto walk_unevaluated_properties (
541553 const sourcemeta::core::JSON &schema,
542554 const std::vector<Documentation::PathSegment> &base_path,
543555 std::vector<Documentation::Row> &rows,
544556 const sourcemeta::core::SchemaFrame &frame,
545- const sourcemeta::core::JSON &root, VisitedSchemas &visited) -> void {
557+ const sourcemeta::core::JSON &root, VisitedSchemas &visited,
558+ std::size_t &next_identifier) -> void {
546559 if (!schema.is_object () || !schema.defines (" unevaluatedProperties" ) ||
547560 !schema.at (" unevaluatedProperties" ).is_object ()) {
548561 return ;
@@ -551,15 +564,16 @@ auto walk_unevaluated_properties(
551564 auto path{base_path};
552565 path.push_back ({.type = Documentation::PathType::Wildcard, .value = " *" });
553566 emit_row (schema.at (" unevaluatedProperties" ), std::move (path), rows, frame,
554- root, visited);
567+ root, visited, next_identifier );
555568}
556569
557570auto walk_unevaluated_items (
558571 const sourcemeta::core::JSON &schema,
559572 const std::vector<Documentation::PathSegment> &base_path,
560573 std::vector<Documentation::Row> &rows,
561574 const sourcemeta::core::SchemaFrame &frame,
562- const sourcemeta::core::JSON &root, VisitedSchemas &visited) -> void {
575+ const sourcemeta::core::JSON &root, VisitedSchemas &visited,
576+ std::size_t &next_identifier) -> void {
563577 if (!schema.is_object () || !schema.defines (" unevaluatedItems" ) ||
564578 !schema.at (" unevaluatedItems" ).is_object ()) {
565579 return ;
@@ -572,15 +586,16 @@ auto walk_unevaluated_items(
572586 auto path{base_path};
573587 path.push_back ({.type = Documentation::PathType::Wildcard, .value = " *" });
574588 emit_row (schema.at (" unevaluatedItems" ), std::move (path), rows, frame, root,
575- visited);
589+ visited, next_identifier );
576590}
577591
578592auto walk_pattern_properties (
579593 const sourcemeta::core::JSON &schema,
580594 const std::vector<Documentation::PathSegment> &base_path,
581595 std::vector<Documentation::Row> &rows,
582596 const sourcemeta::core::SchemaFrame &frame,
583- const sourcemeta::core::JSON &root, VisitedSchemas &visited) -> void {
597+ const sourcemeta::core::JSON &root, VisitedSchemas &visited,
598+ std::size_t &next_identifier) -> void {
584599 if (!schema.is_object () || !schema.defines (" patternProperties" ) ||
585600 !schema.at (" patternProperties" ).is_object ()) {
586601 return ;
@@ -590,7 +605,8 @@ auto walk_pattern_properties(
590605 auto path{base_path};
591606 path.push_back (
592607 {.type = Documentation::PathType::Pattern, .value = entry.first });
593- emit_row (entry.second , std::move (path), rows, frame, root, visited);
608+ emit_row (entry.second , std::move (path), rows, frame, root, visited,
609+ next_identifier);
594610 }
595611}
596612
@@ -639,6 +655,7 @@ auto walk_prefix_items(const sourcemeta::core::JSON &schema,
639655 path.push_back ({.type = Documentation::PathType::Literal,
640656 .value = std::to_string (index)});
641657 Documentation::Row row;
658+ row.identifier = next_identifier++;
642659 row.path = std::move (path);
643660 row.modifiers = modifiers_of (item);
644661 row.type .expression = type_expression_of (item, frame, root, visited);
@@ -778,7 +795,7 @@ auto walk_schema(const sourcemeta::core::JSON &schema, const bool include_root,
778795 documentation.rows .push_back (std::move (row));
779796 return documentation;
780797 }
781- visited.emplace (&target_schema, std:: size_t { 0 } );
798+ visited.emplace (&target_schema, next_identifier );
782799 auto result{walk_schema (target_schema, include_root, frame, root, visited,
783800 next_identifier)};
784801 visited.erase (&target_schema);
@@ -796,25 +813,27 @@ auto walk_schema(const sourcemeta::core::JSON &schema, const bool include_root,
796813 }
797814
798815 if (include_root) {
799- visited.emplace (&schema, documentation.identifier );
800816 emit_row (schema,
801817 {{.type = Documentation::PathType::Synthetic, .value = " root" }},
802- documentation.rows , frame, root, visited);
818+ documentation.rows , frame, root, visited, next_identifier);
819+ visited.emplace (&schema, documentation.rows .back ().identifier );
803820 }
804821
805822 if (!schema.is_object ()) {
806823 if (!include_root) {
807- emit_row (schema, {}, documentation.rows , frame, root, visited);
824+ emit_row (schema, {}, documentation.rows , frame, root, visited,
825+ next_identifier);
808826 }
809827 return documentation;
810828 }
811829
812830 const std::vector<Documentation::PathSegment> empty_path;
813- walk_properties (schema, empty_path, documentation.rows , frame, root, visited);
831+ walk_properties (schema, empty_path, documentation.rows , frame, root, visited,
832+ next_identifier);
814833 walk_pattern_properties (schema, empty_path, documentation.rows , frame, root,
815- visited);
834+ visited, next_identifier );
816835 walk_additional_properties (schema, empty_path, documentation.rows , frame,
817- root, visited);
836+ root, visited, next_identifier );
818837 walk_prefix_items (schema, empty_path, documentation.rows ,
819838 documentation.children , frame, root, visited,
820839 next_identifier);
@@ -827,9 +846,9 @@ auto walk_schema(const sourcemeta::core::JSON &schema, const bool include_root,
827846 walk_if_then_else (schema, documentation.children , frame, root, visited,
828847 next_identifier);
829848 walk_unevaluated_properties (schema, empty_path, documentation.rows , frame,
830- root, visited);
849+ root, visited, next_identifier );
831850 walk_unevaluated_items (schema, empty_path, documentation.rows , frame, root,
832- visited);
851+ visited, next_identifier );
833852
834853 if (schema.is_object () && schema.defines (" contains" ) &&
835854 schema.at (" contains" ).is_object ()) {
@@ -844,7 +863,7 @@ auto walk_schema(const sourcemeta::core::JSON &schema, const bool include_root,
844863 emit_row (contains_schema,
845864 {{.type = Documentation::PathType::Synthetic,
846865 .value = " matching item" }},
847- table.rows , frame, root, visited);
866+ table.rows , frame, root, visited, next_identifier );
848867 walk_any_of (contains_schema, table.children , frame, root, visited,
849868 next_identifier);
850869 walk_one_of (contains_schema, table.children , frame, root, visited,
@@ -868,9 +887,10 @@ auto walk_schema(const sourcemeta::core::JSON &schema, const bool include_root,
868887 Documentation table;
869888 const std::vector<Documentation::PathSegment> decoded_path{
870889 {.type = Documentation::PathType::Synthetic, .value = " decoded" }};
871- emit_row (content_schema, decoded_path, table.rows , frame, root, visited);
890+ emit_row (content_schema, decoded_path, table.rows , frame, root, visited,
891+ next_identifier);
872892 walk_properties (content_schema, decoded_path, table.rows , frame, root,
873- visited);
893+ visited, next_identifier );
874894 walk_any_of (content_schema, table.children , frame, root, visited,
875895 next_identifier);
876896 walk_one_of (content_schema, table.children , frame, root, visited,
@@ -894,7 +914,7 @@ auto walk_schema(const sourcemeta::core::JSON &schema, const bool include_root,
894914 Documentation table;
895915 emit_row (names_schema,
896916 {{.type = Documentation::PathType::Synthetic, .value = " key" }},
897- table.rows , frame, root, visited);
917+ table.rows , frame, root, visited, next_identifier );
898918 walk_any_of (names_schema, table.children , frame, root, visited,
899919 next_identifier);
900920 walk_one_of (names_schema, table.children , frame, root, visited,
@@ -918,7 +938,7 @@ auto walk_schema(const sourcemeta::core::JSON &schema, const bool include_root,
918938 Documentation table;
919939 emit_row (not_schema,
920940 {{.type = Documentation::PathType::Synthetic, .value = " value" }},
921- table.rows , frame, root, visited);
941+ table.rows , frame, root, visited, next_identifier );
922942 walk_any_of (not_schema, table.children , frame, root, visited,
923943 next_identifier);
924944 walk_one_of (not_schema, table.children , frame, root, visited,
@@ -937,7 +957,7 @@ auto walk_schema(const sourcemeta::core::JSON &schema, const bool include_root,
937957 Documentation table;
938958 emit_row (schema.at (" not" ),
939959 {{.type = Documentation::PathType::Synthetic, .value = " value" }},
940- table.rows , frame, root, visited);
960+ table.rows , frame, root, visited, next_identifier );
941961 section.children .push_back (std::move (table));
942962 documentation.children .push_back (std::move (section));
943963 }
@@ -946,7 +966,8 @@ auto walk_schema(const sourcemeta::core::JSON &schema, const bool include_root,
946966 // to say (constraints, type, notes). Emit a single row so it is not lost.
947967 if (!include_root && documentation.rows .empty () &&
948968 documentation.children .empty () && schema.is_object ()) {
949- emit_row (schema, {}, documentation.rows , frame, root, visited);
969+ emit_row (schema, {}, documentation.rows , frame, root, visited,
970+ next_identifier);
950971 }
951972
952973 assert (!documentation.rows .empty () || !documentation.children .empty ());
0 commit comments