1320543Sdim//===-- StructuredData.h ----------------------------------------*- C++ -*-===//
2320543Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6320543Sdim//
7320543Sdim//===----------------------------------------------------------------------===//
8320543Sdim
9320543Sdim#ifndef liblldb_StructuredData_h_
10320543Sdim#define liblldb_StructuredData_h_
11320543Sdim
12320543Sdim#include "llvm/ADT/StringRef.h"
13360784Sdim#include "llvm/Support/JSON.h"
14320543Sdim
15320543Sdim#include "lldb/Utility/ConstString.h"
16344779Sdim#include "lldb/Utility/FileSpec.h"
17360784Sdim#include "lldb/Utility/Stream.h"
18344779Sdim#include "lldb/lldb-enumerations.h"
19320543Sdim
20344779Sdim#include <cassert>
21344779Sdim#include <cstddef>
22344779Sdim#include <cstdint>
23320543Sdim#include <functional>
24320543Sdim#include <map>
25320543Sdim#include <memory>
26320543Sdim#include <string>
27344779Sdim#include <type_traits>
28320543Sdim#include <utility>
29320543Sdim#include <vector>
30320543Sdim
31320543Sdimnamespace lldb_private {
32320543Sdimclass Status;
33320543Sdim}
34320543Sdim
35320543Sdimnamespace lldb_private {
36320543Sdim
37353358Sdim/// \class StructuredData StructuredData.h "lldb/Utility/StructuredData.h"
38341825Sdim/// A class which can hold structured data
39320543Sdim///
40341825Sdim/// The StructuredData class is designed to hold the data from a JSON or plist
41341825Sdim/// style file -- a serialized data structure with dictionaries (maps,
42341825Sdim/// hashes), arrays, and concrete values like integers, floating point
43341825Sdim/// numbers, strings, booleans.
44320543Sdim///
45341825Sdim/// StructuredData does not presuppose any knowledge of the schema for the
46341825Sdim/// data it is holding; it can parse JSON data, for instance, and other parts
47341825Sdim/// of lldb can iterate through the parsed data set to find keys and values
48341825Sdim/// that may be present.
49320543Sdim
50320543Sdimclass StructuredData {
51320543Sdimpublic:
52320543Sdim  class Object;
53320543Sdim  class Array;
54320543Sdim  class Integer;
55320543Sdim  class Float;
56320543Sdim  class Boolean;
57320543Sdim  class String;
58320543Sdim  class Dictionary;
59320543Sdim  class Generic;
60320543Sdim
61320543Sdim  typedef std::shared_ptr<Object> ObjectSP;
62320543Sdim  typedef std::shared_ptr<Array> ArraySP;
63320543Sdim  typedef std::shared_ptr<Integer> IntegerSP;
64320543Sdim  typedef std::shared_ptr<Float> FloatSP;
65320543Sdim  typedef std::shared_ptr<Boolean> BooleanSP;
66320543Sdim  typedef std::shared_ptr<String> StringSP;
67320543Sdim  typedef std::shared_ptr<Dictionary> DictionarySP;
68320543Sdim  typedef std::shared_ptr<Generic> GenericSP;
69320543Sdim
70320543Sdim  class Object : public std::enable_shared_from_this<Object> {
71320543Sdim  public:
72320543Sdim    Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid)
73320543Sdim        : m_type(t) {}
74320543Sdim
75320543Sdim    virtual ~Object() = default;
76320543Sdim
77320543Sdim    virtual bool IsValid() const { return true; }
78320543Sdim
79320543Sdim    virtual void Clear() { m_type = lldb::eStructuredDataTypeInvalid; }
80320543Sdim
81320543Sdim    lldb::StructuredDataType GetType() const { return m_type; }
82320543Sdim
83320543Sdim    void SetType(lldb::StructuredDataType t) { m_type = t; }
84320543Sdim
85320543Sdim    Array *GetAsArray() {
86320543Sdim      return ((m_type == lldb::eStructuredDataTypeArray)
87320543Sdim                  ? static_cast<Array *>(this)
88320543Sdim                  : nullptr);
89320543Sdim    }
90320543Sdim
91320543Sdim    Dictionary *GetAsDictionary() {
92320543Sdim      return ((m_type == lldb::eStructuredDataTypeDictionary)
93320543Sdim                  ? static_cast<Dictionary *>(this)
94320543Sdim                  : nullptr);
95320543Sdim    }
96320543Sdim
97320543Sdim    Integer *GetAsInteger() {
98320543Sdim      return ((m_type == lldb::eStructuredDataTypeInteger)
99320543Sdim                  ? static_cast<Integer *>(this)
100320543Sdim                  : nullptr);
101320543Sdim    }
102320543Sdim
103320543Sdim    uint64_t GetIntegerValue(uint64_t fail_value = 0) {
104320543Sdim      Integer *integer = GetAsInteger();
105320543Sdim      return ((integer != nullptr) ? integer->GetValue() : fail_value);
106320543Sdim    }
107320543Sdim
108320543Sdim    Float *GetAsFloat() {
109320543Sdim      return ((m_type == lldb::eStructuredDataTypeFloat)
110320543Sdim                  ? static_cast<Float *>(this)
111320543Sdim                  : nullptr);
112320543Sdim    }
113320543Sdim
114320543Sdim    double GetFloatValue(double fail_value = 0.0) {
115320543Sdim      Float *f = GetAsFloat();
116320543Sdim      return ((f != nullptr) ? f->GetValue() : fail_value);
117320543Sdim    }
118320543Sdim
119320543Sdim    Boolean *GetAsBoolean() {
120320543Sdim      return ((m_type == lldb::eStructuredDataTypeBoolean)
121320543Sdim                  ? static_cast<Boolean *>(this)
122320543Sdim                  : nullptr);
123320543Sdim    }
124320543Sdim
125320543Sdim    bool GetBooleanValue(bool fail_value = false) {
126320543Sdim      Boolean *b = GetAsBoolean();
127320543Sdim      return ((b != nullptr) ? b->GetValue() : fail_value);
128320543Sdim    }
129320543Sdim
130320543Sdim    String *GetAsString() {
131320543Sdim      return ((m_type == lldb::eStructuredDataTypeString)
132320543Sdim                  ? static_cast<String *>(this)
133320543Sdim                  : nullptr);
134320543Sdim    }
135320543Sdim
136320543Sdim    llvm::StringRef GetStringValue(const char *fail_value = nullptr) {
137320543Sdim      String *s = GetAsString();
138320543Sdim      if (s)
139320543Sdim        return s->GetValue();
140320543Sdim
141320543Sdim      return fail_value;
142320543Sdim    }
143320543Sdim
144320543Sdim    Generic *GetAsGeneric() {
145320543Sdim      return ((m_type == lldb::eStructuredDataTypeGeneric)
146320543Sdim                  ? static_cast<Generic *>(this)
147320543Sdim                  : nullptr);
148320543Sdim    }
149320543Sdim
150320543Sdim    ObjectSP GetObjectForDotSeparatedPath(llvm::StringRef path);
151320543Sdim
152320543Sdim    void DumpToStdout(bool pretty_print = true) const;
153320543Sdim
154360784Sdim    virtual void Serialize(llvm::json::OStream &s) const = 0;
155320543Sdim
156360784Sdim    void Dump(lldb_private::Stream &s, bool pretty_print = true) const {
157360784Sdim      llvm::json::OStream jso(s.AsRawOstream(), pretty_print ? 2 : 0);
158360784Sdim      Serialize(jso);
159360784Sdim    }
160360784Sdim
161320543Sdim  private:
162320543Sdim    lldb::StructuredDataType m_type;
163320543Sdim  };
164320543Sdim
165320543Sdim  class Array : public Object {
166320543Sdim  public:
167320543Sdim    Array() : Object(lldb::eStructuredDataTypeArray) {}
168320543Sdim
169320543Sdim    ~Array() override = default;
170320543Sdim
171320543Sdim    bool
172320543Sdim    ForEach(std::function<bool(Object *object)> const &foreach_callback) const {
173320543Sdim      for (const auto &object_sp : m_items) {
174344779Sdim        if (!foreach_callback(object_sp.get()))
175320543Sdim          return false;
176320543Sdim      }
177320543Sdim      return true;
178320543Sdim    }
179320543Sdim
180320543Sdim    size_t GetSize() const { return m_items.size(); }
181320543Sdim
182320543Sdim    ObjectSP operator[](size_t idx) {
183320543Sdim      if (idx < m_items.size())
184320543Sdim        return m_items[idx];
185320543Sdim      return ObjectSP();
186320543Sdim    }
187320543Sdim
188320543Sdim    ObjectSP GetItemAtIndex(size_t idx) const {
189320543Sdim      assert(idx < GetSize());
190320543Sdim      if (idx < m_items.size())
191320543Sdim        return m_items[idx];
192320543Sdim      return ObjectSP();
193320543Sdim    }
194320543Sdim
195320543Sdim    template <class IntType>
196320543Sdim    bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const {
197320543Sdim      ObjectSP value_sp = GetItemAtIndex(idx);
198320543Sdim      if (value_sp.get()) {
199320543Sdim        if (auto int_value = value_sp->GetAsInteger()) {
200320543Sdim          result = static_cast<IntType>(int_value->GetValue());
201320543Sdim          return true;
202320543Sdim        }
203320543Sdim      }
204320543Sdim      return false;
205320543Sdim    }
206320543Sdim
207320543Sdim    template <class IntType>
208320543Sdim    bool GetItemAtIndexAsInteger(size_t idx, IntType &result,
209320543Sdim                                 IntType default_val) const {
210320543Sdim      bool success = GetItemAtIndexAsInteger(idx, result);
211320543Sdim      if (!success)
212320543Sdim        result = default_val;
213320543Sdim      return success;
214320543Sdim    }
215320543Sdim
216320543Sdim    bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const {
217320543Sdim      ObjectSP value_sp = GetItemAtIndex(idx);
218320543Sdim      if (value_sp.get()) {
219320543Sdim        if (auto string_value = value_sp->GetAsString()) {
220320543Sdim          result = string_value->GetValue();
221320543Sdim          return true;
222320543Sdim        }
223320543Sdim      }
224320543Sdim      return false;
225320543Sdim    }
226320543Sdim
227320543Sdim    bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result,
228320543Sdim                                llvm::StringRef default_val) const {
229320543Sdim      bool success = GetItemAtIndexAsString(idx, result);
230320543Sdim      if (!success)
231320543Sdim        result = default_val;
232320543Sdim      return success;
233320543Sdim    }
234320543Sdim
235320543Sdim    bool GetItemAtIndexAsString(size_t idx, ConstString &result) const {
236320543Sdim      ObjectSP value_sp = GetItemAtIndex(idx);
237320543Sdim      if (value_sp.get()) {
238320543Sdim        if (auto string_value = value_sp->GetAsString()) {
239320543Sdim          result = ConstString(string_value->GetValue());
240320543Sdim          return true;
241320543Sdim        }
242320543Sdim      }
243320543Sdim      return false;
244320543Sdim    }
245320543Sdim
246320543Sdim    bool GetItemAtIndexAsString(size_t idx, ConstString &result,
247320543Sdim                                const char *default_val) const {
248320543Sdim      bool success = GetItemAtIndexAsString(idx, result);
249320543Sdim      if (!success)
250320543Sdim        result.SetCString(default_val);
251320543Sdim      return success;
252320543Sdim    }
253320543Sdim
254320543Sdim    bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const {
255320543Sdim      result = nullptr;
256320543Sdim      ObjectSP value_sp = GetItemAtIndex(idx);
257320543Sdim      if (value_sp.get()) {
258320543Sdim        result = value_sp->GetAsDictionary();
259320543Sdim        return (result != nullptr);
260320543Sdim      }
261320543Sdim      return false;
262320543Sdim    }
263320543Sdim
264320543Sdim    bool GetItemAtIndexAsArray(size_t idx, Array *&result) const {
265320543Sdim      result = nullptr;
266320543Sdim      ObjectSP value_sp = GetItemAtIndex(idx);
267320543Sdim      if (value_sp.get()) {
268320543Sdim        result = value_sp->GetAsArray();
269320543Sdim        return (result != nullptr);
270320543Sdim      }
271320543Sdim      return false;
272320543Sdim    }
273320543Sdim
274320543Sdim    void Push(ObjectSP item) { m_items.push_back(item); }
275320543Sdim
276320543Sdim    void AddItem(ObjectSP item) { m_items.push_back(item); }
277320543Sdim
278360784Sdim    void Serialize(llvm::json::OStream &s) const override;
279320543Sdim
280320543Sdim  protected:
281320543Sdim    typedef std::vector<ObjectSP> collection;
282320543Sdim    collection m_items;
283320543Sdim  };
284320543Sdim
285320543Sdim  class Integer : public Object {
286320543Sdim  public:
287320543Sdim    Integer(uint64_t i = 0)
288320543Sdim        : Object(lldb::eStructuredDataTypeInteger), m_value(i) {}
289320543Sdim
290320543Sdim    ~Integer() override = default;
291320543Sdim
292320543Sdim    void SetValue(uint64_t value) { m_value = value; }
293320543Sdim
294320543Sdim    uint64_t GetValue() { return m_value; }
295320543Sdim
296360784Sdim    void Serialize(llvm::json::OStream &s) const override;
297320543Sdim
298320543Sdim  protected:
299320543Sdim    uint64_t m_value;
300320543Sdim  };
301320543Sdim
302320543Sdim  class Float : public Object {
303320543Sdim  public:
304320543Sdim    Float(double d = 0.0)
305320543Sdim        : Object(lldb::eStructuredDataTypeFloat), m_value(d) {}
306320543Sdim
307320543Sdim    ~Float() override = default;
308320543Sdim
309320543Sdim    void SetValue(double value) { m_value = value; }
310320543Sdim
311320543Sdim    double GetValue() { return m_value; }
312320543Sdim
313360784Sdim    void Serialize(llvm::json::OStream &s) const override;
314320543Sdim
315320543Sdim  protected:
316320543Sdim    double m_value;
317320543Sdim  };
318320543Sdim
319320543Sdim  class Boolean : public Object {
320320543Sdim  public:
321320543Sdim    Boolean(bool b = false)
322320543Sdim        : Object(lldb::eStructuredDataTypeBoolean), m_value(b) {}
323320543Sdim
324320543Sdim    ~Boolean() override = default;
325320543Sdim
326320543Sdim    void SetValue(bool value) { m_value = value; }
327320543Sdim
328320543Sdim    bool GetValue() { return m_value; }
329320543Sdim
330360784Sdim    void Serialize(llvm::json::OStream &s) const override;
331320543Sdim
332320543Sdim  protected:
333320543Sdim    bool m_value;
334320543Sdim  };
335320543Sdim
336320543Sdim  class String : public Object {
337320543Sdim  public:
338320543Sdim    String() : Object(lldb::eStructuredDataTypeString) {}
339320543Sdim    explicit String(llvm::StringRef S)
340320543Sdim        : Object(lldb::eStructuredDataTypeString), m_value(S) {}
341320543Sdim
342320543Sdim    void SetValue(llvm::StringRef S) { m_value = S; }
343320543Sdim
344320543Sdim    llvm::StringRef GetValue() { return m_value; }
345320543Sdim
346360784Sdim    void Serialize(llvm::json::OStream &s) const override;
347320543Sdim
348320543Sdim  protected:
349320543Sdim    std::string m_value;
350320543Sdim  };
351320543Sdim
352320543Sdim  class Dictionary : public Object {
353320543Sdim  public:
354320543Sdim    Dictionary() : Object(lldb::eStructuredDataTypeDictionary), m_dict() {}
355320543Sdim
356320543Sdim    ~Dictionary() override = default;
357320543Sdim
358320543Sdim    size_t GetSize() const { return m_dict.size(); }
359320543Sdim
360320543Sdim    void ForEach(std::function<bool(ConstString key, Object *object)> const
361320543Sdim                     &callback) const {
362320543Sdim      for (const auto &pair : m_dict) {
363344779Sdim        if (!callback(pair.first, pair.second.get()))
364320543Sdim          break;
365320543Sdim      }
366320543Sdim    }
367320543Sdim
368320543Sdim    ObjectSP GetKeys() const {
369320543Sdim      auto object_sp = std::make_shared<Array>();
370320543Sdim      collection::const_iterator iter;
371320543Sdim      for (iter = m_dict.begin(); iter != m_dict.end(); ++iter) {
372320543Sdim        auto key_object_sp = std::make_shared<String>();
373320543Sdim        key_object_sp->SetValue(iter->first.AsCString());
374320543Sdim        object_sp->Push(key_object_sp);
375320543Sdim      }
376320543Sdim      return object_sp;
377320543Sdim    }
378320543Sdim
379320543Sdim    ObjectSP GetValueForKey(llvm::StringRef key) const {
380320543Sdim      ObjectSP value_sp;
381320543Sdim      if (!key.empty()) {
382320543Sdim        ConstString key_cs(key);
383320543Sdim        collection::const_iterator iter = m_dict.find(key_cs);
384320543Sdim        if (iter != m_dict.end())
385320543Sdim          value_sp = iter->second;
386320543Sdim      }
387320543Sdim      return value_sp;
388320543Sdim    }
389320543Sdim
390320543Sdim    bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const {
391320543Sdim      bool success = false;
392320543Sdim      ObjectSP value_sp = GetValueForKey(key);
393320543Sdim      if (value_sp.get()) {
394320543Sdim        Boolean *result_ptr = value_sp->GetAsBoolean();
395320543Sdim        if (result_ptr) {
396320543Sdim          result = result_ptr->GetValue();
397320543Sdim          success = true;
398320543Sdim        }
399320543Sdim      }
400320543Sdim      return success;
401320543Sdim    }
402320543Sdim    template <class IntType>
403320543Sdim    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
404320543Sdim      ObjectSP value_sp = GetValueForKey(key);
405320543Sdim      if (value_sp) {
406320543Sdim        if (auto int_value = value_sp->GetAsInteger()) {
407320543Sdim          result = static_cast<IntType>(int_value->GetValue());
408320543Sdim          return true;
409320543Sdim        }
410320543Sdim      }
411320543Sdim      return false;
412320543Sdim    }
413320543Sdim
414320543Sdim    template <class IntType>
415320543Sdim    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result,
416320543Sdim                                 IntType default_val) const {
417320543Sdim      bool success = GetValueForKeyAsInteger<IntType>(key, result);
418320543Sdim      if (!success)
419320543Sdim        result = default_val;
420320543Sdim      return success;
421320543Sdim    }
422320543Sdim
423320543Sdim    bool GetValueForKeyAsString(llvm::StringRef key,
424320543Sdim                                llvm::StringRef &result) const {
425320543Sdim      ObjectSP value_sp = GetValueForKey(key);
426320543Sdim      if (value_sp.get()) {
427320543Sdim        if (auto string_value = value_sp->GetAsString()) {
428320543Sdim          result = string_value->GetValue();
429320543Sdim          return true;
430320543Sdim        }
431320543Sdim      }
432320543Sdim      return false;
433320543Sdim    }
434320543Sdim
435320543Sdim    bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result,
436320543Sdim                                const char *default_val) const {
437320543Sdim      bool success = GetValueForKeyAsString(key, result);
438320543Sdim      if (!success) {
439320543Sdim        if (default_val)
440320543Sdim          result = default_val;
441320543Sdim        else
442320543Sdim          result = llvm::StringRef();
443320543Sdim      }
444320543Sdim      return success;
445320543Sdim    }
446320543Sdim
447320543Sdim    bool GetValueForKeyAsString(llvm::StringRef key,
448320543Sdim                                ConstString &result) const {
449320543Sdim      ObjectSP value_sp = GetValueForKey(key);
450320543Sdim      if (value_sp.get()) {
451320543Sdim        if (auto string_value = value_sp->GetAsString()) {
452320543Sdim          result = ConstString(string_value->GetValue());
453320543Sdim          return true;
454320543Sdim        }
455320543Sdim      }
456320543Sdim      return false;
457320543Sdim    }
458320543Sdim
459320543Sdim    bool GetValueForKeyAsString(llvm::StringRef key, ConstString &result,
460320543Sdim                                const char *default_val) const {
461320543Sdim      bool success = GetValueForKeyAsString(key, result);
462320543Sdim      if (!success)
463320543Sdim        result.SetCString(default_val);
464320543Sdim      return success;
465320543Sdim    }
466320543Sdim
467320543Sdim    bool GetValueForKeyAsDictionary(llvm::StringRef key,
468320543Sdim                                    Dictionary *&result) const {
469320543Sdim      result = nullptr;
470320543Sdim      ObjectSP value_sp = GetValueForKey(key);
471320543Sdim      if (value_sp.get()) {
472320543Sdim        result = value_sp->GetAsDictionary();
473320543Sdim        return (result != nullptr);
474320543Sdim      }
475320543Sdim      return false;
476320543Sdim    }
477320543Sdim
478320543Sdim    bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const {
479320543Sdim      result = nullptr;
480320543Sdim      ObjectSP value_sp = GetValueForKey(key);
481320543Sdim      if (value_sp.get()) {
482320543Sdim        result = value_sp->GetAsArray();
483320543Sdim        return (result != nullptr);
484320543Sdim      }
485320543Sdim      return false;
486320543Sdim    }
487320543Sdim
488320543Sdim    bool HasKey(llvm::StringRef key) const {
489320543Sdim      ConstString key_cs(key);
490320543Sdim      collection::const_iterator search = m_dict.find(key_cs);
491320543Sdim      return search != m_dict.end();
492320543Sdim    }
493320543Sdim
494320543Sdim    void AddItem(llvm::StringRef key, ObjectSP value_sp) {
495320543Sdim      ConstString key_cs(key);
496320543Sdim      m_dict[key_cs] = value_sp;
497320543Sdim    }
498320543Sdim
499320543Sdim    void AddIntegerItem(llvm::StringRef key, uint64_t value) {
500320543Sdim      AddItem(key, std::make_shared<Integer>(value));
501320543Sdim    }
502320543Sdim
503320543Sdim    void AddFloatItem(llvm::StringRef key, double value) {
504320543Sdim      AddItem(key, std::make_shared<Float>(value));
505320543Sdim    }
506320543Sdim
507320543Sdim    void AddStringItem(llvm::StringRef key, llvm::StringRef value) {
508320543Sdim      AddItem(key, std::make_shared<String>(std::move(value)));
509320543Sdim    }
510320543Sdim
511320543Sdim    void AddBooleanItem(llvm::StringRef key, bool value) {
512320543Sdim      AddItem(key, std::make_shared<Boolean>(value));
513320543Sdim    }
514320543Sdim
515360784Sdim    void Serialize(llvm::json::OStream &s) const override;
516320543Sdim
517320543Sdim  protected:
518320543Sdim    typedef std::map<ConstString, ObjectSP> collection;
519320543Sdim    collection m_dict;
520320543Sdim  };
521320543Sdim
522320543Sdim  class Null : public Object {
523320543Sdim  public:
524320543Sdim    Null() : Object(lldb::eStructuredDataTypeNull) {}
525320543Sdim
526320543Sdim    ~Null() override = default;
527320543Sdim
528320543Sdim    bool IsValid() const override { return false; }
529320543Sdim
530360784Sdim    void Serialize(llvm::json::OStream &s) const override;
531320543Sdim  };
532320543Sdim
533320543Sdim  class Generic : public Object {
534320543Sdim  public:
535320543Sdim    explicit Generic(void *object = nullptr)
536320543Sdim        : Object(lldb::eStructuredDataTypeGeneric), m_object(object) {}
537320543Sdim
538320543Sdim    void SetValue(void *value) { m_object = value; }
539320543Sdim
540320543Sdim    void *GetValue() const { return m_object; }
541320543Sdim
542320543Sdim    bool IsValid() const override { return m_object != nullptr; }
543320543Sdim
544360784Sdim    void Serialize(llvm::json::OStream &s) const override;
545320543Sdim
546320543Sdim  private:
547320543Sdim    void *m_object;
548320543Sdim  };
549320543Sdim
550320543Sdim  static ObjectSP ParseJSON(std::string json_text);
551320543Sdim  static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error);
552320543Sdim};
553320543Sdim
554320543Sdim} // namespace lldb_private
555320543Sdim
556320543Sdim#endif // liblldb_StructuredData_h_
557