Skip to content

Commit 4dd864e

Browse files
Merge pull request #40 from protostuff/feature/option-references
Resolve option references
2 parents ae9ebd2 + a46bdeb commit 4dd864e

32 files changed

+656
-196
lines changed

build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ description = 'Protobuf Plugin for JetBrains IDEs'
1818

1919
repositories {
2020
jcenter()
21+
mavenCentral()
2122
mavenLocal()
2223
maven {
2324
url "https://dl.bintray.com/antlr/maven/"
@@ -30,7 +31,7 @@ dependencies {
3031
exclude group: 'com.jetbrains'
3132
}
3233
compile 'com.google.guava:guava:21.0'
33-
compile 'io.protostuff:protostuff-parser:2.0.0-alpha35'
34+
compile 'io.protostuff:protostuff-parser:2.0.0-alpha36'
3435
}
3536

3637
apply plugin: 'idea'

src/main/java/io/protostuff/jetbrains/plugin/ProtoParserDefinition.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
import com.intellij.psi.tree.TokenSet;
1919
import io.protostuff.compiler.parser.ProtoLexer;
2020
import io.protostuff.compiler.parser.ProtoParser;
21+
import io.protostuff.jetbrains.plugin.psi.CustomFieldReferenceNode;
2122
import io.protostuff.jetbrains.plugin.psi.EnumConstantNode;
2223
import io.protostuff.jetbrains.plugin.psi.EnumNode;
24+
import io.protostuff.jetbrains.plugin.psi.ExtendEntryNode;
2325
import io.protostuff.jetbrains.plugin.psi.ExtendNode;
2426
import io.protostuff.jetbrains.plugin.psi.ExtensionsNode;
2527
import io.protostuff.jetbrains.plugin.psi.FieldNode;
28+
import io.protostuff.jetbrains.plugin.psi.FieldReferenceNode;
2629
import io.protostuff.jetbrains.plugin.psi.FileReferenceNode;
2730
import io.protostuff.jetbrains.plugin.psi.GroupNode;
2831
import io.protostuff.jetbrains.plugin.psi.ImportNode;
@@ -33,7 +36,6 @@
3336
import io.protostuff.jetbrains.plugin.psi.OneOfNode;
3437
import io.protostuff.jetbrains.plugin.psi.OneofFieldNode;
3538
import io.protostuff.jetbrains.plugin.psi.OptionEntryNode;
36-
import io.protostuff.jetbrains.plugin.psi.OptionNameNode;
3739
import io.protostuff.jetbrains.plugin.psi.OptionNode;
3840
import io.protostuff.jetbrains.plugin.psi.OptionValueNode;
3941
import io.protostuff.jetbrains.plugin.psi.PackageStatement;
@@ -45,6 +47,7 @@
4547
import io.protostuff.jetbrains.plugin.psi.RpcMethodNode;
4648
import io.protostuff.jetbrains.plugin.psi.RpcMethodTypeNode;
4749
import io.protostuff.jetbrains.plugin.psi.ServiceNode;
50+
import io.protostuff.jetbrains.plugin.psi.StandardFieldReferenceNode;
4851
import io.protostuff.jetbrains.plugin.psi.SyntaxNode;
4952
import io.protostuff.jetbrains.plugin.psi.TypeReferenceNode;
5053
import java.util.HashMap;
@@ -244,11 +247,14 @@ public ProtoParserDefinition() {
244247
register(ProtoParser.RULE_rpcMethod, RpcMethodNode::new);
245248
register(ProtoParser.RULE_optionEntry, OptionEntryNode::new);
246249
register(ProtoParser.RULE_option, OptionNode::new);
247-
register(ProtoParser.RULE_optionName, OptionNameNode::new);
250+
register(ProtoParser.RULE_fieldRerefence, FieldReferenceNode::new);
251+
register(ProtoParser.RULE_standardFieldRerefence, StandardFieldReferenceNode::new);
252+
register(ProtoParser.RULE_customFieldReference, CustomFieldReferenceNode::new);
248253
register(ProtoParser.RULE_optionValue, OptionValueNode::new);
249254
register(ProtoParser.RULE_oneof, OneOfNode::new);
250255
register(ProtoParser.RULE_oneofField, OneofFieldNode::new);
251256
register(ProtoParser.RULE_extendBlock, ExtendNode::new);
257+
register(ProtoParser.RULE_extendBlockEntry, ExtendEntryNode::new);
252258
register(ProtoParser.RULE_extensions, ExtensionsNode::new);
253259
register(ProtoParser.RULE_map, MapNode::new);
254260
register(ProtoParser.RULE_mapKey, MapKeyNode::new);

src/main/java/io/protostuff/jetbrains/plugin/formatter/BlockFactory.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.protostuff.jetbrains.plugin.formatter;
22

3+
import static io.protostuff.compiler.parser.ProtoParser.RULE_customFieldReference;
34
import static io.protostuff.compiler.parser.ProtoParser.RULE_enumBlock;
45
import static io.protostuff.compiler.parser.ProtoParser.RULE_enumField;
56
import static io.protostuff.compiler.parser.ProtoParser.RULE_enumFieldName;
@@ -12,6 +13,7 @@
1213
import static io.protostuff.compiler.parser.ProtoParser.RULE_fieldModifier;
1314
import static io.protostuff.compiler.parser.ProtoParser.RULE_fieldName;
1415
import static io.protostuff.compiler.parser.ProtoParser.RULE_fieldOptions;
16+
import static io.protostuff.compiler.parser.ProtoParser.RULE_fieldRerefence;
1517
import static io.protostuff.compiler.parser.ProtoParser.RULE_fileReference;
1618
import static io.protostuff.compiler.parser.ProtoParser.RULE_fullIdent;
1719
import static io.protostuff.compiler.parser.ProtoParser.RULE_groupBlock;
@@ -29,7 +31,6 @@
2931
import static io.protostuff.compiler.parser.ProtoParser.RULE_oneofName;
3032
import static io.protostuff.compiler.parser.ProtoParser.RULE_option;
3133
import static io.protostuff.compiler.parser.ProtoParser.RULE_optionEntry;
32-
import static io.protostuff.compiler.parser.ProtoParser.RULE_optionName;
3334
import static io.protostuff.compiler.parser.ProtoParser.RULE_optionValue;
3435
import static io.protostuff.compiler.parser.ProtoParser.RULE_packageName;
3536
import static io.protostuff.compiler.parser.ProtoParser.RULE_packageStatement;
@@ -45,6 +46,7 @@
4546
import static io.protostuff.compiler.parser.ProtoParser.RULE_rpcType;
4647
import static io.protostuff.compiler.parser.ProtoParser.RULE_serviceBlock;
4748
import static io.protostuff.compiler.parser.ProtoParser.RULE_serviceName;
49+
import static io.protostuff.compiler.parser.ProtoParser.RULE_standardFieldRerefence;
4850
import static io.protostuff.compiler.parser.ProtoParser.RULE_syntax;
4951
import static io.protostuff.compiler.parser.ProtoParser.RULE_tag;
5052
import static io.protostuff.compiler.parser.ProtoParser.RULE_textFormat;
@@ -88,7 +90,9 @@ class BlockFactory {
8890
register(rule(RULE_fieldName), LeafBlock::new);
8991
register(rule(RULE_textFormatOptionName), LeafBlock::new);
9092
register(rule(RULE_textFormatOptionValue), LeafBlock::new);
91-
register(rule(RULE_optionName), LeafBlock::new);
93+
register(rule(RULE_fieldRerefence), LeafBlock::new);
94+
register(rule(RULE_standardFieldRerefence), LeafBlock::new);
95+
register(rule(RULE_customFieldReference), LeafBlock::new);
9296
register(rule(RULE_optionValue), LeafBlock::new);
9397
register(rule(RULE_fieldModifier), LeafBlock::new);
9498
register(rule(RULE_typeReference), LeafBlock::new);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.protostuff.jetbrains.plugin.psi;
2+
3+
import com.intellij.lang.ASTNode;
4+
import org.antlr.jetbrains.adapter.psi.AntlrPsiNode;
5+
import org.jetbrains.annotations.NotNull;
6+
7+
/**
8+
* Base class for field reference node parts, used in option name.
9+
*
10+
* @author Kostiantyn Shchepanovskyi
11+
*/
12+
public abstract class AbstractFieldReferenceNode extends AntlrPsiNode {
13+
14+
public AbstractFieldReferenceNode(@NotNull ASTNode node) {
15+
super(node);
16+
}
17+
18+
19+
/**
20+
* Returns true if field reference refers to an extension field.
21+
*/
22+
public abstract boolean isExtension();
23+
24+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.protostuff.jetbrains.plugin.psi;
2+
3+
import com.intellij.lang.ASTNode;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
/**
7+
* Custom field reference node, part of option name (custom options).
8+
*
9+
* @author Kostiantyn Shchepanovskyi
10+
*/
11+
public class CustomFieldReferenceNode extends AbstractFieldReferenceNode {
12+
13+
public CustomFieldReferenceNode(@NotNull ASTNode node) {
14+
super(node);
15+
}
16+
17+
@Override
18+
public boolean isExtension() {
19+
return true;
20+
}
21+
22+
}

src/main/java/io/protostuff/jetbrains/plugin/psi/DataTypeContainer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ public interface DataTypeContainer {
1717

1818
Collection<DataType> getDeclaredDataTypes();
1919

20+
Collection<ExtendNode> getDeclaredExtensions();
21+
2022
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.protostuff.jetbrains.plugin.psi;
2+
3+
import com.intellij.lang.ASTNode;
4+
import org.antlr.jetbrains.adapter.psi.AntlrPsiNode;
5+
import org.jetbrains.annotations.NotNull;
6+
7+
/**
8+
* Extend entry node.
9+
*
10+
* @author Kostiantyn Shchepanovskyi
11+
*/
12+
public class ExtendEntryNode extends AntlrPsiNode implements KeywordsContainer {
13+
14+
public ExtendEntryNode(@NotNull ASTNode node) {
15+
super(node);
16+
}
17+
18+
}

src/main/java/io/protostuff/jetbrains/plugin/psi/ExtendNode.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package io.protostuff.jetbrains.plugin.psi;
22

33
import com.intellij.lang.ASTNode;
4+
import com.intellij.psi.PsiElement;
5+
import java.util.HashMap;
6+
import java.util.Map;
47
import org.antlr.jetbrains.adapter.psi.AntlrPsiNode;
58
import org.jetbrains.annotations.NotNull;
69

@@ -15,4 +18,39 @@ public ExtendNode(@NotNull ASTNode node) {
1518
super(node);
1619
}
1720

21+
public TypeReferenceNode getTarget() {
22+
return findChildByClass(TypeReferenceNode.class);
23+
}
24+
25+
/**
26+
* Returns namespace for fields of this extension.
27+
*/
28+
public String getNamespace() {
29+
PsiElement parent = getParent();
30+
while (parent != null) {
31+
if (parent instanceof DataTypeContainer) {
32+
DataTypeContainer message = (DataTypeContainer) parent;
33+
return message.getNamespace();
34+
}
35+
}
36+
return ".";
37+
}
38+
39+
/**
40+
* Returns extension fields.
41+
*/
42+
public Map<String, FieldNode> getExtensionFields() {
43+
Map<String, FieldNode> result = new HashMap<>();
44+
ExtendEntryNode[] entries = findChildrenByClass(ExtendEntryNode.class);
45+
for (ExtendEntryNode entry : entries) {
46+
for (PsiElement element : entry.getChildren()) {
47+
if (element instanceof FieldNode) {
48+
FieldNode field = (FieldNode) element;
49+
result.put(field.getFieldName(), field);
50+
}
51+
}
52+
}
53+
return result;
54+
}
55+
1856
}

src/main/java/io/protostuff/jetbrains/plugin/psi/FieldNode.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ public String getFieldName() {
4848
return "";
4949
}
5050

51+
public TypeReferenceNode getFieldType() {
52+
return findChildByClass(TypeReferenceNode.class);
53+
}
54+
5155
@Override
5256
public ASTNode getFieldNameNode() {
5357
ASTNode node = getNode();
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package io.protostuff.jetbrains.plugin.psi;
2+
3+
import com.intellij.lang.ASTNode;
4+
import com.intellij.psi.PsiReference;
5+
import io.protostuff.jetbrains.plugin.reference.FieldReferenceProvider;
6+
import org.antlr.jetbrains.adapter.psi.AntlrPsiNode;
7+
import org.jetbrains.annotations.NotNull;
8+
9+
/**
10+
* Option name node.
11+
*
12+
* @author Kostiantyn Shchepanovskyi
13+
*/
14+
public class FieldReferenceNode extends AntlrPsiNode implements KeywordsContainer {
15+
16+
public FieldReferenceNode(@NotNull ASTNode node) {
17+
super(node);
18+
}
19+
20+
@Override
21+
public PsiReference getReference() {
22+
PsiReference[] references = getReferences();
23+
if (references.length > 0) {
24+
return references[0];
25+
}
26+
return null;
27+
}
28+
29+
@NotNull
30+
@Override
31+
public PsiReference[] getReferences() {
32+
FieldReferenceProvider referenceProvider = getProject().getComponent(FieldReferenceProvider.class);
33+
return referenceProvider.getReferencesByElement(this);
34+
}
35+
}

0 commit comments

Comments
 (0)