Fixed caching of qualified names and compiled patterns.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/CommentNodesFinder.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/CommentNodesFinder.java
index 059a2c6..86494d5 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/CommentNodesFinder.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/semicolon/CommentNodesFinder.java
@@ -8,31 +8,39 @@
*/
package com.google.eclipse.protobuf.ui.commands.semicolon;
+import static com.google.common.cache.CacheBuilder.newBuilder;
import static com.google.common.collect.Lists.newArrayList;
+import static com.google.eclipse.protobuf.util.Strings.quote;
import static com.google.eclipse.protobuf.util.SystemProperties.lineSeparator;
import static java.util.regex.Pattern.CASE_INSENSITIVE;
import static org.eclipse.xtext.nodemodel.util.NodeModelUtils.getNode;
import static org.eclipse.xtext.util.Strings.isEmpty;
import static org.eclipse.xtext.util.Tuples.pair;
-import java.util.List;
-import java.util.regex.*;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.nodemodel.*;
-import org.eclipse.xtext.util.*;
-
+import com.google.common.cache.*;
import com.google.eclipse.protobuf.model.util.INodes;
import com.google.inject.*;
+import org.apache.log4j.Logger;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.nodemodel.*;
+import org.eclipse.xtext.util.Pair;
+
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.regex.*;
+
/**
* @author alruiz@google.com (Alex Ruiz)
*/
@Singleton class CommentNodesFinder {
private static final String MATCH_ANYTHING = ".*";
+ private static Logger logger = Logger.getLogger(CommentNodesFinder.class);
+
@Inject private INodes nodes;
- @Inject private final IResourceScopeCache cache = IResourceScopeCache.NullImpl.INSTANCE;
+
+ private final Cache<String, Pattern> patternCache = newBuilder().maximumSize(20).build(new PatternCacheLoader());
Pair<INode, Matcher> matchingCommentNode(EObject target, String... patternsToMatch) {
ICompositeNode node = getNode(target);
@@ -48,7 +56,9 @@
for (String line : comment) {
for (Pattern pattern : compile(patternsToMatch, target)) {
Matcher matcher = pattern.matcher(line);
- if (matcher.matches()) { return pair(currentNode, matcher); }
+ if (matcher.matches()) {
+ return pair(currentNode, matcher);
+ }
}
}
}
@@ -58,13 +68,25 @@
private List<Pattern> compile(String[] patterns, EObject target) {
List<Pattern> compiled = newArrayList();
for (final String s : patterns) {
- Pattern p = cache.get(s, target.eResource(), new Provider<Pattern>() {
- @Override public Pattern get() {
- return Pattern.compile(MATCH_ANYTHING + s + MATCH_ANYTHING, CASE_INSENSITIVE);
- }
- });
+ Pattern p = null;
+ try {
+ p = patternCache.get(s);
+ } catch (ExecutionException e) {
+ logger.error("Unable to obtain pattern from cache for " + quote(s), e);
+ p = PatternCacheLoader.compile(s);
+ }
compiled.add(p);
}
return compiled;
}
+
+ private static class PatternCacheLoader extends CacheLoader<String, Pattern> {
+ @Override public Pattern load(String key) throws Exception {
+ return compile(key);
+ }
+
+ static Pattern compile(String s) {
+ return Pattern.compile(MATCH_ANYTHING + s + MATCH_ANYTHING, CASE_INSENSITIVE);
+ }
+ }
}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/documentation/MLCommentDocumentationProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/documentation/MLCommentDocumentationProvider.java
index 9994bd5..ef9347e 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/documentation/MLCommentDocumentationProvider.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/documentation/MLCommentDocumentationProvider.java
@@ -12,14 +12,14 @@
import static java.util.regex.Pattern.compile;
import static org.eclipse.xtext.nodemodel.util.NodeModelUtils.getNode;
-import java.util.regex.Pattern;
+import com.google.eclipse.protobuf.model.util.INodes;
+import com.google.inject.*;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.documentation.IEObjectDocumentationProvider;
import org.eclipse.xtext.nodemodel.*;
-import com.google.eclipse.protobuf.model.util.INodes;
-import com.google.inject.*;
+import java.util.regex.Pattern;
/**
* Provides multiple-line comments of a protobuf element as its documentation
@@ -42,7 +42,9 @@
private String findComment(EObject o) {
String returnValue = null;
ICompositeNode node = getNode(o);
- if (node == null) { return null; }
+ if (node == null) {
+ return null;
+ }
// get the last multiple-line comment before a non hidden leaf node
for (INode currentNode : node.getAsTreeIterable()) {
if (!nodes.isHiddenLeafNode(currentNode)) {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/core/MiscellaneousPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/core/MiscellaneousPreferenceStoreInitializer.java
index 0d394fe..f768584 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/core/MiscellaneousPreferenceStoreInitializer.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/misc/core/MiscellaneousPreferenceStoreInitializer.java
@@ -18,6 +18,6 @@
public class MiscellaneousPreferenceStoreInitializer implements IPreferenceStoreInitializer {
@Override public void initialize(IPreferenceStoreAccess storeAccess) {
MiscellaneousPreferences preferences = new MiscellaneousPreferences(storeAccess);
- preferences.isGoogleInternal().setDefaultValue(false);
+ preferences.isGoogleInternal().setDefaultValue(true);
}
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/IProtobufQualifiedNameProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/IProtobufQualifiedNameProvider.java
index c2f8020..0042599 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/IProtobufQualifiedNameProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/IProtobufQualifiedNameProvider.java
@@ -21,8 +21,8 @@
/**
* Returns the qualified name of the given model object.
* @param e the given model object.
- * @param namingStrategy gets the name of the model object.
+ * @param strategy gets the name of the model object.
* @return the qualified name of the given model object.
*/
- QualifiedName getFullyQualifiedName(EObject e, NamingStrategy namingStrategy);
+ QualifiedName getFullyQualifiedName(EObject e, NamingStrategy strategy);
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/LocalNamesProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/LocalNamesProvider.java
index f9b2881..5d7b9bf 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/LocalNamesProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/LocalNamesProvider.java
@@ -9,16 +9,19 @@
package com.google.eclipse.protobuf.naming;
import static com.google.common.collect.Lists.newArrayList;
-import static java.util.Collections.*;
+import static com.google.eclipse.protobuf.naming.NameType.NORMAL;
+import static java.util.Collections.emptyList;
import static org.eclipse.xtext.util.Strings.isEmpty;
+import static org.eclipse.xtext.util.Tuples.pair;
-import java.util.List;
+import com.google.eclipse.protobuf.model.util.*;
+import com.google.inject.*;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.naming.*;
+import org.eclipse.xtext.util.*;
-import com.google.eclipse.protobuf.model.util.*;
-import com.google.inject.Inject;
+import java.util.List;
/**
* Provides alternative qualified names for protobuf elements.
@@ -54,30 +57,46 @@
* @author alruiz@google.com (Alex Ruiz)
*/
public class LocalNamesProvider {
+ private static Pair<NameType, List<QualifiedName>> EMPTY_NAMES = emptyNames();
+
+ private static Pair<NameType, List<QualifiedName>> emptyNames() {
+ List<QualifiedName> names = emptyList();
+ return pair(NORMAL, names);
+ }
+
+ @Inject private final IResourceScopeCache cache = IResourceScopeCache.NullImpl.INSTANCE;
+
@Inject private ModelObjects modelObjects;
@Inject private NameResolver nameResolver;
@Inject private IQualifiedNameConverter qualifiedNameConverter;
@Inject private Packages packages;
- public List<QualifiedName> localNames(EObject e, NamingStrategy namingStrategy) {
- List<QualifiedName> allNames = newArrayList();
- EObject current = e;
- String name = namingStrategy.nameOf(e);
- if (isEmpty(name)) {
- return emptyList();
- }
- QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(name);
- allNames.add(qualifiedName);
- while (current.eContainer() != null) {
- current = current.eContainer();
- String containerName = nameResolver.nameOf(current);
- if (isEmpty(containerName)) {
- continue;
+ public List<QualifiedName> localNames(final EObject e, final NamingStrategy strategy) {
+ Pair<EObject, String> key = pair(e, "localFqns");
+ Pair<NameType, List<QualifiedName>> cached = cache.get(key, e.eResource(),
+ new Provider<Pair<NameType, List<QualifiedName>>>() {
+ @Override public Pair<NameType, List<QualifiedName>> get() {
+ List<QualifiedName> allNames = newArrayList();
+ EObject current = e;
+ Pair<NameType, String> name = strategy.nameOf(e);
+ if (name == null) {
+ return EMPTY_NAMES;
+ }
+ QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(name.getSecond());
+ allNames.add(qualifiedName);
+ while (current.eContainer() != null) {
+ current = current.eContainer();
+ String containerName = nameResolver.nameOf(current);
+ if (isEmpty(containerName)) {
+ continue;
+ }
+ qualifiedName = qualifiedNameConverter.toQualifiedName(containerName).append(qualifiedName);
+ allNames.add(qualifiedName);
+ }
+ allNames.addAll(packages.addPackageNameSegments(modelObjects.packageOf(e), qualifiedName));
+ return pair(name.getFirst(), allNames);
}
- qualifiedName = qualifiedNameConverter.toQualifiedName(containerName).append(qualifiedName);
- allNames.add(qualifiedName);
- }
- allNames.addAll(packages.addPackageNameSegments(modelObjects.packageOf(e), qualifiedName));
- return unmodifiableList(allNames);
+ });
+ return cached.getSecond();
}
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NameType.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NameType.java
new file mode 100644
index 0000000..bf26e49
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NameType.java
@@ -0,0 +1,16 @@
+/*
+ * 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.naming;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public enum NameType {
+ NORMAL, OPTION
+}
\ No newline at end of file
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NamingStrategy.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NamingStrategy.java
index c5dc05b..f928ca3 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NamingStrategy.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NamingStrategy.java
@@ -9,6 +9,7 @@
package com.google.eclipse.protobuf.naming;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.util.Pair;
/**
* Knows how to obtain the name of a model object.
@@ -21,5 +22,5 @@
* @param e the given model object.
* @return the name of the given model object.
*/
- String nameOf(EObject e);
+ Pair<NameType, String> nameOf(EObject e);
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NormalNamingStrategy.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NormalNamingStrategy.java
index 90e63a4..e36ed52 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NormalNamingStrategy.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NormalNamingStrategy.java
@@ -8,10 +8,15 @@
*/
package com.google.eclipse.protobuf.naming;
-import org.eclipse.emf.ecore.EObject;
+import static com.google.eclipse.protobuf.naming.NameType.NORMAL;
+import static org.eclipse.xtext.util.Strings.isEmpty;
+import static org.eclipse.xtext.util.Tuples.pair;
import com.google.inject.*;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.util.Pair;
+
/**
* Returns the name of a model object obtained from a <code>{@link NameResolver}</code>.
*
@@ -21,7 +26,11 @@
@Inject private NameResolver nameResolver;
/** {@inheritDoc} */
- @Override public String nameOf(EObject e) {
- return nameResolver.nameOf(e);
+ @Override public Pair<NameType, String> nameOf(EObject e) {
+ String value = nameResolver.nameOf(e);
+ if (isEmpty(value)) {
+ return null;
+ }
+ return pair(NORMAL, value);
}
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/OptionNamingStrategy.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/OptionNamingStrategy.java
index 2dc421c..196c29e 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/OptionNamingStrategy.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/OptionNamingStrategy.java
@@ -1,19 +1,25 @@
/*
* 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
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.google.eclipse.protobuf.naming;
-import org.eclipse.emf.ecore.EObject;
+import static com.google.eclipse.protobuf.naming.NameType.OPTION;
+import static org.eclipse.xtext.util.Strings.isEmpty;
+import static org.eclipse.xtext.util.Tuples.create;
import com.google.eclipse.protobuf.model.util.Options;
import com.google.eclipse.protobuf.protobuf.IndexedElement;
import com.google.inject.*;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.util.Pair;
+
/**
* Returns the name of a model object, to be used as the name of an option.
*
@@ -23,7 +29,7 @@
* @see Options#nameForOption(IndexedElement)
*/
@Singleton public class OptionNamingStrategy implements NamingStrategy {
- @Inject private NameResolver nameResolver;
+ @Inject private NormalNamingStrategy delegate;
@Inject private Options options;
/**
@@ -31,10 +37,14 @@
* @param e the given model object.
* @return the name of the given model object, to be used as the name of an option.
*/
- @Override public String nameOf(EObject e) {
- if (e instanceof IndexedElement) {
- return options.nameForOption((IndexedElement) e);
+ @Override public Pair<NameType, String> nameOf(EObject e) {
+ if (!(e instanceof IndexedElement)) {
+ return delegate.nameOf(e);
}
- return nameResolver.nameOf(e);
+ String value = options.nameForOption((IndexedElement) e);
+ if (isEmpty(value)) {
+ return null;
+ }
+ return create(OPTION, value);
}
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameProvider.java
index 73f3668..fa070a7 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameProvider.java
@@ -8,16 +8,18 @@
*/
package com.google.eclipse.protobuf.naming;
-import static org.eclipse.xtext.util.Strings.isEmpty;
-
-import java.util.List;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.naming.*;
+import static com.google.eclipse.protobuf.naming.NameType.NORMAL;
+import static org.eclipse.xtext.util.Tuples.pair;
import com.google.eclipse.protobuf.model.util.*;
import com.google.eclipse.protobuf.protobuf.Package;
-import com.google.inject.Inject;
+import com.google.inject.*;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.naming.*;
+import org.eclipse.xtext.util.*;
+
+import java.util.List;
/**
* Provides fully-qualified names for protobuf elements.
@@ -26,7 +28,10 @@
*/
public class ProtobufQualifiedNameProvider extends IQualifiedNameProvider.AbstractImpl implements
IProtobufQualifiedNameProvider {
+ private static final Pair<NameType, QualifiedName> EMPTY_NAME = pair(NORMAL, null);
+
@Inject private final IQualifiedNameConverter converter = new IQualifiedNameConverter.DefaultImpl();
+ @Inject private final IResourceScopeCache cache = IResourceScopeCache.NullImpl.INSTANCE;
@Inject private ModelObjects modelObjects;
@Inject private NormalNamingStrategy normalNamingStrategy;
@@ -37,21 +42,27 @@
return getFullyQualifiedName(target, normalNamingStrategy);
}
- @Override public QualifiedName getFullyQualifiedName(EObject e, NamingStrategy namingStrategy) {
- EObject current = e;
- String name = namingStrategy.nameOf(e);
- if (isEmpty(name)) {
- return null;
- }
- QualifiedName qualifiedName = converter.toQualifiedName(name);
- while (current.eContainer() != null) {
- current = current.eContainer();
- QualifiedName parentsQualifiedName = getFullyQualifiedName(current, namingStrategy);
- if (parentsQualifiedName != null) {
- return parentsQualifiedName.append(qualifiedName);
+ @Override public QualifiedName getFullyQualifiedName(final EObject e, final NamingStrategy namingStrategy) {
+ Pair<EObject, String> key = pair(e, "fqn");
+ Pair<NameType, QualifiedName> cached = cache.get(key, e.eResource(), new Provider<Pair<NameType, QualifiedName>>() {
+ @Override public Pair<NameType, QualifiedName> get() {
+ EObject current = e;
+ Pair<NameType, String> name = namingStrategy.nameOf(e);
+ if (name == null) {
+ return EMPTY_NAME;
+ }
+ QualifiedName qualifiedName = converter.toQualifiedName(name.getSecond());
+ while (current.eContainer() != null) {
+ current = current.eContainer();
+ QualifiedName parentsQualifiedName = getFullyQualifiedName(current, namingStrategy);
+ if (parentsQualifiedName != null) {
+ return pair(name.getFirst(), parentsQualifiedName.append(qualifiedName));
+ }
+ }
+ return pair(name.getFirst(), addPackage(e, qualifiedName));
}
- }
- return addPackage(e, qualifiedName);
+ });
+ return cached.getSecond();
}
private QualifiedName addPackage(EObject obj, QualifiedName qualifiedName) {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
index 9dac7b3..8af80df 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
@@ -12,10 +12,6 @@
import static com.google.eclipse.protobuf.validation.Messages.*;
import static java.lang.String.format;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.naming.*;
-import org.eclipse.xtext.validation.*;
-
import com.google.eclipse.protobuf.grammar.Syntaxes;
import com.google.eclipse.protobuf.model.util.*;
import com.google.eclipse.protobuf.naming.NameResolver;
@@ -23,11 +19,15 @@
import com.google.eclipse.protobuf.protobuf.Package;
import com.google.inject.Inject;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.naming.*;
+import org.eclipse.xtext.validation.*;
+
/**
* @author alruiz@google.com (Alex Ruiz)
*/
-@ComposedChecks(validators = { DataTypeValidator.class, ImportValidator.class }) public class ProtobufJavaValidator
- extends AbstractProtobufJavaValidator {
+@ComposedChecks(validators = { DataTypeValidator.class, ImportValidator.class })
+public class ProtobufJavaValidator extends AbstractProtobufJavaValidator {
public static final String SYNTAX_IS_NOT_PROTO2_ERROR = "syntaxIsNotProto2";
public static final String INVALID_FIELD_TAG_NUMBER_ERROR = "invalidFieldTagNumber";
public static final String MORE_THAN_ONE_PACKAGE_ERROR = "moreThanOnePackage";
@@ -53,8 +53,7 @@
}
@Check public void checkTagNumberIsUnique(IndexedElement e) {
- if (isNameNull(e))
- {
+ if (isNameNull(e)) {
return; // we already show an error if name is null, no need to go further.
}
long index = indexedElements.indexOf(e);