@Value.Lazy
    Optional<DeclaringPackage> namedParentPackage() {
      String parentPackageName = SourceNames.parentPackageName(element());
      while (!parentPackageName.isEmpty()) {
        @Nullable PackageElement parentPackage =
            environment().processing()
                .getElementUtils()
                .getPackageElement(parentPackageName);

        if (parentPackage != null) {
          return Optional.of(interner().forPackage(
              ImmutableProto.DeclaringPackage.builder()
                  .environment(environment())
                  .interner(interner())
                  .element(parentPackage)
                  .build()));
        }

        // With JDK 9+ package elements are only returned for packages with a
        // `package-info.class` file. So although the parent may not be found,
        // there may be "ancestor packages" further up the hierarchy.
        parentPackageName = SourceNames.parentPackageName(parentPackageName);
      }
      return Optional.absent();
    }
Name is the only equivalence attribute. Basically packages are interned by name.
@return package name
value-processor/src/org/immutables/value/processor/meta/Proto.java