1 /*
2 * Copyright (C) 2016 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 #include "Annotation.h"
18
19 #include <android-base/logging.h>
20 #include <hidl-util/Formatter.h>
21 #include <hidl-util/StringHelper.h>
22 #include <algorithm>
23 #include <vector>
24
25 namespace android {
26
AnnotationParam(const std::string & name)27 AnnotationParam::AnnotationParam(const std::string& name) : mName(name) {}
28
getName() const29 const std::string& AnnotationParam::getName() const {
30 return mName;
31 }
32
getConstantExpressions()33 std::vector<ConstantExpression*> AnnotationParam::getConstantExpressions() {
34 const auto& constRet = static_cast<const AnnotationParam*>(this)->getConstantExpressions();
35 std::vector<ConstantExpression*> ret(constRet.size());
36 std::transform(constRet.begin(), constRet.end(), ret.begin(),
37 [](const auto* ce) { return const_cast<ConstantExpression*>(ce); });
38 return ret;
39 }
40
getConstantExpressions() const41 std::vector<const ConstantExpression*> AnnotationParam::getConstantExpressions() const {
42 return {};
43 }
44
getSingleString() const45 std::string AnnotationParam::getSingleString() const {
46 std::string value = getSingleValue();
47
48 CHECK(value.size() >= 2 && value[0] == '"' && value[value.size() - 1] == '"')
49 << mName << " must be a string";
50
51 // unquote string
52 value = value.substr(1, value.size() - 2);
53
54 return value;
55 }
56
getSingleBool() const57 bool AnnotationParam::getSingleBool() const {
58 std::string value = getSingleString();
59
60 if (value == "true") {
61 return true;
62 } else if (value == "false") {
63 return false;
64 }
65
66 CHECK(false) << mName << " must be of boolean value (true/false).";
67 return false;
68 }
69
StringAnnotationParam(const std::string & name,std::vector<std::string> * values)70 StringAnnotationParam::StringAnnotationParam(const std::string& name,
71 std::vector<std::string>* values)
72 : AnnotationParam(name), mValues(values) {}
73
getValues() const74 std::vector<std::string> StringAnnotationParam::getValues() const {
75 return *mValues;
76 }
77
getSingleValue() const78 std::string StringAnnotationParam::getSingleValue() const {
79 CHECK_EQ(mValues->size(), 1u) << mName << " requires one value but has multiple";
80 return mValues->at(0);
81 }
82
ConstantExpressionAnnotationParam(const std::string & name,std::vector<ConstantExpression * > * values)83 ConstantExpressionAnnotationParam::ConstantExpressionAnnotationParam(
84 const std::string& name, std::vector<ConstantExpression*>* values)
85 : AnnotationParam(name), mValues(values) {}
86
getValues() const87 std::vector<std::string> ConstantExpressionAnnotationParam::getValues() const {
88 std::vector<std::string> ret;
89 for (const auto* value : *mValues) {
90 ret.push_back(value->value());
91 };
92 return ret;
93 }
94
getSingleValue() const95 std::string ConstantExpressionAnnotationParam::getSingleValue() const {
96 CHECK_EQ(mValues->size(), 1u) << mName << " requires one value but has multiple";
97 return mValues->at(0)->value();
98 }
99
getConstantExpressions() const100 std::vector<const ConstantExpression*> ConstantExpressionAnnotationParam::getConstantExpressions()
101 const {
102 std::vector<const ConstantExpression*> ret;
103 ret.insert(ret.end(), mValues->begin(), mValues->end());
104 return ret;
105 }
106
Annotation(const char * name,AnnotationParamVector * params)107 Annotation::Annotation(const char* name, AnnotationParamVector* params)
108 : mName(name), mParams(params) {}
109
name() const110 std::string Annotation::name() const {
111 return mName;
112 }
113
params() const114 const AnnotationParamVector &Annotation::params() const {
115 return *mParams;
116 }
117
getParam(const std::string & name) const118 const AnnotationParam *Annotation::getParam(const std::string &name) const {
119 for (const auto* i : *mParams) {
120 if (i->getName() == name) {
121 return i;
122 }
123 }
124
125 return nullptr;
126 }
127
getConstantExpressions()128 std::vector<ConstantExpression*> Annotation::getConstantExpressions() {
129 const auto& constRet = static_cast<const Annotation*>(this)->getConstantExpressions();
130 std::vector<ConstantExpression*> ret(constRet.size());
131 std::transform(constRet.begin(), constRet.end(), ret.begin(),
132 [](const auto* ce) { return const_cast<ConstantExpression*>(ce); });
133 return ret;
134 }
135
getConstantExpressions() const136 std::vector<const ConstantExpression*> Annotation::getConstantExpressions() const {
137 std::vector<const ConstantExpression*> ret;
138 for (const auto* param : *mParams) {
139 const auto& retParam = param->getConstantExpressions();
140 ret.insert(ret.end(), retParam.begin(), retParam.end());
141 }
142 return ret;
143 }
144
dump(Formatter & out) const145 void Annotation::dump(Formatter &out) const {
146 out << "@" << mName;
147
148 if (mParams->size() == 0) {
149 return;
150 }
151
152 out << "(";
153
154 for (size_t i = 0; i < mParams->size(); ++i) {
155 if (i > 0) {
156 out << ", ";
157 }
158
159 const AnnotationParam* param = mParams->at(i);
160
161 out << param->getName() << "=";
162
163 const std::vector<std::string>& values = param->getValues();
164 if (values.size() > 1) {
165 out << "{";
166 }
167
168 out << StringHelper::JoinStrings(values, ", ");
169
170 if (values.size() > 1) {
171 out << "}";
172 }
173 }
174
175 out << ")";
176 }
177
178 } // namespace android
179
180