1 /* 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 _ANDROID_DIAGNOSTICS_H 18 #define _ANDROID_DIAGNOSTICS_H 19 20 #include <sstream> 21 #include <string> 22 23 #include "Source.h" 24 #include "android-base/macros.h" 25 #include "androidfw/StringPiece.h" 26 27 namespace android { 28 29 struct DiagMessageActual { 30 Source source; 31 std::string message; 32 }; 33 34 struct DiagMessage { 35 public: 36 DiagMessage() = default; 37 DiagMessageDiagMessage38 explicit DiagMessage(android::StringPiece src) : source_(src) { 39 } 40 DiagMessageDiagMessage41 explicit DiagMessage(const Source& src) : source_(src) { 42 } 43 DiagMessageDiagMessage44 explicit DiagMessage(size_t line) : source_(Source().WithLine(line)) { 45 } 46 47 template <typename T> 48 DiagMessage& operator<<(const T& value) { 49 message_ << value; 50 return *this; 51 } 52 BuildDiagMessage53 DiagMessageActual Build() const { 54 return DiagMessageActual{source_, message_.str()}; 55 } 56 57 private: 58 Source source_; 59 std::stringstream message_; 60 }; 61 62 template <> 63 inline DiagMessage& DiagMessage::operator<<(const ::std::u16string& value) { 64 message_ << value; 65 return *this; 66 } 67 68 struct IDiagnostics { 69 virtual ~IDiagnostics() = default; 70 71 enum class Level { Note, Warn, Error }; 72 73 virtual void Log(Level level, DiagMessageActual& actualMsg) = 0; 74 ErrorIDiagnostics75 virtual void Error(const DiagMessage& message) { 76 DiagMessageActual actual = message.Build(); 77 Log(Level::Error, actual); 78 } 79 WarnIDiagnostics80 virtual void Warn(const DiagMessage& message) { 81 DiagMessageActual actual = message.Build(); 82 Log(Level::Warn, actual); 83 } 84 NoteIDiagnostics85 virtual void Note(const DiagMessage& message) { 86 DiagMessageActual actual = message.Build(); 87 Log(Level::Note, actual); 88 } 89 }; 90 91 class SourcePathDiagnostics : public IDiagnostics { 92 public: SourcePathDiagnostics(const Source & src,IDiagnostics * diag)93 SourcePathDiagnostics(const Source& src, IDiagnostics* diag) : source_(src), diag_(diag) { 94 } 95 Log(Level level,DiagMessageActual & actual_msg)96 void Log(Level level, DiagMessageActual& actual_msg) override { 97 actual_msg.source.path = source_.path; 98 diag_->Log(level, actual_msg); 99 if (level == Level::Error) { 100 error = true; 101 } 102 } 103 HadError()104 bool HadError() { 105 return error; 106 } 107 108 private: 109 Source source_; 110 IDiagnostics* diag_; 111 bool error = false; 112 113 DISALLOW_COPY_AND_ASSIGN(SourcePathDiagnostics); 114 }; 115 116 class NoOpDiagnostics : public IDiagnostics { 117 public: 118 NoOpDiagnostics() = default; 119 Log(Level level,DiagMessageActual & actual_msg)120 void Log(Level level, DiagMessageActual& actual_msg) override { 121 (void)level; 122 (void)actual_msg; 123 } 124 125 DISALLOW_COPY_AND_ASSIGN(NoOpDiagnostics); 126 }; 127 128 } // namespace android 129 130 #endif /* _ANDROID_DIAGNOSTICS_H */ 131