001    /*
002     * Copyright 2010-2015 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.cli.common.messages;
018    
019    import com.intellij.openapi.util.text.StringUtil;
020    import kotlin.io.IoPackage;
021    import org.jetbrains.annotations.NotNull;
022    import org.jetbrains.annotations.Nullable;
023    
024    import java.io.File;
025    
026    public interface MessageRenderer {
027    
028        MessageRenderer XML = new MessageRenderer() {
029            @Override
030            public String renderPreamble() {
031                return "<MESSAGES>";
032            }
033    
034            @Override
035            public String render(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location) {
036                StringBuilder out = new StringBuilder();
037                out.append("<").append(severity.toString());
038                if (location.getPath() != null) {
039                    out.append(" path=\"").append(e(location.getPath())).append("\"");
040                    out.append(" line=\"").append(location.getLine()).append("\"");
041                    out.append(" column=\"").append(location.getColumn()).append("\"");
042                }
043                out.append(">");
044    
045                out.append(e(message));
046    
047                out.append("</").append(severity.toString()).append(">\n");
048                return out.toString();
049            }
050    
051            private String e(String str) {
052                return StringUtil.escapeXml(str);
053            }
054    
055            @Override
056            public String renderConclusion() {
057                return "</MESSAGES>";
058            }
059        };
060    
061        MessageRenderer PLAIN_FULL_PATHS = new PlainText() {
062            @Nullable
063            @Override
064            protected String getPath(@NotNull CompilerMessageLocation location) {
065                return location.getPath();
066            }
067        };
068    
069        MessageRenderer PLAIN_RELATIVE_PATHS = new PlainText() {
070            private final File cwd = new File(".").getAbsoluteFile();
071    
072            @Nullable
073            @Override
074            protected String getPath(@NotNull CompilerMessageLocation location) {
075                String path = location.getPath();
076                return cwd == null || path == null ? path : IoPackage.relativePath(cwd, new File(path));
077            }
078        };
079    
080        abstract class PlainText implements MessageRenderer {
081            @Override
082            public String renderPreamble() {
083                return "";
084            }
085    
086            @Override
087            public String render(
088                    @NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location
089            ) {
090                String path = getPath(location);
091                String position = path == null ? "" : path + ": (" + (location.getLine() + ", " + location.getColumn()) + ") ";
092                return severity + ": " + position + message;
093            }
094    
095            @Nullable
096            protected abstract String getPath(@NotNull CompilerMessageLocation location);
097    
098            @Override
099            public String renderConclusion() {
100                return "";
101            }
102        }
103    
104        String renderPreamble();
105    
106        String render(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location);
107    
108        String renderConclusion();
109    }