Skip to content

Commit 1f5b5b9

Browse files
FHIR Teamcopybara-github
authored andcommitted
Fix marshal fragment with id and extension.
PiperOrigin-RevId: 811154837
1 parent 48a2f9d commit 1f5b5b9

File tree

2 files changed

+103
-4
lines changed

2 files changed

+103
-4
lines changed

go/jsonformat/marshaller.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -690,16 +690,36 @@ func (m *Marshaller) marshalNonPrimitiveFieldValue(f protoreflect.FieldDescripto
690690
}
691691

692692
func (m *Marshaller) marshalReference(rpb protoreflect.Message) (jsonpbhelper.IsJSON, error) {
693-
newRef, err := NewDenormalizedReference(rpb.Interface())
693+
// NewDenormalizedReference creates a new Reference message for marshalling but
694+
// doesn't transfer specific fields from the original fragment such as id and extension.
695+
newRefMsg, err := NewDenormalizedReference(rpb.Interface())
694696
if err != nil {
695697
return nil, err
696698
}
699+
newRef := newRefMsg.ProtoReflect()
700+
701+
refOneofDesc := rpb.Descriptor().Oneofs().ByName("reference")
702+
if refOneofDesc != nil && m.jsonFormat == formatPure {
703+
if f := rpb.WhichOneof(refOneofDesc); f != nil && f.Name() == "fragment" {
704+
fragmentMsg := rpb.Get(f).Message()
705+
706+
idField := fragmentMsg.Descriptor().Fields().ByName("id")
707+
if idField != nil && fragmentMsg.Has(idField) {
708+
newRef.Set(newRef.Descriptor().Fields().ByName("id"), fragmentMsg.Get(idField))
709+
}
710+
711+
extField := fragmentMsg.Descriptor().Fields().ByName("extension")
712+
if extField != nil && fragmentMsg.Has(extField) {
713+
newRef.Set(newRef.Descriptor().Fields().ByName("extension"), fragmentMsg.Get(extField))
714+
}
715+
}
716+
}
697717
if m.jsonFormat != formatPure {
698-
if err := normalizeRelativeReferenceAndIgnoreHistory(newRef); err != nil {
718+
if err := normalizeRelativeReferenceAndIgnoreHistory(newRefMsg); err != nil {
699719
return nil, err
700720
}
701721
}
702-
return m.marshalMessageToMap(newRef.ProtoReflect())
722+
return m.marshalMessageToMap(newRef)
703723
}
704724

705725
func (m *Marshaller) marshalMessageToMap(pb protoreflect.Message) (jsonpbhelper.JSONObject, error) {
@@ -738,7 +758,7 @@ func (m *Marshaller) marshalMessageToMap(pb protoreflect.Message) (jsonpbhelper.
738758
if err != nil {
739759
return nil, err
740760
}
741-
if m.jsonFormat != formatPure && !jsonpbhelper.IsResourceType(pb.Descriptor()) && !jsonpbhelper.IsChoice(pb.Descriptor()){
761+
if m.jsonFormat != formatPure && !jsonpbhelper.IsResourceType(pb.Descriptor()) && !jsonpbhelper.IsChoice(pb.Descriptor()) {
742762
// Omit FHIR element ID fields for analytics json.
743763
// See https://github.com/rbrush/sql-on-fhir/blob/master/sql-on-fhir.md#id-fields-omitted.
744764
delete(decmap, "id")

go/jsonformat/marshaller_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ import (
3636
r4codesystempb "github.com/google/fhir/go/proto/google/fhir/proto/r4/core/resources/code_system_go_proto"
3737
r4conditionpb "github.com/google/fhir/go/proto/google/fhir/proto/r4/core/resources/condition_go_proto"
3838
r4devicepb "github.com/google/fhir/go/proto/google/fhir/proto/r4/core/resources/device_go_proto"
39+
r4observationpb "github.com/google/fhir/go/proto/google/fhir/proto/r4/core/resources/observation_go_proto"
3940
r4patientpb "github.com/google/fhir/go/proto/google/fhir/proto/r4/core/resources/patient_go_proto"
41+
r4questionnairepb "github.com/google/fhir/go/proto/google/fhir/proto/r4/core/resources/questionnaire_go_proto"
4042
r4researchstudypb "github.com/google/fhir/go/proto/google/fhir/proto/r4/core/resources/research_study_go_proto"
4143
r4searchparampb "github.com/google/fhir/go/proto/google/fhir/proto/r4/core/resources/search_parameter_go_proto"
4244
c5pb "github.com/google/fhir/go/proto/google/fhir/proto/r5/core/codes_go_proto"
@@ -750,6 +752,83 @@ func TestMarshalResource(t *testing.T) {
750752
pretty: false,
751753
want: []byte(`{"id":"example","resourceType":"ResearchStudy","status":"draft","text":{"div":"<div xmlns=\"http://www.w3.org/1999/xhtml\">[Put rendering here]</div>","status":"generated"}}`),
752754
},
755+
{
756+
name: "Fragment_extension",
757+
inputs: []mvr{{
758+
ver: fhirversion.R4,
759+
r: &r4questionnairepb.Questionnaire{
760+
Status: &r4questionnairepb.Questionnaire_StatusCode{
761+
Value: c4pb.PublicationStatusCode_ACTIVE,
762+
},
763+
Contained: []*anypb.Any{
764+
marshalToAny(t, &r4pb.ContainedResource{
765+
OneofResource: &r4pb.ContainedResource_Observation{
766+
Observation: &r4observationpb.Observation{
767+
Id: &d4pb.Id{
768+
Value: "Observation1",
769+
},
770+
Code: &d4pb.CodeableConcept{
771+
Text: &d4pb.String{
772+
Value: "test",
773+
},
774+
},
775+
Status: &r4observationpb.Observation_StatusCode{
776+
Value: c4pb.ObservationStatusCode_FINAL,
777+
},
778+
Subject: &d4pb.Reference{
779+
Reference: &d4pb.Reference_Fragment{
780+
Fragment: &d4pb.String{
781+
Value: "Patient1",
782+
Id: &d4pb.String{Value: "123"},
783+
Extension: []*d4pb.Extension{
784+
&d4pb.Extension{
785+
Url: &d4pb.Uri{
786+
Value: "https://example.org",
787+
},
788+
Value: &d4pb.Extension_ValueX{
789+
Choice: &d4pb.Extension_ValueX_StringValue{
790+
StringValue: &d4pb.String{
791+
Value: "extension-value",
792+
},
793+
},
794+
},
795+
},
796+
},
797+
},
798+
},
799+
},
800+
},
801+
},
802+
}),
803+
},
804+
},
805+
}},
806+
pretty: true,
807+
want: []byte(`{
808+
"contained": [
809+
{
810+
"code": {
811+
"text": "test"
812+
},
813+
"id": "Observation1",
814+
"resourceType": "Observation",
815+
"status": "final",
816+
"subject": {
817+
"extension": [
818+
{
819+
"url": "https://example.org",
820+
"valueString": "extension-value"
821+
}
822+
],
823+
"id": "123",
824+
"reference": "#Patient1"
825+
}
826+
}
827+
],
828+
"resourceType": "Questionnaire",
829+
"status": "active"
830+
}`),
831+
},
753832
}
754833

755834
for _, tt := range tests {

0 commit comments

Comments
 (0)