private void CompileIdentityConstraint (XmlSchemaIdentityConstraint xi) {
if (xi.IsProcessing) {
xi.CompiledConstraint = CompiledIdentityConstraint.Empty;
SendValidationEvent(Res.Sch_IdentityConstraintCircularRef, xi);
return;
}
if (xi.CompiledConstraint != null) {
return;
}
xi.IsProcessing = true;
CompiledIdentityConstraint compic = null;
try {
SchemaNamespaceManager xnmgr = new SchemaNamespaceManager(xi);
compic = new CompiledIdentityConstraint(xi, xnmgr);
if (xi is XmlSchemaKeyref) {
XmlSchemaIdentityConstraint ic = (XmlSchemaIdentityConstraint)this.identityConstraints[((XmlSchemaKeyref)xi).Refer];
if (ic == null) {
throw new XmlSchemaException(Res.Sch_UndeclaredIdentityConstraint, ((XmlSchemaKeyref)xi).Refer.ToString(), xi);
}
CompileIdentityConstraint(ic);
if (ic.CompiledConstraint == null) {
throw new XmlSchemaException(Res.Sch_RefInvalidIdentityConstraint, ((XmlSchemaKeyref)xi).Refer.ToString(), xi);
}
// keyref has the different cardinality with the key it referred
if (ic.Fields.Count != xi.Fields.Count) {
throw new XmlSchemaException(Res.Sch_RefInvalidCardin, xi.QualifiedName.ToString(), xi);
}
// keyref can only refer to key/unique
if (ic.CompiledConstraint.Role == CompiledIdentityConstraint.ConstraintRole.Keyref) {
throw new XmlSchemaException(Res.Sch_ReftoKeyref, xi.QualifiedName.ToString(), xi);
}
}
xi.CompiledConstraint = compic;
}
catch (XmlSchemaException e) {
if (e.SourceSchemaObject == null) {
e.SetSource(xi);
}
SendValidationEvent(e);
xi.CompiledConstraint = CompiledIdentityConstraint.Empty;
// empty is better than null here, stop quickly when circle referencing
}
finally {
xi.IsProcessing = false;
}
}