Test upload from mkearney.
[chromium-blink-merge.git] / sync / protocol / proto_value_conversions.cc
blobcee21396559d653cb25c72c3cc0919ef8bf56c96
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Keep this file in sync with the .proto files in this directory.
7 #include "sync/protocol/proto_value_conversions.h"
9 #include "base/base64.h"
10 #include "base/basictypes.h"
11 #include "base/logging.h"
12 #include "base/string_number_conversions.h"
13 #include "base/values.h"
14 #include "sync/protocol/app_notification_specifics.pb.h"
15 #include "sync/protocol/app_setting_specifics.pb.h"
16 #include "sync/protocol/app_specifics.pb.h"
17 #include "sync/protocol/autofill_specifics.pb.h"
18 #include "sync/protocol/bookmark_specifics.pb.h"
19 #include "sync/protocol/encryption.pb.h"
20 #include "sync/protocol/extension_setting_specifics.pb.h"
21 #include "sync/protocol/extension_specifics.pb.h"
22 #include "sync/protocol/nigori_specifics.pb.h"
23 #include "sync/protocol/password_specifics.pb.h"
24 #include "sync/protocol/preference_specifics.pb.h"
25 #include "sync/protocol/proto_enum_conversions.h"
26 #include "sync/protocol/search_engine_specifics.pb.h"
27 #include "sync/protocol/session_specifics.pb.h"
28 #include "sync/protocol/sync.pb.h"
29 #include "sync/protocol/theme_specifics.pb.h"
30 #include "sync/protocol/typed_url_specifics.pb.h"
32 namespace syncer {
34 namespace {
36 // Basic Type -> Value functions.
38 StringValue* MakeInt64Value(int64 x) {
39 return Value::CreateStringValue(base::Int64ToString(x));
42 // TODO(akalin): Perhaps make JSONWriter support BinaryValue and use
43 // that instead of a StringValue.
44 StringValue* MakeBytesValue(const std::string& bytes) {
45 std::string bytes_base64;
46 if (!base::Base64Encode(bytes, &bytes_base64)) {
47 NOTREACHED();
49 return Value::CreateStringValue(bytes_base64);
52 // T is the enum type.
53 template <class T>
54 StringValue* MakeEnumValue(T t, const char* (*converter_fn)(T)) {
55 return Value::CreateStringValue(converter_fn(t));
58 // T is the field type, F is either RepeatedField or RepeatedPtrField,
59 // and V is a subclass of Value.
60 template <class T, class F, class V>
61 ListValue* MakeRepeatedValue(const F& fields, V* (*converter_fn)(T)) {
62 ListValue* list = new ListValue();
63 for (typename F::const_iterator it = fields.begin(); it != fields.end();
64 ++it) {
65 list->Append(converter_fn(*it));
67 return list;
70 } // namespace
72 // Helper macros to reduce the amount of boilerplate.
74 #define SET(field, fn) value->Set(#field, fn(proto.field()))
75 #define SET_REP(field, fn) \
76 value->Set(#field, MakeRepeatedValue(proto.field(), fn))
77 #define SET_ENUM(field, fn) \
78 value->Set(#field, MakeEnumValue(proto.field(), fn))
80 #define SET_BOOL(field) SET(field, Value::CreateBooleanValue)
81 #define SET_BYTES(field) SET(field, MakeBytesValue)
82 #define SET_INT32(field) SET(field, MakeInt64Value)
83 #define SET_INT32_REP(field) SET_REP(field, MakeInt64Value)
84 #define SET_INT64(field) SET(field, MakeInt64Value)
85 #define SET_INT64_REP(field) SET_REP(field, MakeInt64Value)
86 #define SET_STR(field) SET(field, Value::CreateStringValue)
87 #define SET_STR_REP(field) \
88 value->Set(#field, \
89 MakeRepeatedValue<const std::string&, \
90 google::protobuf::RepeatedPtrField< \
91 std::string >, \
92 StringValue>(proto.field(), \
93 Value::CreateStringValue))
95 #define SET_FIELD(field, fn) \
96 do { \
97 if (specifics.has_##field()) { \
98 value->Set(#field, fn(specifics.field())); \
99 } \
100 } while (0)
102 // If you add another macro, don't forget to add an #undef at the end
103 // of this file, too.
105 DictionaryValue* EncryptedDataToValue(const sync_pb::EncryptedData& proto) {
106 DictionaryValue* value = new DictionaryValue();
107 SET_STR(key_name);
108 // TODO(akalin): Shouldn't blob be of type bytes instead of string?
109 SET_BYTES(blob);
110 return value;
113 DictionaryValue* AppSettingsToValue(
114 const sync_pb::AppNotificationSettings& proto) {
115 DictionaryValue* value = new DictionaryValue();
116 SET_BOOL(initial_setup_done);
117 SET_BOOL(disabled);
118 SET_STR(oauth_client_id);
119 return value;
122 DictionaryValue* SessionHeaderToValue(
123 const sync_pb::SessionHeader& proto) {
124 DictionaryValue* value = new DictionaryValue();
125 SET_REP(window, SessionWindowToValue);
126 SET_STR(client_name);
127 SET_ENUM(device_type, GetDeviceTypeString);
128 return value;
131 DictionaryValue* SessionTabToValue(
132 const sync_pb::SessionTab& proto) {
133 DictionaryValue* value = new DictionaryValue();
134 SET_INT32(tab_id);
135 SET_INT32(window_id);
136 SET_INT32(tab_visual_index);
137 SET_INT32(current_navigation_index);
138 SET_BOOL(pinned);
139 SET_STR(extension_app_id);
140 SET_REP(navigation, TabNavigationToValue);
141 SET_BYTES(favicon);
142 SET_ENUM(favicon_type, GetFaviconTypeString);
143 SET_STR(favicon_source);
144 return value;
147 DictionaryValue* SessionWindowToValue(
148 const sync_pb::SessionWindow& proto) {
149 DictionaryValue* value = new DictionaryValue();
150 SET_INT32(window_id);
151 SET_INT32(selected_tab_index);
152 SET_INT32_REP(tab);
153 SET_ENUM(browser_type, GetBrowserTypeString);
154 return value;
157 DictionaryValue* TabNavigationToValue(
158 const sync_pb::TabNavigation& proto) {
159 DictionaryValue* value = new DictionaryValue();
160 SET_STR(virtual_url);
161 SET_STR(referrer);
162 SET_STR(title);
163 SET_STR(state);
164 SET_ENUM(page_transition, GetPageTransitionString);
165 SET_ENUM(navigation_qualifier, GetPageTransitionQualifierString);
166 SET_INT32(unique_id);
167 SET_INT64(timestamp);
168 return value;
171 DictionaryValue* PasswordSpecificsDataToValue(
172 const sync_pb::PasswordSpecificsData& proto) {
173 DictionaryValue* value = new DictionaryValue();
174 SET_INT32(scheme);
175 SET_STR(signon_realm);
176 SET_STR(origin);
177 SET_STR(action);
178 SET_STR(username_element);
179 SET_STR(username_value);
180 SET_STR(password_element);
181 value->SetString("password_value", "<redacted>");
182 SET_BOOL(ssl_valid);
183 SET_BOOL(preferred);
184 SET_INT64(date_created);
185 SET_BOOL(blacklisted);
186 return value;
189 DictionaryValue* DeviceInformationToValue(
190 const sync_pb::DeviceInformation& proto) {
191 DictionaryValue* value = new DictionaryValue();
192 SET_STR(cache_guid);
193 SET_STR(name);
194 SET_STR(platform);
195 SET_STR(chrome_version);
196 return value;
199 DictionaryValue* AppNotificationToValue(
200 const sync_pb::AppNotification& proto) {
201 DictionaryValue* value = new DictionaryValue();
202 SET_STR(guid);
203 SET_STR(app_id);
204 SET_INT64(creation_timestamp_ms);
205 SET_STR(title);
206 SET_STR(body_text);
207 SET_STR(link_url);
208 SET_STR(link_text);
209 return value;
212 DictionaryValue* AppSettingSpecificsToValue(
213 const sync_pb::AppSettingSpecifics& proto) {
214 DictionaryValue* value = new DictionaryValue();
215 SET(extension_setting, ExtensionSettingSpecificsToValue);
216 return value;
219 DictionaryValue* AppSpecificsToValue(
220 const sync_pb::AppSpecifics& proto) {
221 DictionaryValue* value = new DictionaryValue();
222 SET(extension, ExtensionSpecificsToValue);
223 SET(notification_settings, AppSettingsToValue);
224 SET_STR(app_launch_ordinal);
225 SET_STR(page_ordinal);
227 return value;
230 DictionaryValue* AutofillSpecificsToValue(
231 const sync_pb::AutofillSpecifics& proto) {
232 DictionaryValue* value = new DictionaryValue();
233 SET_STR(name);
234 SET_STR(value);
235 SET_INT64_REP(usage_timestamp);
236 SET(profile, AutofillProfileSpecificsToValue);
237 return value;
240 DictionaryValue* AutofillProfileSpecificsToValue(
241 const sync_pb::AutofillProfileSpecifics& proto) {
242 DictionaryValue* value = new DictionaryValue();
243 SET_STR(label);
244 SET_STR(guid);
246 SET_STR_REP(name_first);
247 SET_STR_REP(name_middle);
248 SET_STR_REP(name_last);
249 SET_STR_REP(email_address);
250 SET_STR(company_name);
252 SET_STR(address_home_line1);
253 SET_STR(address_home_line2);
254 SET_STR(address_home_city);
255 SET_STR(address_home_state);
256 SET_STR(address_home_zip);
257 SET_STR(address_home_country);
259 SET_STR_REP(phone_home_whole_number);
260 return value;
263 DictionaryValue* BookmarkSpecificsToValue(
264 const sync_pb::BookmarkSpecifics& proto) {
265 DictionaryValue* value = new DictionaryValue();
266 SET_STR(url);
267 SET_BYTES(favicon);
268 SET_STR(title);
269 return value;
272 DictionaryValue* ExtensionSettingSpecificsToValue(
273 const sync_pb::ExtensionSettingSpecifics& proto) {
274 DictionaryValue* value = new DictionaryValue();
275 SET_STR(extension_id);
276 SET_STR(key);
277 SET_STR(value);
278 return value;
281 DictionaryValue* ExtensionSpecificsToValue(
282 const sync_pb::ExtensionSpecifics& proto) {
283 DictionaryValue* value = new DictionaryValue();
284 SET_STR(id);
285 SET_STR(version);
286 SET_STR(update_url);
287 SET_BOOL(enabled);
288 SET_BOOL(incognito_enabled);
289 SET_STR(name);
290 return value;
293 DictionaryValue* NigoriSpecificsToValue(
294 const sync_pb::NigoriSpecifics& proto) {
295 DictionaryValue* value = new DictionaryValue();
296 SET(encrypted, EncryptedDataToValue);
297 SET_BOOL(using_explicit_passphrase);
298 SET_BOOL(encrypt_bookmarks);
299 SET_BOOL(encrypt_preferences);
300 SET_BOOL(encrypt_autofill_profile);
301 SET_BOOL(encrypt_autofill);
302 SET_BOOL(encrypt_themes);
303 SET_BOOL(encrypt_typed_urls);
304 SET_BOOL(encrypt_extension_settings);
305 SET_BOOL(encrypt_extensions);
306 SET_BOOL(encrypt_sessions);
307 SET_BOOL(encrypt_app_settings);
308 SET_BOOL(encrypt_apps);
309 SET_BOOL(encrypt_search_engines);
310 SET_BOOL(encrypt_everything);
311 SET_REP(device_information, DeviceInformationToValue);
312 SET_BOOL(sync_tab_favicons);
313 return value;
316 DictionaryValue* PasswordSpecificsToValue(
317 const sync_pb::PasswordSpecifics& proto) {
318 DictionaryValue* value = new DictionaryValue();
319 SET(encrypted, EncryptedDataToValue);
320 return value;
323 DictionaryValue* PreferenceSpecificsToValue(
324 const sync_pb::PreferenceSpecifics& proto) {
325 DictionaryValue* value = new DictionaryValue();
326 SET_STR(name);
327 SET_STR(value);
328 return value;
331 DictionaryValue* SearchEngineSpecificsToValue(
332 const sync_pb::SearchEngineSpecifics& proto) {
333 DictionaryValue* value = new DictionaryValue();
334 SET_STR(short_name);
335 SET_STR(keyword);
336 SET_STR(favicon_url);
337 SET_STR(url);
338 SET_BOOL(safe_for_autoreplace);
339 SET_STR(originating_url);
340 SET_INT64(date_created);
341 SET_STR(input_encodings);
342 SET_BOOL(show_in_default_list);
343 SET_STR(suggestions_url);
344 SET_INT32(prepopulate_id);
345 SET_BOOL(autogenerate_keyword);
346 SET_STR(instant_url);
347 SET_INT64(last_modified);
348 SET_STR(sync_guid);
349 return value;
352 DictionaryValue* SessionSpecificsToValue(
353 const sync_pb::SessionSpecifics& proto) {
354 DictionaryValue* value = new DictionaryValue();
355 SET_STR(session_tag);
356 SET(header, SessionHeaderToValue);
357 SET(tab, SessionTabToValue);
358 SET_INT32(tab_node_id);
359 return value;
362 DictionaryValue* ThemeSpecificsToValue(
363 const sync_pb::ThemeSpecifics& proto) {
364 DictionaryValue* value = new DictionaryValue();
365 SET_BOOL(use_custom_theme);
366 SET_BOOL(use_system_theme_by_default);
367 SET_STR(custom_theme_name);
368 SET_STR(custom_theme_id);
369 SET_STR(custom_theme_update_url);
370 return value;
373 DictionaryValue* TypedUrlSpecificsToValue(
374 const sync_pb::TypedUrlSpecifics& proto) {
375 DictionaryValue* value = new DictionaryValue();
376 SET_STR(url);
377 SET_STR(title);
378 SET_BOOL(hidden);
379 SET_INT64_REP(visits);
380 SET_INT32_REP(visit_transitions);
381 return value;
384 DictionaryValue* EntitySpecificsToValue(
385 const sync_pb::EntitySpecifics& specifics) {
386 DictionaryValue* value = new DictionaryValue();
387 SET_FIELD(app, AppSpecificsToValue);
388 SET_FIELD(app_notification, AppNotificationToValue);
389 SET_FIELD(app_setting, AppSettingSpecificsToValue);
390 SET_FIELD(autofill, AutofillSpecificsToValue);
391 SET_FIELD(autofill_profile, AutofillProfileSpecificsToValue);
392 SET_FIELD(bookmark, BookmarkSpecificsToValue);
393 SET_FIELD(extension, ExtensionSpecificsToValue);
394 SET_FIELD(extension_setting, ExtensionSettingSpecificsToValue);
395 SET_FIELD(nigori, NigoriSpecificsToValue);
396 SET_FIELD(password, PasswordSpecificsToValue);
397 SET_FIELD(preference, PreferenceSpecificsToValue);
398 SET_FIELD(search_engine, SearchEngineSpecificsToValue);
399 SET_FIELD(session, SessionSpecificsToValue);
400 SET_FIELD(theme, ThemeSpecificsToValue);
401 SET_FIELD(typed_url, TypedUrlSpecificsToValue);
402 return value;
405 namespace {
407 DictionaryValue* SyncEntityToValue(const sync_pb::SyncEntity& proto,
408 bool include_specifics) {
409 DictionaryValue* value = new DictionaryValue();
410 SET_STR(id_string);
411 SET_STR(parent_id_string);
412 SET_STR(old_parent_id);
413 SET_INT64(version);
414 SET_INT64(mtime);
415 SET_INT64(ctime);
416 SET_STR(name);
417 SET_STR(non_unique_name);
418 SET_INT64(sync_timestamp);
419 SET_STR(server_defined_unique_tag);
420 SET_INT64(position_in_parent);
421 SET_STR(insert_after_item_id);
422 SET_BOOL(deleted);
423 SET_STR(originator_cache_guid);
424 SET_STR(originator_client_item_id);
425 if (include_specifics)
426 SET(specifics, EntitySpecificsToValue);
427 SET_BOOL(folder);
428 SET_STR(client_defined_unique_tag);
429 return value;
432 ListValue* SyncEntitiesToValue(
433 const ::google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>& entities,
434 bool include_specifics) {
435 ListValue* list = new ListValue();
436 ::google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>::const_iterator it;
437 for (it = entities.begin(); it != entities.end(); ++it) {
438 list->Append(SyncEntityToValue(*it, include_specifics));
441 return list;
444 DictionaryValue* ChromiumExtensionActivityToValue(
445 const sync_pb::ChromiumExtensionsActivity& proto) {
446 DictionaryValue* value = new DictionaryValue();
447 SET_STR(extension_id);
448 SET_INT32(bookmark_writes_since_last_commit);
449 return value;
452 DictionaryValue* CommitMessageToValue(
453 const sync_pb::CommitMessage& proto,
454 bool include_specifics) {
455 DictionaryValue* value = new DictionaryValue();
456 value->Set("entries",
457 SyncEntitiesToValue(proto.entries(), include_specifics));
458 SET_STR(cache_guid);
459 SET_REP(extensions_activity, ChromiumExtensionActivityToValue);
460 return value;
463 DictionaryValue* DataTypeProgressMarkerToValue(
464 const sync_pb::DataTypeProgressMarker& proto) {
465 DictionaryValue* value = new DictionaryValue();
466 SET_INT32(data_type_id);
467 SET_BYTES(token);
468 SET_INT64(timestamp_token_for_migration);
469 SET_STR(notification_hint);
470 return value;
473 DictionaryValue* GetUpdatesCallerInfoToValue(
474 const sync_pb::GetUpdatesCallerInfo& proto) {
475 DictionaryValue* value = new DictionaryValue();
476 SET_ENUM(source, GetUpdatesSourceString);
477 SET_BOOL(notifications_enabled);
478 return value;
481 DictionaryValue* GetUpdatesMessageToValue(
482 const sync_pb::GetUpdatesMessage& proto) {
483 DictionaryValue* value = new DictionaryValue();
484 SET(caller_info, GetUpdatesCallerInfoToValue);
485 SET_BOOL(fetch_folders);
486 SET_INT32(batch_size);
487 SET_REP(from_progress_marker, DataTypeProgressMarkerToValue);
488 SET_BOOL(streaming);
489 SET_BOOL(create_mobile_bookmarks_folder);
490 return value;
493 DictionaryValue* EntryResponseToValue(
494 const sync_pb::CommitResponse::EntryResponse& proto) {
495 DictionaryValue* value = new DictionaryValue();
496 SET_ENUM(response_type, GetResponseTypeString);
497 SET_STR(id_string);
498 SET_STR(parent_id_string);
499 SET_INT64(position_in_parent);
500 SET_INT64(version);
501 SET_STR(name);
502 SET_STR(error_message);
503 SET_INT64(mtime);
504 return value;
507 DictionaryValue* CommitResponseToValue(const sync_pb::CommitResponse& proto) {
508 DictionaryValue* value = new DictionaryValue();
509 SET_REP(entryresponse, EntryResponseToValue);
510 return value;
513 DictionaryValue* GetUpdatesResponseToValue(
514 const sync_pb::GetUpdatesResponse& proto,
515 bool include_specifics) {
516 DictionaryValue* value = new DictionaryValue();
517 value->Set("entries",
518 SyncEntitiesToValue(proto.entries(), include_specifics));
519 SET_INT64(changes_remaining);
520 SET_REP(new_progress_marker, DataTypeProgressMarkerToValue);
521 return value;
524 DictionaryValue* ClientCommandToValue(const sync_pb::ClientCommand& proto) {
525 DictionaryValue* value = new DictionaryValue();
526 SET_INT32(set_sync_poll_interval);
527 SET_INT32(set_sync_long_poll_interval);
528 SET_INT32(max_commit_batch_size);
529 SET_INT32(sessions_commit_delay_seconds);
530 SET_INT32(throttle_delay_seconds);
531 return value;
534 DictionaryValue* ErrorToValue(
535 const sync_pb::ClientToServerResponse::Error& proto) {
536 DictionaryValue* value = new DictionaryValue();
537 SET_ENUM(error_type, GetErrorTypeString);
538 SET_STR(error_description);
539 SET_STR(url);
540 SET_ENUM(action, GetActionString);
541 return value;
544 } // namespace
546 DictionaryValue* ClientToServerResponseToValue(
547 const sync_pb::ClientToServerResponse& proto,
548 bool include_specifics) {
549 DictionaryValue* value = new DictionaryValue();
550 SET(commit, CommitResponseToValue);
551 if (proto.has_get_updates()) {
552 value->Set("get_updates", GetUpdatesResponseToValue(proto.get_updates(),
553 include_specifics));
556 SET(error, ErrorToValue);
557 SET_ENUM(error_code, GetErrorTypeString);
558 SET_STR(error_message);
559 SET_STR(store_birthday);
560 SET(client_command, ClientCommandToValue);
561 SET_INT32_REP(migrated_data_type_id);
562 return value;
565 DictionaryValue* ClientToServerMessageToValue(
566 const sync_pb::ClientToServerMessage& proto,
567 bool include_specifics) {
568 DictionaryValue* value = new DictionaryValue();
569 SET_STR(share);
570 SET_INT32(protocol_version);
571 if (proto.has_commit()) {
572 value->Set("commit",
573 CommitMessageToValue(proto.commit(), include_specifics));
576 SET(get_updates, GetUpdatesMessageToValue);
577 SET_STR(store_birthday);
578 SET_BOOL(sync_problem_detected);
579 return value;
583 #undef SET
584 #undef SET_REP
586 #undef SET_BOOL
587 #undef SET_BYTES
588 #undef SET_INT32
589 #undef SET_INT64
590 #undef SET_INT64_REP
591 #undef SET_STR
592 #undef SET_STR_REP
594 #undef SET_FIELD
596 } // namespace syncer