Skip to content

Commit

Permalink
Explicitly handle the Reference.uri field in JSON (de-)serialization …
Browse files Browse the repository at this point in the history
…for FHIR protos since the json name caused a conflict that is no longer permitted in all languages.

This commit has no visible change in behavior, it is a pre-factor for removing the conflicting field name from the generated protocol buffers.

PiperOrigin-RevId: 623245707
  • Loading branch information
rbrush authored and Copybara-Service committed Apr 18, 2024
1 parent 669c086 commit f32916b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
19 changes: 17 additions & 2 deletions go/jsonformat/internal/jsonpbhelper/fhirutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,12 @@ func IsPrimitiveType(d protoreflect.MessageDescriptor) bool {
return ext == apb.StructureDefinitionKindValue_KIND_PRIMITIVE_TYPE
}

// IsReferenceType returns true iff type d is a FHIR reference type.
func IsReferenceType(d protoreflect.MessageDescriptor) bool {
ext := proto.GetExtension(d.Options(), apb.E_FhirStructureDefinitionUrl)
return ext == "http:https://hl7.org/fhir/StructureDefinition/Reference"
}

// IsResourceType returns true iff the message type d is a FHIR resource type.
func IsResourceType(d protoreflect.MessageDescriptor) bool {
ext := proto.GetExtension(d.Options(), apb.E_StructureDefinitionKind).(apb.StructureDefinitionKindValue)
Expand Down Expand Up @@ -1197,9 +1203,18 @@ func buildFieldMap(desc protoreflect.MessageDescriptor) map[string]protoreflect.
fieldMap[name] = f
}
} else {
fieldMap[f.JSONName()] = f
// Historically the FHIR reference URI was mapped to the JSON name "reference", but this
// conflict between a JSON name and protobuf name is now disallowed in some languages, so
// we cannot rely on it in the protobuf definitions.
var jsonName string
if f.JSONName() == "uri" && IsReferenceType(desc) {
jsonName = "reference"
} else {
jsonName = f.JSONName()
}
fieldMap[jsonName] = f
if f.Kind() == protoreflect.MessageKind && IsPrimitiveType(f.Message()) {
fieldMap["_"+f.JSONName()] = f
fieldMap["_"+jsonName] = f
}
}
}
Expand Down
10 changes: 9 additions & 1 deletion go/jsonformat/marshaller.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,15 @@ func (m *Marshaller) marshalExtensions(pb protoreflect.Message, extField protore
}

func (m *Marshaller) marshalFieldValue(decmap jsonpbhelper.JSONObject, f protoreflect.FieldDescriptor, pb protoreflect.Message) error {
jsonName := f.JSONName()
// Historically the FHIR reference URI was mapped to the JSON name "reference", but this
// conflict between a JSON name and protobuf name is now disallowed in some languages, so
// we cannot rely on it in the protobuf definitions.
var jsonName string
if f.JSONName() == "uri" && jsonpbhelper.IsReferenceType(f.Parent().(protoreflect.MessageDescriptor)) {
jsonName = "reference"
} else {
jsonName = f.JSONName()
}
if m.jsonFormat == formatPure {
// for choice type fields in non-analytics output, we need to zoom into the field within oneof.
// e.g. value.quantity changed to valueQuantity
Expand Down

0 comments on commit f32916b

Please sign in to comment.