In progress: [Issue 199] Add ability to navigate to proto element from
generated C++ code.
Initial project import.
diff --git a/com.google.eclipse.protobuf.cdt/.classpath b/com.google.eclipse.protobuf.cdt/.classpath
new file mode 100644
index 0000000..ad32c83
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/com.google.eclipse.protobuf.cdt/.gitignore b/com.google.eclipse.protobuf.cdt/.gitignore
new file mode 100644
index 0000000..40a85ff
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/.gitignore
@@ -0,0 +1 @@
+/.settings
diff --git a/com.google.eclipse.protobuf.cdt/.project b/com.google.eclipse.protobuf.cdt/.project
new file mode 100644
index 0000000..130ae32
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>com.google.eclipse.protobuf.cdt</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/com.google.eclipse.protobuf.cdt/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf.cdt/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d989a9b
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Protocol Buffer Editor: CDT Integration
+Bundle-SymbolicName: com.google.eclipse.protobuf.cdt;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: com.google.eclipse.protobuf.cdt.ProtobufCdtActivator
+Bundle-Vendor: Google, Inc.
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.cdt.core;bundle-version="5.3.1",
+ org.eclipse.cdt.ui;bundle-version="5.3.1",
+ com.google.eclipse.protobuf;bundle-version="1.2.1",
+ com.google.eclipse.protobuf.ui;bundle-version="1.2.1",
+ org.eclipse.core.resources;bundle-version="3.7.100",
+ org.eclipse.jface.text;bundle-version="3.7.1",
+ org.eclipse.xtext;bundle-version="2.2.1",
+ org.eclipse.xtext.ui;bundle-version="2.2.1"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
diff --git a/com.google.eclipse.protobuf.cdt/build.properties b/com.google.eclipse.protobuf.cdt/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/com.google.eclipse.protobuf.cdt/icons/pb.gif b/com.google.eclipse.protobuf.cdt/icons/pb.gif
new file mode 100644
index 0000000..762a318
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/icons/pb.gif
Binary files differ
diff --git a/com.google.eclipse.protobuf.cdt/plugin.xml b/com.google.eclipse.protobuf.cdt/plugin.xml
new file mode 100644
index 0000000..17864bd
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/plugin.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.popupMenus">
+ <viewerContribution
+ id="com.google.eclipse.protobuf.cdt.cEditorPopup"
+ targetID="#CEditorContext">
+ <action
+ class="com.google.eclipse.protobuf.cdt.ProtobufCdtExecutableExtensionFactory:com.google.eclipse.protobuf.cdt.actions.OpenProtoDeclarationAction"
+ icon="icons/pb.gif"
+ id="com.google.eclipse.protobuf.cdt.openProtoDeclaration"
+ label="Open Declaration in .proto File"
+ menubarPath="group.open"
+ style="push">
+ </action>
+ </viewerContribution>
+ </extension>
+
+</plugin>
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtActivator.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtActivator.java
new file mode 100644
index 0000000..caf3075
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtActivator.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012 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.cdt;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+import com.google.inject.*;
+
+/**
+ * Controls the plug-in life cycle.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ProtobufCdtActivator extends AbstractUIPlugin {
+ public static final String PLUGIN_ID = "com.google.eclipse.protobuf.cdt";
+
+ private static ProtobufCdtActivator plugin;
+
+ private final Injector injector;
+
+ public ProtobufCdtActivator() {
+ injector = Guice.createInjector(new ProtobufCdtModule());
+ }
+
+ /**
+ * Returns the singleton instance of this class.
+ * @return the singleton instance of this class.
+ */
+ public static ProtobufCdtActivator getInstance() {
+ return plugin;
+ }
+
+ @Override public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ @Override public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ public Injector getInjector() {
+ return injector;
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtExecutableExtensionFactory.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtExecutableExtensionFactory.java
new file mode 100644
index 0000000..76bcb0a
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtExecutableExtensionFactory.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012 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.cdt;
+
+import org.eclipse.xtext.ui.guice.AbstractGuiceAwareExecutableExtensionFactory;
+import org.osgi.framework.Bundle;
+
+import com.google.inject.Injector;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ProtobufCdtExecutableExtensionFactory extends AbstractGuiceAwareExecutableExtensionFactory {
+
+ @Override protected Bundle getBundle() {
+ return plugIn().getBundle();
+ }
+
+ @Override protected Injector getInjector() {
+ return plugIn().getInjector();
+ }
+
+ private ProtobufCdtActivator plugIn() {
+ return ProtobufCdtActivator.getInstance();
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtModule.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtModule.java
new file mode 100644
index 0000000..2774df5
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtModule.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012 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.cdt;
+
+import static com.google.eclipse.protobuf.cdt.ProtobufObjectsProvider.getfromProtobufPlugin;
+
+import org.eclipse.xtext.service.AbstractGenericModule;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
+
+import com.google.eclipse.protobuf.ui.editor.ModelObjectDefinitionNavigator;
+import com.google.inject.Binder;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ProtobufCdtModule extends AbstractGenericModule {
+ public void configureModelObjectDefinitionNavigator(Binder binder) {
+ bindToProtobufPluginObject(ModelObjectDefinitionNavigator.class, binder);
+ bindToProtobufPluginObject(IPreferenceStoreAccess.class, binder);
+ }
+
+ private <T> void bindToProtobufPluginObject(Class<T> type, Binder binder) {
+ binder.bind(type).toProvider(getfromProtobufPlugin(type));
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufObjectsProvider.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufObjectsProvider.java
new file mode 100644
index 0000000..0bdb758
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufObjectsProvider.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 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.cdt;
+
+import com.google.eclipse.protobuf.ui.util.ProtobufPlugIn;
+import com.google.inject.Provider;
+
+/**
+ * Obtains objects from the protobuf editor plug-in.
+ * @param <T> the type of object to obtain from the protobuf editor plug-in.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class ProtobufObjectsProvider<T> implements Provider<T> {
+ private final Class<T> type;
+
+ static <T> ProtobufObjectsProvider<T> getfromProtobufPlugin(Class<T> type) {
+ return new ProtobufObjectsProvider<T>(type);
+ }
+
+ private ProtobufObjectsProvider(Class<T> type) {
+ this.type = type;
+ }
+
+ @Override public T get() {
+ return ProtobufPlugIn.getInstance(type);
+ }
+}
\ No newline at end of file
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ClassTypeQualifiedNameBuilder.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ClassTypeQualifiedNameBuilder.java
new file mode 100644
index 0000000..b521a6a
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ClassTypeQualifiedNameBuilder.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012 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.cdt.actions;
+
+import static java.util.Collections.*;
+
+import java.util.Collection;
+
+import org.eclipse.cdt.core.dom.IName;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.*;
+import org.eclipse.xtext.naming.QualifiedName;
+
+import com.google.inject.Singleton;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@SuppressWarnings("restriction")
+@Singleton class ClassTypeQualifiedNameBuilder {
+ public Collection<QualifiedName> createQualifiedNamesFrom(CPPClassType classType) {
+ if (isMessage(classType)) {
+ String[] segments = classType.getQualifiedName();
+ return singletonList(QualifiedName.create(segments));
+ }
+ return emptyList();
+ }
+
+ private boolean isMessage(CPPClassType classType) {
+ ICPPBase[] bases = classType.getBases();
+ if (bases.length != 1) {
+ return false;
+ }
+ IName name = bases[0].getBaseClassSpecifierName();
+ if (!(name instanceof CPPASTQualifiedName)) {
+ return false;
+ }
+ CPPASTQualifiedName qualifiedName = (CPPASTQualifiedName) name;
+ if (!qualifiedName.isFullyQualified()) {
+ return false;
+ }
+ String rawSignature = qualifiedName.getRawSignature();
+ return "::google::protobuf::Message".equals(rawSignature);
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ModelObjectDefinitionQueryBuilder.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ModelObjectDefinitionQueryBuilder.java
new file mode 100644
index 0000000..dcb0e0e
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ModelObjectDefinitionQueryBuilder.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012 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.cdt.actions;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.eclipse.protobuf.ui.editor.ModelObjectDefinitionNavigator.Query.query;
+import static java.lang.Math.max;
+import static java.util.Collections.emptyList;
+import static org.eclipse.cdt.internal.ui.editor.ASTProvider.WAIT_NO;
+import static org.eclipse.core.runtime.Status.*;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.cdt.core.dom.ast.*;
+import org.eclipse.cdt.core.model.*;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType;
+import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
+import org.eclipse.cdt.internal.ui.editor.ASTProvider;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.xtext.naming.QualifiedName;
+
+import com.google.eclipse.protobuf.ui.editor.ModelObjectDefinitionNavigator.Query;
+import com.google.inject.Inject;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@SuppressWarnings("restriction")
+class ModelObjectDefinitionQueryBuilder {
+ @Inject private ClassTypeQualifiedNameBuilder nameBuilder;
+ @Inject private ProtoFilePathFinder pathFinder;
+
+ Collection<Query> buildQueries(final IEditorPart editor, final ITextSelection selection) {
+ final IPath protoFilePath = pathFinder.findProtoFilePath(editor);
+ if (protoFilePath == null) {
+ return emptyList();
+ }
+ IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
+ if (workingCopy == null) {
+ return emptyList();
+ }
+ final AtomicReference<Collection<Query>> queriesReference = new AtomicReference<Collection<Query>>();
+ ASTProvider astProvider = ASTProvider.getASTProvider();
+ IStatus status = astProvider.runOnAST(workingCopy, WAIT_NO, null, new ASTRunnable() {
+ @Override public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
+ if (ast == null) {
+ return CANCEL_STATUS;
+ }
+ int offset = selection.getOffset();
+ int length = max(1, selection.getLength());
+ IASTNodeSelector nodeSelector= ast.getNodeSelector(null);
+ IASTName selectedName = nodeSelector.findEnclosingName(offset, length);
+ if (selectedName == null) {
+ return CANCEL_STATUS;
+ }
+ if (selectedName.isDefinition()) {
+ IBinding binding = selectedName.resolveBinding();
+ if (binding instanceof CPPClassType) {
+ Collection<QualifiedName> qualifiedNames = nameBuilder.createQualifiedNamesFrom((CPPClassType) binding);
+ if (qualifiedNames.isEmpty()) {
+ return CANCEL_STATUS;
+ }
+ List<Query> queries = newArrayList();
+ for (QualifiedName qualifiedName : qualifiedNames) {
+ queries.add(query(qualifiedName, protoFilePath));
+ }
+ queriesReference.set(queries);
+ return OK_STATUS;
+ }
+ }
+ return CANCEL_STATUS;
+ }
+ });
+ if (status == CANCEL_STATUS) {
+ return emptyList();
+ }
+ return queriesReference.get();
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/NavigationJobs.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/NavigationJobs.java
new file mode 100644
index 0000000..a46878c
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/NavigationJobs.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012 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.cdt.actions;
+
+import static org.eclipse.core.runtime.Status.OK_STATUS;
+
+import java.util.Collection;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.ui.progress.UIJob;
+
+import com.google.eclipse.protobuf.ui.editor.*;
+import com.google.eclipse.protobuf.ui.editor.ModelObjectDefinitionNavigator.Query;
+import com.google.inject.Inject;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class NavigationJobs {
+ @Inject private ModelObjectDefinitionNavigator navigator;
+
+ void scheduleUsing(final Collection<Query> queries) {
+ UIJob job = new UIJob("Navigating to .proto file") {
+ @Override public IStatus runInUIThread(IProgressMonitor monitor) {
+ for (Query query : queries) {
+ IStatus result = navigator.navigateToDefinition(query);
+ if (result.equals(OK_STATUS)) {
+ break;
+ }
+ }
+ return OK_STATUS;
+ }
+ };
+ job.schedule();
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/OpenProtoDeclarationAction.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/OpenProtoDeclarationAction.java
new file mode 100644
index 0000000..0dd8c35
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/OpenProtoDeclarationAction.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 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.cdt.actions;
+
+import java.util.Collection;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.*;
+
+import com.google.eclipse.protobuf.ui.editor.ModelObjectDefinitionNavigator.Query;
+import com.google.inject.Inject;
+
+/**
+ * Opens the declaration of a C++ element in the corresponding .proto file.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class OpenProtoDeclarationAction implements IEditorActionDelegate {
+ private IEditorPart editor;
+ private ITextSelection selection;
+
+ @Inject private ModelObjectDefinitionQueryBuilder queryBuilder;
+ @Inject private NavigationJobs navigationJobs;
+
+ @Override public void run(IAction action) {
+ if (editor == null || selection == null) {
+ return;
+ }
+ Collection<Query> queries = queryBuilder.buildQueries(editor, selection);
+ if (!queries.isEmpty()) {
+ navigationJobs.scheduleUsing(queries);
+ }
+ }
+
+ @Override public void selectionChanged(IAction action, ISelection selection) {
+ if (selection instanceof ITextSelection) {
+ this.selection = (ITextSelection) selection;
+ return;
+ }
+ this.selection = null;
+ }
+
+ @Override public void setActiveEditor(IAction action, IEditorPart editor) {
+ this.editor = editor;
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ProtoFilePathFinder.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ProtoFilePathFinder.java
new file mode 100644
index 0000000..9ee947e
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ProtoFilePathFinder.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012 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.cdt.actions;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences.compilerPreferences;
+import static org.eclipse.core.runtime.IPath.SEPARATOR;
+import static org.eclipse.xtext.util.Strings.*;
+
+import java.util.List;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
+
+import com.google.eclipse.protobuf.ui.preferences.compiler.core.CompilerPreferences;
+import com.google.inject.Inject;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class ProtoFilePathFinder {
+ private static final String PATH_SEPARATOR = new String(new char[] { SEPARATOR });
+
+ @Inject private IPreferenceStoreAccess storeAccess;
+
+ IPath findProtoFilePath(IEditorPart editor) {
+ IFile file = (IFile) editor.getEditorInput().getAdapter(IFile.class);
+ IPath headerFilePath = file.getFullPath();
+ if (!"h".equals(headerFilePath.getFileExtension())) {
+ return null;
+ }
+ String cppOutputDirectory = cppOutputDirectory(file.getProject());
+ if (isEmpty(cppOutputDirectory)) {
+ return null;
+ }
+ List<String> segments = newArrayList(headerFilePath.segments());
+ for (int i = 0; i < headerFilePath.segmentCount() - 1; i++) {
+ segments.remove(0);
+ if (headerFilePath.segment(i).equals(cppOutputDirectory)) {
+ break;
+ }
+ }
+ String headerFileName = headerFilePath.lastSegment();
+ segments.set(segments.size() - 1, headerFileName.replace("pb.h", "proto"));
+ String protoFilePath = concat(PATH_SEPARATOR, segments);
+ return new Path(protoFilePath);
+ }
+
+ private String cppOutputDirectory(IProject project) {
+ CompilerPreferences preferences = compilerPreferences(storeAccess, project);
+ if (!preferences.compileProtoFiles().getValue() && !preferences.cppCodeGenerationEnabled().getValue()) {
+ return null;
+ }
+ return preferences.cppOutputDirectory().getValue();
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameBuilder.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameBuilder.java
new file mode 100644
index 0000000..2afab3e
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameBuilder.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 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.cdt.actions;
+
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.xtext.naming.QualifiedName;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@SuppressWarnings("restriction")
+interface QualifiedNameBuilder {
+ QualifiedName createQualifiedNameFrom(ASTNode node);
+}
diff --git a/com.google.eclipse.protobuf.ui/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf.ui/META-INF/MANIFEST.MF
index 95017c2..0166022 100644
--- a/com.google.eclipse.protobuf.ui/META-INF/MANIFEST.MF
+++ b/com.google.eclipse.protobuf.ui/META-INF/MANIFEST.MF
@@ -27,5 +27,7 @@
Export-Package: com.google.eclipse.protobuf.ui.contentassist,
com.google.eclipse.protobuf.ui.contentassist.antlr,
com.google.eclipse.protobuf.ui.editor,
+ com.google.eclipse.protobuf.ui.preferences,
+ com.google.eclipse.protobuf.ui.preferences.compiler.core,
com.google.eclipse.protobuf.ui.util
Bundle-Activator: com.google.eclipse.protobuf.ui.internal.ProtobufActivator