FHIR / sushi

SUSHI (aka "SUSHI Unshortens Short Hand Inputs") is a reference implementation command-line interpreter/compiler for FHIR Shorthand (FSH).
Apache License 2.0
147 stars 43 forks source link

Inability to create example data referencing sub extension #391

Closed bwalsh closed 4 years ago

bwalsh commented 4 years ago

Problem

Following guide https://build.fhir.org/ig/HL7/fhir-shorthand/reference.html#extension-paths and comments in #108 and #136

All attempts to access the sub-extension fail with Cannot resolve element from path: See AnvilResearchStudyExample below

Input


Extension:      AnvilDocumentReference
Id:             anvil-document-reference
Title:          "AnVIL document reference"
Description:    "An association to a document."
* value[x] only DRSAttachment

Profile:        AnvilResearchStudy
Parent:         ResearchStudy
Id:             anvil-research-study
Title:          "AnVIL ResearchStudy"
Description:    "An AnVIL ResearchStudy."
* extension contains 
    AnvilDocumentReference named attachments 0..*

Profile:        AnvilResearchSubject
Parent:         ResearchSubject
Id:             anvil-research-subject
Title:          "AnVIL ResearchSubject"
Description:    "An AnVIL ResearchSubject."
* extension contains 
    AnvilDocumentReference named attachments 0..*

Profile:        AnvilSpecimen
Parent:         Specimen
Id:             anvil-specimen
Title:          "AnVIL Specimen"
Description:    "An AnVIL Specimen."
* extension contains 
    AnvilDocumentReference named attachments 0..*

Instance: DRSAttachmentExampleMinimal
InstanceOf: DRSAttachment
Description: "An example representation of a DRSAttachment"
* extension[drs].id = "any-fhir-attachment-id"
* extension[drs].extension[id].valueString = "any-drs-id"
* extension[drs].extension[name].valueString = "any-file-name"
* extension[drs].extension[self_uri].valueString = "drs://url-here"
* extension[drs].extension[created_time].valueDateTime = "1985-04-12T23:20:50.52Z"
* extension[drs].extension[updated_time].valueDateTime = "1985-04-12T23:20:50.52Z"
* extension[drs].extension[size].valueInteger = 12345
* extension[drs].extension[version].valueString = "0.0.0"
* extension[drs].extension[mime_type].valueString = "application/json"
* extension[drs].extension[checksums].extension[checksum].valueString = "abcdef0123456789"
* extension[drs].extension[checksums].extension[type].valueString = "etag"
* extension[drs].extension[access_methods].extension[type].valueString = "s3"
* extension[drs].extension[access_methods].extension[access_url].valueString = "s3://some-url-here"
* extension[drs].extension[access_methods].extension[region].valueString = "us-west"

Instance: AnvilResearchStudyExample
InstanceOf: AnvilResearchStudy
Description: "An example representation of an AnvilResearchStudy"
// these work
* id = "any-project-id"
* title = "my-project-title"
* status = #active
// this passes sushi, but produces the following error in IG `ext-1: Must have either extensions or value[x], not both [extension.exists() != value.exists()]`

* extension[attachments][0].id = "my-attachment-id"

// All of these attempts to access the sub-extension fail with `Cannot resolve element from path:`

// * extension[attachments][0].extension[drs-attachment].extension[id].valueString = "any-drs-id"
// * extension[attachments][0].extension[anvil-document-reference].extension[id].valueString = "any-drs-id"
// * extension[attachments][0].extension[DRSAttachment].extension[id].valueString = "any-drs-id"
// * extension[attachments][0].extension[drs].extension[id].valueString = "any-drs-id"
// * extension[attachments][0].extension[id].valueString = "any-drs-id"
// * extension[anvil-document-reference][0].extension[drs].id = "any-fhir-attachment-id"
// * extension[AnvilDocumentReference][0].extension[drs].id = "any-fhir-attachment-id"
// * extension[attachments][0].extension[drs].id = "any-fhir-attachment-id"
bwalsh commented 4 years ago

My workaround for now is:

* extension[attachments][0].valueReference = Reference(DRSAttachmentExample)
ngfreiter commented 4 years ago

The path:

* extension[attachments][0]

will get you to the AnvilDocumentReference extension. As far as I can tell, this extension does not have any sub-extensions:

Extension:      AnvilDocumentReference
Id:             anvil-document-reference
Title:          "AnVIL document reference"
Description:    "An association to a document."
* value[x] only DRSAttachment

It has a value[x] being set. So you would want a path to be something like:

* extension[attachments][0].value<DataType>

But I'm not sure I know what replaces <DataType> there. That depends on what DRSAttachment is. Is DRSAttachment a profile on Attachment? If that is the case I think the path you would want is:

* extension[attachments][0].valueAttachment
bwalsh commented 4 years ago

@ngfreiter Thanks for responding over the weekend!

The statement .value<DataType> was insightful. I didn't gather that from the docs. As I learn more perhaps I'll create a PR for the docs...

Anyway, still not quite there: A complete example.


Profile:        DRSAttachment
Parent:         Attachment
Id:             drs-attachment
Title:          "DRS Attachment"
Description:    "A FHIR Attachment extended with DRS Object attributes."
// simplification ... lets just make title mandatory
* title 1..1

Instance: DRSAttachmentExample
InstanceOf: DRSAttachment
Description: "An example representation of a DRSAttachment"
* title = "magna carta"

Extension:      AnvilAttachment
Id:             anvil-attachment
Title:          "AnVIL attachment instance"
Description:    "An association to an attachment."
* value[x] only DRSAttachment

Profile:        AnvilResearchStudy
Parent:         ResearchStudy
Id:             anvil-research-study
Title:          "AnVIL ResearchStudy"
Description:    "An AnVIL ResearchStudy."
* extension contains 
    AnvilAttachment named attachments 0..*

Instance: AnvilResearchStudyExample
InstanceOf: AnvilResearchStudy
Description: "An example representation of an AnvilResearchStudy"
* id = "any-project-id"
* title = "my-project-title"
* status = #active

// * extension[attachments][0].valueAttachment = DRSAttachmentExample
// Cannot fix Attachment value: DRSAttachmentExample. Value does not match element type: Attachment

// * extension[attachments][0].valueAnvilAttachment = DRSAttachmentExample
// Cannot resolve element from path: extension[attachments].valueAnvilAttachment

// * extension[attachments][0].valueDRSAttachment = DRSAttachmentExample
// Cannot resolve element from path: extension[attachments].valueDRSAttachment
ngfreiter commented 4 years ago

PRs are always welcome, and thanks for the detailed report!

It looks like you are now bumping up against a limitation of SUSHI. The first line:

* extension[attachments][0].valueAttachment = DRSAttachmentExample

is the line you would want to use, but if you use that line (with the latest version of SUSHI, 0.12.3), you should see an error that is a little more clear than the one you are getting, which says:

Instance DRSAttachmentExample of type Attachment is not an Instance of a Resource or Profile of a Resource. Only Instances of Resources or Profiles of Resources may be assigned to other Instances.

As the error states, SUSHI does not currently support setting Instances of non-Resources (such as Attachment) onto other Instances. We plan to remove this limitation at some point, but for now, you would have to set the values directly on the AnvilResearchStudyExample Instance as follows:

Instance: AnvilResearchStudyExample
InstanceOf: AnvilResearchStudy
Description: "An example representation of an AnvilResearchStudy"
* id = "any-project-id"
* title = "my-project-title"
* status = #active  
* extension[attachments][0].valueAttachment.title = "magna carta"

You should be able to set any field in Attachment using the approach shown on the last line, but replacing title with the name of the desired field.

ngfreiter commented 4 years ago

This was fixed by #464