13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# found in the LICENSE file.
43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import re
63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)def ToUnderscore(obj):
93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  """Converts a string, list, or dict from camelCase to lower_with_underscores.
103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Descends recursively into lists and dicts, converting all dict keys.
123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Returns a newly allocated object of the same structure as the input.
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  """
143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if isinstance(obj, basestring):
153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return re.sub('(?!^)([A-Z]+)', r'_\1', obj).lower()
163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  elif isinstance(obj, list):
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return [ToUnderscore(item) for item in obj]
193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  elif isinstance(obj, dict):
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    output = {}
223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    for k, v in obj.iteritems():
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if isinstance(v, list) or isinstance(v, dict):
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        output[ToUnderscore(k)] = ToUnderscore(v)
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      else:
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        output[ToUnderscore(k)] = v
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return output
283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  else:
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return obj
31