private Dictionary CreateEntityTypes()

in tools/Elastic.CommonSchema.Generator/Projection/TypeProjector.cs [174:248]


		private Dictionary<string, EntityClass> CreateEntityTypes()
		{
			// Create concrete entity instances of base field sets to reference
			var nestedEntityClasses = new Dictionary<string, EntityClass>();
			foreach (var (name, fieldSetBaseClass) in FieldSetsBaseClasses)
			{
				var fieldSet = fieldSetBaseClass.FieldSet;
				var entityClass = EntityClasses[name];
				var parentPath = name;
				if (fieldSet.ReusedHere == null) continue;

				foreach (var reuse in fieldSet.ReusedHere)
				{
					var fieldTokens = reuse.Full.Split('.').ToArray();
					var isArray = reuse.Normalize != null && reuse.Normalize.Contains("array");
					// most common case a reference to a different schema
					if (fieldTokens.Length <= 2 && reuse.SchemaName != name)
					{
						entityClass.EntityReferences[reuse.Full] =
							new EntityPropertyReference(parentPath, reuse.Full, EntityClasses[reuse.SchemaName], reuse.Short, isArray);
					}
					else
					{
						// We can't assume the direct parent is an ECS field e.g
						// email.attachments.file.hash -> file.hash is a property on email.attachments

						var basePaths = fieldTokens.Select((_, i) => string.Join('.', fieldTokens.Take(i + 1))).Reverse().ToArray();
						var inlineObjectPath = basePaths.FirstOrDefault(p => InlineObjects.ContainsKey(p));
						var entityObjectPath = basePaths.FirstOrDefault(p => EntityClasses.ContainsKey(p));
						// check if this deeply nested reference refers to an inline object
						if (!string.IsNullOrEmpty(inlineObjectPath))
						{
							InlineObjects[inlineObjectPath].EntityReferences[reuse.Full] =
								new EntityPropertyReference(inlineObjectPath, reuse.Full, EntityClasses[reuse.SchemaName], reuse.Short, isArray);
						}
						else if (!string.IsNullOrWhiteSpace(entityObjectPath) && reuse.SchemaName != name)
						{
							EntityClasses[entityObjectPath].EntityReferences[reuse.Full] =
								new EntityPropertyReference(entityObjectPath, reuse.Full, EntityClasses[reuse.SchemaName], reuse.Short, isArray);
						}
						// created new nested usage of this entity
						else if (!string.IsNullOrWhiteSpace(entityObjectPath))
						{
							var nestedEntityClass = new SelfReferentialReusedEntityClass(reuse.Full, EntityClasses[reuse.SchemaName].BaseFieldSet, reuse.Short, isArray);
							nestedEntityClasses[reuse.Full] = nestedEntityClass;
						}
						else Warnings.Add($"Unable to project reuse of: ${reuse.Full}");
					}
				}
			}

			foreach (var (fullName, entity) in nestedEntityClasses)
			{
				var fieldTokens = fullName.Split('.').ToArray();
				var parentPaths = fieldTokens.Select((_, i) => string.Join('.', fieldTokens.Take(i + 1))).Reverse().Skip(1).ToArray();
				var nestedPath = parentPaths.FirstOrDefault(p => nestedEntityClasses.ContainsKey(p));
				var entityPath = parentPaths.FirstOrDefault(p => EntityClasses.ContainsKey(p));
				var description = entity is SelfReferentialReusedEntityClass s ? s.ReuseDescription : entity.BaseFieldSet.FieldSet.Description;
				var isArray = entity is SelfReferentialReusedEntityClass { IsArray: true };
				if (!string.IsNullOrEmpty(nestedPath))
				{
					var nestedEntityClassRef = new EntityPropertyReference(nestedPath, fullName, entity, description, isArray);
					nestedEntityClasses[nestedPath].EntityReferences[fullName] = nestedEntityClassRef;
				}
				else if (!string.IsNullOrEmpty(entityPath))
				{
					var nestedEntityClassRef = new EntityPropertyReference(entityPath, fullName, entity, description, isArray);
					EntityClasses[entityPath].EntityReferences[fullName] = nestedEntityClassRef;
				}
				else
					Warnings.Add($"Unable find host to hold the entity reference ${fullName}");
			}

			return nestedEntityClasses;
		}