Skip to content

Commit

Permalink
Makes SplitIfRelativeReference do nothing on unrecognized reference t…
Browse files Browse the repository at this point in the history
…ypes, e.g., "FakeResource/123", rather than failing.

PiperOrigin-RevId: 609775155
  • Loading branch information
nickgeorge authored and Copybara-Service committed Feb 23, 2024
1 parent 37ca26f commit 0d7bca2
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 21 deletions.
22 changes: 9 additions & 13 deletions cc/google/fhir/references.cc
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,13 @@ absl::Status SplitIfRelativeReference(Message* reference) {
std::string version;
if (RE2::FullMatch(uri_string, *kInternalReferenceRegex, &resource_type,
&resource_id, &version)) {
FHIR_ASSIGN_OR_RETURN(
const FieldDescriptor* reference_id_field,
internal::GetReferenceFieldForResource(*reference, resource_type));
const FieldDescriptor* reference_id_field =
internal::GetReferenceFieldForResource(*reference, resource_type);
if (reference_id_field == nullptr) {
// Not a recognized relative reference.
return absl::OkStatus();
}

// Note that we make the reference_id off of the reference before adding it,
// since adding the reference_id would destroy the uri field, since they are
// in the same oneof. This way allows us to copy fields from uri to
Expand Down Expand Up @@ -220,19 +224,11 @@ absl::Status PopulateTypedReferenceId(const std::string& resource_id,
return absl::OkStatus();
}

absl::StatusOr<const FieldDescriptor*> GetReferenceFieldForResource(
const FieldDescriptor* GetReferenceFieldForResource(
const Message& reference, const std::string& resource_type) {
const std::string field_name =
absl::StrCat(ToSnakeCase(resource_type), "_id");
const FieldDescriptor* field =
reference.GetDescriptor()->FindFieldByName(field_name);
if (field == nullptr) {
return InvalidArgumentError(
absl::StrCat("Resource type ", resource_type,
" is not valid for a reference (field ", field_name,
" does not exist)."));
}
return field;
return reference.GetDescriptor()->FindFieldByName(field_name);
}

} // namespace internal
Expand Down
13 changes: 9 additions & 4 deletions cc/google/fhir/references.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace internal {
absl::Status PopulateTypedReferenceId(const std::string& resource_id,
const std::string& version,
::google::protobuf::Message* reference_id);
absl::StatusOr<const ::google::protobuf::FieldDescriptor*> GetReferenceFieldForResource(
const ::google::protobuf::FieldDescriptor* GetReferenceFieldForResource(
const ::google::protobuf::Message& reference, const std::string& resource_type);

} // namespace internal
Expand Down Expand Up @@ -123,9 +123,14 @@ absl::StatusOr<ReferenceType> GetReferenceProtoToResource(
base_resource_type = resource.GetDescriptor();
}

FHIR_ASSIGN_OR_RETURN(const google::protobuf::FieldDescriptor* reference_id_field,
internal::GetReferenceFieldForResource(
reference, base_resource_type->name()));
const google::protobuf::FieldDescriptor* reference_id_field =
internal::GetReferenceFieldForResource(reference,
base_resource_type->name());
if (reference_id_field == nullptr) {
return absl::InvalidArgumentError(absl::Substitute(
"$0 has no reference field for type $1",
reference.GetDescriptor()->full_name(), base_resource_type->name()));
}
::google::protobuf::Message* reference_id =
reference.GetReflection()->MutableMessage(&reference, reference_id_field);
FHIR_RETURN_IF_ERROR(internal::PopulateTypedReferenceId(
Expand Down
15 changes: 15 additions & 0 deletions cc/google/fhir/references_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,21 @@ TEST(GetReferenceProtoToResourceTest, UnprofiledProto) {
EqualsProto(expected));
}

TEST(ReferencesTest, RelativeReferenceSplit) {
Reference r;
r.mutable_uri()->set_value("Patient/123");
ASSERT_TRUE(google::fhir::SplitIfRelativeReference(&r).ok());
EXPECT_EQ(r.patient_id().value(), "123");
EXPECT_TRUE(r.uri().value().empty());
}

TEST(ReferencesTest, UnrecognizedRelativeReferenceStaysAbsolute) {
Reference r;
r.mutable_uri()->set_value("Garbage/123");
ASSERT_TRUE(google::fhir::SplitIfRelativeReference(&r).ok());
EXPECT_EQ(r.uri().value(), "Garbage/123");
}

} // namespace
} // namespace fhir
} // namespace google
3 changes: 1 addition & 2 deletions testdata/r4/validation/reference.invalid.ndjson
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{"reference": "Unknown/resourceType"}
{"uri": "invalidField"}
{"patient_id": "unknownField"}
{"patientId": "unknownField"}
{"patientId": "unknownField"}
3 changes: 1 addition & 2 deletions testdata/stu3/validation/reference.invalid.ndjson
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{"reference": "Unknown/resourceType"}
{"uri": "invalidField"}
{"patient_id": "unknownField"}
{"patientId": "unknownField"}
{"patientId": "unknownField"}

0 comments on commit 0d7bca2

Please sign in to comment.