chromium/third_party/blink/renderer/build/scripts/templates/make_qualified_names.cc.tmpl

{% from "templates/macros.tmpl" import license, source_files_for_generated_file %}
{{ license() }}

{{source_files_for_generated_file(template_file, input_files)}}

#include "{{this_include_path}}"

#include <memory>

#include <iterator>

#include "third_party/blink/renderer/platform/wtf/static_constructors.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hasher.h"

namespace blink {
namespace {{cpp_namespace}} {

DEFINE_GLOBAL(AtomicString, {{namespace_prefix}}NamespaceURI);

{% if tags %}
// Tags

void* tag_storage[kTagsCount * ((sizeof({{namespace}}QualifiedName) + sizeof(void *) - 1) / sizeof(void *))];
{% for tag in tags|sort(attribute='name', case_sensitive=True) %}
const {{namespace}}QualifiedName& {{tag|symbol}}Tag = reinterpret_cast<{{namespace}}QualifiedName*>(&tag_storage)[{{loop.index0}}];
{% endfor %}


std::unique_ptr<const {{namespace}}QualifiedName*[]> GetTags() {
  auto tags = std::make_unique<const {{namespace}}QualifiedName*[]>(kTagsCount);
  for (size_t i = 0; i < kTagsCount; ++i)
    tags[i] = reinterpret_cast<{{namespace}}QualifiedName*>(&tag_storage) + i;
  return tags;
}

{% endif %}
// Attributes

void* attr_storage[kAttrsCount * ((sizeof(QualifiedName) + sizeof(void *) - 1) / sizeof(void *))];

{% for attr in attrs|sort(attribute='name', case_sensitive=True) %}
const QualifiedName& {{attr|symbol}}Attr = reinterpret_cast<QualifiedName*>(&attr_storage)[{{loop.index0}}];
{% endfor %}

{% if namespace != 'HTML' %}
std::unique_ptr<const QualifiedName*[]> GetAttrs() {
  auto attrs = std::make_unique<const QualifiedName*[]>(kAttrsCount);
  for (size_t i = 0; i < kAttrsCount; ++i)
    attrs[i] = reinterpret_cast<QualifiedName*>(&attr_storage) + i;
  return attrs;
}
{% endif %}


void Init() {
  struct NameEntry {
    const char* name;
    unsigned char length;
    unsigned char is_tag;
    unsigned char is_attr;
  };

  // Namespace
  // Use placement new to initialize the globals.
  AtomicString ns_uri("{{namespace_uri}}");
  new ((void*)&{{namespace_prefix}}NamespaceURI) AtomicString(ns_uri);

  {% set tagnames = tags|map(attribute='name')|list() %}
  {% set attrnames = attrs|map(attribute='name')|list() %}
  static const NameEntry kNames[] = {
  {% for name, tag_list in (tags + attrs)|groupby('name')|sort(attribute=0, case_sensitive=True) %}
    { "{{name}}", {{name.original|length}}, {{ (name in tagnames)|int }}, {{ (name in attrnames)|int }} },
  {% endfor %}
  };

  {% if tags %}
  size_t tag_i = 0;
  {% endif %}
  size_t attr_i = 0;
  for (size_t i = 0; i < std::size(kNames); ++i) {
    StringImpl* impl = StringImpl::CreateStatic(kNames[i].name, kNames[i].length);
    {% if tags %}
    if (kNames[i].is_tag) {
      void* address = reinterpret_cast<{{namespace}}QualifiedName*>(&tag_storage) + tag_i;
      QualifiedName::CreateStatic(address, impl, ns_uri);
      ++tag_i;
    }

    if (!kNames[i].is_attr)
      continue;
    {% endif %}
    void* address = reinterpret_cast<QualifiedName*>(&attr_storage) + attr_i;
    {% if use_namespace_for_attrs %}
    QualifiedName::CreateStatic(address, impl, ns_uri);
    {% else %}
    QualifiedName::CreateStatic(address, impl);
    {% endif %}
    ++attr_i;
  }
  {% if tags %}
  DCHECK_EQ(tag_i, kTagsCount);
  {% endif %}
  DCHECK_EQ(attr_i, kAttrsCount);
}

{% if generate_tag_enum %}
const blink::{{namespace}}QualifiedName& TagToQualifiedName(
    {{namespace}}Tag tag) {
  switch (tag) {
{% for tag in tags|sort(attribute='name', case_sensitive=True) %}
    case {{namespace}}Tag::{{tag|tag_symbol}}:
      return {{tag|symbol}}Tag;
{% endfor %}
    case {{namespace}}Tag::kUnknown:
      return static_cast<const blink::{{namespace}}QualifiedName&>(g_null_name);
  }
}
{% endif %}

}  // namespace {{cpp_namespace}}
}  // namespace blink