@@ -805,6 +805,9 @@ object JsonCodec {
805805 case Json .Null => DynamicValue .NoneValue
806806 }
807807
808+ private def error (msg : String , trace : List [JsonError ]): Nothing =
809+ throw UnsafeJson (JsonError .Message (msg) :: trace)
810+
808811 private def enumDecoder [Z ](parentSchema : Schema .Enum [Z ]): ZJsonDecoder [Z ] = {
809812 val caseNameAliases = new mutable.HashMap [String , Schema .Case [Z , Any ]]
810813 parentSchema.cases.foreach { case_ =>
@@ -813,9 +816,6 @@ object JsonCodec {
813816 case_.caseNameAliases.foreach(a => caseNameAliases.put(a, schema))
814817 }
815818
816- def error (msg : String , trace : List [JsonError ]): Nothing =
817- throw UnsafeJson (JsonError .Message (msg) :: trace)
818-
819819 if (parentSchema.cases.forall(_.schema.isInstanceOf [Schema .CaseClass0 [_]])) { // if all cases are CaseClass0, decode as String
820820 if (caseNameAliases.size <= 64 ) {
821821 new ZJsonDecoder [Z ] {
@@ -973,15 +973,10 @@ object JsonCodec {
973973 val capacity = schema.fields.size * 2
974974 val spansWithDecoders =
975975 new util.HashMap [String , (JsonError .ObjectAccess , ZJsonDecoder [Any ])](capacity)
976- val defaults = new util.HashMap [String , Any ](capacity)
977976 schema.fields.foreach { field =>
978- val fieldName = field.fieldName
979977 val spanWithDecoder =
980- (JsonError .ObjectAccess (fieldName), schemaDecoder(field.schema).asInstanceOf [ZJsonDecoder [Any ]])
978+ (JsonError .ObjectAccess (field. fieldName), schemaDecoder(field.schema).asInstanceOf [ZJsonDecoder [Any ]])
981979 field.nameAndAliases.foreach(x => spansWithDecoders.put(x, spanWithDecoder))
982- if ((field.optional || field.transient) && field.defaultValue.isDefined) {
983- defaults.put(fieldName, field.defaultValue.get)
984- }
985980 }
986981 val skipExtraFields = ! schema.annotations.exists(_.isInstanceOf [rejectExtraFields])
987982 (trace : List [JsonError ], in : RetractReader ) => {
@@ -1002,21 +997,33 @@ object JsonCodec {
1002997 lexer.char(trace_, in, ':' )
1003998 val fieldName = span.field
1004999 val prev = map.put(fieldName, dec.unsafeDecode(trace_, in))
1005- if (prev != null ) {
1006- throw UnsafeJson (JsonError .Message (" duplicate" ) :: trace_)
1007- }
1000+ if (prev != null ) error(" duplicate" , trace_)
10081001 } else if (skipExtraFields || discriminator.contains(fieldNameOrAlias)) {
10091002 lexer.char(trace, in, ':' )
10101003 lexer.skipValue(trace, in)
1011- } else {
1012- throw UnsafeJson (JsonError .Message (s " unexpected field: $fieldNameOrAlias" ) :: trace)
1013- }
1004+ } else error(" extra field" , trace)
10141005 continue = lexer.nextField(trace, in)
10151006 }
1016- val it = defaults.entrySet().iterator()
1017- while (it.hasNext) {
1018- val entry = it.next()
1019- map.putIfAbsent(entry.getKey, entry.getValue)
1007+ schema.fields.foreach { field =>
1008+ map.computeIfAbsent(
1009+ field.fieldName,
1010+ fieldName => {
1011+ if ((field.optional || field.transient) && field.defaultValue.isDefined) {
1012+ field.defaultValue.get
1013+ } else {
1014+ var schema = field.schema
1015+ schema match {
1016+ case l : Schema .Lazy [_] => schema = l.schema
1017+ case _ =>
1018+ }
1019+ schema match {
1020+ case _ : Schema .Optional [_] => None
1021+ case collection : Schema .Collection [_, _] => collection.empty
1022+ case _ => error(" missing" , spansWithDecoders.get(fieldName)._1 :: trace)
1023+ }
1024+ }
1025+ }
1026+ )
10201027 }
10211028 (ListMap .newBuilder[String , Any ] ++= ({ // to avoid O(n) insert operations
10221029 import scala .collection .JavaConverters .mapAsScalaMapConverter // use deprecated class for Scala 2.12 compatibility
@@ -1095,10 +1102,7 @@ object JsonCodec {
10951102 case (Some (a), Some (b)) => Fallback .Both (a, b)
10961103 case (Some (a), _) => Fallback .Left (a)
10971104 case (_, Some (b)) => Fallback .Right (b)
1098- case _ =>
1099- throw UnsafeJson (
1100- JsonError .Message (" Fallback decoder was unable to decode both left and right sides" ) :: trace
1101- )
1105+ case _ => error(" Fallback decoder was unable to decode both left and right sides" , trace)
11021106 }
11031107 }
11041108 }
0 commit comments