blob: ab4d284516e1b43bf0b52ab4c87c4a93c1f0b3e6 [file] [log] [blame]
Adam Lesinski1ab598f2015-08-14 14:26:04 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef AAPT_DIAGNOSTICS_H
18#define AAPT_DIAGNOSTICS_H
19
20#include "Source.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070021#include "util/StringPiece.h"
22#include "util/Util.h"
23
24#include <iostream>
25#include <sstream>
26#include <string>
27
28namespace aapt {
29
30struct DiagMessageActual {
31 Source source;
32 std::string message;
33};
34
35struct DiagMessage {
36private:
37 Source mSource;
38 std::stringstream mMessage;
39
40public:
41 DiagMessage() = default;
42
43 DiagMessage(const StringPiece& src) : mSource(src) {
44 }
45
46 DiagMessage(const Source& src) : mSource(src) {
47 }
48
49 template <typename T> DiagMessage& operator<<(const T& value) {
50 mMessage << value;
51 return *this;
52 }
Adam Lesinski1ab598f2015-08-14 14:26:04 -070053
54 DiagMessageActual build() const {
55 return DiagMessageActual{ mSource, mMessage.str() };
56 }
57};
58
59struct IDiagnostics {
60 virtual ~IDiagnostics() = default;
61
62 virtual void error(const DiagMessage& message) = 0;
63 virtual void warn(const DiagMessage& message) = 0;
64 virtual void note(const DiagMessage& message) = 0;
65};
66
67struct StdErrDiagnostics : public IDiagnostics {
Adam Lesinski9ba47d82015-10-13 11:37:10 -070068 size_t mNumErrors = 0;
69
Adam Lesinski1ab598f2015-08-14 14:26:04 -070070 void emit(const DiagMessage& msg, const char* tag) {
71 DiagMessageActual actual = msg.build();
72 if (!actual.source.path.empty()) {
73 std::cerr << actual.source << ": ";
74 }
75 std::cerr << tag << actual.message << "." << std::endl;
76 }
77
78 void error(const DiagMessage& msg) override {
Adam Lesinski9ba47d82015-10-13 11:37:10 -070079 if (mNumErrors < 20) {
80 emit(msg, "error: ");
81 }
82 mNumErrors++;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070083 }
84
85 void warn(const DiagMessage& msg) override {
86 emit(msg, "warn: ");
87 }
88
89 void note(const DiagMessage& msg) override {
90 emit(msg, "note: ");
91 }
92};
93
94} // namespace aapt
95
96#endif /* AAPT_DIAGNOSTICS_H */