text: /*
   * Imported from Douglas Crockford's reference implementation with minimum modification
   * to handle Int64.
   *
   * https://github.com/douglascrockford/JSON-js/blob/c98948ae1944a28e2e8ebc3717894e580aeaaa05/json_parse.js
   *
   * Original license header:
   *
   * json_parse.js
   * 2015-05-02
   * Public Domain.
   * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
   */
  
  
  /*jslint for */
  
  /*property
      at, b, call, charAt, f, fromCharCode, hasOwnProperty, message, n, name,
      prototype, push, r, t, text
  */
  
  var Int64 = require('node-int64');
  var Int64Util = require('./int64_util');
  
  var json_parse = module.exports = (function () {
      "use strict";
  
  // This is a function that can parse a JSON text, producing a JavaScript
  // data structure. It is a simple, recursive descent parser. It does not use
  // eval or regular expressions, so it can be used as a model for implementing
  // a JSON parser in other languages.
  
  // We are defining the function inside of another function to avoid creating
  // global variables.
  
      var at,     // The index of the current character
          ch,     // The current character
          escapee = {
              '"': '"',
              '\\': '\\',
              '/': '/',
              b: '\b',
              f: '\f',
              n: '\n',
              r: '\r',
              t: '\t'
          },
          text,
  
          error = function (m) {
  
  // Call error when something is wrong.
  
              throw new SyntaxError(m);
          },
  
          next = function (c) {
  
  // If a c parameter is provided, verify that it matches the current character.
  
              if (c && c !== ch) {
                  error("Expected '" + c + "' instead of '" + ch + "'");
              }
  
  // Get the next character. When there are no more characters,
  // return the empty string.
  
              ch = text.charAt(at);
              at += 1;
              return ch;
          },
  
          number = function () {
  
  // Parse a number value.
  
              var number,
                  string = '';
  
              if (ch === '-') {
                  string = '-';
                  next('-');
              }
              while (ch >= '0' && ch <= '9') {
                  string += ch;
                  next();
              }
              if (ch === '.') {
                  string += '.';
                  while (next() && ch >= '0' && ch <= '9') {
                      string += ch;
                  }
              }
              if (ch === 'e' || ch === 'E') {
                  string += ch;
                  next();
                  if (ch === '-' || ch === '+') {
                      string += ch;
                      next();
                  }
                  while (ch >= '0' && ch <= '9') {
                      string += ch;
                      next();
                  }
              }
              number = +string;
              if (!isFinite(number)) {
                  error("Bad number");
              } else if (number >= Int64.MAX_INT || number <= Int64.MIN_INT) {
                  // Return raw string for further process in TJSONProtocol
                  return string;
              } else {
                  return number;
              }
          },
  
          string = function () {
  
  // Parse a string value.
  
              var hex,
                  i,
                  string = '',
                  uffff;
  
  // When parsing for string values, we must look for " and \ characters.
  
              if (ch === '"') {
                  while (next()) {
                      if (ch === '"') {
                          next();
                          return string;
                      }
                      if (ch === '\\') {
                          next();
                          if (ch === 'u') {
                              uffff = 0;
                              for (i = 0; i < 4; i += 1) {
                                  hex = parseInt(next(), 16);
                                  if (!isFinite(hex)) {
                                      break;
                                  }
                                  uffff = uffff * 16 + hex;
                              }
                              string += String.fromCharCode(uffff);
                          } else if (typeof escapee[ch] === 'string') {
                              string += escapee[ch];
                          } else {
                              break;
                          }
                      } else {
                          string += ch;
                      }
                  }
              }
              error("Bad string");
          },
  
          white = function () {
  
  // Skip whitespace.
  
              while (ch && ch <= ' ') {
                  next();
              }
          },
  
          word = function () {
  
  // true, false, or null.
  
              switch (ch) {
              case 't':
                  next('t');
                  next('r');
                  next('u');
                  next('e');
                  return true;
              case 'f':
                  next('f');
                  next('a');
                  next('l');
                  next('s');
                  next('e');
                  return false;
              case 'n':
                  next('n');
                  next('u');
                  next('l');
                  next('l');
                  return null;
              }
              error("Unexpected '" + ch + "'");
          },
  
          value,  // Place holder for the value function.
  
          array = function () {
  
  // Parse an array value.
  
              var array = [];
  
              if (ch === '[') {
                  next('[');
                  white();
                  if (ch === ']') {
                      next(']');
                      return array;   // empty array
                  }
                  while (ch) {
                      array.push(value());
                      white();
                      if (ch === ']') {
                          next(']');
                          return array;
                      }
                      next(',');
                      white();
                  }
              }
              error("Bad array");
          },
  
          object = function () {
  
  // Parse an object value.
  
              var key,
                  object = {};
  
              if (ch === '{') {
                  next('{');
                  white();
                  if (ch === '}') {
                      next('}');
                      return object;   // empty object
                  }
                  while (ch) {
                      key = string();
                      white();
                      next(':');
                      if (Object.hasOwnProperty.call(object, key)) {
                          error('Duplicate key "' + key + '"');
                      }
                      object[key] = value();
                      white();
                      if (ch === '}') {
                          next('}');
                          return object;
                      }
                      next(',');
                      white();
                  }
              }
              error("Bad object");
          };
  
      value = function () {
  
  // Parse a JSON value. It could be an object, an array, a string, a number,
  // or a word.
  
          white();
          switch (ch) {
          case '{':
              return object();
          case '[':
              return array();
          case '"':
              return string();
          case '-':
              return number();
          default:
              return ch >= '0' && ch <= '9'
                  ? number()
                  : word();
          }
      };
  
  // Return the json_parse function. It will have access to all of the above
  // functions and variables.
  
      return function (source) {
          var result;
  
          text = source;
          at = 0;
          ch = ' ';
          result = value();
          white();
          if (ch) {
              error("Syntax error");
          }
  
          return result;
      };
  }());
  