private ClassMapping createMapping(Type type, FhirRelease version)
 {
     if (!ClassMapping.TryCreate(type, out var mapping, version))
     {
         Message.Info("Skipped type {0} while doing inspection: not recognized as representing a FHIR type", type.Name);
         return(null);
     }
        /// <summary>
        /// Enumerate this class' properties using reflection, create PropertyMappings
        /// for them and add them to the PropertyMappings.
        /// </summary>
        private static PropertyMappingCollection inspectProperties(Type nativeType, FhirRelease fhirVersion)
        {
            var byName = new Dictionary <string, PropertyMapping>();

            foreach (var property in ReflectionHelper.FindPublicProperties(nativeType))
            {
                if (!PropertyMapping.TryCreate(property, out var propMapping, fhirVersion))
                {
                    continue;
                }

                var propKey = propMapping.Name.ToUpperInvariant();

                if (byName.ContainsKey(propKey))
                {
                    throw Error.InvalidOperation($"Class has multiple properties that are named '{propKey}'. The property name must be unique");
                }

                byName.Add(propKey, propMapping);
            }

            var ordered = byName.Values.OrderBy(pm => pm.Order).ToList();

            return(new PropertyMappingCollection(byName, ordered));
        }
        public static bool TryCreate(Type type, out ClassMapping result, FhirRelease fhirVersion = (FhirRelease)int.MaxValue)
        {
            result = null;

            var typeAttribute = GetAttribute <FhirTypeAttribute>(type.GetTypeInfo(), fhirVersion);

            if (typeAttribute == null)
            {
                return(false);
            }

            if (ReflectionHelper.IsOpenGenericTypeDefinition(type))
            {
                Message.Info("Type {0} is marked as a FhirType and is an open generic type, which cannot be used directly to represent a FHIR datatype", type.Name);
                return(false);
            }

            result = new ClassMapping
            {
                Name       = collectTypeName(typeAttribute, type),
                IsResource = typeAttribute.IsResource || type.CanBeTreatedAsType(typeof(Resource)),
                IsCodeOfT  = ReflectionHelper.IsClosedGenericType(type) &&
                             ReflectionHelper.IsConstructedFromGenericTypeDefinition(type, typeof(Code <>)),
                NativeType          = type,
                IsNestedType        = typeAttribute.IsNestedType,
                _mappingInitializer = () => inspectProperties(type, fhirVersion)
            };

            return(true);
        }
 /// <summary>
 /// Returns the version number of the latest official FHIR releases
 /// </summary>
 /// <param name="fhirRelease">Official FHIR release</param>
 /// <returns>Latest version number</returns>
 public static string FhirVersionFromRelease(FhirRelease fhirRelease)
 {
     return(fhirRelease switch
     {
         FhirRelease.DSTU1 => "0.0.82",
         FhirRelease.DSTU2 => "1.0.2",
         FhirRelease.STU3 => "3.0.2",
         FhirRelease.R4 => "4.0.1",
         FhirRelease.R5 => "4.5.0",
         _ => throw new NotSupportedException($"Unknown FHIR version {fhirRelease}")
     });
 private PropertyMapping(
     string name,
     PropertyInfo pi,
     Type implementingType,
     Type[] fhirTypes,
     FhirRelease version)
 {
     Name             = name;
     _propInfo        = pi;
     _createdVersion  = version;
     ImplementingType = implementingType;
     FhirType         = fhirTypes;
 }
 public ModelInspector(FhirRelease fhirVersion)
 {
     _fhirVersion = fhirVersion;
 }
        internal static T GetAttribute <T>(MemberInfo t, FhirRelease version) where T : Attribute
        {
            return(ReflectionHelper.GetAttributes <T>(t).LastOrDefault(isRelevant));

            bool isRelevant(Attribute a) => !(a is IFhirVersionDependent vd) || vd.AppliesToVersion(version);
        }
 /// <summary>
 /// Determines whether the given attribute applies to a given FHIR release.
 /// </summary>
 /// <remarks>An attribute is applicable to a given <see cref="FhirRelease"/> if
 /// the attribute has a <see cref="IFhirVersionDependent.Since"/> value that
 /// equivalent to or older than <paramref name="release"/> or has no <c>Since</c>
 /// value at all.</remarks>
 public static bool AppliesToRelease(this Attribute me, FhirRelease release) =>
 me is not IFhirVersionDependent vd || vd.Since <= release;
 public static bool AppliesToVersion(this IFhirVersionDependent me, FhirRelease fhirVersion)
 => me.Since <= fhirVersion;