in tools/Elastic.CommonSchema.Generator/Projection/TypeProjector.cs [102:172]
public CommonSchemaTypesProjection CreateProjection()
{
if (Projection != null) return Projection;
var nestedEntityTypes = CreateEntityTypes();
var entities = EntityClasses.Values;
var assignables = entities
.Concat(nestedEntityTypes.Values)
.Where(e => e.EntityReferences.Count > 0)
.SelectMany(e => e.EntityReferences.Select(r => (EntityClass: e, EntityPropertyReference: r)).ToList())
.Select(r =>
{
var prop = r.EntityPropertyReference;
var sharedKey = prop.Key.Split('.') switch
{
[.. { Length: > 1 } ] a => string.Join('.', a[1..]).PascalCase(),
_ => prop.Key.PascalCase()
};
if (r.EntityPropertyReference.Value.Entity is SelfReferentialReusedEntityClass s)
sharedKey = s.Name;
return (Key: sharedKey, r.EntityClass, r.EntityPropertyReference);
})
.GroupBy(e => e.Key)
.SelectMany(g =>
g.Select(r => r.EntityPropertyReference.Value).DistinctBy(r=>r.ClrType)
.Select(r => new AssignableEntityInterface(g.Key, r, g.Select(r=>r.EntityClass).ToList()))
)
//.DistinctBy(g=>g.Name)
.ToList();
foreach (var entity in entities)
entity.AssignableInterfaces = assignables.Where(a => a.Entities.Contains(entity)).DistinctBy(a=>a.Name).ToList();
Projection = new CommonSchemaTypesProjection
{
Version = Schema.Version,
GitRef = Schema.GitRef,
FieldSets = FieldSetsBaseClasses.Values.Where(e=>e.FieldSet.Root != true || e.FieldSet.Name == "base" ).ToList(),
EntityClasses = EntityClasses.Values.Where(e => e.Name != "EcsDocument" && e.BaseFieldSet.FieldSet.Root != true).ToList(),
EntitiesWithPropertiesAtRoot = new Dictionary<EntityClass, string[]>
{
{ EntityClasses.Values.First(e=>e.Name == "Log"), new []{"level"}},
{ EntityClasses.Values.First(e=>e.Name == "Ecs"), new []{"version"}},
},
Base = EntityClasses.Values.First(e=>e.Name == "EcsDocument"),
InlineObjects = InlineObjects.Values.ToList(),
NestedEntityClasses = nestedEntityTypes.Values.ToList(),
Warnings = Warnings.AsReadOnly(),
IndexTemplates = Schema.Templates.Select(kv => new IndexTemplate(kv.Key, kv.Value, Schema.Version)).OrderBy(t=>t.Name).ToList(),
IndexComponents = Schema.Components.Select(kv => new IndexComponent(kv.Key, kv.Value, Schema.Version)).OrderBy(t=>t.Name).ToList(),
AssignableInterfaces = assignables
};
var assignableToEcsDocument = Projection.EntityClasses.Select(e=> assignables.FirstOrDefault(a=>a.Property.Entity == e && a.Property.Name == e.Name)).Where(a => a != null).ToList();
Projection.Base.AssignableInterfaces = assignableToEcsDocument;
var allEntities = Projection.EntityClasses.Concat(Projection.NestedEntityClasses).ToDictionary(kv=>kv.Name);
var assignable = Projection.AssignableInterfaces.ToDictionary(e => e.Name.Substring(1, e.Name.Length - 1));
var propDispatches = new List<PropDispatch>();
foreach (var (name, entity) in allEntities)
{
var found = assignable.TryGetValue(name, out var a);
if (found && a.Property.IsArray)
continue;
if (entity is SelfReferentialReusedEntityClass)
continue;
propDispatches.Add(new PropDispatch(entity, a));
}
Projection.AssignablePropDispatches = propDispatches;
return Projection;
}