in objectModel/Java/objectmodel/src/main/java/com/microsoft/commondatamodel/objectmodel/cdm/CdmCorpusDefinition.java [765:1024]
public CdmObjectBase resolveSymbolReference(
final ResolveOptions resOpt,
final CdmDocumentDefinition fromDoc,
String symbolDef,
final CdmObjectType expectedType,
final boolean retry) {
final ResolveContext ctx = (ResolveContext) this.ctx;
// Given a symbolic name, find the 'highest priority' definition of the object from the point
// of view of a given document (with respect to, wrtDoc) (meaning given a document and the
// things it defines and the files it imports and the files they import, where is the 'last'
// definition found).
if (resOpt == null || resOpt.getWrtDoc() == null || symbolDef == null) {
// No way to figure this out.
return null;
}
CdmDocumentDefinition wrtDoc = resOpt.getWrtDoc();
if (wrtDoc.getNeedsIndexing() && !wrtDoc.isCurrentlyIndexing()) {
if (!wrtDoc.indexIfNeededAsync(resOpt, true).join()) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrIndexFailed);
return null;
}
}
if (wrtDoc.getNeedsIndexing() && resOpt.getImportsLoadStrategy() == ImportsLoadStrategy.DoNotLoad) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrSymbolNotFound, symbolDef, "because the ImportsLoadStrategy is set to DoNotLoad");
return null;
}
// save the symbol name as it got here
String initialSymbol = symbolDef;
// when trying to find a reference, first find the definition that contains it
// and then look for the reference inside it.
boolean isReference = symbolDef != null && symbolDef.endsWith("(ref)");
if (isReference) {
int defIndex = symbolDef.indexOf("/");
symbolDef = symbolDef.substring(0, defIndex);
}
// Get the array of documents where the symbol is defined.
final DocsResult symbolDocsResult = this.docsForSymbol(resOpt, wrtDoc, fromDoc, symbolDef);
CdmDocumentDefinition docBest = symbolDocsResult.getDocBest();
symbolDef = symbolDocsResult.getNewSymbol();
if (!isReference) {
initialSymbol = symbolDef;
}
final List<CdmDocumentDefinition> docs = symbolDocsResult.getDocList();
if (null != docs) {
// Add this symbol to the set being collected in resOpt, we will need this when caching.
if (null == resOpt.getSymbolRefSet()) {
resOpt.setSymbolRefSet(new SymbolSet());
}
resOpt.getSymbolRefSet().add(symbolDef);
// For the given doc, there is a sorted list of imported docs (including the doc
// itself as item 0). Find the lowest number imported document that has a definition
// for this symbol.
if (null == wrtDoc.getImportPriorities()) {
return null;
}
final Map<CdmDocumentDefinition, ImportInfo> importPriority = wrtDoc.getImportPriorities().getImportPriority();
if (importPriority.size() == 0) {
return null;
}
if (null == docBest) {
docBest = CdmCorpusDefinition.fetchPriorityDocument(docs, importPriority);
}
}
// Perhaps we have never heard of this symbol in the imports for this document?
if (null == docBest) {
return null;
}
// Return the definition found in the best document
CdmObjectBase found = docBest.internalDeclarations.get(symbolDef);
// in case we are trying to find a reference, the object we found previously is the definition that contains the reference.
// look inside the definition now.
if (found != null && isReference) {
AtomicReference<CdmObjectBase> foundRef = new AtomicReference<>();
// try to find the reference
final String symbol = initialSymbol;
found.visit("", (obj, objPath) -> {
if (symbol.equals(objPath)) {
foundRef.set((CdmObjectBase) obj);
return true;
}
return false;
}, null);
found = foundRef.get();
}
if (found == null && retry) {
// Maybe just locatable from here not defined here.
// This happens when the symbol is monikered, but the moniker path doesn't lead to the document where the symbol is defined.
// It leads to the document from where the symbol can be found.
// Ex.: resolvedFrom/Owner, while resolvedFrom is the Account that imports Owner.
found = this.resolveSymbolReference(resOpt, docBest, initialSymbol, expectedType, false);
}
if (found != null && expectedType != CdmObjectType.Error) {
switch (expectedType) {
case TraitRef: {
if (found.getObjectType() != CdmObjectType.TraitDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "trait", symbolDef);
found = null;
}
break;
}
case DataTypeRef: {
if (found.getObjectType() != CdmObjectType.DataTypeDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "dataType", symbolDef);
found = null;
}
break;
}
case EntityRef: {
if (found.getObjectType() != CdmObjectType.EntityDef && found.getObjectType() != CdmObjectType.ProjectionDef && found.getObjectType() != CdmObjectType.ConstantEntityDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "entity or type projection or type constant entity", symbolDef);
found = null;
}
break;
}
case ParameterDef: {
if (found.getObjectType() != CdmObjectType.ParameterDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "parameter", symbolDef);
found = null;
}
break;
}
case PurposeRef: {
if (found.getObjectType() != CdmObjectType.PurposeDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "purpose", symbolDef);
found = null;
}
break;
}
case TraitGroupRef:
if (found.getObjectType() != CdmObjectType.TraitGroupDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "traitGroup", symbolDef);
found = null;
}
break;
case AttributeGroupRef: {
if (found.getObjectType() != CdmObjectType.AttributeGroupDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "attributeGroup", symbolDef);
found = null;
}
break;
}
case ProjectionDef: {
if (found.getObjectType() != CdmObjectType.ProjectionDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "add count attribute operation", symbolDef);
found = null;
}
break;
}
case OperationAddCountAttributeDef: {
if (found.getObjectType() != CdmObjectType.OperationAddCountAttributeDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "add supporting attribute operation", symbolDef);
found = null;
}
break;
}
case OperationAddSupportingAttributeDef: {
if (found.getObjectType() != CdmObjectType.OperationAddSupportingAttributeDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "type attribute operation", symbolDef);
found = null;
}
break;
}
case OperationAddTypeAttributeDef: {
if (found.getObjectType() != CdmObjectType.OperationAddTypeAttributeDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "attribute operation", symbolDef);
found = null;
}
break;
}
case OperationExcludeAttributesDef: {
if (found.getObjectType() != CdmObjectType.OperationExcludeAttributesDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "exclude attributes operation", symbolDef);
found = null;
}
break;
}
case OperationArrayExpansionDef: {
if (found.getObjectType() != CdmObjectType.OperationArrayExpansionDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "array expansion operation", symbolDef);
found = null;
}
break;
}
case OperationCombineAttributesDef: {
if (found.getObjectType() != CdmObjectType.OperationCombineAttributesDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "combine attributes operation", symbolDef);
found = null;
}
break;
}
case OperationRenameAttributesDef: {
if (found.getObjectType() != CdmObjectType.OperationRenameAttributesDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "rename attributes operation", symbolDef);
found = null;
}
break;
}
case OperationReplaceAsForeignKeyDef: {
if (found.getObjectType() != CdmObjectType.OperationReplaceAsForeignKeyDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "replace as foreign key operation", symbolDef);
found = null;
}
break;
}
case OperationIncludeAttributesDef: {
if (found.getObjectType() != CdmObjectType.OperationIncludeAttributesDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "include attributes operation", symbolDef);
found = null;
}
break;
}
case OperationAddAttributeGroupDef: {
if (found.getObjectType() != CdmObjectType.OperationAddAttributeGroupDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "add attribute group operation", symbolDef);
found = null;
}
break;
}
case OperationAlterTraitsDef: {
if (found.getObjectType() != CdmObjectType.OperationAlterTraitsDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "alter traits operation", symbolDef);
found = null;
}
break;
}
case OperationAddArtifactAttributeDef: {
if (found.getObjectType() != CdmObjectType.OperationAddArtifactAttributeDef) {
Logger.error(ctx, TAG, "resolveSymbolReference", wrtDoc.getAtCorpusPath(), CdmLogCode.ErrUnexpectedType, "add artifact attribute operation", symbolDef);
found = null;
}
break;
}
default: {
break;
}
}
}
return found;
}