@@ -564,25 +564,38 @@ func marshalUnknownValue(val Value, typ Type, p *AttributePath, enc *msgpack.Enc
564564 refnEnc := msgpack .NewEncoder (& refnBuf )
565565 mapLen := 0
566566
567- for _ , refn := range val .refinements {
568- switch refnVal := refn .(type ) {
569- case refinement.Nullness :
570- err := refnEnc .EncodeInt (int64 (refinement .KeyNullness ))
571- if err != nil {
572- return p .NewErrorf ("error encoding Nullness value refinement key: %w" , err )
573- }
567+ // Nullness refinement applies to all types except for DynamicPseudoType (handled above)
568+ if refnVal , ok := val .refinements [refinement .KeyNullness ]; ok {
569+ data , ok := refnVal .(refinement.Nullness )
570+ if ! ok {
571+ return p .NewErrorf ("error encoding Nullness value refinement: unexpected refinement data of type %T" , refnVal )
572+ }
574573
575- // It shouldn't be possible for an unknown value to be definitely null (i.e. nullness.value = true),
576- // as that should be represented by a known null value instead. This encoding is in place to be compliant
577- // with Terraform's encoding which uses a definitely null refinement to collapse into a known null value.
578- err = refnEnc .EncodeBool (refnVal .Nullness ())
579- if err != nil {
580- return p .NewErrorf ("error encoding Nullness value refinement: %w" , err )
574+ err := refnEnc .EncodeInt (int64 (refinement .KeyNullness ))
575+ if err != nil {
576+ return p .NewErrorf ("error encoding Nullness value refinement key: %w" , err )
577+ }
578+
579+ // It shouldn't be possible for an unknown value to be definitely null (i.e. nullness.value = true),
580+ // as that should be represented by a known null value instead. This encoding is in place to be compliant
581+ // with Terraform's encoding which uses a definitely null refinement to collapse into a known null value.
582+ err = refnEnc .EncodeBool (data .Nullness ())
583+ if err != nil {
584+ return p .NewErrorf ("error encoding Nullness value refinement: %w" , err )
585+ }
586+
587+ mapLen ++
588+ }
589+
590+ // Refinements for strings
591+ if typ .Is (String ) {
592+ if refnVal , ok := val .refinements [refinement .KeyStringPrefix ]; ok {
593+ data , ok := refnVal .(refinement.StringPrefix )
594+ if ! ok {
595+ return p .NewErrorf ("error encoding StringPrefix value refinement: unexpected refinement data of type %T" , refnVal )
581596 }
582597
583- mapLen ++
584- case refinement.StringPrefix :
585- if rawPrefix := refnVal .PrefixValue (); rawPrefix != "" {
598+ if rawPrefix := data .PrefixValue (); rawPrefix != "" {
586599 // Matching go-cty for the max prefix length allowed here
587600 //
588601 // This ensures the total size of the refinements blob does not exceed the limit
@@ -605,17 +618,26 @@ func marshalUnknownValue(val Value, typ Type, p *AttributePath, enc *msgpack.Enc
605618
606619 mapLen ++
607620 }
621+ }
622+ }
623+
624+ // Refinements for numbers
625+ if typ .Is (Number ) {
626+ if refnVal , ok := val .refinements [refinement .KeyNumberLowerBound ]; ok {
627+ data , ok := refnVal .(refinement.NumberLowerBound )
628+ if ! ok {
629+ return p .NewErrorf ("error encoding NumberLowerBound value refinement: unexpected refinement data of type %T" , refnVal )
630+ }
608631
609- case refinement.NumberLowerBound :
610632 // TODO: should check this isn't negative infinity? To match go-cty
611633 boundTfType := Tuple {ElementTypes : []Type {Number , Bool }}
612634
613635 // TODO: Do we need to do this? Kind of nasty
614636 boundTfVal := NewValue (
615637 boundTfType ,
616638 []Value {
617- NewValue (Number , refnVal .LowerBound ()),
618- NewValue (Bool , refnVal .IsInclusive ()),
639+ NewValue (Number , data .LowerBound ()),
640+ NewValue (Bool , data .IsInclusive ()),
619641 },
620642 )
621643
@@ -630,16 +652,23 @@ func marshalUnknownValue(val Value, typ Type, p *AttributePath, enc *msgpack.Enc
630652 }
631653
632654 mapLen ++
633- case refinement.NumberUpperBound :
655+ }
656+
657+ if refnVal , ok := val .refinements [refinement .KeyNumberUpperBound ]; ok {
658+ data , ok := refnVal .(refinement.NumberUpperBound )
659+ if ! ok {
660+ return p .NewErrorf ("error encoding NumberUpperBound value refinement: unexpected refinement data of type %T" , refnVal )
661+ }
662+
634663 // TODO: should check this isn't positive infinity? To match go-cty
635664 boundTfType := Tuple {ElementTypes : []Type {Number , Bool }}
636665
637666 // TODO: Do we need to do this? Kind of nasty
638667 boundTfVal := NewValue (
639668 boundTfType ,
640669 []Value {
641- NewValue (Number , refnVal .UpperBound ()),
642- NewValue (Bool , refnVal .IsInclusive ()),
670+ NewValue (Number , data .UpperBound ()),
671+ NewValue (Bool , data .IsInclusive ()),
643672 },
644673 )
645674
@@ -654,32 +683,46 @@ func marshalUnknownValue(val Value, typ Type, p *AttributePath, enc *msgpack.Enc
654683 }
655684
656685 mapLen ++
657- case refinement.CollectionLengthLowerBound :
686+ }
687+ }
688+
689+ // Refinements for collections
690+ if typ .Is (List {}) || typ .Is (Map {}) || typ .Is (Set {}) {
691+ if refnVal , ok := val .refinements [refinement .KeyCollectionLengthLowerBound ]; ok {
692+ data , ok := refnVal .(refinement.CollectionLengthLowerBound )
693+ if ! ok {
694+ return p .NewErrorf ("error encoding CollectionLengthLowerBound value refinement: unexpected refinement data of type %T" , refnVal )
695+ }
696+
658697 err := refnEnc .EncodeInt (int64 (refinement .KeyCollectionLengthLowerBound ))
659698 if err != nil {
660699 return p .NewErrorf ("error encoding CollectionLengthLowerBound value refinement key: %w" , err )
661700 }
662701
663- err = refnEnc .EncodeInt (refnVal .LowerBound ())
702+ err = refnEnc .EncodeInt (data .LowerBound ())
664703 if err != nil {
665704 return p .NewErrorf ("error encoding CollectionLengthLowerBound value refinement: %w" , err )
666705 }
667706
668707 mapLen ++
669- case refinement.CollectionLengthUpperBound :
708+ }
709+
710+ if refnVal , ok := val .refinements [refinement .KeyCollectionLengthUpperBound ]; ok {
711+ data , ok := refnVal .(refinement.CollectionLengthUpperBound )
712+ if ! ok {
713+ return p .NewErrorf ("error encoding CollectionLengthUpperBound value refinement: unexpected refinement data of type %T" , refnVal )
714+ }
670715 err := refnEnc .EncodeInt (int64 (refinement .KeyCollectionLengthUpperBound ))
671716 if err != nil {
672717 return p .NewErrorf ("error encoding CollectionLengthUpperBound value refinement key: %w" , err )
673718 }
674719
675- err = refnEnc .EncodeInt (refnVal .UpperBound ())
720+ err = refnEnc .EncodeInt (data .UpperBound ())
676721 if err != nil {
677722 return p .NewErrorf ("error encoding CollectionLengthUpperBound value refinement: %w" , err )
678723 }
679724
680725 mapLen ++
681- default :
682- continue
683726 }
684727 }
685728
0 commit comments