65d780c66cf15355080e3305bb90ce8102209e16
[idea/community.git] / jps / jps-builders / src / org / jetbrains / jps / api / CmdlineProtoUtil.java
1 // Copyright 2000-2019 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.api;
3
4 import com.intellij.openapi.util.Pair;
5 import org.jetbrains.annotations.Nullable;
6 import org.jetbrains.jps.builders.BuildTargetType;
7 import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
8 import org.jetbrains.jps.incremental.messages.BuildMessage;
9
10 import java.io.ByteArrayOutputStream;
11 import java.io.PrintStream;
12 import java.nio.charset.StandardCharsets;
13 import java.util.*;
14
15 import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.BuilderMessage;
16 import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
17
18 /**
19  * @author Eugene Zhuravlev
20  */
21 public class CmdlineProtoUtil {
22
23   public static CmdlineRemoteProto.Message.ControllerMessage createUpToDateCheckRequest(String project,
24                                                                                         List<? extends TargetTypeBuildScope> scopes,
25                                                                                         Collection<String> paths,
26                                                                                         final Map<String, String> userData,
27                                                                                         final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals,
28                                                                                         final @Nullable CmdlineRemoteProto.Message.ControllerMessage.FSEvent event) {
29     return createBuildParametersMessage(
30       CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.UP_TO_DATE_CHECK, project, scopes, userData, paths, globals, event
31     );
32   }
33
34   public static CmdlineRemoteProto.Message.ControllerMessage createBuildRequest(String project,
35                                                                                 List<? extends TargetTypeBuildScope> scopes,
36                                                                                 Collection<String> paths,
37                                                                                 final Map<String, String> userData,
38                                                                                 final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals,
39                                                                                 final @Nullable CmdlineRemoteProto.Message.ControllerMessage.FSEvent event) {
40     return createBuildParametersMessage(CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.BUILD, project, scopes,
41                                         userData, paths, globals, event);
42   }
43
44   public static List<TargetTypeBuildScope> createAllModulesScopes(final boolean forceBuild) {
45     return Arrays.asList(
46       createAllTargetsScope(JavaModuleBuildTargetType.PRODUCTION, forceBuild),
47       createAllTargetsScope(JavaModuleBuildTargetType.TEST, forceBuild)
48     );
49   }
50
51   public static TargetTypeBuildScope createAllTargetsScope(BuildTargetType<?> type, boolean forceBuild) {
52     return TargetTypeBuildScope.newBuilder()
53       .setTypeId(type.getTypeId())
54       .setAllTargets(true)
55       .setForceBuild(forceBuild)
56       .build();
57   }
58
59   public static TargetTypeBuildScope createTargetsScope(final String targetTypeId, List<String> targetIds, boolean forceBuild) {
60     return TargetTypeBuildScope.newBuilder().setTypeId(targetTypeId).setForceBuild(forceBuild).addAllTargetId(targetIds).build();
61   }
62
63   private static CmdlineRemoteProto.Message.ControllerMessage createBuildParametersMessage(CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type buildType,
64                                                                                           String project,
65                                                                                           List<? extends TargetTypeBuildScope> scopes,
66                                                                                           Map<String, String> userData,
67                                                                                           Collection<String> paths,
68                                                                                           final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals,
69                                                                                           @Nullable CmdlineRemoteProto.Message.ControllerMessage.FSEvent initialEvent) {
70     final CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Builder
71       builder = CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.newBuilder();
72     builder.setGlobalSettings(globals);
73     builder.setBuildType(buildType);
74     builder.setProjectId(project);
75     builder.addAllScope(scopes);
76     if (!userData.isEmpty()) {
77       for (Map.Entry<String, String> entry : userData.entrySet()) {
78         final String key = entry.getKey();
79         final String value = entry.getValue();
80         if (key != null && value != null) {
81           builder.addBuilderParameter(createPair(key, value));
82         }
83       }
84     }
85     if (!paths.isEmpty()) {
86       builder.addAllFilePath(paths);
87     }
88     final CmdlineRemoteProto.Message.ControllerMessage.Builder controlMessageBuilder = CmdlineRemoteProto.Message.ControllerMessage.newBuilder();
89     if (initialEvent != null) {
90       controlMessageBuilder.setFsEvent(initialEvent);
91     }
92     return controlMessageBuilder.setType(CmdlineRemoteProto.Message.ControllerMessage.Type.BUILD_PARAMETERS).setParamsMessage(builder.build()).build();
93   }
94
95
96   public static CmdlineRemoteProto.Message.KeyValuePair createPair(String key, String value) {
97     return CmdlineRemoteProto.Message.KeyValuePair.newBuilder().setKey(key).setValue(value).build();
98   }
99
100   public static CmdlineRemoteProto.Message.Failure createFailure(String description, @Nullable Throwable cause) {
101     final CmdlineRemoteProto.Message.Failure.Builder builder = CmdlineRemoteProto.Message.Failure.newBuilder();
102     if (description != null) {
103       builder.setDescription(description);
104     }
105     if (cause != null) {
106       final ByteArrayOutputStream baos = new ByteArrayOutputStream();
107       try (PrintStream stream = new PrintStream(baos)) {
108         cause.printStackTrace(stream);
109       }
110       final String stacktrace = new String(baos.toByteArray(), StandardCharsets.UTF_8);
111       builder.setStacktrace(stacktrace);
112       if (description == null) {
113         builder.setDescription(stacktrace);
114       }
115     }
116     return builder.build();
117   }
118
119   public static CmdlineRemoteProto.Message.ControllerMessage createCancelCommand() {
120     return CmdlineRemoteProto.Message.ControllerMessage.newBuilder()
121       .setType(CmdlineRemoteProto.Message.ControllerMessage.Type.CANCEL_BUILD_COMMAND).build();
122   }
123
124   public static BuilderMessage createCompileProgressMessageResponse(String text) {
125     return createCompileMessage(BuildMessage.Kind.PROGRESS, text, null, -1L, -1L, -1L, -1, -1, -1.0f);
126   }
127
128   public static BuilderMessage createCompileProgressMessageResponse(String text, float done) {
129     return createCompileMessage(BuildMessage.Kind.PROGRESS, text, null, -1L, -1L, -1L, -1, -1, done);
130   }
131
132   public static BuilderMessage createCompileMessage(final BuildMessage.Kind kind,
133                                                                                String text,
134                                                                                String path,
135                                                                                long beginOffset, long endOffset, long offset, long line,
136                                                                                long column, float done) {
137
138     final BuilderMessage.CompileMessage.Builder builder = BuilderMessage.CompileMessage.newBuilder();
139     switch (kind) {
140       case ERROR:
141         builder.setKind(BuilderMessage.CompileMessage.Kind.ERROR);
142         break;
143       case WARNING:
144         builder.setKind(BuilderMessage.CompileMessage.Kind.WARNING);
145         break;
146       case INFO:
147         builder.setKind(BuilderMessage.CompileMessage.Kind.INFO);
148         break;
149       case JPS_INFO:
150         builder.setKind(BuilderMessage.CompileMessage.Kind.JPS_INFO);
151         break;
152       case INTERNAL_BUILDER_ERROR:
153         builder.setKind(BuilderMessage.CompileMessage.Kind.INTERNAL_BUILDER_ERROR);
154         break;
155       case OTHER:
156         builder.setKind(BuilderMessage.CompileMessage.Kind.OTHER);
157         break;
158       default:
159         builder.setKind(BuilderMessage.CompileMessage.Kind.PROGRESS);
160     }
161     if (text != null) {
162       builder.setText(text);
163     }
164     if (path != null) {
165       builder.setSourceFilePath(path);
166     }
167     if (beginOffset >= 0L) {
168       builder.setProblemBeginOffset(beginOffset);
169     }
170     if (endOffset >= 0L) {
171       builder.setProblemEndOffset(endOffset);
172     }
173     if (offset >= 0L) {
174       builder.setProblemLocationOffset(offset);
175     }
176     if (line >= 0L) {
177       builder.setLine(line);
178     }
179     if (column >= 0L) {
180       builder.setColumn(column);
181     }
182     if (done >= 0.0f) {
183       builder.setDone(done);
184     }
185     return BuilderMessage.newBuilder().setType(BuilderMessage.Type.COMPILE_MESSAGE).setCompileMessage(builder.build()).build();
186   }
187
188   public static BuilderMessage createCustomBuilderMessage(String builderId, String messageType, String messageText) {
189     BuilderMessage.BuildEvent.CustomBuilderMessage builderMessage =
190       BuilderMessage.BuildEvent.CustomBuilderMessage.newBuilder()
191         .setBuilderId(builderId)
192         .setMessageType(messageType)
193         .setMessageText(messageText)
194         .build();
195     return createBuildEvent(BuilderMessage.BuildEvent.Type.CUSTOM_BUILDER_MESSAGE, null, null, null, builderMessage);
196   }
197
198   public static BuilderMessage createBuildCompletedEvent(@Nullable String description, final BuilderMessage.BuildEvent.Status status) {
199     return createBuildEvent(BuilderMessage.BuildEvent.Type.BUILD_COMPLETED, description, status, null, null);
200   }
201
202   public static BuilderMessage createFileGeneratedEvent(final Collection<? extends Pair<String, String>> paths) {
203     return createBuildEvent(BuilderMessage.BuildEvent.Type.FILES_GENERATED, null, null, paths, null);
204   }
205
206   private static BuilderMessage createBuildEvent(final BuilderMessage.BuildEvent.Type type,
207                                                  @Nullable String description,
208                                                  @Nullable final BuilderMessage.BuildEvent.Status status,
209                                                  @Nullable Collection<? extends Pair<String, String>> generatedPaths,
210                                                  @Nullable final BuilderMessage.BuildEvent.CustomBuilderMessage builderMessage) {
211     final BuilderMessage.BuildEvent.Builder builder = BuilderMessage.BuildEvent.newBuilder().setEventType(type);
212     if (description != null) {
213       builder.setDescription(description);
214     }
215     if (status != null) {
216       builder.setCompletionStatus(status);
217     }
218     if (generatedPaths != null) {
219       for (Pair<String, String> pair : generatedPaths) {
220         final BuilderMessage.BuildEvent.GeneratedFile.Builder fileBuilder = BuilderMessage.BuildEvent.GeneratedFile.newBuilder();
221         final BuilderMessage.BuildEvent.GeneratedFile generatedFile = fileBuilder.setOutputRoot(pair.first).setRelativePath(pair.second).build();
222         builder.addGeneratedFiles(generatedFile);
223       }
224     }
225     if (builderMessage != null) {
226       builder.setCustomBuilderMessage(builderMessage);
227     }
228     return BuilderMessage.newBuilder().setType(BuilderMessage.Type.BUILD_EVENT).setBuildEvent(builder.build()).build();
229   }
230
231   public static BuilderMessage createParamRequest() {
232     return BuilderMessage.newBuilder().setType(BuilderMessage.Type.PARAM_REQUEST).build();
233   }
234
235   public static CmdlineRemoteProto.Message toMessage(UUID sessionId, BuilderMessage builderMessage) {
236     return CmdlineRemoteProto.Message.newBuilder().setSessionId(toProtoUUID(sessionId)).setType(CmdlineRemoteProto.Message.Type.BUILDER_MESSAGE).setBuilderMessage(builderMessage).build();
237   }
238
239   public static CmdlineRemoteProto.Message toMessage(UUID sessionId, CmdlineRemoteProto.Message.ControllerMessage builderMessage) {
240     return CmdlineRemoteProto.Message.newBuilder().setSessionId(toProtoUUID(sessionId)).setType(CmdlineRemoteProto.Message.Type.CONTROLLER_MESSAGE).setControllerMessage(
241       builderMessage).build();
242   }
243
244   public static CmdlineRemoteProto.Message toMessage(UUID sessionId, CmdlineRemoteProto.Message.Failure failure) {
245     return CmdlineRemoteProto.Message.newBuilder().setSessionId(toProtoUUID(sessionId)).setType(CmdlineRemoteProto.Message.Type.FAILURE).setFailure(failure).build();
246   }
247
248   private static CmdlineRemoteProto.Message.UUID toProtoUUID(UUID sessionId) {
249     final CmdlineRemoteProto.Message.UUID.Builder uuidBuilder = CmdlineRemoteProto.Message.UUID.newBuilder();
250     return uuidBuilder.setMostSigBits(sessionId.getMostSignificantBits()).setLeastSigBits(sessionId.getLeastSignificantBits()).build();
251   }
252 }