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         consumes("application/json,text/json");
176         validateEnd = env("JsonParser.validateEnd", false);
177      }
178
179      /**
180       * Copy constructor.
181       *
182       * @param copyFrom The bean to copy from.
183       */
184      protected Builder(JsonParser copyFrom) {
185         super(copyFrom);
186         validateEnd = copyFrom.validateEnd;
187      }
188
189      /**
190       * Copy constructor.
191       *
192       * @param copyFrom The builder to copy from.
193       */
194      protected Builder(Builder copyFrom) {
195         super(copyFrom);
196         validateEnd = copyFrom.validateEnd;
197      }
198
199      @Override /* Context.Builder */
200      public Builder copy() {
201         return new Builder(this);
202      }
203
204      @Override /* Context.Builder */
205      public JsonParser build() {
206         return cache(CACHE).build(JsonParser.class);
207      }
208
209      @Override /* Context.Builder */
210      public HashKey hashKey() {
211         return HashKey.of(
212            super.hashKey(),
213            validateEnd
214         );
215      }
216
217      //-----------------------------------------------------------------------------------------------------------------
218      // Properties
219      //-----------------------------------------------------------------------------------------------------------------
220
221      /**
222       * Validate end.
223       *
224       * <p>
225       * When enabled, after parsing a POJO from the input, verifies that the remaining input in
226       * the stream consists of only comments or whitespace.
227       *
228       * <h5 class='section'>Example:</h5>
229       * <p class='bjava'>
230       *    <jc>// Create a parser that validates that there's no garbage at the end of the input.</jc>
231       *    ReaderParser <jv>parser</jv> = JsonParser.
232       *       .<jsm>create</jsm>()
233       *       .validateEnd()
234       *       .build();
235       *
236       *    <jc>// Should fail because input has multiple POJOs.</jc>
237       *    String <jv>json</jv> = <js>"{foo:'bar'}{baz:'qux'}"</js>;
238       *    MyBean <jv>myBean</jv> =<jv>parser</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>);
239       * </p>
240       *
241       * @return This object.
242       */
243      @FluentSetter
244      public Builder validateEnd() {
245         return validateEnd(true);
246      }
247
248      /**
249       * Same as {@link #validateEnd()} but allows you to explicitly specify the value.
250       *
251       * @param value The value for this setting.
252       * @return This object.
253       */
254      @FluentSetter
255      public Builder validateEnd(boolean value) {
256         validateEnd = value;
257         return this;
258      }
259
260      // <FluentSetters>
261
262      @Override /* GENERATED - org.apache.juneau.Context.Builder */
263      public Builder annotations(Annotation...values) {
264         super.annotations(values);
265         return this;
266      }
267
268      @Override /* GENERATED - org.apache.juneau.Context.Builder */
269      public Builder apply(AnnotationWorkList work) {
270         super.apply(work);
271         return this;
272      }
273
274      @Override /* GENERATED - org.apache.juneau.Context.Builder */
275      public Builder applyAnnotations(java.lang.Class<?>...fromClasses) {
276         super.applyAnnotations(fromClasses);
277         return this;
278      }
279
280      @Override /* GENERATED - org.apache.juneau.Context.Builder */
281      public Builder applyAnnotations(Method...fromMethods) {
282         super.applyAnnotations(fromMethods);
283         return this;
284      }
285
286      @Override /* GENERATED - org.apache.juneau.Context.Builder */
287      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
288         super.cache(value);
289         return this;
290      }
291
292      @Override /* GENERATED - org.apache.juneau.Context.Builder */
293      public Builder debug() {
294         super.debug();
295         return this;
296      }
297
298      @Override /* GENERATED - org.apache.juneau.Context.Builder */
299      public Builder debug(boolean value) {
300         super.debug(value);
301         return this;
302      }
303
304      @Override /* GENERATED - org.apache.juneau.Context.Builder */
305      public Builder impl(Context value) {
306         super.impl(value);
307         return this;
308      }
309
310      @Override /* GENERATED - org.apache.juneau.Context.Builder */
311      public Builder type(Class<? extends org.apache.juneau.Context> value) {
312         super.type(value);
313         return this;
314      }
315
316      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
317      public Builder beanClassVisibility(Visibility value) {
318         super.beanClassVisibility(value);
319         return this;
320      }
321
322      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
323      public Builder beanConstructorVisibility(Visibility value) {
324         super.beanConstructorVisibility(value);
325         return this;
326      }
327
328      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
329      public Builder beanContext(BeanContext value) {
330         super.beanContext(value);
331         return this;
332      }
333
334      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
335      public Builder beanContext(BeanContext.Builder value) {
336         super.beanContext(value);
337         return this;
338      }
339
340      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
341      public Builder beanDictionary(java.lang.Class<?>...values) {
342         super.beanDictionary(values);
343         return this;
344      }
345
346      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
347      public Builder beanFieldVisibility(Visibility value) {
348         super.beanFieldVisibility(value);
349         return this;
350      }
351
352      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
353      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
354         super.beanInterceptor(on, value);
355         return this;
356      }
357
358      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
359      public Builder beanMapPutReturnsOldValue() {
360         super.beanMapPutReturnsOldValue();
361         return this;
362      }
363
364      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
365      public Builder beanMethodVisibility(Visibility value) {
366         super.beanMethodVisibility(value);
367         return this;
368      }
369
370      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
371      public Builder beanProperties(Map<String,Object> values) {
372         super.beanProperties(values);
373         return this;
374      }
375
376      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
377      public Builder beanProperties(Class<?> beanClass, String properties) {
378         super.beanProperties(beanClass, properties);
379         return this;
380      }
381
382      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
383      public Builder beanProperties(String beanClassName, String properties) {
384         super.beanProperties(beanClassName, properties);
385         return this;
386      }
387
388      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
389      public Builder beanPropertiesExcludes(Map<String,Object> values) {
390         super.beanPropertiesExcludes(values);
391         return this;
392      }
393
394      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
395      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
396         super.beanPropertiesExcludes(beanClass, properties);
397         return this;
398      }
399
400      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
401      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
402         super.beanPropertiesExcludes(beanClassName, properties);
403         return this;
404      }
405
406      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
407      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
408         super.beanPropertiesReadOnly(values);
409         return this;
410      }
411
412      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
413      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
414         super.beanPropertiesReadOnly(beanClass, properties);
415         return this;
416      }
417
418      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
419      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
420         super.beanPropertiesReadOnly(beanClassName, properties);
421         return this;
422      }
423
424      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
425      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
426         super.beanPropertiesWriteOnly(values);
427         return this;
428      }
429
430      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
431      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
432         super.beanPropertiesWriteOnly(beanClass, properties);
433         return this;
434      }
435
436      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
437      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
438         super.beanPropertiesWriteOnly(beanClassName, properties);
439         return this;
440      }
441
442      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
443      public Builder beansRequireDefaultConstructor() {
444         super.beansRequireDefaultConstructor();
445         return this;
446      }
447
448      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
449      public Builder beansRequireSerializable() {
450         super.beansRequireSerializable();
451         return this;
452      }
453
454      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
455      public Builder beansRequireSettersForGetters() {
456         super.beansRequireSettersForGetters();
457         return this;
458      }
459
460      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
461      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
462         super.dictionaryOn(on, values);
463         return this;
464      }
465
466      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
467      public Builder disableBeansRequireSomeProperties() {
468         super.disableBeansRequireSomeProperties();
469         return this;
470      }
471
472      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
473      public Builder disableIgnoreMissingSetters() {
474         super.disableIgnoreMissingSetters();
475         return this;
476      }
477
478      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
479      public Builder disableIgnoreTransientFields() {
480         super.disableIgnoreTransientFields();
481         return this;
482      }
483
484      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
485      public Builder disableIgnoreUnknownNullBeanProperties() {
486         super.disableIgnoreUnknownNullBeanProperties();
487         return this;
488      }
489
490      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
491      public Builder disableInterfaceProxies() {
492         super.disableInterfaceProxies();
493         return this;
494      }
495
496      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
497      public <T> Builder example(Class<T> pojoClass, T o) {
498         super.example(pojoClass, o);
499         return this;
500      }
501
502      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
503      public <T> Builder example(Class<T> pojoClass, String json) {
504         super.example(pojoClass, json);
505         return this;
506      }
507
508      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
509      public Builder findFluentSetters() {
510         super.findFluentSetters();
511         return this;
512      }
513
514      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
515      public Builder findFluentSetters(Class<?> on) {
516         super.findFluentSetters(on);
517         return this;
518      }
519
520      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
521      public Builder ignoreInvocationExceptionsOnGetters() {
522         super.ignoreInvocationExceptionsOnGetters();
523         return this;
524      }
525
526      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
527      public Builder ignoreInvocationExceptionsOnSetters() {
528         super.ignoreInvocationExceptionsOnSetters();
529         return this;
530      }
531
532      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
533      public Builder ignoreUnknownBeanProperties() {
534         super.ignoreUnknownBeanProperties();
535         return this;
536      }
537
538      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
539      public Builder ignoreUnknownEnumValues() {
540         super.ignoreUnknownEnumValues();
541         return this;
542      }
543
544      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
545      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
546         super.implClass(interfaceClass, implClass);
547         return this;
548      }
549
550      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
551      public Builder implClasses(Map<Class<?>,Class<?>> values) {
552         super.implClasses(values);
553         return this;
554      }
555
556      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
557      public Builder interfaceClass(Class<?> on, Class<?> value) {
558         super.interfaceClass(on, value);
559         return this;
560      }
561
562      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
563      public Builder interfaces(java.lang.Class<?>...value) {
564         super.interfaces(value);
565         return this;
566      }
567
568      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
569      public Builder locale(Locale value) {
570         super.locale(value);
571         return this;
572      }
573
574      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
575      public Builder mediaType(MediaType value) {
576         super.mediaType(value);
577         return this;
578      }
579
580      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
581      public Builder notBeanClasses(java.lang.Class<?>...values) {
582         super.notBeanClasses(values);
583         return this;
584      }
585
586      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
587      public Builder notBeanPackages(String...values) {
588         super.notBeanPackages(values);
589         return this;
590      }
591
592      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
593      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
594         super.propertyNamer(value);
595         return this;
596      }
597
598      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
599      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
600         super.propertyNamer(on, value);
601         return this;
602      }
603
604      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
605      public Builder sortProperties() {
606         super.sortProperties();
607         return this;
608      }
609
610      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
611      public Builder sortProperties(java.lang.Class<?>...on) {
612         super.sortProperties(on);
613         return this;
614      }
615
616      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
617      public Builder stopClass(Class<?> on, Class<?> value) {
618         super.stopClass(on, value);
619         return this;
620      }
621
622      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
623      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
624         super.swap(normalClass, swappedClass, swapFunction);
625         return this;
626      }
627
628      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
629      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
630         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
631         return this;
632      }
633
634      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
635      public Builder swaps(java.lang.Class<?>...values) {
636         super.swaps(values);
637         return this;
638      }
639
640      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
641      public Builder timeZone(TimeZone value) {
642         super.timeZone(value);
643         return this;
644      }
645
646      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
647      public Builder typeName(Class<?> on, String value) {
648         super.typeName(on, value);
649         return this;
650      }
651
652      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
653      public Builder typePropertyName(String value) {
654         super.typePropertyName(value);
655         return this;
656      }
657
658      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
659      public Builder typePropertyName(Class<?> on, String value) {
660         super.typePropertyName(on, value);
661         return this;
662      }
663
664      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
665      public Builder useEnumNames() {
666         super.useEnumNames();
667         return this;
668      }
669
670      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
671      public Builder useJavaBeanIntrospector() {
672         super.useJavaBeanIntrospector();
673         return this;
674      }
675
676      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
677      public Builder autoCloseStreams() {
678         super.autoCloseStreams();
679         return this;
680      }
681
682      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
683      public Builder autoCloseStreams(boolean value) {
684         super.autoCloseStreams(value);
685         return this;
686      }
687
688      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
689      public Builder consumes(String value) {
690         super.consumes(value);
691         return this;
692      }
693
694      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
695      public Builder debugOutputLines(int value) {
696         super.debugOutputLines(value);
697         return this;
698      }
699
700      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
701      public Builder listener(Class<? extends org.apache.juneau.parser.ParserListener> value) {
702         super.listener(value);
703         return this;
704      }
705
706      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
707      public Builder strict() {
708         super.strict();
709         return this;
710      }
711
712      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
713      public Builder strict(boolean value) {
714         super.strict(value);
715         return this;
716      }
717
718      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
719      public Builder trimStrings() {
720         super.trimStrings();
721         return this;
722      }
723
724      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
725      public Builder trimStrings(boolean value) {
726         super.trimStrings(value);
727         return this;
728      }
729
730      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
731      public Builder unbuffered() {
732         super.unbuffered();
733         return this;
734      }
735
736      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
737      public Builder unbuffered(boolean value) {
738         super.unbuffered(value);
739         return this;
740      }
741
742      @Override /* GENERATED - org.apache.juneau.parser.ReaderParser.Builder */
743      public Builder fileCharset(Charset value) {
744         super.fileCharset(value);
745         return this;
746      }
747
748      @Override /* GENERATED - org.apache.juneau.parser.ReaderParser.Builder */
749      public Builder streamCharset(Charset value) {
750         super.streamCharset(value);
751         return this;
752      }
753
754      // </FluentSetters>
755   }
756
757   //-------------------------------------------------------------------------------------------------------------------
758   // Instance
759   //-------------------------------------------------------------------------------------------------------------------
760
761   final boolean validateEnd;
762
763   private final Map<ClassMeta<?>,JsonClassMeta> jsonClassMetas = new ConcurrentHashMap<>();
764   private final Map<BeanPropertyMeta,JsonBeanPropertyMeta> jsonBeanPropertyMetas = new ConcurrentHashMap<>();
765
766   /**
767    * Constructor.
768    *
769    * @param builder The builder for this object.
770    */
771   public JsonParser(Builder builder) {
772      super(builder);
773      validateEnd = builder.validateEnd;
774   }
775
776   @Override /* Context */
777   public Builder copy() {
778      return new Builder(this);
779   }
780
781   @Override /* Context */
782   public JsonParserSession.Builder createSession() {
783      return JsonParserSession.create(this);
784   }
785
786   @Override /* Context */
787   public JsonParserSession getSession() {
788      return createSession().build();
789   }
790
791   //-----------------------------------------------------------------------------------------------------------------
792   // Extended metadata
793   //-----------------------------------------------------------------------------------------------------------------
794
795   @Override /* JsonMetaProvider */
796   public JsonClassMeta getJsonClassMeta(ClassMeta<?> cm) {
797      JsonClassMeta m = jsonClassMetas.get(cm);
798      if (m == null) {
799         m = new JsonClassMeta(cm, this);
800         jsonClassMetas.put(cm, m);
801      }
802      return m;
803   }
804
805   @Override /* JsonMetaProvider */
806   public JsonBeanPropertyMeta getJsonBeanPropertyMeta(BeanPropertyMeta bpm) {
807      if (bpm == null)
808         return JsonBeanPropertyMeta.DEFAULT;
809      JsonBeanPropertyMeta m = jsonBeanPropertyMetas.get(bpm);
810      if (m == null) {
811         m = new JsonBeanPropertyMeta(bpm.getDelegateFor(), this);
812         jsonBeanPropertyMetas.put(bpm, m);
813      }
814      return m;
815   }
816
817   //-----------------------------------------------------------------------------------------------------------------
818   // Properties
819   //-----------------------------------------------------------------------------------------------------------------
820
821   /**
822    * Validate end.
823    *
824    * @see Builder#validateEnd()
825    * @return
826    *    <jk>true</jk> if after parsing a POJO from the input, verifies that the remaining input in
827    *    the stream consists of only comments or whitespace.
828    */
829   protected final boolean isValidateEnd() {
830      return validateEnd;
831   }
832}