001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.json;
014
015import java.lang.annotation.*;
016import java.lang.reflect.*;
017import java.nio.charset.*;
018import java.util.*;
019import java.util.concurrent.*;
020
021import org.apache.juneau.*;
022import org.apache.juneau.collections.*;
023import org.apache.juneau.internal.*;
024import org.apache.juneau.parser.*;
025import org.apache.juneau.utils.*;
026
027/**
028 * Parses any valid JSON text into a POJO model.
029 *
030 * <h5 class='topic'>Media types</h5>
031 * <p>
032 * Handles <c>Content-Type</c> types:  <bc>application/json, text/json</bc>
033 *
034 * <h5 class='topic'>Description</h5>
035 * <p>
036 * This parser uses a state machine, which makes it very fast and efficient.  It parses JSON in about 70% of the
037 * time that it takes the built-in Java DOM parsers to parse equivalent XML.
038 *
039 * <p>
040 * This parser handles all valid JSON syntax.
041 * In addition, when strict mode is disable, the parser also handles the following:
042 * <ul class='spaced-list'>
043 *    <li>
044 *       Javascript comments (both {@code /*} and {@code //}) are ignored.
045 *    <li>
046 *       Both single and double quoted strings.
047 *    <li>
048 *       Automatically joins concatenated strings (e.g. <code><js>"aaa"</js> + <js>'bbb'</js></code>).
049 *    <li>
050 *       Unquoted attributes and values.
051 * </ul>
052 *
053 * <p>
054 * Also handles negative, decimal, hexadecimal, octal, and double numbers, including exponential notation.
055 *
056 * <p>
057 * This parser handles the following input, and automatically returns the corresponding Java class.
058 * <ul class='spaced-list'>
059 *    <li>
060 *       JSON objects (<js>"{...}"</js>) are converted to {@link JsonMap JsonMaps}.
061 *       <b>Note:</b>  If a <code><xa>_type</xa>=<xs>'xxx'</xs></code> attribute is specified on the object, then an
062 *       attempt is made to convert the object to an instance of the specified Java bean class.
063 *       See the {@link org.apache.juneau.BeanContext.Builder#typePropertyName(String)} setting for more information about parsing
064 *       beans from JSON.
065 *    <li>
066 *       JSON arrays (<js>"[...]"</js>) are converted to {@link JsonList JsonLists}.
067 *    <li>
068 *       JSON string literals (<js>"'xyz'"</js>) are converted to {@link String Strings}.
069 *    <li>
070 *       JSON numbers (<js>"123"</js>, including octal/hexadecimal/exponential notation) are converted to
071 *       {@link Integer Integers}, {@link Long Longs}, {@link Float Floats}, or {@link Double Doubles} depending on
072 *       whether the number is decimal, and the size of the number.
073 *    <li>
074 *       JSON booleans (<js>"false"</js>) are converted to {@link Boolean Booleans}.
075 *    <li>
076 *       JSON nulls (<js>"null"</js>) are converted to <jk>null</jk>.
077 *    <li>
078 *       Input consisting of only whitespace or JSON comments are converted to <jk>null</jk>.
079 * </ul>
080 *
081 * <p>
082 * Input can be any of the following:
083 * <ul class='spaced-list'>
084 *    <li>
085 *       <js>"{...}"</js> - Converted to an {@link JsonMap} or an instance of a Java bean if a <xa>_type</xa>
086 *       attribute is present.
087 *    <li>
088 *       <js>"[...]"</js> - Converted to an {@link JsonList}.
089 *    <li>
090 *       <js>"123..."</js> - Converted to a {@link Number} (either {@link Integer}, {@link Long}, {@link Float},
091 *       or {@link Double}).
092 *    <li>
093 *       <js>"true"</js>/<js>"false"</js> - Converted to a {@link Boolean}.
094 *    <li>
095 *       <js>"null"</js> - Returns <jk>null</jk>.
096 *    <li>
097 *       <js>"'xxx'"</js> - Converted to a {@link String}.
098 *    <li>
099 *       <js>"\"xxx\""</js> - Converted to a {@link String}.
100 *    <li>
101 *       <js>"'xxx' + \"yyy\""</js> - Converted to a concatenated {@link String}.
102 * </ul>
103 *
104 * <p>
105 * TIP:  If you know you're parsing a JSON object or array, it can be easier to parse it using the
106 * {@link JsonMap#JsonMap(CharSequence) JsonMap(CharSequence)} or {@link JsonList#JsonList(CharSequence)
107 * JsonList(CharSequence)} constructors instead of using this class.
108 * The end result should be the same.
109 *
110 * <h5 class='section'>Notes:</h5><ul>
111 *    <li class='note'>This class is thread safe and reusable.
112 * </ul>
113 *
114 * <h5 class='section'>See Also:</h5><ul>
115 *    <li class='link'><a class="doclink" href="../../../../index.html#jm.JsonDetails">JSON Details</a>
116
117 * </ul>
118 */
119public class JsonParser extends ReaderParser implements JsonMetaProvider {
120
121   //-------------------------------------------------------------------------------------------------------------------
122   // Static
123   //-------------------------------------------------------------------------------------------------------------------
124
125   /** Default parser, all default settings.*/
126   public static final JsonParser DEFAULT = new JsonParser(create());
127
128   /** Default parser, all default settings.*/
129   public static final JsonParser DEFAULT_STRICT = new JsonParser.Strict(create());
130
131   /**
132    * Creates a new builder for this object.
133    *
134    * @return A new builder.
135    */
136   public static Builder create() {
137      return new Builder();
138   }
139
140   //-------------------------------------------------------------------------------------------------------------------
141   // Static subclasses
142   //-------------------------------------------------------------------------------------------------------------------
143
144   /** Default parser, strict mode. */
145   public static class Strict extends JsonParser {
146
147      /**
148       * Constructor.
149       *
150       * @param builder The builder for this object.
151       */
152      public Strict(Builder builder) {
153         super(builder.strict().validateEnd());
154      }
155   }
156
157   //-------------------------------------------------------------------------------------------------------------------
158   // Builder
159   //-------------------------------------------------------------------------------------------------------------------
160
161   /**
162    * Builder class.
163    */
164   @FluentSetters
165   public static class Builder extends ReaderParser.Builder {
166
167      private static final Cache<HashKey,JsonParser> CACHE = Cache.of(HashKey.class, JsonParser.class).build();
168
169      boolean validateEnd;
170
171      /**
172       * Constructor, default settings.
173       */
174      protected Builder() {
175         super();
176         consumes("application/json,text/json");
177         validateEnd = env("JsonParser.validateEnd", false);
178      }
179
180      /**
181       * Copy constructor.
182       *
183       * @param copyFrom The bean to copy from.
184       */
185      protected Builder(JsonParser copyFrom) {
186         super(copyFrom);
187         validateEnd = copyFrom.validateEnd;
188      }
189
190      /**
191       * Copy constructor.
192       *
193       * @param copyFrom The builder to copy from.
194       */
195      protected Builder(Builder copyFrom) {
196         super(copyFrom);
197         validateEnd = copyFrom.validateEnd;
198      }
199
200      @Override /* Context.Builder */
201      public Builder copy() {
202         return new Builder(this);
203      }
204
205      @Override /* Context.Builder */
206      public JsonParser build() {
207         return cache(CACHE).build(JsonParser.class);
208      }
209
210      @Override /* Context.Builder */
211      public HashKey hashKey() {
212         return HashKey.of(
213            super.hashKey(),
214            validateEnd
215         );
216      }
217
218      //-----------------------------------------------------------------------------------------------------------------
219      // Properties
220      //-----------------------------------------------------------------------------------------------------------------
221
222      /**
223       * Validate end.
224       *
225       * <p>
226       * When enabled, after parsing a POJO from the input, verifies that the remaining input in
227       * the stream consists of only comments or whitespace.
228       *
229       * <h5 class='section'>Example:</h5>
230       * <p class='bjava'>
231       *    <jc>// Create a parser that validates that there's no garbage at the end of the input.</jc>
232       *    ReaderParser <jv>parser</jv> = JsonParser.
233       *       .<jsm>create</jsm>()
234       *       .validateEnd()
235       *       .build();
236       *
237       *    <jc>// Should fail because input has multiple POJOs.</jc>
238       *    String <jv>json</jv> = <js>"{foo:'bar'}{baz:'qux'}"</js>;
239       *    MyBean <jv>myBean</jv> =<jv>parser</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>);
240       * </p>
241       *
242       * @return This object.
243       */
244      @FluentSetter
245      public Builder validateEnd() {
246         return validateEnd(true);
247      }
248
249      /**
250       * Same as {@link #validateEnd()} but allows you to explicitly specify the value.
251       *
252       * @param value The value for this setting.
253       * @return This object.
254       */
255      @FluentSetter
256      public Builder validateEnd(boolean value) {
257         validateEnd = value;
258         return this;
259      }
260
261      // <FluentSetters>
262
263      @Override /* GENERATED - org.apache.juneau.Context.Builder */
264      public Builder annotations(Annotation...values) {
265         super.annotations(values);
266         return this;
267      }
268
269      @Override /* GENERATED - org.apache.juneau.Context.Builder */
270      public Builder apply(AnnotationWorkList work) {
271         super.apply(work);
272         return this;
273      }
274
275      @Override /* GENERATED - org.apache.juneau.Context.Builder */
276      public Builder applyAnnotations(java.lang.Class<?>...fromClasses) {
277         super.applyAnnotations(fromClasses);
278         return this;
279      }
280
281      @Override /* GENERATED - org.apache.juneau.Context.Builder */
282      public Builder applyAnnotations(Method...fromMethods) {
283         super.applyAnnotations(fromMethods);
284         return this;
285      }
286
287      @Override /* GENERATED - org.apache.juneau.Context.Builder */
288      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
289         super.cache(value);
290         return this;
291      }
292
293      @Override /* GENERATED - org.apache.juneau.Context.Builder */
294      public Builder debug() {
295         super.debug();
296         return this;
297      }
298
299      @Override /* GENERATED - org.apache.juneau.Context.Builder */
300      public Builder debug(boolean value) {
301         super.debug(value);
302         return this;
303      }
304
305      @Override /* GENERATED - org.apache.juneau.Context.Builder */
306      public Builder impl(Context value) {
307         super.impl(value);
308         return this;
309      }
310
311      @Override /* GENERATED - org.apache.juneau.Context.Builder */
312      public Builder type(Class<? extends org.apache.juneau.Context> value) {
313         super.type(value);
314         return this;
315      }
316
317      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
318      public Builder beanClassVisibility(Visibility value) {
319         super.beanClassVisibility(value);
320         return this;
321      }
322
323      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
324      public Builder beanConstructorVisibility(Visibility value) {
325         super.beanConstructorVisibility(value);
326         return this;
327      }
328
329      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
330      public Builder beanContext(BeanContext value) {
331         super.beanContext(value);
332         return this;
333      }
334
335      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
336      public Builder beanContext(BeanContext.Builder value) {
337         super.beanContext(value);
338         return this;
339      }
340
341      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
342      public Builder beanDictionary(java.lang.Class<?>...values) {
343         super.beanDictionary(values);
344         return this;
345      }
346
347      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
348      public Builder beanFieldVisibility(Visibility value) {
349         super.beanFieldVisibility(value);
350         return this;
351      }
352
353      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
354      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
355         super.beanInterceptor(on, value);
356         return this;
357      }
358
359      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
360      public Builder beanMapPutReturnsOldValue() {
361         super.beanMapPutReturnsOldValue();
362         return this;
363      }
364
365      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
366      public Builder beanMethodVisibility(Visibility value) {
367         super.beanMethodVisibility(value);
368         return this;
369      }
370
371      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
372      public Builder beanProperties(Map<String,Object> values) {
373         super.beanProperties(values);
374         return this;
375      }
376
377      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
378      public Builder beanProperties(Class<?> beanClass, String properties) {
379         super.beanProperties(beanClass, properties);
380         return this;
381      }
382
383      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
384      public Builder beanProperties(String beanClassName, String properties) {
385         super.beanProperties(beanClassName, properties);
386         return this;
387      }
388
389      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
390      public Builder beanPropertiesExcludes(Map<String,Object> values) {
391         super.beanPropertiesExcludes(values);
392         return this;
393      }
394
395      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
396      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
397         super.beanPropertiesExcludes(beanClass, properties);
398         return this;
399      }
400
401      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
402      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
403         super.beanPropertiesExcludes(beanClassName, properties);
404         return this;
405      }
406
407      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
408      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
409         super.beanPropertiesReadOnly(values);
410         return this;
411      }
412
413      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
414      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
415         super.beanPropertiesReadOnly(beanClass, properties);
416         return this;
417      }
418
419      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
420      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
421         super.beanPropertiesReadOnly(beanClassName, properties);
422         return this;
423      }
424
425      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
426      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
427         super.beanPropertiesWriteOnly(values);
428         return this;
429      }
430
431      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
432      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
433         super.beanPropertiesWriteOnly(beanClass, properties);
434         return this;
435      }
436
437      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
438      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
439         super.beanPropertiesWriteOnly(beanClassName, properties);
440         return this;
441      }
442
443      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
444      public Builder beansRequireDefaultConstructor() {
445         super.beansRequireDefaultConstructor();
446         return this;
447      }
448
449      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
450      public Builder beansRequireSerializable() {
451         super.beansRequireSerializable();
452         return this;
453      }
454
455      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
456      public Builder beansRequireSettersForGetters() {
457         super.beansRequireSettersForGetters();
458         return this;
459      }
460
461      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
462      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
463         super.dictionaryOn(on, values);
464         return this;
465      }
466
467      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
468      public Builder disableBeansRequireSomeProperties() {
469         super.disableBeansRequireSomeProperties();
470         return this;
471      }
472
473      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
474      public Builder disableIgnoreMissingSetters() {
475         super.disableIgnoreMissingSetters();
476         return this;
477      }
478
479      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
480      public Builder disableIgnoreTransientFields() {
481         super.disableIgnoreTransientFields();
482         return this;
483      }
484
485      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
486      public Builder disableIgnoreUnknownNullBeanProperties() {
487         super.disableIgnoreUnknownNullBeanProperties();
488         return this;
489      }
490
491      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
492      public Builder disableInterfaceProxies() {
493         super.disableInterfaceProxies();
494         return this;
495      }
496
497      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
498      public <T> Builder example(Class<T> pojoClass, T o) {
499         super.example(pojoClass, o);
500         return this;
501      }
502
503      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
504      public <T> Builder example(Class<T> pojoClass, String json) {
505         super.example(pojoClass, json);
506         return this;
507      }
508
509      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
510      public Builder findFluentSetters() {
511         super.findFluentSetters();
512         return this;
513      }
514
515      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
516      public Builder findFluentSetters(Class<?> on) {
517         super.findFluentSetters(on);
518         return this;
519      }
520
521      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
522      public Builder ignoreInvocationExceptionsOnGetters() {
523         super.ignoreInvocationExceptionsOnGetters();
524         return this;
525      }
526
527      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
528      public Builder ignoreInvocationExceptionsOnSetters() {
529         super.ignoreInvocationExceptionsOnSetters();
530         return this;
531      }
532
533      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
534      public Builder ignoreUnknownBeanProperties() {
535         super.ignoreUnknownBeanProperties();
536         return this;
537      }
538
539      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
540      public Builder ignoreUnknownEnumValues() {
541         super.ignoreUnknownEnumValues();
542         return this;
543      }
544
545      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
546      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
547         super.implClass(interfaceClass, implClass);
548         return this;
549      }
550
551      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
552      public Builder implClasses(Map<Class<?>,Class<?>> values) {
553         super.implClasses(values);
554         return this;
555      }
556
557      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
558      public Builder interfaceClass(Class<?> on, Class<?> value) {
559         super.interfaceClass(on, value);
560         return this;
561      }
562
563      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
564      public Builder interfaces(java.lang.Class<?>...value) {
565         super.interfaces(value);
566         return this;
567      }
568
569      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
570      public Builder locale(Locale value) {
571         super.locale(value);
572         return this;
573      }
574
575      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
576      public Builder mediaType(MediaType value) {
577         super.mediaType(value);
578         return this;
579      }
580
581      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
582      public Builder notBeanClasses(java.lang.Class<?>...values) {
583         super.notBeanClasses(values);
584         return this;
585      }
586
587      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
588      public Builder notBeanPackages(String...values) {
589         super.notBeanPackages(values);
590         return this;
591      }
592
593      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
594      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
595         super.propertyNamer(value);
596         return this;
597      }
598
599      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
600      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
601         super.propertyNamer(on, value);
602         return this;
603      }
604
605      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
606      public Builder sortProperties() {
607         super.sortProperties();
608         return this;
609      }
610
611      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
612      public Builder sortProperties(java.lang.Class<?>...on) {
613         super.sortProperties(on);
614         return this;
615      }
616
617      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
618      public Builder stopClass(Class<?> on, Class<?> value) {
619         super.stopClass(on, value);
620         return this;
621      }
622
623      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
624      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
625         super.swap(normalClass, swappedClass, swapFunction);
626         return this;
627      }
628
629      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
630      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
631         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
632         return this;
633      }
634
635      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
636      public Builder swaps(java.lang.Class<?>...values) {
637         super.swaps(values);
638         return this;
639      }
640
641      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
642      public Builder timeZone(TimeZone value) {
643         super.timeZone(value);
644         return this;
645      }
646
647      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
648      public Builder typeName(Class<?> on, String value) {
649         super.typeName(on, value);
650         return this;
651      }
652
653      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
654      public Builder typePropertyName(String value) {
655         super.typePropertyName(value);
656         return this;
657      }
658
659      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
660      public Builder typePropertyName(Class<?> on, String value) {
661         super.typePropertyName(on, value);
662         return this;
663      }
664
665      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
666      public Builder useEnumNames() {
667         super.useEnumNames();
668         return this;
669      }
670
671      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
672      public Builder useJavaBeanIntrospector() {
673         super.useJavaBeanIntrospector();
674         return this;
675      }
676
677      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
678      public Builder autoCloseStreams() {
679         super.autoCloseStreams();
680         return this;
681      }
682
683      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
684      public Builder autoCloseStreams(boolean value) {
685         super.autoCloseStreams(value);
686         return this;
687      }
688
689      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
690      public Builder consumes(String value) {
691         super.consumes(value);
692         return this;
693      }
694
695      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
696      public Builder debugOutputLines(int value) {
697         super.debugOutputLines(value);
698         return this;
699      }
700
701      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
702      public Builder listener(Class<? extends org.apache.juneau.parser.ParserListener> value) {
703         super.listener(value);
704         return this;
705      }
706
707      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
708      public Builder strict() {
709         super.strict();
710         return this;
711      }
712
713      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
714      public Builder strict(boolean value) {
715         super.strict(value);
716         return this;
717      }
718
719      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
720      public Builder trimStrings() {
721         super.trimStrings();
722         return this;
723      }
724
725      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
726      public Builder trimStrings(boolean value) {
727         super.trimStrings(value);
728         return this;
729      }
730
731      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
732      public Builder unbuffered() {
733         super.unbuffered();
734         return this;
735      }
736
737      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
738      public Builder unbuffered(boolean value) {
739         super.unbuffered(value);
740         return this;
741      }
742
743      @Override /* GENERATED - org.apache.juneau.parser.ReaderParser.Builder */
744      public Builder fileCharset(Charset value) {
745         super.fileCharset(value);
746         return this;
747      }
748
749      @Override /* GENERATED - org.apache.juneau.parser.ReaderParser.Builder */
750      public Builder streamCharset(Charset value) {
751         super.streamCharset(value);
752         return this;
753      }
754
755      // </FluentSetters>
756   }
757
758   //-------------------------------------------------------------------------------------------------------------------
759   // Instance
760   //-------------------------------------------------------------------------------------------------------------------
761
762   final boolean validateEnd;
763
764   private final Map<ClassMeta<?>,JsonClassMeta> jsonClassMetas = new ConcurrentHashMap<>();
765   private final Map<BeanPropertyMeta,JsonBeanPropertyMeta> jsonBeanPropertyMetas = new ConcurrentHashMap<>();
766
767   /**
768    * Constructor.
769    *
770    * @param builder The builder for this object.
771    */
772   public JsonParser(Builder builder) {
773      super(builder);
774      validateEnd = builder.validateEnd;
775   }
776
777   @Override /* Context */
778   public Builder copy() {
779      return new Builder(this);
780   }
781
782   @Override /* Context */
783   public JsonParserSession.Builder createSession() {
784      return JsonParserSession.create(this);
785   }
786
787   @Override /* Context */
788   public JsonParserSession getSession() {
789      return createSession().build();
790   }
791
792   //-----------------------------------------------------------------------------------------------------------------
793   // Extended metadata
794   //-----------------------------------------------------------------------------------------------------------------
795
796   @Override /* JsonMetaProvider */
797   public JsonClassMeta getJsonClassMeta(ClassMeta<?> cm) {
798      JsonClassMeta m = jsonClassMetas.get(cm);
799      if (m == null) {
800         m = new JsonClassMeta(cm, this);
801         jsonClassMetas.put(cm, m);
802      }
803      return m;
804   }
805
806   @Override /* JsonMetaProvider */
807   public JsonBeanPropertyMeta getJsonBeanPropertyMeta(BeanPropertyMeta bpm) {
808      if (bpm == null)
809         return JsonBeanPropertyMeta.DEFAULT;
810      JsonBeanPropertyMeta m = jsonBeanPropertyMetas.get(bpm);
811      if (m == null) {
812         m = new JsonBeanPropertyMeta(bpm.getDelegateFor(), this);
813         jsonBeanPropertyMetas.put(bpm, m);
814      }
815      return m;
816   }
817
818   //-----------------------------------------------------------------------------------------------------------------
819   // Properties
820   //-----------------------------------------------------------------------------------------------------------------
821
822   /**
823    * Validate end.
824    *
825    * @see Builder#validateEnd()
826    * @return
827    *    <jk>true</jk> if after parsing a POJO from the input, verifies that the remaining input in
828    *    the stream consists of only comments or whitespace.
829    */
830   protected final boolean isValidateEnd() {
831      return validateEnd;
832   }
833}