• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2024 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <algorithm>
6#include <limits>
7#include <string>
8
9#include "{{basename}}.h"
10#include "{{basename}}.pb.h"
11
12#include "base/strings/string_number_conversions.h"
13
14namespace {
15{% for func in functions %}
16std::string {{func['name']}}(domatolpm::Context* ctx, const {{proto_ns}}::{{func['proto_type']}});
17{% endfor %}
18{% for func in oneoffunctions %}
19std::string {{func['name']}}(domatolpm::Context* ctx, const {{proto_ns}}::{{func['proto_type']}});
20{% endfor %}
21{% for func in stfunctions %}
22std::string {{func['name']}}(domatolpm::Context* ctx, const {{proto_ns}}::{{func['proto_type']}});
23{% endfor %}
24
25template <typename From, typename To>
26[[maybe_unused]] std::string handle_int_conversion(domatolpm::Context* ctx [[maybe_unused]],
27                                                   const From& arg,
28                                                   const To& min = std::numeric_limits<To>::min(),
29                                                   const To& max = std::numeric_limits<To>::max()) {
30    To conv = arg;
31    return base::NumberToString(std::clamp(conv, min, max));
32}
33
34[[maybe_unused]] std::string handle_float(domatolpm::Context* ctx [[maybe_unused]], const float& arg) {
35    return base::NumberToString(arg);
36}
37
38[[maybe_unused]] std::string handle_double(domatolpm::Context* ctx [[maybe_unused]], const double& arg) {
39    return base::NumberToString(arg);
40}
41
42[[maybe_unused]] std::string handle_char(domatolpm::Context* ctx [[maybe_unused]], const int32_t& arg) {
43    char conv = arg;
44    return std::string(1, conv);
45}
46
47[[maybe_unused]] std::string handle_string(domatolpm::Context* ctx [[maybe_unused]], const std::string& arg) {
48    return arg;
49}
50
51[[maybe_unused]] std::string handle_hex(domatolpm::Context* ctx [[maybe_unused]], const int32_t& arg) {
52    return handle_int_conversion<int32_t, int32_t>(ctx, arg);
53}
54
55{% if generate_one_line_handler -%}
56std::string handle_one_line(domatolpm::Context* ctx, const {{proto_ns}}::line& arg) {
57    ctx->GetBuilder()->append("{{line_prefix}}");
58    ctx->GetBuilder()->append(handle_line(ctx, arg));
59    ctx->GetBuilder()->append("{{line_suffix}}\n");
60    return "";
61}
62{% endif -%}
63
64{% for func in functions %}
65{% if not func.creates_new() and func.exprs|length == 1 %}
66[[maybe_unused]] std::string {{func.name}}(domatolpm::Context* ctx, const {{proto_ns}}::{{func.proto_type}}) {
67    return {{func.exprs[0].repr()}};
68}
69{% else %}
70[[maybe_unused]] std::string {{func.name}}(domatolpm::Context* ctx, const {{proto_ns}}::{{func.proto_type}}) {
71    std::string buf;
72{% if func.creates_new() %}
73    std::string varname = std::string("{{func.creator['var_prefix']}}") + ctx->GetNewID();
74    buf += std::string("var ") + varname;
75    if (arg.has_old()) {
76      if (ctx->HasVar("{{func.creator['var_type']}}")) {
77        buf += " = ";
78        buf += ctx->GetVar("{{func.creator['var_type']}}", arg.old());
79        buf += ";";
80        ctx->GetBuilder()->append(buf);
81        return varname;
82      }
83    }
84{% endif %}
85{% for expr in func.exprs %}
86    buf += {{expr.repr()}};
87{% endfor %}
88{% if func.creates_new() %}
89    ctx->GetBuilder()->append(buf);
90    {% if func.creator['var_type'] == 'line' %}
91    return std::string();
92    {% else %}
93    ctx->SetVar("{{func.creator['var_type']}}", varname);
94    return varname;
95    {% endif %}
96{% else %}
97    return buf;
98{% endif %}
99}
100{% endif %}
101{% endfor %}
102
103{% for func in stfunctions %}
104[[maybe_unused]] std::string {{func.name}}(domatolpm::Context* ctx, const {{proto_ns}}::{{func.proto_type}}) {
105    static const char *possibilities[] = {
106        {% for string in func.strings %}
107        {{string.repr()}},
108        {% endfor %}
109    };
110    return possibilities[arg.{{func.var_name}}() % {{func.strings|length}}];
111}
112{% endfor %}
113
114{% for func in oneoffunctions %}
115[[maybe_unused]] std::string {{func.name}}(domatolpm::Context* ctx, const {{proto_ns}}::{{func.proto_type}}) {
116    {% for k, v in func.all_except_last().items() %}
117    if (arg.has_{{k}}()) {
118        {% if v|length == 1 %}
119        return {{v[0].repr()}};
120        {% else %}
121            {% for expr in v %}
122                {% if loop.index == 1 %}
123        std::string buf = {{expr.repr()}};
124                {% else %}
125        buf += {{expr.repr()}};
126                {% endif %}
127            {% endfor %}
128        return buf;
129        {% endif %}
130    }
131    {% endfor %}
132    else {
133        {% if func.last()|length == 1 %}
134        return {{func.last()[0].repr()}};
135        {% else %}
136            {% for expr in func.last() %}
137                {% if loop.index == 1 %}
138        std::string buf = {{expr.repr()}};
139                {% else %}
140        buf += {{expr.repr()}};
141                {% endif %}
142            {% endfor %}
143        return buf;
144        {% endif %}
145    }
146}
147{% endfor %}
148
149{% if generate_repeated_lines %}
150std::string handle_lines(domatolpm::Context* ctx, const {{proto_ns}}::lines& arg) {
151    for (const auto& line: arg.lines_v()) {
152        handle_one_line(ctx, line);
153    }
154    return "";
155}
156{% endif %}
157
158}
159
160namespace {{cpp_ns}} {
161
162bool {{root.name}}(domatolpm::Context* ctx, const {{proto_ns}}::{{root.proto_type}}) {
163    std::string buf;
164    buf.reserve(1024 * 128);
165{% for expr in root.exprs %}
166    buf += {{expr.repr()}};
167{% endfor %}
168    ctx->GetBuilder()->append(buf);
169    return true;
170}
171
172} // {{cpp_ns}}
173