# Copyright 2012 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import print_function

import os.path

from json_parse import OrderedDict
from memoize import memoize


def _IsTypeFromManifestKeys(namespace, typename, fallback):
  # type(Namespace, str, bool) -> bool
  """Computes whether 'from_manifest_keys' is true for the given type.
  """
  if typename in namespace._manifest_referenced_types:
    return True

  return fallback

class ParseException(Exception):
  """Thrown when data in the model is invalid.
  """
  def __init__(self, parent, message):
    hierarchy = _GetModelHierarchy(parent)
    hierarchy.append(message)
    Exception.__init__(
        self, 'Model parse exception at:\n' + '\n'.join(hierarchy))


class Model(object):
  """Model of all namespaces that comprise an API.

  Properties:
  - |namespaces| a map of a namespace name to its model.Namespace
  """
  def __init__(self, allow_inline_enums=True):
    self._allow_inline_enums = allow_inline_enums
    self.namespaces = {}

  def AddNamespace(self,
                   json,
                   source_file,
                   include_compiler_options=False,
                   environment=None):
    """Add a namespace's json to the model and returns the namespace.
    """
    namespace = Namespace(json,
                          source_file,
                          include_compiler_options=include_compiler_options,
                          environment=environment,
                          allow_inline_enums=self._allow_inline_enums)
    self.namespaces[namespace.name] = namespace
    return namespace


def CreateFeature(name, model):
  if isinstance(model, dict):
    return SimpleFeature(name, model)
  return ComplexFeature(name, [SimpleFeature(name, child) for child in model])


class ComplexFeature(object):
  """A complex feature which may be made of several simple features.

  Properties:
  - |name| the name of the feature
  - |unix_name| the unix_name of the feature
  - |feature_list| a list of simple features which make up the feature
  """
  def __init__(self, feature_name, features):
    self.name = feature_name
    self.unix_name = UnixName(self.name)
    self.feature_list = features

class SimpleFeature(object):
  """A simple feature, which can make up a complex feature, as specified in
  files such as chrome/common/extensions/api/_permission_features.json.

  Properties:
  - |name| the name of the feature
  - |unix_name| the unix_name of the feature
  - |channel| the channel where the feature is released
  - |extension_types| the types which can use the feature
  - |allowlist| a list of extensions allowed to use the feature
  """
  def __init__(self, feature_name, feature_def):
    self.name = feature_name
    self.unix_name = UnixName(self.name)
    self.channel = feature_def['channel']
    self.extension_types = feature_def['extension_types']
    self.allowlist = feature_def.get('allowlist')


class Namespace(object):
  """An API namespace.

  Properties:
  - |name| the name of the namespace
  - |description| the description of the namespace
  - |deprecated| a reason and possible alternative for a deprecated api
  - |unix_name| the unix_name of the namespace
  - |source_file| the file that contained the namespace definition
  - |source_file_dir| the directory component of |source_file|
  - |source_file_filename| the filename component of |source_file|
  - |platforms| if not None, the list of platforms that the namespace is
                available to
  - |types| a map of type names to their model.Type
  - |functions| a map of function names to their model.Function
  - |events| a map of event names to their model.Function
  - |properties| a map of property names to their model.Property
  - |compiler_options| the compiler_options dict, only not empty if
                       |include_compiler_options| is True
  - |manifest_keys| is a Type representing the manifest keys for this namespace.
  """
  def __init__(self,
               json,
               source_file,
               include_compiler_options=False,
               environment=None,
               allow_inline_enums=True):
    self.name = json['namespace']
    if 'description' not in json:
      # TODO(kalman): Go back to throwing an error here.
      print('%s must have a "description" field. This will appear '
                       'on the API summary page.' % self.name)
      json['description'] = ''
    self.description = json['description']
    self.nodoc = json.get('nodoc', False)
    self.deprecated = json.get('deprecated', None)
    self.unix_name = UnixName(self.name)
    self.source_file = source_file
    self.source_file_dir, self.source_file_filename = os.path.split(source_file)
    self.short_filename = os.path.basename(source_file).split('.')[0]
    self.parent = None
    self.allow_inline_enums = allow_inline_enums
    self.platforms = _GetPlatforms(json)
    toplevel_origin = Origin(from_client=True, from_json=True)

    # While parsing manifest keys, we store all the types referenced by manifest
    # keys. This is useful for computing the correct Origin for types in the
    # namespace. This also necessitates parsing manifest keys before types.
    self._manifest_referenced_types = set()
    self.manifest_keys = _GetManifestKeysType(self, json)

    self.types = _GetTypes(self, json, self, toplevel_origin)
    self.functions = _GetFunctions(self, json, self)
    self.events = _GetEvents(self, json, self)
    self.properties = _GetProperties(self, json, self, toplevel_origin)
    if include_compiler_options:
      self.compiler_options = json.get('compiler_options', {})
    else:
      self.compiler_options = {}
    self.environment = environment
    self.documentation_options = json.get('documentation_options', {})


class Origin(object):
  """Stores the possible origin of model object as a pair of bools. These are:

  |from_client| indicating that instances can originate from users of
                generated code (for example, function results), or
  |from_json|   indicating that instances can originate from the JSON (for
                example, function parameters)
  |from_manifest_keys| indicating that instances for this type can be parsed
                from manifest keys.

  It is possible for model objects to originate from both the client and json,
  for example Types defined in the top-level schema, in which case both
  |from_client| and |from_json| would be True.
  """

  def __init__(self,
               from_client=False,
               from_json=False,
               from_manifest_keys=False):
    if not from_client and not from_json and not from_manifest_keys:
      raise ValueError(
          'One of (from_client, from_json, from_manifest_keys) must be true')
    self.from_client = from_client
    self.from_json = from_json
    self.from_manifest_keys = from_manifest_keys


class Type(object):
  """A Type defined in the json.

  Properties:
  - |name| the type name
  - |namespace| the Type's namespace
  - |description| the description of the type (if provided)
  - |properties| a map of property unix_names to their model.Property
  - |functions| a map of function names to their model.Function
  - |events| a map of event names to their model.Event
  - |origin| the Origin of the type
  - |property_type| the PropertyType of this Type
  - |item_type| if this is an array, the type of items in the array
  - |simple_name| the name of this Type without a namespace
  - |additional_properties| the type of the additional properties, if any is
                            specified
  """
  def __init__(self,
               parent,
               name,
               json,
               namespace,
               input_origin):
    self.name = name

    # The typename "ManifestKeys" is reserved.
    if name == 'ManifestKeys':
      assert parent == namespace and input_origin.from_manifest_keys, \
          'ManifestKeys type is reserved'

    self.namespace = namespace
    self.simple_name = _StripNamespace(self.name, namespace)
    self.unix_name = UnixName(self.name)
    self.description = json.get('description', None)
    self.jsexterns = json.get('jsexterns', None)
    self.nodoc = json.get('nodoc', False)

    # Copy the Origin and override the |from_manifest_keys| value as necessary.
    # We need to do this to ensure types reference by manifest types have the
    # correct value for |origin.from_manifest_keys|.
    self.origin = Origin(
      input_origin.from_client, input_origin.from_json,
      _IsTypeFromManifestKeys(namespace, name, input_origin.from_manifest_keys))

    self.parent = parent
    self.instance_of = json.get('isInstanceOf', None)
    self.is_serializable_function = json.get('serializableFunction', False)
    # TODO(kalman): Only objects need functions/events/properties, but callers
    # assume that all types have them. Fix this.
    self.functions = _GetFunctions(self, json, namespace)
    self.events = _GetEvents(self, json, namespace)
    self.properties = _GetProperties(self, json, namespace, self.origin)

    json_type = json.get('type', None)
    if json_type == 'array':
      self.property_type = PropertyType.ARRAY
      self.item_type = Type(self, '%sType' % name, json['items'], namespace,
                            self.origin)
    elif '$ref' in json:
      self.property_type = PropertyType.REF
      self.ref_type = json['$ref']

      # Record all types referenced by manifest types so that the proper Origin
      # can be set for them during type parsing.
      if self.origin.from_manifest_keys:
        namespace._manifest_referenced_types.add(self.ref_type)

    elif 'enum' in json and json_type == 'string':
      if not namespace.allow_inline_enums and not isinstance(parent, Namespace):
        raise ParseException(
            self,
            'Inline enum "%s" found in namespace "%s". These are not allowed. '
                'See crbug.com/472279' % (name, namespace.name))
      self.property_type = PropertyType.ENUM
      self.enum_values = [EnumValue(value) for value in json['enum']]
      self.cpp_enum_prefix_override = json.get('cpp_enum_prefix_override', None)
    elif json_type == 'any':
      self.property_type = PropertyType.ANY
    elif json_type == 'binary':
      self.property_type = PropertyType.BINARY
    elif json_type == 'boolean':
      self.property_type = PropertyType.BOOLEAN
    elif json_type == 'integer':
      self.property_type = PropertyType.INTEGER
    elif (json_type == 'double' or
          json_type == 'number'):
      self.property_type = PropertyType.DOUBLE
    elif json_type == 'string':
      self.property_type = PropertyType.STRING
    elif 'choices' in json:
      self.property_type = PropertyType.CHOICES
      def generate_type_name(type_json):
        if 'items' in type_json:
          return '%ss' % generate_type_name(type_json['items'])
        if '$ref' in type_json:
          return type_json['$ref']
        if 'type' in type_json:
          return type_json['type']
        return None
      self.choices = [
          Type(self,
               generate_type_name(choice) or 'choice%s' % i,
               choice,
               namespace,
               self.origin)
          for i, choice in enumerate(json['choices'])]
    elif json_type == 'object':
      if not (
          'isInstanceOf' in json or
          'properties' in json or
          'additionalProperties' in json or
          'functions' in json or
          'events' in json):
        raise ParseException(self, name + " has no properties or functions")
      self.property_type = PropertyType.OBJECT
      additional_properties_json = json.get('additionalProperties', None)
      if additional_properties_json is not None:
        self.additional_properties = Type(self,
                                          'additionalProperties',
                                          additional_properties_json,
                                          namespace,
                                          self.origin)
      else:
        self.additional_properties = None
    elif json_type == 'function':
      self.property_type = PropertyType.FUNCTION
      # Sometimes we might have an unnamed function, e.g. if it's a property
      # of an object. Use the name of the property in that case.
      function_name = json.get('name', name)
      self.function = Function(
        self, function_name, json, namespace, self.origin)
    else:
      raise ParseException(self, 'Unsupported JSON type %s' % json_type)

  def IsRootManifestKeyType(self):
    # type: () -> boolean
    ''' Returns true if this type corresponds to the top level ManifestKeys
    type.
    '''
    return self.name == 'ManifestKeys'

class Function(object):
  """A Function defined in the API.

  Properties:
  - |name| the function name
  - |platforms| if not None, the list of platforms that the function is
                available to
  - |params| a list of parameters to the function (order matters). A separate
             parameter is used for each choice of a 'choices' parameter
  - |deprecated| a reason and possible alternative for a deprecated function
  - |description| a description of the function (if provided)
  - |returns_async| an asynchronous return for the function. This may be
                    specified either though the returns_async field or a
                    callback function at the end of the parameters, but not both
  - |optional| whether the Function is "optional"; this only makes sense to be
               present when the Function is representing a callback property
  - |simple_name| the name of this Function without a namespace
  - |returns| the return type of the function; None if the function does not
    return a value
  """
  def __init__(self,
               parent,
               name,
               json,
               namespace,
               origin):
    self.name = name
    self.simple_name = _StripNamespace(self.name, namespace)
    self.platforms = _GetPlatforms(json)
    self.params = []
    self.description = json.get('description')
    self.deprecated = json.get('deprecated')
    self.returns_async = None
    self.optional = _GetWithDefaultChecked(parent, json, 'optional', False)
    self.parent = parent
    self.nocompile = json.get('nocompile')
    options = json.get('options', {})
    self.conditions = options.get('conditions', [])
    self.actions = options.get('actions', [])
    self.supports_listeners = options.get('supportsListeners', True)
    self.supports_rules = options.get('supportsRules', False)
    self.supports_dom = options.get('supportsDom', False)
    self.nodoc = json.get('nodoc', False)

    def GeneratePropertyFromParam(p):
      return Property(self, p['name'], p, namespace, origin)

    self.filters = [GeneratePropertyFromParam(filter_instance)
                    for filter_instance in json.get('filters', [])]

    returns_async = json.get('returns_async', None)
    if returns_async:
      returns_async_params = returns_async.get('parameters')
      if (returns_async_params is None):
        raise ValueError(
            'parameters key not specified on returns_async: %s.%s in %s' %
            (namespace.name, name, namespace.source_file))
      if len(returns_async_params) > 1:
        raise ValueError('Only a single parameter can be specific on '
                         'returns_async: %s.%s in %s' %
                         (namespace.name, name, namespace.source_file))
      self.returns_async = ReturnsAsync(self, returns_async, namespace,
                                        Origin(from_client=True), True)
      # TODO(https://crbug.com/1143032): Returning a synchronous value is
      # incompatible with returning a promise. There are APIs that specify this,
      # though. Some appear to be incorrectly specified (i.e., don't return a
      # value, but claim to), but others actually do return something. We'll
      # need to handle those when converting them to allow promises.
      if json.get('returns') is not None:
        raise ValueError(
            'Cannot specify both returns and returns_async: %s.%s'
            % (namespace.name, name))

    params = json.get('parameters', [])
    callback_param = None
    for i, param in enumerate(params):
      # We consider the final function argument to the API to be the callback
      # parameter if returns_async wasn't specified. Otherwise, we consider all
      # function arguments to just be properties.
      if i == len(params) - 1 and param.get(
          'type') == 'function' and not self.returns_async:
        callback_param = param
      else:
        # Treat all intermediate function arguments as properties. Certain APIs,
        # such as the webstore, have these.
        self.params.append(GeneratePropertyFromParam(param))

    if callback_param:
      # Even though we are creating a ReturnsAsync type here, this does not
      # support being returned via a Promise, as this is implied by
      # "returns_async" being found in the JSON.
      # This is just a holder type for the callback.
      self.returns_async = ReturnsAsync(self, callback_param, namespace,
                                        Origin(from_client=True), False)

    self.returns = None
    if 'returns' in json:
      self.returns = Type(self,
                          '%sReturnType' % name,
                          json['returns'],
                          namespace,
                          origin)


class ReturnsAsync(object):
  """A structure documenting asynchronous return values (through a callback or
  promise) for an API function.

  Properties:
  - |name| the name of the asynchronous return, generally 'callback'
  - |simple_name| the name of this ReturnsAsync without a namespace
  - |description| a description of the ReturnsAsync (if provided)
  - |optional| whether specifying the ReturnsAsync is "optional" (in situations
               where promises are supported, this will be ignored as promises
               inheriently make a callback optional)
  - |params| a list of parameters supplied to the function in the case of using
             callbacks, or the list of properties on the returned object in the
             case of using promises
  - |can_return_promise| whether this can be treated as a Promise as well as
                         callback
  """
  def __init__(self, parent, json, namespace, origin, can_return_promise):
    self.name = json.get('name')
    self.simple_name = _StripNamespace(self.name, namespace)
    self.description = json.get('description')
    self.optional = _GetWithDefaultChecked(parent, json, 'optional', False)
    self.nocompile = json.get('nocompile')
    self.parent = parent
    self.can_return_promise = can_return_promise

    if json.get('returns') is not None:
      raise ValueError('Cannot return a value from an asynchronous return: '
                       '%s.%s' % (namespace.name, self.name))
    if json.get('deprecated') is not None:
      raise ValueError('Cannot specify deprecated on an asynchronous return: '
                       '%s.%s' % (namespace.name, self.name))

    def GeneratePropertyFromParam(p):
      return Property(self, p['name'], p, namespace, origin)

    params = json.get('parameters', [])
    self.params = []
    for _, param in enumerate(params):
      self.params.append(GeneratePropertyFromParam(param))


class Property(object):
  """A property of a type OR a parameter to a function.
  Properties:
  - |name| name of the property as in the json. This shouldn't change since
    it is the key used to access Value::Dict
  - |unix_name| the unix_style_name of the property. Used as variable name
  - |optional| a boolean representing whether the property is optional
  - |description| a description of the property (if provided)
  - |type_| the model.Type of this property
  - |simple_name| the name of this Property without a namespace
  - |deprecated| a reason and possible alternative for a deprecated property
  """
  def __init__(self, parent, name, json, namespace, origin):
    """Creates a Property from JSON.
    """
    self.parent = parent
    self.name = name
    self._unix_name = UnixName(self.name)
    self._unix_name_used = False
    self.origin = origin
    self.simple_name = _StripNamespace(self.name, namespace)
    self.description = json.get('description', None)
    self.optional = json.get('optional', None)
    self.instance_of = json.get('isInstanceOf', None)
    self.deprecated = json.get('deprecated')
    self.nodoc = json.get('nodoc', False)

    # HACK: only support very specific value types.
    is_allowed_value = (
        '$ref' not in json and
        ('type' not in json or json['type'] == 'integer'
                            or json['type'] == 'number'
                            or json['type'] == 'string'))

    self.value = None
    if 'value' in json and is_allowed_value:
      self.value = json['value']
      if 'type' not in json:
        # Sometimes the type of the value is left out, and we need to figure
        # it out for ourselves.
        if isinstance(self.value, int):
          json['type'] = 'integer'
        elif isinstance(self.value, float):
          json['type'] = 'double'
        elif isinstance(self.value, basestring):
          json['type'] = 'string'
        else:
          # TODO(kalman): support more types as necessary.
          raise ParseException(
              parent,
              '"%s" is not a supported type for "value"' % type(self.value))

    self.type_ = Type(parent, name, json, namespace, origin)

  def GetUnixName(self):
    """Gets the property's unix_name. Raises AttributeError if not set.
    """
    if not self._unix_name:
      raise AttributeError('No unix_name set on %s' % self.name)
    self._unix_name_used = True
    return self._unix_name

  def SetUnixName(self, unix_name):
    """Set the property's unix_name. Raises AttributeError if the unix_name has
    already been used (GetUnixName has been called).
    """
    if unix_name == self._unix_name:
      return
    if self._unix_name_used:
      raise AttributeError(
          'Cannot set the unix_name on %s; '
          'it is already used elsewhere as %s' %
          (self.name, self._unix_name))
    self._unix_name = unix_name

  unix_name = property(GetUnixName, SetUnixName)

class EnumValue(object):
  """A single value from an enum.
  Properties:
  - |name| name of the property as in the json.
  - |description| a description of the property (if provided)
  """
  def __init__(self, json):
    if isinstance(json, dict):
      self.name = json['name']
      self.description = json.get('description')
    else:
      self.name = json
      self.description = None

  def CamelName(self):
    return CamelName(self.name)

class _Enum(object):
  """Superclass for enum types with a "name" field, setting up repr/eq/ne.
  Enums need to do this so that equality/non-equality work over pickling.
  """
  @staticmethod
  def GetAll(cls):
    """Yields all _Enum objects declared in |cls|.
    """
    for prop_key in dir(cls):
      prop_value = getattr(cls, prop_key)
      if isinstance(prop_value, _Enum):
        yield prop_value

  def __init__(self, name):
    self.name = name

  def __eq__(self, other):
    return type(other) == type(self) and other.name == self.name
  def __ne__(self, other):
    return not (self == other)

  def __repr__(self):
    return self.name

  def __str__(self):
    return repr(self)

  def __hash__(self):
    return hash(self.name)


class _PropertyTypeInfo(_Enum):
  def __init__(self, is_fundamental, name):
    _Enum.__init__(self, name)
    self.is_fundamental = is_fundamental

  def __repr__(self):
    return self.name

class PropertyType(object):
  """Enum of different types of properties/parameters.
  """
  ANY = _PropertyTypeInfo(False, "any")
  ARRAY = _PropertyTypeInfo(False, "array")
  BINARY = _PropertyTypeInfo(False, "binary")
  BOOLEAN = _PropertyTypeInfo(True, "boolean")
  CHOICES = _PropertyTypeInfo(False, "choices")
  DOUBLE = _PropertyTypeInfo(True, "double")
  ENUM = _PropertyTypeInfo(False, "enum")
  FUNCTION = _PropertyTypeInfo(False, "function")
  INT64 = _PropertyTypeInfo(True, "int64")
  INTEGER = _PropertyTypeInfo(True, "integer")
  OBJECT = _PropertyTypeInfo(False, "object")
  REF = _PropertyTypeInfo(False, "ref")
  STRING = _PropertyTypeInfo(True, "string")

def IsCPlusPlusKeyword(name):
  """Returns true if `name` is a C++ reserved keyword.
  """
  # Obtained from https://en.cppreference.com/w/cpp/keyword.
  keywords = {
    "alignas",
    "alignof",
    "and",
    "and_eq",
    "asm",
    "atomic_cancel",
    "atomic_commit",
    "atomic_noexcept",
    "auto",
    "bitand",
    "bitor",
    "bool",
    "break",
    "case",
    "catch",
    "char",
    "char8_t",
    "char16_t",
    "char32_t",
    "class",
    "compl",
    "concept",
    "const",
    "consteval",
    "constexpr",
    "constinit",
    "const_cast",
    "continue",
    "co_await",
    "co_return",
    "co_yield",
    "decltype",
    "default",
    "delete",
    "do",
    "double",
    "dynamic_cast",
    "else",
    "enum",
    "explicit",
    "export",
    "extern",
    "false",
    "float",
    "for",
    "friend",
    "goto",
    "if",
    "inline",
    "int",
    "long",
    "mutable",
    "namespace",
    "new",
    "noexcept",
    "not",
    "not_eq",
    "nullptr",
    "operator",
    "or",
    "or_eq",
    "private",
    "protected",
    "public",
    "reflexpr",
    "register",
    "reinterpret_cast",
    "requires",
    "return",
    "short",
    "signed",
    "sizeof",
    "static",
    "static_assert",
    "static_cast",
    "struct",
    "switch",
    "synchronized",
    "template",
    "this",
    "thread_local",
    "throw",
    "true",
    "try",
    "typedef",
    "typeid",
    "typename",
    "union",
    "unsigned",
    "using",
    "virtual",
    "void",
    "volatile",
    "wchar_t",
    "while",
    "xor",
    "xor_eq"
  }
  return name in keywords

@memoize
def UnixName(name):
  '''Returns the unix_style name for a given lowerCamelCase string.
  '''
  # Append an extra underscore to the |name|'s end if it's a reserved C++
  # keyword in order to avoid compilation errors in generated code.
  # Note: In some cases, this is overly greedy, because the unix name is
  # appended to another string (such as in choices, where it becomes
  # "as_double_"). We can fix this if this situation becomes common, but for now
  # it's only hit in tests, and not worth the complexity.
  if IsCPlusPlusKeyword(name):
    name = name + '_'

  # Prepend an extra underscore to the |name|'s start if it doesn't start with a
  # letter or underscore to ensure the generated unix name follows C++
  # identifier rules.
  assert(name)
  if name[0].isdigit():
    name = '_' + name

  unix_name = []
  for i, c in enumerate(name):
    if c.isupper() and i > 0 and name[i - 1] != '_':
      # Replace lowerUpper with lower_Upper.
      if name[i - 1].islower():
        unix_name.append('_')
      # Replace ACMEWidgets with ACME_Widgets
      elif i + 1 < len(name) and name[i + 1].islower():
        unix_name.append('_')
    if c == '.':
      # Replace hello.world with hello_world.
      unix_name.append('_')
    else:
      # Everything is lowercase.
      unix_name.append(c.lower())
  return ''.join(unix_name)


@memoize
def CamelName(snake):
  ''' Converts a snake_cased_string to a camelCasedOne. '''
  pieces = snake.split('_')
  camel = []
  for i, piece in enumerate(pieces):
    if i == 0:
      camel.append(piece)
    else:
      camel.append(piece.capitalize())
  return ''.join(camel)


def _StripNamespace(name, namespace):
  if name.startswith(namespace.name + '.'):
    return name[len(namespace.name + '.'):]
  return name


def _GetModelHierarchy(entity):
  """Returns the hierarchy of the given model entity."""
  hierarchy = []
  while entity is not None:
    hierarchy.append(getattr(entity, 'name', repr(entity)))
    if isinstance(entity, Namespace):
      hierarchy.insert(0, '  in %s' % entity.source_file)
    entity = getattr(entity, 'parent', None)
  hierarchy.reverse()
  return hierarchy


def _GetTypes(parent, json, namespace, origin):
  """Creates Type objects extracted from |json|.
  """
  assert hasattr(namespace, 'manifest_keys'), \
    'Types should be parsed after parsing manifest keys.'

  types = OrderedDict()
  for type_json in json.get('types', []):
    type_ = Type(parent, type_json['id'], type_json, namespace, origin)
    types[type_.name] = type_
  return types


def _GetFunctions(parent, json, namespace):
  """Creates Function objects extracted from |json|.
  """
  functions = OrderedDict()
  for function_json in json.get('functions', []):
    function = Function(parent,
                        function_json['name'],
                        function_json,
                        namespace,
                        Origin(from_json=True))
    functions[function.name] = function
  return functions


def _GetEvents(parent, json, namespace):
  """Creates Function objects generated from the events in |json|.
  """
  events = OrderedDict()
  for event_json in json.get('events', []):
    event = Function(parent,
                     event_json['name'],
                     event_json,
                     namespace,
                     Origin(from_client=True))
    events[event.name] = event
  return events


def _GetProperties(parent, json, namespace, origin):
  """Generates Property objects extracted from |json|.
  """
  properties = OrderedDict()
  for name, property_json in json.get('properties', {}).items():
    properties[name] = Property(parent, name, property_json, namespace, origin)
  return properties


def _GetManifestKeysType(self, json):
  # type: (OrderedDict) -> Type
  """Returns the Type for manifest keys parsing, or None if there are no
  manifest keys in this namespace.
  """
  if not json.get('manifest_keys'):
    return None

  # Create a dummy object to parse "manifest_keys" as a type.
  manifest_keys_type = {
    'type': 'object',
    'properties': json['manifest_keys'],
  }
  return Type(self, 'ManifestKeys', manifest_keys_type, self,
              Origin(from_manifest_keys=True))

def _GetWithDefaultChecked(self, json, key, default):
  if json.get(key) == default:
    raise ParseException(
        self, 'The attribute "%s" is specified as "%s", but this is the '
        'default value if the attribute is not included. It should be removed.'
        % (key, default))
  return json.get(key, default)

class _PlatformInfo(_Enum):
  def __init__(self, name):
    _Enum.__init__(self, name)


class Platforms(object):
  """Enum of the possible platforms.
  """
  CHROMEOS = _PlatformInfo("chromeos")
  FUCHSIA = _PlatformInfo("fuchsia")
  LACROS = _PlatformInfo("lacros")
  LINUX = _PlatformInfo("linux")
  MAC = _PlatformInfo("mac")
  WIN = _PlatformInfo("win")


def _GetPlatforms(json):
  if 'platforms' not in json or json['platforms'] == None:
    return None
  # Sanity check: platforms should not be an empty list.
  if not json['platforms']:
    raise ValueError('"platforms" cannot be an empty list')
  platforms = []
  for platform_name in json['platforms']:
    platform_enum = None
    for platform in _Enum.GetAll(Platforms):
      if platform_name == platform.name:
        platform_enum = platform
        break
    if not platform_enum:
      raise ValueError('Invalid platform specified: ' + platform_name)
    platforms.append(platform_enum)
  return platforms
