@@ -461,6 +461,7 @@ class Printer private (config: Printer.PrinterConfig) {
461461object Parser {
462462 private final case class ParserConfig (
463463 isIgnoringUnknownFields : Boolean ,
464+ failOnOverlappingOneofKeys : Boolean ,
464465 mapEntriesAsKeyValuePairs : Boolean ,
465466 formatRegistry : FormatRegistry ,
466467 typeRegistry : TypeRegistry
@@ -472,6 +473,7 @@ class Parser private (config: Parser.ParserConfig) {
472473 this (
473474 Parser .ParserConfig (
474475 isIgnoringUnknownFields = false ,
476+ failOnOverlappingOneofKeys = false ,
475477 mapEntriesAsKeyValuePairs = false ,
476478 JsonFormat .DefaultRegistry ,
477479 TypeRegistry .empty
@@ -490,6 +492,7 @@ class Parser private (config: Parser.ParserConfig) {
490492 this (
491493 Parser .ParserConfig (
492494 isIgnoringUnknownFields = false ,
495+ failOnOverlappingOneofKeys = false ,
493496 mapEntriesAsKeyValuePairs = false ,
494497 formatRegistry,
495498 typeRegistry
@@ -499,6 +502,9 @@ class Parser private (config: Parser.ParserConfig) {
499502 def ignoringUnknownFields : Parser =
500503 new Parser (config.copy(isIgnoringUnknownFields = true ))
501504
505+ def failOnOverlappingOneofKeys : Parser =
506+ new Parser (config.copy(failOnOverlappingOneofKeys = true ))
507+
502508 def mapEntriesAsKeyValuePairs : Parser =
503509 new Parser (config.copy(mapEntriesAsKeyValuePairs = true ))
504510
@@ -527,7 +533,24 @@ class Parser private (config: Parser.ParserConfig) {
527533 value : JValue ,
528534 skipTypeUrl : Boolean
529535 )(implicit cmp : GeneratedMessageCompanion [A ]): A = {
530- cmp.messageReads.read(fromJsonToPMessage(cmp, value, skipTypeUrl))
536+ val message = fromJsonToPMessage(cmp, value, skipTypeUrl)
537+ if (config.failOnOverlappingOneofKeys) {
538+ validateOneofs(message)
539+ }
540+ cmp.messageReads.read(message)
541+ }
542+
543+ private def validateOneofs [A <: GeneratedMessage ](message : PMessage ) = {
544+ message.value.keys
545+ .groupBy(_.containingOneof)
546+ .filter(x => x._1.isDefined && x._2.size != 1 )
547+ .values
548+ .headOption
549+ .foreach(keys =>
550+ throw new JsonFormatException (
551+ s " Overlapping keys in oneof: ${keys.map(_.name).mkString(" , " )}"
552+ )
553+ )
531554 }
532555
533556 private def fromJsonToPMessage (
0 commit comments