Package protobuf.lang.resolve

Source Code of protobuf.lang.resolve.PbResolveUtil

package protobuf.lang.resolve;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiElement;

import static protobuf.lang.psi.PbPsiEnums.*;

import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.PsiPackage;
import protobuf.lang.psi.api.*;
import protobuf.lang.psi.api.block.PbBlock;
import protobuf.lang.psi.api.declaration.*;
import protobuf.lang.psi.api.reference.PbRef;
import protobuf.lang.psi.utils.PbPsiUtil;

/**
* @author Nikolay Matveev
* Date: Mar 29, 2010
*/
public abstract class PbResolveUtil {

    private final static Logger LOG = Logger.getInstance(PbResolveUtil.class.getName());   

    public static PsiElement resolveInScope(final PsiElement scope, final PbRef ref) {
        ReferenceKind kind = ref.getRefKind();
        String refName = ref.getReferenceName();
        if(refName == null){
            return null;
        }
        if (scope instanceof PsiPackage) {
            switch (kind) {
                case FILE:
                case PACKAGE: {

                }
                case MESSAGE_OR_GROUP_FIELD: {
                    assert false;
                }
                break;
                case MESSAGE_OR_GROUP:
                case MESSAGE_OR_ENUM_OR_GROUP:
                case EXTEND_FIELD: {
                    //get imported files by package name and invoke this function for these files
                    PbFile containingFile = (PbFile) ref.getElement().getContainingFile();
                    if (PbPsiUtil.isSamePackage(containingFile, (PsiPackage) scope)) {
                        PsiElement resolveResult = resolveInScope(containingFile, ref);
                        if (resolveResult != null) {
                            return resolveResult;
                        }
                    }
                    PbFile[] importedFiles = PbPsiUtil.getImportedFilesByPackageName(containingFile, ((PsiPackage) scope).getQualifiedName());
                    for (PbFile importedFile : importedFiles) {
                        PsiElement resolveResult = resolveInScope(importedFile, ref);
                        if (resolveResult != null) {
                            return resolveResult;
                        }
                    }
                }
                break;
                case MESSAGE_OR_PACKAGE_OR_GROUP: {
                    PbFile containingFile = (PbFile) ref.getElement().getContainingFile();
                    //resolve in subpackages scope
                    //alg: find subpackage and then find it in subpackages
                    PsiPackage subPackage = resolveInSubPackagesScope((PsiPackage) scope, refName);
                    if (subPackage != null) {
                        //f(subPackage, thisFile) -> boolean
                        //true if this subPackage in visible scope either false
                        if (PbPsiUtil.isVisibleSubPackage(subPackage, containingFile)) {
                            return subPackage;
                        }
                    }
                    //resolve in containing file
                    if (PbPsiUtil.isSamePackage(containingFile, (PsiPackage) scope)) {
                        PsiElement resolveResult = resolveInScope(containingFile, ref);
                        if (resolveResult != null) {
                            return resolveResult;
                        }
                    }
                    //resolve in imported files scope
                    PbFile[] importedFiles = PbPsiUtil.getImportedFilesByPackageName(containingFile, ((PsiPackage) scope).getQualifiedName());
                    for (PbFile importedFile : importedFiles) {
                        PsiElement resolveResult = resolveInScope(importedFile, ref);
                        if (resolveResult != null) {
                            return resolveResult;
                        }
                    }
                }
                break;
            }

        } else if (scope instanceof PbBlock || scope instanceof PbFile) {
            switch (kind) {
                case FILE:
                case PACKAGE: {
                    assert false;
                }
                case MESSAGE_OR_PACKAGE_OR_GROUP:
                case MESSAGE_OR_GROUP: {
                    PsiElement[] children = scope.getChildren();
                    for (PsiElement child : children) {
                        if (child instanceof PbMessageDef || (!(scope instanceof PbFile) && child instanceof PbGroupDef)) {
                            if (refName.equals(((PsiNamedElement) child).getName())) {
                                return child;
                            }
                        }
                    }
                    //LOG.info(refName + " : MESSAGE_OR_PACKAGE_OR_GROUP not resolved in " + (scope instanceof PbFile ? "PbFile" : ("PbBlock: " + ((PbBlock) scope).getParent().getText())));
                }
                break;
                case MESSAGE_OR_ENUM_OR_GROUP: {
                    PsiElement[] children = scope.getChildren();
                    for (PsiElement child : children) {
                        if (child instanceof PbMessageDef || child instanceof PbEnumDef || child instanceof PbGroupDef) {
                            if (refName.equals(((PsiNamedElement) child).getName())) {
                                return child;
                            }
                        }
                    }
                }
                break;
                case EXTEND_FIELD: {
                    PsiElement[] children = scope.getChildren();
                    for (PsiElement child : children) {
                        if (child instanceof PbExtendDef) {
                            PbBlock extendBlock = ((PbExtendDef) child).getBlock();
                            if (extendBlock == null) {
                                return null;
                            }
                            PsiElement[] extendChildren = extendBlock.getChildren();
                            for (PsiElement extendChild : extendChildren) {
                                if (extendChild instanceof PbFieldDef && refName.equals(((PbFieldDef) extendChild).getName())) {
                                    return extendChild;
                                } else if (extendChild instanceof PbGroupDef && refName.equals(((PbGroupDef) extendChild).getFieldName())) {
                                    return extendChild;
                                }
                            }
                        }
                    }
                }
                break;
                case MESSAGE_OR_GROUP_FIELD: {
                    if (scope instanceof PbFile) assert false;
                    PsiElement[] children = scope.getChildren();
                    for (PsiElement child : children) {
                        if (child instanceof PbFieldDef) {
                            if (refName.equals(((PsiNamedElement) child).getName())) {
                                return child;
                            }
                        } else if (child instanceof PbGroupDef && refName.equals(((PbGroupDef) child).getFieldName())) {
                            return child;
                        }
                    }
                }
                break;
            }
        }
        return null;
    }

    public static PsiPackage resolveInSubPackagesScope(final PsiPackage parentPackage, String refName) {
        PsiPackage[] subPackages = parentPackage.getSubPackages();
        for (PsiPackage subPackage : subPackages) {
            if (subPackage.getName().equals(refName)) {
                return subPackage;
            }
        }
        return null;
    }

}
TOP

Related Classes of protobuf.lang.resolve.PbResolveUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.