@@ -404,6 +404,221 @@ class XmlDeserializerMapTest {
404404
405405 println (resp)
406406 }
407+
408+ // https://github.com/awslabs/aws-sdk-kotlin/issues/962
409+ @Test
410+ fun itHandlesConsecutiveFlatMaps () {
411+ val payload = """
412+ <object>
413+ <firstMap>
414+ <key>key1</key>
415+ <value>1</value>
416+ </firstMap>
417+ <firstMap>
418+ <key>key2</key>
419+ <value>2</value>
420+ </firstMap>
421+ <firstMap>
422+ <key>key3</key>
423+ <value>3</value>
424+ </firstMap>
425+ <secondMap>
426+ <key>key4</key>
427+ <value>4</value>
428+ </secondMap>
429+ <secondMap>
430+ <key>key5</key>
431+ <value>5</value>
432+ </secondMap>
433+ </object>
434+ """ .encodeToByteArray()
435+ val firstMapDescriptor = SdkFieldDescriptor (SerialKind .Map , XmlSerialName (" firstMap" ), XmlMapName (null , " key" , " value" ), Flattened )
436+ val secondMapDescriptor = SdkFieldDescriptor (SerialKind .Map , XmlSerialName (" secondMap" ), XmlMapName (null , " key" , " value" ), Flattened )
437+
438+ val objDescriptor = SdkObjectDescriptor .build {
439+ trait(XmlSerialName (" object" ))
440+ field(firstMapDescriptor)
441+ field(secondMapDescriptor)
442+ }
443+ var firstMap = mutableMapOf<String , Int >()
444+ var secondMap = mutableMapOf<String , Int >()
445+ val deserializer = XmlDeserializer (payload)
446+ deserializer.deserializeStruct(objDescriptor) {
447+ loop@while (true ) {
448+ when (findNextFieldIndex()) {
449+ firstMapDescriptor.index ->
450+ firstMap =
451+ deserializer.deserializeMap(firstMapDescriptor) {
452+ val map0 = mutableMapOf<String , Int >()
453+ while (hasNextEntry()) {
454+ val k0 = key()
455+ val v0 = if (nextHasValue()) { deserializeInt() } else { deserializeNull(); continue }
456+ map0[k0] = v0
457+ }
458+ map0
459+ }
460+ secondMapDescriptor.index ->
461+ secondMap =
462+ deserializer.deserializeMap(secondMapDescriptor) {
463+ val map0 = mutableMapOf<String , Int >()
464+ while (hasNextEntry()) {
465+ val k0 = key()
466+ val v0 = if (nextHasValue()) { deserializeInt() } else { deserializeNull(); continue }
467+ map0[k0] = v0
468+ }
469+ map0
470+ }
471+ null -> break @loop
472+ else -> skipValue()
473+ }
474+ }
475+ }
476+
477+ val expectedFirstMap = mapOf (" key1" to 1 , " key2" to 2 , " key3" to 3 )
478+ firstMap.shouldContainExactly(expectedFirstMap)
479+ val expectedSecondMap = mapOf (" key4" to 4 , " key5" to 5 )
480+ secondMap.shouldContainExactly(expectedSecondMap)
481+ }
482+
483+ @Test
484+ fun itHandlesMapsFollowedByFlatMaps () {
485+ val payload = """
486+ <object>
487+ <map>
488+ <entry>
489+ <key>key1</key>
490+ <value>1</value>
491+ </entry>
492+ <entry>
493+ <key>key2</key>
494+ <value>2</value>
495+ </entry>
496+ </map>
497+ <flatMap>
498+ <key>key3</key>
499+ <value>3</value>
500+ </flatMap>
501+ <flatMap>
502+ <key>key4</key>
503+ <value>4</value>
504+ </flatMap>
505+ </object>
506+ """ .encodeToByteArray()
507+ val mapDescriptor = SdkFieldDescriptor (SerialKind .Map , XmlSerialName (" map" ))
508+ val flatMapDescriptor = SdkFieldDescriptor (SerialKind .Map , XmlSerialName (" flatMap" ), Flattened )
509+ val objDescriptor = SdkObjectDescriptor .build {
510+ trait(XmlSerialName (" object" ))
511+ field(mapDescriptor)
512+ field(flatMapDescriptor)
513+ }
514+
515+ var map = mutableMapOf<String , Int >()
516+ var flatMap = mutableMapOf<String , Int >()
517+
518+ val deserializer = XmlDeserializer (payload)
519+ deserializer.deserializeStruct(objDescriptor) {
520+ loop@while (true ) {
521+ when (findNextFieldIndex()) {
522+ mapDescriptor.index ->
523+ map =
524+ deserializer.deserializeMap(mapDescriptor) {
525+ val map0 = mutableMapOf<String , Int >()
526+ while (hasNextEntry()) {
527+ val k0 = key()
528+ val v0 = if (nextHasValue()) { deserializeInt() } else { deserializeNull(); continue }
529+ map0[k0] = v0
530+ }
531+ map0
532+ }
533+ flatMapDescriptor.index ->
534+ flatMap =
535+ deserializer.deserializeMap(flatMapDescriptor) {
536+ val map0 = mutableMapOf<String , Int >()
537+ while (hasNextEntry()) {
538+ val k0 = key()
539+ val v0 = if (nextHasValue()) { deserializeInt() } else { deserializeNull(); continue }
540+ map0[k0] = v0
541+ }
542+ map0
543+ }
544+ null -> break @loop
545+ else -> skipValue()
546+ }
547+ }
548+ }
549+ map.shouldContainExactly(mapOf (" key1" to 1 , " key2" to 2 ))
550+ flatMap.shouldContainExactly(mapOf (" key3" to 3 , " key4" to 4 ))
551+ }
552+
553+ @Test
554+ fun itHandlesFlatMapsFollowedByMaps () {
555+ val payload = """
556+ <object>
557+ <flatMap>
558+ <key>key3</key>
559+ <value>3</value>
560+ </flatMap>
561+ <flatMap>
562+ <key>key4</key>
563+ <value>4</value>
564+ </flatMap>
565+ <map>
566+ <entry>
567+ <key>key1</key>
568+ <value>1</value>
569+ </entry>
570+ <entry>
571+ <key>key2</key>
572+ <value>2</value>
573+ </entry>
574+ </map>
575+ </object>
576+ """ .encodeToByteArray()
577+ val mapDescriptor = SdkFieldDescriptor (SerialKind .Map , XmlSerialName (" map" ))
578+ val flatMapDescriptor = SdkFieldDescriptor (SerialKind .Map , XmlSerialName (" flatMap" ), Flattened )
579+ val objDescriptor = SdkObjectDescriptor .build {
580+ trait(XmlSerialName (" object" ))
581+ field(mapDescriptor)
582+ field(flatMapDescriptor)
583+ }
584+
585+ var map = mutableMapOf<String , Int >()
586+ var flatMap = mutableMapOf<String , Int >()
587+
588+ val deserializer = XmlDeserializer (payload)
589+ deserializer.deserializeStruct(objDescriptor) {
590+ loop@while (true ) {
591+ when (findNextFieldIndex()) {
592+ mapDescriptor.index ->
593+ map =
594+ deserializer.deserializeMap(mapDescriptor) {
595+ val map0 = mutableMapOf<String , Int >()
596+ while (hasNextEntry()) {
597+ val k0 = key()
598+ val v0 = if (nextHasValue()) { deserializeInt() } else { deserializeNull(); continue }
599+ map0[k0] = v0
600+ }
601+ map0
602+ }
603+ flatMapDescriptor.index ->
604+ flatMap =
605+ deserializer.deserializeMap(flatMapDescriptor) {
606+ val map0 = mutableMapOf<String , Int >()
607+ while (hasNextEntry()) {
608+ val k0 = key()
609+ val v0 = if (nextHasValue()) { deserializeInt() } else { deserializeNull(); continue }
610+ map0[k0] = v0
611+ }
612+ map0
613+ }
614+ null -> break @loop
615+ else -> skipValue()
616+ }
617+ }
618+ }
619+ map.shouldContainExactly(mapOf (" key1" to 1 , " key2" to 2 ))
620+ flatMap.shouldContainExactly(mapOf (" key3" to 3 , " key4" to 4 ))
621+ }
407622}
408623
409624internal class XmlMapsOperationDeserializer () {
0 commit comments