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