@@ -557,6 +557,75 @@ inline bool Object::erase(StringRef K) {
557
557
return M.erase (ObjectKey (K));
558
558
}
559
559
560
+ // / A "cursor" marking a position within a Value.
561
+ // / The Value is a tree, and this is the path from the root to the current node.
562
+ // / This is used to associate errors with particular subobjects.
563
+ class Path {
564
+ public:
565
+ class Root ;
566
+
567
+ // / Records that the value at the current path is invalid.
568
+ // / Message is e.g. "expected number" and becomes part of the final error.
569
+ // / This overwrites any previously written error message in the root.
570
+ void report (llvm::StringLiteral Message);
571
+
572
+ // / The root may be treated as a Path.
573
+ Path (Root &R) : Parent(nullptr ), Seg(&R) {}
574
+ // / Derives a path for an array element: this[Index]
575
+ Path index (unsigned Index) const { return Path (this , Segment (Index)); }
576
+ // / Derives a path for an object field: this.Field
577
+ Path field (StringRef Field) const { return Path (this , Segment (Field)); }
578
+
579
+ private:
580
+ // / One element in a JSON path: an object field (.foo) or array index [27].
581
+ // / Exception: the root Path encodes a pointer to the Path::Root.
582
+ class Segment {
583
+ uintptr_t Pointer;
584
+ unsigned Offset;
585
+
586
+ public:
587
+ Segment () = default ;
588
+ Segment (Root *R) : Pointer(reinterpret_cast <uintptr_t >(R)) {}
589
+ Segment (llvm::StringRef Field)
590
+ : Pointer(reinterpret_cast <uintptr_t >(Field.data())),
591
+ Offset (static_cast <unsigned >(Field.size())) {}
592
+ Segment (unsigned Index) : Pointer(0 ), Offset(Index) {}
593
+
594
+ bool isField () const { return Pointer != 0 ; }
595
+ StringRef field () const {
596
+ return StringRef (reinterpret_cast <const char *>(Pointer), Offset);
597
+ }
598
+ unsigned index () const { return Offset; }
599
+ Root *root () const { return reinterpret_cast <Root *>(Pointer); }
600
+ };
601
+
602
+ const Path *Parent;
603
+ Segment Seg;
604
+
605
+ Path (const Path *Parent, Segment S) : Parent(Parent), Seg(S) {}
606
+ };
607
+
608
+ // / The root is the trivial Path to the root value.
609
+ // / It also stores the latest reported error and the path where it occurred.
610
+ class Path ::Root {
611
+ llvm::StringRef Name;
612
+ llvm::StringLiteral ErrorMessage;
613
+ std::vector<Path::Segment> ErrorPath; // Only valid in error state. Reversed.
614
+
615
+ friend void Path::report (llvm::StringLiteral Message);
616
+
617
+ public:
618
+ Root (llvm::StringRef Name = " " ) : Name(Name), ErrorMessage(" " ) {}
619
+ // No copy/move allowed as there are incoming pointers.
620
+ Root (Root &&) = delete ;
621
+ Root &operator =(Root &&) = delete ;
622
+ Root (const Root &) = delete ;
623
+ Root &operator =(const Root &) = delete ;
624
+
625
+ // / Returns the last error reported, or else a generic error.
626
+ Error getError () const ;
627
+ };
628
+
560
629
// Standard deserializers are provided for primitive types.
561
630
// See comments on Value.
562
631
inline bool fromJSON (const Value &E, std::string &Out) {
0 commit comments