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"
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
)) {
49 return Value::CreateStringValue(bytes_base64
);
52 // T is the enum type.
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();
65 list
->Append(converter_fn(*it
));
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) \
89 MakeRepeatedValue<const std::string&, \
90 google::protobuf::RepeatedPtrField< \
92 StringValue>(proto.field(), \
93 Value::CreateStringValue))
95 #define SET_FIELD(field, fn) \
97 if (specifics.has_##field()) { \
98 value->Set(#field, fn(specifics.field())); \
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();
108 // TODO(akalin): Shouldn't blob be of type bytes instead of string?
113 DictionaryValue
* AppSettingsToValue(
114 const sync_pb::AppNotificationSettings
& proto
) {
115 DictionaryValue
* value
= new DictionaryValue();
116 SET_BOOL(initial_setup_done
);
118 SET_STR(oauth_client_id
);
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
);
131 DictionaryValue
* SessionTabToValue(
132 const sync_pb::SessionTab
& proto
) {
133 DictionaryValue
* value
= new DictionaryValue();
135 SET_INT32(window_id
);
136 SET_INT32(tab_visual_index
);
137 SET_INT32(current_navigation_index
);
139 SET_STR(extension_app_id
);
140 SET_REP(navigation
, TabNavigationToValue
);
142 SET_ENUM(favicon_type
, GetFaviconTypeString
);
143 SET_STR(favicon_source
);
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
);
153 SET_ENUM(browser_type
, GetBrowserTypeString
);
157 DictionaryValue
* TabNavigationToValue(
158 const sync_pb::TabNavigation
& proto
) {
159 DictionaryValue
* value
= new DictionaryValue();
160 SET_STR(virtual_url
);
164 SET_ENUM(page_transition
, GetPageTransitionString
);
165 SET_ENUM(navigation_qualifier
, GetPageTransitionQualifierString
);
166 SET_INT32(unique_id
);
167 SET_INT64(timestamp
);
171 DictionaryValue
* PasswordSpecificsDataToValue(
172 const sync_pb::PasswordSpecificsData
& proto
) {
173 DictionaryValue
* value
= new DictionaryValue();
175 SET_STR(signon_realm
);
178 SET_STR(username_element
);
179 SET_STR(username_value
);
180 SET_STR(password_element
);
181 value
->SetString("password_value", "<redacted>");
184 SET_INT64(date_created
);
185 SET_BOOL(blacklisted
);
189 DictionaryValue
* DeviceInformationToValue(
190 const sync_pb::DeviceInformation
& proto
) {
191 DictionaryValue
* value
= new DictionaryValue();
195 SET_STR(chrome_version
);
199 DictionaryValue
* AppNotificationToValue(
200 const sync_pb::AppNotification
& proto
) {
201 DictionaryValue
* value
= new DictionaryValue();
204 SET_INT64(creation_timestamp_ms
);
212 DictionaryValue
* AppSettingSpecificsToValue(
213 const sync_pb::AppSettingSpecifics
& proto
) {
214 DictionaryValue
* value
= new DictionaryValue();
215 SET(extension_setting
, ExtensionSettingSpecificsToValue
);
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
);
230 DictionaryValue
* AutofillSpecificsToValue(
231 const sync_pb::AutofillSpecifics
& proto
) {
232 DictionaryValue
* value
= new DictionaryValue();
235 SET_INT64_REP(usage_timestamp
);
236 SET(profile
, AutofillProfileSpecificsToValue
);
240 DictionaryValue
* AutofillProfileSpecificsToValue(
241 const sync_pb::AutofillProfileSpecifics
& proto
) {
242 DictionaryValue
* value
= new DictionaryValue();
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
);
263 DictionaryValue
* BookmarkSpecificsToValue(
264 const sync_pb::BookmarkSpecifics
& proto
) {
265 DictionaryValue
* value
= new DictionaryValue();
272 DictionaryValue
* ExtensionSettingSpecificsToValue(
273 const sync_pb::ExtensionSettingSpecifics
& proto
) {
274 DictionaryValue
* value
= new DictionaryValue();
275 SET_STR(extension_id
);
281 DictionaryValue
* ExtensionSpecificsToValue(
282 const sync_pb::ExtensionSpecifics
& proto
) {
283 DictionaryValue
* value
= new DictionaryValue();
288 SET_BOOL(incognito_enabled
);
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
);
316 DictionaryValue
* PasswordSpecificsToValue(
317 const sync_pb::PasswordSpecifics
& proto
) {
318 DictionaryValue
* value
= new DictionaryValue();
319 SET(encrypted
, EncryptedDataToValue
);
323 DictionaryValue
* PreferenceSpecificsToValue(
324 const sync_pb::PreferenceSpecifics
& proto
) {
325 DictionaryValue
* value
= new DictionaryValue();
331 DictionaryValue
* SearchEngineSpecificsToValue(
332 const sync_pb::SearchEngineSpecifics
& proto
) {
333 DictionaryValue
* value
= new DictionaryValue();
336 SET_STR(favicon_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
);
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
);
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
);
373 DictionaryValue
* TypedUrlSpecificsToValue(
374 const sync_pb::TypedUrlSpecifics
& proto
) {
375 DictionaryValue
* value
= new DictionaryValue();
379 SET_INT64_REP(visits
);
380 SET_INT32_REP(visit_transitions
);
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
);
407 DictionaryValue
* SyncEntityToValue(const sync_pb::SyncEntity
& proto
,
408 bool include_specifics
) {
409 DictionaryValue
* value
= new DictionaryValue();
411 SET_STR(parent_id_string
);
412 SET_STR(old_parent_id
);
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
);
423 SET_STR(originator_cache_guid
);
424 SET_STR(originator_client_item_id
);
425 if (include_specifics
)
426 SET(specifics
, EntitySpecificsToValue
);
428 SET_STR(client_defined_unique_tag
);
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
));
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
);
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
));
459 SET_REP(extensions_activity
, ChromiumExtensionActivityToValue
);
463 DictionaryValue
* DataTypeProgressMarkerToValue(
464 const sync_pb::DataTypeProgressMarker
& proto
) {
465 DictionaryValue
* value
= new DictionaryValue();
466 SET_INT32(data_type_id
);
468 SET_INT64(timestamp_token_for_migration
);
469 SET_STR(notification_hint
);
473 DictionaryValue
* GetUpdatesCallerInfoToValue(
474 const sync_pb::GetUpdatesCallerInfo
& proto
) {
475 DictionaryValue
* value
= new DictionaryValue();
476 SET_ENUM(source
, GetUpdatesSourceString
);
477 SET_BOOL(notifications_enabled
);
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
);
489 SET_BOOL(create_mobile_bookmarks_folder
);
493 DictionaryValue
* EntryResponseToValue(
494 const sync_pb::CommitResponse::EntryResponse
& proto
) {
495 DictionaryValue
* value
= new DictionaryValue();
496 SET_ENUM(response_type
, GetResponseTypeString
);
498 SET_STR(parent_id_string
);
499 SET_INT64(position_in_parent
);
502 SET_STR(error_message
);
507 DictionaryValue
* CommitResponseToValue(const sync_pb::CommitResponse
& proto
) {
508 DictionaryValue
* value
= new DictionaryValue();
509 SET_REP(entryresponse
, EntryResponseToValue
);
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
);
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
);
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
);
540 SET_ENUM(action
, GetActionString
);
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(),
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
);
565 DictionaryValue
* ClientToServerMessageToValue(
566 const sync_pb::ClientToServerMessage
& proto
,
567 bool include_specifics
) {
568 DictionaryValue
* value
= new DictionaryValue();
570 SET_INT32(protocol_version
);
571 if (proto
.has_commit()) {
573 CommitMessageToValue(proto
.commit(), include_specifics
));
576 SET(get_updates
, GetUpdatesMessageToValue
);
577 SET_STR(store_birthday
);
578 SET_BOOL(sync_problem_detected
);
596 } // namespace syncer