| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 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 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 17 | #include "proto/ProtoSerialize.h" | 
|  | 18 |  | 
|  | 19 | #include "android-base/logging.h" | 
|  | 20 | #include "androidfw/ResourceTypes.h" | 
|  | 21 |  | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 22 | #include "ResourceTable.h" | 
|  | 23 | #include "ResourceUtils.h" | 
|  | 24 | #include "ValueVisitor.h" | 
|  | 25 | #include "proto/ProtoHelpers.h" | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 26 |  | 
|  | 27 | namespace aapt { | 
|  | 28 |  | 
|  | 29 | namespace { | 
|  | 30 |  | 
|  | 31 | class ReferenceIdToNameVisitor : public ValueVisitor { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 32 | public: | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 33 | using ValueVisitor::Visit; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 34 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 35 | explicit ReferenceIdToNameVisitor( | 
|  | 36 | const std::map<ResourceId, ResourceNameRef>* mapping) | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 37 | : mapping_(mapping) { | 
|  | 38 | CHECK(mapping_ != nullptr); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 39 | } | 
|  | 40 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 41 | void Visit(Reference* reference) override { | 
|  | 42 | if (!reference->id || !reference->id.value().is_valid()) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 43 | return; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 44 | } | 
|  | 45 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 46 | ResourceId id = reference->id.value(); | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 47 | auto cache_iter = mapping_->find(id); | 
|  | 48 | if (cache_iter != mapping_->end()) { | 
|  | 49 | reference->name = cache_iter->second.ToResourceName(); | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 50 | } | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 51 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 52 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 53 | private: | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 54 | const std::map<ResourceId, ResourceNameRef>* mapping_; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 55 | }; | 
|  | 56 |  | 
|  | 57 | class PackagePbDeserializer { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 58 | public: | 
|  | 59 | PackagePbDeserializer(const android::ResStringPool* valuePool, | 
|  | 60 | const android::ResStringPool* sourcePool, | 
|  | 61 | const android::ResStringPool* symbolPool, | 
|  | 62 | const Source& source, IDiagnostics* diag) | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 63 | : value_pool_(valuePool), | 
|  | 64 | source_pool_(sourcePool), | 
|  | 65 | symbol_pool_(symbolPool), | 
|  | 66 | source_(source), | 
|  | 67 | diag_(diag) {} | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 68 |  | 
|  | 69 | public: | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 70 | bool DeserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 71 | Maybe<uint8_t> id; | 
|  | 72 | if (pbPackage.has_package_id()) { | 
|  | 73 | id = static_cast<uint8_t>(pbPackage.package_id()); | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 74 | } | 
|  | 75 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 76 | std::map<ResourceId, ResourceNameRef> idIndex; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 77 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 78 | ResourceTablePackage* pkg = | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 79 | table->CreatePackage(pbPackage.package_name(), id); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 80 | for (const pb::Type& pbType : pbPackage.types()) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 81 | const ResourceType* resType = ParseResourceType(pbType.name()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 82 | if (!resType) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 83 | diag_->Error(DiagMessage(source_) << "unknown type '" << pbType.name() | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 84 | << "'"); | 
|  | 85 | return {}; | 
|  | 86 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 87 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 88 | ResourceTableType* type = pkg->FindOrCreateType(*resType); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 89 |  | 
|  | 90 | for (const pb::Entry& pbEntry : pbType.entries()) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 91 | ResourceEntry* entry = type->FindOrCreateEntry(pbEntry.name()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 92 |  | 
|  | 93 | // Deserialize the symbol status (public/private with source and | 
|  | 94 | // comments). | 
|  | 95 | if (pbEntry.has_symbol_status()) { | 
|  | 96 | const pb::SymbolStatus& pbStatus = pbEntry.symbol_status(); | 
|  | 97 | if (pbStatus.has_source()) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 98 | DeserializeSourceFromPb(pbStatus.source(), *source_pool_, | 
|  | 99 | &entry->symbol_status.source); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 100 | } | 
|  | 101 |  | 
|  | 102 | if (pbStatus.has_comment()) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 103 | entry->symbol_status.comment = pbStatus.comment(); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 104 | } | 
|  | 105 |  | 
|  | 106 | SymbolState visibility = | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 107 | DeserializeVisibilityFromPb(pbStatus.visibility()); | 
|  | 108 | entry->symbol_status.state = visibility; | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 109 |  | 
|  | 110 | if (visibility == SymbolState::kPublic) { | 
|  | 111 | // This is a public symbol, we must encode the ID now if there is | 
|  | 112 | // one. | 
|  | 113 | if (pbEntry.has_id()) { | 
|  | 114 | entry->id = static_cast<uint16_t>(pbEntry.id()); | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 115 | } | 
|  | 116 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 117 | if (type->symbol_status.state != SymbolState::kPublic) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 118 | // If the type has not been made public, do so now. | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 119 | type->symbol_status.state = SymbolState::kPublic; | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 120 | if (pbType.has_id()) { | 
|  | 121 | type->id = static_cast<uint8_t>(pbType.id()); | 
|  | 122 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 123 | } | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 124 | } else if (visibility == SymbolState::kPrivate) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 125 | if (type->symbol_status.state == SymbolState::kUndefined) { | 
|  | 126 | type->symbol_status.state = SymbolState::kPrivate; | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 127 | } | 
|  | 128 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 129 | } | 
|  | 130 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 131 | ResourceId resId(pbPackage.package_id(), pbType.id(), pbEntry.id()); | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 132 | if (resId.is_valid()) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 133 | idIndex[resId] = ResourceNameRef(pkg->name, type->type, entry->name); | 
|  | 134 | } | 
|  | 135 |  | 
|  | 136 | for (const pb::ConfigValue& pbConfigValue : pbEntry.config_values()) { | 
|  | 137 | const pb::ConfigDescription& pbConfig = pbConfigValue.config(); | 
|  | 138 |  | 
|  | 139 | ConfigDescription config; | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 140 | if (!DeserializeConfigDescriptionFromPb(pbConfig, &config)) { | 
|  | 141 | diag_->Error(DiagMessage(source_) << "invalid configuration"); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 142 | return {}; | 
|  | 143 | } | 
|  | 144 |  | 
|  | 145 | ResourceConfigValue* configValue = | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 146 | entry->FindOrCreateValue(config, pbConfig.product()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 147 | if (configValue->value) { | 
|  | 148 | // Duplicate config. | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 149 | diag_->Error(DiagMessage(source_) << "duplicate configuration"); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 150 | return {}; | 
|  | 151 | } | 
|  | 152 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 153 | configValue->value = DeserializeValueFromPb( | 
|  | 154 | pbConfigValue.value(), config, &table->string_pool); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 155 | if (!configValue->value) { | 
|  | 156 | return {}; | 
|  | 157 | } | 
|  | 158 | } | 
|  | 159 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 160 | } | 
|  | 161 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 162 | ReferenceIdToNameVisitor visitor(&idIndex); | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 163 | VisitAllValuesInPackage(pkg, &visitor); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 164 | return true; | 
|  | 165 | } | 
|  | 166 |  | 
|  | 167 | private: | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 168 | std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item, | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 169 | const ConfigDescription& config, | 
|  | 170 | StringPool* pool) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 171 | if (pb_item.has_ref()) { | 
|  | 172 | const pb::Reference& pb_ref = pb_item.ref(); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 173 | std::unique_ptr<Reference> ref = util::make_unique<Reference>(); | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 174 | if (!DeserializeReferenceFromPb(pb_ref, ref.get())) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 175 | return {}; | 
|  | 176 | } | 
|  | 177 | return std::move(ref); | 
|  | 178 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 179 | } else if (pb_item.has_prim()) { | 
|  | 180 | const pb::Primitive& pb_prim = pb_item.prim(); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 181 | android::Res_value prim = {}; | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 182 | prim.dataType = static_cast<uint8_t>(pb_prim.type()); | 
|  | 183 | prim.data = pb_prim.data(); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 184 | return util::make_unique<BinaryPrimitive>(prim); | 
|  | 185 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 186 | } else if (pb_item.has_id()) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 187 | return util::make_unique<Id>(); | 
|  | 188 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 189 | } else if (pb_item.has_str()) { | 
|  | 190 | const uint32_t idx = pb_item.str().idx(); | 
|  | 191 | const std::string str = util::GetString(*value_pool_, idx); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 192 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 193 | const android::ResStringPool_span* spans = value_pool_->styleAt(idx); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 194 | if (spans && spans->name.index != android::ResStringPool_span::END) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 195 | StyleString style_str = {str}; | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 196 | while (spans->name.index != android::ResStringPool_span::END) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 197 | style_str.spans.push_back( | 
|  | 198 | Span{util::GetString(*value_pool_, spans->name.index), | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 199 | spans->firstChar, spans->lastChar}); | 
|  | 200 | spans++; | 
|  | 201 | } | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 202 | return util::make_unique<StyledString>(pool->MakeRef( | 
|  | 203 | style_str, | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 204 | StringPool::Context(StringPool::Context::kStylePriority, config))); | 
|  | 205 | } | 
|  | 206 | return util::make_unique<String>( | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 207 | pool->MakeRef(str, StringPool::Context(config))); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 208 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 209 | } else if (pb_item.has_raw_str()) { | 
|  | 210 | const uint32_t idx = pb_item.raw_str().idx(); | 
|  | 211 | const std::string str = util::GetString(*value_pool_, idx); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 212 | return util::make_unique<RawString>( | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 213 | pool->MakeRef(str, StringPool::Context(config))); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 214 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 215 | } else if (pb_item.has_file()) { | 
|  | 216 | const uint32_t idx = pb_item.file().path_idx(); | 
|  | 217 | const std::string str = util::GetString(*value_pool_, idx); | 
|  | 218 | return util::make_unique<FileReference>(pool->MakeRef( | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 219 | str, | 
|  | 220 | StringPool::Context(StringPool::Context::kHighPriority, config))); | 
|  | 221 |  | 
|  | 222 | } else { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 223 | diag_->Error(DiagMessage(source_) << "unknown item"); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 224 | } | 
|  | 225 | return {}; | 
|  | 226 | } | 
|  | 227 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 228 | std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value, | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 229 | const ConfigDescription& config, | 
|  | 230 | StringPool* pool) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 231 | const bool is_weak = pb_value.has_weak() ? pb_value.weak() : false; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 232 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 233 | std::unique_ptr<Value> value; | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 234 | if (pb_value.has_item()) { | 
|  | 235 | value = DeserializeItemFromPb(pb_value.item(), config, pool); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 236 | if (!value) { | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 237 | return {}; | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 238 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 239 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 240 | } else if (pb_value.has_compound_value()) { | 
|  | 241 | const pb::CompoundValue& pb_compound_value = pb_value.compound_value(); | 
|  | 242 | if (pb_compound_value.has_attr()) { | 
|  | 243 | const pb::Attribute& pb_attr = pb_compound_value.attr(); | 
|  | 244 | std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(is_weak); | 
|  | 245 | attr->type_mask = pb_attr.format_flags(); | 
|  | 246 | attr->min_int = pb_attr.min_int(); | 
|  | 247 | attr->max_int = pb_attr.max_int(); | 
|  | 248 | for (const pb::Attribute_Symbol& pb_symbol : pb_attr.symbols()) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 249 | Attribute::Symbol symbol; | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 250 | DeserializeItemCommon(pb_symbol, &symbol.symbol); | 
|  | 251 | if (!DeserializeReferenceFromPb(pb_symbol.name(), &symbol.symbol)) { | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 252 | return {}; | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 253 | } | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 254 | symbol.value = pb_symbol.value(); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 255 | attr->symbols.push_back(std::move(symbol)); | 
|  | 256 | } | 
|  | 257 | value = std::move(attr); | 
|  | 258 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 259 | } else if (pb_compound_value.has_style()) { | 
|  | 260 | const pb::Style& pb_style = pb_compound_value.style(); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 261 | std::unique_ptr<Style> style = util::make_unique<Style>(); | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 262 | if (pb_style.has_parent()) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 263 | style->parent = Reference(); | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 264 | if (!DeserializeReferenceFromPb(pb_style.parent(), | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 265 | &style->parent.value())) { | 
|  | 266 | return {}; | 
|  | 267 | } | 
|  | 268 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 269 | if (pb_style.has_parent_source()) { | 
|  | 270 | Source parent_source; | 
|  | 271 | DeserializeSourceFromPb(pb_style.parent_source(), *source_pool_, | 
|  | 272 | &parent_source); | 
|  | 273 | style->parent.value().SetSource(std::move(parent_source)); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 274 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 275 | } | 
|  | 276 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 277 | for (const pb::Style_Entry& pb_entry : pb_style.entries()) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 278 | Style::Entry entry; | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 279 | DeserializeItemCommon(pb_entry, &entry.key); | 
|  | 280 | if (!DeserializeReferenceFromPb(pb_entry.key(), &entry.key)) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 281 | return {}; | 
|  | 282 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 283 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 284 | entry.value = DeserializeItemFromPb(pb_entry.item(), config, pool); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 285 | if (!entry.value) { | 
|  | 286 | return {}; | 
|  | 287 | } | 
|  | 288 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 289 | DeserializeItemCommon(pb_entry, entry.value.get()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 290 | style->entries.push_back(std::move(entry)); | 
|  | 291 | } | 
|  | 292 | value = std::move(style); | 
|  | 293 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 294 | } else if (pb_compound_value.has_styleable()) { | 
|  | 295 | const pb::Styleable& pb_styleable = pb_compound_value.styleable(); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 296 | std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>(); | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 297 | for (const pb::Styleable_Entry& pb_entry : pb_styleable.entries()) { | 
|  | 298 | Reference attr_ref; | 
|  | 299 | DeserializeItemCommon(pb_entry, &attr_ref); | 
|  | 300 | DeserializeReferenceFromPb(pb_entry.attr(), &attr_ref); | 
|  | 301 | styleable->entries.push_back(std::move(attr_ref)); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 302 | } | 
|  | 303 | value = std::move(styleable); | 
|  | 304 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 305 | } else if (pb_compound_value.has_array()) { | 
|  | 306 | const pb::Array& pb_array = pb_compound_value.array(); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 307 | std::unique_ptr<Array> array = util::make_unique<Array>(); | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 308 | for (const pb::Array_Entry& pb_entry : pb_array.entries()) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 309 | std::unique_ptr<Item> item = | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 310 | DeserializeItemFromPb(pb_entry.item(), config, pool); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 311 | if (!item) { | 
|  | 312 | return {}; | 
|  | 313 | } | 
|  | 314 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 315 | DeserializeItemCommon(pb_entry, item.get()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 316 | array->items.push_back(std::move(item)); | 
|  | 317 | } | 
|  | 318 | value = std::move(array); | 
|  | 319 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 320 | } else if (pb_compound_value.has_plural()) { | 
|  | 321 | const pb::Plural& pb_plural = pb_compound_value.plural(); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 322 | std::unique_ptr<Plural> plural = util::make_unique<Plural>(); | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 323 | for (const pb::Plural_Entry& pb_entry : pb_plural.entries()) { | 
|  | 324 | size_t pluralIdx = DeserializePluralEnumFromPb(pb_entry.arity()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 325 | plural->values[pluralIdx] = | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 326 | DeserializeItemFromPb(pb_entry.item(), config, pool); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 327 | if (!plural->values[pluralIdx]) { | 
|  | 328 | return {}; | 
|  | 329 | } | 
|  | 330 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 331 | DeserializeItemCommon(pb_entry, plural->values[pluralIdx].get()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 332 | } | 
|  | 333 | value = std::move(plural); | 
|  | 334 |  | 
|  | 335 | } else { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 336 | diag_->Error(DiagMessage(source_) << "unknown compound value"); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 337 | return {}; | 
|  | 338 | } | 
|  | 339 | } else { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 340 | diag_->Error(DiagMessage(source_) << "unknown value"); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 341 | return {}; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 342 | } | 
|  | 343 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 344 | CHECK(value) << "forgot to set value"; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 345 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 346 | value->SetWeak(is_weak); | 
|  | 347 | DeserializeItemCommon(pb_value, value.get()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 348 | return value; | 
|  | 349 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 350 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 351 | bool DeserializeReferenceFromPb(const pb::Reference& pb_ref, | 
|  | 352 | Reference* out_ref) { | 
|  | 353 | out_ref->reference_type = DeserializeReferenceTypeFromPb(pb_ref.type()); | 
|  | 354 | out_ref->private_reference = pb_ref.private_(); | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 355 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 356 | if (!pb_ref.has_id() && !pb_ref.has_symbol_idx()) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 357 | return false; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 358 | } | 
|  | 359 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 360 | if (pb_ref.has_id()) { | 
|  | 361 | out_ref->id = ResourceId(pb_ref.id()); | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 362 | } | 
|  | 363 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 364 | if (pb_ref.has_symbol_idx()) { | 
|  | 365 | const std::string str_symbol = | 
|  | 366 | util::GetString(*symbol_pool_, pb_ref.symbol_idx()); | 
|  | 367 | ResourceNameRef name_ref; | 
|  | 368 | if (!ResourceUtils::ParseResourceName(str_symbol, &name_ref, nullptr)) { | 
|  | 369 | diag_->Error(DiagMessage(source_) << "invalid reference name '" | 
|  | 370 | << str_symbol << "'"); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 371 | return false; | 
|  | 372 | } | 
|  | 373 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 374 | out_ref->name = name_ref.ToResourceName(); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 375 | } | 
|  | 376 | return true; | 
|  | 377 | } | 
|  | 378 |  | 
|  | 379 | template <typename T> | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 380 | void DeserializeItemCommon(const T& pb_item, Value* out_value) { | 
|  | 381 | if (pb_item.has_source()) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 382 | Source source; | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 383 | DeserializeSourceFromPb(pb_item.source(), *source_pool_, &source); | 
|  | 384 | out_value->SetSource(std::move(source)); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 385 | } | 
|  | 386 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 387 | if (pb_item.has_comment()) { | 
|  | 388 | out_value->SetComment(pb_item.comment()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 389 | } | 
|  | 390 | } | 
|  | 391 |  | 
|  | 392 | private: | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 393 | const android::ResStringPool* value_pool_; | 
|  | 394 | const android::ResStringPool* source_pool_; | 
|  | 395 | const android::ResStringPool* symbol_pool_; | 
|  | 396 | const Source source_; | 
|  | 397 | IDiagnostics* diag_; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 398 | }; | 
|  | 399 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 400 | }  // namespace | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 401 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 402 | std::unique_ptr<ResourceTable> DeserializeTableFromPb( | 
|  | 403 | const pb::ResourceTable& pb_table, const Source& source, | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 404 | IDiagnostics* diag) { | 
|  | 405 | // We import the android namespace because on Windows NO_ERROR is a macro, not | 
|  | 406 | // an enum, which | 
|  | 407 | // causes errors when qualifying it with android:: | 
|  | 408 | using namespace android; | 
| Adam Lesinski | 803c7c8 | 2016-04-06 16:09:43 -0700 | [diff] [blame] | 409 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 410 | std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>(); | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 411 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 412 | if (!pb_table.has_string_pool()) { | 
|  | 413 | diag->Error(DiagMessage(source) << "no string pool found"); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 414 | return {}; | 
|  | 415 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 416 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 417 | ResStringPool value_pool; | 
|  | 418 | status_t result = value_pool.setTo(pb_table.string_pool().data().data(), | 
|  | 419 | pb_table.string_pool().data().size()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 420 | if (result != NO_ERROR) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 421 | diag->Error(DiagMessage(source) << "invalid string pool"); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 422 | return {}; | 
|  | 423 | } | 
|  | 424 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 425 | ResStringPool source_pool; | 
|  | 426 | if (pb_table.has_source_pool()) { | 
|  | 427 | result = source_pool.setTo(pb_table.source_pool().data().data(), | 
|  | 428 | pb_table.source_pool().data().size()); | 
| Adam Lesinski | 803c7c8 | 2016-04-06 16:09:43 -0700 | [diff] [blame] | 429 | if (result != NO_ERROR) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 430 | diag->Error(DiagMessage(source) << "invalid source pool"); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 431 | return {}; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 432 | } | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 433 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 434 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 435 | ResStringPool symbol_pool; | 
|  | 436 | if (pb_table.has_symbol_pool()) { | 
|  | 437 | result = symbol_pool.setTo(pb_table.symbol_pool().data().data(), | 
|  | 438 | pb_table.symbol_pool().data().size()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 439 | if (result != NO_ERROR) { | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 440 | diag->Error(DiagMessage(source) << "invalid symbol pool"); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 441 | return {}; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 442 | } | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 443 | } | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 444 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 445 | PackagePbDeserializer package_pb_deserializer(&value_pool, &source_pool, | 
|  | 446 | &symbol_pool, source, diag); | 
|  | 447 | for (const pb::Package& pb_package : pb_table.packages()) { | 
|  | 448 | if (!package_pb_deserializer.DeserializeFromPb(pb_package, table.get())) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 449 | return {}; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 450 | } | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 451 | } | 
|  | 452 | return table; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 453 | } | 
|  | 454 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 455 | std::unique_ptr<ResourceFile> DeserializeCompiledFileFromPb( | 
|  | 456 | const pb::CompiledFile& pb_file, const Source& source, IDiagnostics* diag) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 457 | std::unique_ptr<ResourceFile> file = util::make_unique<ResourceFile>(); | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 458 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 459 | ResourceNameRef name_ref; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 460 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 461 | // Need to create an lvalue here so that nameRef can point to something real. | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 462 | if (!ResourceUtils::ParseResourceName(pb_file.resource_name(), &name_ref)) { | 
|  | 463 | diag->Error(DiagMessage(source) | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 464 | << "invalid resource name in compiled file header: " | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 465 | << pb_file.resource_name()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 466 | return {}; | 
|  | 467 | } | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 468 | file->name = name_ref.ToResourceName(); | 
|  | 469 | file->source.path = pb_file.source_path(); | 
|  | 470 | DeserializeConfigDescriptionFromPb(pb_file.config(), &file->config); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 471 |  | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 472 | for (const pb::CompiledFile_Symbol& pb_symbol : pb_file.exported_symbols()) { | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 473 | // Need to create an lvalue here so that nameRef can point to something | 
|  | 474 | // real. | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 475 | if (!ResourceUtils::ParseResourceName(pb_symbol.resource_name(), | 
|  | 476 | &name_ref)) { | 
|  | 477 | diag->Error(DiagMessage(source) | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 478 | << "invalid resource name for exported symbol in " | 
|  | 479 | "compiled file header: " | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 480 | << pb_file.resource_name()); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 481 | return {}; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 482 | } | 
| Adam Lesinski | ce5e56e | 2016-10-21 17:56:45 -0700 | [diff] [blame] | 483 | file->exported_symbols.push_back( | 
|  | 484 | SourcedResourceName{name_ref.ToResourceName(), pb_symbol.line_no()}); | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 485 | } | 
|  | 486 | return file; | 
| Adam Lesinski | 59e04c6 | 2016-02-04 15:59:23 -0800 | [diff] [blame] | 487 | } | 
|  | 488 |  | 
| Adam Lesinski | b54ef10 | 2016-10-21 13:38:42 -0700 | [diff] [blame] | 489 | }  // namespace aapt |