1// Copyright (c) 2013 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.
4
5'use strict';
6
7base.require('base.quad');
8base.require('tracing.trace_model.object_instance');
9
10base.exportTo('cc', function() {
11  var convertedNameCache = {};
12  function convertNameToJSConvention(name) {
13    if (name in convertedNameCache)
14      return convertedNameCache[name];
15
16    if (name[0] == '_' ||
17        name[name.length - 1] == '_') {
18      convertedNameCache[name] = name;
19      return name;
20    }
21
22    var words = name.split('_');
23    if (words.length == 1) {
24      convertedNameCache[name] = words[0];
25      return words[0];
26    }
27
28    for (var i = 1; i < words.length; i++)
29      words[i] = words[i][0].toUpperCase() + words[i].substring(1);
30
31    convertedNameCache[name] = words.join('');
32    return convertedNameCache[name];
33  }
34
35  function convertObjectFieldNamesToJSConventions(object) {
36    base.iterObjectFieldsRecursively(
37        object,
38        function(object, fieldName, fieldValue) {
39          delete object[fieldName];
40          object[newFieldName] = fieldValue;
41          return newFieldName;
42        });
43  }
44
45  function convertQuadSuffixedTypesToQuads(object) {
46    base.iterObjectFieldsRecursively(
47        object,
48        function(object, fieldName, fieldValue) {
49        });
50  }
51
52  function convertObject(object) {
53    convertObjectFieldNamesToJSConventions(object);
54    convertQuadSuffixedTypesToQuads(object);
55  }
56
57  function moveRequiredFieldsFromArgsToToplevel(object, fields) {
58    for (var i = 0; i < fields.length; i++) {
59      var key = fields[i];
60      if (object.args[key] === undefined)
61        throw Error('Expected field ' + key + ' not found in args');
62      if (object[key] !== undefined)
63        throw Error('Field ' + key + ' already in object');
64      object[key] = object.args[key];
65      delete object.args[key];
66    }
67  }
68
69  function moveOptionalFieldsFromArgsToToplevel(object, fields) {
70    for (var i = 0; i < fields.length; i++) {
71      var key = fields[i];
72      if (object.args[key] === undefined)
73        continue;
74      if (object[key] !== undefined)
75        throw Error('Field ' + key + ' already in object');
76      object[key] = object.args[key];
77      delete object.args[key];
78    }
79  }
80
81  function preInitializeObject(object) {
82    preInitializeObjectInner(object.args, false);
83  }
84
85  function preInitializeObjectInner(object, hasRecursed) {
86    if (!(object instanceof Object))
87      return;
88
89    if (object instanceof Array) {
90      for (var i = 0; i < object.length; i++)
91        preInitializeObjectInner(object[i], true);
92      return;
93    }
94
95    if (hasRecursed &&
96        (object instanceof tracing.trace_model.ObjectSnapshot ||
97         object instanceof tracing.trace_model.ObjectInstance))
98      return;
99
100    for (var key in object) {
101      var newKey = convertNameToJSConvention(key);
102      if (newKey != key) {
103        var value = object[key];
104        delete object[key];
105        object[newKey] = value;
106        key = newKey;
107      }
108
109      if (/Quad$/.test(key) && !(object[key] instanceof base.Quad)) {
110        var q;
111        try {
112          q = base.Quad.From8Array(object[key]);
113        } catch (e) {
114          console.log(e);
115        }
116        object[key] = q;
117        continue;
118      }
119
120      preInitializeObjectInner(object[key], true);
121    }
122  }
123
124  return {
125    preInitializeObject: preInitializeObject,
126    convertNameToJSConvention: convertNameToJSConvention,
127    moveRequiredFieldsFromArgsToToplevel: moveRequiredFieldsFromArgsToToplevel,
128    moveOptionalFieldsFromArgsToToplevel: moveOptionalFieldsFromArgsToToplevel
129  };
130});
131