AAPT2: Enable building proto artifacts

- This will allow the bundle tool to ingest the outputs of the aapt2 link
  phase.

Bug: 64143208
Test: manual
Change-Id: I1a4b3ce5c2ffbbdc4bc642c3371a9ef2e7e9ad71
This commit is contained in:
Adam Lesinski
2017-10-13 09:36:53 -07:00
parent 0045116606
commit e59f0d80ec
12 changed files with 188 additions and 148 deletions

View File

@@ -35,11 +35,11 @@ namespace aapt {
namespace {
class PrintVisitor : public DescendingValueVisitor {
class PrintVisitor : public ConstValueVisitor {
public:
using DescendingValueVisitor::Visit;
using ConstValueVisitor::Visit;
void Visit(Attribute* attr) override {
void Visit(const Attribute* attr) override {
std::cout << "(attr) type=";
attr->PrintMask(&std::cout);
static constexpr uint32_t kMask =
@@ -55,7 +55,7 @@ class PrintVisitor : public DescendingValueVisitor {
}
}
void Visit(Style* style) override {
void Visit(const Style* style) override {
std::cout << "(style)";
if (style->parent) {
const Reference& parent_ref = style->parent.value();
@@ -90,15 +90,15 @@ class PrintVisitor : public DescendingValueVisitor {
}
}
void Visit(Array* array) override {
void Visit(const Array* array) override {
array->Print(&std::cout);
}
void Visit(Plural* plural) override {
void Visit(const Plural* plural) override {
plural->Print(&std::cout);
}
void Visit(Styleable* styleable) override {
void Visit(const Styleable* styleable) override {
std::cout << "(styleable)";
for (const auto& attr : styleable->entries) {
std::cout << "\n ";
@@ -116,17 +116,17 @@ class PrintVisitor : public DescendingValueVisitor {
}
}
void VisitItem(Item* item) override {
void VisitItem(const Item* item) override {
item->Print(&std::cout);
}
};
} // namespace
void Debug::PrintTable(ResourceTable* table, const DebugPrintTableOptions& options) {
void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions& options) {
PrintVisitor visitor;
for (auto& package : table->packages) {
for (const auto& package : table.packages) {
std::cout << "Package name=" << package->name;
if (package->id) {
std::cout << " id=" << std::hex << (int)package->id.value() << std::dec;
@@ -261,11 +261,11 @@ void Debug::DumpHex(const void* data, size_t len) {
namespace {
class XmlPrinter : public xml::Visitor {
class XmlPrinter : public xml::ConstVisitor {
public:
using xml::Visitor::Visit;
using xml::ConstVisitor::Visit;
void Visit(xml::Element* el) override {
void Visit(const xml::Element* el) override {
const size_t previous_size = prefix_.size();
for (const xml::NamespaceDecl& decl : el->namespace_decls) {
@@ -301,11 +301,11 @@ class XmlPrinter : public xml::Visitor {
}
prefix_ += " ";
xml::Visitor::Visit(el);
xml::ConstVisitor::Visit(el);
prefix_.resize(previous_size);
}
void Visit(xml::Text* text) override {
void Visit(const xml::Text* text) override {
std::cerr << prefix_ << "T: '" << text->text << "'\n";
}
@@ -315,9 +315,9 @@ class XmlPrinter : public xml::Visitor {
} // namespace
void Debug::DumpXml(xml::XmlResource* doc) {
void Debug::DumpXml(const xml::XmlResource& doc) {
XmlPrinter printer;
doc->root->Accept(&printer);
doc.root->Accept(&printer);
}
} // namespace aapt

View File

@@ -31,13 +31,11 @@ struct DebugPrintTableOptions {
};
struct Debug {
static void PrintTable(ResourceTable* table,
const DebugPrintTableOptions& options = {});
static void PrintTable(const ResourceTable& table, const DebugPrintTableOptions& options = {});
static void PrintStyleGraph(ResourceTable* table,
const ResourceName& target_style);
static void DumpHex(const void* data, size_t len);
static void DumpXml(xml::XmlResource* doc);
static std::string ToString(xml::XmlResource* doc);
static void DumpXml(const xml::XmlResource& doc);
};
} // namespace aapt

View File

@@ -704,8 +704,15 @@ std::unique_ptr<Item> ParseBinaryResValue(const ResourceType& type, const Config
} else {
if (type != ResourceType::kString && util::StartsWith(str, "res/")) {
// This must be a FileReference.
return util::make_unique<FileReference>(dst_pool->MakeRef(
str, StringPool::Context(StringPool::Context::kHighPriority, config)));
std::unique_ptr<FileReference> file_ref =
util::make_unique<FileReference>(dst_pool->MakeRef(
str, StringPool::Context(StringPool::Context::kHighPriority, config)));
if (util::EndsWith(*file_ref->path, ".xml")) {
file_ref->type = ResourceFile::Type::kBinaryXml;
} else if (util::EndsWith(*file_ref->path, ".png")) {
file_ref->type = ResourceFile::Type::kPng;
}
return std::move(file_ref);
}
// There are no styles associated with this string, so treat it as a simple string.

View File

@@ -269,8 +269,19 @@ message StyledString {
// A value that is a reference to an external entity, like an XML file or a PNG.
message FileReference {
enum Type {
UNKNOWN = 0;
PNG = 1;
BINARY_XML = 2;
PROTO_XML = 3;
}
// Path to a file within the APK (typically res/type-config/entry.ext).
string path = 1;
// The type of file this path points to. For UAM bundle, this cannot be
// BINARY_XML.
Type type = 2;
}
// A value that represents a primitive data type (float, int, boolean, etc.).

View File

@@ -41,14 +41,8 @@ message CompiledFile {
// The configuration for which the resource is defined.
aapt.pb.Configuration config = 2;
enum Type {
UNKNOWN = 0;
PNG = 1;
BINARY_XML = 2;
PROTO_XML = 3;
}
Type type = 3;
// The type of the file.
aapt.pb.FileReference.Type type = 3;
// The filesystem path to where the source file originated.
// Mainly used to display helpful error messages.
@@ -56,7 +50,4 @@ message CompiledFile {
// Any symbols this file auto-generates/exports (eg. @+id/foo in an XML file).
repeated Symbol exported_symbol = 5;
// If this is a compiled XML file, this is the root node.
aapt.pb.XmlNode xml_root = 6;
}

View File

@@ -65,21 +65,19 @@ static bool TryDumpFile(IAaptContext* context, const std::string& file_path) {
std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(file_path, &err);
if (zip) {
ResourceTable table;
if (io::IFile* file = zip->FindFile("resources.arsc.flat")) {
if (io::IFile* file = zip->FindFile("resources.pb")) {
std::unique_ptr<io::IData> data = file->OpenAsData();
if (data == nullptr) {
context->GetDiagnostics()->Error(DiagMessage(file_path)
<< "failed to open resources.arsc.flat");
context->GetDiagnostics()->Error(DiagMessage(file_path) << "failed to open resources.pb");
return false;
}
pb::ResourceTable pb_table;
if (!pb_table.ParseFromArray(data->data(), data->size())) {
context->GetDiagnostics()->Error(DiagMessage(file_path) << "invalid resources.arsc.flat");
context->GetDiagnostics()->Error(DiagMessage(file_path) << "invalid resources.pb");
return false;
}
ResourceTable table;
if (!DeserializeTableFromPb(pb_table, &table, &err)) {
context->GetDiagnostics()->Error(DiagMessage(file_path)
<< "failed to parse table: " << err);
@@ -98,7 +96,7 @@ static bool TryDumpFile(IAaptContext* context, const std::string& file_path) {
}
}
Debug::PrintTable(&table, print_options);
Debug::PrintTable(table, print_options);
return true;
}
@@ -137,7 +135,7 @@ static bool TryDumpFile(IAaptContext* context, const std::string& file_path) {
continue;
}
Debug::PrintTable(&table, print_options);
Debug::PrintTable(table, print_options);
} else if (entry->Type() == ContainerEntryType::kResFile) {
pb::internal::CompiledFile pb_compiled_file;
off64_t offset;

View File

@@ -71,6 +71,14 @@ using ::android::base::StringPrintf;
namespace aapt {
constexpr static const char kApkResourceTablePath[] = "resources.arsc";
constexpr static const char kProtoResourceTablePath[] = "resources.pb";
enum class OutputFormat {
kApk,
kProto,
};
struct LinkOptions {
std::string output_path;
std::string manifest_path;
@@ -79,6 +87,7 @@ struct LinkOptions {
std::vector<std::string> assets_dirs;
bool output_to_directory = false;
bool auto_add_overlay = false;
OutputFormat output_format = OutputFormat::kApk;
// Java/Proguard options.
Maybe<std::string> generate_java_class_path;
@@ -253,26 +262,39 @@ class FeatureSplitSymbolTableDelegate : public DefaultSymbolTableDelegate {
IAaptContext* context_;
};
static bool FlattenXml(IAaptContext* context, xml::XmlResource* xml_res, const StringPiece& path,
bool keep_raw_values, bool utf16, IArchiveWriter* writer) {
BigBuffer buffer(1024);
XmlFlattenerOptions options = {};
options.keep_raw_values = keep_raw_values;
options.use_utf16 = utf16;
XmlFlattener flattener(&buffer, options);
if (!flattener.Consume(context, xml_res)) {
return false;
}
static bool FlattenXml(IAaptContext* context, const xml::XmlResource& xml_res,
const StringPiece& path, bool keep_raw_values, bool utf16,
OutputFormat format, IArchiveWriter* writer) {
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path) << "writing to archive (keep_raw_values="
<< (keep_raw_values ? "true" : "false")
<< ")");
}
io::BigBufferInputStream input_stream(&buffer);
return io::CopyInputStreamToArchive(context, &input_stream, path.to_string(),
ArchiveEntry::kCompress, writer);
switch (format) {
case OutputFormat::kApk: {
BigBuffer buffer(1024);
XmlFlattenerOptions options = {};
options.keep_raw_values = keep_raw_values;
options.use_utf16 = utf16;
XmlFlattener flattener(&buffer, options);
if (!flattener.Consume(context, &xml_res)) {
return false;
}
io::BigBufferInputStream input_stream(&buffer);
return io::CopyInputStreamToArchive(context, &input_stream, path.to_string(),
ArchiveEntry::kCompress, writer);
} break;
case OutputFormat::kProto: {
pb::XmlNode pb_node;
SerializeXmlResourceToPb(xml_res, &pb_node);
return io::CopyProtoToArchive(context, &pb_node, path.to_string(), ArchiveEntry::kCompress,
writer);
} break;
}
return false;
}
static std::unique_ptr<ResourceTable> LoadTableFromPb(const Source& source, const void* data,
@@ -310,6 +332,7 @@ struct ResourceFileFlattenerOptions {
bool keep_raw_values = false;
bool do_not_compress_anything = false;
bool update_proguard_spec = false;
OutputFormat output_format = OutputFormat::kApk;
std::unordered_set<std::string> extensions_to_not_compress;
};
@@ -627,8 +650,9 @@ bool ResourceFileFlattener::Flatten(ResourceTable* table, IArchiveWriter* archiv
return false;
}
}
error |= !FlattenXml(context_, doc.get(), dst_path, options_.keep_raw_values,
false /*utf16*/, archive_writer);
error |= !FlattenXml(context_, *doc, dst_path, options_.keep_raw_values,
false /*utf16*/, options_.output_format, archive_writer);
}
} else {
error |= !io::CopyFileToArchive(context_, file_op.file_to_copy, file_op.dst_path,
@@ -927,23 +951,29 @@ class LinkCommand {
}
}
bool FlattenTable(ResourceTable* table, IArchiveWriter* writer) {
BigBuffer buffer(1024);
TableFlattener flattener(options_.table_flattener_options, &buffer);
if (!flattener.Consume(context_, table)) {
context_->GetDiagnostics()->Error(DiagMessage() << "failed to flatten resource table");
return false;
bool FlattenTable(ResourceTable* table, OutputFormat format, IArchiveWriter* writer) {
switch (format) {
case OutputFormat::kApk: {
BigBuffer buffer(1024);
TableFlattener flattener(options_.table_flattener_options, &buffer);
if (!flattener.Consume(context_, table)) {
context_->GetDiagnostics()->Error(DiagMessage() << "failed to flatten resource table");
return false;
}
io::BigBufferInputStream input_stream(&buffer);
return io::CopyInputStreamToArchive(context_, &input_stream, kApkResourceTablePath,
ArchiveEntry::kAlign, writer);
} break;
case OutputFormat::kProto: {
pb::ResourceTable pb_table;
SerializeTableToPb(*table, &pb_table);
return io::CopyProtoToArchive(context_, &pb_table, kProtoResourceTablePath,
ArchiveEntry::kCompress, writer);
} break;
}
io::BigBufferInputStream input_stream(&buffer);
return io::CopyInputStreamToArchive(context_, &input_stream, "resources.arsc",
ArchiveEntry::kAlign, writer);
}
bool FlattenTableToPb(ResourceTable* table, IArchiveWriter* writer) {
pb::ResourceTable pb_table;
SerializeTableToPb(*table, &pb_table);
return io::CopyProtoToArchive(context_, &pb_table, "resources.arsc.flat", 0, writer);
return false;
}
bool WriteJavaFile(ResourceTable* table, const StringPiece& package_name_to_generate,
@@ -1172,7 +1202,7 @@ class LinkCommand {
}
std::unique_ptr<ResourceTable> LoadTablePbFromCollection(io::IFileCollection* collection) {
io::IFile* file = collection->FindFile("resources.arsc.flat");
io::IFile* file = collection->FindFile(kProtoResourceTablePath);
if (!file) {
return {};
}
@@ -1466,15 +1496,13 @@ class LinkCommand {
return true;
}
/**
* Writes the AndroidManifest, ResourceTable, and all XML files referenced by
* the ResourceTable to the IArchiveWriter.
*/
// Writes the AndroidManifest, ResourceTable, and all XML files referenced by the ResourceTable
// to the IArchiveWriter.
bool WriteApk(IArchiveWriter* writer, proguard::KeepSet* keep_set, xml::XmlResource* manifest,
ResourceTable* table) {
const bool keep_raw_values = context_->GetPackageType() == PackageType::kStaticLib;
bool result = FlattenXml(context_, manifest, "AndroidManifest.xml", keep_raw_values,
true /*utf16*/, writer);
bool result = FlattenXml(context_, *manifest, "AndroidManifest.xml", keep_raw_values,
true /*utf16*/, options_.output_format, writer);
if (!result) {
return false;
}
@@ -1489,6 +1517,7 @@ class LinkCommand {
file_flattener_options.no_xml_namespaces = options_.no_xml_namespaces;
file_flattener_options.update_proguard_spec =
static_cast<bool>(options_.generate_proguard_rules_path);
file_flattener_options.output_format = options_.output_format;
ResourceFileFlattener file_flattener(file_flattener_options, context_, keep_set);
@@ -1497,15 +1526,9 @@ class LinkCommand {
return false;
}
if (context_->GetPackageType() == PackageType::kStaticLib) {
if (!FlattenTableToPb(table, writer)) {
return false;
}
} else {
if (!FlattenTable(table, writer)) {
context_->GetDiagnostics()->Error(DiagMessage() << "failed to write resources.arsc");
return false;
}
if (!FlattenTable(table, options_.output_format, writer)) {
context_->GetDiagnostics()->Error(DiagMessage() << "failed to write resource table");
return false;
}
return true;
}
@@ -1869,6 +1892,7 @@ int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) {
bool verbose = false;
bool shared_lib = false;
bool static_lib = false;
bool proto_format = false;
Maybe<std::string> stable_id_file_path;
std::vector<std::string> split_args;
Flags flags =
@@ -1949,6 +1973,10 @@ int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) {
.OptionalSwitch("--shared-lib", "Generates a shared Android runtime library.",
&shared_lib)
.OptionalSwitch("--static-lib", "Generate a static Android library.", &static_lib)
.OptionalSwitch("--proto-format",
"Generates compiled resources in Protobuf format.\n"
"Suitable as input to the bundle tool for generating an App Bundle.",
&proto_format)
.OptionalSwitch("--no-static-lib-packages",
"Merge all library resources under the app's package.",
&options.no_static_lib_packages)
@@ -2035,21 +2063,25 @@ int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) {
context.SetVerbose(verbose);
}
if (shared_lib && static_lib) {
context.GetDiagnostics()->Error(DiagMessage()
<< "only one of --shared-lib and --static-lib can be defined");
if (int{shared_lib} + int{static_lib} + int{proto_format} > 1) {
context.GetDiagnostics()->Error(
DiagMessage()
<< "only one of --shared-lib, --static-lib, or --proto_format can be defined");
return 1;
}
// The default build type.
context.SetPackageType(PackageType::kApp);
context.SetPackageId(kAppPackageId);
if (shared_lib) {
context.SetPackageType(PackageType::kSharedLib);
context.SetPackageId(0x00);
} else if (static_lib) {
context.SetPackageType(PackageType::kStaticLib);
context.SetPackageId(kAppPackageId);
} else {
context.SetPackageType(PackageType::kApp);
context.SetPackageId(kAppPackageId);
options.output_format = OutputFormat::kProto;
} else if (proto_format) {
options.output_format = OutputFormat::kProto;
}
if (package_id) {

View File

@@ -43,7 +43,7 @@ TEST(ContainerTest, SerializeCompiledFile) {
pb::internal::CompiledFile pb_compiled_file;
pb_compiled_file.set_resource_name("android:layout/main.xml");
pb_compiled_file.set_type(pb::internal::CompiledFile::Type::CompiledFile_Type_PROTO_XML);
pb_compiled_file.set_type(pb::FileReference::PROTO_XML);
pb_compiled_file.set_source_path("res/layout/main.xml");
io::StringInputStream data(expected_data);
ASSERT_TRUE(writer.AddResFileEntry(pb_compiled_file, &data));

View File

@@ -56,9 +56,9 @@ static bool cmp_xml_attribute_by_id(const xml::Attribute* a, const xml::Attribut
return false;
}
class XmlFlattenerVisitor : public xml::Visitor {
class XmlFlattenerVisitor : public xml::ConstVisitor {
public:
using xml::Visitor::Visit;
using xml::ConstVisitor::Visit;
StringPool pool;
std::map<uint8_t, StringPool> package_pools;
@@ -74,7 +74,7 @@ class XmlFlattenerVisitor : public xml::Visitor {
: buffer_(buffer), options_(options) {
}
void Visit(xml::Text* node) override {
void Visit(const xml::Text* node) override {
if (util::TrimWhitespace(node->text).empty()) {
// Skip whitespace only text nodes.
return;
@@ -95,7 +95,7 @@ class XmlFlattenerVisitor : public xml::Visitor {
writer.Finish();
}
void Visit(xml::Element* node) override {
void Visit(const xml::Element* node) override {
for (const xml::NamespaceDecl& decl : node->namespace_decls) {
// Skip dedicated tools namespace.
if (decl.uri != xml::kSchemaTools) {
@@ -125,7 +125,7 @@ class XmlFlattenerVisitor : public xml::Visitor {
start_writer.Finish();
}
xml::Visitor::Visit(node);
xml::ConstVisitor::Visit(node);
{
ChunkWriter end_writer(buffer_);
@@ -182,12 +182,13 @@ class XmlFlattenerVisitor : public xml::Visitor {
writer.Finish();
}
void WriteAttributes(xml::Element* node, ResXMLTree_attrExt* flat_elem, ChunkWriter* writer) {
void WriteAttributes(const xml::Element* node, ResXMLTree_attrExt* flat_elem,
ChunkWriter* writer) {
filtered_attrs_.clear();
filtered_attrs_.reserve(node->attributes.size());
// Filter the attributes.
for (xml::Attribute& attr : node->attributes) {
for (const xml::Attribute& attr : node->attributes) {
if (attr.namespace_uri != xml::kSchemaTools) {
filtered_attrs_.push_back(&attr);
}
@@ -282,12 +283,12 @@ class XmlFlattenerVisitor : public xml::Visitor {
XmlFlattenerOptions options_;
// Scratch vector to filter attributes. We avoid allocations making this a member.
std::vector<xml::Attribute*> filtered_attrs_;
std::vector<const xml::Attribute*> filtered_attrs_;
};
} // namespace
bool XmlFlattener::Flatten(IAaptContext* context, xml::Node* node) {
bool XmlFlattener::Flatten(IAaptContext* context, const xml::Node* node) {
BigBuffer node_buffer(1024);
XmlFlattenerVisitor visitor(&node_buffer, options_);
node->Accept(&visitor);
@@ -341,7 +342,7 @@ bool XmlFlattener::Flatten(IAaptContext* context, xml::Node* node) {
return true;
}
bool XmlFlattener::Consume(IAaptContext* context, xml::XmlResource* resource) {
bool XmlFlattener::Consume(IAaptContext* context, const xml::XmlResource* resource) {
if (!resource->root) {
return false;
}

View File

@@ -34,18 +34,18 @@ struct XmlFlattenerOptions {
bool use_utf16 = false;
};
class XmlFlattener : public IXmlResourceConsumer {
class XmlFlattener {
public:
XmlFlattener(BigBuffer* buffer, XmlFlattenerOptions options)
: buffer_(buffer), options_(options) {
}
bool Consume(IAaptContext* context, xml::XmlResource* resource) override;
bool Consume(IAaptContext* context, const xml::XmlResource* resource);
private:
DISALLOW_COPY_AND_ASSIGN(XmlFlattener);
bool Flatten(IAaptContext* context, xml::Node* node);
bool Flatten(IAaptContext* context, const xml::Node* node);
BigBuffer* buffer_;
XmlFlattenerOptions options_;

View File

@@ -390,8 +390,15 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr
}
ResourceTableType* type = pkg->FindOrCreateType(*res_type);
if (pb_type.has_type_id()) {
type->id = static_cast<uint8_t>(pb_type.type_id().id());
}
for (const pb::Entry& pb_entry : pb_type.entry()) {
ResourceEntry* entry = type->FindOrCreateEntry(pb_entry.name());
if (pb_entry.has_entry_id()) {
entry->id = static_cast<uint16_t>(pb_entry.entry_id().id());
}
// Deserialize the symbol status (public/private with source and comments).
if (pb_entry.has_symbol_status()) {
@@ -405,21 +412,11 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr
const SymbolState visibility = DeserializeVisibilityFromPb(pb_status.visibility());
entry->symbol_status.state = visibility;
if (visibility == SymbolState::kPublic) {
// This is a public symbol, we must encode the ID now if there is one.
if (pb_entry.has_entry_id()) {
entry->id = static_cast<uint16_t>(pb_entry.entry_id().id());
}
if (type->symbol_status.state != SymbolState::kPublic) {
// If the type has not been made public, do so now.
type->symbol_status.state = SymbolState::kPublic;
if (pb_type.has_type_id()) {
type->id = static_cast<uint8_t>(pb_type.type_id().id());
}
}
// Propagate the public visibility up to the Type.
type->symbol_status.state = SymbolState::kPublic;
} else if (visibility == SymbolState::kPrivate) {
// Only propagate if no previous state was assigned.
if (type->symbol_status.state == SymbolState::kUndefined) {
type->symbol_status.state = SymbolState::kPrivate;
}
@@ -484,15 +481,14 @@ bool DeserializeTableFromPb(const pb::ResourceTable& pb_table, ResourceTable* ou
return true;
}
static ResourceFile::Type DeserializeCompiledFileType(
const pb::internal::CompiledFile::Type& pb_type) {
switch (pb_type) {
case pb::internal::CompiledFile::Type::CompiledFile_Type_PNG:
return ResourceFile::Type::kPng;
case pb::internal::CompiledFile::Type::CompiledFile_Type_BINARY_XML:
static ResourceFile::Type DeserializeFileReferenceTypeFromPb(const pb::FileReference::Type& type) {
switch (type) {
case pb::FileReference::BINARY_XML:
return ResourceFile::Type::kBinaryXml;
case pb::internal::CompiledFile::Type::CompiledFile_Type_PROTO_XML:
case pb::FileReference::PROTO_XML:
return ResourceFile::Type::kProtoXml;
case pb::FileReference::PNG:
return ResourceFile::Type::kPng;
default:
return ResourceFile::Type::kUnknown;
}
@@ -510,7 +506,7 @@ bool DeserializeCompiledFileFromPb(const pb::internal::CompiledFile& pb_file,
out_file->name = name_ref.ToResourceName();
out_file->source.path = pb_file.source_path();
out_file->type = DeserializeCompiledFileType(pb_file.type());
out_file->type = DeserializeFileReferenceTypeFromPb(pb_file.type());
std::string config_error;
if (!DeserializeConfigFromPb(pb_file.config(), &out_file->config, &config_error)) {
@@ -773,8 +769,12 @@ std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
} break;
case pb::Item::kFile: {
return util::make_unique<FileReference>(value_pool->MakeRef(
pb_item.file().path(), StringPool::Context(StringPool::Context::kHighPriority, config)));
const pb::FileReference& pb_file = pb_item.file();
std::unique_ptr<FileReference> file_ref =
util::make_unique<FileReference>(value_pool->MakeRef(
pb_file.path(), StringPool::Context(StringPool::Context::kHighPriority, config)));
file_ref->type = DeserializeFileReferenceTypeFromPb(pb_file.type());
return std::move(file_ref);
} break;
default:

View File

@@ -361,6 +361,19 @@ static pb::Plural_Arity SerializePluralEnumToPb(size_t plural_idx) {
return pb::Plural_Arity_OTHER;
}
static pb::FileReference::Type SerializeFileReferenceTypeToPb(const ResourceFile::Type& type) {
switch (type) {
case ResourceFile::Type::kBinaryXml:
return pb::FileReference::BINARY_XML;
case ResourceFile::Type::kProtoXml:
return pb::FileReference::PROTO_XML;
case ResourceFile::Type::kPng:
return pb::FileReference::PNG;
default:
return pb::FileReference::UNKNOWN;
}
}
namespace {
class ValueSerializer : public ConstValueVisitor {
@@ -395,7 +408,9 @@ class ValueSerializer : public ConstValueVisitor {
}
void Visit(const FileReference* file) override {
out_value_->mutable_item()->mutable_file()->set_path(*file->path);
pb::FileReference* pb_file = out_value_->mutable_item()->mutable_file();
pb_file->set_path(*file->path);
pb_file->set_type(SerializeFileReferenceTypeToPb(file->type));
}
void Visit(const Id* /*id*/) override {
@@ -507,23 +522,10 @@ void SerializeItemToPb(const Item& item, pb::Item* out_item) {
out_item->MergeFrom(value.item());
}
static pb::internal::CompiledFile::Type SerializeCompiledFileType(const ResourceFile::Type& type) {
switch (type) {
case ResourceFile::Type::kPng:
return pb::internal::CompiledFile::Type::CompiledFile_Type_PNG;
case ResourceFile::Type::kBinaryXml:
return pb::internal::CompiledFile::Type::CompiledFile_Type_BINARY_XML;
case ResourceFile::Type::kProtoXml:
return pb::internal::CompiledFile::Type::CompiledFile_Type_PROTO_XML;
default:
return pb::internal::CompiledFile::Type::CompiledFile_Type_UNKNOWN;
}
}
void SerializeCompiledFileToPb(const ResourceFile& file, pb::internal::CompiledFile* out_file) {
out_file->set_resource_name(file.name.ToString());
out_file->set_source_path(file.source.path);
out_file->set_type(SerializeCompiledFileType(file.type));
out_file->set_type(SerializeFileReferenceTypeToPb(file.type));
SerializeConfig(file.config, out_file->mutable_config());
for (const SourcedResourceName& exported : file.exported_symbols) {