in runtime/serde/serde-xml/common/src/aws/smithy/kotlin/runtime/serde/xml/XmlDeserializer.kt [143:187]
override fun hasNextElement(): Boolean {
if (!flattened && firstCall) {
val nextToken = reader.peek()
val matchedListDescriptor = nextToken is XmlToken.BeginElement && descriptor.nameMatches(nextToken.name.tag)
val hasChildren = if (nextToken == null) false else nextToken.depth >= reader.lastToken!!.depth
if (!matchedListDescriptor && !hasChildren) return false
// Discard the wrapper and move to the first element in the list
if (matchedListDescriptor) reader.nextToken()
firstCall = false
}
if (flattened) {
// Because our subtree is not CHILD, we cannot rely on the subtree boundary to determine end of collection.
// Rather, we search for either the next begin token matching the (flat) list member name which should
// be immediately after the current token
// peek at the next token if there is one, in the case of a list of structs, the next token is actually
// the end of the current flat list element in which case we need to peek twice
val next = when (val peeked = reader.peek()) {
is XmlToken.EndElement -> {
if (peeked.name.local == descriptor.serialName.name) {
// consume the end token
reader.nextToken()
reader.peek()
} else {
peeked
}
}
else -> peeked
}
val tokens = listOfNotNull(reader.lastToken, next)
// Iterate over the token stream until begin token matching name is found or end element matching list is found.
return tokens
.filterIsInstance<XmlToken.BeginElement>()
.any { it.name.local == descriptor.serialName.name }
} else {
// If we can find another begin token w/ the element name, we have more elements to process
return reader.seek<XmlToken.BeginElement> { it.name.local == elementName }.isNotTerminal()
}
}