@Override
  @SuppressWarnings("JdkObsolete") // MessageFormat requires StringBuffer in its api
  protected @NotNull Component renderTranslatable(final @NotNull TranslatableComponent component, final @NotNull C context) {
    final @Nullable MessageFormat format = this.translate(component.key(), component.fallback(), context);
    if (format == null) {
      // we don't have a translation for this component, but the arguments or children
      // of this component might need additional rendering

      final TranslatableComponent.Builder builder = Component.translatable()
        .key(component.key()).fallback(component.fallback());
      if (!component.arguments().isEmpty()) {
        final List<TranslationArgument> args = new ArrayList<>(component.arguments());
        for (int i = 0, size = args.size(); i < size; i++) {
          final TranslationArgument arg = args.get(i);
          if (arg.value() instanceof Component) {
            args.set(i, TranslationArgument.component(this.render(((Component) arg.value()), context)));
          }
        }
        builder.arguments(args);
      }
      return this.mergeStyleAndOptionallyDeepRender(component, builder, context);
    }

    final List<TranslationArgument> args = component.arguments();

    final TextComponent.Builder builder = Component.text();
    this.mergeStyle(component, builder, context);

    // no arguments makes this render very simple
    if (args.isEmpty()) {
      builder.content(format.format(null, new StringBuffer(), null).toString());
      return this.optionallyRenderChildrenAppendAndBuild(component.children(), builder, context);
    }

    final Object[] nulls = new Object[args.size()];
    final StringBuffer sb = format.format(nulls, new StringBuffer(), null);
    final AttributedCharacterIterator it = format.formatToCharacterIterator(nulls);

    while (it.getIndex() < it.getEndIndex()) {
      final int end = it.getRunLimit();
      final Integer index = (Integer) it.getAttribute(MessageFormat.Field.ARGUMENT);
      if (index != null) {
        final TranslationArgument arg = args.get(index);
        if (arg.value() instanceof Component) {
          builder.append(this.render(arg.asComponent(), context));
        } else {
          builder.append(arg.asComponent()); // todo: number rendering?
        }
      } else {
        builder.append(Component.text(sb.substring(it.getIndex(), end)));
      }
      it.setIndex(end);
    }

    return this.optionallyRenderChildrenAppendAndBuild(component.children(), builder, context);
  }
Gets a message format from a key, fallback string, and context.

@param key a translation key
@param fallback the fallback string
@param context a context
@return a message format or {@code null} to skip translation
api/src/main/java/net/kyori/adventure/text/renderer/TranslatableComponentRenderer.java