18cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski/*
28cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski * Copyright (C) 2016 The Android Open Source Project
38cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski *
48cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
58cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski * you may not use this file except in compliance with the License.
68cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski * You may obtain a copy of the License at
78cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski *
88cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
98cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski *
108cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski * Unless required by applicable law or agreed to in writing, software
118cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
128cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski * See the License for the specific language governing permissions and
148cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski * limitations under the License.
158cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski */
168cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
174670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski#include "format/proto/ProtoSerialize.h"
188cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
198cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski#include "ValueVisitor.h"
208cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski#include "util/BigBuffer.h"
218cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
228cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskinamespace aapt {
238cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2470414f22dcab1d4ce3c2e9d981f3256a9ba62515Ryan Mitchellvoid SerializeStringPoolToPb(const StringPool& pool, pb::StringPool* out_pb_pool, IDiagnostics* diag) {
258cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  BigBuffer buffer(1024);
2670414f22dcab1d4ce3c2e9d981f3256a9ba62515Ryan Mitchell  StringPool::FlattenUtf8(&buffer, pool, diag);
278cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
288cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  std::string* data = out_pb_pool->mutable_data();
298cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  data->reserve(buffer.size());
308cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
318cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  size_t offset = 0;
328cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  for (const BigBuffer::Block& block : buffer) {
338cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    data->insert(data->begin() + offset, block.buffer.get(), block.buffer.get() + block.size);
348cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    offset += block.size;
358cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
368cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
378cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
388cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskivoid SerializeSourceToPb(const Source& source, StringPool* src_pool, pb::Source* out_pb_source) {
398cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  StringPool::Ref ref = src_pool->MakeRef(source.path);
408cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_pb_source->set_path_idx(static_cast<uint32_t>(ref.index()));
418cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  if (source.line) {
428cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    out_pb_source->mutable_position()->set_line_number(static_cast<uint32_t>(source.line.value()));
438cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
448cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
458cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
4671be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinskistatic pb::Visibility::Level SerializeVisibilityToPb(Visibility::Level state) {
478cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (state) {
4871be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski    case Visibility::Level::kPrivate:
4971be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski      return pb::Visibility::PRIVATE;
5071be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski    case Visibility::Level::kPublic:
5171be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski      return pb::Visibility::PUBLIC;
528cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    default:
538cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
548cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
5571be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski  return pb::Visibility::UNKNOWN;
568cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
578cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
588cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskivoid SerializeConfig(const ConfigDescription& config, pb::Configuration* out_pb_config) {
598cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_pb_config->set_mcc(config.mcc);
608cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_pb_config->set_mnc(config.mnc);
618cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_pb_config->set_locale(config.GetBcp47LanguageTag());
628cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
638cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.screenLayout & ConfigDescription::MASK_LAYOUTDIR) {
648cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::LAYOUTDIR_LTR:
658cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_layout_direction(pb::Configuration_LayoutDirection_LAYOUT_DIRECTION_LTR);
668cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
678cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
688cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::LAYOUTDIR_RTL:
698cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_layout_direction(pb::Configuration_LayoutDirection_LAYOUT_DIRECTION_RTL);
708cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
718cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
728cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
738cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_pb_config->set_screen_width(config.screenWidth);
748cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_pb_config->set_screen_height(config.screenHeight);
758cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_pb_config->set_screen_width_dp(config.screenWidthDp);
768cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_pb_config->set_screen_height_dp(config.screenHeightDp);
778cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_pb_config->set_smallest_screen_width_dp(config.smallestScreenWidthDp);
788cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
798cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.screenLayout & ConfigDescription::MASK_SCREENSIZE) {
808cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::SCREENSIZE_SMALL:
818cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_screen_layout_size(
828cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_SMALL);
838cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
848cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
858cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::SCREENSIZE_NORMAL:
868cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_screen_layout_size(
878cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_NORMAL);
888cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
898cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
908cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::SCREENSIZE_LARGE:
918cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_screen_layout_size(
928cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_LARGE);
938cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
948cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
958cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::SCREENSIZE_XLARGE:
968cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_screen_layout_size(
978cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_XLARGE);
988cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
998cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
1008cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1018cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.screenLayout & ConfigDescription::MASK_SCREENLONG) {
1028cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::SCREENLONG_YES:
1038cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_screen_layout_long(
1048cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          pb::Configuration_ScreenLayoutLong_SCREEN_LAYOUT_LONG_LONG);
1058cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1068cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1078cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::SCREENLONG_NO:
1088cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_screen_layout_long(
1098cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          pb::Configuration_ScreenLayoutLong_SCREEN_LAYOUT_LONG_NOTLONG);
1108cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1118cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
1128cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1138cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.screenLayout2 & ConfigDescription::MASK_SCREENROUND) {
1148cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::SCREENROUND_YES:
1158cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_screen_round(pb::Configuration_ScreenRound_SCREEN_ROUND_ROUND);
1168cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1178cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1188cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::SCREENROUND_NO:
1198cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_screen_round(pb::Configuration_ScreenRound_SCREEN_ROUND_NOTROUND);
1208cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1218cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
1228cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1238cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.colorMode & ConfigDescription::MASK_WIDE_COLOR_GAMUT) {
1248cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::WIDE_COLOR_GAMUT_YES:
1258cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_wide_color_gamut(pb::Configuration_WideColorGamut_WIDE_COLOR_GAMUT_WIDECG);
1268cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1278cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1288cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::WIDE_COLOR_GAMUT_NO:
1298cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_wide_color_gamut(
1308cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          pb::Configuration_WideColorGamut_WIDE_COLOR_GAMUT_NOWIDECG);
1318cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1328cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
1338cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1348cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.colorMode & ConfigDescription::MASK_HDR) {
1358cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::HDR_YES:
1368cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_hdr(pb::Configuration_Hdr_HDR_HIGHDR);
1378cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1388cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1398cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::HDR_NO:
1408cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_hdr(pb::Configuration_Hdr_HDR_LOWDR);
1418cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1428cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
1438cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1448cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.orientation) {
1458cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::ORIENTATION_PORT:
1468cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_orientation(pb::Configuration_Orientation_ORIENTATION_PORT);
1478cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1488cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1498cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::ORIENTATION_LAND:
1508cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_orientation(pb::Configuration_Orientation_ORIENTATION_LAND);
1518cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1528cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1538cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::ORIENTATION_SQUARE:
1548cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_orientation(pb::Configuration_Orientation_ORIENTATION_SQUARE);
1558cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1568cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
1578cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1588cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.uiMode & ConfigDescription::MASK_UI_MODE_TYPE) {
1598cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::UI_MODE_TYPE_NORMAL:
1608cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_NORMAL);
1618cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1628cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1638cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::UI_MODE_TYPE_DESK:
1648cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_DESK);
1658cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1668cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1678cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::UI_MODE_TYPE_CAR:
1688cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_CAR);
1698cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1708cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1718cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::UI_MODE_TYPE_TELEVISION:
1728cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_TELEVISION);
1738cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1748cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1758cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::UI_MODE_TYPE_APPLIANCE:
1768cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_APPLIANCE);
1778cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1788cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1798cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::UI_MODE_TYPE_WATCH:
1808cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_WATCH);
1818cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1828cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1838cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::UI_MODE_TYPE_VR_HEADSET:
1848cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_VRHEADSET);
1858cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1868cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
1878cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1888cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.uiMode & ConfigDescription::MASK_UI_MODE_NIGHT) {
1898cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::UI_MODE_NIGHT_YES:
1908cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_ui_mode_night(pb::Configuration_UiModeNight_UI_MODE_NIGHT_NIGHT);
1918cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1928cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1938cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::UI_MODE_NIGHT_NO:
1948cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_ui_mode_night(pb::Configuration_UiModeNight_UI_MODE_NIGHT_NOTNIGHT);
1958cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
1968cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
1978cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
1988cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_pb_config->set_density(config.density);
1998cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2008cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.touchscreen) {
2018cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::TOUCHSCREEN_NOTOUCH:
2028cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_touchscreen(pb::Configuration_Touchscreen_TOUCHSCREEN_NOTOUCH);
2038cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2048cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2058cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::TOUCHSCREEN_STYLUS:
2068cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_touchscreen(pb::Configuration_Touchscreen_TOUCHSCREEN_STYLUS);
2078cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2088cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2098cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::TOUCHSCREEN_FINGER:
2108cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_touchscreen(pb::Configuration_Touchscreen_TOUCHSCREEN_FINGER);
2118cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2128cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
2138cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2148cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.inputFlags & ConfigDescription::MASK_KEYSHIDDEN) {
2158cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::KEYSHIDDEN_NO:
2168cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_keys_hidden(pb::Configuration_KeysHidden_KEYS_HIDDEN_KEYSEXPOSED);
2178cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2188cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2198cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::KEYSHIDDEN_YES:
2208cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_keys_hidden(pb::Configuration_KeysHidden_KEYS_HIDDEN_KEYSHIDDEN);
2218cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2228cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2238cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::KEYSHIDDEN_SOFT:
2248cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_keys_hidden(pb::Configuration_KeysHidden_KEYS_HIDDEN_KEYSSOFT);
2258cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2268cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
2278cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2288cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.keyboard) {
2298cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::KEYBOARD_NOKEYS:
2308cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_keyboard(pb::Configuration_Keyboard_KEYBOARD_NOKEYS);
2318cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2328cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2338cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::KEYBOARD_QWERTY:
2348cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_keyboard(pb::Configuration_Keyboard_KEYBOARD_QWERTY);
2358cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2368cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2378cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::KEYBOARD_12KEY:
2388cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_keyboard(pb::Configuration_Keyboard_KEYBOARD_TWELVEKEY);
2398cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2408cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
2418cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2428cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.inputFlags & ConfigDescription::MASK_NAVHIDDEN) {
2438cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::NAVHIDDEN_NO:
2448cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_nav_hidden(pb::Configuration_NavHidden_NAV_HIDDEN_NAVEXPOSED);
2458cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2468cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2478cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::NAVHIDDEN_YES:
2488cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_nav_hidden(pb::Configuration_NavHidden_NAV_HIDDEN_NAVHIDDEN);
2498cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2508cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
2518cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2528cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (config.navigation) {
2538cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::NAVIGATION_NONAV:
2548cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_navigation(pb::Configuration_Navigation_NAVIGATION_NONAV);
2558cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2568cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2578cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::NAVIGATION_DPAD:
2588cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_navigation(pb::Configuration_Navigation_NAVIGATION_DPAD);
2598cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2608cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2618cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::NAVIGATION_TRACKBALL:
2628cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_navigation(pb::Configuration_Navigation_NAVIGATION_TRACKBALL);
2638cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2648cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2658cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case ConfigDescription::NAVIGATION_WHEEL:
2668cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      out_pb_config->set_navigation(pb::Configuration_Navigation_NAVIGATION_WHEEL);
2678cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
2688cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
2698cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2708cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_pb_config->set_sdk_version(config.sdkVersion);
2718cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
2728cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
27370414f22dcab1d4ce3c2e9d981f3256a9ba62515Ryan Mitchellvoid SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table,
27470414f22dcab1d4ce3c2e9d981f3256a9ba62515Ryan Mitchell                        IDiagnostics* diag) {
2758cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  StringPool source_pool;
2768cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  for (const std::unique_ptr<ResourceTablePackage>& package : table.packages) {
2778cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::Package* pb_package = out_table->add_package();
2788cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    if (package->id) {
2798cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb_package->mutable_package_id()->set_id(package->id.value());
2808cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
2818cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_package->set_package_name(package->name);
2828cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2838cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    for (const std::unique_ptr<ResourceTableType>& type : package->types) {
2848cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb::Type* pb_type = pb_package->add_type();
2858cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      if (type->id) {
2868cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski        pb_type->mutable_type_id()->set_id(type->id.value());
2878cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      }
28893190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski      pb_type->set_name(to_string(type->type).to_string());
2898cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
2908cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      for (const std::unique_ptr<ResourceEntry>& entry : type->entries) {
2918cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski        pb::Entry* pb_entry = pb_type->add_entry();
2928cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski        if (entry->id) {
2938cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          pb_entry->mutable_entry_id()->set_id(entry->id.value());
2948cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski        }
2958cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski        pb_entry->set_name(entry->name);
2968cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
29771be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski        // Write the Visibility struct.
29871be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski        pb::Visibility* pb_visibility = pb_entry->mutable_visibility();
29971be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski        pb_visibility->set_level(SerializeVisibilityToPb(entry->visibility.level));
30071be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski        SerializeSourceToPb(entry->visibility.source, &source_pool,
30171be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski                            pb_visibility->mutable_source());
30271be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski        pb_visibility->set_comment(entry->visibility.comment);
30371be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski
30471be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski        if (entry->allow_new) {
30571be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski          pb::AllowNew* pb_allow_new = pb_entry->mutable_allow_new();
30671be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski          SerializeSourceToPb(entry->allow_new.value().source, &source_pool,
30771be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski                              pb_allow_new->mutable_source());
30871be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski          pb_allow_new->set_comment(entry->allow_new.value().comment);
30971be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski        }
31071be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski
31171be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski        if (entry->overlayable) {
31271be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski          pb::Overlayable* pb_overlayable = pb_entry->mutable_overlayable();
31371be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski          SerializeSourceToPb(entry->overlayable.value().source, &source_pool,
31471be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski                              pb_overlayable->mutable_source());
31571be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski          pb_overlayable->set_comment(entry->overlayable.value().comment);
31671be70507de9cb619b644e55eda1cc181e3f7e90Adam Lesinski        }
3178cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
3188cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski        for (const std::unique_ptr<ResourceConfigValue>& config_value : entry->values) {
3198cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          pb::ConfigValue* pb_config_value = pb_entry->add_config_value();
3208cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          SerializeConfig(config_value->config, pb_config_value->mutable_config());
3218cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          pb_config_value->mutable_config()->set_product(config_value->product);
3228cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski          SerializeValueToPb(*config_value->value, pb_config_value->mutable_value(), &source_pool);
3238cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski        }
3248cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      }
3258cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
3268cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
32770414f22dcab1d4ce3c2e9d981f3256a9ba62515Ryan Mitchell  SerializeStringPoolToPb(source_pool, out_table->mutable_source_pool(), diag);
3288cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
3298cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
3308cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskistatic pb::Reference_Type SerializeReferenceTypeToPb(Reference::Type type) {
3318cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (type) {
3328cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case Reference::Type::kResource:
3338cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      return pb::Reference_Type_REFERENCE;
3348cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case Reference::Type::kAttribute:
3358cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      return pb::Reference_Type_ATTRIBUTE;
3368cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    default:
3378cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
3388cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
3398cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  return pb::Reference_Type_REFERENCE;
3408cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
3418cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
3428cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskistatic void SerializeReferenceToPb(const Reference& ref, pb::Reference* pb_ref) {
3438cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb_ref->set_id(ref.id.value_or_default(ResourceId(0x0)).id);
3448cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
3458cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  if (ref.name) {
34693190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski    pb_ref->set_name(ref.name.value().to_string());
3478cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
3488cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
3498cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb_ref->set_private_(ref.private_reference);
3508cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb_ref->set_type(SerializeReferenceTypeToPb(ref.reference_type));
3518cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
3528cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
3538cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskitemplate <typename T>
3548cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskistatic void SerializeItemMetaDataToPb(const Item& item, T* pb_item, StringPool* src_pool) {
3558cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  if (src_pool != nullptr) {
3568cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    SerializeSourceToPb(item.GetSource(), src_pool, pb_item->mutable_source());
3578cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
3588cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb_item->set_comment(item.GetComment());
3598cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
3608cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
3618cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskistatic pb::Plural_Arity SerializePluralEnumToPb(size_t plural_idx) {
3628cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  switch (plural_idx) {
3638cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case Plural::Zero:
3648cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      return pb::Plural_Arity_ZERO;
3658cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case Plural::One:
3668cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      return pb::Plural_Arity_ONE;
3678cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case Plural::Two:
3688cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      return pb::Plural_Arity_TWO;
3698cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case Plural::Few:
3708cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      return pb::Plural_Arity_FEW;
3718cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    case Plural::Many:
3728cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      return pb::Plural_Arity_MANY;
3738cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    default:
3748cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      break;
3758cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
3768cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  return pb::Plural_Arity_OTHER;
3778cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
3788cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
379e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinskistatic pb::FileReference::Type SerializeFileReferenceTypeToPb(const ResourceFile::Type& type) {
380e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski  switch (type) {
381e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski    case ResourceFile::Type::kBinaryXml:
382e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski      return pb::FileReference::BINARY_XML;
383e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski    case ResourceFile::Type::kProtoXml:
384e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski      return pb::FileReference::PROTO_XML;
385e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski    case ResourceFile::Type::kPng:
386e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski      return pb::FileReference::PNG;
387e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski    default:
388e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski      return pb::FileReference::UNKNOWN;
389e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski  }
390e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski}
391e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski
3928cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskinamespace {
3938cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
3948cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskiclass ValueSerializer : public ConstValueVisitor {
3958cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski public:
3968cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  using ConstValueVisitor::Visit;
3978cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
3988cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  ValueSerializer(pb::Value* out_value, StringPool* src_pool)
3998cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      : out_value_(out_value), src_pool_(src_pool) {
4008cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
4018cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
4028cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const Reference* ref) override {
4038cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    SerializeReferenceToPb(*ref, out_value_->mutable_item()->mutable_ref());
4048cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
4058cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
4068cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const String* str) override {
4078cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    out_value_->mutable_item()->mutable_str()->set_value(*str->value);
4088cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
4098cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
4108cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const RawString* str) override {
4118cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    out_value_->mutable_item()->mutable_raw_str()->set_value(*str->value);
4128cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
4138cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
4148cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const StyledString* str) override {
4158cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::StyledString* pb_str = out_value_->mutable_item()->mutable_styled_str();
4168cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_str->set_value(str->value->value);
4178cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    for (const StringPool::Span& span : str->value->spans) {
4188cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb::StyledString::Span* pb_span = pb_str->add_span();
4198cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb_span->set_tag(*span.name);
4208cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb_span->set_first_char(span.first_char);
4218cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb_span->set_last_char(span.last_char);
4228cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
4238cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
4248cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
4258cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const FileReference* file) override {
426e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski    pb::FileReference* pb_file = out_value_->mutable_item()->mutable_file();
427e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski    pb_file->set_path(*file->path);
428e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski    pb_file->set_type(SerializeFileReferenceTypeToPb(file->type));
4298cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
4308cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
4318cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const Id* /*id*/) override {
4328cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    out_value_->mutable_item()->mutable_id();
4338cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
4348cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
4358cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const BinaryPrimitive* prim) override {
4368cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    android::Res_value val = {};
4378cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    prim->Flatten(&val);
4388cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
4398cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::Primitive* pb_prim = out_value_->mutable_item()->mutable_prim();
440d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz
441d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz    switch (val.dataType) {
442d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      case android::Res_value::TYPE_NULL: {
443d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        if (val.data == android::Res_value::DATA_NULL_UNDEFINED) {
444d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz          pb_prim->set_allocated_null_value(new pb::Primitive_NullType());
445d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        } else if (val.data == android::Res_value::DATA_NULL_EMPTY) {
446d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz          pb_prim->set_allocated_empty_value(new pb::Primitive_EmptyType());
447d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        } else {
448d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz          LOG(FATAL) << "Unexpected data value for TYPE_NULL BinaryPrimitive: " << val.data;
449d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        }
450d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      } break;
451d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      case android::Res_value::TYPE_FLOAT: {
452d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        pb_prim->set_float_value(*(float*)&val.data);
453d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      } break;
454d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      case android::Res_value::TYPE_DIMENSION: {
4558b74927e9ecf4d14898d09c168d0d38f164a92bcMichael Wachenschwanz        pb_prim->set_dimension_value(val.data);
456d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      } break;
457d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      case android::Res_value::TYPE_FRACTION: {
4588b74927e9ecf4d14898d09c168d0d38f164a92bcMichael Wachenschwanz        pb_prim->set_fraction_value(val.data);
459d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      } break;
460d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      case android::Res_value::TYPE_INT_DEC: {
461d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        pb_prim->set_int_decimal_value(static_cast<int32_t>(val.data));
462d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      } break;
463d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      case android::Res_value::TYPE_INT_HEX: {
46422ed4122e7849a4538208c65f403298fe0fff891Dave Ingram        pb_prim->set_int_hexadecimal_value(val.data);
465d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      } break;
466d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      case android::Res_value::TYPE_INT_BOOLEAN: {
467d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        pb_prim->set_boolean_value(static_cast<bool>(val.data));
468d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      } break;
469d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      case android::Res_value::TYPE_INT_COLOR_ARGB8: {
470d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        pb_prim->set_color_argb8_value(val.data);
471d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      } break;
472d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      case android::Res_value::TYPE_INT_COLOR_RGB8: {
473d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        pb_prim->set_color_rgb8_value(val.data);
474d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      } break;
475d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      case android::Res_value::TYPE_INT_COLOR_ARGB4: {
476d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        pb_prim->set_color_argb4_value(val.data);
477d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      } break;
478d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      case android::Res_value::TYPE_INT_COLOR_RGB4: {
479d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        pb_prim->set_color_rgb4_value(val.data);
480d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      } break;
481d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz      default:
482d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        LOG(FATAL) << "Unexpected BinaryPrimitive type: " << val.dataType;
483d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz        break;
484d06f1f38a9266f4674a89d69d33198abd12b0e78Michael Wachenschwanz    }
4858cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
4868cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
4878cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const Attribute* attr) override {
4888cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::Attribute* pb_attr = out_value_->mutable_compound_value()->mutable_attr();
4898cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_attr->set_format_flags(attr->type_mask);
4908cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_attr->set_min_int(attr->min_int);
4918cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_attr->set_max_int(attr->max_int);
4928cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
4938cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    for (auto& symbol : attr->symbols) {
4948cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb::Attribute_Symbol* pb_symbol = pb_attr->add_symbol();
4958cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeItemMetaDataToPb(symbol.symbol, pb_symbol, src_pool_);
4968cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeReferenceToPb(symbol.symbol, pb_symbol->mutable_name());
4978cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb_symbol->set_value(symbol.value);
4988cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
4998cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
5008cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5018cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const Style* style) override {
5028cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::Style* pb_style = out_value_->mutable_compound_value()->mutable_style();
5038cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    if (style->parent) {
5048cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      const Reference& parent = style->parent.value();
5058cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeReferenceToPb(parent, pb_style->mutable_parent());
5068cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      if (src_pool_ != nullptr) {
5078cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski        SerializeSourceToPb(parent.GetSource(), src_pool_, pb_style->mutable_parent_source());
5088cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      }
5098cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
5108cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5118cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    for (const Style::Entry& entry : style->entries) {
5128cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb::Style_Entry* pb_entry = pb_style->add_entry();
5138cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeReferenceToPb(entry.key, pb_entry->mutable_key());
5148cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeItemMetaDataToPb(entry.key, pb_entry, src_pool_);
5158cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeItemToPb(*entry.value, pb_entry->mutable_item());
5168cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
5178cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
5188cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5198cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const Styleable* styleable) override {
5208cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::Styleable* pb_styleable = out_value_->mutable_compound_value()->mutable_styleable();
5218cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    for (const Reference& entry : styleable->entries) {
5228cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb::Styleable_Entry* pb_entry = pb_styleable->add_entry();
5238cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeItemMetaDataToPb(entry, pb_entry, src_pool_);
5248cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeReferenceToPb(entry, pb_entry->mutable_attr());
5258cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
5268cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
5278cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5288cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const Array* array) override {
5298cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::Array* pb_array = out_value_->mutable_compound_value()->mutable_array();
5308cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    for (const std::unique_ptr<Item>& element : array->elements) {
5318cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb::Array_Element* pb_element = pb_array->add_element();
5328cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeItemMetaDataToPb(*element, pb_element, src_pool_);
5338cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeItemToPb(*element, pb_element->mutable_item());
5348cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
5358cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
5368cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5378cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void Visit(const Plural* plural) override {
5388cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::Plural* pb_plural = out_value_->mutable_compound_value()->mutable_plural();
5398cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    const size_t count = plural->values.size();
5408cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    for (size_t i = 0; i < count; i++) {
5418cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      if (!plural->values[i]) {
5428cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski        // No plural value set here.
5438cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski        continue;
5448cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      }
5458cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5468cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb::Plural_Entry* pb_entry = pb_plural->add_entry();
5478cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb_entry->set_arity(SerializePluralEnumToPb(i));
5488cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeItemMetaDataToPb(*plural->values[i], pb_entry, src_pool_);
5498cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeItemToPb(*plural->values[i], pb_entry->mutable_item());
5508cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
5518cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
5528cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5538cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  void VisitAny(const Value* unknown) override {
5548cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    LOG(FATAL) << "unimplemented value: " << *unknown;
5558cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
5568cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5578cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski private:
5588cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb::Value* out_value_;
5598cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  StringPool* src_pool_;
5608cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski};
5618cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5628cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}  // namespace
5638cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5648cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskivoid SerializeValueToPb(const Value& value, pb::Value* out_value, StringPool* src_pool) {
5658cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  ValueSerializer serializer(out_value, src_pool);
5668cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  value.Accept(&serializer);
5678cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5688cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  // Serialize the meta-data of the Value.
5698cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_value->set_comment(value.GetComment());
5708cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_value->set_weak(value.IsWeak());
5718cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  if (src_pool != nullptr) {
5728cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    SerializeSourceToPb(value.GetSource(), src_pool, out_value->mutable_source());
5738cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
5748cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
5758cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5768cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskivoid SerializeItemToPb(const Item& item, pb::Item* out_item) {
5778cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb::Value value;
5788cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  ValueSerializer serializer(&value, nullptr);
5798cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  item.Accept(&serializer);
5808cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_item->MergeFrom(value.item());
5818cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
5828cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5838cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskivoid SerializeCompiledFileToPb(const ResourceFile& file, pb::internal::CompiledFile* out_file) {
58493190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  out_file->set_resource_name(file.name.to_string());
5858cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  out_file->set_source_path(file.source.path);
586e59f0d80ec19249f72c07ae191ad673d040443e3Adam Lesinski  out_file->set_type(SerializeFileReferenceTypeToPb(file.type));
5878cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  SerializeConfig(file.config, out_file->mutable_config());
5888cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5898cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  for (const SourcedResourceName& exported : file.exported_symbols) {
5908cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::internal::CompiledFile_Symbol* pb_symbol = out_file->add_exported_symbol();
59193190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski    pb_symbol->set_resource_name(exported.name.to_string());
5928cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_symbol->mutable_source()->set_line_number(exported.line);
5938cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
5948cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
5958cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
5968cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskistatic void SerializeXmlCommon(const xml::Node& node, pb::XmlNode* out_node) {
5978cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb::SourcePosition* pb_src = out_node->mutable_source();
5988cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb_src->set_line_number(node.line_number);
5998cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb_src->set_column_number(node.column_number);
6008cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
6018cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
6028cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskivoid SerializeXmlToPb(const xml::Element& el, pb::XmlNode* out_node) {
6038cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  SerializeXmlCommon(el, out_node);
6048cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
6058cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb::XmlElement* pb_element = out_node->mutable_element();
6068cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb_element->set_name(el.name);
6078cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  pb_element->set_namespace_uri(el.namespace_uri);
6088cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
6098cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  for (const xml::NamespaceDecl& ns : el.namespace_decls) {
6108cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::XmlNamespace* pb_ns = pb_element->add_namespace_declaration();
6118cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_ns->set_prefix(ns.prefix);
6128cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_ns->set_uri(ns.uri);
6138cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::SourcePosition* pb_src = pb_ns->mutable_source();
6148cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_src->set_line_number(ns.line_number);
6158cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_src->set_column_number(ns.column_number);
6168cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
6178cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
6188cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  for (const xml::Attribute& attr : el.attributes) {
6198cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb::XmlAttribute* pb_attr = pb_element->add_attribute();
6208cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_attr->set_name(attr.name);
6218cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_attr->set_namespace_uri(attr.namespace_uri);
6228cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    pb_attr->set_value(attr.value);
6238cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    if (attr.compiled_attribute) {
6248cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      const ResourceId attr_id = attr.compiled_attribute.value().id.value_or_default({});
6258cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb_attr->set_resource_id(attr_id.id);
6268cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
6278cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    if (attr.compiled_value != nullptr) {
6288cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeItemToPb(*attr.compiled_value, pb_attr->mutable_compiled_item());
6298cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb::SourcePosition* pb_src = pb_attr->mutable_source();
6308cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb_src->set_line_number(attr.compiled_value->GetSource().line.value_or_default(0));
6318cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
6328cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
6338cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
6348cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  for (const std::unique_ptr<xml::Node>& child : el.children) {
6358cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    if (const xml::Element* child_el = xml::NodeCast<xml::Element>(child.get())) {
6368cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeXmlToPb(*child_el, pb_element->add_child());
6378cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    } else if (const xml::Text* text_el = xml::NodeCast<xml::Text>(child.get())) {
6388cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb::XmlNode* pb_child_node = pb_element->add_child();
6398cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      SerializeXmlCommon(*text_el, pb_child_node);
6408cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      pb_child_node->set_text(text_el->text);
6418cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    } else {
6428cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski      LOG(FATAL) << "unhandled XmlNode type";
6438cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski    }
6448cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  }
6458cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
6468cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
6478cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinskivoid SerializeXmlResourceToPb(const xml::XmlResource& resource, pb::XmlNode* out_node) {
6488cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski  SerializeXmlToPb(*resource.root, out_node);
6498cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}
6508cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski
6518cdca1bd722049facf5bbec44ec3ca67cade5288Adam Lesinski}  // namespace aapt
652