/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* A JSON pretty-printer class. */

// A typical JSON-writing library requires you to first build up a data
// structure that represents a JSON object and then serialize it (to file, or
// somewhere else). This approach makes for a clean API, but building the data
// structure takes up memory. Sometimes that isn't desirable, such as when the
// JSON data is produced for memory reporting.
//
// The JSONWriter class instead allows JSON data to be written out
// incrementally without building up large data structures.
//
// The API is slightly uglier than you would see in a typical JSON-writing
// library, but still fairly easy to use. It's possible to generate invalid
// JSON with JSONWriter, but typically the most basic testing will identify any
// such problems.
//
// Similarly, there are no RAII facilities for automatically closing objects
// and arrays. These would be nice if you are generating all your code within
// nested functions, but in other cases you'd have to maintain an explicit
// stack of RAII objects and manually unwind it, which is no better than just
// calling "end" functions. Furthermore, the consequences of forgetting to
// close an object or array are obvious and, again, will be identified via
// basic testing, unlike other cases where RAII is typically used (e.g. smart
// pointers) and the consequences of defects are more subtle.
//
// Importantly, the class does solve the two hard problems of JSON
// pretty-printing, which are (a) correctly escaping strings, and (b) adding
// appropriate indentation and commas between items.
//
// By default, every property is placed on its own line. However, it is
// possible to request that objects and arrays be placed entirely on a single
// line, which can reduce output size significantly in some cases.
//
// Strings used (for property names and string property values) are |const
// char*| throughout, and can be ASCII or UTF-8.
//
// EXAMPLE
// -------
// Assume that |MyWriteFunc| is a class that implements |JSONWriteFunc|. The
// following code:
//
//   JSONWriter w(MakeUnique<MyWriteFunc>());
//   w.Start();
//   {
//     w.NullProperty("null");
//     w.BoolProperty("bool", true);
//     w.IntProperty("int", 1);
//     w.StartArrayProperty("array");
//     {
//       w.StringElement("string");
//       w.StartObjectElement();
//       {
//         w.DoubleProperty("double", 3.4);
//         w.StartArrayProperty("single-line array", w.SingleLineStyle);
//         {
//           w.IntElement(1);
//           w.StartObjectElement();  // SingleLineStyle is inherited from
//           w.EndObjectElement();    //   above for this collection
//         }
//         w.EndArray();
//       }
//       w.EndObjectElement();
//     }
//     w.EndArrayProperty();
//   }
//   w.End();
//
// will produce pretty-printed output for the following JSON object:
//
//  {
//   "null": null,
//   "bool": true,
//   "int": 1,
//   "array": [
//    "string",
//    {
//     "double": 3.4,
//     "single-line array": [1, {}]
//    }
//   ]
//  }
//
// The nesting in the example code is obviously optional, but can aid
// readability.

#ifndef mozilla_JSONWriter_h
#define mozilla_JSONWriter_h

#include "mozilla/double-conversion.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/PodOperations.h"
#include "mozilla/Snprintf.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Vector.h"

#include <stdio.h>

namespace mozilla {

// A quasi-functor for JSONWriter. We don't use a true functor because that
// requires templatizing JSONWriter, and the templatization seeps to lots of
// places we don't want it to.
class JSONWriteFunc
{
public:
  virtual void Write(const char* aStr) = 0;
  virtual ~JSONWriteFunc() {}
};

// Ideally this would be within |EscapedString| but when compiling with GCC
// on Linux that caused link errors, whereas this formulation didn't.
namespace detail {
extern MFBT_DATA const char gTwoCharEscapes[256];
} // namespace detail

class JSONWriter
{
  // From http://www.ietf.org/rfc/rfc4627.txt:
  //
  //   "All Unicode characters may be placed within the quotation marks except
  //   for the characters that must be escaped: quotation mark, reverse
  //   solidus, and the control characters (U+0000 through U+001F)."
  //
  // This implementation uses two-char escape sequences where possible, namely:
  //
  //   \", \\, \b, \f, \n, \r, \t
  //
  // All control characters not in the above list are represented with a
  // six-char escape sequence, e.g. '\u000b' (a.k.a. '\v').
  //
  class EscapedString
  {
    // Only one of |mUnownedStr| and |mOwnedStr| are ever non-null. |mIsOwned|
    // indicates which one is in use. They're not within a union because that
    // wouldn't work with UniquePtr.
    bool mIsOwned;
    const char* mUnownedStr;
    UniquePtr<char[]> mOwnedStr;

    void SanityCheck() const
    {
      MOZ_ASSERT_IF( mIsOwned,  mOwnedStr.get() && !mUnownedStr);
      MOZ_ASSERT_IF(!mIsOwned, !mOwnedStr.get() &&  mUnownedStr);
    }

    static char hexDigitToAsciiChar(uint8_t u)
    {
      u = u & 0xf;
      return u < 10 ? '0' + u : 'a' + (u - 10);
    }

  public:
    explicit EscapedString(const char* aStr)
      : mUnownedStr(nullptr)
      , mOwnedStr(nullptr)
    {
      const char* p;

      // First, see if we need to modify the string.
      size_t nExtra = 0;
      p = aStr;
      while (true) {
        uint8_t u = *p;   // ensure it can't be interpreted as negative
        if (u == 0) {
          break;
        }
        if (detail::gTwoCharEscapes[u]) {
          nExtra += 1;
        } else if (u <= 0x1f) {
          nExtra += 5;
        }
        p++;
      }

      if (nExtra == 0) {
        // No escapes needed. Easy.
        mIsOwned = false;
        mUnownedStr = aStr;
        return;
      }

      // Escapes are needed. We'll create a new string.
      mIsOwned = true;
      size_t len = (p - aStr) + nExtra;
      mOwnedStr = MakeUnique<char[]>(len + 1);

      p = aStr;
      size_t i = 0;

      while (true) {
        uint8_t u = *p;   // ensure it can't be interpreted as negative
        if (u == 0) {
          mOwnedStr[i] = 0;
          break;
        }
        if (detail::gTwoCharEscapes[u]) {
          mOwnedStr[i++] = '\\';
          mOwnedStr[i++] = detail::gTwoCharEscapes[u];
        } else if (u <= 0x1f) {
          mOwnedStr[i++] = '\\';
          mOwnedStr[i++] = 'u';
          mOwnedStr[i++] = '0';
          mOwnedStr[i++] = '0';
          mOwnedStr[i++] = hexDigitToAsciiChar((u & 0x00f0) >> 4);
          mOwnedStr[i++] = hexDigitToAsciiChar(u & 0x000f);
        } else {
          mOwnedStr[i++] = u;
        }
        p++;
      }
    }

    ~EscapedString()
    {
      SanityCheck();
    }

    const char* get() const
    {
      SanityCheck();
      return mIsOwned ? mOwnedStr.get() : mUnownedStr;
    }
  };

public:
  // Collections (objects and arrays) are printed in a multi-line style by
  // default. This can be changed to a single-line style if SingleLineStyle is
  // specified. If a collection is printed in single-line style, every nested
  // collection within it is also printed in single-line style, even if
  // multi-line style is requested.
  enum CollectionStyle {
    MultiLineStyle,   // the default
    SingleLineStyle
  };

protected:
  const UniquePtr<JSONWriteFunc> mWriter;
  Vector<bool, 8> mNeedComma;     // do we need a comma at depth N?
  Vector<bool, 8> mNeedNewlines;  // do we need newlines at depth N?
  size_t mDepth;                  // the current nesting depth

  void Indent()
  {
    for (size_t i = 0; i < mDepth; i++) {
      mWriter->Write(" ");
    }
  }

  // Adds whatever is necessary (maybe a comma, and then a newline and
  // whitespace) to separate an item (property or element) from what's come
  // before.
  void Separator()
  {
    if (mNeedComma[mDepth]) {
      mWriter->Write(",");
    }
    if (mDepth > 0 && mNeedNewlines[mDepth]) {
      mWriter->Write("\n");
      Indent();
    } else if (mNeedComma[mDepth]) {
      mWriter->Write(" ");
    }
  }

  void PropertyNameAndColon(const char* aName)
  {
    EscapedString escapedName(aName);
    mWriter->Write("\"");
    mWriter->Write(escapedName.get());
    mWriter->Write("\": ");
  }

  void Scalar(const char* aMaybePropertyName, const char* aStringValue)
  {
    Separator();
    if (aMaybePropertyName) {
      PropertyNameAndColon(aMaybePropertyName);
    }
    mWriter->Write(aStringValue);
    mNeedComma[mDepth] = true;
  }

  void QuotedScalar(const char* aMaybePropertyName, const char* aStringValue)
  {
    Separator();
    if (aMaybePropertyName) {
      PropertyNameAndColon(aMaybePropertyName);
    }
    mWriter->Write("\"");
    mWriter->Write(aStringValue);
    mWriter->Write("\"");
    mNeedComma[mDepth] = true;
  }

  void NewVectorEntries()
  {
    // If these tiny allocations OOM we might as well just crash because we
    // must be in serious memory trouble.
    MOZ_RELEASE_ASSERT(mNeedComma.resizeUninitialized(mDepth + 1));
    MOZ_RELEASE_ASSERT(mNeedNewlines.resizeUninitialized(mDepth + 1));
    mNeedComma[mDepth] = false;
    mNeedNewlines[mDepth] = true;
  }

  void StartCollection(const char* aMaybePropertyName, const char* aStartChar,
                       CollectionStyle aStyle = MultiLineStyle)
  {
    Separator();
    if (aMaybePropertyName) {
      mWriter->Write("\"");
      mWriter->Write(aMaybePropertyName);
      mWriter->Write("\": ");
    }
    mWriter->Write(aStartChar);
    mNeedComma[mDepth] = true;
    mDepth++;
    NewVectorEntries();
    mNeedNewlines[mDepth] =
      mNeedNewlines[mDepth - 1] && aStyle == MultiLineStyle;
  }

  // Adds the whitespace and closing char necessary to end a collection.
  void EndCollection(const char* aEndChar)
  {
    if (mNeedNewlines[mDepth]) {
      mWriter->Write("\n");
      mDepth--;
      Indent();
    } else {
      mDepth--;
    }
    mWriter->Write(aEndChar);
  }

public:
  explicit JSONWriter(UniquePtr<JSONWriteFunc> aWriter)
    : mWriter(Move(aWriter))
    , mNeedComma()
    , mNeedNewlines()
    , mDepth(0)
  {
    NewVectorEntries();
  }

  // Returns the JSONWriteFunc passed in at creation, for temporary use. The
  // JSONWriter object still owns the JSONWriteFunc.
  JSONWriteFunc* WriteFunc() const { return mWriter.get(); }

  // For all the following functions, the "Prints:" comment indicates what the
  // basic output looks like. However, it doesn't indicate the whitespace and
  // trailing commas, which are automatically added as required.
  //
  // All property names and string properties are escaped as necessary.

  // Prints: {
  void Start(CollectionStyle aStyle = MultiLineStyle)
  {
    StartCollection(nullptr, "{", aStyle);
  }

  // Prints: }
  void End() { EndCollection("}\n"); }

  // Prints: "<aName>": null
  void NullProperty(const char* aName)
  {
    Scalar(aName, "null");
  }

  // Prints: null
  void NullElement() { NullProperty(nullptr); }

  // Prints: "<aName>": <aBool>
  void BoolProperty(const char* aName, bool aBool)
  {
    Scalar(aName, aBool ? "true" : "false");
  }

  // Prints: <aBool>
  void BoolElement(bool aBool) { BoolProperty(nullptr, aBool); }

  // Prints: "<aName>": <aInt>
  void IntProperty(const char* aName, int64_t aInt)
  {
    char buf[64];
    snprintf_literal(buf, "%" PRId64, aInt);
    Scalar(aName, buf);
  }

  // Prints: <aInt>
  void IntElement(int64_t aInt) { IntProperty(nullptr, aInt); }

  // Prints: "<aName>": <aDouble>
  void DoubleProperty(const char* aName, double aDouble)
  {
    static const size_t buflen = 64;
    char buf[buflen];
    const double_conversion::DoubleToStringConverter &converter =
      double_conversion::DoubleToStringConverter::EcmaScriptConverter();
    double_conversion::StringBuilder builder(buf, buflen);
    converter.ToShortest(aDouble, &builder);
    Scalar(aName, builder.Finalize());
  }

  // Prints: <aDouble>
  void DoubleElement(double aDouble) { DoubleProperty(nullptr, aDouble); }

  // Prints: "<aName>": "<aStr>"
  void StringProperty(const char* aName, const char* aStr)
  {
    EscapedString escapedStr(aStr);
    QuotedScalar(aName, escapedStr.get());
  }

  // Prints: "<aStr>"
  void StringElement(const char* aStr) { StringProperty(nullptr, aStr); }

  // Prints: "<aName>": [
  void StartArrayProperty(const char* aName,
                          CollectionStyle aStyle = MultiLineStyle)
  {
    StartCollection(aName, "[", aStyle);
  }

  // Prints: [
  void StartArrayElement(CollectionStyle aStyle = MultiLineStyle)
  {
    StartArrayProperty(nullptr, aStyle);
  }

  // Prints: ]
  void EndArray() { EndCollection("]"); }

  // Prints: "<aName>": {
  void StartObjectProperty(const char* aName,
                           CollectionStyle aStyle = MultiLineStyle)
  {
    StartCollection(aName, "{", aStyle);
  }

  // Prints: {
  void StartObjectElement(CollectionStyle aStyle = MultiLineStyle)
  {
    StartObjectProperty(nullptr, aStyle);
  }

  // Prints: }
  void EndObject() { EndCollection("}"); }
};

} // namespace mozilla

#endif /* mozilla_JSONWriter_h */

