Repository: FHIR/sushi
Pull request #728 (2021-01-14 13:30:47)

Support integer64
This addresses [CIMPL-622](https://standardhealthrecord.atlassian.net/browse/CIMPL-622) adds support for the [integer64 type](http://build.fhir.org/datatypes.html#integer64) introduced in R5. The only place I found that needed updating was assignment rules. Note that integer64 is treated differently from other numeric types, because we serialize it as a string in JSON, not as a number.

To test this, Extension works well. Here is an example I used to test out various different rules:
```
Extension: MyExtension
* value[x] only integer64
* valueInteger64 MS
* valueInteger64 1..1
* valueInteger64 = 1234567890
```

ngfreiter: @cmoesel your comments should be addressed https://github.com/FHIR/sushi/pull/728/commits/5176aba98c574681c7f3c65383cedd6ad8303230 and https://github.com/FHIR/sushi/pull/728/commits/223e1a8cab595ecaafcb6bbae9414865c40fb46b

Patch:
diff --git a/src/fhirtypes/ElementDefinition.ts b/src/fhirtypes/ElementDefinition.ts
index 3056816..d6af302 100644
--- a/src/fhirtypes/ElementDefinition.ts
+++ b/src/fhirtypes/ElementDefinition.ts
@@ -182,6 +182,8 @@ export class ElementDefinition {
   patternDecimal: number;
   fixedInteger: number;
   patternInteger: number;
+  fixedInteger64: string;
+  patternInteger64: string;
   fixedUnsignedInt: number;
   patternUnsignedInt: number;
   fixedPositiveInt: number;
@@ -1147,6 +1149,8 @@ export class ElementDefinition {
       type = 'Canonical';
     } else if (value instanceof InstanceDefinition) {
       type = 'InstanceDefinition';
+    } else if (typeof value === 'bigint') {
+      type = 'number';
     } else {
       type = typeof value;
     }
@@ -1425,15 +1429,20 @@ export class ElementDefinition {
    * @throws {ValueAlreadyAssignedError} when the value is already assigned to a different value
    * @throws {MismatchedTypeError} when the value does not match the type of the ElementDefinition
    */
-  private assignNumber(value: number, exactly = false): void {
+  private assignNumber(value: number | bigint, exactly = false): void {
     const type = this.type[0].code;
+    const valueAsNumber = Number(value);
     if (
       type === 'decimal' ||
-      (type === 'integer' && Number.isInteger(value)) ||
-      (type === 'unsignedInt' && Number.isInteger(value) && value >= 0) ||
-      (type === 'positiveInt' && Number.isInteger(value) && value > 0)
+      (type === 'integer' && Number.isInteger(valueAsNumber)) ||
+      (type === 'unsignedInt' && Number.isInteger(valueAsNumber) && valueAsNumber >= 0) ||
+      (type === 'positiveInt' && Number.isInteger(valueAsNumber) && valueAsNumber > 0)
     ) {
-      this.assignFHIRValue(value.toString(), value, exactly, type);
+      this.assignFHIRValue(value.toString(), valueAsNumber, exactly, type);
+    } else if (type === 'integer64' && typeof value === 'bigint') {
+      // integer64 is dealt with separately, since it is represented as a string in FHIR
+      // see: http://hl7.org/fhir/2020Sep/datatypes.html#integer64
+      this.assignFHIRValue(value.toString(), value.toString(), exactly, type);
     } else {
       throw new MismatchedTypeError('number', value, type);
     }
@@ -1474,7 +1483,8 @@ export class ElementDefinition {
       (type === 'oid' && /^urn:oid:[0-2](\.(0|[1-9][0-9]*))+$/.test(value)) ||
       (type === 'id' && /^[A-Za-z0-9\-\.]{1,64}$/.test(value)) ||
       (type === 'markdown' && /^\s*(\S|\s)*$/.test(value)) ||
-      type === 'uuid'
+      type === 'uuid' ||
+      (type === 'integer64' && /^[-]?\d+$/.test(value))
     ) {
       this.assignFHIRValue(`"${value}"`, value, exactly, type);
     } else if (type == 'xhtml' && this.checkXhtml(value)) {
diff --git a/src/fshtypes/rules/AssignmentRule.ts b/src/fshtypes/rules/AssignmentRule.ts
index 7fc2b1d..7561d5f 100644
--- a/src/fshtypes/rules/AssignmentRule.ts
+++ b/src/fshtypes/rules/AssignmentRule.ts
@@ -6,6 +6,7 @@ import { FshCanonical } from '../FshCanonical';
 export type AssignmentValueType =
   | boolean
   | number
+  | bigint
   | string
   | FshCanonical
   | FshCode
diff --git a/src/import/FSHImporter.ts b/src/import/FSHImporter.ts
index 8457d33..2e7308f 100644
--- a/src/import/FSHImporter.ts
+++ b/src/import/FSHImporter.ts
@@ -1162,7 +1162,10 @@ export class FSHImporter extends FSHVisitor {
     }
 
     if (ctx.NUMBER()) {
-      return parseFloat(ctx.NUMBER().getText());
+      const numberString = ctx.NUMBER().getText();
+      // If the number is an integer, store it as a bigint, a FHIR integer64 may be larger
+      // than an integer we can safely store as a number
+      return /^[-]?\d+$/.test(numberString) ? BigInt(numberString) : parseFloat(numberString);
     }
 
     if (ctx.DATETIME()) {


Test patch:
diff --git a/test/fhirtypes/ElementDefinition.assignNumber.test.ts b/test/fhirtypes/ElementDefinition.assignNumber.test.ts
index 8ed70dc..3ddae38 100644
--- a/test/fhirtypes/ElementDefinition.assignNumber.test.ts
+++ b/test/fhirtypes/ElementDefinition.assignNumber.test.ts
@@ -1,9 +1,11 @@
 import path from 'path';
+import fs from 'fs-extra';
 import { cloneDeep } from 'lodash';
 import { loadFromPath } from '../../src/fhirdefs/load';
 import { FHIRDefinitions } from '../../src/fhirdefs/FHIRDefinitions';
 import { StructureDefinition } from '../../src/fhirtypes/StructureDefinition';
 import { TestFisher } from '../testhelpers';
+import { ElementDefinition } from '../../src/fhirtypes';
 
 describe('ElementDefinition', () => {
   let defs: FHIRDefinitions;
@@ -51,7 +53,7 @@ describe('ElementDefinition', () => {
       const riskEstimateValue = riskEvidenceSynthesis.elements.find(
         e => e.id === 'RiskEvidenceSynthesis.riskEstimate.value'
       );
-      riskEstimateValue.assignValue(123);
+      riskEstimateValue.assignValue(BigInt(123));
       expect(riskEstimateValue.patternDecimal).toBe(123);
       expect(riskEstimateValue.fixedDecimal).toBeUndefined();
     });
@@ -60,7 +62,7 @@ describe('ElementDefinition', () => {
       const riskEstimateValue = riskEvidenceSynthesis.elements.find(
         e => e.id === 'RiskEvidenceSynthesis.riskEstimate.value'
       );
-      riskEstimateValue.assignValue(123, true);
+      riskEstimateValue.assignValue(BigInt(123), true);
       expect(riskEstimateValue.fixedDecimal).toBe(123);
       expect(riskEstimateValue.patternDecimal).toBeUndefined();
     });
@@ -156,7 +158,7 @@ describe('ElementDefinition', () => {
       const riskEstimateValueNumeratorCount = riskEvidenceSynthesis.elements.find(
         e => e.id === 'RiskEvidenceSynthesis.riskEstimate.numeratorCount'
       );
-      riskEstimateValueNumeratorCount.assignValue(123);
+      riskEstimateValueNumeratorCount.assignValue(BigInt(123));
       expect(riskEstimateValueNumeratorCount.patternInteger).toBe(123);
       expect(riskEstimateValueNumeratorCount.fixedInteger).toBeUndefined();
     });
@@ -165,7 +167,7 @@ describe('ElementDefinition', () => {
       const riskEstimateValueNumeratorCount = riskEvidenceSynthesis.elements.find(
         e => e.id === 'RiskEvidenceSynthesis.riskEstimate.numeratorCount'
       );
-      riskEstimateValueNumeratorCount.assignValue(123, true);
+      riskEstimateValueNumeratorCount.assignValue(BigInt(123), true);
       expect(riskEstimateValueNumeratorCount.fixedInteger).toBe(123);
       expect(riskEstimateValueNumeratorCount.patternInteger).toBeUndefined();
     });
@@ -174,15 +176,15 @@ describe('ElementDefinition', () => {
       const riskEstimateValueNumeratorCount = riskEvidenceSynthesis.elements.find(
         e => e.id === 'RiskEvidenceSynthesis.riskEstimate.numeratorCount'
       );
-      riskEstimateValueNumeratorCount.assignValue(123);
+      riskEstimateValueNumeratorCount.assignValue(BigInt(123));
       expect(riskEstimateValueNumeratorCount.patternInteger).toBe(123);
       expect(() => {
-        riskEstimateValueNumeratorCount.assignValue(124);
+        riskEstimateValueNumeratorCount.assignValue(BigInt(124));
       }).toThrow(
         'Cannot assign 124 to this element; a different integer is already assigned: 123.'
       );
       expect(() => {
-        riskEstimateValueNumeratorCount.assignValue(124, true);
+        riskEstimateValueNumeratorCount.assignValue(BigInt(124), true);
       }).toThrow(
         'Cannot assign 124 to this element; a different integer is already assigned: 123.'
       );
@@ -192,10 +194,10 @@ describe('ElementDefinition', () => {
       const riskEstimateValueNumeratorCount = riskEvidenceSynthesis.elements.find(
         e => e.id === 'RiskEvidenceSynthesis.riskEstimate.numeratorCount'
       );
-      riskEstimateValueNumeratorCount.assignValue(123, true);
+      riskEstimateValueNumeratorCount.assignValue(BigInt(123), true);
       expect(riskEstimateValueNumeratorCount.fixedInteger).toBe(123);
       expect(() => {
-        riskEstimateValueNumeratorCount.assignValue(124, true);
+        riskEstimateValueNumeratorCount.assignValue(BigInt(124), true);
       }).toThrow(
         'Cannot assign 124 to this element; a different integer is already assigned: 123.'
       );
@@ -205,10 +207,10 @@ describe('ElementDefinition', () => {
       const riskEstimateValueNumeratorCount = riskEvidenceSynthesis.elements.find(
         e => e.id === 'RiskEvidenceSynthesis.riskEstimate.numeratorCount'
       );
-      riskEstimateValueNumeratorCount.assignValue(123, true);
+      riskEstimateValueNumeratorCount.assignValue(BigInt(123), true);
       expect(riskEstimateValueNumeratorCount.fixedInteger).toBe(123);
       expect(() => {
-        riskEstimateValueNumeratorCount.assignValue(123);
+        riskEstimateValueNumeratorCount.assignValue(BigInt(123));
       }).toThrow(
         'Cannot assign this element using a pattern; as it is already assigned in the StructureDefinition using fixedInteger.'
       );
@@ -231,7 +233,7 @@ describe('ElementDefinition', () => {
       const reliableCache = capabilityStatement.elements.find(
         e => e.id === 'CapabilityStatement.messaging.reliableCache'
       );
-      reliableCache.assignValue(0);
+      reliableCache.assignValue(BigInt(0));
       expect(reliableCache.patternUnsignedInt).toBe(0);
       expect(reliableCache.fixedUnsignedInt).toBeUndefined();
     });
@@ -240,7 +242,7 @@ describe('ElementDefinition', () => {
       const reliableCache = capabilityStatement.elements.find(
         e => e.id === 'CapabilityStatement.messaging.reliableCache'
       );
-      reliableCache.assignValue(0, true);
+      reliableCache.assignValue(BigInt(0), true);
       expect(reliableCache.fixedUnsignedInt).toBe(0);
       expect(reliableCache.patternUnsignedInt).toBeUndefined();
     });
@@ -262,10 +264,10 @@ describe('ElementDefinition', () => {
         e => e.id === 'CapabilityStatement.messaging.reliableCache'
       );
       expect(() => {
-        reliableCache.assignValue(-24);
+        reliableCache.assignValue(BigInt(-24));
       }).toThrow('Cannot assign number value: -24. Value does not match element type: unsignedInt');
       expect(() => {
-        reliableCache.assignValue(-24, true);
+        reliableCache.assignValue(BigInt(-24), true);
       }).toThrow('Cannot assign number value: -24. Value does not match element type: unsignedInt');
     });
 
@@ -273,15 +275,15 @@ describe('ElementDefinition', () => {
       const reliableCache = capabilityStatement.elements.find(
         e => e.id === 'CapabilityStatement.messaging.reliableCache'
       );
-      reliableCache.assignValue(12);
+      reliableCache.assignValue(BigInt(12));
       expect(reliableCache.patternUnsignedInt).toBe(12);
       expect(() => {
-        reliableCache.assignValue(34);
+        reliableCache.assignValue(BigInt(34));
       }).toThrow(
         'Cannot assign 34 to this element; a different unsignedInt is already assigned: 12.'
       );
       expect(() => {
-        reliableCache.assignValue(34, true);
+        reliableCache.assignValue(BigInt(34), true);
       }).toThrow(
         'Cannot assign 34 to this element; a different unsignedInt is already assigned: 12.'
       );
@@ -291,10 +293,10 @@ describe('ElementDefinition', () => {
       const reliableCache = capabilityStatement.elements.find(
         e => e.id === 'CapabilityStatement.messaging.reliableCache'
       );
-      reliableCache.assignValue(12, true);
+      reliableCache.assignValue(BigInt(12), true);
       expect(reliableCache.fixedUnsignedInt).toBe(12);
       expect(() => {
-        reliableCache.assignValue(34, true);
+        reliableCache.assignValue(BigInt(34), true);
       }).toThrow(
         'Cannot assign 34 to this element; a different unsignedInt is already assigned: 12.'
       );
@@ -304,10 +306,10 @@ describe('ElementDefinition', () => {
       const reliableCache = capabilityStatement.elements.find(
         e => e.id === 'CapabilityStatement.messaging.reliableCache'
       );
-      reliableCache.assignValue(12, true);
+      reliableCache.assignValue(BigInt(12), true);
       expect(reliableCache.fixedUnsignedInt).toBe(12);
       expect(() => {
-        reliableCache.assignValue(34, true);
+        reliableCache.assignValue(BigInt(34), true);
       }).toThrow(
         'Cannot assign 34 to this element; a different unsignedInt is already assigned: 12.'
       );
@@ -317,10 +319,10 @@ describe('ElementDefinition', () => {
       const reliableCache = capabilityStatement.elements.find(
         e => e.id === 'CapabilityStatement.messaging.reliableCache'
       );
-      reliableCache.assignValue(12, true);
+      reliableCache.assignValue(BigInt(12), true);
       expect(reliableCache.fixedUnsignedInt).toBe(12);
       expect(() => {
-        reliableCache.assignValue(12);
+        reliableCache.assignValue(BigInt(12));
       }).toThrow(
         'Cannot assign this element using a pattern; as it is already assigned in the StructureDefinition using fixedUnsignedInt.'
       );
@@ -331,7 +333,7 @@ describe('ElementDefinition', () => {
       const minutesDuration = appointment.elements.find(
         e => e.id === 'Appointment.minutesDuration'
       );
-      minutesDuration.assignValue(12);
+      minutesDuration.assignValue(BigInt(12));
       expect(minutesDuration.patternPositiveInt).toBe(12);
       expect(minutesDuration.fixedPositiveInt).toBeUndefined();
     });
@@ -340,7 +342,7 @@ describe('ElementDefinition', () => {
       const minutesDuration = appointment.elements.find(
         e => e.id === 'Appointment.minutesDuration'
       );
-      minutesDuration.assignValue(12, true);
+      minutesDuration.assignValue(BigInt(12), true);
       expect(minutesDuration.fixedPositiveInt).toBe(12);
       expect(minutesDuration.patternPositiveInt).toBeUndefined();
     });
@@ -362,10 +364,10 @@ describe('ElementDefinition', () => {
         e => e.id === 'Appointment.minutesDuration'
       );
       expect(() => {
-        minutesDuration.assignValue(0);
+        minutesDuration.assignValue(BigInt(0));
       }).toThrow('Cannot assign number value: 0. Value does not match element type: positiveInt');
       expect(() => {
-        minutesDuration.assignValue(0, true);
+        minutesDuration.assignValue(BigInt(0), true);
       }).toThrow('Cannot assign number value: 0. Value does not match element type: positiveInt');
     });
 
@@ -374,10 +376,10 @@ describe('ElementDefinition', () => {
         e => e.id === 'Appointment.minutesDuration'
       );
       expect(() => {
-        minutesDuration.assignValue(-12);
+        minutesDuration.assignValue(BigInt(-12));
       }).toThrow('Cannot assign number value: -12. Value does not match element type: positiveInt');
       expect(() => {
-        minutesDuration.assignValue(-12, true);
+        minutesDuration.assignValue(BigInt(-12), true);
       }).toThrow('Cannot assign number value: -12. Value does not match element type: positiveInt');
     });
 
@@ -385,15 +387,15 @@ describe('ElementDefinition', () => {
       const minutesDuration = appointment.elements.find(
         e => e.id === 'Appointment.minutesDuration'
       );
-      minutesDuration.assignValue(12);
+      minutesDuration.assignValue(BigInt(12));
       expect(minutesDuration.patternPositiveInt).toEqual(12);
       expect(() => {
-        minutesDuration.assignValue(34);
+        minutesDuration.assignValue(BigInt(34));
       }).toThrow(
         'Cannot assign 34 to this element; a different positiveInt is already assigned: 12.'
       );
       expect(() => {
-        minutesDuration.assignValue(34, true);
+        minutesDuration.assignValue(BigInt(34), true);
       }).toThrow(
         'Cannot assign 34 to this element; a different positiveInt is already assigned: 12.'
       );
@@ -403,10 +405,10 @@ describe('ElementDefinition', () => {
       const minutesDuration = appointment.elements.find(
         e => e.id === 'Appointment.minutesDuration'
       );
-      minutesDuration.assignValue(12, true);
+      minutesDuration.assignValue(BigInt(12), true);
       expect(minutesDuration.fixedPositiveInt).toEqual(12);
       expect(() => {
-        minutesDuration.assignValue(34, true);
+        minutesDuration.assignValue(BigInt(34), true);
       }).toThrow(
         'Cannot assign 34 to this element; a different positiveInt is already assigned: 12.'
       );
@@ -416,10 +418,10 @@ describe('ElementDefinition', () => {
       const minutesDuration = appointment.elements.find(
         e => e.id === 'Appointment.minutesDuration'
       );
-      minutesDuration.assignValue(12, true);
+      minutesDuration.assignValue(BigInt(12), true);
       expect(minutesDuration.fixedPositiveInt).toEqual(12);
       expect(() => {
-        minutesDuration.assignValue(12);
+        minutesDuration.assignValue(BigInt(12));
       }).toThrow(
         'Cannot assign this element using a pattern; as it is already assigned in the StructureDefinition using fixedPositiveInt.'
       );
@@ -429,22 +431,22 @@ describe('ElementDefinition', () => {
     it('should throw MismatchedTypeError when assigning an integer to a non-numerical value', () => {
       const status = observation.elements.find(e => e.id === 'Observation.status');
       expect(() => {
-        status.assignValue(123);
+        status.assignValue(BigInt(123));
       }).toThrow('Cannot assign number value: 123. Value does not match element type: code');
       expect(() => {
-        status.assignValue(123, true);
+        status.assignValue(BigInt(123), true);
       }).toThrow('Cannot assign number value: 123. Value does not match element type: code');
     });
 
     it('should throw NoSingleTypeError when element has multiple types', () => {
       const valueX = observation.elements.find(e => e.id === 'Observation.value[x]');
       expect(() => {
-        valueX.assignValue(123);
+        valueX.assignValue(BigInt(123));
       }).toThrow(
         'Cannot assign number value on this element since this element does not have a single type'
       );
       expect(() => {
-        valueX.assignValue(123, true);
+        valueX.assignValue(BigInt(123), true);
       }).toThrow(
         'Cannot assign number value on this element since this element does not have a single type'
       );
@@ -452,4 +454,96 @@ describe('ElementDefinition', () => {
       expect(valueX.fixedInteger).toBeUndefined();
     });
   });
+
+  describe('#integer64', () => {
+    let valueX: ElementDefinition;
+    let valueInteger64: ElementDefinition;
+    beforeAll(() => {
+      const r5Extension = StructureDefinition.fromJSON(
+        JSON.parse(
+          fs.readFileSync(
+            path.join(
+              __dirname,
+              '..',
+              'testhelpers',
+              'testdefs',
+              'r5-definitions',
+              'StructureDefinition-Extension.json'
+            ),
+            'utf-8'
+          )
+        )
+      );
+      valueX = r5Extension.elements.find(e => e.id === 'Extension.value[x]');
+    });
+
+    beforeEach(() => {
+      valueInteger64 = cloneDeep(valueX);
+      valueInteger64.type = valueInteger64.type.filter(t => t.code === 'integer64');
+    });
+
+    // assigning an integer64
+    // NOTE: Tests of assigning an integer64 as a string are in ElementDefinition.assignString.test.ts
+    it('should assign an integer to an integer64', () => {
+      valueInteger64.assignValue(BigInt(123));
+      expect(valueInteger64.patternInteger64).toBe('123');
+      expect(valueInteger64.fixedInteger64).toBeUndefined();
+    });
+
+    it('should assign an integer to an integer64 (exactly)', () => {
+      valueInteger64.assignValue(BigInt(123), true);
+      expect(valueInteger64.patternInteger64).toBeUndefined();
+      expect(valueInteger64.fixedInteger64).toBe('123');
+    });
+
+    it('should assign a large integer to an integer64 without losing precision', () => {
+      valueInteger64.assignValue(BigInt('12345678901234567890'));
+      expect(valueInteger64.patternInteger64).toBe('12345678901234567890');
+      expect(valueInteger64.fixedInteger64).toBeUndefined();
+    });
+
+    it('should throw ValueAlreadyAssignedError when assigning an already assigned integer by pattern[x]', () => {
+      valueInteger64.assignValue(BigInt(123));
+      expect(valueInteger64.patternInteger64).toBe('123');
+      expect(() => {
+        valueInteger64.assignValue(BigInt(124));
+      }).toThrow(
+        'Cannot assign 124 to this element; a different integer64 is already assigned: "123".'
+      );
+      expect(() => {
+        valueInteger64.assignValue(BigInt(124), true);
+      }).toThrow(
+        'Cannot assign 124 to this element; a different integer64 is already assigned: "123".'
+      );
+    });
+
+    it('should throw ValueAlreadyAssignedError when assigning an already assigned integer by fixed[x]', () => {
+      valueInteger64.assignValue(BigInt(123), true);
+      expect(valueInteger64.fixedInteger64).toBe('123');
+      expect(() => {
+        valueInteger64.assignValue(BigInt(124), true);
+      }).toThrow(
+        'Cannot assign 124 to this element; a different integer64 is already assigned: "123".'
+      );
+    });
+
+    it('should throw FixedToPatternError when trying to change fixed[x] to pattern[x]', () => {
+      valueInteger64.assignValue(BigInt(123), true);
+      expect(valueInteger64.fixedInteger64).toBe('123');
+      expect(() => {
+        valueInteger64.assignValue(BigInt(123));
+      }).toThrow(
+        'Cannot assign this element using a pattern; as it is already assigned in the StructureDefinition using fixedInteger64.'
+      );
+    });
+
+    it('should throw MismatchedTypeError when assigning a decimal to an integer64 value', () => {
+      expect(() => {
+        valueInteger64.assignValue(12.3);
+      }).toThrow('Cannot assign number value: 12.3. Value does not match element type: integer64');
+      expect(() => {
+        valueInteger64.assignValue(12.3, true);
+      }).toThrow('Cannot assign number value: 12.3. Value does not match element type: integer64');
+    });
+  });
 });
diff --git a/test/fhirtypes/ElementDefinition.assignString.test.ts b/test/fhirtypes/ElementDefinition.assignString.test.ts
index 9df7cfe..109327d 100644
--- a/test/fhirtypes/ElementDefinition.assignString.test.ts
+++ b/test/fhirtypes/ElementDefinition.assignString.test.ts
@@ -1,8 +1,9 @@
 import path from 'path';
+import fs from 'fs-extra';
 import { cloneDeep } from 'lodash';
 import { loadFromPath } from '../../src/fhirdefs/load';
 import { FHIRDefinitions } from '../../src/fhirdefs/FHIRDefinitions';
-import { StructureDefinition } from '../../src/fhirtypes/StructureDefinition';
+import { StructureDefinition, ElementDefinition } from '../../src/fhirtypes';
 import { TestFisher } from '../testhelpers';
 
 describe('ElementDefinition', () => {
@@ -1091,5 +1092,65 @@ describe('ElementDefinition', () => {
       expect(valueX.patternString).toBeUndefined();
       expect(valueX.fixedString).toBeUndefined();
     });
+    describe('#integer64', () => {
+      let valueX: ElementDefinition;
+      let valueInteger64: ElementDefinition;
+      beforeAll(() => {
+        const r5Extension = StructureDefinition.fromJSON(
+          JSON.parse(
+            fs.readFileSync(
+              path.join(
+                __dirname,
+                '..',
+                'testhelpers',
+                'testdefs',
+                'r5-definitions',
+                'StructureDefinition-Extension.json'
+              ),
+              'utf-8'
+            )
+          )
+        );
+        valueX = r5Extension.elements.find(e => e.id === 'Extension.value[x]');
+      });
+
+      beforeEach(() => {
+        valueInteger64 = cloneDeep(valueX);
+        valueInteger64.type = valueInteger64.type.filter(t => t.code === 'integer64');
+      });
+
+      // assigning an integer64
+      // NOTE: Tests of assigning an integer64 as a number are in ElementDefinition.assignNumber.test.ts
+      it('should assign an integer string to an integer64', () => {
+        valueInteger64.assignValue('123');
+        expect(valueInteger64.patternInteger64).toBe('123');
+        expect(valueInteger64.fixedInteger64).toBeUndefined();
+      });
+
+      it('should assign an integer string to an integer64 (exactly)', () => {
+        valueInteger64.assignValue('123', true);
+        expect(valueInteger64.patternInteger64).toBeUndefined();
+        expect(valueInteger64.fixedInteger64).toBe('123');
+      });
+
+      it('should throw MismatchedTypeError when assigning a decimal string to an integer64 value', () => {
+        expect(() => {
+          valueInteger64.assignValue('12.3');
+        }).toThrow(
+          'Cannot assign string value: 12.3. Value does not match element type: integer64'
+        );
+        expect(() => {
+          valueInteger64.assignValue('12.3', true);
+        }).toThrow(
+          'Cannot assign string value: 12.3. Value does not match element type: integer64'
+        );
+      });
+
+      it('should throw MismatchedTypeError when assigning a string to an integer64 value', () => {
+        expect(() => {
+          valueInteger64.assignValue('foo');
+        }).toThrow('Cannot assign string value: foo. Value does not match element type: integer64');
+      });
+    });
   });
 });
diff --git a/test/testhelpers/testdefs/r5-definitions/StructureDefinition-Extension.json b/test/testhelpers/testdefs/r5-definitions/StructureDefinition-Extension.json
new file mode 100644
index 0000000..d471d68
--- /dev/null
+++ b/test/testhelpers/testdefs/r5-definitions/StructureDefinition-Extension.json
@@ -0,0 +1,1 @@
+{"resourceType":"StructureDefinition","id":"Extension","meta":{"lastUpdated":"2020-08-20T17:41:31.970+10:00"},"text":{"status":"generated","div":"<div xmlns=\"http://www.w3.org/1999/xhtml\">\n            <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" style=\"border: 0px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top;\">\n              <tr style=\"border: 1px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top\">\n                <th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">\n                  <a href=\"formats.html#table\" title=\"The logical name of the element\">Name</a>\n                </th>\n                <th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">\n                  <a href=\"formats.html#table\" title=\"Information about the use of the element\">Flags</a>\n                </th>\n                <th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">\n                  <a href=\"formats.html#table\" title=\"Minimum and Maximum # of times the the element can appear in the instance\">Card.</a>\n                </th>\n                <th style=\"width: 100px\" class=\"hierarchy\">\n                  <a href=\"formats.html#table\" title=\"Reference to the type of the element\">Type</a>\n                </th>\n                <th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">\n                  <a href=\"formats.html#table\" title=\"Additional information about the element\">Description &amp; Constraints</a>\n                  <span style=\"float: right\">\n                    <a href=\"formats.html#table\" title=\"Legend for this format\">\n                      <img src=\"help16.png\" alt=\"doco\" style=\"background-color: inherit\"/>\n                    </a>\n                  </span>\n                </th>\n              </tr>\n              <tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: white\">\n                <td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAACCAYAAACg/LjIAAAAI0lEQVR42u3QIQEAAAACIL/6/4MvTAQOkLYBAAB4kAAAANwMad9AqkRjgNAAAAAASUVORK5CYII=)\" class=\"hierarchy\">\n                  <img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAWCAYAAAABxvaqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wYeFzIs1vtcMQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAE0lEQVQI12P4//8/AxMDAwNdCABMPwMo2ctnoQAAAABJRU5ErkJggg==\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/>\n                  <img src=\"data:image/png;base64,R0lGODlhEAAQAPQfAOvGUf7ztuvPMf/78/fkl/Pbg+u8Rvjqteu2Pf3zxPz36Pz0z+vTmPzurPvuw/npofbjquvNefHVduuyN+uuMu3Oafbgjfnqvf/3zv/3xevPi+vRjP/20/bmsP///wD/ACH5BAEKAB8ALAAAAAAQABAAAAVl4CeOZGme5qCqqDg8jyVJaz1876DsmAQAgqDgltspMEhMJoMZ4iy6I1AooFCIv+wKybziALVAoAEjYLwDgGIpJhMslgxaLR4/3rMAWoBp32V5exg8Shl1ckRUQVaMVkQ2kCstKCEAOw==\" alt=\".\" style=\"background-color: white; background-color: inherit\" title=\"Element\" class=\"hierarchy\"/> \n                  <a href=\"extensibility-definitions.html#Extension\" title=\"Extension : Optional Extension Element - found in all resources.\">Extension</a>\n                </td>\n                <td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">\n                  <a style=\"padding-left: 3px; padding-right: 3px; border: 1px grey solid; font-weight: bold; color: black; background-color: #e6ffe6\" href=\"versions.html#std-process\" title=\"Standards Status = Normative\">N</a>\n                </td>\n                <td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/>\n                <td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">\n                  <a href=\"types.html#Element\">Element</a>\n                </td>\n                <td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">Optional Extensions Element\n                  <br/>\n                  <span style=\"font-style: italic\" title=\"ext-1\">+ Rule: Must have either extensions or value[x], not both</span>\n                  <br/>Elements defined in Ancestors: \n                  <a href=\"types.html#Element\" title=\"Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.\">id</a>, \n                  <a href=\"types.html#Element\" title=\"May be used to represent additional information that is not part of the basic definition of the element. To make the use of extensions safe and manageable, there is a strict set of governance  applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.\">extension</a>\n                </td>\n              </tr>\n\n              <tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: #F7F7F7\">\n                <td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAACCAYAAACg/LjIAAAAL0lEQVR42u3XsQ0AQAgCQHdl/xn8jxvYWB3JlTR0VJLa+OltBwAAYP6EEQAAgCsPVYVAgIJrA/sAAAAASUVORK5CYII=)\" class=\"hierarchy\">\n                  <img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAWCAYAAAABxvaqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wYeFzIs1vtcMQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAE0lEQVQI12P4//8/AxMDAwNdCABMPwMo2ctnoQAAAABJRU5ErkJggg==\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/>\n                  <img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAWCAYAAADJqhx8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wYeFzI3XJ6V3QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAANklEQVQ4y+2RsQ0AIAzDav7/2VzQwoCY4iWbZSmo1QGoUgNMghvWaIejPQW/CrrNCylIwcOCDYfLNRcNer4SAAAAAElFTkSuQmCC\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/>\n                  <img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAARklEQVQ4y2P8//8/AyWAhYFCMAgMuHjx4n+KXaCv+I0szW8WpCG8kFO1lGFKW/SIjAUYgxz/MzAwMDC+nqhDUTQyjuYFBgCNmhP4OvTRgwAAAABJRU5ErkJggg==\" alt=\".\" style=\"background-color: #F7F7F7; background-color: inherit\" title=\"Primitive Data Type\" class=\"hierarchy\"/> \n                  <a href=\"extensibility-definitions.html#Extension.url\" title=\"Extension.url : Source of the definition for the extension code - a logical name or a URL.\">url</a>\n                </td>\n                <td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/>\n                <td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">1..1</td>\n                <td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">\n                  <a href=\"datatypes.html#uri\">uri</a>\n                </td>\n                <td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">identifies the meaning of the extension</td>\n              </tr>\n\n              <tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: white\">\n                <td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAACCAYAAACg/LjIAAAAI0lEQVR42u3QIQEAAAACIL/6/4MvTAQOkLYBAAB4kAAAANwMad9AqkRjgNAAAAAASUVORK5CYII=)\" class=\"hierarchy\">\n                  <img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAWCAYAAAABxvaqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wYeFzIs1vtcMQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAE0lEQVQI12P4//8/AxMDAwNdCABMPwMo2ctnoQAAAABJRU5ErkJggg==\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/>\n                  <img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAWCAYAAADJqhx8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wYeFzME+lXFigAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAANklEQVQ4y+3OsRUAIAjEUOL+O8cJABttJM11/x1qZAGqRBEVcNIqdWj1efDqQbb3HwwwwEfABmQUHSPM9dtDAAAAAElFTkSuQmCC\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/>\n                  <img src=\"data:image/png;base64,R0lGODlhEAAQAPZ/APrkusOiYvvfqbiXWaV2G+jGhdq1b8GgYf3v1frw3vTUlsWkZNewbcSjY/DQkad4Hb6dXv3u0f3v1ObEgfPTlerJiP3w1v79+e7OkPrfrfnjuNOtZPrpydaxa+/YrvvdpP779ZxvFPvnwKKBQaFyF/369M2vdaqHRPz58/HNh/vowufFhfroxO3OkPrluv779tK0e6JzGProwvrow9m4eOnIifPTlPDPkP78+Naxaf3v0/zowfXRi+bFhLWUVv379/rnwPvszv3rye3LiPvnv+3MjPDasKiIS/789/3x2f747eXDg+7Mifvu0tu7f+/QkfDTnPXWmPrjsvrjtPbPgrqZW+/QlPz48K2EMv36866OUPvowat8Ivvgq/Pbrvzgq/PguvrgrqN0Gda2evfYm9+7d/rpw9q6e/LSku/Rl/XVl/LSlfrkt+zVqe7Wqv3x1/bNffbOf59wFdS6if3u0vrqyP3owPvepfXQivDQkO/PkKh9K7STVf779P///wD/ACH5BAEKAH8ALAAAAAAQABAAAAemgH+CgxeFF4OIhBdKGwFChYl/hYwbdkoBPnaQkosbG3d3VEpSUlonUoY1Gzo6QkI8SrGxWBOFG4uySgY5ZWR3PFy2hnaWZXC/PHcPwkpJk1ShoHcxhQEXSUmtFy6+0iSFVResrjoTPDzdcoU+F65CduVU6KAhhQa3F8Tx8nchBoYuqoTLZoAKFRIhqGwqJAULFx0GYpBQeChRIR4TJm6KJMhQRUSBAAA7\" alt=\".\" style=\"background-color: white; background-color: inherit\" title=\"Data Type\" class=\"hierarchy\"/> \n                  <a href=\"extensibility-definitions.html#Extension.value_x_\" title=\"Extension.value[x] : Value of extension - must be one of a constrained set of the data types (see [Extensibility](extensibility.html) for a list).\">value[x]</a>\n                </td>\n                <td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/>\n                <td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">0..1</td>\n                <td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">\n                  <a href=\"datatypes.html#open\">*</a>\n                </td>\n                <td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">Value of extension</td>\n              </tr>\n\n              <tr>\n                <td colspan=\"5\" class=\"hierarchy\">\n                  <br/>\n                  <a href=\"formats.html#table\" title=\"Legend for this format\">\n                    <img src=\"help16.png\" alt=\"doco\" style=\"background-color: inherit\"/> Documentation for this format\n                  </a>\n                </td>\n              </tr>\n            </table>\n          </div>"},"extension":[{"url":"http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status","valueCode":"normative"},{"url":"http://hl7.org/fhir/StructureDefinition/structuredefinition-normative-version","valueCode":"4.0.0"}],"url":"http://hl7.org/fhir/StructureDefinition/Extension","version":"4.5.0","name":"Extension","status":"active","date":"2020-08-20T17:41:31+10:00","publisher":"HL7 FHIR Standard","contact":[{"telecom":[{"system":"url","value":"http://hl7.org/fhir"}]}],"description":"Base StructureDefinition for Extension Type: Optional Extension Element - found in all resources.","purpose":"The ability to add extensions in a structured way is what keeps FHIR resources simple.","fhirVersion":"4.5.0","mapping":[{"identity":"rim","uri":"http://hl7.org/v3","name":"RIM Mapping"}],"kind":"complex-type","abstract":false,"type":"Extension","baseDefinition":"http://hl7.org/fhir/StructureDefinition/DataType","derivation":"specialization","snapshot":{"element":[{"id":"Extension","extension":[{"url":"http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status","valueCode":"normative"},{"url":"http://hl7.org/fhir/StructureDefinition/structuredefinition-normative-version","valueCode":"4.0.0"}],"path":"Extension","short":"Optional Extensions Element","definition":"Optional Extension Element - found in all resources.","min":0,"max":"*","base":{"path":"Extension","min":0,"max":"*"},"constraint":[{"key":"ele-1","severity":"error","human":"All FHIR elements must have a @value or children","expression":"hasValue() or (children().count() > id.count())","xpath":"@value|f:*|h:div","source":"http://hl7.org/fhir/StructureDefinition/Element"},{"key":"ext-1","severity":"error","human":"Must have either extensions or value[x], not both","expression":"extension.exists() != value.exists()","xpath":"exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])","source":"http://hl7.org/fhir/StructureDefinition/Extension"}],"isModifier":false,"mapping":[{"identity":"rim","map":"n/a"},{"identity":"rim","map":"N/A"}]},{"id":"Extension.id","path":"Extension.id","representation":["xmlAttr"],"short":"Unique id for inter-element referencing","definition":"Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.","min":0,"max":"1","base":{"path":"Element.id","min":0,"max":"1"},"type":[{"extension":[{"url":"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type","valueUri":"string"}],"code":"http://hl7.org/fhirpath/System.String"}],"isModifier":false,"isSummary":false,"mapping":[{"identity":"rim","map":"n/a"}]},{"id":"Extension.extension","path":"Extension.extension","slicing":{"discriminator":[{"type":"value","path":"url"}],"description":"Extensions are always sliced by (at least) url","rules":"open"},"short":"Additional content defined by implementations","definition":"May be used to represent additional information that is not part of the basic definition of the element. To make the use of extensions safe and manageable, there is a strict set of governance  applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.","comment":"There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions.  The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone.","alias":["extensions","user content"],"min":0,"max":"*","base":{"path":"Element.extension","min":0,"max":"*"},"type":[{"code":"Extension"}],"constraint":[{"key":"ele-1","severity":"error","human":"All FHIR elements must have a @value or children","expression":"hasValue() or (children().count() > id.count())","xpath":"@value|f:*|h:div","source":"http://hl7.org/fhir/StructureDefinition/Element"},{"key":"ext-1","severity":"error","human":"Must have either extensions or value[x], not both","expression":"extension.exists() != value.exists()","xpath":"exists(f:extension)!=exists(f:*[starts-with(local-name(.), \"value\")])","source":"http://hl7.org/fhir/StructureDefinition/Extension"}],"isModifier":false,"isSummary":false,"mapping":[{"identity":"rim","map":"n/a"}]},{"id":"Extension.url","path":"Extension.url","representation":["xmlAttr"],"short":"identifies the meaning of the extension","definition":"Source of the definition for the extension code - a logical name or a URL.","comment":"The definition may point directly to a computable or human-readable definition of the extensibility codes, or it may be a logical URI as declared in some other specification. The definition SHALL be a URI for the Structure Definition defining the extension.","min":1,"max":"1","base":{"path":"Extension.url","min":1,"max":"1"},"type":[{"extension":[{"url":"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type","valueUri":"uri"}],"code":"http://hl7.org/fhirpath/System.String"}],"isModifier":false,"isSummary":false,"mapping":[{"identity":"rim","map":"N/A"}]},{"id":"Extension.value[x]","path":"Extension.value[x]","short":"Value of extension","definition":"Value of extension - must be one of a constrained set of the data types (see [Extensibility](extensibility.html) for a list).","min":0,"max":"1","base":{"path":"Extension.value[x]","min":0,"max":"1"},"type":[{"code":"base64Binary"},{"code":"boolean"},{"code":"canonical"},{"code":"code"},{"code":"date"},{"code":"dateTime"},{"code":"decimal"},{"code":"id"},{"code":"instant"},{"code":"integer"},{"code":"integer64"},{"code":"markdown"},{"code":"oid"},{"code":"positiveInt"},{"code":"string"},{"code":"time"},{"code":"unsignedInt"},{"code":"uri"},{"code":"url"},{"code":"uuid"},{"code":"Address"},{"code":"Age"},{"code":"Annotation"},{"code":"Attachment"},{"code":"CodeableConcept"},{"code":"Coding"},{"code":"ContactPoint"},{"code":"Count"},{"code":"Distance"},{"code":"Duration"},{"code":"HumanName"},{"code":"Identifier"},{"code":"Money"},{"code":"Period"},{"code":"Quantity"},{"code":"Range"},{"code":"Ratio"},{"code":"Reference"},{"code":"SampledData"},{"code":"Signature"},{"code":"Timing"},{"code":"ContactDetail"},{"code":"Contributor"},{"code":"DataRequirement"},{"code":"Expression"},{"code":"ParameterDefinition"},{"code":"RelatedArtifact"},{"code":"TriggerDefinition"},{"code":"UsageContext"},{"code":"Dosage"},{"code":"Meta"}],"constraint":[{"key":"ele-1","severity":"error","human":"All FHIR elements must have a @value or children","expression":"hasValue() or (children().count() > id.count())","xpath":"@value|f:*|h:div","source":"http://hl7.org/fhir/StructureDefinition/Element"}],"isModifier":false,"isSummary":false,"mapping":[{"identity":"rim","map":"N/A"}]}]},"differential":{"element":[{"id":"Extension","extension":[{"url":"http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status","valueCode":"normative"},{"url":"http://hl7.org/fhir/StructureDefinition/structuredefinition-normative-version","valueCode":"4.0.0"}],"path":"Extension","short":"Optional Extensions Element","definition":"Optional Extension Element - found in all resources.","min":0,"max":"*","constraint":[{"key":"ext-1","severity":"error","human":"Must have either extensions or value[x], not both","expression":"extension.exists() != value.exists()","xpath":"exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])","source":"http://hl7.org/fhir/StructureDefinition/Extension"}],"mapping":[{"identity":"rim","map":"N/A"}]},{"id":"Extension.url","path":"Extension.url","representation":["xmlAttr"],"short":"identifies the meaning of the extension","definition":"Source of the definition for the extension code - a logical name or a URL.","comment":"The definition may point directly to a computable or human-readable definition of the extensibility codes, or it may be a logical URI as declared in some other specification. The definition SHALL be a URI for the Structure Definition defining the extension.","min":1,"max":"1","type":[{"extension":[{"url":"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type","valueUri":"uri"}],"code":"http://hl7.org/fhirpath/System.String"}],"mapping":[{"identity":"rim","map":"N/A"}]},{"id":"Extension.value[x]","path":"Extension.value[x]","short":"Value of extension","definition":"Value of extension - must be one of a constrained set of the data types (see [Extensibility](extensibility.html) for a list).","min":0,"max":"1","type":[{"code":"base64Binary"},{"code":"boolean"},{"code":"canonical"},{"code":"code"},{"code":"date"},{"code":"dateTime"},{"code":"decimal"},{"code":"id"},{"code":"instant"},{"code":"integer"},{"code":"integer64"},{"code":"markdown"},{"code":"oid"},{"code":"positiveInt"},{"code":"string"},{"code":"time"},{"code":"unsignedInt"},{"code":"uri"},{"code":"url"},{"code":"uuid"},{"code":"Address"},{"code":"Age"},{"code":"Annotation"},{"code":"Attachment"},{"code":"CodeableConcept"},{"code":"Coding"},{"code":"ContactPoint"},{"code":"Count"},{"code":"Distance"},{"code":"Duration"},{"code":"HumanName"},{"code":"Identifier"},{"code":"Money"},{"code":"Period"},{"code":"Quantity"},{"code":"Range"},{"code":"Ratio"},{"code":"Reference"},{"code":"SampledData"},{"code":"Signature"},{"code":"Timing"},{"code":"ContactDetail"},{"code":"Contributor"},{"code":"DataRequirement"},{"code":"Expression"},{"code":"ParameterDefinition"},{"code":"RelatedArtifact"},{"code":"TriggerDefinition"},{"code":"UsageContext"},{"code":"Dosage"},{"code":"Meta"}],"mapping":[{"identity":"rim","map":"N/A"}]}]}}
\ No newline at end of file