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

"""Generates C++ source files from a mojom.Module."""

import mojom.generate.generator as generator
import mojom.generate.module as mojom
import mojom.generate.pack as pack
from mojom.generate.template_expander import UseJinja


_kind_to_cpp_type = {
  mojom.BOOL:                  "bool",
  mojom.INT8:                  "int8_t",
  mojom.UINT8:                 "uint8_t",
  mojom.INT16:                 "int16_t",
  mojom.UINT16:                "uint16_t",
  mojom.INT32:                 "int32_t",
  mojom.UINT32:                "uint32_t",
  mojom.FLOAT:                 "float",
  mojom.INT64:                 "int64_t",
  mojom.UINT64:                "uint64_t",
  mojom.DOUBLE:                "double",
}

_kind_to_cpp_literal_suffix = {
  mojom.UINT8:        "U",
  mojom.UINT16:       "U",
  mojom.UINT32:       "U",
  mojom.FLOAT:        "f",
  mojom.UINT64:       "ULL",
}

# TODO(rockot): Get rid of these globals. This requires some refactoring of the
# generator library code so that filters can use the generator as context.
_current_typemap = {}
_for_blink = False
# TODO(rockot, yzshen): The variant handling is kind of a hack currently. Make
# it right.
_variant = None
_export_attribute = None


class _NameFormatter(object):
  """A formatter for the names of kinds or values."""

  def __init__(self, token, variant):
    self._token = token
    self._variant = variant

  def Format(self, separator, prefixed=False, internal=False,
             include_variant=False, add_same_module_namespaces=False,
             flatten_nested_kind=False):
    """Formats the name according to the given configuration.

    Args:
      separator: Separator between different parts of the name.
      prefixed: Whether a leading separator should be added.
      internal: Returns the name in the "internal" namespace.
      include_variant: Whether to include variant as namespace. If |internal| is
          True, then this flag is ignored and variant is not included.
      add_same_module_namespaces: Includes all namespaces even if the token is
          from the same module as the current mojom file.
      flatten_nested_kind: It is allowed to define enums inside structs and
          interfaces. If this flag is set to True, this method concatenates the
          parent kind and the nested kind with '_', instead of treating the
          parent kind as a scope."""

    parts = []
    if self._ShouldIncludeNamespace(add_same_module_namespaces):
      if prefixed:
        parts.append("")
      parts.extend(self._GetNamespace())
      if include_variant and self._variant and not internal:
        parts.append(self._variant)
    parts.extend(self._GetName(internal, flatten_nested_kind))
    return separator.join(parts)

  def FormatForCpp(self, add_same_module_namespaces=False, internal=False,
                   flatten_nested_kind=False):
    return self.Format(
        "::", prefixed=True,
        add_same_module_namespaces=add_same_module_namespaces,
        internal=internal, include_variant=True,
        flatten_nested_kind=flatten_nested_kind)

  def FormatForMojom(self):
    return self.Format(".", add_same_module_namespaces=True)

  def _MapKindName(self, token, internal):
    if not internal:
      return token.name
    if (mojom.IsStructKind(token) or mojom.IsUnionKind(token) or
        mojom.IsEnumKind(token)):
      return token.name + "_Data"
    return token.name

  def _GetName(self, internal, flatten_nested_kind):
    if isinstance(self._token, mojom.EnumValue):
      name_parts = _NameFormatter(self._token.enum, self._variant)._GetName(
          internal, flatten_nested_kind)
      name_parts.append(self._token.name)
      return name_parts

    name_parts = []
    if internal:
      name_parts.append("internal")

    if (flatten_nested_kind and mojom.IsEnumKind(self._token) and
        self._token.parent_kind):
      name = "%s_%s" % (self._token.parent_kind.name,
                        self._MapKindName(self._token, internal))
      name_parts.append(name)
      return name_parts

    if self._token.parent_kind:
      name_parts.append(self._MapKindName(self._token.parent_kind, internal))
    name_parts.append(self._MapKindName(self._token, internal))
    return name_parts

  def _ShouldIncludeNamespace(self, add_same_module_namespaces):
    return add_same_module_namespaces or self._token.imported_from

  def _GetNamespace(self):
    if self._token.imported_from:
      return NamespaceToArray(self._token.imported_from["namespace"])
    elif hasattr(self._token, "module"):
      return NamespaceToArray(self._token.module.namespace)
    return []


def ConstantValue(constant):
  return ExpressionToText(constant.value, kind=constant.kind)

# TODO(yzshen): Revisit the default value feature. It was designed prior to
# custom type mapping.
def DefaultValue(field):
  if field.default:
    if mojom.IsStructKind(field.kind):
      assert field.default == "default"
      if not IsTypemappedKind(field.kind):
        return "%s::New()" % GetNameForKind(field.kind)
    return ExpressionToText(field.default, kind=field.kind)
  return ""

def NamespaceToArray(namespace):
  return namespace.split(".") if namespace else []

def GetNameForKind(kind, internal=False, flatten_nested_kind=False,
                   add_same_module_namespaces=False):
  return _NameFormatter(kind, _variant).FormatForCpp(
      internal=internal, flatten_nested_kind=flatten_nested_kind,
      add_same_module_namespaces=add_same_module_namespaces)

def GetQualifiedNameForKind(kind, internal=False, flatten_nested_kind=False,
                            include_variant=True):
  return _NameFormatter(
      kind, _variant if include_variant else None).FormatForCpp(
          internal=internal, add_same_module_namespaces=True,
          flatten_nested_kind=flatten_nested_kind)


def GetWtfHashFnNameForEnum(enum):
  return _NameFormatter(
      enum, None).Format("_", internal=True, add_same_module_namespaces=True,
                         flatten_nested_kind=True) + "HashFn"


def GetFullMojomNameForKind(kind):
  return _NameFormatter(kind, _variant).FormatForMojom()

def IsTypemappedKind(kind):
  return hasattr(kind, "name") and \
      GetFullMojomNameForKind(kind) in _current_typemap

def IsNativeOnlyKind(kind):
  return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \
      kind.native_only


def IsHashableKind(kind):
  """Check if the kind can be hashed.

  Args:
    kind: {Kind} The kind to check.

  Returns:
    {bool} True if a value of this kind can be hashed.
  """
  checked = set()
  def Check(kind):
    if kind.spec in checked:
      return True
    checked.add(kind.spec)
    if mojom.IsNullableKind(kind):
      return False
    elif mojom.IsStructKind(kind):
      if (IsTypemappedKind(kind) and
          not _current_typemap[GetFullMojomNameForKind(kind)]["hashable"]):
        return False
      return all(Check(field.kind) for field in kind.fields)
    elif mojom.IsEnumKind(kind):
      return not IsTypemappedKind(kind) or _current_typemap[
          GetFullMojomNameForKind(kind)]["hashable"]
    elif mojom.IsUnionKind(kind):
      return all(Check(field.kind) for field in kind.fields)
    elif mojom.IsAnyHandleKind(kind):
      return False
    elif mojom.IsAnyInterfaceKind(kind):
      return False
    # TODO(tibell): Arrays and maps could be made hashable. We just don't have a
    # use case yet.
    elif mojom.IsArrayKind(kind):
      return False
    elif mojom.IsMapKind(kind):
      return False
    else:
      return True
  return Check(kind)


def AllEnumValues(enum):
  """Return all enum values associated with an enum.

  Args:
    enum: {mojom.Enum} The enum type.

  Returns:
   {Set[int]} The values.
  """
  return set(field.numeric_value for field in enum.fields)


def GetNativeTypeName(typemapped_kind):
  return _current_typemap[GetFullMojomNameForKind(typemapped_kind)]["typename"]

def GetCppPodType(kind):
  return _kind_to_cpp_type[kind]

def FormatConstantDeclaration(constant, nested=False):
  if mojom.IsStringKind(constant.kind):
    if nested:
      return "const char %s[]" % constant.name
    return "%sextern const char %s[]" % \
        ((_export_attribute + " ") if _export_attribute else "", constant.name)
  return "constexpr %s %s = %s" % (GetCppPodType(constant.kind), constant.name,
                                   ConstantValue(constant))

def GetCppWrapperType(kind, add_same_module_namespaces=False):
  def _AddOptional(type_name):
    pattern = "WTF::Optional<%s>" if _for_blink else "base::Optional<%s>"
    return pattern % type_name

  if IsTypemappedKind(kind):
    type_name = GetNativeTypeName(kind)
    if (mojom.IsNullableKind(kind) and
        not _current_typemap[GetFullMojomNameForKind(kind)][
           "nullable_is_same_type"]):
      type_name = _AddOptional(type_name)
    return type_name
  if mojom.IsEnumKind(kind):
    return GetNameForKind(
        kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
    return "%sPtr" % GetNameForKind(
        kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsArrayKind(kind):
    pattern = "WTF::Vector<%s>" if _for_blink else "std::vector<%s>"
    if mojom.IsNullableKind(kind):
      pattern = _AddOptional(pattern)
    return pattern % GetCppWrapperType(
        kind.kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsMapKind(kind):
    pattern = ("WTF::HashMap<%s, %s>" if _for_blink else
               "std::unordered_map<%s, %s>")
    if mojom.IsNullableKind(kind):
      pattern = _AddOptional(pattern)
    return pattern % (
        GetCppWrapperType(
            kind.key_kind,
            add_same_module_namespaces=add_same_module_namespaces),
        GetCppWrapperType(
            kind.value_kind,
            add_same_module_namespaces=add_same_module_namespaces))
  if mojom.IsInterfaceKind(kind):
    return "%sPtr" % GetNameForKind(
        kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsInterfaceRequestKind(kind):
    return "%sRequest" % GetNameForKind(
        kind.kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsAssociatedInterfaceKind(kind):
    return "%sAssociatedPtrInfo" % GetNameForKind(
        kind.kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsAssociatedInterfaceRequestKind(kind):
    return "%sAssociatedRequest" % GetNameForKind(
        kind.kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsStringKind(kind):
    if _for_blink:
      return "WTF::String"
    type_name = "std::string"
    return _AddOptional(type_name) if mojom.IsNullableKind(kind) else type_name
  if mojom.IsGenericHandleKind(kind):
    return "mojo::ScopedHandle"
  if mojom.IsDataPipeConsumerKind(kind):
    return "mojo::ScopedDataPipeConsumerHandle"
  if mojom.IsDataPipeProducerKind(kind):
    return "mojo::ScopedDataPipeProducerHandle"
  if mojom.IsMessagePipeKind(kind):
    return "mojo::ScopedMessagePipeHandle"
  if mojom.IsSharedBufferKind(kind):
    return "mojo::ScopedSharedBufferHandle"
  if not kind in _kind_to_cpp_type:
    raise Exception("Unrecognized kind %s" % kind.spec)
  return _kind_to_cpp_type[kind]

def IsMoveOnlyKind(kind):
  if IsTypemappedKind(kind):
    if mojom.IsEnumKind(kind):
      return False
    return _current_typemap[GetFullMojomNameForKind(kind)]["move_only"]
  if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
    return True
  if mojom.IsArrayKind(kind):
    return IsMoveOnlyKind(kind.kind)
  if mojom.IsMapKind(kind):
    return IsMoveOnlyKind(kind.value_kind)
  if mojom.IsAnyHandleOrInterfaceKind(kind):
    return True
  return False

def IsCopyablePassByValue(kind):
  if not IsTypemappedKind(kind):
    return False
  return _current_typemap[GetFullMojomNameForKind(kind)][
      "copyable_pass_by_value"]

def ShouldPassParamByValue(kind):
  return ((not mojom.IsReferenceKind(kind)) or IsMoveOnlyKind(kind) or
      IsCopyablePassByValue(kind))

def GetCppWrapperParamType(kind):
  cpp_wrapper_type = GetCppWrapperType(kind)
  return (cpp_wrapper_type if ShouldPassParamByValue(kind)
                           else "const %s&" % cpp_wrapper_type)

def GetCppFieldType(kind):
  if mojom.IsStructKind(kind):
    return ("mojo::internal::Pointer<%s>" %
        GetNameForKind(kind, internal=True))
  if mojom.IsUnionKind(kind):
    return "%s" % GetNameForKind(kind, internal=True)
  if mojom.IsArrayKind(kind):
    return ("mojo::internal::Pointer<mojo::internal::Array_Data<%s>>" %
            GetCppFieldType(kind.kind))
  if mojom.IsMapKind(kind):
    return ("mojo::internal::Pointer<mojo::internal::Map_Data<%s, %s>>" %
            (GetCppFieldType(kind.key_kind), GetCppFieldType(kind.value_kind)))
  if mojom.IsInterfaceKind(kind):
    return "mojo::internal::Interface_Data"
  if mojom.IsInterfaceRequestKind(kind):
    return "mojo::internal::Handle_Data"
  if mojom.IsAssociatedInterfaceKind(kind):
    return "mojo::internal::AssociatedInterface_Data"
  if mojom.IsAssociatedInterfaceRequestKind(kind):
    return "mojo::internal::AssociatedEndpointHandle_Data"
  if mojom.IsEnumKind(kind):
    return "int32_t"
  if mojom.IsStringKind(kind):
    return "mojo::internal::Pointer<mojo::internal::String_Data>"
  if mojom.IsAnyHandleKind(kind):
    return "mojo::internal::Handle_Data"
  return _kind_to_cpp_type[kind]

def GetCppUnionFieldType(kind):
  if mojom.IsUnionKind(kind):
    return ("mojo::internal::Pointer<%s>" % GetNameForKind(kind, internal=True))
  return GetCppFieldType(kind)

def GetUnionGetterReturnType(kind):
  if mojom.IsReferenceKind(kind):
    return "%s&" % GetCppWrapperType(kind)
  return GetCppWrapperType(kind)

def GetUnionTraitGetterReturnType(kind):
  """Get field type used in UnionTraits template specialization.

  The type may be qualified as UnionTraits specializations live outside the
  namespace where e.g. structs are defined.

  Args:
    kind: {Kind} The type of the field.

  Returns:
    {str} The C++ type to use for the field.
  """
  if mojom.IsReferenceKind(kind):
    return "%s&" % GetCppWrapperType(kind, add_same_module_namespaces=True)
  return GetCppWrapperType(kind, add_same_module_namespaces=True)

def GetCppDataViewType(kind, qualified=False):
  def _GetName(input_kind):
    return _NameFormatter(input_kind, None).FormatForCpp(
        add_same_module_namespaces=qualified, flatten_nested_kind=True)

  if mojom.IsEnumKind(kind):
    return _GetName(kind)
  if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
    return "%sDataView" % _GetName(kind)
  if mojom.IsArrayKind(kind):
    return "mojo::ArrayDataView<%s>" % GetCppDataViewType(kind.kind, qualified)
  if mojom.IsMapKind(kind):
    return ("mojo::MapDataView<%s, %s>" % (
        GetCppDataViewType(kind.key_kind, qualified),
        GetCppDataViewType(kind.value_kind, qualified)))
  if mojom.IsStringKind(kind):
    return "mojo::StringDataView"
  if mojom.IsInterfaceKind(kind):
    return "%sPtrDataView" % _GetName(kind)
  if mojom.IsInterfaceRequestKind(kind):
    return "%sRequestDataView" % _GetName(kind.kind)
  if mojom.IsAssociatedInterfaceKind(kind):
    return "%sAssociatedPtrInfoDataView" % _GetName(kind.kind)
  if mojom.IsAssociatedInterfaceRequestKind(kind):
    return "%sAssociatedRequestDataView" % _GetName(kind.kind)
  if mojom.IsGenericHandleKind(kind):
    return "mojo::ScopedHandle"
  if mojom.IsDataPipeConsumerKind(kind):
    return "mojo::ScopedDataPipeConsumerHandle"
  if mojom.IsDataPipeProducerKind(kind):
    return "mojo::ScopedDataPipeProducerHandle"
  if mojom.IsMessagePipeKind(kind):
    return "mojo::ScopedMessagePipeHandle"
  if mojom.IsSharedBufferKind(kind):
    return "mojo::ScopedSharedBufferHandle"
  return _kind_to_cpp_type[kind]

def GetUnmappedTypeForSerializer(kind):
  return GetCppDataViewType(kind, qualified=True)

def TranslateConstants(token, kind):
  if isinstance(token, mojom.NamedValue):
    return GetNameForKind(token, flatten_nested_kind=True)

  if isinstance(token, mojom.BuiltinValue):
    if token.value == "double.INFINITY":
      return "std::numeric_limits<double>::infinity()"
    if token.value == "float.INFINITY":
      return "std::numeric_limits<float>::infinity()"
    if token.value == "double.NEGATIVE_INFINITY":
      return "-std::numeric_limits<double>::infinity()"
    if token.value == "float.NEGATIVE_INFINITY":
      return "-std::numeric_limits<float>::infinity()"
    if token.value == "double.NAN":
      return "std::numeric_limits<double>::quiet_NaN()"
    if token.value == "float.NAN":
      return "std::numeric_limits<float>::quiet_NaN()"

  if (kind is not None and mojom.IsFloatKind(kind)):
      return token if token.isdigit() else token + "f";

  # Per C++11, 2.14.2, the type of an integer literal is the first of the
  # corresponding list in Table 6 in which its value can be represented. In this
  # case, the list for decimal constants with no suffix is:
  #   int, long int, long long int
  # The standard considers a program ill-formed if it contains an integer
  # literal that cannot be represented by any of the allowed types.
  #
  # As it turns out, MSVC doesn't bother trying to fall back to long long int,
  # so the integral constant -2147483648 causes it grief: it decides to
  # represent 2147483648 as an unsigned integer, and then warns that the unary
  # minus operator doesn't make sense on unsigned types. Doh!
  if kind == mojom.INT32 and token == "-2147483648":
    return "(-%d - 1) /* %s */" % (
        2**31 - 1, "Workaround for MSVC bug; see https://crbug.com/445618")

  return "%s%s" % (token, _kind_to_cpp_literal_suffix.get(kind, ""))

def ExpressionToText(value, kind=None):
  return TranslateConstants(value, kind)

def RequiresContextForDataView(kind):
  for field in kind.fields:
    if mojom.IsReferenceKind(field.kind):
      return True
  return False

def ShouldInlineStruct(struct):
  # TODO(darin): Base this on the size of the wrapper class.
  if len(struct.fields) > 4:
    return False
  for field in struct.fields:
    if mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind):
      return False
  return True

def ContainsMoveOnlyMembers(struct):
  for field in struct.fields:
    if IsMoveOnlyKind(field.kind):
      return True
  return False

def ShouldInlineUnion(union):
  return not any(
      mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind)
           for field in union.fields)


class StructConstructor(object):
  """Represents a constructor for a generated struct.

  Fields:
    fields: {[Field]} All struct fields in order.
    params: {[Field]} The fields that are passed as params.
  """

  def __init__(self, fields, params):
    self._fields = fields
    self._params = set(params)

  @property
  def params(self):
    return [field for field in self._fields if field in self._params]

  @property
  def fields(self):
    for field in self._fields:
      yield (field, field in self._params)


def GetStructConstructors(struct):
  """Returns a list of constructors for a struct.

  Params:
    struct: {Struct} The struct to return constructors for.

  Returns:
    {[StructConstructor]} A list of StructConstructors that should be generated
    for |struct|.
  """
  if not mojom.IsStructKind(struct):
    raise TypeError
  # Types that are neither copyable nor movable can't be passed to a struct
  # constructor so only generate a default constructor.
  if any(IsTypemappedKind(field.kind) and _current_typemap[
      GetFullMojomNameForKind(field.kind)]["non_copyable_non_movable"]
         for field in struct.fields):
    return [StructConstructor(struct.fields, [])]

  param_counts = [0]
  for version in struct.versions:
    if param_counts[-1] != version.num_fields:
      param_counts.append(version.num_fields)

  ordinal_fields = sorted(struct.fields, key=lambda field: field.ordinal)
  return (StructConstructor(struct.fields, ordinal_fields[:param_count])
          for param_count in param_counts)


def GetContainerValidateParamsCtorArgs(kind):
  if mojom.IsStringKind(kind):
    expected_num_elements = 0
    element_is_nullable = False
    key_validate_params = "nullptr"
    element_validate_params = "nullptr"
    enum_validate_func = "nullptr"
  elif mojom.IsMapKind(kind):
    expected_num_elements = 0
    element_is_nullable = False
    key_validate_params = GetNewContainerValidateParams(mojom.Array(
        kind=kind.key_kind))
    element_validate_params = GetNewContainerValidateParams(mojom.Array(
        kind=kind.value_kind))
    enum_validate_func = "nullptr"
  else:  # mojom.IsArrayKind(kind)
    expected_num_elements = generator.ExpectedArraySize(kind) or 0
    element_is_nullable = mojom.IsNullableKind(kind.kind)
    key_validate_params = "nullptr"
    element_validate_params = GetNewContainerValidateParams(kind.kind)
    if mojom.IsEnumKind(kind.kind):
      enum_validate_func = ("%s::Validate" %
                            GetQualifiedNameForKind(kind.kind, internal=True,
                                                    flatten_nested_kind=True))
    else:
      enum_validate_func = "nullptr"

  if enum_validate_func == "nullptr":
    if key_validate_params == "nullptr":
      return "%d, %s, %s" % (expected_num_elements,
                             "true" if element_is_nullable else "false",
                             element_validate_params)
    else:
      return "%s, %s" % (key_validate_params, element_validate_params)
  else:
    return "%d, %s" % (expected_num_elements, enum_validate_func)

def GetNewContainerValidateParams(kind):
  if (not mojom.IsArrayKind(kind) and not mojom.IsMapKind(kind) and
      not mojom.IsStringKind(kind)):
    return "nullptr"

  return "new mojo::internal::ContainerValidateParams(%s)" % (
      GetContainerValidateParamsCtorArgs(kind))

class Generator(generator.Generator):

  cpp_filters = {
    "all_enum_values": AllEnumValues,
    "constant_value": ConstantValue,
    "contains_handles_or_interfaces": mojom.ContainsHandlesOrInterfaces,
    "contains_move_only_members": ContainsMoveOnlyMembers,
    "cpp_wrapper_param_type": GetCppWrapperParamType,
    "cpp_data_view_type": GetCppDataViewType,
    "cpp_field_type": GetCppFieldType,
    "cpp_union_field_type": GetCppUnionFieldType,
    "cpp_pod_type": GetCppPodType,
    "cpp_union_getter_return_type": GetUnionGetterReturnType,
    "cpp_union_trait_getter_return_type": GetUnionTraitGetterReturnType,
    "cpp_wrapper_type": GetCppWrapperType,
    "default_value": DefaultValue,
    "expression_to_text": ExpressionToText,
    "format_constant_declaration": FormatConstantDeclaration,
    "get_container_validate_params_ctor_args":
        GetContainerValidateParamsCtorArgs,
    "get_name_for_kind": GetNameForKind,
    "get_pad": pack.GetPad,
    "get_qualified_name_for_kind": GetQualifiedNameForKind,
    "has_callbacks": mojom.HasCallbacks,
    "has_sync_methods": mojom.HasSyncMethods,
    "requires_context_for_data_view": RequiresContextForDataView,
    "should_inline": ShouldInlineStruct,
    "should_inline_union": ShouldInlineUnion,
    "is_array_kind": mojom.IsArrayKind,
    "is_enum_kind": mojom.IsEnumKind,
    "is_integral_kind": mojom.IsIntegralKind,
    "is_native_only_kind": IsNativeOnlyKind,
    "is_any_handle_kind": mojom.IsAnyHandleKind,
    "is_any_interface_kind": mojom.IsAnyInterfaceKind,
    "is_any_handle_or_interface_kind": mojom.IsAnyHandleOrInterfaceKind,
    "is_associated_kind": mojom.IsAssociatedKind,
    "is_hashable": IsHashableKind,
    "is_map_kind": mojom.IsMapKind,
    "is_nullable_kind": mojom.IsNullableKind,
    "is_object_kind": mojom.IsObjectKind,
    "is_reference_kind": mojom.IsReferenceKind,
    "is_string_kind": mojom.IsStringKind,
    "is_struct_kind": mojom.IsStructKind,
    "is_typemapped_kind": IsTypemappedKind,
    "is_union_kind": mojom.IsUnionKind,
    "passes_associated_kinds": mojom.PassesAssociatedKinds,
    "struct_constructors": GetStructConstructors,
    "stylize_method": generator.StudlyCapsToCamel,
    "under_to_camel": generator.UnderToCamel,
    "unmapped_type_for_serializer": GetUnmappedTypeForSerializer,
    "wtf_hash_fn_name_for_enum": GetWtfHashFnNameForEnum,
  }

  def GetExtraTraitsHeaders(self):
    extra_headers = set()
    for typemap in self._GetAllUsedTypemaps():
      extra_headers.update(typemap.get("traits_headers", []))
    return sorted(extra_headers)

  def _GetAllUsedTypemaps(self):
    """Returns the typemaps for types needed for serialization in this module.

    A type is needed for serialization if it is contained by a struct or union
    defined in this module, is a parameter of a message in an interface in
    this module or is contained within another type needed for serialization.
    """
    used_typemaps = []
    seen_types = set()
    def AddKind(kind):
      if (mojom.IsIntegralKind(kind) or mojom.IsStringKind(kind) or
          mojom.IsDoubleKind(kind) or mojom.IsFloatKind(kind) or
          mojom.IsAnyHandleKind(kind) or
          mojom.IsInterfaceKind(kind) or
          mojom.IsInterfaceRequestKind(kind) or
          mojom.IsAssociatedKind(kind)):
        pass
      elif mojom.IsArrayKind(kind):
        AddKind(kind.kind)
      elif mojom.IsMapKind(kind):
        AddKind(kind.key_kind)
        AddKind(kind.value_kind)
      else:
        name = GetFullMojomNameForKind(kind)
        if name in seen_types:
          return
        seen_types.add(name)

        typemap = _current_typemap.get(name, None)
        if typemap:
          used_typemaps.append(typemap)
        if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
          for field in kind.fields:
            AddKind(field.kind)

    for kind in self.module.structs + self.module.unions:
      for field in kind.fields:
        AddKind(field.kind)

    for interface in self.module.interfaces:
      for method in interface.methods:
        for parameter in method.parameters + (method.response_parameters or []):
          AddKind(parameter.kind)

    return used_typemaps

  def GetExtraPublicHeaders(self):
    all_enums = list(self.module.enums)
    for struct in self.module.structs:
      all_enums.extend(struct.enums)
    for interface in self.module.interfaces:
      all_enums.extend(interface.enums)

    types = set(GetFullMojomNameForKind(typename)
                for typename in
                self.module.structs + all_enums + self.module.unions)
    headers = set()
    for typename, typemap in self.typemap.iteritems():
      if typename in types:
        headers.update(typemap.get("public_headers", []))
    return sorted(headers)

  def _GetDirectlyUsedKinds(self):
    for struct in self.module.structs + self.module.unions:
      for field in struct.fields:
        yield field.kind

    for interface in self.module.interfaces:
      for method in interface.methods:
        for param in method.parameters + (method.response_parameters or []):
          yield param.kind

  def GetJinjaExports(self):
    structs = self.GetStructs()
    interfaces = self.GetInterfaces()
    all_enums = list(self.module.enums)
    for struct in structs:
      all_enums.extend(struct.enums)
    for interface in interfaces:
      all_enums.extend(interface.enums)

    return {
      "module": self.module,
      "namespace": self.module.namespace,
      "namespaces_as_array": NamespaceToArray(self.module.namespace),
      "imports": self.module.imports,
      "kinds": self.module.kinds,
      "enums": self.module.enums,
      "all_enums": all_enums,
      "structs": structs,
      "unions": self.GetUnions(),
      "interfaces": interfaces,
      "variant": self.variant,
      "extra_traits_headers": self.GetExtraTraitsHeaders(),
      "extra_public_headers": self.GetExtraPublicHeaders(),
      "for_blink": self.for_blink,
      "use_once_callback": self.use_once_callback,
      "export_attribute": self.export_attribute,
      "export_header": self.export_header,
    }

  @staticmethod
  def GetTemplatePrefix():
    return "cpp_templates"

  @classmethod
  def GetFilters(cls):
    return cls.cpp_filters

  @UseJinja("module.h.tmpl")
  def GenerateModuleHeader(self):
    return self.GetJinjaExports()

  @UseJinja("module.cc.tmpl")
  def GenerateModuleSource(self):
    return self.GetJinjaExports()

  @UseJinja("module-shared.h.tmpl")
  def GenerateModuleSharedHeader(self):
    return self.GetJinjaExports()

  @UseJinja("module-shared-internal.h.tmpl")
  def GenerateModuleSharedInternalHeader(self):
    return self.GetJinjaExports()

  @UseJinja("module-shared.cc.tmpl")
  def GenerateModuleSharedSource(self):
    return self.GetJinjaExports()

  def GenerateFiles(self, args):
    if self.generate_non_variant_code:
      self.Write(self.GenerateModuleSharedHeader(),
                 self.MatchMojomFilePath("%s-shared.h" % self.module.name))
      self.Write(
          self.GenerateModuleSharedInternalHeader(),
          self.MatchMojomFilePath("%s-shared-internal.h" % self.module.name))
      self.Write(self.GenerateModuleSharedSource(),
                 self.MatchMojomFilePath("%s-shared.cc" % self.module.name))
    else:
      global _current_typemap
      _current_typemap = self.typemap
      global _for_blink
      _for_blink = self.for_blink
      global _use_once_callback
      _use_once_callback = self.use_once_callback
      global _variant
      _variant = self.variant
      global _export_attribute
      _export_attribute = self.export_attribute
      suffix = "-%s" % self.variant if self.variant else ""
      self.Write(self.GenerateModuleHeader(),
                 self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix)))
      self.Write(
          self.GenerateModuleSource(),
          self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix)))
