| /* |
| * Copyright (c) 2011 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.naming; |
| |
| import static com.google.common.collect.Lists.newArrayList; |
| import static com.google.eclipse.protobuf.naming.NameType.NORMAL; |
| import static java.util.Collections.emptyList; |
| import static org.eclipse.xtext.util.Strings.isEmpty; |
| import static org.eclipse.xtext.util.Tuples.pair; |
| |
| import java.util.List; |
| |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.xtext.naming.*; |
| import org.eclipse.xtext.util.*; |
| |
| import com.google.eclipse.protobuf.model.util.*; |
| import com.google.inject.*; |
| |
| /** |
| * Provides alternative qualified names for protobuf elements. |
| * <p> |
| * For example, given the following proto element: |
| * |
| * <pre> |
| * package test.alternative.names; |
| * |
| * message Person { |
| * optional string name = 1; |
| * |
| * enum PhoneType { |
| * HOME = 0; |
| * WORK = 1; |
| * } |
| * } |
| * </pre> |
| * |
| * The default qualified name for {@code PhoneType} is {@code alternative.names.Person.PhoneType}. The problem is that |
| * protoc also recognizes the following as qualified names: |
| * <ul> |
| * <li>{@code PhoneType}</li> |
| * <li>{@code Person.PhoneType}</li> |
| * <li>{@code names.Person.PhoneType}</li> |
| * <li>{@code test.names.Person.PhoneType}</li> |
| * </ul> |
| * </p> |
| * |
| * @author alruiz@google.com (Alex Ruiz) |
| */ |
| public class LocalNamesProvider { |
| private static Pair<NameType, List<QualifiedName>> EMPTY_NAMES = emptyNames(); |
| |
| private static Pair<NameType, List<QualifiedName>> emptyNames() { |
| List<QualifiedName> names = emptyList(); |
| return pair(NORMAL, names); |
| } |
| |
| @Inject private final IResourceScopeCache cache = IResourceScopeCache.NullImpl.INSTANCE; |
| |
| @Inject private ModelObjects modelObjects; |
| @Inject private NameResolver nameResolver; |
| @Inject private IQualifiedNameConverter qualifiedNameConverter; |
| @Inject private Packages packages; |
| |
| public List<QualifiedName> localNames(final EObject e, final NamingStrategy strategy) { |
| Pair<EObject, String> key = pair(e, "localFqns"); |
| Pair<NameType, List<QualifiedName>> cached = cache.get(key, e.eResource(), |
| new Provider<Pair<NameType, List<QualifiedName>>>() { |
| @Override public Pair<NameType, List<QualifiedName>> get() { |
| List<QualifiedName> allNames = newArrayList(); |
| EObject current = e; |
| Pair<NameType, String> name = strategy.nameOf(e); |
| if (name == null) { |
| return EMPTY_NAMES; |
| } |
| QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(name.getSecond()); |
| allNames.add(qualifiedName); |
| while (current.eContainer() != null) { |
| current = current.eContainer(); |
| String containerName = nameResolver.nameOf(current); |
| if (isEmpty(containerName)) { |
| continue; |
| } |
| qualifiedName = qualifiedNameConverter.toQualifiedName(containerName).append(qualifiedName); |
| allNames.add(qualifiedName); |
| } |
| allNames.addAll(packages.addPackageNameSegments(modelObjects.packageOf(e), qualifiedName)); |
| return pair(name.getFirst(), allNames); |
| } |
| }); |
| return cached.getSecond(); |
| } |
| } |