protected virtual MetaMetadata FindOrGenerateInheritedMetaMetadata(MetaMetadataRepository repository, InheritanceHandler inheritanceHandler)
{
MetaMetadata inheritedMmd = this.TypeMmd;
if (inheritedMmd == null)
{
MmdScope mmdScope = this.Scope;
String inheritedMmdName = Type ?? Name;
if (ExtendsAttribute != null)
{
// determine new type name
if (inheritedMmdName == null)
throw new MetaMetadataException("attribute 'name' must be specified: " + this);
if (inheritanceHandler.ResolveMmdName(inheritedMmdName) != null)
// currently we don't encourage re-using existing name. however, in the future, when package names are available, we can change this.
throw new MetaMetadataException("meta-metadata '" + inheritedMmdName + "' already exists! please use another name to prevent name collision. hint: use 'tag' to change the tag if needed.");
// determine from which meta-metadata to inherit
inheritedMmd = inheritanceHandler.ResolveMmdName(ExtendsAttribute);
if (ExtendsAttribute == null || inheritedMmd == null)
throw new MetaMetadataException("super type not specified or recognized: " + this + ", super type name: " + ExtendsAttribute);
// generate inline mmds and put it into current scope
MetaMetadata generatedMmd = this.GenerateMetaMetadata(inheritedMmdName, inheritedMmd);
mmdScope.Put(inheritedMmdName, generatedMmd);
mmdScope.Put(generatedMmd.Name, generatedMmd);
// recursively do inheritance on generated mmd
generatedMmd.InheritMetaMetadata(null); // this will set generateClassDescriptor to true if necessary
MakeThisFieldUseMmd(inheritedMmdName, generatedMmd);
return generatedMmd;
}
else
{
// use type / extends
if (inheritedMmdName == null)
throw new MetaMetadataException("no type / extends defined for " + this
+ " (note that due to a limitation explicit child_scalar_type is needed for scalar collection fields, even if it has been declared in super field).");
NameType[] nameType = new NameType[1];
inheritedMmd = inheritanceHandler.ResolveMmdName(inheritedMmdName, nameType);
if (inheritedMmd == null)
throw new MetaMetadataException("meta-metadata not found: " + inheritedMmdName + " (if you want to define new types inline, you need to specify extends/child_extends).");
if (!inheritedMmdName.Equals(inheritedMmd.Name) && nameType[0] == NameType.MMD)
{
// could be inline mmd
this.MakeThisFieldUseMmd(inheritedMmdName, inheritedMmd);
}
// process normal mmd / field
Debug.WriteLine("setting " + this + ".inheritedMmd to " + inheritedMmd);
TypeMmd = inheritedMmd;
}
}
return inheritedMmd;
}