View Javadoc
1   /* Generated By:JavaCC: Do not edit this line. JsonParser.java */
2   /*
3    * #%L
4    * JsonParser.jj - mongodb-async-driver - Allanbank Consulting, Inc.
5    * %%
6    * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
7    * %%
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * You may obtain a copy of the License at
11   * 
12   *      http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   * #L%
20   */
21  package com.allanbank.mongodb.bson.json;
22  
23  import java.io.Reader;
24  import java.io.StringReader;
25  import java.text.SimpleDateFormat;
26  import java.util.Arrays;
27  import java.util.Date;
28  import java.util.List;
29  import java.util.TimeZone;
30  import java.util.concurrent.TimeUnit;
31  
32  import com.allanbank.mongodb.bson.Document;
33  import com.allanbank.mongodb.bson.Element;
34  import com.allanbank.mongodb.bson.builder.ArrayBuilder;
35  import com.allanbank.mongodb.bson.builder.BuilderFactory;
36  import com.allanbank.mongodb.bson.builder.DocumentBuilder;
37  import com.allanbank.mongodb.bson.element.ObjectId;
38  import com.allanbank.mongodb.error.JsonParseException;
39  import com.allanbank.mongodb.bson.io.EndianUtils;
40  import com.allanbank.mongodb.util.IOUtils;
41  
42  /**
43   * Parser for JSON documents.  This parser does not handle functions or complex expressions.
44   * <p>
45   * The intent of this parser is not to create a full capability JSON parser but 
46   * instead to provide a simplified parser that accepts most valid documents.  
47   * This parsers may also accept invalid documents/programs.
48   * </p>
49   * <p>
50   * This class is not currently part of the drivers API.  We intend to eventually provide some 
51   * basic JSON-->Document functionality but are looking for feedback from the community
52   * on that interface. 
53   * </p>
54   * <p>
55   * Users should not utilize this class directly.  Instead they should use the 
56   * {@link Json} static class.
57   * </p>
58   *
59   * @see <a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>
60   * @api.no This class is <b>NOT</b> part of the drivers API. This class may be
61   *         mutated in incompatible ways between any two releases of the driver.
62   * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
63   */
64  @SuppressWarnings({ "unused", "javadoc", "deprecated" })
65  /* package */ class JsonParser implements JsonParserConstants {
66      /** The default time zone. */
67      public static final TimeZone UTC = TimeZone.getTimeZone("UTC");
68  
69      /** The time formats accepted/parsed. */
70      private static final String[] DATE_FORMATS = new String[] {
71              "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ssZ",
72              "yyyy-MM-dd'T'HH:mmZ", "yyyy-MM-dd'T'HH:mm:ss.SSS",
73              "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd'T'HH:mm",
74              "yyyy-MM-dd HH:mm:ss.SSSZ", "yyyy-MM-dd HH:mm:ssZ",
75              "yyyy-MM-dd HH:mmZ", "yyyy-MM-dd HH:mm:ss.SSS",
76              "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd", };
77  
78      /**
79       * Create a new JsonParser.
80       */
81      public JsonParser() {
82          this(new StringReader(""));
83      }
84  
85      /**
86       * Parses the current source of data.
87       * 
88       * @param text
89       *            The text JSON to parse.
90       * @return The Document or list of documents parsed.
91       * @throws ParseException
92       *             On a failure to parse the JSON document.
93       */
94      public Object parse(final String text) throws ParseException {
95          ReInit(new StringReader(text));
96          return parse();
97      }
98  
99      /**
100      * Parses the current source of data.
101      * 
102      * @param reader
103      *            The text JSON to parse.
104      * @return The Document or list of documents parsed.
105      * @throws ParseException
106      *             On a failure to parse the JSON document.
107      */
108     public Object parse(final Reader reader) throws ParseException {
109         ReInit(reader);
110         return parse();
111     }
112 
113     /**
114      * Converts the Base64 string to a binary array.
115      * 
116      * @param base64Token
117      *            The Base64 encoded bytes.
118      * @return The decoded bytes.
119      * @throws JsonParseException
120      *             On a failure to decodee the binary.
121      */
122     private byte[] toBinaryFromBase64(final Token base64Token)
123             throws JsonParseException {
124         final String base64 = trimQuotes(base64Token.image);
125         try {
126             return IOUtils.base64ToBytes(base64);
127         }
128         catch (final IllegalArgumentException iae) {
129             throw new JsonParseException(iae.getMessage() + " (line "
130                     + base64Token.beginLine + ", column "
131                     + base64Token.beginColumn + ")", iae,
132                     base64Token.beginLine, base64Token.beginColumn);
133         }
134     }
135 
136     /**
137      * Converts the HEX string to a binary array.
138      * 
139      * @param hexToken
140      *            The HEX encoded bytes.
141      * @return The decoded bytes.
142      * @throws JsonParseException
143      *             On a failure to decodee the binary.
144      */
145     private byte[] toBinaryFromHex(final Token hexToken)
146             throws JsonParseException {
147         final String hex = trimQuotes(hexToken.image);
148         try {
149             return IOUtils.hexToBytes(hex);
150         }
151         catch (final IllegalArgumentException iae) {
152             throw new JsonParseException(iae.getMessage() + " (line "
153                     + hexToken.beginLine + ", column " + hexToken.beginColumn
154                     + ")", iae, hexToken.beginLine, hexToken.beginColumn);
155         }
156     }
157 
158     /**
159      * Parses the ISO date string into a long field.
160      * 
161      * @param timestampToken
162      *            The timestamp string.
163      * @return The Date for the time string.
164      * @throws JsonParseException
165      *             On a failure to parse the date string.
166      */
167     private Date toDate(final Token timestampToken) throws JsonParseException {
168 
169         Exception last = null;
170         final String timestamp = trimQuotes(timestampToken.image);
171         for (final String format : DATE_FORMATS) {
172             final SimpleDateFormat f = new SimpleDateFormat(format);
173             f.setTimeZone(UTC);
174             try {
175                 return f.parse(timestamp);
176             }
177             catch (final java.text.ParseException pe) {
178                 // Ignore. Try the next.
179                 last = pe;
180             }
181         }
182 
183         throw new JsonParseException("Could not parse the time string '"
184                 + timestamp + "' @ line " + timestampToken.beginLine
185                 + ", column " + timestampToken.beginColumn + ".", last,
186                 timestampToken.beginLine, timestampToken.beginColumn);
187     }
188 
189     /**
190      * Parses the ISO date string into a long field.
191      * 
192      * @param timestampToken
193      *            The timestamp string.
194      * @return The Date for the time string.
195      * @throws JsonParseException
196      *             On a failure to parse the date string.
197      */
198     private Date toDateFromEpoch(final Token timestampToken)
199             throws JsonParseException {
200 
201         try {
202             return new Date(Long.parseLong(timestampToken.image));
203         }
204         catch (NumberFormatException nfe) {
205             throw new JsonParseException("Could not parse the time milliseconds '"
206                     + timestampToken.image + "' @ line " + timestampToken.beginLine
207                     + ", column " + timestampToken.beginColumn + ".", nfe,
208                     timestampToken.beginLine, timestampToken.beginColumn);
209         }
210     }
211 
212     /**
213      * Converts the HEX string to an integer.
214      * 
215      * @param hexToken
216      *            The HEX encoded bytes.
217      * @return The decoded integer.
218      * @throws JsonParseException
219      *             On a failure to decodee the integer.
220      */
221     private int toIntFromHex(final Token hexToken) throws JsonParseException {
222         String hex = trimQuotes(hexToken.image);
223         if (hex.startsWith("0x") || hex.startsWith("0X")) {
224             hex = hex.substring(2);
225         }
226 
227         try {
228             return Integer.parseInt(hex, 16);
229         }
230         catch (final NumberFormatException nfe) {
231             throw new JsonParseException(nfe.getMessage() + " (line "
232                     + hexToken.beginLine + ", column " + hexToken.beginColumn
233                     + ")", nfe, hexToken.beginLine, hexToken.beginColumn);
234         }
235     }
236 
237     /**
238      * Converts the timestamp and increment into a MongoTimestamp Long value..
239      * 
240      * @param timestampToken
241      *            The Mongo timestamp value (seconds since UNIX Epoch).
242      * @param incrementToken
243      *            The increment for the Mongo Timestamp.
244      * @return The MongoTimestamp long value.
245      * @throws JsonParseException
246      *             On a failure to decode the timestamp integers.
247      */
248     private long toMongoTimestamp(final Token timestampToken,
249             final Token incrementToken) throws JsonParseException {
250         long value = 0;
251 
252         final String timestamp = trimQuotes(timestampToken.image);
253         final String increment = trimQuotes(incrementToken.image);
254         try {
255             final long timePortion = Long.parseLong(timestamp) & 0xFFFFFFFFL;
256 
257             // Time is specified in milliseconds but only store seconds
258             // so we truncate the time to milliseconds.
259             value = TimeUnit.MILLISECONDS.toSeconds(timePortion);
260             value <<= Integer.SIZE;
261             value += (Long.parseLong(increment) & 0xFFFFFFFFL);
262         }
263         catch (final NumberFormatException nfe) {
264             throw new JsonParseException(nfe.getMessage() + " (line "
265                     + timestampToken.beginLine + ", column "
266                     + timestampToken.beginColumn + ")", nfe,
267                     timestampToken.beginLine, timestampToken.beginColumn);
268         }
269         return value;
270     }
271 
272     /**
273      * Tries to create a Mongo Timestamp from the four tokens in a document that
274      * looks like:
275      * <code>{ $timestamp : { &lt;token1&gt; : &lt;token2&gt; , &lt;token3&gt; : &lt;token4&gt; } }</code>
276      * The second and fourth tokens should be integers. The first and third
277      * should be either 't' or 'i'.
278      * 
279      * @param t1
280      *            The first token in the document.
281      * @param t2
282      *            The second token in the document, should be an integer.
283      * @param t3
284      *            The third token in the document.
285      * @param t4
286      *            The fourth token in the document, should be an integer.
287      */
288     private long toMongoTimestamp(Token t1, Token t2, Token t3, Token t4) {
289         try {
290             long t2Int = Long.parseLong(trimQuotes(t2.image));
291             long t4Int = Long.parseLong(trimQuotes(t4.image));
292 
293             String t1Str = trimQuotes(t1.image);
294             String t3Str = trimQuotes(t3.image);
295 
296             long value = 0;
297             if ("t".equals(t1Str) && "i".equals(t3Str)) {
298                 // Time is specified in milliseconds but only store seconds
299                 // so we truncate the time to milliseconds.
300                 value = TimeUnit.MILLISECONDS.toSeconds(t2Int);
301                 value <<= Integer.SIZE;
302                 value += (t4Int & 0xFFFFFFFFL);
303             }
304             else if ("t".equals(t3Str) && "i".equals(t1Str)) {
305                 value = TimeUnit.MILLISECONDS.toSeconds(t4Int);
306                 value <<= Integer.SIZE;
307                 value += (t2Int & 0xFFFFFFFFL);
308             }
309             else {
310                 throw new JsonParseException(
311                         "Invalid MongoDB Timestamp document at line "
312                                 + t1.beginLine + ", column " + t1.beginColumn
313                                 + ":", t1.beginLine, t1.beginColumn);
314             }
315             return value;
316         }
317         catch (NumberFormatException nfe) {
318             throw new JsonParseException(nfe.getMessage() + " (line "
319                     + t1.beginLine + ", column " + t1.beginColumn + ")", nfe,
320                     t1.beginLine, t1.beginColumn);
321         }
322     }
323 
324     /**
325      * Creates a ObjectId from the hex binary representation.
326      * 
327      * @param hexBytesToken
328      *            The hex bytes for the ObjectId.
329      * @return The ObjectId.
330      * @throws JsonParseException
331      *             On a failure to decode the hex binary into an ObjectId.
332      */
333     private ObjectId toObjectId(final Token hexBytesToken)
334             throws JsonParseException {
335         int timestamp = 0;
336         long machineId = 0;
337 
338         final String hexBytes = trimQuotes(hexBytesToken.image);
339         try {
340             return new ObjectId(hexBytes);
341         }
342         catch (final IllegalArgumentException iae) {
343             throw new JsonParseException(iae.getMessage() + " (line "
344                     + hexBytesToken.beginLine + ", column "
345                     + hexBytesToken.beginColumn + ")", iae,
346                     hexBytesToken.beginLine, hexBytesToken.beginColumn);
347         }
348     }
349 
350     /**
351      * Trims the quotes from the string.
352      * 
353      * @param string
354      *            The string to trim the quotes from.
355      * @return The string without the quotes.
356      */
357     private String trimQuotes(final String string) {
358         if (!string.isEmpty()) {
359             final int length = string.length();
360             final char first = string.charAt(0);
361             final char last = string.charAt(length - 1);
362             if ((first == last) && ((first == '"') || (first == '\u005c''))) {
363                 return string.substring(1, length - 1);
364             }
365         }
366 
367         return string;
368     }
369 
370   final protected Object parse() throws ParseException {
371     Object result = null;
372     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
373     case TOKEN_OPEN_BRACE:
374       result = document(null);
375       break;
376     case TOKEN_OPEN_BRACKET:
377       result = array(null);
378       break;
379     default:
380       jj_la1[0] = jj_gen;
381       jj_consume_token(-1);
382       throw new ParseException();
383     }
384         {if (true) return result;}
385     throw new Error("Missing return statement in function");
386   }
387 
388   final private Document document(DocumentBuilder builder) throws ParseException {
389     DocumentBuilder b = builder;
390     if( b == null ) {
391         b = BuilderFactory.start();
392     }
393     jj_consume_token(TOKEN_OPEN_BRACE);
394     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
395     case STRING_LITERAL:
396     case HEX_DIGIT:
397     case IDENTIFIER_NAME:
398       members(b);
399       break;
400     default:
401       jj_la1[1] = jj_gen;
402       ;
403     }
404     jj_consume_token(TOKEN_CLOSE_BRACE);
405         {if (true) return b.build();}
406     throw new Error("Missing return statement in function");
407   }
408 
409   final private List<Element> array(ArrayBuilder builder) throws ParseException {
410     ArrayBuilder b = builder;
411     if( b == null ) {
412         b = BuilderFactory.startArray();
413     }
414     jj_consume_token(TOKEN_OPEN_BRACKET);
415     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
416     case TOKEN_TRUE:
417     case TOKEN_FALSE:
418     case TOKEN_NULL:
419     case TOKEN_OPEN_BRACE:
420     case TOKEN_OPEN_BRACKET:
421     case DOUBLE:
422     case INTEGER:
423     case STRING_LITERAL:
424     case HEX_DIGIT:
425     case TOKEN_BINDATA:
426     case TOKEN_HEXDATA:
427     case TOKEN_ISODATE:
428     case TOKEN_NUMBERLONG:
429     case TOKEN_OBJECTID:
430     case TOKEN_TIMESTAMP:
431     case TOKEN_MAXKEY:
432     case TOKEN_MINKEY:
433     case TOKEN_DB_POINTER:
434     case IDENTIFIER_NAME:
435       elements(b);
436       break;
437     default:
438       jj_la1[2] = jj_gen;
439       ;
440     }
441     jj_consume_token(TOKEN_CLOSE_BRACKET);
442         {if (true) return Arrays.asList(b.build());}
443     throw new Error("Missing return statement in function");
444   }
445 
446   final private void members(DocumentBuilder builder) throws ParseException {
447     pair(builder);
448     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
449     case TOKEN_COMMA:
450       jj_consume_token(TOKEN_COMMA);
451       members(builder);
452       break;
453     default:
454       jj_la1[3] = jj_gen;
455       ;
456     }
457   }
458 
459   final private void pair(DocumentBuilder builder) throws ParseException {
460     Token nameToken = null;
461     String name = null;
462     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
463     case IDENTIFIER_NAME:
464       nameToken = jj_consume_token(IDENTIFIER_NAME);
465                                           name = nameToken.image;
466       break;
467     case STRING_LITERAL:
468       nameToken = jj_consume_token(STRING_LITERAL);
469                                          name = trimQuotes( nameToken.image );
470       break;
471     case HEX_DIGIT:
472       nameToken = jj_consume_token(HEX_DIGIT);
473                                     name = nameToken.image;
474       break;
475     default:
476       jj_la1[4] = jj_gen;
477       jj_consume_token(-1);
478       throw new ParseException();
479     }
480     jj_consume_token(TOKEN_COLON);
481     documentValue(name, builder);
482   }
483 
484   final private void elements(ArrayBuilder builder) throws ParseException {
485     arrayValue(builder);
486     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
487     case TOKEN_COMMA:
488       jj_consume_token(TOKEN_COMMA);
489       elements(builder);
490       break;
491     default:
492       jj_la1[5] = jj_gen;
493       ;
494     }
495   }
496 
497   final private void arrayValue(ArrayBuilder builder) throws ParseException {
498     Token t1 = null;
499     Token t2 = null;
500     Token t3 = null;
501     Token t4 = null;
502     if (jj_2_1(2)) {
503       jj_consume_token(TOKEN_OPEN_BRACE);
504       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
505       case TOKEN_BINARY:
506         jj_consume_token(TOKEN_BINARY);
507         jj_consume_token(TOKEN_COLON);
508         t2 = jj_consume_token(STRING_LITERAL);
509         jj_consume_token(TOKEN_COMMA);
510         jj_consume_token(TOKEN_TYPE);
511         jj_consume_token(TOKEN_COLON);
512         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
513         case INTEGER:
514           t1 = jj_consume_token(INTEGER);
515           break;
516         case STRING_LITERAL:
517           t3 = jj_consume_token(STRING_LITERAL);
518           break;
519         default:
520           jj_la1[6] = jj_gen;
521           jj_consume_token(-1);
522           throw new ParseException();
523         }
524               if( t1 != null ) {
525                   builder.addBinary( (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
526               } else {
527                   builder.addBinary( (byte) toIntFromHex(t3), toBinaryFromBase64(t2) );
528               }
529         break;
530       case TOKEN_TYPE:
531         jj_consume_token(TOKEN_TYPE);
532         jj_consume_token(TOKEN_COLON);
533         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
534         case INTEGER:
535           t1 = jj_consume_token(INTEGER);
536           break;
537         case STRING_LITERAL:
538           t3 = jj_consume_token(STRING_LITERAL);
539           break;
540         default:
541           jj_la1[7] = jj_gen;
542           jj_consume_token(-1);
543           throw new ParseException();
544         }
545         jj_consume_token(TOKEN_COMMA);
546         jj_consume_token(TOKEN_BINARY);
547         jj_consume_token(TOKEN_COLON);
548         t2 = jj_consume_token(STRING_LITERAL);
549               if( t1 != null ) {
550                   builder.addBinary( (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
551               } else {
552                   builder.addBinary( (byte) toIntFromHex(t3), toBinaryFromBase64(t2) );
553               }
554         break;
555       case TOKEN_DATE:
556         jj_consume_token(TOKEN_DATE);
557         jj_consume_token(TOKEN_COLON);
558         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
559         case INTEGER:
560           t1 = jj_consume_token(INTEGER);
561           break;
562         case STRING_LITERAL:
563           t2 = jj_consume_token(STRING_LITERAL);
564           break;
565         default:
566           jj_la1[8] = jj_gen;
567           jj_consume_token(-1);
568           throw new ParseException();
569         }
570               if ( t1 != null ) {
571                   builder.add( toDateFromEpoch(t1) );
572               } else {
573                   builder.add( toDate(t2) );
574               }
575         break;
576       case TOKEN_TS:
577         jj_consume_token(TOKEN_TS);
578         jj_consume_token(TOKEN_COLON);
579         jj_consume_token(TOKEN_OPEN_BRACE);
580         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
581         case IDENTIFIER_NAME:
582           t1 = jj_consume_token(IDENTIFIER_NAME);
583           break;
584         case STRING_LITERAL:
585           t1 = jj_consume_token(STRING_LITERAL);
586           break;
587         default:
588           jj_la1[9] = jj_gen;
589           jj_consume_token(-1);
590           throw new ParseException();
591         }
592         jj_consume_token(TOKEN_COLON);
593         t2 = jj_consume_token(INTEGER);
594         jj_consume_token(TOKEN_COMMA);
595         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
596         case IDENTIFIER_NAME:
597           t3 = jj_consume_token(IDENTIFIER_NAME);
598           break;
599         case STRING_LITERAL:
600           t3 = jj_consume_token(STRING_LITERAL);
601           break;
602         default:
603           jj_la1[10] = jj_gen;
604           jj_consume_token(-1);
605           throw new ParseException();
606         }
607         jj_consume_token(TOKEN_COLON);
608         t4 = jj_consume_token(INTEGER);
609         jj_consume_token(TOKEN_CLOSE_BRACE);
610               builder.addMongoTimestamp( toMongoTimestamp(t1, t2, t3, t4) );
611         break;
612       case TOKEN_REGEX:
613         jj_consume_token(TOKEN_REGEX);
614         jj_consume_token(TOKEN_COLON);
615         t1 = jj_consume_token(STRING_LITERAL);
616         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
617         case TOKEN_COMMA:
618           jj_consume_token(TOKEN_COMMA);
619           jj_consume_token(TOKEN_OPTIONS);
620           jj_consume_token(TOKEN_COLON);
621           t2 = jj_consume_token(STRING_LITERAL);
622           break;
623         default:
624           jj_la1[11] = jj_gen;
625           ;
626         }
627               if ( t2 != null ) {
628                   builder.addRegularExpression( trimQuotes(t1.image), trimQuotes(t2.image) );
629               } else {
630                   builder.addRegularExpression( trimQuotes(t1.image), "" );
631               }
632         break;
633       case TOKEN_OPTIONS:
634         jj_consume_token(TOKEN_OPTIONS);
635         jj_consume_token(TOKEN_COLON);
636         t2 = jj_consume_token(STRING_LITERAL);
637         jj_consume_token(TOKEN_COMMA);
638         jj_consume_token(TOKEN_REGEX);
639         jj_consume_token(TOKEN_COLON);
640         t1 = jj_consume_token(STRING_LITERAL);
641               builder.addRegularExpression( trimQuotes(t1.image), trimQuotes(t2.image) );
642         break;
643       case TOKEN_OID:
644         jj_consume_token(TOKEN_OID);
645         jj_consume_token(TOKEN_COLON);
646         t1 = jj_consume_token(STRING_LITERAL);
647               builder.addObjectId( toObjectId(t1) );
648         break;
649       case TOKEN_MAX:
650         jj_consume_token(TOKEN_MAX);
651         jj_consume_token(TOKEN_COLON);
652         jj_consume_token(INTEGER);
653              builder.addMaxKey();
654         break;
655       case TOKEN_MIN:
656         jj_consume_token(TOKEN_MIN);
657         jj_consume_token(TOKEN_COLON);
658         jj_consume_token(INTEGER);
659              builder.addMinKey();
660         break;
661       default:
662         jj_la1[12] = jj_gen;
663         jj_consume_token(-1);
664         throw new ParseException();
665       }
666       jj_consume_token(TOKEN_CLOSE_BRACE);
667     } else {
668       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
669       case TOKEN_OPEN_BRACE:
670         document(builder.push());
671         break;
672       case TOKEN_OPEN_BRACKET:
673         array(builder.pushArray());
674         break;
675       case HEX_DIGIT:
676         t1 = jj_consume_token(HEX_DIGIT);
677                              builder.addSymbol(t1.image);
678         break;
679       case IDENTIFIER_NAME:
680         t1 = jj_consume_token(IDENTIFIER_NAME);
681                                    builder.addSymbol(t1.image);
682         break;
683       case STRING_LITERAL:
684         t1 = jj_consume_token(STRING_LITERAL);
685                                   builder.addString(trimQuotes(t1.image));
686         break;
687       case DOUBLE:
688         t1 = jj_consume_token(DOUBLE);
689                           builder.addDouble(Double.parseDouble(t1.image));
690         break;
691       case INTEGER:
692         t1 = jj_consume_token(INTEGER);
693              // Experimentally determine the size of the integer.
694              long value = Long.parseLong(t1.image);
695              if( (Integer.MIN_VALUE <= value) && (value <= Integer.MAX_VALUE) ) {
696                 builder.addInteger((int) value);
697              } else {
698                 builder.addLong(value);
699              }
700         break;
701       case TOKEN_TRUE:
702         jj_consume_token(TOKEN_TRUE);
703                          builder.addBoolean(true);
704         break;
705       case TOKEN_FALSE:
706         jj_consume_token(TOKEN_FALSE);
707                           builder.addBoolean(false);
708         break;
709       case TOKEN_NULL:
710         jj_consume_token(TOKEN_NULL);
711                          builder.addNull();
712         break;
713       case TOKEN_BINDATA:
714         jj_consume_token(TOKEN_BINDATA);
715         jj_consume_token(69);
716         t1 = jj_consume_token(INTEGER);
717         jj_consume_token(TOKEN_COMMA);
718         t2 = jj_consume_token(STRING_LITERAL);
719         jj_consume_token(70);
720              builder.addBinary( (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
721         break;
722       case TOKEN_HEXDATA:
723         jj_consume_token(TOKEN_HEXDATA);
724         jj_consume_token(69);
725         t1 = jj_consume_token(INTEGER);
726         jj_consume_token(TOKEN_COMMA);
727         t2 = jj_consume_token(STRING_LITERAL);
728         jj_consume_token(70);
729              builder.addBinary( (byte) Integer.parseInt(t1.image), toBinaryFromHex(t2) );
730         break;
731       case TOKEN_ISODATE:
732         jj_consume_token(TOKEN_ISODATE);
733         jj_consume_token(69);
734         t1 = jj_consume_token(STRING_LITERAL);
735         jj_consume_token(70);
736              builder.add( toDate(t1) );
737         break;
738       case TOKEN_NUMBERLONG:
739         jj_consume_token(TOKEN_NUMBERLONG);
740         jj_consume_token(69);
741         t1 = jj_consume_token(STRING_LITERAL);
742         jj_consume_token(70);
743              builder.addLong(Long.parseLong(trimQuotes(t1.image)));
744         break;
745       case TOKEN_OBJECTID:
746         jj_consume_token(TOKEN_OBJECTID);
747         jj_consume_token(69);
748         t1 = jj_consume_token(STRING_LITERAL);
749         jj_consume_token(70);
750              builder.addObjectId( toObjectId(t1) );
751         break;
752       case TOKEN_TIMESTAMP:
753         jj_consume_token(TOKEN_TIMESTAMP);
754         jj_consume_token(69);
755         t1 = jj_consume_token(INTEGER);
756         jj_consume_token(TOKEN_COMMA);
757         t2 = jj_consume_token(INTEGER);
758         jj_consume_token(70);
759              builder.addMongoTimestamp( toMongoTimestamp(t1, t2) );
760         break;
761       case TOKEN_MAXKEY:
762         jj_consume_token(TOKEN_MAXKEY);
763         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
764         case 69:
765           jj_consume_token(69);
766           jj_consume_token(70);
767           break;
768         default:
769           jj_la1[13] = jj_gen;
770           ;
771         }
772              builder.addMaxKey();
773         break;
774       case TOKEN_MINKEY:
775         jj_consume_token(TOKEN_MINKEY);
776         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
777         case 69:
778           jj_consume_token(69);
779           jj_consume_token(70);
780           break;
781         default:
782           jj_la1[14] = jj_gen;
783           ;
784         }
785              builder.addMinKey();
786         break;
787       case TOKEN_DB_POINTER:
788         jj_consume_token(TOKEN_DB_POINTER);
789         jj_consume_token(69);
790         t1 = jj_consume_token(STRING_LITERAL);
791         jj_consume_token(TOKEN_COMMA);
792         t2 = jj_consume_token(STRING_LITERAL);
793         jj_consume_token(TOKEN_COMMA);
794         jj_consume_token(TOKEN_OBJECTID);
795         jj_consume_token(69);
796         t3 = jj_consume_token(STRING_LITERAL);
797         jj_consume_token(70);
798         jj_consume_token(70);
799              builder.addDBPointer(trimQuotes(t1.image), trimQuotes(t2.image), toObjectId(t3));
800         break;
801       default:
802         jj_la1[15] = jj_gen;
803         jj_consume_token(-1);
804         throw new ParseException();
805       }
806     }
807   }
808 
809   final private void documentValue(String name, DocumentBuilder builder) throws ParseException {
810     Token t1 = null;
811     Token t2 = null;
812     Token t3 = null;
813     Token t4 = null;
814     if (jj_2_2(2)) {
815       jj_consume_token(TOKEN_OPEN_BRACE);
816       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
817       case TOKEN_BINARY:
818         jj_consume_token(TOKEN_BINARY);
819         jj_consume_token(TOKEN_COLON);
820         t2 = jj_consume_token(STRING_LITERAL);
821         jj_consume_token(TOKEN_COMMA);
822         jj_consume_token(TOKEN_TYPE);
823         jj_consume_token(TOKEN_COLON);
824         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
825         case INTEGER:
826           t1 = jj_consume_token(INTEGER);
827           break;
828         case STRING_LITERAL:
829           t3 = jj_consume_token(STRING_LITERAL);
830           break;
831         default:
832           jj_la1[16] = jj_gen;
833           jj_consume_token(-1);
834           throw new ParseException();
835         }
836               if( t1 != null ) {
837                   builder.addBinary( name, (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
838               } else {
839                   builder.addBinary( name, (byte) toIntFromHex(t3), toBinaryFromBase64(t2) );
840               }
841         break;
842       case TOKEN_TYPE:
843         jj_consume_token(TOKEN_TYPE);
844         jj_consume_token(TOKEN_COLON);
845         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
846         case INTEGER:
847           t1 = jj_consume_token(INTEGER);
848           break;
849         case STRING_LITERAL:
850           t3 = jj_consume_token(STRING_LITERAL);
851           break;
852         default:
853           jj_la1[17] = jj_gen;
854           jj_consume_token(-1);
855           throw new ParseException();
856         }
857         jj_consume_token(TOKEN_COMMA);
858         jj_consume_token(TOKEN_BINARY);
859         jj_consume_token(TOKEN_COLON);
860         t2 = jj_consume_token(STRING_LITERAL);
861               if( t1 != null ) {
862                   builder.addBinary( name, (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
863               } else {
864                   builder.addBinary( name, (byte) toIntFromHex(t3), toBinaryFromBase64(t2) );
865               }
866         break;
867       case TOKEN_DATE:
868         jj_consume_token(TOKEN_DATE);
869         jj_consume_token(TOKEN_COLON);
870         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
871         case INTEGER:
872           t1 = jj_consume_token(INTEGER);
873           break;
874         case STRING_LITERAL:
875           t2 = jj_consume_token(STRING_LITERAL);
876           break;
877         default:
878           jj_la1[18] = jj_gen;
879           jj_consume_token(-1);
880           throw new ParseException();
881         }
882               if ( t1 != null ) {
883                   builder.add( name, toDateFromEpoch(t1) );
884               } else {
885                   builder.add( name, toDate(t2) );
886               }
887         break;
888       case TOKEN_TS:
889         jj_consume_token(TOKEN_TS);
890         jj_consume_token(TOKEN_COLON);
891         jj_consume_token(TOKEN_OPEN_BRACE);
892         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
893         case IDENTIFIER_NAME:
894           t1 = jj_consume_token(IDENTIFIER_NAME);
895           break;
896         case STRING_LITERAL:
897           t1 = jj_consume_token(STRING_LITERAL);
898           break;
899         default:
900           jj_la1[19] = jj_gen;
901           jj_consume_token(-1);
902           throw new ParseException();
903         }
904         jj_consume_token(TOKEN_COLON);
905         t2 = jj_consume_token(INTEGER);
906         jj_consume_token(TOKEN_COMMA);
907         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
908         case IDENTIFIER_NAME:
909           t3 = jj_consume_token(IDENTIFIER_NAME);
910           break;
911         case STRING_LITERAL:
912           t3 = jj_consume_token(STRING_LITERAL);
913           break;
914         default:
915           jj_la1[20] = jj_gen;
916           jj_consume_token(-1);
917           throw new ParseException();
918         }
919         jj_consume_token(TOKEN_COLON);
920         t4 = jj_consume_token(INTEGER);
921         jj_consume_token(TOKEN_CLOSE_BRACE);
922               builder.addMongoTimestamp( name, toMongoTimestamp(t1, t2, t3, t4) );
923         break;
924       case TOKEN_REGEX:
925         jj_consume_token(TOKEN_REGEX);
926         jj_consume_token(TOKEN_COLON);
927         t1 = jj_consume_token(STRING_LITERAL);
928         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
929         case TOKEN_COMMA:
930           jj_consume_token(TOKEN_COMMA);
931           jj_consume_token(TOKEN_OPTIONS);
932           jj_consume_token(TOKEN_COLON);
933           t2 = jj_consume_token(STRING_LITERAL);
934           break;
935         default:
936           jj_la1[21] = jj_gen;
937           ;
938         }
939               if ( t2 != null ) {
940                   builder.addRegularExpression( name, trimQuotes(t1.image), trimQuotes(t2.image) );
941               } else {
942                   builder.addRegularExpression( name, trimQuotes(t1.image), "" );
943               }
944         break;
945       case TOKEN_OPTIONS:
946         jj_consume_token(TOKEN_OPTIONS);
947         jj_consume_token(TOKEN_COLON);
948         t2 = jj_consume_token(STRING_LITERAL);
949         jj_consume_token(TOKEN_COMMA);
950         jj_consume_token(TOKEN_REGEX);
951         jj_consume_token(TOKEN_COLON);
952         t1 = jj_consume_token(STRING_LITERAL);
953               builder.addRegularExpression( name, trimQuotes(t1.image), trimQuotes(t2.image) );
954         break;
955       case TOKEN_OID:
956         jj_consume_token(TOKEN_OID);
957         jj_consume_token(TOKEN_COLON);
958         t1 = jj_consume_token(STRING_LITERAL);
959               builder.addObjectId( name, toObjectId(t1) );
960         break;
961       case TOKEN_MAX:
962         jj_consume_token(TOKEN_MAX);
963         jj_consume_token(TOKEN_COLON);
964         jj_consume_token(INTEGER);
965              builder.addMaxKey(name);
966         break;
967       case TOKEN_MIN:
968         jj_consume_token(TOKEN_MIN);
969         jj_consume_token(TOKEN_COLON);
970         jj_consume_token(INTEGER);
971              builder.addMinKey(name);
972         break;
973       default:
974         jj_la1[22] = jj_gen;
975         jj_consume_token(-1);
976         throw new ParseException();
977       }
978       jj_consume_token(TOKEN_CLOSE_BRACE);
979     } else {
980       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
981       case TOKEN_OPEN_BRACE:
982         document(builder.push(name));
983         break;
984       case TOKEN_OPEN_BRACKET:
985         array(builder.pushArray(name));
986         break;
987       case HEX_DIGIT:
988         t1 = jj_consume_token(HEX_DIGIT);
989                              builder.addSymbol(name, t1.image);
990         break;
991       case IDENTIFIER_NAME:
992         t1 = jj_consume_token(IDENTIFIER_NAME);
993                                    builder.addSymbol(name, t1.image);
994         break;
995       case STRING_LITERAL:
996         t1 = jj_consume_token(STRING_LITERAL);
997                                   builder.addString(name, trimQuotes(t1.image));
998         break;
999       case DOUBLE:
1000         t1 = jj_consume_token(DOUBLE);
1001                           builder.addDouble(name, Double.parseDouble(t1.image));
1002         break;
1003       case INTEGER:
1004         t1 = jj_consume_token(INTEGER);
1005              // Experimentally determine the size of the integer.
1006              long value = Long.parseLong(t1.image);
1007              if( (Integer.MIN_VALUE <= value) && (value <= Integer.MAX_VALUE) ) {
1008                 builder.addInteger(name, (int) value);
1009              } else {
1010                 builder.addLong(name, value);
1011              }
1012         break;
1013       case TOKEN_TRUE:
1014         jj_consume_token(TOKEN_TRUE);
1015                          builder.addBoolean(name, true);
1016         break;
1017       case TOKEN_FALSE:
1018         jj_consume_token(TOKEN_FALSE);
1019                           builder.addBoolean(name, false);
1020         break;
1021       case TOKEN_NULL:
1022         jj_consume_token(TOKEN_NULL);
1023                          builder.addNull(name);
1024         break;
1025       case TOKEN_BINDATA:
1026         jj_consume_token(TOKEN_BINDATA);
1027         jj_consume_token(69);
1028         t1 = jj_consume_token(INTEGER);
1029         jj_consume_token(TOKEN_COMMA);
1030         t2 = jj_consume_token(STRING_LITERAL);
1031         jj_consume_token(70);
1032              builder.addBinary( name, (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
1033         break;
1034       case TOKEN_HEXDATA:
1035         jj_consume_token(TOKEN_HEXDATA);
1036         jj_consume_token(69);
1037         t1 = jj_consume_token(INTEGER);
1038         jj_consume_token(TOKEN_COMMA);
1039         t2 = jj_consume_token(STRING_LITERAL);
1040         jj_consume_token(70);
1041              builder.addBinary( name, (byte) Integer.parseInt(t1.image), toBinaryFromHex(t2) );
1042         break;
1043       case TOKEN_ISODATE:
1044         jj_consume_token(TOKEN_ISODATE);
1045         jj_consume_token(69);
1046         t1 = jj_consume_token(STRING_LITERAL);
1047         jj_consume_token(70);
1048              builder.add( name, toDate(t1) );
1049         break;
1050       case TOKEN_NUMBERLONG:
1051         jj_consume_token(TOKEN_NUMBERLONG);
1052         jj_consume_token(69);
1053         t1 = jj_consume_token(STRING_LITERAL);
1054         jj_consume_token(70);
1055              builder.addLong(name, Long.parseLong(trimQuotes(t1.image)));
1056         break;
1057       case TOKEN_OBJECTID:
1058         jj_consume_token(TOKEN_OBJECTID);
1059         jj_consume_token(69);
1060         t1 = jj_consume_token(STRING_LITERAL);
1061         jj_consume_token(70);
1062              builder.addObjectId( name, toObjectId(t1) );
1063         break;
1064       case TOKEN_TIMESTAMP:
1065         jj_consume_token(TOKEN_TIMESTAMP);
1066         jj_consume_token(69);
1067         t1 = jj_consume_token(INTEGER);
1068         jj_consume_token(TOKEN_COMMA);
1069         t2 = jj_consume_token(INTEGER);
1070         jj_consume_token(70);
1071              builder.addMongoTimestamp( name, toMongoTimestamp(t1, t2) );
1072         break;
1073       case TOKEN_MAXKEY:
1074         jj_consume_token(TOKEN_MAXKEY);
1075         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1076         case 69:
1077           jj_consume_token(69);
1078           jj_consume_token(70);
1079           break;
1080         default:
1081           jj_la1[23] = jj_gen;
1082           ;
1083         }
1084              builder.addMaxKey(name);
1085         break;
1086       case TOKEN_MINKEY:
1087         jj_consume_token(TOKEN_MINKEY);
1088         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
1089         case 69:
1090           jj_consume_token(69);
1091           jj_consume_token(70);
1092           break;
1093         default:
1094           jj_la1[24] = jj_gen;
1095           ;
1096         }
1097              builder.addMinKey(name);
1098         break;
1099       case TOKEN_DB_POINTER:
1100         jj_consume_token(TOKEN_DB_POINTER);
1101         jj_consume_token(69);
1102         t1 = jj_consume_token(STRING_LITERAL);
1103         jj_consume_token(TOKEN_COMMA);
1104         t2 = jj_consume_token(STRING_LITERAL);
1105         jj_consume_token(TOKEN_COMMA);
1106         jj_consume_token(TOKEN_OBJECTID);
1107         jj_consume_token(69);
1108         t3 = jj_consume_token(STRING_LITERAL);
1109         jj_consume_token(70);
1110         jj_consume_token(70);
1111              builder.addDBPointer(name, trimQuotes(t1.image), trimQuotes(t2.image), toObjectId(t3));
1112         break;
1113       default:
1114         jj_la1[25] = jj_gen;
1115         jj_consume_token(-1);
1116         throw new ParseException();
1117       }
1118     }
1119   }
1120 
1121   private boolean jj_2_1(int xla) {
1122     jj_la = xla; jj_lastpos = jj_scanpos = token;
1123     try { return !jj_3_1(); }
1124     catch(LookaheadSuccess ls) { return true; }
1125     finally { jj_save(0, xla); }
1126   }
1127 
1128   private boolean jj_2_2(int xla) {
1129     jj_la = xla; jj_lastpos = jj_scanpos = token;
1130     try { return !jj_3_2(); }
1131     catch(LookaheadSuccess ls) { return true; }
1132     finally { jj_save(1, xla); }
1133   }
1134 
1135   private boolean jj_3R_5() {
1136     if (jj_scan_token(TOKEN_REGEX)) return true;
1137     return false;
1138   }
1139 
1140   private boolean jj_3R_16() {
1141     if (jj_scan_token(TOKEN_OID)) return true;
1142     return false;
1143   }
1144 
1145   private boolean jj_3_2() {
1146     if (jj_scan_token(TOKEN_OPEN_BRACE)) return true;
1147     Token xsp;
1148     xsp = jj_scanpos;
1149     if (jj_3R_10()) {
1150     jj_scanpos = xsp;
1151     if (jj_3R_11()) {
1152     jj_scanpos = xsp;
1153     if (jj_3R_12()) {
1154     jj_scanpos = xsp;
1155     if (jj_3R_13()) {
1156     jj_scanpos = xsp;
1157     if (jj_3R_14()) {
1158     jj_scanpos = xsp;
1159     if (jj_3R_15()) {
1160     jj_scanpos = xsp;
1161     if (jj_3R_16()) {
1162     jj_scanpos = xsp;
1163     if (jj_3R_17()) {
1164     jj_scanpos = xsp;
1165     if (jj_3R_18()) return true;
1166     }
1167     }
1168     }
1169     }
1170     }
1171     }
1172     }
1173     }
1174     return false;
1175   }
1176 
1177   private boolean jj_3R_15() {
1178     if (jj_scan_token(TOKEN_OPTIONS)) return true;
1179     return false;
1180   }
1181 
1182   private boolean jj_3R_4() {
1183     if (jj_scan_token(TOKEN_TS)) return true;
1184     return false;
1185   }
1186 
1187   private boolean jj_3R_14() {
1188     if (jj_scan_token(TOKEN_REGEX)) return true;
1189     return false;
1190   }
1191 
1192   private boolean jj_3R_3() {
1193     if (jj_scan_token(TOKEN_DATE)) return true;
1194     return false;
1195   }
1196 
1197   private boolean jj_3R_13() {
1198     if (jj_scan_token(TOKEN_TS)) return true;
1199     return false;
1200   }
1201 
1202   private boolean jj_3R_2() {
1203     if (jj_scan_token(TOKEN_TYPE)) return true;
1204     return false;
1205   }
1206 
1207   private boolean jj_3R_9() {
1208     if (jj_scan_token(TOKEN_MIN)) return true;
1209     return false;
1210   }
1211 
1212   private boolean jj_3R_12() {
1213     if (jj_scan_token(TOKEN_DATE)) return true;
1214     return false;
1215   }
1216 
1217   private boolean jj_3R_1() {
1218     if (jj_scan_token(TOKEN_BINARY)) return true;
1219     return false;
1220   }
1221 
1222   private boolean jj_3R_8() {
1223     if (jj_scan_token(TOKEN_MAX)) return true;
1224     return false;
1225   }
1226 
1227   private boolean jj_3R_7() {
1228     if (jj_scan_token(TOKEN_OID)) return true;
1229     return false;
1230   }
1231 
1232   private boolean jj_3R_11() {
1233     if (jj_scan_token(TOKEN_TYPE)) return true;
1234     return false;
1235   }
1236 
1237   private boolean jj_3_1() {
1238     if (jj_scan_token(TOKEN_OPEN_BRACE)) return true;
1239     Token xsp;
1240     xsp = jj_scanpos;
1241     if (jj_3R_1()) {
1242     jj_scanpos = xsp;
1243     if (jj_3R_2()) {
1244     jj_scanpos = xsp;
1245     if (jj_3R_3()) {
1246     jj_scanpos = xsp;
1247     if (jj_3R_4()) {
1248     jj_scanpos = xsp;
1249     if (jj_3R_5()) {
1250     jj_scanpos = xsp;
1251     if (jj_3R_6()) {
1252     jj_scanpos = xsp;
1253     if (jj_3R_7()) {
1254     jj_scanpos = xsp;
1255     if (jj_3R_8()) {
1256     jj_scanpos = xsp;
1257     if (jj_3R_9()) return true;
1258     }
1259     }
1260     }
1261     }
1262     }
1263     }
1264     }
1265     }
1266     return false;
1267   }
1268 
1269   private boolean jj_3R_6() {
1270     if (jj_scan_token(TOKEN_OPTIONS)) return true;
1271     return false;
1272   }
1273 
1274   private boolean jj_3R_18() {
1275     if (jj_scan_token(TOKEN_MIN)) return true;
1276     return false;
1277   }
1278 
1279   private boolean jj_3R_10() {
1280     if (jj_scan_token(TOKEN_BINARY)) return true;
1281     return false;
1282   }
1283 
1284   private boolean jj_3R_17() {
1285     if (jj_scan_token(TOKEN_MAX)) return true;
1286     return false;
1287   }
1288 
1289   /** Generated Token Manager. */
1290   public JsonParserTokenManager token_source;
1291   JavaCharStream jj_input_stream;
1292   /** Current token. */
1293   public Token token;
1294   /** Next token. */
1295   public Token jj_nt;
1296   private int jj_ntk;
1297   private Token jj_scanpos, jj_lastpos;
1298   private int jj_la;
1299   private int jj_gen;
1300   final private int[] jj_la1 = new int[26];
1301   static private int[] jj_la1_0;
1302   static private int[] jj_la1_1;
1303   static private int[] jj_la1_2;
1304   static {
1305       jj_la1_init_0();
1306       jj_la1_init_1();
1307       jj_la1_init_2();
1308    }
1309    private static void jj_la1_init_0() {
1310       jj_la1_0 = new int[] {0x2800,0x10000000,0x10302f00,0x8000,0x10000000,0x8000,0x10200000,0x10200000,0x10200000,0x10000000,0x10000000,0x8000,0x0,0x0,0x0,0x10302f00,0x10200000,0x10200000,0x10200000,0x10000000,0x10000000,0x8000,0x0,0x0,0x0,0x10302f00,};
1311    }
1312    private static void jj_la1_init_1() {
1313       jj_la1_1 = new int[] {0x0,0x2000040,0x200ffc0,0x0,0x2000040,0x0,0x0,0x0,0x0,0x2000000,0x2000000,0x0,0x1ff0000,0x0,0x0,0x200ffc0,0x0,0x0,0x0,0x2000000,0x2000000,0x0,0x1ff0000,0x0,0x0,0x200ffc0,};
1314    }
1315    private static void jj_la1_init_2() {
1316       jj_la1_2 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0x0,};
1317    }
1318   final private JJCalls[] jj_2_rtns = new JJCalls[2];
1319   private boolean jj_rescan = false;
1320   private int jj_gc = 0;
1321 
1322   /** Constructor with InputStream. */
1323   public JsonParser(java.io.InputStream stream) {
1324      this(stream, null);
1325   }
1326   /** Constructor with InputStream and supplied encoding */
1327   public JsonParser(java.io.InputStream stream, String encoding) {
1328     try { jj_input_stream = new JavaCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
1329     token_source = new JsonParserTokenManager(jj_input_stream);
1330     token = new Token();
1331     jj_ntk = -1;
1332     jj_gen = 0;
1333     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
1334     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1335   }
1336 
1337   /** Reinitialise. */
1338   public void ReInit(java.io.InputStream stream) {
1339      ReInit(stream, null);
1340   }
1341   /** Reinitialise. */
1342   public void ReInit(java.io.InputStream stream, String encoding) {
1343     try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
1344     token_source.ReInit(jj_input_stream);
1345     token = new Token();
1346     jj_ntk = -1;
1347     jj_gen = 0;
1348     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
1349     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1350   }
1351 
1352   /** Constructor. */
1353   public JsonParser(java.io.Reader stream) {
1354     jj_input_stream = new JavaCharStream(stream, 1, 1);
1355     token_source = new JsonParserTokenManager(jj_input_stream);
1356     token = new Token();
1357     jj_ntk = -1;
1358     jj_gen = 0;
1359     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
1360     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1361   }
1362 
1363   /** Reinitialise. */
1364   public void ReInit(java.io.Reader stream) {
1365     jj_input_stream.ReInit(stream, 1, 1);
1366     token_source.ReInit(jj_input_stream);
1367     token = new Token();
1368     jj_ntk = -1;
1369     jj_gen = 0;
1370     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
1371     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1372   }
1373 
1374   /** Constructor with generated Token Manager. */
1375   public JsonParser(JsonParserTokenManager tm) {
1376     token_source = tm;
1377     token = new Token();
1378     jj_ntk = -1;
1379     jj_gen = 0;
1380     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
1381     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1382   }
1383 
1384   /** Reinitialise. */
1385   public void ReInit(JsonParserTokenManager tm) {
1386     token_source = tm;
1387     token = new Token();
1388     jj_ntk = -1;
1389     jj_gen = 0;
1390     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
1391     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
1392   }
1393 
1394   private Token jj_consume_token(int kind) throws ParseException {
1395     Token oldToken;
1396     if ((oldToken = token).next != null) token = token.next;
1397     else token = token.next = token_source.getNextToken();
1398     jj_ntk = -1;
1399     if (token.kind == kind) {
1400       jj_gen++;
1401       if (++jj_gc > 100) {
1402         jj_gc = 0;
1403         for (int i = 0; i < jj_2_rtns.length; i++) {
1404           JJCalls c = jj_2_rtns[i];
1405           while (c != null) {
1406             if (c.gen < jj_gen) c.first = null;
1407             c = c.next;
1408           }
1409         }
1410       }
1411       return token;
1412     }
1413     token = oldToken;
1414     jj_kind = kind;
1415     throw generateParseException();
1416   }
1417 
1418   static private final class LookaheadSuccess extends java.lang.Error { }
1419   final private LookaheadSuccess jj_ls = new LookaheadSuccess();
1420   private boolean jj_scan_token(int kind) {
1421     if (jj_scanpos == jj_lastpos) {
1422       jj_la--;
1423       if (jj_scanpos.next == null) {
1424         jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
1425       } else {
1426         jj_lastpos = jj_scanpos = jj_scanpos.next;
1427       }
1428     } else {
1429       jj_scanpos = jj_scanpos.next;
1430     }
1431     if (jj_rescan) {
1432       int i = 0; Token tok = token;
1433       while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
1434       if (tok != null) jj_add_error_token(kind, i);
1435     }
1436     if (jj_scanpos.kind != kind) return true;
1437     if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
1438     return false;
1439   }
1440 
1441 
1442 /** Get the next Token. */
1443   final public Token getNextToken() {
1444     if (token.next != null) token = token.next;
1445     else token = token.next = token_source.getNextToken();
1446     jj_ntk = -1;
1447     jj_gen++;
1448     return token;
1449   }
1450 
1451 /** Get the specific Token. */
1452   final public Token getToken(int index) {
1453     Token t = token;
1454     for (int i = 0; i < index; i++) {
1455       if (t.next != null) t = t.next;
1456       else t = t.next = token_source.getNextToken();
1457     }
1458     return t;
1459   }
1460 
1461   private int jj_ntk() {
1462     if ((jj_nt=token.next) == null)
1463       return (jj_ntk = (token.next=token_source.getNextToken()).kind);
1464     else
1465       return (jj_ntk = jj_nt.kind);
1466   }
1467 
1468   private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
1469   private int[] jj_expentry;
1470   private int jj_kind = -1;
1471   private int[] jj_lasttokens = new int[100];
1472   private int jj_endpos;
1473 
1474   private void jj_add_error_token(int kind, int pos) {
1475     if (pos >= 100) return;
1476     if (pos == jj_endpos + 1) {
1477       jj_lasttokens[jj_endpos++] = kind;
1478     } else if (jj_endpos != 0) {
1479       jj_expentry = new int[jj_endpos];
1480       for (int i = 0; i < jj_endpos; i++) {
1481         jj_expentry[i] = jj_lasttokens[i];
1482       }
1483       jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
1484         int[] oldentry = (int[])(it.next());
1485         if (oldentry.length == jj_expentry.length) {
1486           for (int i = 0; i < jj_expentry.length; i++) {
1487             if (oldentry[i] != jj_expentry[i]) {
1488               continue jj_entries_loop;
1489             }
1490           }
1491           jj_expentries.add(jj_expentry);
1492           break jj_entries_loop;
1493         }
1494       }
1495       if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
1496     }
1497   }
1498 
1499   /** Generate ParseException. */
1500   public ParseException generateParseException() {
1501     jj_expentries.clear();
1502     boolean[] la1tokens = new boolean[71];
1503     if (jj_kind >= 0) {
1504       la1tokens[jj_kind] = true;
1505       jj_kind = -1;
1506     }
1507     for (int i = 0; i < 26; i++) {
1508       if (jj_la1[i] == jj_gen) {
1509         for (int j = 0; j < 32; j++) {
1510           if ((jj_la1_0[i] & (1<<j)) != 0) {
1511             la1tokens[j] = true;
1512           }
1513           if ((jj_la1_1[i] & (1<<j)) != 0) {
1514             la1tokens[32+j] = true;
1515           }
1516           if ((jj_la1_2[i] & (1<<j)) != 0) {
1517             la1tokens[64+j] = true;
1518           }
1519         }
1520       }
1521     }
1522     for (int i = 0; i < 71; i++) {
1523       if (la1tokens[i]) {
1524         jj_expentry = new int[1];
1525         jj_expentry[0] = i;
1526         jj_expentries.add(jj_expentry);
1527       }
1528     }
1529     jj_endpos = 0;
1530     jj_rescan_token();
1531     jj_add_error_token(0, 0);
1532     int[][] exptokseq = new int[jj_expentries.size()][];
1533     for (int i = 0; i < jj_expentries.size(); i++) {
1534       exptokseq[i] = jj_expentries.get(i);
1535     }
1536     return new ParseException(token, exptokseq, tokenImage);
1537   }
1538 
1539   /** Enable tracing. */
1540   final public void enable_tracing() {
1541   }
1542 
1543   /** Disable tracing. */
1544   final public void disable_tracing() {
1545   }
1546 
1547   private void jj_rescan_token() {
1548     jj_rescan = true;
1549     for (int i = 0; i < 2; i++) {
1550     try {
1551       JJCalls p = jj_2_rtns[i];
1552       do {
1553         if (p.gen > jj_gen) {
1554           jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
1555           switch (i) {
1556             case 0: jj_3_1(); break;
1557             case 1: jj_3_2(); break;
1558           }
1559         }
1560         p = p.next;
1561       } while (p != null);
1562       } catch(LookaheadSuccess ls) { }
1563     }
1564     jj_rescan = false;
1565   }
1566 
1567   private void jj_save(int index, int xla) {
1568     JJCalls p = jj_2_rtns[index];
1569     while (p.gen > jj_gen) {
1570       if (p.next == null) { p = p.next = new JJCalls(); break; }
1571       p = p.next;
1572     }
1573     p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
1574   }
1575 
1576   static final class JJCalls {
1577     int gen;
1578     Token first;
1579     int arg;
1580     JJCalls next;
1581   }
1582 
1583 }