Line data Source code
1 : /* JSON parsing
2 : Copyright (C) 2017-2026 Free Software Foundation, Inc.
3 : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #ifndef GCC_JSON_PARSING_H
22 : #define GCC_JSON_PARSING_H
23 :
24 : #include "json.h"
25 :
26 : namespace json
27 : {
28 :
29 : /* Declarations for parsing JSON to a json::value * tree. */
30 :
31 : /* Abstract base class for recording what the locations of JSON values
32 : were as they parsed. */
33 :
34 : class location_map
35 : {
36 : public:
37 : /* A point within the JSON input file. */
38 : struct point
39 : {
40 : size_t m_unichar_idx; /* zero-based. */
41 : int m_line; /* one-based. */
42 : int m_column; /* zero-based unichar count. */
43 : };
44 :
45 : /* A range of points within the JSON input file.
46 : Both endpoints are part of the range. */
47 : struct range
48 : {
49 : point m_start;
50 : point m_end;
51 : };
52 :
53 : virtual ~location_map () {}
54 : virtual void record_range_for_value (json::value *jv, const range &r) = 0;
55 96 : virtual void on_finished_parsing () {}
56 : };
57 :
58 : /* Implementation of json::location_map that records ranges to a std::map. */
59 :
60 : class simple_location_map : public location_map
61 : {
62 : public:
63 : void
64 0 : record_range_for_value (json::value *jv,
65 : const range &r) final override
66 : {
67 0 : m_map_jv_to_range[jv] = r;
68 0 : }
69 :
70 : const json::location_map::range &
71 : get_range_for_value (const json::value &jv) const
72 : {
73 : auto iter = m_map_jv_to_range.find (&jv);
74 : gcc_assert (iter != m_map_jv_to_range.end ());
75 : return iter->second;
76 : }
77 :
78 : private:
79 : std::map<const json::value *, range> m_map_jv_to_range;
80 : };
81 :
82 : /* Class for recording an error within a JSON file. */
83 :
84 : class error
85 : {
86 : public:
87 20 : error (const location_map::range &r, char *msg)
88 20 : : m_range (r), m_msg (msg)
89 : {
90 : }
91 20 : ~error ()
92 : {
93 20 : free (m_msg);
94 20 : }
95 :
96 : const location_map::range &get_range () const { return m_range; }
97 20 : const char *get_msg () const { return m_msg; }
98 :
99 : private:
100 : location_map::range m_range;
101 : char *m_msg;
102 : };
103 :
104 : /* Class for the result of an operation: either a value or an error
105 : (or both null for the case of "successful nullptr").
106 : The types must be default-constructible. */
107 :
108 : template <typename ValueType, typename ErrorType>
109 196 : struct result
110 : {
111 268 : result (ValueType val) : m_val (std::move (val)), m_err () {}
112 28 : result (ErrorType err) : m_val (), m_err (std::move (err)) {}
113 :
114 : ValueType m_val;
115 : ErrorType m_err;
116 : };
117 :
118 : /* Typedef for the result of parsing JSON: ownership of either a
119 : json::value * or of a json::error *. */
120 : typedef result<std::unique_ptr<value>,
121 : std::unique_ptr<error>> parser_result_t;
122 :
123 : /* Functions for parsing JSON buffers. */
124 :
125 : extern parser_result_t
126 : parse_utf8_string (size_t length,
127 : const char *utf8_buf,
128 : bool allow_comments,
129 : location_map *out_loc_map);
130 : extern parser_result_t
131 : parse_utf8_string (const char *utf8,
132 : bool allow_comments,
133 : location_map *out_loc_map);
134 :
135 : } // namespace json
136 :
137 : #endif /* GCC_JSON_PARSING_H */
|