+
+ # Use `append_json` to implement `to_json`.
+ #
+ # Therefore, one that redefine `append_json` may use the following
+ # redefinition to link `to_json` and `append_json`:
+ #
+ # ~~~nitish
+ # redef fun to_json do return to_json_by_append
+ # ~~~
+ #
+ # Note: This is not the default implementation of `to_json` in order to
+ # avoid cyclic references between `append_json` and `to_json` when none are
+ # implemented.
+ protected fun to_json_by_append: String do
+ var buffer = new RopeBuffer
+ append_json(buffer)
+ return buffer.write_to_string
+ end
+
+ # Append the JSON representation of `self` to the specified buffer.
+ #
+ # SEE: `to_json`
+ fun append_json(buffer: Buffer) do buffer.append(to_json)
+
+ # Pretty print JSON string.
+ #
+ # ~~~
+ # var obj = new JsonObject
+ # obj["foo"] = 1
+ # obj["bar"] = true
+ # var arr = new JsonArray
+ # arr.add 2
+ # arr.add false
+ # arr.add "baz"
+ # obj["baz"] = arr
+ # var res = obj.to_pretty_json
+ # var exp = """{
+ # \t"foo": 1,
+ # \t"bar": true,
+ # \t"baz": [2, false, "baz"]
+ # }\n"""
+ # assert res == exp
+ # ~~~
+ fun to_pretty_json: String do
+ var res = new FlatBuffer
+ pretty_json_visit(res, 0)
+ res.add '\n'
+ return res.write_to_string
+ end
+
+ private fun pretty_json_visit(buffer: FlatBuffer, indent: Int) is abstract