@@ -206,26 +206,55 @@ public <T> void declareField(BiConsumer<Value, T> consumer, ContextParser<Contex
206
206
throw new IllegalArgumentException ("[type] is required" );
207
207
}
208
208
209
- if (consumer == REQUIRED_CONSTRUCTOR_ARG_MARKER || consumer == OPTIONAL_CONSTRUCTOR_ARG_MARKER ) {
209
+ if (isConstructorArg ( consumer ) ) {
210
210
/*
211
- * Constructor arguments are detected by these "marker" consumers. It keeps the API looking clean even if it is a bit sleezy. We
212
- * then build a new consumer directly against the object parser that triggers the "constructor arg just arrived behavior" of the
213
- * parser. Conveniently, we can close over the position of the constructor in the argument list so we don't need to do any fancy
211
+ * Build a new consumer directly against the object parser that
212
+ * triggers the "constructor arg just arrived behavior" of the
213
+ * parser. Conveniently, we can close over the position of the
214
+ * constructor in the argument list so we don't need to do any fancy
214
215
* or expensive lookups whenever the constructor args come in.
215
216
*/
216
- int position = constructorArgInfos .size ();
217
- boolean required = consumer == REQUIRED_CONSTRUCTOR_ARG_MARKER ;
218
- constructorArgInfos .add (new ConstructorArgInfo (parseField , required ));
217
+ int position = addConstructorArg (consumer , parseField );
219
218
objectParser .declareField ((target , v ) -> target .constructorArg (position , v ), parser , parseField , type );
220
219
} else {
221
220
numberOfFields += 1 ;
222
221
objectParser .declareField (queueingConsumer (consumer , parseField ), parser , parseField , type );
223
222
}
224
223
}
225
224
225
+ @ Override
226
+ public <T > void declareNamedObject (BiConsumer <Value , T > consumer , NamedObjectParser <T , Context > namedObjectParser ,
227
+ ParseField parseField ) {
228
+ if (consumer == null ) {
229
+ throw new IllegalArgumentException ("[consumer] is required" );
230
+ }
231
+ if (namedObjectParser == null ) {
232
+ throw new IllegalArgumentException ("[parser] is required" );
233
+ }
234
+ if (parseField == null ) {
235
+ throw new IllegalArgumentException ("[parseField] is required" );
236
+ }
237
+
238
+ if (isConstructorArg (consumer )) {
239
+ /*
240
+ * Build a new consumer directly against the object parser that
241
+ * triggers the "constructor arg just arrived behavior" of the
242
+ * parser. Conveniently, we can close over the position of the
243
+ * constructor in the argument list so we don't need to do any fancy
244
+ * or expensive lookups whenever the constructor args come in.
245
+ */
246
+ int position = addConstructorArg (consumer , parseField );
247
+ objectParser .declareNamedObject ((target , v ) -> target .constructorArg (position , v ), namedObjectParser , parseField );
248
+ } else {
249
+ numberOfFields += 1 ;
250
+ objectParser .declareNamedObject (queueingConsumer (consumer , parseField ), namedObjectParser , parseField );
251
+ }
252
+ }
253
+
226
254
@ Override
227
255
public <T > void declareNamedObjects (BiConsumer <Value , List <T >> consumer , NamedObjectParser <T , Context > namedObjectParser ,
228
256
ParseField parseField ) {
257
+
229
258
if (consumer == null ) {
230
259
throw new IllegalArgumentException ("[consumer] is required" );
231
260
}
@@ -236,19 +265,15 @@ public <T> void declareNamedObjects(BiConsumer<Value, List<T>> consumer, NamedOb
236
265
throw new IllegalArgumentException ("[parseField] is required" );
237
266
}
238
267
239
- if (consumer == REQUIRED_CONSTRUCTOR_ARG_MARKER || consumer == OPTIONAL_CONSTRUCTOR_ARG_MARKER ) {
268
+ if (isConstructorArg ( consumer ) ) {
240
269
/*
241
- * Constructor arguments are detected by this "marker" consumer. It
242
- * keeps the API looking clean even if it is a bit sleezy. We then
243
- * build a new consumer directly against the object parser that
270
+ * Build a new consumer directly against the object parser that
244
271
* triggers the "constructor arg just arrived behavior" of the
245
272
* parser. Conveniently, we can close over the position of the
246
273
* constructor in the argument list so we don't need to do any fancy
247
274
* or expensive lookups whenever the constructor args come in.
248
275
*/
249
- int position = constructorArgInfos .size ();
250
- boolean required = consumer == REQUIRED_CONSTRUCTOR_ARG_MARKER ;
251
- constructorArgInfos .add (new ConstructorArgInfo (parseField , required ));
276
+ int position = addConstructorArg (consumer , parseField );
252
277
objectParser .declareNamedObjects ((target , v ) -> target .constructorArg (position , v ), namedObjectParser , parseField );
253
278
} else {
254
279
numberOfFields += 1 ;
@@ -272,19 +297,15 @@ public <T> void declareNamedObjects(BiConsumer<Value, List<T>> consumer, NamedOb
272
297
throw new IllegalArgumentException ("[parseField] is required" );
273
298
}
274
299
275
- if (consumer == REQUIRED_CONSTRUCTOR_ARG_MARKER || consumer == OPTIONAL_CONSTRUCTOR_ARG_MARKER ) {
300
+ if (isConstructorArg ( consumer ) ) {
276
301
/*
277
- * Constructor arguments are detected by this "marker" consumer. It
278
- * keeps the API looking clean even if it is a bit sleezy. We then
279
- * build a new consumer directly against the object parser that
302
+ * Build a new consumer directly against the object parser that
280
303
* triggers the "constructor arg just arrived behavior" of the
281
304
* parser. Conveniently, we can close over the position of the
282
305
* constructor in the argument list so we don't need to do any fancy
283
306
* or expensive lookups whenever the constructor args come in.
284
307
*/
285
- int position = constructorArgInfos .size ();
286
- boolean required = consumer == REQUIRED_CONSTRUCTOR_ARG_MARKER ;
287
- constructorArgInfos .add (new ConstructorArgInfo (parseField , required ));
308
+ int position = addConstructorArg (consumer , parseField );
288
309
objectParser .declareNamedObjects ((target , v ) -> target .constructorArg (position , v ), namedObjectParser ,
289
310
wrapOrderedModeCallBack (orderedModeCallback ), parseField );
290
311
} else {
@@ -294,6 +315,27 @@ public <T> void declareNamedObjects(BiConsumer<Value, List<T>> consumer, NamedOb
294
315
}
295
316
}
296
317
318
+ /**
319
+ * Constructor arguments are detected by this "marker" consumer. It
320
+ * keeps the API looking clean even if it is a bit sleezy.
321
+ */
322
+ private boolean isConstructorArg (BiConsumer <?, ?> consumer ) {
323
+ return consumer == REQUIRED_CONSTRUCTOR_ARG_MARKER || consumer == OPTIONAL_CONSTRUCTOR_ARG_MARKER ;
324
+ }
325
+
326
+ /**
327
+ * Add a constructor argument
328
+ * @param consumer Either {@link #REQUIRED_CONSTRUCTOR_ARG_MARKER} or {@link #REQUIRED_CONSTRUCTOR_ARG_MARKER}
329
+ * @param parseField Parse field
330
+ * @return The argument position
331
+ */
332
+ private int addConstructorArg (BiConsumer <?, ?> consumer , ParseField parseField ) {
333
+ int position = constructorArgInfos .size ();
334
+ boolean required = consumer == REQUIRED_CONSTRUCTOR_ARG_MARKER ;
335
+ constructorArgInfos .add (new ConstructorArgInfo (parseField , required ));
336
+ return position ;
337
+ }
338
+
297
339
@ Override
298
340
public String getName () {
299
341
return objectParser .getName ();
0 commit comments