/**
   * Actual abstract value type that is definitive model for the value type.
   *
   * @return abstract value type name forms
   */
  @Value.Lazy
  public NameForms typeAbstract() {
    List<String> classSegments = Lists.newArrayListWithExpectedSize(2);
    Element e = SourceNames.collectClassSegments(protoclass().sourceElement(), classSegments);
    verify(e instanceof PackageElement);

    String packageOf = ((PackageElement) e).getQualifiedName().toString();
    String relative = DOT_JOINER.join(classSegments);
    boolean relativeAlreadyQualified = false;

    if (!implementationPackage().equals(packageOf)) {
      relative = DOT_JOINER.join(packageOf, relative);
      relativeAlreadyQualified = true;
    }

    return ImmutableConstitution.NameForms.builder()
        .simple(names().typeAbstract)
        .relativeRaw(relative)
        .packageOf(packageOf)
        .genericArgs(generics().args())
        .relativeAlreadyQualified(relativeAlreadyQualified)
        .visibility(protoclass().visibility())
        .build();
  }