• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Jackson JSON-processor.
2  *
3  * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi
4  */
5 package com.fasterxml.jackson.core;
6 
7 import java.io.*;
8 import java.math.BigDecimal;
9 import java.math.BigInteger;
10 import java.util.concurrent.atomic.AtomicBoolean;
11 import java.util.concurrent.atomic.AtomicInteger;
12 import java.util.concurrent.atomic.AtomicLong;
13 
14 import com.fasterxml.jackson.core.JsonParser.NumberType;
15 import com.fasterxml.jackson.core.io.CharacterEscapes;
16 import com.fasterxml.jackson.core.type.WritableTypeId;
17 import com.fasterxml.jackson.core.type.WritableTypeId.Inclusion;
18 import com.fasterxml.jackson.core.util.JacksonFeatureSet;
19 import com.fasterxml.jackson.core.util.VersionUtil;
20 
21 import static com.fasterxml.jackson.core.JsonTokenId.*;
22 
23 /**
24  * Base class that defines public API for writing JSON content.
25  * Instances are created using factory methods of
26  * a {@link JsonFactory} instance.
27  *
28  * @author Tatu Saloranta
29  */
30 public abstract class JsonGenerator
31     implements Closeable, Flushable, Versioned
32 {
33     /**
34      * Default set of {@link StreamReadCapability}ies that may be used as
35      * basis for format-specific readers (or as bogus instance if non-null
36      * set needs to be passed).
37      *
38      * @since 2.12
39      */
40     protected final static JacksonFeatureSet<StreamWriteCapability> DEFAULT_WRITE_CAPABILITIES
41         = JacksonFeatureSet.fromDefaults(StreamWriteCapability.values());
42 
43     /**
44      * Default set of {@link StreamReadCapability}ies for typical textual formats,
45      * to use either as-is, or as a base with possible differences.
46      *
47      * @since 2.12
48      */
49     protected final static JacksonFeatureSet<StreamWriteCapability> DEFAULT_TEXTUAL_WRITE_CAPABILITIES
50         = DEFAULT_WRITE_CAPABILITIES.with(StreamWriteCapability.CAN_WRITE_FORMATTED_NUMBERS);
51 
52     /**
53      * Default set of {@link StreamReadCapability}ies for typical binary formats,
54      * to use either as-is, or as a base with possible differences.
55      *
56      * @since 2.12
57      */
58     protected final static JacksonFeatureSet<StreamWriteCapability> DEFAULT_BINARY_WRITE_CAPABILITIES
59         = DEFAULT_WRITE_CAPABILITIES.with(StreamWriteCapability.CAN_WRITE_BINARY_NATIVELY);
60 
61     /**
62      * Enumeration that defines all togglable features for generators.
63      */
64     public enum Feature {
65         // // Low-level I/O / content features
66 
67         /**
68          * Feature that determines whether generator will automatically
69          * close underlying output target that is NOT owned by the
70          * generator.
71          * If disabled, calling application has to separately
72          * close the underlying {@link OutputStream} and {@link Writer}
73          * instances used to create the generator. If enabled, generator
74          * will handle closing, as long as generator itself gets closed:
75          * this happens when end-of-input is encountered, or generator
76          * is closed by a call to {@link JsonGenerator#close}.
77          *<p>
78          * Feature is enabled by default.
79          */
80         AUTO_CLOSE_TARGET(true),
81 
82         /**
83          * Feature that determines what happens when the generator is
84          * closed while there are still unmatched
85          * {@link JsonToken#START_ARRAY} or {@link JsonToken#START_OBJECT}
86          * entries in output content. If enabled, such Array(s) and/or
87          * Object(s) are automatically closed; if disabled, nothing
88          * specific is done.
89          *<p>
90          * Feature is enabled by default.
91          */
92         AUTO_CLOSE_JSON_CONTENT(true),
93 
94         /**
95          * Feature that specifies that calls to {@link #flush} will cause
96          * matching <code>flush()</code> to underlying {@link OutputStream}
97          * or {@link Writer}; if disabled this will not be done.
98          * Main reason to disable this feature is to prevent flushing at
99          * generator level, if it is not possible to prevent method being
100          * called by other code (like <code>ObjectMapper</code> or third
101          * party libraries).
102          *<p>
103          * Feature is enabled by default.
104          */
105         FLUSH_PASSED_TO_STREAM(true),
106 
107         // // Quoting-related features
108 
109         /**
110          * Feature that determines whether JSON Object field names are
111          * quoted using double-quotes, as specified by JSON specification
112          * or not. Ability to disable quoting was added to support use
113          * cases where they are not usually expected, which most commonly
114          * occurs when used straight from Javascript.
115          *<p>
116          * Feature is enabled by default (since it is required by JSON specification).
117          *
118          * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#QUOTE_FIELD_NAMES} instead
119          */
120         @Deprecated
121         QUOTE_FIELD_NAMES(true),
122 
123         /**
124          * Feature that determines whether "exceptional" (not real number)
125          * float/double values are output as quoted strings.
126          * The values checked are Double.Nan,
127          * Double.POSITIVE_INFINITY and Double.NEGATIVE_INIFINTY (and
128          * associated Float values).
129          * If feature is disabled, these numbers are still output using
130          * associated literal values, resulting in non-conformant
131          * output.
132          *<p>
133          * Feature is enabled by default.
134          *
135          * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#WRITE_NAN_AS_STRINGS} instead
136          */
137          @Deprecated
138         QUOTE_NON_NUMERIC_NUMBERS(true),
139 
140         // // Character escaping features
141 
142         /**
143          * Feature that specifies that all characters beyond 7-bit ASCII
144          * range (i.e. code points of 128 and above) need to be output
145          * using format-specific escapes (for JSON, backslash escapes),
146          * if format uses escaping mechanisms (which is generally true
147          * for textual formats but not for binary formats).
148          *<p>
149          * Note that this setting may not necessarily make sense for all
150          * data formats (for example, binary formats typically do not use
151          * any escaping mechanisms; and some textual formats do not have
152          * general-purpose escaping); if so, settings is simply ignored.
153          * Put another way, effects of this feature are data-format specific.
154          *<p>
155          * Feature is disabled by default.
156          *
157          * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#ESCAPE_NON_ASCII} instead
158          */
159         @Deprecated
160         ESCAPE_NON_ASCII(false),
161 
162         // // Datatype coercion features
163 
164         /**
165          * Feature that forces all Java numbers to be written as Strings,
166          * even if the underlying data format has non-textual representation
167          * (which is the case for JSON as well as all binary formats).
168          * Default state is 'false', meaning that Java numbers are to
169          * be serialized using basic numeric serialization (as JSON
170          * numbers, integral or floating point, for example).
171          * If enabled, all such numeric values are instead written out as
172          * textual values (which for JSON means quoted in double-quotes).
173          *<p>
174          * One use case is to avoid problems with Javascript limitations:
175          * since Javascript standard specifies that all number handling
176          * should be done using 64-bit IEEE 754 floating point values,
177          * result being that some 64-bit integer values can not be
178          * accurately represent (as mantissa is only 51 bit wide).
179          *<p>
180          * Feature is disabled by default.
181          *
182          * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#WRITE_NUMBERS_AS_STRINGS} instead
183          */
184         @Deprecated
185         WRITE_NUMBERS_AS_STRINGS(false),
186 
187         /**
188          * Feature that determines whether {@link java.math.BigDecimal} entries are
189          * serialized using {@link java.math.BigDecimal#toPlainString()} to prevent
190          * values to be written using scientific notation.
191          *<p>
192          * NOTE: only affects generators that serialize {@link java.math.BigDecimal}s
193          * using textual representation (textual formats but potentially some binary
194          * formats).
195          *<p>
196          * Feature is disabled by default, so default output mode is used; this generally
197          * depends on how {@link BigDecimal} has been created.
198          *
199          * @since 2.3
200          */
201         WRITE_BIGDECIMAL_AS_PLAIN(false),
202 
203         // // Schema/Validity support features
204 
205         /**
206          * Feature that determines whether {@link JsonGenerator} will explicitly
207          * check that no duplicate JSON Object field names are written.
208          * If enabled, generator will check all names within context and report
209          * duplicates by throwing a {@link JsonGenerationException}; if disabled,
210          * no such checking will be done. Assumption in latter case is
211          * that caller takes care of not trying to write duplicate names.
212          *<p>
213          * Note that enabling this feature will incur performance overhead
214          * due to having to store and check additional information.
215          *<p>
216          * Feature is disabled by default.
217          *
218          * @since 2.3
219          */
220         STRICT_DUPLICATE_DETECTION(false),
221 
222         /**
223          * Feature that determines what to do if the underlying data format requires knowledge
224          * of all properties to output, and if no definition is found for a property that
225          * caller tries to write. If enabled, such properties will be quietly ignored;
226          * if disabled, a {@link JsonProcessingException} will be thrown to indicate the
227          * problem.
228          * Typically most textual data formats do NOT require schema information (although
229          * some do, such as CSV), whereas many binary data formats do require definitions
230          * (such as Avro, protobuf), although not all (Smile, CBOR, BSON and MessagePack do not).
231          *<p>
232          * Note that support for this feature is implemented by individual data format
233          * module, if (and only if) it makes sense for the format in question. For JSON,
234          * for example, this feature has no effect as properties need not be pre-defined.
235          *<p>
236          * Feature is disabled by default, meaning that if the underlying data format
237          * requires knowledge of all properties to output, attempts to write an unknown
238          * property will result in a {@link JsonProcessingException}
239          *
240          * @since 2.5
241          */
242         IGNORE_UNKNOWN(false),
243         ;
244 
245         private final boolean _defaultState;
246         private final int _mask;
247 
248         /**
249          * Method that calculates bit set (flags) of all features that
250          * are enabled by default.
251          */
collectDefaults()252         public static int collectDefaults()
253         {
254             int flags = 0;
255             for (Feature f : values()) {
256                 if (f.enabledByDefault()) {
257                     flags |= f.getMask();
258                 }
259             }
260             return flags;
261         }
262 
Feature(boolean defaultState)263         private Feature(boolean defaultState) {
264             _defaultState = defaultState;
265             _mask = (1 << ordinal());
266         }
267 
enabledByDefault()268         public boolean enabledByDefault() { return _defaultState; }
269 
270         /**
271          * @since 2.3
272          */
enabledIn(int flags)273         public boolean enabledIn(int flags) { return (flags & _mask) != 0; }
274 
getMask()275         public int getMask() { return _mask; }
276     }
277 
278     /*
279     /**********************************************************
280     /* Configuration
281     /**********************************************************
282      */
283 
284     /**
285      * Object that handles pretty-printing (usually additional
286      * white space to make results more human-readable) during
287      * output. If null, no pretty-printing is done.
288      */
289     protected PrettyPrinter _cfgPrettyPrinter;
290 
291     /*
292     /**********************************************************
293     /* Construction, initialization
294     /**********************************************************
295      */
296 
JsonGenerator()297     protected JsonGenerator() { }
298 
299     /**
300      * Method that can be called to set or reset the object to
301      * use for writing Java objects as JsonContent
302      * (using method {@link #writeObject}).
303      *
304      * @return Generator itself (this), to allow chaining
305      */
setCodec(ObjectCodec oc)306     public abstract JsonGenerator setCodec(ObjectCodec oc);
307 
308     /**
309      * Method for accessing the object used for writing Java
310      * object as JSON content
311      * (using method {@link #writeObject}).
312      */
getCodec()313     public abstract ObjectCodec getCodec();
314 
315     /**
316      * Accessor for finding out version of the bundle that provided this generator instance.
317      */
318     @Override
version()319     public abstract Version version();
320 
321     /*
322     /**********************************************************
323     /* Public API, Feature configuration
324     /**********************************************************
325      */
326 
327     /**
328      * Method for enabling specified parser features:
329      * check {@link Feature} for list of available features.
330      *
331      * @return Generator itself (this), to allow chaining
332      */
enable(Feature f)333     public abstract JsonGenerator enable(Feature f);
334 
335     /**
336      * Method for disabling specified  features
337      * (check {@link Feature} for list of features)
338      *
339      * @return Generator itself (this), to allow chaining
340      */
disable(Feature f)341     public abstract JsonGenerator disable(Feature f);
342 
343     /**
344      * Method for enabling or disabling specified feature:
345      * check {@link Feature} for list of available features.
346      *
347      * @return Generator itself (this), to allow chaining
348      */
configure(Feature f, boolean state)349     public final JsonGenerator configure(Feature f, boolean state) {
350         if (state) enable(f); else disable(f);
351         return this;
352     }
353 
354     /**
355      * Method for checking whether given feature is enabled.
356      * Check {@link Feature} for list of available features.
357      */
isEnabled(Feature f)358     public abstract boolean isEnabled(Feature f);
359 
360     /**
361      * @since 2.10
362      */
isEnabled(StreamWriteFeature f)363     public boolean isEnabled(StreamWriteFeature f) {
364         return isEnabled(f.mappedFeature());
365     }
366 
367     /**
368      * Bulk access method for getting state of all standard (non-dataformat-specific)
369      * {@link JsonGenerator.Feature}s.
370      *
371      * @return Bit mask that defines current states of all standard {@link JsonGenerator.Feature}s.
372      *
373      * @since 2.3
374      */
getFeatureMask()375     public abstract int getFeatureMask();
376 
377     /**
378      * Bulk set method for (re)setting states of all standard {@link Feature}s
379      *
380      * @since 2.3
381      *
382      * @param values Bitmask that defines which {@link Feature}s are enabled
383      *    and which disabled
384      *
385      * @return This parser object, to allow chaining of calls
386      *
387      * @deprecated Since 2.7, use {@link #overrideStdFeatures(int, int)} instead -- remove from 2.9
388      */
389     @Deprecated
setFeatureMask(int values)390     public abstract JsonGenerator setFeatureMask(int values);
391 
392     /**
393      * Bulk set method for (re)setting states of features specified by <code>mask</code>.
394      * Functionally equivalent to
395      *<code>
396      *    int oldState = getFeatureMask();
397      *    int newState = (oldState &amp; ~mask) | (values &amp; mask);
398      *    setFeatureMask(newState);
399      *</code>
400      * but preferred as this lets caller more efficiently specify actual changes made.
401      *
402      * @param values Bit mask of set/clear state for features to change
403      * @param mask Bit mask of features to change
404      *
405      * @since 2.6
406      */
overrideStdFeatures(int values, int mask)407     public JsonGenerator overrideStdFeatures(int values, int mask) {
408         int oldState = getFeatureMask();
409         int newState = (oldState & ~mask) | (values & mask);
410         return setFeatureMask(newState);
411     }
412 
413     /**
414      * Bulk access method for getting state of all {@link FormatFeature}s, format-specific
415      * on/off configuration settings.
416      *
417      * @return Bit mask that defines current states of all standard {@link FormatFeature}s.
418      *
419      * @since 2.6
420      */
getFormatFeatures()421     public int getFormatFeatures() {
422         return 0;
423     }
424 
425     /**
426      * Bulk set method for (re)setting states of {@link FormatFeature}s,
427      * by specifying values (set / clear) along with a mask, to determine
428      * which features to change, if any.
429      *<p>
430      * Default implementation will simply throw an exception to indicate that
431      * the generator implementation does not support any {@link FormatFeature}s.
432      *
433      * @param values Bit mask of set/clear state for features to change
434      * @param mask Bit mask of features to change
435      *
436      * @since 2.6
437      */
overrideFormatFeatures(int values, int mask)438     public JsonGenerator overrideFormatFeatures(int values, int mask) {
439         // 08-Oct-2018, tatu: For 2.10 we actually do get `JsonWriteFeature`s, although they
440         //    are (for 2.x only, not for 3.x) mapper to legacy settings. So do not freak out:
441 //        throw new IllegalArgumentException("No FormatFeatures defined for generator of type "+getClass().getName());
442         return this;
443     }
444 
445     /*
446     /**********************************************************
447     /* Public API, Schema configuration
448     /**********************************************************
449      */
450 
451     /**
452      * Method to call to make this generator use specified schema.
453      * Method must be called before generating any content, right after instance
454      * has been created.
455      * Note that not all generators support schemas; and those that do usually only
456      * accept specific types of schemas: ones defined for data format this generator
457      * produces.
458      *<p>
459      * If generator does not support specified schema, {@link UnsupportedOperationException}
460      * is thrown.
461      *
462      * @param schema Schema to use
463      *
464      * @throws UnsupportedOperationException if generator does not support schema
465      */
setSchema(FormatSchema schema)466     public void setSchema(FormatSchema schema) {
467         throw new UnsupportedOperationException(String.format(
468                 "Generator of type %s does not support schema of type '%s'",
469                 getClass().getName(), schema.getSchemaType()));
470     }
471 
472     /**
473      * Method for accessing Schema that this parser uses, if any.
474      * Default implementation returns null.
475      *
476      * @since 2.1
477      */
getSchema()478     public FormatSchema getSchema() { return null; }
479 
480     /*
481     /**********************************************************
482     /* Public API, other configuration
483     /**********************************************************
484       */
485 
486     /**
487      * Method for setting a custom pretty printer, which is usually
488      * used to add indentation for improved human readability.
489      * By default, generator does not do pretty printing.
490      *<p>
491      * To use the default pretty printer that comes with core
492      * Jackson distribution, call {@link #useDefaultPrettyPrinter}
493      * instead.
494      *
495      * @return Generator itself (this), to allow chaining
496      */
setPrettyPrinter(PrettyPrinter pp)497     public JsonGenerator setPrettyPrinter(PrettyPrinter pp) {
498         _cfgPrettyPrinter = pp;
499         return this;
500     }
501 
502     /**
503      * Accessor for checking whether this generator has a configured
504      * {@link PrettyPrinter}; returns it if so, null if none configured.
505      *
506      * @since 2.1
507      */
getPrettyPrinter()508     public PrettyPrinter getPrettyPrinter() {
509         return _cfgPrettyPrinter;
510     }
511 
512     /**
513      * Convenience method for enabling pretty-printing using
514      * the default pretty printer
515      * ({@link com.fasterxml.jackson.core.util.DefaultPrettyPrinter}).
516      *
517      * @return Generator itself (this), to allow chaining
518      */
useDefaultPrettyPrinter()519     public abstract JsonGenerator useDefaultPrettyPrinter();
520 
521     /**
522      * Method that can be called to request that generator escapes
523      * all character codes above specified code point (if positive value);
524      * or, to not escape any characters except for ones that must be
525      * escaped for the data format (if -1).
526      * To force escaping of all non-ASCII characters, for example,
527      * this method would be called with value of 127.
528      *<p>
529      * Note that generators are NOT required to support setting of value
530      * higher than 127, because there are other ways to affect quoting
531      * (or lack thereof) of character codes between 0 and 127.
532      * Not all generators support concept of escaping, either; if so,
533      * calling this method will have no effect.
534      *<p>
535      * Default implementation does nothing; sub-classes need to redefine
536      * it according to rules of supported data format.
537      *
538      * @param charCode Either -1 to indicate that no additional escaping
539      *   is to be done; or highest code point not to escape (meaning higher
540      *   ones will be), if positive value.
541      */
setHighestNonEscapedChar(int charCode)542     public JsonGenerator setHighestNonEscapedChar(int charCode) { return this; }
543 
544     /**
545      * Accessor method for testing what is the highest unescaped character
546      * configured for this generator. This may be either positive value
547      * (when escaping configuration has been set and is in effect), or
548      * 0 to indicate that no additional escaping is in effect.
549      * Some generators may not support additional escaping: for example,
550      * generators for binary formats that do not use escaping should
551      * simply return 0.
552      *
553      * @return Currently active limitation for highest non-escaped character,
554      *   if defined; or 0 to indicate no additional escaping is performed.
555      */
getHighestEscapedChar()556     public int getHighestEscapedChar() { return 0; }
557 
558     /**
559      * Method for accessing custom escapes factory uses for {@link JsonGenerator}s
560      * it creates.
561      */
getCharacterEscapes()562     public CharacterEscapes getCharacterEscapes() { return null; }
563 
564     /**
565      * Method for defining custom escapes factory uses for {@link JsonGenerator}s
566      * it creates.
567      *<p>
568      * Default implementation does nothing and simply returns this instance.
569      */
setCharacterEscapes(CharacterEscapes esc)570     public JsonGenerator setCharacterEscapes(CharacterEscapes esc) { return this; }
571 
572     /**
573      * Method that allows overriding String used for separating root-level
574      * JSON values (default is single space character)
575      *<p>
576      * Default implementation throws {@link UnsupportedOperationException}.
577      *
578      * @param sep Separator to use, if any; null means that no separator is
579      *   automatically added
580      *
581      * @since 2.1
582      */
setRootValueSeparator(SerializableString sep)583     public JsonGenerator setRootValueSeparator(SerializableString sep) {
584         throw new UnsupportedOperationException();
585     }
586 
587     /*
588     /**********************************************************
589     /* Public API, output state access
590     /**********************************************************
591      */
592 
593     /**
594      * Method that can be used to get access to object that is used
595      * as target for generated output; this is usually either
596      * {@link OutputStream} or {@link Writer}, depending on what
597      * generator was constructed with.
598      * Note that returned value may be null in some cases; including
599      * case where implementation does not want to exposed raw
600      * source to caller.
601      * In cases where output has been decorated, object returned here
602      * is the decorated version; this allows some level of interaction
603      * between users of generator and decorator object.
604      *<p>
605      * In general use of this accessor should be considered as
606      * "last effort", i.e. only used if no other mechanism is applicable.
607      */
getOutputTarget()608     public Object getOutputTarget() {
609         return null;
610     }
611 
612     /**
613      * Method for verifying amount of content that is buffered by generator
614      * but not yet flushed to the underlying target (stream, writer),
615      * in units (byte, char) that the generator implementation uses for buffering;
616      * or -1 if this information is not available.
617      * Unit used is often the same as the unit of underlying target (that is,
618      * `byte` for {@link java.io.OutputStream}, `char` for {@link java.io.Writer}),
619      * but may differ if buffering is done before encoding.
620      * Default JSON-backed implementations do use matching units.
621      *<p>
622      * Note: non-JSON implementations will be retrofitted for 2.6 and beyond;
623      * please report if you see -1 (missing override)
624      *
625      * @return Amount of content buffered in internal units, if amount known and
626      *    accessible; -1 if not accessible.
627      *
628      * @since 2.6
629      */
getOutputBuffered()630     public int getOutputBuffered() {
631         return -1;
632     }
633 
634     /**
635      * Helper method, usually equivalent to:
636      *<code>
637      *   getOutputContext().getCurrentValue();
638      *</code>
639      *<p>
640      * Note that "current value" is NOT populated (or used) by Streaming parser;
641      * it is only used by higher-level data-binding functionality.
642      * The reason it is included here is that it can be stored and accessed hierarchically,
643      * and gets passed through data-binding.
644      *
645      * @since 2.5
646      */
getCurrentValue()647     public Object getCurrentValue() {
648         JsonStreamContext ctxt = getOutputContext();
649         return (ctxt == null) ? null : ctxt.getCurrentValue();
650     }
651 
652     /**
653      * Helper method, usually equivalent to:
654      *<code>
655      *   getOutputContext().setCurrentValue(v);
656      *</code>
657      *
658      * @since 2.5
659      */
setCurrentValue(Object v)660     public void setCurrentValue(Object v) {
661         JsonStreamContext ctxt = getOutputContext();
662         if (ctxt != null) {
663             ctxt.setCurrentValue(v);
664         }
665     }
666 
667     /*
668     /**********************************************************
669     /* Public API, capability introspection methods
670     /**********************************************************
671      */
672 
673     /**
674      * Method that can be used to verify that given schema can be used with
675      * this generator (using {@link #setSchema}).
676      *
677      * @param schema Schema to check
678      *
679      * @return True if this generator can use given schema; false if not
680      */
canUseSchema(FormatSchema schema)681     public boolean canUseSchema(FormatSchema schema) { return false; }
682 
683     /**
684      * Introspection method that may be called to see if the underlying
685      * data format supports some kind of Object Ids natively (many do not;
686      * for example, JSON doesn't).
687      * This method <b>must</b> be called prior to calling
688      * {@link #writeObjectId} or {@link #writeObjectRef}.
689      *<p>
690      * Default implementation returns false; overridden by data formats
691      * that do support native Object Ids. Caller is expected to either
692      * use a non-native notation (explicit property or such), or fail,
693      * in case it can not use native object ids.
694      *
695      * @since 2.3
696      */
canWriteObjectId()697     public boolean canWriteObjectId() { return false; }
698 
699     /**
700      * Introspection method that may be called to see if the underlying
701      * data format supports some kind of Type Ids natively (many do not;
702      * for example, JSON doesn't).
703      * This method <b>must</b> be called prior to calling
704      * {@link #writeTypeId}.
705      *<p>
706      * Default implementation returns false; overridden by data formats
707      * that do support native Type Ids. Caller is expected to either
708      * use a non-native notation (explicit property or such), or fail,
709      * in case it can not use native type ids.
710      *
711      * @since 2.3
712      */
canWriteTypeId()713     public boolean canWriteTypeId() { return false; }
714 
715     /**
716      * Introspection method that may be called to see if the underlying
717      * data format supports "native" binary data; that is, an efficient
718      * output of binary content without encoding.
719      *<p>
720      * Default implementation returns false; overridden by data formats
721      * that do support native binary content.
722      *
723      * @since 2.3
724      */
canWriteBinaryNatively()725     public boolean canWriteBinaryNatively() { return false; }
726 
727     /**
728      * Introspection method to call to check whether it is ok to omit
729      * writing of Object fields or not. Most formats do allow omission,
730      * but certain positional formats (such as CSV) require output of
731      * placeholders, even if no real values are to be emitted.
732      *
733      * @since 2.3
734      */
canOmitFields()735     public boolean canOmitFields() { return true; }
736 
737     /**
738      * Introspection method to call to check whether it is possible
739      * to write numbers using {@link #writeNumber(java.lang.String)}
740      * using possible custom format, or not. Typically textual formats
741      * allow this (and JSON specifically does), whereas binary formats
742      * do not allow this (except by writing them as Strings).
743      * Usual reason for calling this method is to check whether custom
744      * formatting of numbers may be applied by higher-level code (databinding)
745      * or not.
746      *
747      * @since 2.8
748      */
canWriteFormattedNumbers()749     public boolean canWriteFormattedNumbers() { return false; }
750 
751     /**
752      * Accessor for getting metadata on capabilities of this parser, based on
753      * underlying data format being read (directly or indirectly).
754      *
755      * @return Set of read capabilities for content to read via this parser
756      *
757      * @since 2.12
758      */
getWriteCapabilities()759     public JacksonFeatureSet<StreamWriteCapability> getWriteCapabilities() {
760         return DEFAULT_WRITE_CAPABILITIES;
761     }
762 
763     /*
764     /**********************************************************
765     /* Public API, write methods, structural
766     /**********************************************************
767      */
768 
769     /**
770      * Method for writing starting marker of a Array value
771      * (for JSON this is character '['; plus possible white space decoration
772      * if pretty-printing is enabled).
773      *<p>
774      * Array values can be written in any context where values
775      * are allowed: meaning everywhere except for when
776      * a field name is expected.
777      */
writeStartArray()778     public abstract void writeStartArray() throws IOException;
779 
780     /**
781      * Method for writing start marker of an Array value, similar
782      * to {@link #writeStartArray()}, but also specifying how many
783      * elements will be written for the array before calling
784      * {@link #writeEndArray()}.
785      *<p>
786      * Default implementation simply calls {@link #writeStartArray()}.
787      *
788      * @param size Number of elements this array will have: actual
789      *   number of values written (before matching call to
790      *   {@link #writeEndArray()} MUST match; generator MAY verify
791      *   this is the case.
792      *
793      * @since 2.4
794      *
795      * @deprecated Since 2.12 Use {@link #writeStartArray(Object, int)} instead
796      */
797     @Deprecated
writeStartArray(int size)798     public void writeStartArray(int size) throws IOException {
799         writeStartArray();
800     }
801 
802     /**
803      * @since 2.10
804      */
writeStartArray(Object forValue)805     public void writeStartArray(Object forValue) throws IOException {
806         writeStartArray();
807         setCurrentValue(forValue);
808     }
809 
810     /**
811      * @since 2.10
812      */
writeStartArray(Object forValue, int size)813     public void writeStartArray(Object forValue, int size) throws IOException {
814         writeStartArray(size);
815         setCurrentValue(forValue);
816     }
817 
818     /**
819      * Method for writing closing marker of a JSON Array value
820      * (character ']'; plus possible white space decoration
821      * if pretty-printing is enabled).
822      *<p>
823      * Marker can be written if the innermost structured type
824      * is Array.
825      */
writeEndArray()826     public abstract void writeEndArray() throws IOException;
827 
828     /**
829      * Method for writing starting marker of an Object value
830      * (character '{'; plus possible white space decoration
831      * if pretty-printing is enabled).
832      *<p>
833      * Object values can be written in any context where values
834      * are allowed: meaning everywhere except for when
835      * a field name is expected.
836      */
writeStartObject()837     public abstract void writeStartObject() throws IOException;
838 
839     /**
840      * Method for writing starting marker of an Object value
841      * to represent the given Java Object value.
842      * Argument is offered as metadata, but more
843      * importantly it should be assigned as the "current value"
844      * for the Object content that gets constructed and initialized.
845      *<p>
846      * Object values can be written in any context where values
847      * are allowed: meaning everywhere except for when
848      * a field name is expected.
849      *
850      * @since 2.8
851      */
writeStartObject(Object forValue)852     public void writeStartObject(Object forValue) throws IOException
853     {
854         writeStartObject();
855         setCurrentValue(forValue);
856     }
857 
858     /**
859      * Method for writing starting marker of an Object value
860      * to represent the given Java Object value.
861      * Argument is offered as metadata, but more
862      * importantly it should be assigned as the "current value"
863      * for the Object content that gets constructed and initialized.
864      * In addition, caller knows number of key/value pairs ("properties")
865      * that will get written for the Object value: this is relevant for
866      * some format backends (but not, as an example, for JSON).
867      *<p>
868      * Object values can be written in any context where values
869      * are allowed: meaning everywhere except for when
870      * a field name is expected.
871      *
872      * @since 2.10
873      */
writeStartObject(Object forValue, int size)874     public void writeStartObject(Object forValue, int size) throws IOException
875     {
876         writeStartObject();
877         setCurrentValue(forValue);
878     }
879 
880     /**
881      * Method for writing closing marker of an Object value
882      * (character '}'; plus possible white space decoration
883      * if pretty-printing is enabled).
884      *<p>
885      * Marker can be written if the innermost structured type
886      * is Object, and the last written event was either a
887      * complete value, or START-OBJECT marker (see JSON specification
888      * for more details).
889      */
writeEndObject()890     public abstract void writeEndObject() throws IOException;
891 
892     /**
893      * Method for writing a field name (JSON String surrounded by
894      * double quotes: syntactically identical to a JSON String value),
895      * possibly decorated by white space if pretty-printing is enabled.
896      *<p>
897      * Field names can only be written in Object context (check out
898      * JSON specification for details), when field name is expected
899      * (field names alternate with values).
900      */
writeFieldName(String name)901     public abstract void writeFieldName(String name) throws IOException;
902 
903     /**
904      * Method similar to {@link #writeFieldName(String)}, main difference
905      * being that it may perform better as some of processing (such as
906      * quoting of certain characters, or encoding into external encoding
907      * if supported by generator) can be done just once and reused for
908      * later calls.
909      *<p>
910      * Default implementation simple uses unprocessed name container in
911      * serialized String; implementations are strongly encouraged to make
912      * use of more efficient methods argument object has.
913      */
writeFieldName(SerializableString name)914     public abstract void writeFieldName(SerializableString name) throws IOException;
915 
916     /**
917      * Alternative to {@link #writeFieldName(String)} that may be used
918      * in cases where property key is of numeric type; either where
919      * underlying format supports such notion (some binary formats do,
920      * unlike JSON), or for convenient conversion into String presentation.
921      * Default implementation will simply convert id into <code>String</code>
922      * and call {@link #writeFieldName(String)}.
923      *
924      * @since 2.8
925      */
writeFieldId(long id)926     public void writeFieldId(long id) throws IOException {
927         writeFieldName(Long.toString(id));
928     }
929 
930     /*
931     /**********************************************************
932     /* Public API, write methods, scalar arrays (2.8)
933     /**********************************************************
934      */
935 
936     /**
937      * Value write method that can be called to write a single
938      * array (sequence of {@link JsonToken#START_ARRAY}, zero or
939      * more {@link JsonToken#VALUE_NUMBER_INT}, {@link JsonToken#END_ARRAY})
940      *
941      * @since 2.8
942      *
943      * @param array Array that contains values to write
944      * @param offset Offset of the first element to write, within array
945      * @param length Number of elements in array to write, from `offset` to `offset + len - 1`
946      */
writeArray(int[] array, int offset, int length)947     public void writeArray(int[] array, int offset, int length) throws IOException
948     {
949         if (array == null) {
950             throw new IllegalArgumentException("null array");
951         }
952         _verifyOffsets(array.length, offset, length);
953         writeStartArray(array, length);
954         for (int i = offset, end = offset+length; i < end; ++i) {
955             writeNumber(array[i]);
956         }
957         writeEndArray();
958     }
959 
960     /**
961      * Value write method that can be called to write a single
962      * array (sequence of {@link JsonToken#START_ARRAY}, zero or
963      * more {@link JsonToken#VALUE_NUMBER_INT}, {@link JsonToken#END_ARRAY})
964      *
965      * @since 2.8
966      *
967      * @param array Array that contains values to write
968      * @param offset Offset of the first element to write, within array
969      * @param length Number of elements in array to write, from `offset` to `offset + len - 1`
970      */
writeArray(long[] array, int offset, int length)971     public void writeArray(long[] array, int offset, int length) throws IOException
972     {
973         if (array == null) {
974             throw new IllegalArgumentException("null array");
975         }
976         _verifyOffsets(array.length, offset, length);
977         writeStartArray(array, length);
978         for (int i = offset, end = offset+length; i < end; ++i) {
979             writeNumber(array[i]);
980         }
981         writeEndArray();
982     }
983 
984     /**
985      * Value write method that can be called to write a single
986      * array (sequence of {@link JsonToken#START_ARRAY}, zero or
987      * more {@link JsonToken#VALUE_NUMBER_FLOAT}, {@link JsonToken#END_ARRAY})
988      *
989      * @since 2.8
990      *
991      * @param array Array that contains values to write
992      * @param offset Offset of the first element to write, within array
993      * @param length Number of elements in array to write, from `offset` to `offset + len - 1`
994      */
writeArray(double[] array, int offset, int length)995     public void writeArray(double[] array, int offset, int length) throws IOException
996     {
997         if (array == null) {
998             throw new IllegalArgumentException("null array");
999         }
1000         _verifyOffsets(array.length, offset, length);
1001         writeStartArray(array, length);
1002         for (int i = offset, end = offset+length; i < end; ++i) {
1003             writeNumber(array[i]);
1004         }
1005         writeEndArray();
1006     }
1007 
1008     /**
1009      * Value write method that can be called to write a single
1010      * array (sequence of {@link JsonToken#START_ARRAY}, zero or
1011      * more {@link JsonToken#VALUE_STRING}, {@link JsonToken#END_ARRAY})
1012      *
1013      * @since 2.11
1014      *
1015      * @param array Array that contains values to write
1016      * @param offset Offset of the first element to write, within array
1017      * @param length Number of elements in array to write, from `offset` to `offset + len - 1`
1018      */
writeArray(String[] array, int offset, int length)1019     public void writeArray(String[] array, int offset, int length) throws IOException
1020     {
1021         if (array == null) {
1022             throw new IllegalArgumentException("null array");
1023         }
1024         _verifyOffsets(array.length, offset, length);
1025         writeStartArray(array, length);
1026         for (int i = offset, end = offset+length; i < end; ++i) {
1027             writeString(array[i]);
1028         }
1029         writeEndArray();
1030     }
1031 
1032     /*
1033     /**********************************************************
1034     /* Public API, write methods, text/String values
1035     /**********************************************************
1036      */
1037 
1038     /**
1039      * Method for outputting a String value. Depending on context
1040      * this means either array element, (object) field value or
1041      * a stand alone String; but in all cases, String will be
1042      * surrounded in double quotes, and contents will be properly
1043      * escaped as required by JSON specification.
1044      */
writeString(String text)1045     public abstract void writeString(String text) throws IOException;
1046 
1047     /**
1048      * Method for outputting a String value. Depending on context
1049      * this means either array element, (object) field value or
1050      * a stand alone String; but in all cases, String will be
1051      * surrounded in double quotes, and contents will be properly
1052      * escaped as required by JSON specification.
1053      * If the reader is null, then write a null.
1054      * If len is &lt; 0, then write all contents of the reader.
1055      * Otherwise, write only len characters.
1056      *
1057      * @since 2.9
1058      */
writeString(Reader reader, int len)1059     public void writeString(Reader reader, int len) throws IOException {
1060         // Let's implement this as "unsupported" to make it easier to add new parser impls
1061         _reportUnsupportedOperation();
1062     }
1063 
1064     /**
1065      * Method for outputting a String value. Depending on context
1066      * this means either array element, (object) field value or
1067      * a stand alone String; but in all cases, String will be
1068      * surrounded in double quotes, and contents will be properly
1069      * escaped as required by JSON specification.
1070      */
writeString(char[] text, int offset, int len)1071     public abstract void writeString(char[] text, int offset, int len) throws IOException;
1072 
1073     /**
1074      * Method similar to {@link #writeString(String)}, but that takes
1075      * {@link SerializableString} which can make this potentially
1076      * more efficient to call as generator may be able to reuse
1077      * quoted and/or encoded representation.
1078      *<p>
1079      * Default implementation just calls {@link #writeString(String)};
1080      * sub-classes should override it with more efficient implementation
1081      * if possible.
1082      */
writeString(SerializableString text)1083     public abstract void writeString(SerializableString text) throws IOException;
1084 
1085     /**
1086      * Method similar to {@link #writeString(String)} but that takes as
1087      * its input a UTF-8 encoded String that is to be output as-is, without additional
1088      * escaping (type of which depends on data format; backslashes for JSON).
1089      * However, quoting that data format requires (like double-quotes for JSON) will be added
1090      * around the value if and as necessary.
1091      *<p>
1092      * Note that some backends may choose not to support this method: for
1093      * example, if underlying destination is a {@link java.io.Writer}
1094      * using this method would require UTF-8 decoding.
1095      * If so, implementation may instead choose to throw a
1096      * {@link UnsupportedOperationException} due to ineffectiveness
1097      * of having to decode input.
1098      */
writeRawUTF8String(byte[] text, int offset, int length)1099     public abstract void writeRawUTF8String(byte[] text, int offset, int length)
1100         throws IOException;
1101 
1102     /**
1103      * Method similar to {@link #writeString(String)} but that takes as its input
1104      * a UTF-8 encoded String which has <b>not</b> been escaped using whatever
1105      * escaping scheme data format requires (for JSON that is backslash-escaping
1106      * for control characters and double-quotes; for other formats something else).
1107      * This means that textual JSON backends need to check if value needs
1108      * JSON escaping, but otherwise can just be copied as is to output.
1109      * Also, quoting that data format requires (like double-quotes for JSON) will be added
1110      * around the value if and as necessary.
1111      *<p>
1112      * Note that some backends may choose not to support this method: for
1113      * example, if underlying destination is a {@link java.io.Writer}
1114      * using this method would require UTF-8 decoding.
1115      * In this case
1116      * generator implementation may instead choose to throw a
1117      * {@link UnsupportedOperationException} due to ineffectiveness
1118      * of having to decode input.
1119      */
writeUTF8String(byte[] text, int offset, int length)1120     public abstract void writeUTF8String(byte[] text, int offset, int length)
1121         throws IOException;
1122 
1123     /*
1124     /**********************************************************
1125     /* Public API, write methods, binary/raw content
1126     /**********************************************************
1127      */
1128 
1129     /**
1130      * Method that will force generator to copy
1131      * input text verbatim with <b>no</b> modifications (including
1132      * that no escaping is done and no separators are added even
1133      * if context [array, object] would otherwise require such).
1134      * If such separators are desired, use
1135      * {@link #writeRawValue(String)} instead.
1136      *<p>
1137      * Note that not all generator implementations necessarily support
1138      * such by-pass methods: those that do not will throw
1139      * {@link UnsupportedOperationException}.
1140      */
writeRaw(String text)1141     public abstract void writeRaw(String text) throws IOException;
1142 
1143     /**
1144      * Method that will force generator to copy
1145      * input text verbatim with <b>no</b> modifications (including
1146      * that no escaping is done and no separators are added even
1147      * if context [array, object] would otherwise require such).
1148      * If such separators are desired, use
1149      * {@link #writeRawValue(String)} instead.
1150      *<p>
1151      * Note that not all generator implementations necessarily support
1152      * such by-pass methods: those that do not will throw
1153      * {@link UnsupportedOperationException}.
1154      */
writeRaw(String text, int offset, int len)1155     public abstract void writeRaw(String text, int offset, int len) throws IOException;
1156 
1157     /**
1158      * Method that will force generator to copy
1159      * input text verbatim with <b>no</b> modifications (including
1160      * that no escaping is done and no separators are added even
1161      * if context [array, object] would otherwise require such).
1162      * If such separators are desired, use
1163      * {@link #writeRawValue(String)} instead.
1164      *<p>
1165      * Note that not all generator implementations necessarily support
1166      * such by-pass methods: those that do not will throw
1167      * {@link UnsupportedOperationException}.
1168      */
writeRaw(char[] text, int offset, int len)1169     public abstract void writeRaw(char[] text, int offset, int len) throws IOException;
1170 
1171     /**
1172      * Method that will force generator to copy
1173      * input text verbatim with <b>no</b> modifications (including
1174      * that no escaping is done and no separators are added even
1175      * if context [array, object] would otherwise require such).
1176      * If such separators are desired, use
1177      * {@link #writeRawValue(String)} instead.
1178      *<p>
1179      * Note that not all generator implementations necessarily support
1180      * such by-pass methods: those that do not will throw
1181      * {@link UnsupportedOperationException}.
1182      */
writeRaw(char c)1183     public abstract void writeRaw(char c) throws IOException;
1184 
1185     /**
1186      * Method that will force generator to copy
1187      * input text verbatim with <b>no</b> modifications (including
1188      * that no escaping is done and no separators are added even
1189      * if context [array, object] would otherwise require such).
1190      * If such separators are desired, use
1191      * {@link #writeRawValue(String)} instead.
1192      *<p>
1193      * Note that not all generator implementations necessarily support
1194      * such by-pass methods: those that do not will throw
1195      * {@link UnsupportedOperationException}.
1196      *<p>
1197      * The default implementation delegates to {@link #writeRaw(String)};
1198      * other backends that support raw inclusion of text are encouraged
1199      * to implement it in more efficient manner (especially if they
1200      * use UTF-8 encoding).
1201      *
1202      * @since 2.1
1203      */
1204 //    public abstract void writeRaw(SerializableString raw) throws IOException;
writeRaw(SerializableString raw)1205     public void writeRaw(SerializableString raw) throws IOException {
1206         writeRaw(raw.getValue());
1207     }
1208 
1209     /**
1210      * Method that will force generator to copy
1211      * input text verbatim without any modifications, but assuming
1212      * it must constitute a single legal JSON value (number, string,
1213      * boolean, null, Array or List). Assuming this, proper separators
1214      * are added if and as needed (comma or colon), and generator
1215      * state updated to reflect this.
1216      */
writeRawValue(String text)1217     public abstract void writeRawValue(String text) throws IOException;
1218 
writeRawValue(String text, int offset, int len)1219     public abstract void writeRawValue(String text, int offset, int len) throws IOException;
1220 
writeRawValue(char[] text, int offset, int len)1221     public abstract void writeRawValue(char[] text, int offset, int len) throws IOException;
1222 
1223     /**
1224      * Method similar to {@link #writeRawValue(String)}, but potentially more
1225      * efficient as it may be able to use pre-encoded content (similar to
1226      * {@link #writeRaw(SerializableString)}.
1227      *
1228      * @since 2.5
1229      */
writeRawValue(SerializableString raw)1230     public void writeRawValue(SerializableString raw) throws IOException {
1231         writeRawValue(raw.getValue());
1232     }
1233 
1234     /**
1235      * Method that will output given chunk of binary data as base64
1236      * encoded, as a complete String value (surrounded by double quotes).
1237      * This method defaults
1238      *<p>
1239      * Note: because JSON Strings can not contain unescaped linefeeds,
1240      * if linefeeds are included (as per last argument), they must be
1241      * escaped. This adds overhead for decoding without improving
1242      * readability.
1243      * Alternatively if linefeeds are not included,
1244      * resulting String value may violate the requirement of base64
1245      * RFC which mandates line-length of 76 characters and use of
1246      * linefeeds. However, all {@link JsonParser} implementations
1247      * are required to accept such "long line base64"; as do
1248      * typical production-level base64 decoders.
1249      *
1250      * @param bv Base64 variant to use: defines details such as
1251      *   whether padding is used (and if so, using which character);
1252      *   what is the maximum line length before adding linefeed,
1253      *   and also the underlying alphabet to use.
1254      */
writeBinary(Base64Variant bv, byte[] data, int offset, int len)1255     public abstract void writeBinary(Base64Variant bv,
1256             byte[] data, int offset, int len) throws IOException;
1257 
1258     /**
1259      * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)},
1260      * but default to using the Jackson default Base64 variant
1261      * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}).
1262      */
writeBinary(byte[] data, int offset, int len)1263     public void writeBinary(byte[] data, int offset, int len) throws IOException {
1264         writeBinary(Base64Variants.getDefaultVariant(), data, offset, len);
1265     }
1266 
1267     /**
1268      * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)},
1269      * but assumes default to using the Jackson default Base64 variant
1270      * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}). Also
1271      * assumes that whole byte array is to be output.
1272      */
writeBinary(byte[] data)1273     public void writeBinary(byte[] data) throws IOException {
1274         writeBinary(Base64Variants.getDefaultVariant(), data, 0, data.length);
1275     }
1276 
1277     /**
1278      * Similar to {@link #writeBinary(Base64Variant,InputStream,int)},
1279      * but assumes default to using the Jackson default Base64 variant
1280      * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}).
1281      *
1282      * @param data InputStream to use for reading binary data to write.
1283      *    Will not be closed after successful write operation
1284      * @param dataLength (optional) number of bytes that will be available;
1285      *    or -1 to be indicate it is not known. Note that implementations
1286      *    need not support cases where length is not known in advance; this
1287      *    depends on underlying data format: JSON output does NOT require length,
1288      *    other formats may
1289      */
writeBinary(InputStream data, int dataLength)1290     public int writeBinary(InputStream data, int dataLength)
1291         throws IOException {
1292         return writeBinary(Base64Variants.getDefaultVariant(), data, dataLength);
1293     }
1294 
1295     /**
1296      * Method similar to {@link #writeBinary(Base64Variant,byte[],int,int)},
1297      * but where input is provided through a stream, allowing for incremental
1298      * writes without holding the whole input in memory.
1299      *
1300      * @param bv Base64 variant to use
1301      * @param data InputStream to use for reading binary data to write.
1302      *    Will not be closed after successful write operation
1303      * @param dataLength (optional) number of bytes that will be available;
1304      *    or -1 to be indicate it is not known.
1305      *    If a positive length is given, <code>data</code> MUST provide at least
1306      *    that many bytes: if not, an exception will be thrown.
1307      *    Note that implementations
1308      *    need not support cases where length is not known in advance; this
1309      *    depends on underlying data format: JSON output does NOT require length,
1310      *    other formats may.
1311      *
1312      * @return Number of bytes read from <code>data</code> and written as binary payload
1313      *
1314      * @since 2.1
1315      */
writeBinary(Base64Variant bv, InputStream data, int dataLength)1316     public abstract int writeBinary(Base64Variant bv,
1317             InputStream data, int dataLength) throws IOException;
1318 
1319     /*
1320     /**********************************************************
1321     /* Public API, write methods, numeric
1322     /**********************************************************
1323      */
1324 
1325     /**
1326      * Method for outputting given value as JSON number.
1327      * Can be called in any context where a value is expected
1328      * (Array value, Object field value, root-level value).
1329      * Additional white space may be added around the value
1330      * if pretty-printing is enabled.
1331      *
1332      * @param v Number value to write
1333      *
1334      * @since 2.2
1335      */
writeNumber(short v)1336     public void writeNumber(short v) throws IOException { writeNumber((int) v); }
1337 
1338     /**
1339      * Method for outputting given value as JSON number.
1340      * Can be called in any context where a value is expected
1341      * (Array value, Object field value, root-level value).
1342      * Additional white space may be added around the value
1343      * if pretty-printing is enabled.
1344      *
1345      * @param v Number value to write
1346      */
writeNumber(int v)1347     public abstract void writeNumber(int v) throws IOException;
1348 
1349     /**
1350      * Method for outputting given value as JSON number.
1351      * Can be called in any context where a value is expected
1352      * (Array value, Object field value, root-level value).
1353      * Additional white space may be added around the value
1354      * if pretty-printing is enabled.
1355      *
1356      * @param v Number value to write
1357      */
writeNumber(long v)1358     public abstract void writeNumber(long v) throws IOException;
1359 
1360     /**
1361      * Method for outputting given value as JSON number.
1362      * Can be called in any context where a value is expected
1363      * (Array value, Object field value, root-level value).
1364      * Additional white space may be added around the value
1365      * if pretty-printing is enabled.
1366      *
1367      * @param v Number value to write
1368      */
writeNumber(BigInteger v)1369     public abstract void writeNumber(BigInteger v) throws IOException;
1370 
1371     /**
1372      * Method for outputting indicate JSON numeric value.
1373      * Can be called in any context where a value is expected
1374      * (Array value, Object field value, root-level value).
1375      * Additional white space may be added around the value
1376      * if pretty-printing is enabled.
1377      *
1378      * @param v Number value to write
1379      */
writeNumber(double v)1380     public abstract void writeNumber(double v) throws IOException;
1381 
1382     /**
1383      * Method for outputting indicate JSON numeric value.
1384      * Can be called in any context where a value is expected
1385      * (Array value, Object field value, root-level value).
1386      * Additional white space may be added around the value
1387      * if pretty-printing is enabled.
1388      *
1389      * @param v Number value to write
1390      */
writeNumber(float v)1391     public abstract void writeNumber(float v) throws IOException;
1392 
1393     /**
1394      * Method for outputting indicate JSON numeric value.
1395      * Can be called in any context where a value is expected
1396      * (Array value, Object field value, root-level value).
1397      * Additional white space may be added around the value
1398      * if pretty-printing is enabled.
1399      *
1400      * @param v Number value to write
1401      */
writeNumber(BigDecimal v)1402     public abstract void writeNumber(BigDecimal v) throws IOException;
1403 
1404     /**
1405      * Write method that can be used for custom numeric types that can
1406      * not be (easily?) converted to "standard" Java number types.
1407      * Because numbers are not surrounded by double quotes, regular
1408      * {@link #writeString} method can not be used; nor
1409      * {@link #writeRaw} because that does not properly handle
1410      * value separators needed in Array or Object contexts.
1411      *<p>
1412      * Note: because of lack of type safety, some generator
1413      * implementations may not be able to implement this
1414      * method. For example, if a binary JSON format is used,
1415      * it may require type information for encoding; similarly
1416      * for generator-wrappers around Java objects or JSON nodes.
1417      * If implementation does not implement this method,
1418      * it needs to throw {@link UnsupportedOperationException}.
1419      *
1420      * @throws UnsupportedOperationException If underlying data format does not
1421      *   support numbers serialized textually AND if generator is not allowed
1422      *   to just output a String instead (Schema-based formats may require actual
1423      *   number, for example)
1424      */
writeNumber(String encodedValue)1425     public abstract void writeNumber(String encodedValue) throws IOException;
1426 
1427     /**
1428      * Overloaded version of {@link #writeNumber(String)} with same semantics
1429      * but possibly more efficient operation.
1430      *
1431      * @since 2.11
1432      */
writeNumber(char[] encodedValueBuffer, int offset, int length)1433     public void writeNumber(char[] encodedValueBuffer, int offset, int length) throws IOException {
1434         writeNumber(new String(encodedValueBuffer, offset, length));
1435     }
1436 
1437     /*
1438     /**********************************************************
1439     /* Public API, write methods, other value types
1440     /**********************************************************
1441      */
1442 
1443     /**
1444      * Method for outputting literal JSON boolean value (one of
1445      * Strings 'true' and 'false').
1446      * Can be called in any context where a value is expected
1447      * (Array value, Object field value, root-level value).
1448      * Additional white space may be added around the value
1449      * if pretty-printing is enabled.
1450      */
writeBoolean(boolean state)1451     public abstract void writeBoolean(boolean state) throws IOException;
1452 
1453     /**
1454      * Method for outputting literal JSON null value.
1455      * Can be called in any context where a value is expected
1456      * (Array value, Object field value, root-level value).
1457      * Additional white space may be added around the value
1458      * if pretty-printing is enabled.
1459      */
writeNull()1460     public abstract void writeNull() throws IOException;
1461 
1462     /**
1463      * Method that can be called on backends that support passing opaque datatypes of
1464      * non-JSON formats
1465      *
1466      * @since 2.8
1467      */
writeEmbeddedObject(Object object)1468     public void writeEmbeddedObject(Object object) throws IOException {
1469         // 01-Sep-2016, tatu: As per [core#318], handle small number of cases
1470         if (object == null) {
1471             writeNull();
1472             return;
1473         }
1474         if (object instanceof byte[]) {
1475             writeBinary((byte[]) object);
1476             return;
1477         }
1478         throw new JsonGenerationException("No native support for writing embedded objects of type "
1479                 +object.getClass().getName(),
1480                 this);
1481     }
1482 
1483     /*
1484     /**********************************************************
1485     /* Public API, write methods, Native Ids (type, object)
1486     /**********************************************************
1487      */
1488 
1489     /**
1490      * Method that can be called to output so-called native Object Id.
1491      * Note that it may only be called after ensuring this is legal
1492      * (with {@link #canWriteObjectId()}), as not all data formats
1493      * have native type id support; and some may only allow them in
1494      * certain positions or locations.
1495      * If output is not allowed by the data format in this position,
1496      * a {@link JsonGenerationException} will be thrown.
1497      *
1498      * @since 2.3
1499      */
writeObjectId(Object id)1500     public void writeObjectId(Object id) throws IOException {
1501         throw new JsonGenerationException("No native support for writing Object Ids", this);
1502     }
1503 
1504     /**
1505      * Method that can be called to output references to native Object Ids.
1506      * Note that it may only be called after ensuring this is legal
1507      * (with {@link #canWriteObjectId()}), as not all data formats
1508      * have native type id support; and some may only allow them in
1509      * certain positions or locations.
1510      * If output is not allowed by the data format in this position,
1511      * a {@link JsonGenerationException} will be thrown.
1512      */
writeObjectRef(Object id)1513     public void writeObjectRef(Object id) throws IOException {
1514         throw new JsonGenerationException("No native support for writing Object Ids", this);
1515     }
1516 
1517     /**
1518      * Method that can be called to output so-called native Type Id.
1519      * Note that it may only be called after ensuring this is legal
1520      * (with {@link #canWriteTypeId()}), as not all data formats
1521      * have native type id support; and some may only allow them in
1522      * certain positions or locations.
1523      * If output is not allowed by the data format in this position,
1524      * a {@link JsonGenerationException} will be thrown.
1525      *
1526      * @since 2.3
1527      */
writeTypeId(Object id)1528     public void writeTypeId(Object id) throws IOException {
1529         throw new JsonGenerationException("No native support for writing Type Ids", this);
1530     }
1531 
1532     /*
1533      * Replacement method for {@link #writeTypeId(Object)} which is called
1534      * regardless of whether format has native type ids. If it does have native
1535      * type ids, those are to be used (if configuration allows this), if not,
1536      * structural type id inclusion is to be used. For JSON, for example, no
1537      * native type ids exist and structural inclusion is always used.
1538      *<p>
1539      * NOTE: databind may choose to skip calling this method for some special cases
1540      * (and instead included type id via regular write methods and/or {@link #writeTypeId}
1541      * -- this is discouraged, but not illegal, and may be necessary as a work-around
1542      * in some cases.
1543      *
1544      * @since 2.9
1545      */
writeTypePrefix(WritableTypeId typeIdDef)1546     public WritableTypeId writeTypePrefix(WritableTypeId typeIdDef) throws IOException
1547     {
1548         Object id = typeIdDef.id;
1549 
1550         final JsonToken valueShape = typeIdDef.valueShape;
1551         if (canWriteTypeId()) {
1552             typeIdDef.wrapperWritten = false;
1553             // just rely on native type output method (sub-classes likely to override)
1554             writeTypeId(id);
1555         } else {
1556             // No native type id; write wrappers
1557             // Normally we only support String type ids (non-String reserved for native type ids)
1558             String idStr = (id instanceof String) ? (String) id : String.valueOf(id);
1559             typeIdDef.wrapperWritten = true;
1560 
1561             Inclusion incl = typeIdDef.include;
1562             // first: can not output "as property" if value not Object; if so, must do "as array"
1563             if ((valueShape != JsonToken.START_OBJECT)
1564                     && incl.requiresObjectContext()) {
1565                 typeIdDef.include = incl = WritableTypeId.Inclusion.WRAPPER_ARRAY;
1566             }
1567 
1568             switch (incl) {
1569             case PARENT_PROPERTY:
1570                 // nothing to do here, as it has to be written in suffix...
1571                 break;
1572             case PAYLOAD_PROPERTY:
1573                 // only output as native type id; otherwise caller must handle using some
1574                 // other mechanism, so...
1575                 break;
1576             case METADATA_PROPERTY:
1577                 // must have Object context by now, so simply write as field name
1578                 // Note, too, that it's bit tricky, since we must print START_OBJECT that is part
1579                 // of value first -- and then NOT output it later on: hence return "early"
1580                 writeStartObject(typeIdDef.forValue);
1581                 writeStringField(typeIdDef.asProperty, idStr);
1582                 return typeIdDef;
1583 
1584             case WRAPPER_OBJECT:
1585                 // NOTE: this is wrapper, not directly related to value to output, so don't pass
1586                 writeStartObject();
1587                 writeFieldName(idStr);
1588                 break;
1589             case WRAPPER_ARRAY:
1590             default: // should never occur but translate as "as-array"
1591                 writeStartArray(); // wrapper, not actual array object to write
1592                 writeString(idStr);
1593             }
1594         }
1595         // and finally possible start marker for value itself:
1596         if (valueShape == JsonToken.START_OBJECT) {
1597             writeStartObject(typeIdDef.forValue);
1598         } else if (valueShape == JsonToken.START_ARRAY) {
1599             // should we now set the current object?
1600             writeStartArray();
1601         }
1602         return typeIdDef;
1603     }
1604 
1605     /*
1606      * @since 2.9
1607      */
writeTypeSuffix(WritableTypeId typeIdDef)1608     public WritableTypeId writeTypeSuffix(WritableTypeId typeIdDef) throws IOException
1609     {
1610         final JsonToken valueShape = typeIdDef.valueShape;
1611         // First: does value need closing?
1612         if (valueShape == JsonToken.START_OBJECT) {
1613             writeEndObject();
1614         } else if (valueShape == JsonToken.START_ARRAY) {
1615             writeEndArray();
1616         }
1617 
1618         if (typeIdDef.wrapperWritten) {
1619             switch (typeIdDef.include) {
1620             case WRAPPER_ARRAY:
1621                 writeEndArray();
1622                 break;
1623             case PARENT_PROPERTY:
1624                 // unusually, need to output AFTER value. And no real wrapper...
1625                 {
1626                     Object id = typeIdDef.id;
1627                     String idStr = (id instanceof String) ? (String) id : String.valueOf(id);
1628                     writeStringField(typeIdDef.asProperty, idStr);
1629                 }
1630                 break;
1631             case METADATA_PROPERTY:
1632             case PAYLOAD_PROPERTY:
1633                 // no actual wrapper; included within Object itself
1634                 break;
1635             case WRAPPER_OBJECT:
1636             default: // should never occur but...
1637                 writeEndObject();
1638                 break;
1639             }
1640         }
1641         return typeIdDef;
1642     }
1643 
1644     /*
1645     /**********************************************************
1646     /* Public API, write methods, serializing Java objects
1647     /**********************************************************
1648      */
1649 
1650     /**
1651      * Method for writing given Java object (POJO) as Json.
1652      * Exactly how the object gets written depends on object
1653      * in question (ad on codec, its configuration); for most
1654      * beans it will result in JSON Object, but for others JSON
1655      * Array, or String or numeric value (and for nulls, JSON
1656      * null literal.
1657      * <b>NOTE</b>: generator must have its <b>object codec</b>
1658      * set to non-null value; for generators created by a mapping
1659      * factory this is the case, for others not.
1660      */
writeObject(Object pojo)1661     public abstract void writeObject(Object pojo) throws IOException;
1662 
1663     /**
1664      * Method for writing given JSON tree (expressed as a tree
1665      * where given JsonNode is the root) using this generator.
1666      * This will generally just call
1667      * {@link #writeObject} with given node, but is added
1668      * for convenience and to make code more explicit in cases
1669      * where it deals specifically with trees.
1670      */
writeTree(TreeNode rootNode)1671     public abstract void writeTree(TreeNode rootNode) throws IOException;
1672 
1673     /*
1674     /**********************************************************
1675     /* Public API, convenience field write methods
1676     /**********************************************************
1677      */
1678 
1679     // 04-Oct-2019, tatu: Reminder: these could be defined final to
1680     //    remember NOT to override in delegating sub-classes -- but
1681     //    not final in 2.x to reduce compatibility issues
1682 
1683     /**
1684      * Convenience method for outputting a field entry ("member")
1685      * that contains specified data in base64-encoded form.
1686      * Equivalent to:
1687      *<pre>
1688      *  writeFieldName(fieldName);
1689      *  writeBinary(value);
1690      *</pre>
1691      */
writeBinaryField(String fieldName, byte[] data)1692     public void writeBinaryField(String fieldName, byte[] data) throws IOException {
1693         writeFieldName(fieldName);
1694         writeBinary(data);
1695     }
1696 
1697     /**
1698      * Convenience method for outputting a field entry ("member")
1699      * that has a boolean value. Equivalent to:
1700      *<pre>
1701      *  writeFieldName(fieldName);
1702      *  writeBoolean(value);
1703      *</pre>
1704      */
writeBooleanField(String fieldName, boolean value)1705     public void writeBooleanField(String fieldName, boolean value) throws IOException {
1706         writeFieldName(fieldName);
1707         writeBoolean(value);
1708     }
1709 
1710     /**
1711      * Convenience method for outputting a field entry ("member")
1712      * that has JSON literal value null. Equivalent to:
1713      *<pre>
1714      *  writeFieldName(fieldName);
1715      *  writeNull();
1716      *</pre>
1717      */
writeNullField(String fieldName)1718     public void writeNullField(String fieldName) throws IOException {
1719         writeFieldName(fieldName);
1720         writeNull();
1721     }
1722 
1723     /**
1724      * Convenience method for outputting a field entry ("member")
1725      * that has a String value. Equivalent to:
1726      *<pre>
1727      *  writeFieldName(fieldName);
1728      *  writeString(value);
1729      *</pre>
1730      *<p>
1731      * Note: many performance-sensitive implementations override this method
1732      */
writeStringField(String fieldName, String value)1733     public void writeStringField(String fieldName, String value) throws IOException {
1734         writeFieldName(fieldName);
1735         writeString(value);
1736     }
1737 
1738     /**
1739      * Convenience method for outputting a field entry ("member")
1740      * that has the specified numeric value. Equivalent to:
1741      *<pre>
1742      *  writeFieldName(fieldName);
1743      *  writeNumber(value);
1744      *</pre>
1745      *
1746      * @since 2.11
1747      */
writeNumberField(String fieldName, short value)1748     public void writeNumberField(String fieldName, short value) throws IOException {
1749         writeFieldName(fieldName);
1750         writeNumber(value);
1751     }
1752 
1753     /**
1754      * Convenience method for outputting a field entry ("member")
1755      * that has the specified numeric value. Equivalent to:
1756      *<pre>
1757      *  writeFieldName(fieldName);
1758      *  writeNumber(value);
1759      *</pre>
1760      */
writeNumberField(String fieldName, int value)1761     public void writeNumberField(String fieldName, int value) throws IOException {
1762         writeFieldName(fieldName);
1763         writeNumber(value);
1764     }
1765 
1766     /**
1767      * Convenience method for outputting a field entry ("member")
1768      * that has the specified numeric value. Equivalent to:
1769      *<pre>
1770      *  writeFieldName(fieldName);
1771      *  writeNumber(value);
1772      *</pre>
1773      */
writeNumberField(String fieldName, long value)1774     public void writeNumberField(String fieldName, long value) throws IOException {
1775         writeFieldName(fieldName);
1776         writeNumber(value);
1777     }
1778 
1779     /**
1780      * Convenience method for outputting a field entry ("member")
1781      * that has the specified numeric value. Equivalent to:
1782      *<pre>
1783      *  writeFieldName(fieldName);
1784      *  writeNumber(value);
1785      *</pre>
1786      *
1787      * @since 2.11
1788      */
writeNumberField(String fieldName, BigInteger value)1789     public void writeNumberField(String fieldName, BigInteger value) throws IOException {
1790         writeFieldName(fieldName);
1791         writeNumber(value);
1792     }
1793 
1794     /**
1795      * Convenience method for outputting a field entry ("member")
1796      * that has the specified numeric value. Equivalent to:
1797      *<pre>
1798      *  writeFieldName(fieldName);
1799      *  writeNumber(value);
1800      *</pre>
1801      */
writeNumberField(String fieldName, float value)1802     public void writeNumberField(String fieldName, float value) throws IOException {
1803         writeFieldName(fieldName);
1804         writeNumber(value);
1805     }
1806 
1807     /**
1808      * Convenience method for outputting a field entry ("member")
1809      * that has the specified numeric value. Equivalent to:
1810      *<pre>
1811      *  writeFieldName(fieldName);
1812      *  writeNumber(value);
1813      *</pre>
1814      */
writeNumberField(String fieldName, double value)1815     public void writeNumberField(String fieldName, double value) throws IOException {
1816         writeFieldName(fieldName);
1817         writeNumber(value);
1818     }
1819 
1820     /**
1821      * Convenience method for outputting a field entry ("member")
1822      * that has the specified numeric value.
1823      * Equivalent to:
1824      *<pre>
1825      *  writeFieldName(fieldName);
1826      *  writeNumber(value);
1827      *</pre>
1828      */
writeNumberField(String fieldName, BigDecimal value)1829     public void writeNumberField(String fieldName, BigDecimal value) throws IOException {
1830         writeFieldName(fieldName);
1831         writeNumber(value);
1832     }
1833 
1834     /**
1835      * Convenience method for outputting a field entry ("member")
1836      * (that will contain a JSON Array value), and the START_ARRAY marker.
1837      * Equivalent to:
1838      *<pre>
1839      *  writeFieldName(fieldName);
1840      *  writeStartArray();
1841      *</pre>
1842      *<p>
1843      * Note: caller still has to take care to close the array
1844      * (by calling {#link #writeEndArray}) after writing all values
1845      * of the value Array.
1846      */
writeArrayFieldStart(String fieldName)1847     public void writeArrayFieldStart(String fieldName) throws IOException {
1848         writeFieldName(fieldName);
1849         writeStartArray();
1850     }
1851 
1852     /**
1853      * Convenience method for outputting a field entry ("member")
1854      * (that will contain an Object value), and the START_OBJECT marker.
1855      * Equivalent to:
1856      *<pre>
1857      *  writeFieldName(fieldName);
1858      *  writeStartObject();
1859      *</pre>
1860      *<p>
1861      * Note: caller still has to take care to close the Object
1862      * (by calling {#link #writeEndObject}) after writing all
1863      * entries of the value Object.
1864      */
writeObjectFieldStart(String fieldName)1865     public void writeObjectFieldStart(String fieldName) throws IOException {
1866         writeFieldName(fieldName);
1867         writeStartObject();
1868     }
1869 
1870     /**
1871      * Convenience method for outputting a field entry ("member")
1872      * that has contents of specific Java object as its value.
1873      * Equivalent to:
1874      *<pre>
1875      *  writeFieldName(fieldName);
1876      *  writeObject(pojo);
1877      *</pre>
1878      */
writeObjectField(String fieldName, Object pojo)1879     public void writeObjectField(String fieldName, Object pojo) throws IOException {
1880         writeFieldName(fieldName);
1881         writeObject(pojo);
1882     }
1883 
1884     // // // But this method does need to be delegate so...
1885 
1886     /**
1887      * Method called to indicate that a property in this position was
1888      * skipped. It is usually only called for generators that return
1889      * <code>false</code> from {@link #canOmitFields()}.
1890      *<p>
1891      * Default implementation does nothing.
1892      *
1893      * @since 2.3
1894      */
writeOmittedField(String fieldName)1895     public void writeOmittedField(String fieldName) throws IOException { }
1896 
1897     /*
1898     /**********************************************************
1899     /* Public API, copy-through methods
1900     /**********************************************************
1901      */
1902 
1903     /**
1904      * Method for copying contents of the current event that
1905      * the given parser instance points to.
1906      * Note that the method <b>will not</b> copy any other events,
1907      * such as events contained within JSON Array or Object structures.
1908      *<p>
1909      * Calling this method will not advance the given
1910      * parser, although it may cause parser to internally process
1911      * more data (if it lazy loads contents of value events, for example)
1912      */
copyCurrentEvent(JsonParser p)1913     public void copyCurrentEvent(JsonParser p) throws IOException
1914     {
1915         JsonToken t = p.currentToken();
1916         final int token = (t == null) ? ID_NOT_AVAILABLE : t.id();
1917         switch (token) {
1918         case ID_NOT_AVAILABLE:
1919             _reportError("No current event to copy");
1920             break; // never gets here
1921         case ID_START_OBJECT:
1922             writeStartObject();
1923             break;
1924         case ID_END_OBJECT:
1925             writeEndObject();
1926             break;
1927         case ID_START_ARRAY:
1928             writeStartArray();
1929             break;
1930         case ID_END_ARRAY:
1931             writeEndArray();
1932             break;
1933         case ID_FIELD_NAME:
1934             writeFieldName(p.getCurrentName());
1935             break;
1936         case ID_STRING:
1937             if (p.hasTextCharacters()) {
1938                 writeString(p.getTextCharacters(), p.getTextOffset(), p.getTextLength());
1939             } else {
1940                 writeString(p.getText());
1941             }
1942             break;
1943         case ID_NUMBER_INT:
1944         {
1945             NumberType n = p.getNumberType();
1946             if (n == NumberType.INT) {
1947                 writeNumber(p.getIntValue());
1948             } else if (n == NumberType.BIG_INTEGER) {
1949                 writeNumber(p.getBigIntegerValue());
1950             } else {
1951                 writeNumber(p.getLongValue());
1952             }
1953             break;
1954         }
1955         case ID_NUMBER_FLOAT:
1956         {
1957             NumberType n = p.getNumberType();
1958             if (n == NumberType.BIG_DECIMAL) {
1959                 writeNumber(p.getDecimalValue());
1960             } else if (n == NumberType.FLOAT) {
1961                 writeNumber(p.getFloatValue());
1962             } else {
1963                 writeNumber(p.getDoubleValue());
1964             }
1965             break;
1966         }
1967         case ID_TRUE:
1968             writeBoolean(true);
1969             break;
1970         case ID_FALSE:
1971             writeBoolean(false);
1972             break;
1973         case ID_NULL:
1974             writeNull();
1975             break;
1976         case ID_EMBEDDED_OBJECT:
1977             writeObject(p.getEmbeddedObject());
1978             break;
1979         default:
1980             throw new IllegalStateException("Internal error: unknown current token, "+t);
1981         }
1982     }
1983 
1984     /**
1985      * Method for copying contents of the current event
1986      * <b>and following events that it encloses</b>
1987      * the given parser instance points to.
1988      *<p>
1989      * So what constitutes enclosing? Here is the list of
1990      * events that have associated enclosed events that will
1991      * get copied:
1992      *<ul>
1993      * <li>{@link JsonToken#START_OBJECT}:
1994      *   all events up to and including matching (closing)
1995      *   {@link JsonToken#END_OBJECT} will be copied
1996      *  </li>
1997      * <li>{@link JsonToken#START_ARRAY}
1998      *   all events up to and including matching (closing)
1999      *   {@link JsonToken#END_ARRAY} will be copied
2000      *  </li>
2001      * <li>{@link JsonToken#FIELD_NAME} the logical value (which
2002      *   can consist of a single scalar value; or a sequence of related
2003      *   events for structured types (JSON Arrays, Objects)) will
2004      *   be copied along with the name itself. So essentially the
2005      *   whole <b>field entry</b> (name and value) will be copied.
2006      *  </li>
2007      *</ul>
2008      *<p>
2009      * After calling this method, parser will point to the
2010      * <b>last event</b> that was copied. This will either be
2011      * the event parser already pointed to (if there were no
2012      * enclosed events), or the last enclosed event copied.
2013      */
copyCurrentStructure(JsonParser p)2014     public void copyCurrentStructure(JsonParser p) throws IOException
2015     {
2016         JsonToken t = p.currentToken();
2017         // Let's handle field-name separately first
2018         int id = (t == null) ? ID_NOT_AVAILABLE : t.id();
2019         if (id == ID_FIELD_NAME) {
2020             writeFieldName(p.getCurrentName());
2021             t = p.nextToken();
2022             id = (t == null) ? ID_NOT_AVAILABLE : t.id();
2023             // fall-through to copy the associated value
2024         }
2025         switch (id) {
2026         case ID_START_OBJECT:
2027             writeStartObject();
2028             _copyCurrentContents(p);
2029             return;
2030         case ID_START_ARRAY:
2031             writeStartArray();
2032             _copyCurrentContents(p);
2033             return;
2034 
2035         default:
2036             copyCurrentEvent(p);
2037         }
2038     }
2039 
2040     /**
2041      * @since 2.10
2042      */
_copyCurrentContents(JsonParser p)2043     protected void _copyCurrentContents(JsonParser p) throws IOException
2044     {
2045         int depth = 1;
2046         JsonToken t;
2047 
2048         // Mostly copied from `copyCurrentEvent()`, but with added nesting counts
2049         while ((t = p.nextToken()) != null) {
2050             switch (t.id()) {
2051             case ID_FIELD_NAME:
2052                 writeFieldName(p.getCurrentName());
2053                 break;
2054 
2055             case ID_START_ARRAY:
2056                 writeStartArray();
2057                 ++depth;
2058                 break;
2059 
2060             case ID_START_OBJECT:
2061                 writeStartObject();
2062                 ++depth;
2063                 break;
2064 
2065             case ID_END_ARRAY:
2066                 writeEndArray();
2067                 if (--depth == 0) {
2068                     return;
2069                 }
2070                 break;
2071             case ID_END_OBJECT:
2072                 writeEndObject();
2073                 if (--depth == 0) {
2074                     return;
2075                 }
2076                 break;
2077 
2078             case ID_STRING:
2079                 if (p.hasTextCharacters()) {
2080                     writeString(p.getTextCharacters(), p.getTextOffset(), p.getTextLength());
2081                 } else {
2082                     writeString(p.getText());
2083                 }
2084                 break;
2085             case ID_NUMBER_INT:
2086             {
2087                 NumberType n = p.getNumberType();
2088                 if (n == NumberType.INT) {
2089                     writeNumber(p.getIntValue());
2090                 } else if (n == NumberType.BIG_INTEGER) {
2091                     writeNumber(p.getBigIntegerValue());
2092                 } else {
2093                     writeNumber(p.getLongValue());
2094                 }
2095                 break;
2096             }
2097             case ID_NUMBER_FLOAT:
2098             {
2099                 NumberType n = p.getNumberType();
2100                 if (n == NumberType.BIG_DECIMAL) {
2101                     writeNumber(p.getDecimalValue());
2102                 } else if (n == NumberType.FLOAT) {
2103                     writeNumber(p.getFloatValue());
2104                 } else {
2105                     writeNumber(p.getDoubleValue());
2106                 }
2107                 break;
2108             }
2109             case ID_TRUE:
2110                 writeBoolean(true);
2111                 break;
2112             case ID_FALSE:
2113                 writeBoolean(false);
2114                 break;
2115             case ID_NULL:
2116                 writeNull();
2117                 break;
2118             case ID_EMBEDDED_OBJECT:
2119                 writeObject(p.getEmbeddedObject());
2120                 break;
2121             default:
2122                 throw new IllegalStateException("Internal error: unknown current token, "+t);
2123             }
2124         }
2125     }
2126 
2127     /*
2128     /**********************************************************
2129     /* Public API, context access
2130     /**********************************************************
2131      */
2132 
2133     /**
2134      * @return Context object that can give information about logical
2135      *   position within generated json content.
2136      */
getOutputContext()2137     public abstract JsonStreamContext getOutputContext();
2138 
2139     /*
2140     /**********************************************************
2141     /* Public API, buffer handling
2142     /**********************************************************
2143      */
2144 
2145     /**
2146      * Method called to flush any buffered content to the underlying
2147      * target (output stream, writer), and to flush the target itself
2148      * as well.
2149      */
2150     @Override
flush()2151     public abstract void flush() throws IOException;
2152 
2153     /**
2154      * Method that can be called to determine whether this generator
2155      * is closed or not. If it is closed, no more output can be done.
2156      */
isClosed()2157     public abstract boolean isClosed();
2158 
2159     /*
2160     /**********************************************************
2161     /* Closeable implementation
2162     /**********************************************************
2163      */
2164 
2165     /**
2166      * Method called to close this generator, so that no more content
2167      * can be written.
2168      *<p>
2169      * Whether the underlying target (stream, writer) gets closed depends
2170      * on whether this generator either manages the target (i.e. is the
2171      * only one with access to the target -- case if caller passes a
2172      * reference to the resource such as File, but not stream); or
2173      * has feature {@link Feature#AUTO_CLOSE_TARGET} enabled.
2174      * If either of above is true, the target is also closed. Otherwise
2175      * (not managing, feature not enabled), target is not closed.
2176      */
2177     @Override
close()2178     public abstract void close() throws IOException;
2179 
2180     /*
2181     /**********************************************************
2182     /* Helper methods for sub-classes
2183     /**********************************************************
2184      */
2185 
2186     /**
2187      * Helper method used for constructing and throwing
2188      * {@link JsonGenerationException} with given base message.
2189      *<p>
2190      * Note that sub-classes may override this method to add more detail
2191      * or use a {@link JsonGenerationException} sub-class.
2192      */
_reportError(String msg)2193     protected void _reportError(String msg) throws JsonGenerationException {
2194         throw new JsonGenerationException(msg, this);
2195     }
2196 
_throwInternal()2197     protected final void _throwInternal() { VersionUtil.throwInternal(); }
2198 
_reportUnsupportedOperation()2199     protected void _reportUnsupportedOperation() {
2200         throw new UnsupportedOperationException("Operation not supported by generator of type "+getClass().getName());
2201     }
2202 
2203     /**
2204      * @since 2.8
2205      */
_verifyOffsets(int arrayLength, int offset, int length)2206     protected final void _verifyOffsets(int arrayLength, int offset, int length)
2207     {
2208         if ((offset < 0) || (offset + length) > arrayLength) {
2209             throw new IllegalArgumentException(String.format(
2210                     "invalid argument(s) (offset=%d, length=%d) for input array of %d element",
2211                     offset, length, arrayLength));
2212         }
2213     }
2214 
2215     /**
2216      * Helper method to try to call appropriate write method for given
2217      * untyped Object. At this point, no structural conversions should be done,
2218      * only simple basic types are to be coerced as necessary.
2219      *
2220      * @param value Non-null value to write
2221      */
_writeSimpleObject(Object value)2222     protected void _writeSimpleObject(Object value)  throws IOException
2223     {
2224         // 31-Dec-2009, tatu: Actually, we could just handle some basic
2225         //    types even without codec. This can improve interoperability,
2226         //    and specifically help with TokenBuffer.
2227         if (value == null) {
2228             writeNull();
2229             return;
2230         }
2231         if (value instanceof String) {
2232             writeString((String) value);
2233             return;
2234         }
2235         if (value instanceof Number) {
2236             Number n = (Number) value;
2237             if (n instanceof Integer) {
2238                 writeNumber(n.intValue());
2239                 return;
2240             } else if (n instanceof Long) {
2241                 writeNumber(n.longValue());
2242                 return;
2243             } else if (n instanceof Double) {
2244                 writeNumber(n.doubleValue());
2245                 return;
2246             } else if (n instanceof Float) {
2247                 writeNumber(n.floatValue());
2248                 return;
2249             } else if (n instanceof Short) {
2250                 writeNumber(n.shortValue());
2251                 return;
2252             } else if (n instanceof Byte) {
2253                 writeNumber(n.byteValue());
2254                 return;
2255             } else if (n instanceof BigInteger) {
2256                 writeNumber((BigInteger) n);
2257                 return;
2258             } else if (n instanceof BigDecimal) {
2259                 writeNumber((BigDecimal) n);
2260                 return;
2261 
2262             // then Atomic types
2263             } else if (n instanceof AtomicInteger) {
2264                 writeNumber(((AtomicInteger) n).get());
2265                 return;
2266             } else if (n instanceof AtomicLong) {
2267                 writeNumber(((AtomicLong) n).get());
2268                 return;
2269             }
2270         } else if (value instanceof byte[]) {
2271             writeBinary((byte[]) value);
2272             return;
2273         } else if (value instanceof Boolean) {
2274             writeBoolean((Boolean) value);
2275             return;
2276         } else if (value instanceof AtomicBoolean) {
2277             writeBoolean(((AtomicBoolean) value).get());
2278             return;
2279         }
2280         throw new IllegalStateException("No ObjectCodec defined for the generator, can only serialize simple wrapper types (type passed "
2281                 +value.getClass().getName()+")");
2282     }
2283 }
2284