@@ -367,10 +367,10 @@ def computeMData.map [Monad m] [MonadQuotation m] [MonadError m] [MonadEnv m] [M
367367 }
368368
369369def computeMData.ordinary.computeShape [Monad m] [MonadQuotation m] [MonadError m] [MonadEnv m] [MonadOptions m] [MonadLog m] [MonadRef m] [AddMessageContext m] [MonadResolveName m]
370- (mod? : Modifier) (is_scalar : Bool ) (lean_type_inner : Ident) : m (TSyntax `term × LeanShape) := do
370+ (mod? : Modifier) (internal_type? : Option InternalType) (enum_type? : Option Name ) (lean_type_inner : Ident) : m (TSyntax `term × LeanShape) := do
371371 match mod? with
372372 | .default | .required =>
373- if is_scalar then
373+ if internal_type?.isSome || enum_type?.isSome then
374374 pure (← `($lean_type_inner), LeanShape.strict)
375375 else
376376 pure (← `(Option $lean_type_inner), LeanShape.option)
@@ -424,7 +424,7 @@ def computeMData.ordinary [Monad m] [MonadQuotation m] [MonadError m] [MonadEnv
424424 let (is_scalar, internal_type?, enum_type?, oneof_type?) ← getProtoTypeMData mutEnums mutOneofs messages proto_type
425425 if oneof_type?.isSome && !(mod? matches .default) then
426426 throwErrorAt name "oneof field cannot have cardinality modifier: {oneof_type?.get!}"
427- let (lean_type, lean_shape) ← computeMData.ordinary.computeShape mod? is_scalar lean_type_inner
427+ let (lean_type, lean_shape) ← computeMData.ordinary.computeShape mod? internal_type? enum_type? lean_type_inner
428428 let builder? ← internal_type?.mapM InternalType.builder
429429 let builder? := if oneof_type?.isNone then some (builder?.getD (mkIdentFrom proto_type (proto_type.getId.str "builder" ))) else none
430430 let toMessage? := if is_scalar then none else some (mkIdentFrom proto_type (proto_type.getId.str "toMessage" ))
551551private def construct_toMessage (name : Ident) (push_name : String → Ident) (fields : Array ProtoFieldMData) : CommandElabM (Ident × Command) := do
552552 let msg ← mkIdent <$> mkFreshUserName `msg
553553 let val ← mkIdent <$> mkFreshUserName `val
554- let toMessageBody ← fields.mapM fun {mod, field_proj, field_num, options, is_scalar, builder?, oneof_type?, toMessage?, test_unset, map_info?, ..} => do
554+ let toMessageBody ← fields.mapM fun {mod, field_proj, field_num, options, is_scalar, internal_type?, builder?, enum_type ?, oneof_type?, toMessage?, test_unset, map_info?, ..} => do
555555 if let some map_info := map_info? then
556556 let entries ← mkIdent <$> mkFreshUserName `entries
557557 let submsg ← mkIdent <$> mkFreshUserName `submsg
@@ -586,7 +586,7 @@ private def construct_toMessage (name : Ident) (push_name : String → Ident) (f
586586 let builder := builder?.get!
587587 match mod with
588588 | .default =>
589- if is_scalar then
589+ if internal_type?.isSome || enum_type?.isSome then
590590 `(Parser.Term.doSeqItem| let $msg ← do
591591 if $test_unset ($field_proj $val) then
592592 pure $msg
@@ -595,7 +595,7 @@ private def construct_toMessage (name : Ident) (push_name : String → Ident) (f
595595 else
596596 `(Parser.Term.doSeqItem| let $msg ← $field_num:num <~? (Option.mapM $builder ($field_proj $val)) # $msg)
597597 | .required =>
598- if is_scalar then
598+ if internal_type?.isSome || enum_type?.isSome then
599599 `(Parser.Term.doSeqItem| let $msg ← do
600600 if $test_unset ($field_proj $val) then
601601 pure $msg
@@ -612,10 +612,20 @@ private def construct_toMessage (name : Ident) (push_name : String → Ident) (f
612612 | .optional =>
613613 `(Parser.Term.doSeqItem| let $msg ← $field_num:num <~? (Option.mapM $builder ($field_proj $val)) # $msg)
614614 | .repeated =>
615- if options.packed?.getD is_scalar then
616- `(Parser.Term.doSeqItem| let $msg ← $field_num:num <~p (Array.mapM $builder ($field_proj $val)) # $msg)
615+ if options.packed?.isEqSome true then
616+ `(Parser.Term.doSeqItem|
617+ let $msg ← do
618+ if $test_unset ($field_proj $val) then
619+ pure $msg
620+ else
621+ $field_num:num <~p (Array.mapM $builder ($field_proj $val)) # $msg)
617622 else
618- `(Parser.Term.doSeqItem| let $msg ← $field_num:num <~f (Array.mapM $builder ($field_proj $val)) # $msg)
623+ `(Parser.Term.doSeqItem|
624+ let $msg ← do
625+ if $test_unset ($field_proj $val) then
626+ pure $msg
627+ else
628+ $field_num:num <~f (Array.mapM $builder ($field_proj $val)) # $msg)
619629 let toMessageId := push_name "toMessage"
620630 let toMessage ← `(partial def $toMessageId :ident : $name → Except Protobuf.Encoding.ProtoError Protobuf.Encoding.Message := fun $val => do
621631 let $msg:ident := Protobuf.Encoding.Message.emptyWithCapacity $(quote fields.size)
@@ -637,7 +647,7 @@ private def construct_builder (name : Ident) (push_name : String → Ident) (toM
637647private def construct_fromMessage (name : Ident) (push_name : String → Ident) (fields : Array ProtoFieldMData) : CommandElabM (Ident × Command) := do
638648 let msg ← mkIdent <$> mkFreshUserName `msg
639649 let ns := fields.map ProtoFieldMData.field_num
640- let decoder ← fields.mapM (β := (Ident × TSyntax ``Parser.Term.doSeqItem)) fun {mod, field_name, field_proj, field_num, options, is_scalar, oneof_type?, decoder??, decoder_rep?, decoder_rep_packed?, fromMessage??, map_info?, ..} => do
650+ let decoder ← fields.mapM (β := (Ident × TSyntax ``Parser.Term.doSeqItem)) fun {mod, field_name, field_proj, field_num, options, is_scalar, internal_type?, enum_type?, oneof_type?, decoder??, decoder_rep?, decoder_rep_packed?, fromMessage??, map_info?, ..} => do
641651 let var ← mkIdent <$> mkFreshUserName (field_name.getId)
642652 if let some map_info := map_info? then
643653 let key_decoder? := map_info.key_decoder?
@@ -668,12 +678,12 @@ private def construct_fromMessage (name : Ident) (push_name : String → Ident)
668678 let decoder? := decoder??.get!
669679 let stx ← match mod with
670680 | .default =>
671- if is_scalar then
681+ if internal_type?.isSome || enum_type?.isSome then
672682 `(Parser.Term.doSeqItem| let $var ← ($decoder? $msg $field_num:num <&> (fun x => Option.getD x Inhabited.default)))
673683 else
674684 `(Parser.Term.doSeqItem| let $var ← ($decoder? $msg $field_num:num))
675685 | .required =>
676- if is_scalar then
686+ if internal_type?.isSome || enum_type?.isSome then
677687 `(Parser.Term.doSeqItem| let $var ← ($decoder? $msg $field_num:num >>= (fun x => Option.getDM x
678688 (throw (Protobuf.Encoding.ProtoError.missingRequiredField s! "required field `{ $(quote field_proj.getId.toString)} ` is missing when decoding the message" )))))
679689 else
@@ -686,7 +696,7 @@ private def construct_fromMessage (name : Ident) (push_name : String → Ident)
686696 | .optional =>
687697 `(Parser.Term.doSeqItem| let $var ← ($decoder? $msg $field_num:num))
688698 | .repeated =>
689- if options.packed?.getD is_scalar then
699+ if options.packed?.isEqSome true then
690700 assert! decoder_rep_packed?.isSome
691701 let decoder_rep_packed := decoder_rep_packed?.get!
692702 `(Parser.Term.doSeqItem| let $var ← ($decoder_rep_packed $msg $field_num:num))
@@ -730,7 +740,7 @@ private def construct_decoder_rep (name : Ident) (push_name : String → Ident)
730740private def construct_merge (name : Ident) (push_name : String → Ident) (fields : Array ProtoFieldMData) : CommandElabM (Ident × Command) := do
731741 let a ← mkIdent <$> mkFreshUserName `a
732742 let b ← mkIdent <$> mkFreshUserName `b
733- let mergeBody ← fields.mapM (β := (Ident × TSyntax ``Parser.Term.doSeqItem)) fun {mod, proto_type, field_name, field_proj := field_proj, is_scalar , oneof_type?, map_info?, ..} => do
743+ let mergeBody ← fields.mapM (β := (Ident × TSyntax ``Parser.Term.doSeqItem)) fun {mod, proto_type, field_name, field_proj, internal_type?, enum_type? , oneof_type?, map_info?, ..} => do
734744 let var ← mkIdent <$> mkFreshUserName (field_name.getId)
735745 let va ← `($field_proj $a)
736746 let vb ← `($field_proj $b)
@@ -744,18 +754,16 @@ private def construct_merge (name : Ident) (push_name : String → Ident) (field
744754 else
745755 let stx ← match mod with
746756 | .default | .required =>
747- if is_scalar then
757+ if internal_type?.isSome || enum_type?.isSome then
748758 `(Parser.Term.doSeqItem| let $var := $vb)
749- else if (proto_type matches `(string) | `(bytes)) then
750- `(Parser.Term.doSeqItem| let $var := $vb <|> $va) -- optional, last first
751759 else
752760 `(Parser.Term.doSeqItem| let $var := match $va:term, $vb:term with
753761 | Option.some x, Option.some y => Option.some ($merger x y)
754762 | Option.some x, _ => Option.some x
755763 | _, Option.some y => Option.some y
756764 | _, _ => Option.none)
757765 | .optional =>
758- if is_scalar || (proto_type matches `(string) | `(bytes)) then
766+ if internal_type?.isSome || enum_type?.isSome then
759767 `(Parser.Term.doSeqItem| let $var := $vb <|> $va)
760768 else
761769 `(Parser.Term.doSeqItem| let $var := match $va:term, $vb:term with
0 commit comments