function buildDictionary(slice, options, indent) {
  indent = indent || '  ';
  let to_ret = '@{\n';
  if (Object.hasOwn(slice, `${options.usesDtcg ? '$' : ''}value`)) {
    const token = /** @type {TransformedToken} */ (slice);
    let value = options.usesDtcg ? token.$value : token.value;
    const type = options.usesDtcg ? token.$type : token.type;
    if (type === 'dimension' || type === 'fontSize' || type === 'time') {
      value = '@' + value;
    }
    to_ret += indent + '@"value": ' + value + ',\n';
    to_ret += indent + '@"name": @"' + token.name + '",\n';

    for (const name in token.attributes) {
      if (token.attributes[name]) {
        to_ret += indent + '@"' + name + '": @"' + token.attributes[name] + '",\n';
      }
    }

    // remove last comma
    return to_ret.slice(0, -2) + '\n' + indent + '}';
  } else {
    for (const name in slice) {
      to_ret +=
        indent + '@"' + name + '": ' + buildDictionary(slice[name], options, indent + '  ') + ',\n';
    }
    // remove last comma
    return to_ret.slice(0, -2) + '\n' + indent + '}';
  }
}
@param {TransformedTokens} slice
@param {Config & LocalOptions} options
@param {string} [indent]