if (_closed) {
return null;
}
while (true) {
Event evt = _yamlParser.getEvent();
// is null ok? Assume it is, for now, consider to be same as end-of-doc
if (evt == null) {
return (_currToken = null);
}
_lastEvent = evt;
/* One complication: field names are only inferred from the
* fact that we are in Object context...
*/
if (_parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) {
if (!evt.is(Event.ID.Scalar)) {
// end is fine
if (evt.is(Event.ID.MappingEnd)) {
if (!_parsingContext.inObject()) { // sanity check is optional, but let's do it for now
_reportMismatchedEndMarker('}', ']');
}
_parsingContext = _parsingContext.getParent();
return (_currToken = JsonToken.END_OBJECT);
}
_reportError("Expected a field name (Scalar value in YAML), got this instead: "+evt);
}
String name = ((ScalarEvent) evt).getValue();
_currentFieldName = name;
_parsingContext.setCurrentName(name);
return (_currToken = JsonToken.FIELD_NAME);
}
// Ugh. Why not expose id, to be able to Switch?
// scalar values are probably the commonest:
if (evt.is(Event.ID.Scalar)) {
return (_currToken = _decodeScalar((ScalarEvent) evt));
}
// followed by maps, then arrays
if (evt.is(Event.ID.MappingStart)) {
Mark m = evt.getStartMark();
_parsingContext = _parsingContext.createChildObjectContext(m.getLine(), m.getColumn());
return (_currToken = JsonToken.START_OBJECT);
}
if (evt.is(Event.ID.MappingEnd)) { // actually error; can not have map-end here
_reportError("Not expecting END_OBJECT but a value");
}
if (evt.is(Event.ID.SequenceStart)) {
Mark m = evt.getStartMark();
_parsingContext = _parsingContext.createChildArrayContext(m.getLine(), m.getColumn());
return (_currToken = JsonToken.START_ARRAY);
}
if (evt.is(Event.ID.SequenceEnd)) {
if (!_parsingContext.inArray()) { // sanity check is optional, but let's do it for now
_reportMismatchedEndMarker(']', '}');
}
_parsingContext = _parsingContext.getParent();
return (_currToken = JsonToken.END_ARRAY);
}
// after this, less common tokens:
if (evt.is(Event.ID.DocumentEnd)) {
// logical end of doc; fine. Two choices; either skip, or
// return null as marker. Do latter, for now. But do NOT close.
return (_currToken = null);
}
if (evt.is(Event.ID.DocumentStart)) {
// does this matter? Shouldn't, should it?
continue;
}
if (evt.is(Event.ID.Alias)) {
// for now, nothing to do: in future, maybe try to expose as ObjectIds?
continue;
}
if (evt.is(Event.ID.StreamEnd)) { // end-of-input; force closure
close();
return (_currToken = null);
}
if (evt.is(Event.ID.StreamStart)) { // useless, skip
continue;
}
}
}