001/*
002 * Copyright (C) 2014 Square, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *    https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.avaje.json;
017
018import java.io.Closeable;
019import java.math.BigDecimal;
020import java.math.BigInteger;
021
022/**
023 * Reads json content as a stream of JSON tokens and content.
024 */
025public interface JsonReader extends Closeable {
026
027  /**
028   * Unwrap and return the underlying JsonParser.
029   * <p>
030   * When using avaje-jsonb-jackson this will return the underlying Jackson JsonParser.
031   *
032   * <pre>{@code
033   *
034   * // when using avaje-jsonb-jackson
035   * var jacksonParser = jsonReader.unwrap(JsonParser.class);
036   *
037   * }</pre>
038   */
039  <T> T unwrap(Class<T> type);
040
041  /**
042   * Read the beginning of an ARRAY or x-json-stream (new line delimited json content).
043   */
044  default void beginStream() {
045    beginArray();
046  }
047
048  /**
049   * Read the end of an ARRAY or x-json-stream (new line delimited json content).
050   */
051  default void endStream() {
052    endArray();
053  }
054
055  /**
056   * Return true if there is a next element in an ARRAY or x-json-stream (new line delimited json content).
057   * <p>
058   * Effectively this allows for new line delimited rather than commas between array elements.
059   */
060  default boolean hasNextStreamElement() {
061    return hasNextElement();
062  }
063
064  /**
065   * Read array begin.
066   */
067  void beginArray();
068
069  /**
070   * Read array end.
071   */
072  void endArray();
073
074  /**
075   * Return true if there is a next element in an ARRAY.
076   */
077  boolean hasNextElement();
078
079  /**
080   * Set the current property names.
081   * <p>
082   * Can be used by the reader to optimize the reading of known names.
083   */
084  void beginObject(PropertyNames names);
085
086  /**
087   * Read begin object.
088   */
089  void beginObject();
090
091  /**
092   * Read end object.
093   */
094  void endObject();
095
096  /**
097   * Return true if there is a next field to be read in an OBJECT.
098   */
099  boolean hasNextField();
100
101  /**
102   * Return the next field.
103   */
104  String nextField();
105
106  /**
107   * Return true if the value to be read is a null.
108   */
109  boolean isNullValue();
110
111  /**
112   * Read and return the next value as a boolean.
113   */
114  boolean readBoolean();
115
116  /**
117   * Read and return the next value as an int.
118   */
119  int readInt();
120
121  /**
122   * Read and return the next value as a long.
123   */
124  long readLong();
125
126  /**
127   * Read and return the next value as a double.
128   */
129  double readDouble();
130
131  /**
132   * Read and return the next value as a BigDecimal.
133   */
134  BigDecimal readDecimal();
135
136  /**
137   * Read and return the next value as a BigInteger.
138   */
139  BigInteger readBigInteger();
140
141  /**
142   * Read and return the next value as String.
143   */
144  String readString();
145
146  /**
147   * Read and return the binary value from base64.
148   */
149  byte[] readBinary();
150
151  /**
152   * Read and return raw json content as a String.
153   */
154  String readRaw();
155
156  /**
157   * Return the current location. This is typically used when reporting errors.
158   */
159  String location();
160
161  /**
162   * Return the current Token.
163   */
164  Token currentToken();
165
166  /**
167   * Close the resources of the reader.
168   */
169  void close();
170
171  /**
172   * Skip the next value.
173   */
174  void skipValue();
175
176  /**
177   * Reading json with an unmapped field, throw an Exception if failOnUnmapped is true.
178   */
179  void unmappedField(String fieldName);
180
181  /**
182   * Explicitly state if the streaming content contains ARRAY '[' and ']' tokens.
183   * <p>
184   * The builtin avaje-jsonb parser detects this automatically. Effectively we only need
185   * to set this when we are using the Jackson core parser.
186   *
187   * <pre>{@code
188   *
189   *  try (JsonReader reader = jsonb.reader(arrayJson)) {
190   *    // content contains ARRAY '[' and ']' tokens, use streamArray(true)
191   *    Stream<MyBasic> asStream = type.stream(reader.streamArray(true));
192   *    asStream.forEach(...);
193   *  }
194   *
195   * }</pre>
196   *
197   * @param streamArray When true the content is expected to contain ARRAY '[' and ']' tokens.
198   */
199  default JsonReader streamArray(boolean streamArray) {
200    // do nothing by default, jackson specifically needs this option
201    return this;
202  }
203
204  /**
205   * A structure, name, or value type in a JSON-encoded string.
206   */
207  enum Token {
208
209    /**
210     * The opening of a JSON array. Written using {@link JsonWriter#beginArray} and read using
211     * {@link JsonReader#beginArray}.
212     */
213    BEGIN_ARRAY,
214
215    /**
216     * The opening of a JSON object. Written using {@link JsonWriter#beginObject} and read using
217     * {@link JsonReader#beginObject}.
218     */
219    BEGIN_OBJECT,
220
221    /**
222     * A JSON string.
223     */
224    STRING,
225
226    /**
227     * A JSON number represented in this API by a Java {@code double}, {@code long}, or {@code int}.
228     */
229    NUMBER,
230
231    /**
232     * A JSON {@code true} or {@code false}.
233     */
234    BOOLEAN,
235
236    /**
237     * A JSON {@code null}.
238     */
239    NULL,
240
241  }
242}