docs: def visit_ClassDef(self, node):  # pylint: disable=invalid-name
          """Visit top-level classes."""
          # Resolve everything as root scope contains everything from the process module.
          for base in node.bases:
              # Cover `from resolwe.process import ...`.
              if isinstance(base, ast.Name) and isinstance(base.ctx, ast.Load):
                  base = getattr(runtime, base.id, None)
              # Cover `from resolwe import process`.
              elif isinstance(base, ast.Attribute) and isinstance(base.ctx, ast.Load):
                  base = getattr(runtime, base.attr, None)
              else:
                  continue
  
              if issubclass(base, runtime.Process):
                  break
          else:
              return
  
          descriptor = ProcessDescriptor(source=self.source)
  
          # Available embedded classes.
          embedded_class_fields = {
              runtime.PROCESS_INPUTS_NAME: descriptor.inputs,
              runtime.PROCESS_OUTPUTS_NAME: descriptor.outputs,
          }
  
          # Parse metadata in class body.
          for item in node.body:
              if isinstance(item, ast.Assign):
                  # Possible metadata.
                  if (len(item.targets) == 1 and isinstance(item.targets[0], ast.Name)
                          and isinstance(item.targets[0].ctx, ast.Store)
                          and item.targets[0].id in PROCESS_METADATA):
                      # Try to get the metadata value.
                      value = PROCESS_METADATA[item.targets[0].id].get_value(item.value)
                      setattr(descriptor.metadata, item.targets[0].id, value)
              elif (isinstance(item, ast.Expr) and isinstance(item.value, ast.Str)
                    and descriptor.metadata.description is None):
                  # Possible description string.
                  descriptor.metadata.description = item.value.s
              elif isinstance(item, ast.ClassDef) and item.name in embedded_class_fields.keys():
                  # Possible input/output declaration.
                  self.visit_field_class(item, descriptor, embedded_class_fields[item.name])
  
          descriptor.validate()
          self.processes.append(descriptor)