Fix broken scoping of provided descriptor.proto
* Fixes bug https://github.com/google/protobuf-dt/issues/4
* Removes changes from https://github.com/google/protobuf-dt/commit/d380a66e5b08981955090ec84d79cc3feb00a21d
Change-Id: I990c17d69686c7e90160cddb741ea9e114da2dd3
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestModule.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestModule.java
index 4668d91..990696b 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestModule.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestModule.java
@@ -10,21 +10,14 @@
import static com.google.eclipse.protobuf.junit.core.GeneratedProtoFiles.protoFile;
import static org.eclipse.xtext.util.Strings.isEmpty;
-
-import com.google.eclipse.protobuf.model.util.Imports;
-import com.google.eclipse.protobuf.preferences.general.PreferenceNames;
-import com.google.eclipse.protobuf.protobuf.Import;
-import com.google.eclipse.protobuf.scoping.IImportResolver;
-import com.google.eclipse.protobuf.scoping.IUriResolver;
-import com.google.inject.Inject;
+import java.io.File;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EReference;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
-import org.mockito.Mockito;
-
-import java.io.File;
+import com.google.eclipse.protobuf.model.util.Imports;
+import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.scoping.IImportResolver;
+import com.google.inject.Inject;
/**
* Guice module for unit testing.
@@ -42,22 +35,6 @@
protected void configure() {
binder().bind(IImportResolver.class).to(ImportResolver.class);
mockAndBind(EReference.class);
- IPreferenceStoreAccess mockStoreAccess = Mockito.mock(IPreferenceStoreAccess.class);
- IUriResolver mockUriResolver = Mockito.mock(IUriResolver.class);
- binder().bind(IPreferenceStoreAccess.class).toInstance(mockStoreAccess);
- // TODO (atrookey) Get rid of the excessive mocking.
- binder().bind(IUriResolver.class).toInstance(mockUriResolver);
- IPreferenceStore mockPreferenceStore = Mockito.mock(IPreferenceStore.class);
- Mockito.when(mockStoreAccess.getWritablePreferenceStore(Mockito.anyObject()))
- .thenReturn(mockPreferenceStore);
- Mockito.when(mockPreferenceStore.getString(PreferenceNames.DESCRIPTOR_PROTO_PATH))
- .thenReturn(PreferenceNames.DEFAULT_DESCRIPTOR_PATH);
- Mockito.when(
- mockUriResolver.resolveUri(
- Mockito.eq(PreferenceNames.DEFAULT_DESCRIPTOR_PATH),
- Mockito.anyObject(),
- Mockito.anyObject()))
- .thenReturn("platform:/plugin/com.google.eclipse.protobuf/descriptor.proto");
}
private static class ImportResolver implements IImportResolver {
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_mapEntryTypeOf_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_mapEntryTypeOf_Test.java
deleted file mode 100644
index 0bdb09f..0000000
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/MessageFields_mapEntryTypeOf_Test.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2015 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.model.util;
-
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.hamcrest.core.IsNull.nullValue;
-import static org.junit.Assert.assertThat;
-import static com.google.eclipse.protobuf.junit.core.UnitTestModule.unitTestModule;
-import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
-
-import org.junit.Rule;
-import org.junit.Test;
-
-import com.google.eclipse.protobuf.junit.core.XtextRule;
-import com.google.eclipse.protobuf.protobuf.MessageField;
-import com.google.inject.Inject;
-
-/**
- * Tests for <code>{@link MessageFields#mapEntryTypeOf(MessageField)}</code>.
- *
- * @author jogl@google.com (John Glassmyer)
- */
-public class MessageFields_mapEntryTypeOf_Test {
- @Rule public XtextRule xtext = overrideRuntimeModuleWith(unitTestModule());
-
- @Inject private MessageFields fields;
-
- // syntax = "proto2";
- //
- // message Person {
- // optional string name = 1;
- // }
- @Test public void should_return_null_for_scalar() {
- MessageField field = xtext.find("name", MessageField.class);
- assertThat(fields.mapEntryTypeOf(field), nullValue());
- }
-
- // syntax = "proto2";
- //
- // message Person {
- // optional string name = 1;
- // optional PhoneNumber number = 2;
- //
- // message PhoneNumber {
- // optional string value = 1;
- // }
- // }
- @Test public void should_return_null_for_message() {
- MessageField field = xtext.find("number", MessageField.class);
- assertThat(fields.mapEntryTypeOf(field), nullValue());
- }
-
- // syntax = "proto2";
- //
- // message Person {
- // optional map<string, PhoneNumber> phone_book = 1;
- //
- // message PhoneNumber {
- // optional string value = 1;
- // }
- // }
- @Test public void should_return_entry_type_for_map() {
- MessageField field = xtext.find("phone_book", MessageField.class);
- assertThat(fields.mapEntryTypeOf(field).getName(), equalTo("MapEntry"));
- }
-}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor_availableOptionsFor_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor_availableOptionsFor_Test.java
deleted file mode 100644
index 4d29754..0000000
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor_availableOptionsFor_Test.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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.scoping;
-
-import static com.google.common.collect.Maps.newHashMap;
-import static com.google.eclipse.protobuf.junit.core.IntegrationTestModule.integrationTestModule;
-import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
-import static com.google.eclipse.protobuf.junit.matchers.FieldHasType.isBool;
-import static com.google.eclipse.protobuf.junit.matchers.FieldHasType.isString;
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.mock;
-
-import com.google.eclipse.protobuf.junit.core.XtextRule;
-import com.google.eclipse.protobuf.protobuf.Import;
-import com.google.eclipse.protobuf.protobuf.Message;
-import com.google.eclipse.protobuf.protobuf.MessageField;
-import com.google.eclipse.protobuf.protobuf.Protobuf;
-import com.google.inject.Inject;
-
-import org.eclipse.emf.ecore.EObject;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * Tests for <code>{@link ProtoDescriptor#availableOptionsFor(EObject)}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class ProtoDescriptor_availableOptionsFor_Test {
- @Rule public XtextRule xtext = overrideRuntimeModuleWith(integrationTestModule());
-
- @Inject private ProtoDescriptorProvider descriptorProvider;
- private Options options;
- private ProtoDescriptor descriptor;
-
- @Before public void setUp() {
- options = new Options();
- descriptor = descriptorProvider.primaryDescriptor(null);
- }
-
- @Test public void should_return_all_file_options() {
- Protobuf optionContainer = mock(Protobuf.class);
- options.mapByName(descriptor.availableOptionsFor(optionContainer));
- assertThat(options.option("java_package"), isString());
- assertThat(options.option("java_outer_classname"), isString());
- assertThat(options.option("java_multiple_files"), isBool());
- assertThat(options.option("java_generate_equals_and_hash"), isBool());
- assertNotNull(options.option("optimize_for"));
- assertThat(options.option("cc_generic_services"), isBool());
- assertThat(options.option("java_generic_services"), isBool());
- assertThat(options.option("py_generic_services"), isBool());
- }
-
- @Test public void should_return_all_message_options() {
- Message optionContainer = mock(Message.class);
- options.mapByName(descriptor.availableOptionsFor(optionContainer));
- assertThat(options.option("message_set_wire_format"), isBool());
- assertThat(options.option("no_standard_descriptor_accessor"), isBool());
- }
-
- @Test public void should_return_all_field_options() {
- MessageField optionContainer = mock(MessageField.class);
- options.mapByName(descriptor.availableOptionsFor(optionContainer));
- assertNotNull(options.option("ctype"));
- assertThat(options.option("packed"), isBool());
- assertThat(options.option("deprecated"), isBool());
- assertThat(options.option("experimental_map_key"), isString());
- }
-
- @Test public void should_return_empty_List_if_given_model_does_not_have_options() {
- Import optionContainer = mock(Import.class);
- Collection<MessageField> foundOptions = descriptor.availableOptionsFor(optionContainer);
- assertThat(foundOptions.size(), equalTo(0));
- }
-
- private static class Options {
- private final Map<String, MessageField> optionsByName = newHashMap();
-
- void mapByName(Collection<MessageField> options) {
- optionsByName.clear();
- for (MessageField option : options) {
- String name = option.getName();
- optionsByName.put(name, option);
- }
- }
-
- MessageField option(String name) {
- return optionsByName.get(name);
- }
- }
-}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor_enumTypeOf_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor_enumTypeOf_Test.java
deleted file mode 100644
index 137f118..0000000
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor_enumTypeOf_Test.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.scoping;
-
-import static com.google.eclipse.protobuf.junit.core.IntegrationTestModule.integrationTestModule;
-import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
-import static com.google.eclipse.protobuf.scoping.OptionType.FILE;
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-
-import com.google.eclipse.protobuf.junit.core.XtextRule;
-import com.google.eclipse.protobuf.protobuf.Enum;
-import com.google.eclipse.protobuf.protobuf.MessageField;
-import com.google.inject.Inject;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-/**
- * Tests for <code>{@link ProtoDescriptor#enumTypeOf(MessageField)}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class ProtoDescriptor_enumTypeOf_Test {
- @Rule public XtextRule xtext = overrideRuntimeModuleWith(integrationTestModule());
-
- @Inject private ProtoDescriptorProvider descriptorProvider;
- private ProtoDescriptor descriptor;
-
- @Before public void setUp() {
- descriptor = descriptorProvider.primaryDescriptor(null);
- }
-
- @Test public void should_return_Enum_if_field_type_is_enum() {
- MessageField option = descriptor.option("optimize_for", FILE);
- Enum anEnum = descriptor.enumTypeOf(option);
- assertThat(anEnum.getName(), equalTo("OptimizeMode"));
- }
-
- @Test public void should_return_null_if_field_is_null() {
- assertNull(descriptor.enumTypeOf(null));
- }
-}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_ComplexTypeLink_target_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_ComplexTypeLink_target_Test.java
index 6b0b1f5..8062b5d 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_ComplexTypeLink_target_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_ComplexTypeLink_target_Test.java
@@ -10,27 +10,25 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.when;
-
import static com.google.eclipse.protobuf.junit.IEObjectDescriptions.descriptionsIn;
import static com.google.eclipse.protobuf.junit.core.IntegrationTestModule.integrationTestModule;
import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
import static com.google.eclipse.protobuf.junit.matchers.ContainAllNames.containAll;
-import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE;
-import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE_LINK;
import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE_LINK__TARGET;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.scoping.IScope;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import com.google.eclipse.protobuf.junit.core.XtextRule;
import com.google.eclipse.protobuf.protobuf.Enum;
+import com.google.eclipse.protobuf.protobuf.MapType;
+import com.google.eclipse.protobuf.protobuf.MapTypeLink;
import com.google.eclipse.protobuf.protobuf.ComplexTypeLink;
import com.google.eclipse.protobuf.protobuf.MessageField;
+import com.google.eclipse.protobuf.protobuf.TypeLink;
import com.google.inject.Inject;
/**
@@ -41,15 +39,8 @@
public class ProtobufScopeProvider_scope_ComplexTypeLink_target_Test {
@Rule public XtextRule xtext = overrideRuntimeModuleWith(integrationTestModule());
- @Inject private EReference reference;
@Inject private ProtobufScopeProvider scopeProvider;
- @Before
- public void setup() {
- when(reference.getEReferenceType()).thenReturn(COMPLEX_TYPE);
- when(reference.getEContainingClass()).thenReturn(COMPLEX_TYPE_LINK);
- }
-
// syntax = "proto2";
// package com.google.proto;
//
@@ -70,7 +61,7 @@
// }
@Test public void should_provide_Types() {
MessageField field = xtext.find("type", MessageField.class);
- IScope scope = scopeProvider.getScope(typeOf(field), reference);
+ IScope scope = scopeProvider.getScope(typeOf(field), COMPLEX_TYPE_LINK__TARGET);
assertThat(descriptionsIn(scope), containAll("Type", "proto.Type", "google.proto.Type",
"com.google.proto.Type", "Address", "proto.Address", "google.proto.Address",
"com.google.proto.Address", "Contact", "proto.Contact", "google.proto.Contact",
@@ -104,7 +95,7 @@
// }
@Test public void should_provide_imported_Types() {
MessageField field = xtext.find("type", " =", MessageField.class);
- IScope scope = scopeProvider.getScope(typeOf(field), reference);
+ IScope scope = scopeProvider.getScope(typeOf(field), COMPLEX_TYPE_LINK__TARGET);
assertThat(descriptionsIn(scope), containAll("test.proto.Type", "test.proto.Address",
"Contact", "proto.Contact", "google.proto.Contact", "com.google.proto.Contact"));
}
@@ -136,7 +127,7 @@
// }
@Test public void should_provide_imported_Types_with_equal_package() {
MessageField field = xtext.find("type", " =", MessageField.class);
- IScope scope = scopeProvider.getScope(typeOf(field), reference);
+ IScope scope = scopeProvider.getScope(typeOf(field), COMPLEX_TYPE_LINK__TARGET);
assertThat(descriptionsIn(scope), containAll("Type", "proto.Type", "google.proto.Type",
"com.google.proto.Type", "Address", "proto.Address", "google.proto.Address",
"com.google.proto.Address", "Contact", "proto.Contact", "google.proto.Contact",
@@ -170,7 +161,7 @@
// }
@Test public void should_provide_public_imported_Types() {
MessageField field = xtext.find("type", " =", MessageField.class);
- IScope scope = scopeProvider.getScope(typeOf(field), reference);
+ IScope scope = scopeProvider.getScope(typeOf(field), COMPLEX_TYPE_LINK__TARGET);
assertThat(descriptionsIn(scope), containAll("test.proto.Type", "test.proto.Address",
"Contact", "proto.Contact", "google.proto.Contact", "com.google.proto.Contact"));
}
@@ -209,7 +200,7 @@
// }
@Test public void should_provide_public_imported_Types_with_more_than_one_level() {
MessageField field = xtext.find("type", " =", MessageField.class);
- IScope scope = scopeProvider.getScope(typeOf(field), reference);
+ IScope scope = scopeProvider.getScope(typeOf(field), COMPLEX_TYPE_LINK__TARGET);
assertThat(descriptionsIn(scope), containAll("test.proto.Type", "test.proto.Address",
"Contact", "proto.Contact", "google.proto.Contact", "com.google.proto.Contact"));
}
@@ -239,11 +230,29 @@
IScope scope = scopeProvider.getScope(field, COMPLEX_TYPE_LINK__TARGET);
Object scopedEnum =
scope
- .getSingleElement(QualifiedName.create("sample", "proto", "foo", "Fruit"))
- .getEObjectOrProxy();
+ .getSingleElement(QualifiedName.create("sample", "proto", "foo", "Fruit"))
+ .getEObjectOrProxy();
assertEquals(expectedEnum, scopedEnum);
}
+ // syntax = "proto2";
+ // package sample.proto.foo;
+ //
+ // message Foo {
+ // map<string, Bar> mapField = 1;
+ // }
+ //
+ // message Bar {}
+ @Test public void should_provide_ComplexType_for_map_value() {
+ MessageField mapField = xtext.find("mapField", " =", MessageField.class);
+ MapType mapType = ((MapTypeLink) mapField.getType()).getTarget();
+ TypeLink valueType = mapType.getValueType();
+ IScope scope = scopeProvider.getScope(valueType, COMPLEX_TYPE_LINK__TARGET);
+ assertThat(descriptionsIn(scope), containAll("Foo", "proto.foo.Foo", "foo.Foo",
+ "Bar", "proto.foo.Bar", "foo.Bar", "sample.proto.foo.Foo",
+ "sample.proto.foo.Bar"));
+ }
+
private static ComplexTypeLink typeOf(MessageField field) {
return (ComplexTypeLink) field.getType();
}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
index 9f87e74..0deeb76 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
@@ -8,9 +8,7 @@
*/
package com.google.eclipse.protobuf.ui.contentassist;
-import static com.google.common.collect.Lists.newArrayList;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.CLOSING_BRACKET;
-import static com.google.eclipse.protobuf.grammar.CommonKeyword.DEFAULT;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.EQUAL;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.FALSE;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.NAN;
@@ -19,12 +17,8 @@
import static com.google.eclipse.protobuf.grammar.CommonKeyword.SYNTAX;
import static com.google.eclipse.protobuf.grammar.CommonKeyword.TRUE;
import static com.google.eclipse.protobuf.protobuf.ModifierEnum.OPTIONAL;
-import static com.google.eclipse.protobuf.protobuf.ModifierEnum.REPEATED;
import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.LITERAL;
-import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.OPTION;
-import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.DEFAULT_EQUAL;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.DEFAULT_EQUAL_IN_BRACKETS;
-import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.DEFAULT_EQUAL_STRING;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.DEFAULT_EQUAL_STRING_IN_BRACKETS;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.EMPTY_STRING;
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.EQUAL_PROTO2_IN_QUOTES;
@@ -33,7 +27,6 @@
import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.PROTO3_IN_QUOTES;
import static com.google.eclipse.protobuf.util.CommonWords.space;
import static java.lang.String.valueOf;
-import static java.util.Collections.emptyList;
import static org.eclipse.xtext.EcoreUtil2.getAllContentsOfType;
import static org.eclipse.xtext.util.Strings.toFirstLower;
@@ -49,20 +42,14 @@
import com.google.eclipse.protobuf.protobuf.DefaultValueFieldOption;
import com.google.eclipse.protobuf.protobuf.Enum;
import com.google.eclipse.protobuf.protobuf.FieldName;
-import com.google.eclipse.protobuf.protobuf.FieldOption;
import com.google.eclipse.protobuf.protobuf.IndexedElement;
import com.google.eclipse.protobuf.protobuf.Literal;
import com.google.eclipse.protobuf.protobuf.MessageField;
import com.google.eclipse.protobuf.protobuf.ModifierEnum;
-import com.google.eclipse.protobuf.protobuf.NativeFieldOption;
-import com.google.eclipse.protobuf.protobuf.NativeOption;
import com.google.eclipse.protobuf.protobuf.Option;
import com.google.eclipse.protobuf.protobuf.SimpleValueField;
-import com.google.eclipse.protobuf.scoping.ProtoDescriptor;
-import com.google.eclipse.protobuf.scoping.ProtoDescriptorProvider;
import com.google.eclipse.protobuf.ui.grammar.CompoundElement;
import com.google.eclipse.protobuf.ui.labeling.Images;
-import com.google.eclipse.protobuf.util.EResources;
import com.google.inject.Inject;
import org.eclipse.emf.ecore.EObject;
@@ -78,9 +65,6 @@
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext;
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor;
-import java.util.Collection;
-import java.util.List;
-
/**
* @author alruiz@google.com (Alex Ruiz)
@@ -88,7 +72,6 @@
* @see <a href="http://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#content-assist">Xtext Content Assist</a>
*/
public class ProtobufProposalProvider extends AbstractProtobufProposalProvider {
- @Inject private ProtoDescriptorProvider descriptorProvider;
@Inject private Images images;
@Inject private IndexedElements indexedElements;
@Inject private PluginImageHelper imageHelper;
@@ -114,40 +97,6 @@
proposeAndAccept(proposal, imageHelper.getImage(images.imageFor(SYNTAX)), context, acceptor);
}
- @Override public void completeNativeOption_Source(EObject model, Assignment assignment,
- ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
- ProtoDescriptor descriptor =
- descriptorProvider.primaryDescriptor(EResources.getProjectOf(model.eResource()));
- Collection<MessageField> optionProperties = descriptor.availableOptionsFor(model);
- if (!optionProperties.isEmpty()) {
- proposeOptions(optionProperties, context, acceptor);
- }
- }
-
- private void proposeOptions(Collection<MessageField> optionSources, ContentAssistContext context,
- ICompletionProposalAcceptor acceptor) {
- for (MessageField source : optionSources) {
- proposeOption(source, context, acceptor);
- }
- }
-
- @Override public void completeNativeOption_Value(EObject model, Assignment assignment,
- ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
- NativeOption option = (NativeOption) model;
- MessageField optionSource = (MessageField) options.rootSourceOf(option);
- if (optionSource == null) {
- return;
- }
- ProtoDescriptor descriptor =
- descriptorProvider.primaryDescriptor(EResources.getProjectOf(model.eResource()));
- Enum enumType = descriptor.enumTypeOf(optionSource);
- if (enumType != null) {
- proposeAndAccept(enumType, context, acceptor);
- return;
- }
- proposePrimitiveValues(optionSource, context, acceptor);
- }
-
@Override public void complete_ID(EObject model, RuleCall ruleCall, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {}
@@ -356,93 +305,6 @@
return imageHelper.getImage(images.defaultImage());
}
- @Override public void completeNativeFieldOption_Source(EObject model, Assignment assignment,
- ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
- MessageField field = extractElementFromContext(context, MessageField.class);
- if (field != null) {
- proposeNativeOptions(field, context, acceptor);
- }
- }
-
- private void proposeNativeOptions(MessageField field, ContentAssistContext context,
- ICompletionProposalAcceptor acceptor) {
- List<String> optionNames = existingFieldOptionNames(field);
- proposeDefaultKeyword(field, optionNames, context, acceptor);
- ProtoDescriptor descriptor =
- descriptorProvider.primaryDescriptor(EResources.getProjectOf(context.getResource()));
- for (MessageField optionSource : descriptor.availableOptionsFor(field)) {
- String optionName = optionSource.getName();
- if (optionNames.contains(optionName) || ("packed".equals(optionName) && !canBePacked(field))) {
- continue;
- }
- proposeOption(optionSource, context, acceptor);
- }
- }
-
- private List<String> existingFieldOptionNames(IndexedElement e) {
- List<FieldOption> allFieldOptions = indexedElements.fieldOptionsOf(e);
- if (allFieldOptions.isEmpty()) {
- return emptyList();
- }
- List<String> optionNames = newArrayList();
- for (FieldOption option : allFieldOptions) {
- optionNames.add(options.nameOf(option));
- }
- return optionNames;
- }
-
- private void proposeDefaultKeyword(IndexedElement e, List<String> existingOptionNames, ContentAssistContext context,
- ICompletionProposalAcceptor acceptor) {
- if (e instanceof MessageField) {
- MessageField field = (MessageField) e;
- if (!messageFields.isOptional(field) || existingOptionNames.contains(DEFAULT.toString())) {
- return;
- }
- CompoundElement display = DEFAULT_EQUAL;
- int cursorPosition = display.charCount();
- if (messageFields.isString(field)) {
- display = DEFAULT_EQUAL_STRING;
- cursorPosition++;
- }
- createAndAccept(display, cursorPosition, context, acceptor);
- }
- }
-
- private boolean canBePacked(IndexedElement e) {
- if (e instanceof MessageField) {
- MessageField field = (MessageField) e;
- return messageFields.isPrimitive(field) && REPEATED.equals(field.getModifier());
- }
- return false;
- }
-
- private void proposeOption(MessageField optionSource, ContentAssistContext context,
- ICompletionProposalAcceptor acceptor) {
- String displayString = optionSource.getName();
- String proposalText = displayString + space() + EQUAL + space();
- Object value = defaultValueOf(optionSource);
- if (value != null) {
- proposalText = proposalText + value;
- }
- ICompletionProposal proposal = createCompletionProposal(proposalText, displayString, imageForOption(), context);
- if (value == EMPTY_STRING && proposal instanceof ConfigurableCompletionProposal) {
- // set cursor between the proposal's quotes
- ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal;
- configurable.setCursorPosition(proposalText.length() - 1);
- }
- acceptor.accept(proposal);
- }
-
- private Object defaultValueOf(MessageField field) {
- if (messageFields.isBool(field)) {
- return TRUE;
- }
- if (messageFields.isString(field)) {
- return EMPTY_STRING;
- }
- return null;
- }
-
@Override public void completeDefaultValueFieldOption_Value(EObject model, Assignment assignment,
ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
MessageField field = null;
@@ -458,22 +320,6 @@
proposeFieldValue(field, context, acceptor);
}
- @Override public void completeNativeFieldOption_Value(EObject model, Assignment assignment,
- ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
- if (model instanceof NativeFieldOption) {
- NativeFieldOption option = (NativeFieldOption) model;
- ProtoDescriptor descriptor =
- descriptorProvider.primaryDescriptor(EResources.getProjectOf(context.getResource()));
- MessageField field = (MessageField) options.rootSourceOf(option);
- Enum enumType = descriptor.enumTypeOf(field);
- if (enumType != null) {
- proposeAndAccept(enumType, context, acceptor);
- return;
- }
- proposePrimitiveValues(field, context, acceptor);
- }
- }
-
private boolean proposePrimitiveValues(MessageField field, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
if (messageFields.isBool(field)) {
@@ -513,10 +359,6 @@
acceptor.accept(proposal);
}
- private Image imageForOption() {
- return imageHelper.getImage(images.imageFor(OPTION));
- }
-
@Override public void completeOptionSource_Target(EObject model, Assignment assignment,
ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
}
diff --git a/com.google.eclipse.protobuf/build.properties b/com.google.eclipse.protobuf/build.properties
index a06b6f0..df8424a 100644
--- a/com.google.eclipse.protobuf/build.properties
+++ b/com.google.eclipse.protobuf/build.properties
@@ -5,6 +5,5 @@
plugin.xml,\
OSGI-INF/,\
descriptor.proto,\
- map_entry.proto,\
schema/descriptor-source.exsd,\
model/
diff --git a/com.google.eclipse.protobuf/map_entry.proto b/com.google.eclipse.protobuf/map_entry.proto
deleted file mode 100644
index 64ef6a5..0000000
--- a/com.google.eclipse.protobuf/map_entry.proto
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2015 Google Inc. All rights reserved.
-syntax = "proto2";
-
-package google.protobuf;
-
-// An entry in a map field.
-//
-// Specified here as if the defining map field were "map<string, string>" as a temporary hack
-// until protobuf-dt is able to synthesize entry types for map fields with arbitary value types.
-// This avoids "Couldn't resolve" errors on "key" and "value" fields and enables completion of them.
-message MapEntry {
- // The key of an entry in a map field.
- //
- // Specified here as "string" due to technical limitations in protobuf-dt. The actual type of
- // this key field is specified by the defining map field.
- optional string key = 1;
-
- // The value of an entry in a map field.
- //
- // Specified here as "string" due to technical limitations in protobuf-dt. The actual type of
- // this value field is specified by the defining map field.
- optional string value = 2;
-}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/MessageFields.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/MessageFields.java
index 1107a3d..e882b82 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/MessageFields.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/MessageFields.java
@@ -37,8 +37,6 @@
import com.google.eclipse.protobuf.protobuf.ScalarType;
import com.google.eclipse.protobuf.protobuf.ScalarTypeLink;
import com.google.eclipse.protobuf.protobuf.TypeLink;
-import com.google.eclipse.protobuf.scoping.ProtoDescriptorProvider;
-import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
@@ -46,11 +44,12 @@
*
* @author alruiz@google.com (Alex Ruiz)
*/
-@Singleton public class MessageFields {
- @Inject private ProtoDescriptorProvider descriptorProvider;
-
+@Singleton
+public class MessageFields {
/**
- * Indicates whether the modifier of the given field is <code>{@link ModifierEnum#OPTIONAL}</code>.
+ * Indicates whether the modifier of the given field is <code>{@link
+ * ModifierEnum#OPTIONAL}</code>.
+ *
* @param field the given field.
* @return {@code true} if the modifier of the given field is "optional," {@code false} otherwise.
*/
@@ -59,9 +58,11 @@
}
/**
- * Indicates whether the type of the given field is primitive. Primitive types include: {@code double}, {@code float},
- * {@code int32}, {@code int64}, {@code uint32}, {@code uint64}, {@code sint32}, {@code sint64}, {@code fixed32},
- * {@code fixed64}, {@code sfixed32}, {@code sfixed64} and {@code bool}.
+ * Indicates whether the type of the given field is primitive. Primitive types include: {@code
+ * double}, {@code float}, {@code int32}, {@code int64}, {@code uint32}, {@code uint64}, {@code
+ * sint32}, {@code sint64}, {@code fixed32}, {@code fixed64}, {@code sfixed32}, {@code sfixed64}
+ * and {@code bool}.
+ *
* @param field the given field.
* @return {@code true} if the type of the given field is primitive, {@code false} otherwise.
*/
@@ -76,6 +77,7 @@
/**
* Indicates whether the given field is of type {@code bool}.
+ *
* @param field the given field.
* @return {@code true} if the given field is of type {@code bool}, {@code false} otherwise.
*/
@@ -85,6 +87,7 @@
/**
* Indicates whether the given field is of type {@code bytes}.
+ *
* @param field the given field.
* @return {@code true} if the given field is of type {@code bytes}, {@code false} otherwise.
*/
@@ -94,6 +97,7 @@
/**
* Indicates whether the given field is of type {@code float} or {@code double}.
+ *
* @param field the given field.
* @return {@code true} if the given field is a floating point number, {@code false} otherwise.
*/
@@ -102,17 +106,21 @@
}
/**
- * Indicates whether the given field is of type {@code fixed32}, {@code fixed64}, {@code int32}, {@code int64},
- * {@code sfixed32}, {@code sfixed64}, {@code sint32}, {@code sint64}, {@code uint32} or {@code uint64}.
+ * Indicates whether the given field is of type {@code fixed32}, {@code fixed64}, {@code int32},
+ * {@code int64}, {@code sfixed32}, {@code sfixed64}, {@code sint32}, {@code sint64}, {@code
+ * uint32} or {@code uint64}.
+ *
* @param field the given field.
* @return {@code true} if the given field is an integer, {@code false} otherwise.
*/
public boolean isInteger(MessageField field) {
- return isScalarType(field, FIXED32, FIXED64, INT32, INT64, SFIXED32, SFIXED64, SINT32, SINT64, UINT32, UINT64);
+ return isScalarType(
+ field, FIXED32, FIXED64, INT32, INT64, SFIXED32, SFIXED64, SINT32, SINT64, UINT32, UINT64);
}
/**
* Indicates whether the given field is of type {@code string}.
+ *
* @param field the given field.
* @return {@code true} if the given field is of type {@code string}, {@code false} otherwise.
*/
@@ -121,7 +129,9 @@
}
/**
- * Indicates whether the given field is of type {@code fixed32}, {@code fixed64}, {@code uint32} or {@code uint64}.
+ * Indicates whether the given field is of type {@code fixed32}, {@code fixed64}, {@code uint32}
+ * or {@code uint64}.
+ *
* @param field the given field.
* @return {@code true} if the given field is an unsigned integer, {@code false} otherwise.
*/
@@ -144,6 +154,7 @@
/**
* Returns the name of the type of the given field.
+ *
* @param field the given field.
* @return the name of the type of the given field.
*/
@@ -173,8 +184,10 @@
/**
* Returns the message type of the given field, only if the type of the given field is a message.
+ *
* @param field the given field.
- * @return the message type of the given field or {@code null} if the type of the given field is not message.
+ * @return the message type of the given field or {@code null} if the type of the given field is
+ * not message.
*/
public Message messageTypeOf(MessageField field) {
ComplexType fieldType = complexTypeOf(field.getType());
@@ -183,8 +196,10 @@
/**
* Returns the enum type of the given field, only if the type of the given field is an enum.
+ *
* @param field the given field.
- * @return the enum type of the given field or {@code null} if the type of the given field is not enum.
+ * @return the enum type of the given field or {@code null} if the type of the given field is not
+ * enum.
*/
public Enum enumTypeOf(MessageField field) {
ComplexType fieldType = complexTypeOf(field.getType());
@@ -197,8 +212,10 @@
/**
* Returns the scalar type of the given field, only if the type of the given field is a scalar.
+ *
* @param field the given field.
- * @return the scalar type of the given field or {@code null} if the type of the given field is not a scalar.
+ * @return the scalar type of the given field or {@code null} if the type of the given field is
+ * not a scalar.
*/
public ScalarType scalarTypeOf(MessageField field) {
return scalarTypeOf(field.getType());
@@ -211,15 +228,4 @@
private MapType mapTypeOf(TypeLink typeLink) {
return typeLink instanceof MapTypeLink ? ((MapTypeLink) typeLink).getTarget() : null;
}
-
- /**
- * Returns a Message representing an entry in a map of the given field's type, or null if the
- * given field is not of map type.
- */
- public Message mapEntryTypeOf(MessageField field) {
- // TODO(jogl): Dynamically create and return a message type with key and value fields matching
- // the key and value types of the target MapType.
- return field.getType() instanceof MapTypeLink
- ? (Message) descriptorProvider.mapEntryDescriptor().allTypes().get(0) : null;
- }
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/preferences/general/GeneralPreferences.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/preferences/general/GeneralPreferences.java
index bfabcd4..d7f7f20 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/preferences/general/GeneralPreferences.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/preferences/general/GeneralPreferences.java
@@ -15,19 +15,16 @@
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
+/** @author alruiz@google.com (Alex Ruiz) */
public class GeneralPreferences {
private final IPreferenceStore store;
public GeneralPreferences(IPreferenceStoreAccess storeAccess, IProject project) {
IPreferenceStore preferenceStore = storeAccess.getWritablePreferenceStore(project);
- boolean enableProjectSettings =
- preferenceStore.getBoolean(ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME);
- if (!enableProjectSettings) {
+ if (!preferenceStore.getBoolean(ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME)) {
preferenceStore = storeAccess.getWritablePreferenceStore();
}
this.store = preferenceStore;
@@ -41,6 +38,10 @@
return store.getString(PreferenceNames.DESCRIPTOR_PROTO_PATH);
}
+ public void addPropertyChangeListener(IPropertyChangeListener listener) {
+ store.addPropertyChangeListener(listener);
+ }
+
public static class Initializer extends DefaultPreservingInitializer {
@Override
public void setDefaults() {
@@ -49,4 +50,4 @@
setDefault(PreferenceNames.DESCRIPTOR_PROTO_PATH, PreferenceNames.DEFAULT_DESCRIPTOR_PATH);
}
}
-}
\ No newline at end of file
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/preferences/general/PreferenceNames.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/preferences/general/PreferenceNames.java
index 0d75034..7598f6e 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/preferences/general/PreferenceNames.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/preferences/general/PreferenceNames.java
@@ -8,14 +8,27 @@
*/
package com.google.eclipse.protobuf.preferences.general;
-/**
- * Preference names for descriptor proto preferences.
- */
+/** Preference names for descriptor proto preferences. */
public final class PreferenceNames {
+ /**
+ * Default value for the preference {@literal general.descriptorPath}.
+ */
public static final String DEFAULT_DESCRIPTOR_PATH = "google/protobuf/descriptor.proto";
+
+ /**
+ * Preference storing the import path of the options definition file.
+ */
public static final String DESCRIPTOR_PROTO_PATH = "general.descriptorPath";
+
+ /**
+ * Preference determining whether the project specific settings for the are enabled.
+ */
public static final String ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME =
"general.enableProjectSettings";
+
+ /**
+ * Preference determining whether protocol buffer files are validated on activation.
+ */
public static final String VALIDATE_FILES_ON_ACTIVATION = "general.validateFilesOnActivation";
private PreferenceNames() {}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
index 2d773c9..140c530 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
@@ -10,7 +10,6 @@
import static com.google.common.collect.Maps.newHashMap;
-import com.google.eclipse.protobuf.protobuf.AbstractOption;
import com.google.eclipse.protobuf.protobuf.Enum;
import com.google.eclipse.protobuf.protobuf.IndexedElement;
import com.google.eclipse.protobuf.protobuf.Literal;
@@ -23,14 +22,22 @@
import java.util.Map;
import java.util.Map.Entry;
+import org.eclipse.emf.ecore.EObject;
+
/**
* Types of options (by location.)
*
* @author alruiz@google.com (Alex Ruiz)
*/
enum OptionType {
- FILE("FileOptions"), MESSAGE("MessageOptions"), FIELD("FieldOptions"), ENUM("EnumOptions"),
- LITERAL("EnumValueOptions"), SERVICE("ServiceOptions"), RPC("MethodOptions"), STREAM("StreamOptions");
+ FILE("FileOptions"),
+ MESSAGE("MessageOptions"),
+ FIELD("FieldOptions"),
+ ENUM("EnumOptions"),
+ LITERAL("EnumValueOptions"),
+ SERVICE("ServiceOptions"),
+ RPC("MethodOptions"),
+ STREAM("StreamOptions");
private static final Map<Class<?>, OptionType> OPTION_TYPES_BY_CONTAINER = newHashMap();
@@ -54,6 +61,7 @@
/**
* Returns the name of the message in descriptor.proto that specifies the type of an option.
+ *
* @return the name of the message in descriptor.proto that specifies the type of an option.
*/
String messageName() {
@@ -62,20 +70,20 @@
/**
* Returns the type of the given option.
- * @param option the given option.
+ *
+ * @param container the {@code OptionSource}, {@code Option}, or container of an {@code Option}.
* @return the type of the given option or {@code null} if a type cannot be found.
*/
- static OptionType typeOf(AbstractOption option) {
- return findOptionTypeForLevelOf(option.eContainer());
- }
-
- static OptionType findOptionTypeForLevelOf(Object container) {
- for (Entry<Class<?>, OptionType> optionTypeByContainer : OPTION_TYPES_BY_CONTAINER.entrySet()) {
- if (optionTypeByContainer.getKey().isInstance(container)) {
- return optionTypeByContainer.getValue();
+ static OptionType typeOf(EObject container) {
+ if (container != null) {
+ for (Entry<Class<?>, OptionType> optionTypeByContainer :
+ OPTION_TYPES_BY_CONTAINER.entrySet()) {
+ if (optionTypeByContainer.getKey().isInstance(container)) {
+ return optionTypeByContainer.getValue();
+ }
}
+ return typeOf(container.eContainer());
}
-
return null;
}
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java
deleted file mode 100644
index e1906e7..0000000
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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.scoping;
-
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.MESSAGE_FIELD__TYPE;
-import static com.google.eclipse.protobuf.scoping.OptionType.findOptionTypeForLevelOf;
-import static com.google.eclipse.protobuf.util.Encodings.UTF_8;
-import static java.util.Collections.emptyList;
-import static java.util.Collections.unmodifiableCollection;
-import static java.util.Collections.unmodifiableList;
-import static org.eclipse.xtext.EcoreUtil2.getAllContentsOfType;
-import static org.eclipse.xtext.EcoreUtil2.resolveLazyCrossReferences;
-import static org.eclipse.xtext.util.CancelIndicator.NullImpl;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.eclipse.protobuf.model.util.INodes;
-import com.google.eclipse.protobuf.protobuf.ComplexType;
-import com.google.eclipse.protobuf.protobuf.Enum;
-import com.google.eclipse.protobuf.protobuf.Message;
-import com.google.eclipse.protobuf.protobuf.MessageElement;
-import com.google.eclipse.protobuf.protobuf.MessageField;
-import com.google.eclipse.protobuf.protobuf.NativeOption;
-import com.google.eclipse.protobuf.protobuf.Protobuf;
-
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.nodemodel.INode;
-import org.eclipse.xtext.parser.IParseResult;
-import org.eclipse.xtext.parser.IParser;
-import org.eclipse.xtext.resource.XtextResource;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Contains the elements from descriptor.proto (provided with protobuf's library.)
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class ProtoDescriptor {
- private static final Map<String, OptionType> OPTION_DEFINITION_BY_NAME = new HashMap<>();
-
- static {
- populateMap();
- }
-
- private static void populateMap() {
- for (OptionType type : OptionType.values()) {
- OPTION_DEFINITION_BY_NAME.put(type.messageName(), type);
- }
- }
-
- private final List<ComplexType> allTypes = new ArrayList<>();
- private final Map<OptionType, Map<String, MessageField>> optionsByType = new HashMap<>();
- private final Map<String, Enum> enumsByName = new HashMap<>();
-
- private Protobuf root;
-
- private final String importUri;
- private final INodes nodes;
- private final XtextResource resource;
-
- ProtoDescriptor(String importUri, URI location, IParser parser, INodes nodes) {
- this.importUri = importUri;
- this.nodes = nodes;
- addOptionTypes();
- resource = new XtextResource(location);
- try (InputStreamReader reader = new InputStreamReader(contents(location), UTF_8)) {
- IParseResult result = parser.parse(reader);
- root = (Protobuf) result.getRootASTElement();
- resource.getContents().add(root);
- resolveLazyCrossReferences(resource, NullImpl);
- initContents();
- } catch (Throwable t) {
- throw new IllegalStateException("Unable to parse descriptor.proto", t);
- }
- }
-
- /**
- * Returns the contents of the descriptor file at the given location.
- * @param descriptorLocation the location of the descriptor file.
- * @return the contents of the descriptor file.
- * @throws IOException if something goes wrong.
- */
- protected InputStream contents(URI descriptorLocation) throws IOException {
- URL url = new URL(descriptorLocation.toString());
- return url.openConnection().getInputStream();
- }
-
- private void addOptionTypes() {
- for (OptionType type : OptionType.values()) {
- optionsByType.put(type, new LinkedHashMap<String, MessageField>());
- }
- }
-
- private void initContents() {
- allTypes.addAll(getAllContentsOfType(root, ComplexType.class));
- for (ComplexType t : allTypes) {
- if (!(t instanceof Message)) {
- continue;
- }
- Message m = (Message) t;
- OptionType type = OPTION_DEFINITION_BY_NAME.get(m.getName());
- if (type == null) {
- continue;
- }
- initOptions(m, type);
- }
- }
-
- private void initOptions(Message optionGroup, OptionType type) {
- for (MessageElement e : optionGroup.getElements()) {
- if (e instanceof MessageField) {
- addOption((MessageField) e, type);
- continue;
- }
- if (e instanceof Enum) {
- Enum anEnum = (Enum) e;
- String name = anEnum.getName();
- enumsByName.put(name, anEnum);
- }
- }
- }
-
- private void addOption(MessageField optionSource, OptionType type) {
- if (shouldIgnore(optionSource)) {
- return;
- }
- String name = optionSource.getName();
- optionsByType.get(type).put(name, optionSource);
- }
-
- private boolean shouldIgnore(MessageField field) {
- return "uninterpreted_option".equals(field.getName());
- }
-
- /**
- * Returns the options available for the given option or option container. The returned options are defined in
- * {@code google/protobuf/descriptor.proto} (more details can be found <a
- * href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
- * @param o the given option or option container.
- * @return the options available for the given option or option container, or an empty collection if the are not any
- * options available.
- */
- public Collection<MessageField> availableOptionsFor(EObject o) {
- EObject target = o;
- if (target instanceof NativeOption) {
- target = target.eContainer();
- }
- OptionType type = findOptionTypeForLevelOf(target);
- if (type == null) {
- return emptyList();
- }
- return optionsOfType(type);
- }
-
- @VisibleForTesting Collection<MessageField> optionsOfType(OptionType type) {
- return unmodifiableCollection(optionsByType.get(type).values());
- }
-
- /**
- * Returns the enum type of the given field, only if the given field is defined in
- * {@code google/protobuf/descriptor.proto} and its type is enum (more details can be found <a
- * href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
- * @param field the given field.
- * @return the enum type of the given field or {@code null} if the type of the given field is not enum.
- */
- public Enum enumTypeOf(MessageField field) {
- if (field == null) {
- return null;
- }
- INode node = nodes.firstNodeForFeature(field, MESSAGE_FIELD__TYPE);
- if (node == null) {
- return null;
- }
- String typeName = node.getText();
- return (isNullOrEmpty(typeName)) ? null : enumByName(typeName.trim());
- }
-
- @VisibleForTesting Enum enumByName(String qualifiedName) {
- String[] segments = qualifiedName.split("\\.");
- if (segments == null || segments.length == 0) {
- return null;
- }
- return enumsByName.get(segments[segments.length - 1]);
- }
-
- /**
- * Returns all types in descriptor.proto.
- * @return all types in descriptor.proto.
- */
- public List<ComplexType> allTypes() {
- return unmodifiableList(allTypes);
- }
-
- public XtextResource resource() {
- return resource;
- }
-
- /**
- * Returns the URI to use when importing descriptor.proto.
- * @return the URI to use when importing descriptor.proto.
- */
- public String importUri() {
- return importUri;
- }
-
- @VisibleForTesting MessageField option(String name, OptionType type) {
- Map<String, MessageField> optionByName = optionsByType.get(type);
- return (optionByName != null) ? optionByName.get(name) : null;
- }
-}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java
index 68b8989..66d8981 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java
@@ -9,25 +9,7 @@
package com.google.eclipse.protobuf.scoping;
import static com.google.eclipse.protobuf.preferences.general.PreferenceNames.DESCRIPTOR_PROTO_PATH;
-
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableList;
-import com.google.eclipse.protobuf.model.util.INodes;
-import com.google.eclipse.protobuf.preferences.general.GeneralPreferences;
-import com.google.eclipse.protobuf.preferences.general.PreferenceNames;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtensionRegistry;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.jface.util.IPropertyChangeListener;
-import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.xtext.parser.IParser;
-import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
+import static com.google.eclipse.protobuf.preferences.general.PreferenceNames.ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -36,68 +18,98 @@
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableList;
+import com.google.eclipse.protobuf.preferences.general.GeneralPreferences;
+import com.google.eclipse.protobuf.preferences.general.PreferenceNames;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
/**
* Provider of <code>{@link ProtoDescriptor}</code>s.
*
* @author Alex Ruiz
*/
-@Singleton public class ProtoDescriptorProvider {
- private static final String EXTENSION_ID = "com.google.eclipse.protobuf.descriptorSource";
+@Singleton
+public class ProtoDescriptorProvider {
+ public class ProtoDescriptorInfo {
+ final String importUri;
+ final URI location;
- private final IPreferenceStoreAccess storeAccess;
- private final IExtensionRegistry registry;
- private final IParser parser;
- private final INodes nodes;
- private final IUriResolver resolver;
+ ProtoDescriptorInfo(String importUri, URI location) {
+ this.importUri = importUri;
+ this.location = location;
+ }
+ }
private static final URI DEFAULT_DESCRIPTOR_LOCATION =
URI.createURI("platform:/plugin/com.google.eclipse.protobuf/descriptor.proto");
- private final ProtoDescriptorInfo openSourceProtoDescriptorInfo;
- private final ProtoDescriptorInfo extensionPointDescriptorInfo;
-
- private static final String MAP_ENTRY_DESCRIPTOR_PATH = "google/protobuf/map_entry.proto";
- private static final URI MAP_ENTRY_DESCRIPTOR_LOCATION =
- URI.createURI("platform:/plugin/com.google.eclipse.protobuf/map_entry.proto");;
- private final ProtoDescriptorInfo mapEntryDescriptorInfo;
-
+ private static final String EXTENSION_ID = "com.google.eclipse.protobuf.descriptorSource";
private static final Logger LOG =
Logger.getLogger(ProtoDescriptorProvider.class.getCanonicalName());
- private final
- LoadingCache<IProject, Map<String, ProtoDescriptorInfo>> descriptorCache = CacheBuilder
- .newBuilder().build(new CacheLoader<IProject, Map<String, ProtoDescriptorInfo>>() {
- @Override
- public Map<String, ProtoDescriptorInfo> load(final IProject project) {
- return loadDescriptorInfos(project);
- }
- });
+ private static URI descriptorLocation(IConfigurationElement e) {
+ String path = e.getAttribute("path");
+ if (path.isEmpty()) {
+ return null;
+ }
+ StringBuilder uri = new StringBuilder();
+ uri.append("platform:/plugin/").append(e.getContributor().getName()).append("/").append(path);
+ return URI.createURI(uri.toString());
+ }
+
+ private final LoadingCache<IProject, Map<String, ProtoDescriptorInfo>> descriptorCache =
+ CacheBuilder.newBuilder()
+ .build(
+ new CacheLoader<IProject, Map<String, ProtoDescriptorInfo>>() {
+ @Override
+ public Map<String, ProtoDescriptorInfo> load(final IProject project) {
+ return loadDescriptorInfos(project);
+ }
+ });
+
+ private final ProtoDescriptorInfo extensionPointDescriptorInfo;
+ private final ProtoDescriptorInfo openSourceProtoDescriptorInfo;
+ private final IExtensionRegistry registry;
+
+ private final IUriResolver resolver;
+
+ private final IPreferenceStoreAccess storeAccess;
@Inject
- ProtoDescriptorProvider(IPreferenceStoreAccess storeAccess, IExtensionRegistry registry,
- IParser parser, INodes nodes, IUriResolver resolver) {
+ ProtoDescriptorProvider(
+ IPreferenceStoreAccess storeAccess, IExtensionRegistry registry, IUriResolver resolver) {
this.storeAccess = storeAccess;
this.registry = registry;
- this.parser = parser;
- this.nodes = nodes;
this.resolver = resolver;
this.openSourceProtoDescriptorInfo = getOpenSourceProtoDescriptorInfo();
- this.mapEntryDescriptorInfo = getMapEntryDescriptorInfo();
this.extensionPointDescriptorInfo = getExtensionPointDescriptorInfo();
}
- public ProtoDescriptor primaryDescriptor(IProject project) {
+ public ImmutableList<URI> allDescriptorLocations(IProject project) {
Map<String, ProtoDescriptorInfo> descriptorInfos = getDescriptorInfosFor(project);
+ ImmutableList.Builder<URI> descriptorLocations = ImmutableList.builder();
for (ProtoDescriptorInfo descriptorInfo : descriptorInfos.values()) {
- return descriptorInfo.protoDescriptor;
+ descriptorLocations.add(descriptorInfo.location);
}
- return openSourceProtoDescriptorInfo.protoDescriptor;
+ return descriptorLocations.build();
}
- public ProtoDescriptor descriptor(IProject project, String importUri) {
+ public ProtoDescriptorInfo descriptor(IProject project, String importUri) {
Map<String, ProtoDescriptorInfo> descriptorInfos = getDescriptorInfosFor(project);
ProtoDescriptorInfo descriptorInfo = descriptorInfos.get(importUri);
if (descriptorInfo != null) {
- return descriptorInfo.protoDescriptor;
+ return descriptorInfo;
}
URI uri = URI.createURI(importUri);
for (Entry<String, ProtoDescriptorInfo> info : descriptorInfos.entrySet()) {
@@ -108,13 +120,24 @@
return null;
}
- public ImmutableList<URI> allDescriptorLocations(IProject project) {
- Map<String, ProtoDescriptorInfo> descriptorInfos = getDescriptorInfosFor(project);
- ImmutableList.Builder<URI> descriptorLocations = ImmutableList.builder();
- for (ProtoDescriptorInfo descriptorInfo : descriptorInfos.values()) {
- descriptorLocations.add(descriptorInfo.location);
+ private ProtoDescriptorInfo descriptorInfo(IConfigurationElement e) {
+ String importUri = e.getAttribute("importUri");
+ if (importUri.isEmpty()) {
+ return null;
}
- return descriptorLocations.build();
+ URI location = descriptorLocation(e);
+ if (location == null) {
+ return null;
+ }
+ try {
+ return new ProtoDescriptorInfo(importUri, location);
+ } catch (IllegalStateException exception) {
+ LOG.log(
+ Level.WARNING,
+ "Error when initializing descriptor proto from extension point",
+ exception);
+ return null;
+ }
}
public URI descriptorLocation(IProject project, String importUri) {
@@ -127,63 +150,9 @@
return null;
}
- public ProtoDescriptor mapEntryDescriptor() {
- return mapEntryDescriptorInfo.protoDescriptor;
- }
-
- private Map<String, ProtoDescriptorInfo> loadDescriptorInfos(final IProject project) {
- Map<String, ProtoDescriptorInfo> descriptorInfos = new LinkedHashMap<>();
-
- // Add descriptor.proto from preferences
- GeneralPreferences preferences = new GeneralPreferences(storeAccess, project);
- String descriptorProtoUri = preferences.getDescriptorProtoPath();
- if (!PreferenceNames.DEFAULT_DESCRIPTOR_PATH.equals(descriptorProtoUri)) {
- String resolvedUri = resolver.resolveUri(descriptorProtoUri, null, project);
- if (resolvedUri != null) {
- URI descriptorProtoLocation = URI.createURI(resolvedUri);
- if (descriptorProtoLocation != null) {
- ProtoDescriptor protoDescriptor =
- new ProtoDescriptor(descriptorProtoUri, descriptorProtoLocation, parser, nodes);
- ProtoDescriptorInfo descriptorInfo =
- new ProtoDescriptorInfo(descriptorProtoUri, descriptorProtoLocation, protoDescriptor);
- descriptorInfos.put(descriptorProtoUri, descriptorInfo);
- }
- } else {
- LOG.log(Level.WARNING,
- "Unable to resolve URI for descriptor proto location: " + descriptorProtoUri);
- }
- }
-
- // Add the extension point descriptor proto
- if (extensionPointDescriptorInfo != null) {
- if (!descriptorInfos.containsKey(extensionPointDescriptorInfo.importUri)) {
- descriptorInfos.put(extensionPointDescriptorInfo.importUri, extensionPointDescriptorInfo);
- }
- }
-
- // Add the open source descriptor proto
- if (!descriptorInfos.containsKey(PreferenceNames.DEFAULT_DESCRIPTOR_PATH)) {
- descriptorInfos.put(PreferenceNames.DEFAULT_DESCRIPTOR_PATH,
- openSourceProtoDescriptorInfo);
- }
-
- // Set property change listener for this project
- storeAccess.getContextPreferenceStore(project).addPropertyChangeListener(
- new IPropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- if (event.getProperty().contains(DESCRIPTOR_PROTO_PATH)) {
- descriptorCache.invalidate(project);
- }
- }
- });
- return descriptorInfos;
- }
-
private Map<String, ProtoDescriptorInfo> getDescriptorInfosFor(IProject project) {
if (project == null) {
- Map<String, ProtoDescriptorInfo> descriptorInfos =
- new LinkedHashMap<>();
+ Map<String, ProtoDescriptorInfo> descriptorInfos = new LinkedHashMap<>();
descriptorInfos.put(PreferenceNames.DEFAULT_DESCRIPTOR_PATH, openSourceProtoDescriptorInfo);
return descriptorInfos;
}
@@ -195,20 +164,6 @@
}
}
- private ProtoDescriptorInfo getOpenSourceProtoDescriptorInfo() {
- ProtoDescriptor descriptor = new ProtoDescriptor(PreferenceNames.DEFAULT_DESCRIPTOR_PATH,
- DEFAULT_DESCRIPTOR_LOCATION, parser, nodes);
- return new ProtoDescriptorInfo(PreferenceNames.DEFAULT_DESCRIPTOR_PATH,
- DEFAULT_DESCRIPTOR_LOCATION, descriptor);
- }
-
- private ProtoDescriptorInfo getMapEntryDescriptorInfo() {
- ProtoDescriptor descriptor = new ProtoDescriptor(
- MAP_ENTRY_DESCRIPTOR_PATH, MAP_ENTRY_DESCRIPTOR_LOCATION, parser, nodes);
- return new ProtoDescriptorInfo(
- MAP_ENTRY_DESCRIPTOR_PATH, MAP_ENTRY_DESCRIPTOR_LOCATION, descriptor);
- }
-
private ProtoDescriptorInfo getExtensionPointDescriptorInfo() {
IConfigurationElement[] config = registry.getConfigurationElementsFor(EXTENSION_ID);
if (config == null) {
@@ -223,44 +178,67 @@
return null;
}
- private ProtoDescriptorInfo descriptorInfo(IConfigurationElement e) {
- String importUri = e.getAttribute("importUri");
- if (importUri.isEmpty()) {
- return null;
- }
- URI location = descriptorLocation(e);
- if (location == null) {
- return null;
- }
- try {
- return new ProtoDescriptorInfo(importUri, location,
- new ProtoDescriptor(importUri, location, parser, nodes));
- } catch (IllegalStateException exception) {
- LOG.log(Level.WARNING, "Error when initializing descriptor proto from extension point",
- exception);
- return null;
- }
+ private ProtoDescriptorInfo getOpenSourceProtoDescriptorInfo() {
+ return new ProtoDescriptorInfo(
+ PreferenceNames.DEFAULT_DESCRIPTOR_PATH, DEFAULT_DESCRIPTOR_LOCATION);
}
- private static URI descriptorLocation(IConfigurationElement e) {
- String path = e.getAttribute("path");
- if (path.isEmpty()) {
- return null;
+ private Map<String, ProtoDescriptorInfo> loadDescriptorInfos(final IProject project) {
+ Map<String, ProtoDescriptorInfo> descriptorInfos = new LinkedHashMap<>();
+
+ // Add descriptor.proto from preferences
+ GeneralPreferences preferences = new GeneralPreferences(storeAccess, project);
+ String descriptorProtoUri = preferences.getDescriptorProtoPath();
+ if (!PreferenceNames.DEFAULT_DESCRIPTOR_PATH.equals(descriptorProtoUri)) {
+ String resolvedUri = resolver.resolveUri(descriptorProtoUri, null, project);
+ if (resolvedUri != null) {
+ URI descriptorProtoLocation = URI.createURI(resolvedUri);
+ if (descriptorProtoLocation != null) {
+ ProtoDescriptorInfo descriptorInfo =
+ new ProtoDescriptorInfo(descriptorProtoUri, descriptorProtoLocation);
+ descriptorInfos.put(descriptorProtoUri, descriptorInfo);
+ }
+ } else {
+ LOG.log(
+ Level.WARNING,
+ "Unable to resolve URI for descriptor proto location: " + descriptorProtoUri);
+ }
}
- StringBuilder uri = new StringBuilder();
- uri.append("platform:/plugin/").append(e.getContributor().getName()).append("/").append(path);
- return URI.createURI(uri.toString());
+
+ // Add the extension point descriptor proto
+ if (extensionPointDescriptorInfo != null) {
+ if (!descriptorInfos.containsKey(extensionPointDescriptorInfo.importUri)) {
+ descriptorInfos.put(extensionPointDescriptorInfo.importUri, extensionPointDescriptorInfo);
+ }
+ }
+
+ // Add the open source descriptor proto
+ if (!descriptorInfos.containsKey(PreferenceNames.DEFAULT_DESCRIPTOR_PATH)) {
+ descriptorInfos.put(PreferenceNames.DEFAULT_DESCRIPTOR_PATH, openSourceProtoDescriptorInfo);
+ }
+
+ IPropertyChangeListener changeListener =
+ new IPropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ String property = event.getProperty();
+ if (property.contains(DESCRIPTOR_PROTO_PATH)
+ || property.contains(ENABLE_PROJECT_SETTINGS_PREFERENCE_NAME)) {
+ descriptorCache.invalidate(project);
+ }
+ }
+ };
+
+ // Set property change listener for this project
+ preferences.addPropertyChangeListener(changeListener);
+ return descriptorInfos;
}
- private static class ProtoDescriptorInfo {
- final String importUri;
- final URI location;
- final ProtoDescriptor protoDescriptor;
-
- ProtoDescriptorInfo(String importUri, URI location, ProtoDescriptor protoDescriptor) {
- this.importUri = importUri;
- this.location = location;
- this.protoDescriptor = protoDescriptor;
+ public ProtoDescriptorInfo primaryDescriptor(IProject project) {
+ Map<String, ProtoDescriptorInfo> descriptorInfos = getDescriptorInfosFor(project);
+ for (ProtoDescriptorInfo descriptorInfo : descriptorInfos.values()) {
+ return descriptorInfo;
}
+ return openSourceProtoDescriptorInfo;
}
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
index 0efad69..5baf2c7 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
@@ -8,18 +8,10 @@
*/
package com.google.eclipse.protobuf.scoping;
-import static com.google.eclipse.protobuf.util.Encodings.UTF_8;
import static com.google.eclipse.protobuf.util.Tracer.DEBUG_SCOPING;
import static com.google.eclipse.protobuf.validation.ProtobufResourceValidator.getScopeProviderTimingCollector;
-import static java.util.Collections.singletonMap;
-import static org.eclipse.emf.ecore.resource.ContentHandler.UNSPECIFIED_CONTENT_TYPE;
-import static org.eclipse.xtext.EcoreUtil2.resolveLazyCrossReferences;
-import static org.eclipse.xtext.resource.XtextResource.OPTION_ENCODING;
-import static org.eclipse.xtext.util.CancelIndicator.NullImpl;
-
import com.google.eclipse.protobuf.naming.ProtobufQualifiedNameConverter;
import com.google.eclipse.protobuf.naming.ProtobufQualifiedNameProvider;
-import com.google.eclipse.protobuf.preferences.general.PreferenceNames;
import com.google.eclipse.protobuf.protobuf.ComplexType;
import com.google.eclipse.protobuf.protobuf.ComplexTypeLink;
import com.google.eclipse.protobuf.protobuf.ComplexValue;
@@ -27,15 +19,11 @@
import com.google.eclipse.protobuf.protobuf.CustomFieldOption;
import com.google.eclipse.protobuf.protobuf.CustomOption;
import com.google.eclipse.protobuf.protobuf.DefaultValueFieldOption;
-import com.google.eclipse.protobuf.protobuf.Enum;
import com.google.eclipse.protobuf.protobuf.ExtensionFieldName;
import com.google.eclipse.protobuf.protobuf.FieldName;
-import com.google.eclipse.protobuf.protobuf.FieldOption;
import com.google.eclipse.protobuf.protobuf.Group;
import com.google.eclipse.protobuf.protobuf.IndexedElement;
-import com.google.eclipse.protobuf.protobuf.Literal;
import com.google.eclipse.protobuf.protobuf.LiteralLink;
-import com.google.eclipse.protobuf.protobuf.Message;
import com.google.eclipse.protobuf.protobuf.MessageField;
import com.google.eclipse.protobuf.protobuf.NativeFieldOption;
import com.google.eclipse.protobuf.protobuf.NativeOption;
@@ -44,33 +32,24 @@
import com.google.eclipse.protobuf.protobuf.OptionSource;
import com.google.eclipse.protobuf.protobuf.Package;
import com.google.eclipse.protobuf.protobuf.Protobuf;
-import com.google.eclipse.protobuf.protobuf.Rpc;
-import com.google.eclipse.protobuf.protobuf.Stream;
import com.google.eclipse.protobuf.protobuf.TypeLink;
import com.google.eclipse.protobuf.protobuf.ValueField;
import com.google.eclipse.protobuf.util.EResources;
import com.google.inject.Inject;
import com.google.inject.Provider;
-import org.apache.log4j.Level;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.eclipse.xtext.scoping.impl.ImportNormalizer;
-import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
import org.eclipse.xtext.util.IResourceScopeCache;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -81,40 +60,8 @@
* @author atrookey@google.com (Alexander Rookey)
*/
public class ProtobufScopeProvider extends AbstractDeclarativeScopeProvider {
- /**
- * Returns the name of the descriptor.proto message declaring default options. The options must
- * match the option type of {@code context}. For example, if {@code context} is a file option,
- * {@code FileOptions} should be returned because it contains the declarations of the default file
- * options.
- */
- // TODO (atrookey) Create utility for getting the type of an Option.
- private static String getOptionType(EObject context) {
- if (context == null) {
- return "FileOptions";
- }
- if (context instanceof Message) {
- return "MessageOptions";
- }
- if (context instanceof Enum) {
- return "EnumOptions";
- }
- if (context instanceof FieldOption) {
- return "FieldOptions";
- }
- if (context instanceof Rpc) {
- return "MethodOptions";
- }
- if (context instanceof Stream) {
- return "StreamOptions";
- }
- if (context instanceof Literal) {
- return "EnumValueOptions";
- }
- return getOptionType(context.eContainer());
- }
- @Inject private IPreferenceStoreAccess storeAccess;
- @Inject private IUriResolver uriResolver;
+ @Inject private ProtoDescriptorProvider descriptorProvider;
@Inject private IResourceScopeCache cache;
@Inject private ProtobufQualifiedNameConverter nameConverter;
@Inject private ProtobufQualifiedNameProvider nameProvider;
@@ -217,27 +164,10 @@
/** Returns descriptor associated with the current project. */
private @Nullable Resource getDescriptorResource(EObject context) {
- URI descriptorLocation;
IProject project = EResources.getProjectOf(context.eResource());
- IPreferenceStore store = storeAccess.getWritablePreferenceStore(project);
- String rawDescriptorLocation = store.getString(PreferenceNames.DESCRIPTOR_PROTO_PATH);
- descriptorLocation =
- URI.createURI(uriResolver.resolveUri(rawDescriptorLocation, null, project));
ResourceSet resourceSet = context.eResource().getResourceSet();
- Resource resource = resourceSet.getResource(descriptorLocation, true);
- if (resource != null) {
- return resource;
- }
- try {
- InputStream contents = openFile(descriptorLocation);
- resource = resourceSet.createResource(descriptorLocation, UNSPECIFIED_CONTENT_TYPE);
- resource.load(contents, singletonMap(OPTION_ENCODING, UTF_8));
- resolveLazyCrossReferences(resource, NullImpl);
- return resource;
- } catch (IOException e) {
- logger.log(Level.ERROR, e);
- }
- return null;
+ ProtoDescriptorProvider.ProtoDescriptorInfo descriptorInfo = descriptorProvider.primaryDescriptor(project);
+ return resourceSet.getResource(descriptorInfo.location, true);
}
/** Returns the global scope provider. */
@@ -284,14 +214,6 @@
}
/**
- * Returns the InputStream associated with the resource at location {@code descriptorLocation}.
- */
- private InputStream openFile(URI fileLocation) throws IOException {
- URL url = new URL(fileLocation.toString());
- return url.openConnection().getInputStream();
- }
-
- /**
* Scopes the {@code FieldName}.
*
* <p>For example: <pre>
@@ -464,7 +386,7 @@
* google.protobuf.FileOptions.java_package} defined in descriptor.proto.
*/
public IScope scope_OptionSource_target(OptionSource optionSource, EReference reference) {
- String optionType = getOptionType(optionSource);
+ String optionType = OptionType.typeOf(optionSource).messageName();
Resource resource = optionSource.eResource();
IScope descriptorScope =
cache.get(