1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867
|
# Copyright 2017 The Chromium Authors
# 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 an idl (mojom) Module."""
import os
# This is called from cronet_bindings_generator.py which does some magic to add
# libraries to the lookup path which pylint does not
# pylint: disable=import-error
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
# pylint: enable=import-error
# pylint: disable=useless-object-inheritance,super-with-arguments
_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",
}
ATTRIBUTE_ABSTRACT = "Abstract"
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,
internal=False,
include_variant=False,
omit_namespace_for_module=None,
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.
omit_namespace_for_module: If the token is from the specified module,
don't add the namespaces of the module to the name.
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(omit_namespace_for_module):
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,
omit_namespace_for_module=None,
internal=False,
flatten_nested_kind=False):
return self.Format("_",
omit_namespace_for_module=omit_namespace_for_module,
internal=internal,
include_variant=True,
flatten_nested_kind=flatten_nested_kind)
def FormatForMojom(self):
return self.Format(".")
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, _):
return self._token.module
# pylint: disable=inconsistent-return-statements
def _GetNamespace(self):
if self._token.module:
return NamespaceToArray(self._token.module.namespace)
# pylint: enable=inconsistent-return-statements
def NamespaceToArray(namespace):
return namespace.split(".") if namespace else []
def IsNativeOnlyKind(kind):
return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \
kind.native_only
def UseCustomSerializer(kind):
return mojom.IsStructKind(kind) and kind.custom_serializer
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 GetCppPodType(kind):
return _kind_to_cpp_type[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 ShouldInlineUnion(union):
return not any(
mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind)
for field in union.fields)
def IsAbstract(kind):
return kind.attributes.get(ATTRIBUTE_ABSTRACT, False) \
if kind.attributes else False
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)
class Generator(generator.Generator):
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 IsBasicKind(kind):
return (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))
def AddKind(kind):
if IsBasicKind(kind):
pass
elif mojom.IsArrayKind(kind):
AddKind(kind.kind)
elif mojom.IsMapKind(kind):
AddKind(kind.key_kind)
AddKind(kind.value_kind)
else:
name = self._GetFullMojomNameForKind(kind)
if name in seen_types:
return
seen_types.add(name)
typemap = self.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(
self._GetFullMojomNameForKind(typename)
for typename in self.module.structs + all_enums + self.module.unions)
headers = set()
for typename, typemap in self.typemap.items():
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):
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)
return {
"all_enums": all_enums,
"enums": self.module.enums,
"export_attribute": self.export_attribute,
"export_header": self.export_header,
"extra_public_headers": self._GetExtraPublicHeaders(),
"extra_traits_headers": self._GetExtraTraitsHeaders(),
"for_blink": self.for_blink,
"imports": self.module.imports,
"interfaces": self.module.interfaces,
"kinds": self.module.kinds,
"module": self.module,
"namespace": self.module.namespace,
"namespaces_as_array": NamespaceToArray(self.module.namespace),
"structs": self.module.structs,
"unions": self.module.unions,
"variant": self.variant,
}
@staticmethod
def GetTemplatePrefix():
return "c_templates"
def GetFilters(self):
cpp_filters = {
"all_enum_values": AllEnumValues,
"c_wrapper_type": self._GetCWrapperType,
"constant_value": self._ConstantValue,
"contains_handles_or_interfaces": mojom.ContainsHandlesOrInterfaces,
"contains_move_only_members": self._ContainsMoveOnlyMembers,
"cpp_wrapper_param_type": self._GetCppWrapperParamType,
"cpp_data_view_type": self._GetCppDataViewType,
"cpp_field_type": self._GetCppFieldType,
"cpp_union_field_type": self._GetCppUnionFieldType,
"cpp_pod_type": GetCppPodType,
"cpp_union_getter_return_type": self._GetUnionGetterReturnType,
"cpp_union_trait_getter_return_type":
self._GetUnionTraitGetterReturnType,
"cpp_wrapper_type": self._GetCppWrapperType,
"default_value": self._DefaultValue,
"expression_to_text": self._ExpressionToText,
"format_constant_declaration": self._FormatConstantDeclaration,
"get_container_validate_params_ctor_args":
self._GetContainerValidateParamsCtorArgs,
"get_name_for_kind": self._GetNameForKind,
"get_pad": pack.GetPad,
"get_qualified_name_for_kind": self._GetQualifiedNameForKind,
"has_callbacks": mojom.HasCallbacks,
"has_sync_methods": mojom.HasSyncMethods,
"requires_context_for_data_view": RequiresContextForDataView,
"should_inline": ShouldInlineStruct,
"should_inline_union": ShouldInlineUnion,
"is_abstract": IsAbstract,
"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": self._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": self._IsTypemappedKind,
"is_union_kind": mojom.IsUnionKind,
"passes_associated_kinds": mojom.PassesAssociatedKinds,
"struct_constructors": self._GetStructConstructors,
"under_to_camel": generator.ToCamel,
"unmapped_type_for_serializer": self._GetUnmappedTypeForSerializer,
}
return cpp_filters
@UseJinja("module_c.h.tmpl")
def _GenerateModuleHeader(self):
return self._GetJinjaExports()
@UseJinja("module_impl_interface.h.tmpl")
def _GenerateModuleInterfaceHeader(self):
return self._GetJinjaExports()
@UseJinja("module_impl_interface.cc.tmpl")
def _GenerateModuleInterfaceSource(self):
return self._GetJinjaExports()
@UseJinja("module_impl_interface_unittest.cc.tmpl")
def _GenerateModuleInterfaceUnittest(self):
return self._GetJinjaExports()
@UseJinja("module_impl_struct.h.tmpl")
def _GenerateModuleStructHeader(self):
return self._GetJinjaExports()
@UseJinja("module_impl_struct.cc.tmpl")
def _GenerateModuleStructSource(self):
return self._GetJinjaExports()
@UseJinja("module_impl_struct_unittest.cc.tmpl")
def _GenerateModuleStructUnittest(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, _):
self.module.Stylize(generator.Stylizer())
# TODO(mef): Remove this when generated files are not checked in.
path, module = os.path.split(self.module.path)
self.module.path = os.path.join(path, "generated", module)
if self.generate_non_variant_code:
self.Write(self._GenerateModuleSharedHeader(),
"%s-shared.h" % self.module.path)
self.Write(self._GenerateModuleSharedInternalHeader(),
"%s-shared-internal.h" % self.module.path)
self.Write(self._GenerateModuleSharedSource(),
"%s-shared.cc" % self.module.path)
else:
suffix = "-%s" % self.variant if self.variant else ""
self.Write(self._GenerateModuleHeader(),
"%s%s_c.h" % (self.module.path, suffix))
self.Write(self._GenerateModuleInterfaceHeader(),
"%s%s_impl_interface.h" % (self.module.path, suffix))
self.Write(self._GenerateModuleInterfaceSource(),
"%s%s_impl_interface.cc" % (self.module.path, suffix))
self.Write(self._GenerateModuleInterfaceUnittest(),
"%s%s_impl_interface_unittest.cc" % (self.module.path, suffix))
self.Write(self._GenerateModuleStructHeader(),
"%s%s_impl_struct.h" % (self.module.path, suffix))
self.Write(self._GenerateModuleStructSource(),
"%s%s_impl_struct.cc" % (self.module.path, suffix))
self.Write(self._GenerateModuleStructUnittest(),
"%s%s_impl_struct_unittest.cc" % (self.module.path, suffix))
def _ConstantValue(self, constant):
return self._ExpressionToText(constant.value, kind=constant.kind)
def _DefaultValue(self, field):
if not field.default:
return ""
if mojom.IsStructKind(field.kind):
assert field.default == "default"
if self._IsTypemappedKind(field.kind):
return ""
return "%s::New()" % self._GetNameForKind(field.kind)
expression = self._ExpressionToText(field.default, kind=field.kind)
if mojom.IsEnumKind(field.kind) and self._IsTypemappedKind(field.kind):
expression = "mojo::internal::ConvertEnumValue<%s, %s>(%s)" % (
self._GetNameForKind(field.kind), self._GetCppWrapperType(
field.kind), expression)
return expression
def _GetNameForKind(self,
kind,
internal=False,
flatten_nested_kind=False,
add_same_module_namespaces=False):
return _NameFormatter(kind, self.variant).FormatForCpp(
internal=internal,
flatten_nested_kind=flatten_nested_kind,
omit_namespace_for_module=(None if add_same_module_namespaces else
self.module))
def _GetQualifiedNameForKind(self,
kind,
internal=False,
flatten_nested_kind=False,
include_variant=True):
return _NameFormatter(
kind, self.variant if include_variant else None).FormatForCpp(
internal=internal, flatten_nested_kind=flatten_nested_kind)
def _GetFullMojomNameForKind(self, kind):
return _NameFormatter(kind, self.variant).FormatForMojom()
def _IsTypemappedKind(self, kind):
return hasattr(kind, "name") and \
self._GetFullMojomNameForKind(kind) in self.typemap
def _IsHashableKind(self, 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
if mojom.IsStructKind(kind):
if kind.native_only:
return False
if (self._IsTypemappedKind(kind) and
not self.typemap[self._GetFullMojomNameForKind(kind)]["hashable"]):
return False
return all(Check(field.kind) for field in kind.fields)
if mojom.IsEnumKind(kind):
return not self._IsTypemappedKind(kind) or self.typemap[
self._GetFullMojomNameForKind(kind)]["hashable"]
if mojom.IsUnionKind(kind):
return all(Check(field.kind) for field in kind.fields)
if mojom.IsAnyHandleKind(kind):
return False
if mojom.IsAnyInterfaceKind(kind):
return False
# TODO(crbug.com/41326458): Arrays and maps could be made hashable. We just
# don't have a use case yet.
if mojom.IsArrayKind(kind):
return False
if mojom.IsMapKind(kind):
return False
return True
return Check(kind)
def _GetNativeTypeName(self, typemapped_kind):
return self.typemap[self._GetFullMojomNameForKind(
typemapped_kind)]["typename"]
def _FormatConstantDeclaration(self, constant, nested=False):
if mojom.IsStringKind(constant.kind):
if nested:
return "const char %s[]" % constant.name
return "%sextern const char %s[]" % \
((self.export_attribute + " ") if self.export_attribute else "",
constant.name)
return "const %s %s_%s = %s" % (GetCppPodType(
constant.kind), self.module.namespace, constant.name,
self._ConstantValue(constant))
def _GetCppWrapperType(self, kind, add_same_module_namespaces=False):
def _AddOptional(type_name):
return "std::optional<%s>" % type_name
if self._IsTypemappedKind(kind):
type_name = self._GetNativeTypeName(kind)
if (mojom.IsNullableKind(kind) and not self.typemap[
self._GetFullMojomNameForKind(kind)]["nullable_is_same_type"]):
type_name = _AddOptional(type_name)
return type_name
if mojom.IsEnumKind(kind):
return self._GetNameForKind(
kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
return "%s" % self._GetNameForKind(
kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsArrayKind(kind):
pattern = "WTF::Vector<%s>" if self.for_blink else "std::vector<%s>"
if mojom.IsNullableKind(kind):
pattern = _AddOptional(pattern)
return pattern % self._GetCppWrapperType(
kind.kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsMapKind(kind):
pattern = ("WTF::HashMap<%s, %s>"
if self.for_blink else "std::unordered_map<%s, %s>")
if mojom.IsNullableKind(kind):
pattern = _AddOptional(pattern)
return pattern % (
self._GetCppWrapperType(
kind.key_kind,
add_same_module_namespaces=add_same_module_namespaces),
self._GetCppWrapperType(
kind.value_kind,
add_same_module_namespaces=add_same_module_namespaces))
if mojom.IsInterfaceKind(kind):
return "%sPtr" % self._GetNameForKind(
kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsInterfaceRequestKind(kind):
return "%sRequest" % self._GetNameForKind(
kind.kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsAssociatedInterfaceKind(kind):
return "%sAssociatedPtrInfo" % self._GetNameForKind(
kind.kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsAssociatedInterfaceRequestKind(kind):
return "%sAssociatedRequest" % self._GetNameForKind(
kind.kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsStringKind(kind):
if self.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 "Cronet_RawDataPtr"
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(self, kind):
if self._IsTypemappedKind(kind):
if mojom.IsEnumKind(kind):
return False
return self.typemap[self._GetFullMojomNameForKind(kind)]["move_only"]
if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
return True
if mojom.IsArrayKind(kind):
return self._IsMoveOnlyKind(kind.kind)
if mojom.IsMapKind(kind):
return (self._IsMoveOnlyKind(kind.value_kind)
or self._IsMoveOnlyKind(kind.key_kind))
if mojom.IsAnyHandleOrInterfaceKind(kind):
return True
return False
def _IsCopyablePassByValue(self, kind):
if not self._IsTypemappedKind(kind):
return False
return self.typemap[self._GetFullMojomNameForKind(
kind)]["copyable_pass_by_value"]
def _ShouldPassParamByValue(self, kind):
return ((not mojom.IsReferenceKind(kind)) or self._IsMoveOnlyKind(kind)
or self._IsCopyablePassByValue(kind))
def _GetCWrapperType(self, kind):
if mojom.IsStringKind(kind):
return "Cronet_String"
if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
return "%sPtr" % self._GetNameForKind(kind)
return self._GetCppWrapperType(kind)
def _GetCppWrapperParamType(self, kind):
cpp_wrapper_type = self._GetCppWrapperType(kind)
return (cpp_wrapper_type if self._ShouldPassParamByValue(kind) else
"const %s&" % cpp_wrapper_type)
def _GetCppFieldType(self, kind):
if mojom.IsStructKind(kind):
return ("mojo::internal::Pointer<%s>" %
self._GetNameForKind(kind, internal=True))
if mojom.IsUnionKind(kind):
return "%s" % self._GetNameForKind(kind, internal=True)
if mojom.IsArrayKind(kind):
return ("mojo::internal::Pointer<mojo::internal::Array_Data<%s>>" %
self._GetCppFieldType(kind.kind))
if mojom.IsMapKind(kind):
return ("mojo::internal::Pointer<mojo::internal::Map_Data<%s, %s>>" %
(self._GetCppFieldType(
kind.key_kind), self._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(self, kind):
if mojom.IsUnionKind(kind):
return ("mojo::internal::Pointer<%s>" %
self._GetNameForKind(kind, internal=True))
return self._GetCppFieldType(kind)
def _GetUnionGetterReturnType(self, kind):
if mojom.IsReferenceKind(kind):
return "%s&" % self._GetCppWrapperType(kind)
return self._GetCppWrapperType(kind)
def _GetUnionTraitGetterReturnType(self, 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&" % self._GetCppWrapperType(kind,
add_same_module_namespaces=True)
return self._GetCppWrapperType(kind, add_same_module_namespaces=True)
def _TranslateConstants(self, token, kind):
if isinstance(token, mojom.NamedValue):
return self._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"
return "%s%s" % (token, _kind_to_cpp_literal_suffix.get(kind, ""))
def _ExpressionToText(self, value, kind=None):
return self._TranslateConstants(value, kind)
def _ContainsMoveOnlyMembers(self, struct):
for field in struct.fields:
if self._IsMoveOnlyKind(field.kind):
return True
return False
def _GetStructConstructors(self, 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(
self._IsTypemappedKind(field.kind)
and self.typemap[self._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(self, 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 = self._GetNewContainerValidateParams(
mojom.Array(kind=kind.key_kind))
element_validate_params = self._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 = self._GetNewContainerValidateParams(kind.kind)
if mojom.IsEnumKind(kind.kind):
enum_validate_func = ("%s::Validate" % self._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)
return "%s, %s" % (key_validate_params, element_validate_params)
return "%d, %s" % (expected_num_elements, enum_validate_func)
def _GetNewContainerValidateParams(self, kind):
if (not mojom.IsArrayKind(kind) and not mojom.IsMapKind(kind)
and not mojom.IsStringKind(kind)):
return "nullptr"
return "new mojo::internal::ContainerValidateParams(%s)" % (
self._GetContainerValidateParamsCtorArgs(kind))
def _GetCppDataViewType(self, kind, qualified=False):
def _GetName(input_kind):
return _NameFormatter(input_kind, None).FormatForCpp(
omit_namespace_for_module=(None if qualified else self.module),
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>" % (self._GetCppDataViewType(
kind.kind, qualified))
if mojom.IsMapKind(kind):
return ("mojo::MapDataView<%s, %s>" %
(self._GetCppDataViewType(kind.key_kind, qualified),
self._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(self, kind):
return self._GetCppDataViewType(kind, qualified=True)
|