com.google.eclipse.protobuf.scoping.ProtobufImportScope.java Source code

Java tutorial

Introduction

Here is the source code for com.google.eclipse.protobuf.scoping.ProtobufImportScope.java

Source

/*
 * Copyright (c) 2016 Google Inc.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package com.google.eclipse.protobuf.scoping;

import static com.google.eclipse.protobuf.model.util.QualifiedNames.removeLeadingDot;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.ISelectable;
import org.eclipse.xtext.resource.impl.AliasedEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.ImportNormalizer;
import org.eclipse.xtext.scoping.impl.ImportScope;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;

/**
 * {@link ImportScope} that allows additional ImportNormalizers to be added.
 *
 * @author (atrookey@google.com) Alexander Rookey
 */
public class ProtobufImportScope extends ImportScope {
    private final EClass type;
    private List<ImportNormalizer> normalizers;

    public ProtobufImportScope(List<ImportNormalizer> namespaceResolvers, IScope parent, ISelectable importFrom,
            EClass type, boolean ignoreCase) {
        super(namespaceResolvers, parent, importFrom, type, ignoreCase);
        this.type = type;
        this.normalizers = removeDuplicates(namespaceResolvers);
    }

    /*
     * Override {@link ImportScope.getAliasedElements(Iterable<IEObjectDescription>)} to use local
     * {@link ImportNormalizer} list.
     */
    @Override
    protected Iterable<IEObjectDescription> getAliasedElements(Iterable<IEObjectDescription> candidates) {
        Multimap<QualifiedName, IEObjectDescription> keyToDescription = LinkedHashMultimap.create();
        Multimap<QualifiedName, ImportNormalizer> keyToNormalizer = HashMultimap.create();

        for (IEObjectDescription imported : candidates) {
            QualifiedName fullyQualifiedName = imported.getName();
            for (ImportNormalizer normalizer : normalizers) {
                QualifiedName alias = normalizer.deresolve(fullyQualifiedName);
                if (alias != null) {
                    QualifiedName key = alias;
                    if (isIgnoreCase()) {
                        key = key.toLowerCase();
                    }
                    keyToDescription.put(key, new AliasedEObjectDescription(alias, imported));
                    keyToNormalizer.put(key, normalizer);
                }
            }
        }
        for (QualifiedName name : keyToNormalizer.keySet()) {
            if (keyToNormalizer.get(name).size() > 1)
                keyToDescription.removeAll(name);
        }
        return keyToDescription.values();
    }

    /*
     * Override {@link ImportScope.getLocalElementsByName(QualifiedName)} to use local
     * {@link ImportNormalizer} list.
     */
    @Override
    protected Iterable<IEObjectDescription> getLocalElementsByName(QualifiedName name) {
        List<IEObjectDescription> result = new ArrayList<>();
        QualifiedName resolvedQualifiedName = null;
        ISelectable importFrom = getImportFrom();
        for (ImportNormalizer normalizer : normalizers) {
            final QualifiedName resolvedName = normalizer.resolve(name);
            if (resolvedName != null) {
                Iterable<IEObjectDescription> resolvedElements = importFrom.getExportedObjects(type, resolvedName,
                        isIgnoreCase());
                for (IEObjectDescription resolvedElement : resolvedElements) {
                    if (resolvedQualifiedName == null)
                        resolvedQualifiedName = resolvedName;
                    else if (!resolvedQualifiedName.equals(resolvedName)) {
                        if (result.get(0).getEObjectOrProxy() != resolvedElement.getEObjectOrProxy()) {
                            return Collections.emptyList();
                        }
                    }
                    QualifiedName alias = normalizer.deresolve(resolvedElement.getName());
                    if (alias == null)
                        throw new IllegalStateException(
                                "Couldn't deresolve " + resolvedElement.getName() + " with import " + normalizer);
                    final AliasedEObjectDescription aliasedEObjectDescription = new AliasedEObjectDescription(alias,
                            resolvedElement);
                    result.add(aliasedEObjectDescription);
                }
            }
        }
        return result;
    }

    /** Before getting element, check for and remove leading dot. */
    @Override
    public IEObjectDescription getSingleElement(QualifiedName name) {
        return super.getSingleElement(removeLeadingDot(name));
    }

    public void addNormalizer(ImportNormalizer normalizer) {
        normalizers.add(normalizer);
    }

    public void addAllNormalizers(Collection<ImportNormalizer> normalizer) {
        normalizers.addAll(normalizer);
    }
}