353faad2f27b0b59de017076e1e99f37074c00e5
[idea/community.git] / jps / jps-builders-6 / src / org / jetbrains / jps / javac / JavacProtoUtil.java
1 // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package org.jetbrains.jps.javac;
3
4 import com.google.protobuf.ByteString;
5 import com.intellij.openapi.util.io.FileUtilRt;
6 import org.jetbrains.annotations.Nullable;
7 import org.jetbrains.jps.incremental.BinaryContent;
8
9 import javax.tools.Diagnostic;
10 import javax.tools.JavaFileManager;
11 import javax.tools.JavaFileObject;
12 import java.io.ByteArrayOutputStream;
13 import java.io.File;
14 import java.io.PrintStream;
15 import java.net.URI;
16 import java.util.*;
17
18 /**
19  * @author Eugene Zhuravlev
20  */
21 public class JavacProtoUtil {
22
23   public static JavacRemoteProto.Message.Request createCancelRequest() {
24     return JavacRemoteProto.Message.Request.newBuilder().setRequestType(JavacRemoteProto.Message.Request.Type.CANCEL).build();
25   }
26
27   public static JavacRemoteProto.Message.Request createShutdownRequest() {
28     return JavacRemoteProto.Message.Request.newBuilder().setRequestType(JavacRemoteProto.Message.Request.Type.SHUTDOWN).build();
29   }
30
31   public static JavacRemoteProto.Message.Request createCompilationRequest(List<String> options,
32                                                                           Collection<? extends File> files,
33                                                                           Collection<? extends File> classpath,
34                                                                           Collection<? extends File> platformCp,
35                                                                           ModulePath modulePath,
36                                                                           Collection<? extends File> upgradeModulePath,
37                                                                           Collection<? extends File> sourcePath,
38                                                                           Map<File, Set<File>> outs) {
39     final JavacRemoteProto.Message.Request.Builder builder = JavacRemoteProto.Message.Request.newBuilder();
40     builder.setRequestType(JavacRemoteProto.Message.Request.Type.COMPILE);
41     builder.addAllOption(options);
42     for (File file : files) {
43       builder.addFile(FileUtilRt.toSystemIndependentName(file.getPath()));
44     }
45     for (File file : classpath) {
46       builder.addClasspath(FileUtilRt.toSystemIndependentName(file.getPath()));
47     }
48     for (File file : platformCp) {
49       builder.addPlatformClasspath(FileUtilRt.toSystemIndependentName(file.getPath()));
50     }
51     for (File file : modulePath.getPath()) {
52       final String pathEntry = FileUtilRt.toSystemIndependentName(file.getPath());
53       builder.addModulePath(pathEntry);
54       final String moduleName = modulePath.getModuleName(file);
55       if (moduleName != null) {
56         builder.putModuleNames(pathEntry, moduleName);
57       }
58     }
59     for (File file : upgradeModulePath) {
60       builder.addUpgradeModulePath(FileUtilRt.toSystemIndependentName(file.getPath()));
61     }
62     for (File file : sourcePath) {
63       builder.addSourcepath(FileUtilRt.toSystemIndependentName(file.getPath()));
64     }
65     for (Map.Entry<File, Set<File>> entry : outs.entrySet()) {
66       final JavacRemoteProto.Message.Request.OutputGroup.Builder groupBuilder = JavacRemoteProto.Message.Request.OutputGroup.newBuilder();
67       groupBuilder.setOutputRoot(FileUtilRt.toSystemIndependentName(entry.getKey().getPath()));
68       for (File srcRoot : entry.getValue()) {
69         groupBuilder.addSourceRoot(FileUtilRt.toSystemIndependentName(srcRoot.getPath()));
70       }
71       builder.addOutput(groupBuilder.build());
72     }
73     return builder.build();
74   }
75
76
77   public static JavacRemoteProto.Message.Response createOutputObjectResponse(OutputFileObject fileObject) {
78     final JavacRemoteProto.Message.Response.OutputObject.Builder msgBuilder = JavacRemoteProto.Message.Response.OutputObject.newBuilder();
79
80     msgBuilder.setKind(convertKind(fileObject.getKind()));
81     msgBuilder.setFilePath(FileUtilRt.toSystemIndependentName(fileObject.getFile().getPath()));
82     final BinaryContent content = fileObject.getContent();
83     if (content != null) {
84       msgBuilder.setContent(ByteString.copyFrom(content.getBuffer(), content.getOffset(), content.getLength()));
85     }
86     final String className = fileObject.getClassName();
87     if (className != null) {
88       msgBuilder.setClassName(className);
89     }
90     final File outputRoot = fileObject.getOutputRoot();
91     if (outputRoot != null) {
92       msgBuilder.setOutputRoot(FileUtilRt.toSystemIndependentName(outputRoot.getPath()));
93     }
94     final String relativePath = fileObject.getRelativePath();
95     if (relativePath != null) {
96       msgBuilder.setRelativePath(relativePath);
97     }
98     final URI srcUri = fileObject.getSourceUri();
99     if (srcUri != null) {
100       msgBuilder.setSourceUri(srcUri.toString());
101     }
102     final JavaFileManager.Location location = fileObject.getLocation();
103     if (location != null) {
104       msgBuilder.setLocation(location.getName());
105     }
106     final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder();
107     builder.setResponseType(JavacRemoteProto.Message.Response.Type.OUTPUT_OBJECT).setOutputObject(msgBuilder.build());
108
109     return builder.build();
110   }
111
112   public static JavacRemoteProto.Message.Response createCustomDataResponse(String pluginId, String dataName, byte[] data) {
113     final JavacRemoteProto.Message.Response.OutputObject outObjMsg = JavacRemoteProto.Message.Response.OutputObject.newBuilder()
114       .setKind(JavacRemoteProto.Message.Response.OutputObject.Kind.OTHER)
115       .setFilePath(pluginId)
116       .setClassName(dataName)
117       .setContent(ByteString.copyFrom(data))
118       .build();
119     return JavacRemoteProto.Message.Response.newBuilder()
120       .setResponseType(JavacRemoteProto.Message.Response.Type.CUSTOM_OUTPUT_OBJECT)
121       .setOutputObject(outObjMsg)
122       .build();
123   }
124
125   public static JavacRemoteProto.Message.Response createSourceFileLoadedResponse(File srcFile) {
126     final JavacRemoteProto.Message.Response.OutputObject outObjMsg = JavacRemoteProto.Message.Response.OutputObject.newBuilder()
127       .setKind(convertKind(JavaFileObject.Kind.SOURCE)).setFilePath(FileUtilRt.toSystemIndependentName(srcFile.getPath())).build();
128
129     final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder();
130     builder.setResponseType(JavacRemoteProto.Message.Response.Type.SRC_FILE_LOADED).setOutputObject(outObjMsg);
131
132     return builder.build();
133   }
134
135   public static JavacRemoteProto.Message.Response createClassDataResponse(String className, Collection<String> imports, Collection<String> staticImports) {
136     final JavacRemoteProto.Message.Response.ClassData.Builder msgBuilder = JavacRemoteProto.Message.Response.ClassData.newBuilder();
137     msgBuilder.setClassName(className);
138     if (!imports.isEmpty()) {
139       msgBuilder.addAllImportStatement(imports);
140     }
141     if (!staticImports.isEmpty()) {
142       msgBuilder.addAllStaticImport(imports);
143     }
144     final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder();
145     builder.setResponseType(JavacRemoteProto.Message.Response.Type.CLASS_DATA).setClassData(msgBuilder.build());
146     return builder.build();
147   }
148
149   public static JavacRemoteProto.Message.Response createStdOutputResponse(String text) {
150     final JavacRemoteProto.Message.Response.CompileMessage.Builder msgBuilder = JavacRemoteProto.Message.Response.CompileMessage.newBuilder();
151     msgBuilder.setKind(JavacRemoteProto.Message.Response.CompileMessage.Kind.STD_OUT);
152     msgBuilder.setText(text);
153     final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder();
154     builder.setResponseType(JavacRemoteProto.Message.Response.Type.BUILD_MESSAGE).setCompileMessage(msgBuilder.build());
155
156     return builder.build();
157   }
158
159   public static JavacRemoteProto.Message.Response createBuildMessageResponse(Diagnostic<? extends JavaFileObject> diagnostic) {
160     final JavacRemoteProto.Message.Response.CompileMessage.Builder msgBuilder = JavacRemoteProto.Message.Response.CompileMessage.newBuilder();
161
162     msgBuilder.setKind(convertKind(diagnostic.getKind()));
163     msgBuilder.setText(diagnostic.getMessage(Locale.US));
164
165     final JavaFileObject source = diagnostic.getSource();
166     URI srcUri = null;
167     try {
168       srcUri = source != null? source.toUri() : null;
169     }
170     catch (Exception ignored) {
171     }
172     if (srcUri != null) {
173       msgBuilder.setSourceUri(srcUri.toString());
174     }
175     msgBuilder.setLine(diagnostic.getLineNumber());
176     msgBuilder.setColumn(diagnostic.getColumnNumber());
177     msgBuilder.setProblemBeginOffset(diagnostic.getStartPosition());
178     msgBuilder.setProblemEndOffset(diagnostic.getEndPosition());
179     msgBuilder.setProblemLocationOffset(diagnostic.getPosition());
180
181     final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder();
182     builder.setResponseType(JavacRemoteProto.Message.Response.Type.BUILD_MESSAGE).setCompileMessage(msgBuilder.build());
183
184     return builder.build();
185   }
186
187   public static JavacRemoteProto.Message.Response createRequestAckResponse() {
188     return JavacRemoteProto.Message.Response.newBuilder().setResponseType(JavacRemoteProto.Message.Response.Type.REQUEST_ACK).build();
189   }
190
191   public static JavacRemoteProto.Message.Response createBuildCompletedResponse(boolean code) {
192     final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder();
193     builder.setResponseType(JavacRemoteProto.Message.Response.Type.BUILD_COMPLETED).setCompletionStatus(code);
194     return builder.build();
195   }
196
197   public static JavacRemoteProto.Message.Failure createFailure(String description, @Nullable Throwable ex) {
198     final JavacRemoteProto.Message.Failure.Builder builder = JavacRemoteProto.Message.Failure.newBuilder();
199     builder.setDescription(description);
200     if (ex != null) {
201       final ByteArrayOutputStream baos = new ByteArrayOutputStream();
202       ex.printStackTrace(new PrintStream(baos));
203       builder.setStacktrace(new String(baos.toByteArray()));
204     }
205     return builder.build();
206   }
207
208   public static JavacRemoteProto.Message toMessage(UUID requestId, JavacRemoteProto.Message.Request request) {
209     return JavacRemoteProto.Message.newBuilder().setMessageType(JavacRemoteProto.Message.Type.REQUEST).setSessionId(toProtoUUID(requestId)).setRequest(request).build();
210   }
211
212   public static JavacRemoteProto.Message toMessage(UUID requestId, JavacRemoteProto.Message.Response response) {
213     return JavacRemoteProto.Message.newBuilder().setMessageType(JavacRemoteProto.Message.Type.RESPONSE).setSessionId(toProtoUUID(requestId)).setResponse(response).build();
214   }
215
216   public static JavacRemoteProto.Message toMessage(UUID requestId, JavacRemoteProto.Message.Failure failure) {
217     return JavacRemoteProto.Message.newBuilder().setMessageType(JavacRemoteProto.Message.Type.FAILURE).setSessionId(toProtoUUID(requestId)).setFailure(failure).build();
218   }
219
220   public static JavacRemoteProto.Message.UUID toProtoUUID(UUID requestId) {
221     return JavacRemoteProto.Message.UUID.newBuilder().setMostSigBits(requestId.getMostSignificantBits()).setLeastSigBits(requestId.getLeastSignificantBits()).build();
222   }
223
224   public static UUID fromProtoUUID(JavacRemoteProto.Message.UUID requestId) {
225     return new UUID(requestId.getMostSigBits(), requestId.getLeastSigBits());
226   }
227
228   private static JavacRemoteProto.Message.Response.OutputObject.Kind convertKind(JavaFileObject.Kind kind) {
229     switch (kind) {
230       case CLASS:
231         return JavacRemoteProto.Message.Response.OutputObject.Kind.CLASS;
232       case SOURCE:
233         return JavacRemoteProto.Message.Response.OutputObject.Kind.SOURCE;
234       case HTML:
235         return JavacRemoteProto.Message.Response.OutputObject.Kind.HTML;
236       default:
237         return JavacRemoteProto.Message.Response.OutputObject.Kind.OTHER;
238     }
239   }
240
241   private static JavacRemoteProto.Message.Response.CompileMessage.Kind convertKind(Diagnostic.Kind kind) {
242     switch (kind) {
243       case ERROR: return JavacRemoteProto.Message.Response.CompileMessage.Kind.ERROR;
244       case MANDATORY_WARNING: return JavacRemoteProto.Message.Response.CompileMessage.Kind.MANDATORY_WARNING;
245       case WARNING: return JavacRemoteProto.Message.Response.CompileMessage.Kind.WARNING;
246       case NOTE: return JavacRemoteProto.Message.Response.CompileMessage.Kind.NOTE;
247       default:
248         return JavacRemoteProto.Message.Response.CompileMessage.Kind.OTHER;
249     }
250   }
251 }