static Tag resolve(final ArgumentQueue args, final Context ctx) throws ParsingException {
    final String type = args.popOr("a type of block, entity, or storage is required").lowerValue();
    final NBTComponentBuilder<?, ?> builder;
    if (BLOCK.equals(type)) {
      final String pos = args.popOr("A position is required").value();
      try {
        builder = Component.blockNBT()
          .pos(BlockNBTComponent.Pos.fromString(pos));
      } catch (final IllegalArgumentException ex) {
        throw ctx.newException(ex.getMessage(), args);
      }
    } else if (ENTITY.equals(type)) {
      builder = Component.entityNBT()
        .selector(args.popOr("A selector is required").value());
    } else if (STORAGE.equals(type)) {
      builder = Component.storageNBT()
        .storage(Key.key(args.popOr("A storage key is required").value()));
    } else {
      throw ctx.newException("Unknown nbt tag type '" + type + "'", args);
    }

    builder.nbtPath(args.popOr("An NBT path is required").value());

    if (args.hasNext()) {
      final String popped = args.pop().value();

      if (INTERPRET.equalsIgnoreCase(popped)) {
        builder.interpret(true);
      } else {
        builder.separator(ctx.deserialize(popped));

        if (args.hasNext() && args.pop().value().equalsIgnoreCase(INTERPRET)) {
          builder.interpret(true);
        }
      }
    }

    return Tag.inserting(builder.build());
  }
One tag for all NBT components.

@since 4.13.0
text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/NbtTag.java