1 /*
   2  * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.module;
  27 
  28 import java.io.InputStream;
  29 import java.io.IOException;
  30 import java.io.PrintStream;
  31 import java.io.UncheckedIOException;
  32 import java.lang.reflect.AccessFlag;
  33 import java.nio.ByteBuffer;
  34 import java.nio.file.Path;
  35 import java.util.ArrayList;
  36 import java.util.Arrays;
  37 import java.util.Collection;
  38 import java.util.Collections;
  39 import java.util.EnumSet;
  40 import java.util.HashMap;
  41 import java.util.HashSet;
  42 import java.util.List;
  43 import java.util.Locale;
  44 import java.util.Map;
  45 import java.util.Objects;
  46 import java.util.Optional;
  47 import java.util.Set;
  48 import java.util.function.Supplier;
  49 import java.util.stream.Collectors;
  50 import java.util.stream.Stream;
  51 
  52 import static jdk.internal.module.Checks.*;
  53 import static java.util.Objects.*;
  54 
  55 import jdk.internal.module.Checks;
  56 import jdk.internal.module.ModuleInfo;
  57 
  58 
  59 /**
  60  * A module descriptor.
  61  *
  62  * <p> A module descriptor describes a named module and defines methods to
  63  * obtain each of its components. The module descriptor for a named module
  64  * in the Java virtual machine is obtained by invoking the {@link
  65  * java.lang.Module Module}'s {@link java.lang.Module#getDescriptor
  66  * getDescriptor} method. Module descriptors can also be created using the
  67  * {@link ModuleDescriptor.Builder} class or by reading the binary form of a
  68  * module declaration ({@code module-info.class}) using the {@link
  69  * #read(InputStream,Supplier) read} methods defined here. </p>
  70  *
  71  * <p> A module descriptor describes a <em>normal</em>, open, or automatic
  72  * module. <em>Normal</em> modules and open modules describe their {@linkplain
  73  * #requires() dependences}, {@link #exports() exported-packages}, the services
  74  * that they {@linkplain #uses() use} or {@linkplain #provides() provide}, and other
  75  * components. <em>Normal</em> modules may {@linkplain #opens() open} specific
  76  * packages. The module descriptor for an open module does not declare any
  77  * open packages (its {@code opens} method returns an empty set) but when
  78  * instantiated in the Java virtual machine then it is treated as if all
  79  * packages are open. The module descriptor for an automatic module does not
  80  * declare any dependences (except for the mandatory dependency on {@code
  81  * java.base}), and does not declare any exported or open packages. Automatic
  82  * modules receive special treatment during resolution so that they read all
  83  * other modules in the configuration. When an automatic module is instantiated
  84  * in the Java virtual machine then it reads every unnamed module and is
  85  * treated as if all packages are exported and open. </p>
  86  *
  87  * <p> {@code ModuleDescriptor} objects are immutable and safe for use by
  88  * multiple concurrent threads.</p>
  89  *
  90  * @see java.lang.Module
  91  * @since 9
  92  */
  93 
  94 public class ModuleDescriptor
  95     implements Comparable<ModuleDescriptor>
  96 {
  97 
  98     /**
  99      * A modifier on a module.
 100      *
 101      * @see ModuleDescriptor#modifiers()
 102      * @since 9
 103      */
 104     public enum Modifier {
 105         /**
 106          * An open module. An open module does not declare any open packages
 107          * but the resulting module is treated as if all packages are open.
 108          */
 109         OPEN(AccessFlag.OPEN.mask()),
 110 
 111         /**
 112          * An automatic module. An automatic module is treated as if it exports
 113          * and opens all packages.
 114          *
 115          * @apiNote This modifier does not correspond to a module flag in the
 116          * binary form of a module declaration ({@code module-info.class}).
 117          */
 118         AUTOMATIC(0 /* no flag per above comment */),
 119 
 120         /**
 121          * The module was not explicitly or implicitly declared.
 122          */
 123         SYNTHETIC(AccessFlag.SYNTHETIC.mask()),
 124 
 125         /**
 126          * The module was implicitly declared.
 127          */
 128         MANDATED(AccessFlag.MANDATED.mask());
 129 
 130         private final int mask;
 131         private Modifier(int mask) {
 132             this.mask = mask;
 133         }
 134         private int mask() {return mask;}
 135     }
 136 
 137     /**
 138      * <p> A dependence upon a module. </p>
 139      *
 140      * @see ModuleDescriptor#requires()
 141      * @since 9
 142      */
 143 
 144     public static final class Requires
 145         implements Comparable<Requires>
 146     {
 147 
 148         /**
 149          * A modifier on a module dependence.
 150          *
 151          * @see Requires#modifiers()
 152          * @since 9
 153          */
 154         public enum Modifier {
 155 
 156             /**
 157              * The dependence causes any module which depends on the <i>current
 158              * module</i> to have an implicitly declared dependence on the module
 159              * named by the {@code Requires}.
 160              */
 161             TRANSITIVE(AccessFlag.TRANSITIVE.mask()),
 162 
 163             /**
 164              * The dependence is mandatory in the static phase, during compilation,
 165              * but is optional in the dynamic phase, during execution.
 166              */
 167             STATIC(AccessFlag.STATIC_PHASE.mask()),
 168 
 169             /**
 170              * The dependence was not explicitly or implicitly declared in the
 171              * source of the module declaration.
 172              */
 173             SYNTHETIC(AccessFlag.SYNTHETIC.mask()),
 174 
 175             /**
 176              * The dependence was implicitly declared in the source of the module
 177              * declaration.
 178              */
 179             MANDATED(AccessFlag.MANDATED.mask());
 180             private final int mask;
 181             private Modifier(int mask) {
 182                 this.mask = mask;
 183             }
 184             private int mask() {return mask;}
 185         }
 186         private final Set<Modifier> mods;
 187         private final String name;
 188         private final Version compiledVersion;
 189         private final String rawCompiledVersion;
 190 
 191         private Requires(Set<Modifier> ms, String mn, Version v, String vs) {
 192             assert v == null || vs == null;
 193             this.mods = Set.copyOf(ms);
 194             this.name = mn;
 195             this.compiledVersion = v;
 196             this.rawCompiledVersion = vs;
 197         }
 198 
 199         private Requires(Set<Modifier> ms, String mn, Version v, boolean unused) {
 200             this.mods = ms;
 201             this.name = mn;
 202             this.compiledVersion = v;
 203             this.rawCompiledVersion = null;
 204         }
 205 
 206         /**
 207          * Returns the set of modifiers.
 208          *
 209          * @return A possibly-empty unmodifiable set of modifiers
 210          */
 211         public Set<Modifier> modifiers() {
 212             return mods;
 213         }
 214 
 215         /**
 216          * Returns the set of the module {@linkplain AccessFlag
 217          * requires flags}.
 218          *
 219          * @return A possibly-empty unmodifiable set of requires flags
 220          * @see #modifiers()
 221          * @jvms 4.7.25 The Module Attribute
 222          * @since 20
 223          */
 224         public Set<AccessFlag> accessFlags() {
 225             int mask = 0;
 226             for (var modifier : mods) {
 227                 mask |= modifier.mask();
 228             }
 229             return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE_REQUIRES);
 230         }
 231 
 232         /**
 233          * Return the module name.
 234          *
 235          * @return The module name
 236          */
 237         public String name() {
 238             return name;
 239         }
 240 
 241         /**
 242          * Returns the version of the module if recorded at compile-time.
 243          *
 244          * @return The version of the module if recorded at compile-time,
 245          *         or an empty {@code Optional} if no version was recorded or
 246          *         the version string recorded is {@linkplain Version#parse(String)
 247          *         unparseable}
 248          */
 249         public Optional<Version> compiledVersion() {
 250             return Optional.ofNullable(compiledVersion);
 251         }
 252 
 253         /**
 254          * Returns the string with the possibly-unparseable version of the module
 255          * if recorded at compile-time.
 256          *
 257          * @return The string containing the version of the module if recorded
 258          *         at compile-time, or an empty {@code Optional} if no version
 259          *         was recorded
 260          *
 261          * @see #compiledVersion()
 262          */
 263         public Optional<String> rawCompiledVersion() {
 264             if (compiledVersion != null) {
 265                 return Optional.of(compiledVersion.toString());
 266             } else {
 267                 return Optional.ofNullable(rawCompiledVersion);
 268             }
 269         }
 270 
 271         /**
 272          * Compares this module dependence to another.
 273          *
 274          * <p> Two {@code Requires} objects are compared by comparing their
 275          * module names lexicographically. Where the module names are equal
 276          * then the sets of modifiers are compared in the same way that
 277          * module modifiers are compared (see {@link ModuleDescriptor#compareTo
 278          * ModuleDescriptor.compareTo}). Where the module names are equal and
 279          * the set of modifiers are equal then the version of the modules
 280          * recorded at compile-time are compared. When comparing the versions
 281          * recorded at compile-time then a dependence that has a recorded
 282          * version is considered to succeed a dependence that does not have a
 283          * recorded version. If both recorded versions are {@linkplain
 284          * Version#parse(String) unparseable} then the {@linkplain
 285          * #rawCompiledVersion() raw version strings} are compared
 286          * lexicographically. </p>
 287          *
 288          * @param  that
 289          *         The module dependence to compare
 290          *
 291          * @return A negative integer, zero, or a positive integer if this module
 292          *         dependence is less than, equal to, or greater than the given
 293          *         module dependence
 294          */
 295         @Override
 296         public int compareTo(Requires that) {
 297             if (this == that) return 0;
 298 
 299             int c = this.name().compareTo(that.name());
 300             if (c != 0) return c;
 301 
 302             // modifiers
 303             long v1 = modsValue(this.modifiers());
 304             long v2 = modsValue(that.modifiers());
 305             c = Long.compare(v1, v2);
 306             if (c != 0) return c;
 307 
 308             // compiledVersion
 309             c = compare(this.compiledVersion, that.compiledVersion);
 310             if (c != 0) return c;
 311 
 312             // rawCompiledVersion
 313             c = compare(this.rawCompiledVersion, that.rawCompiledVersion);
 314             if (c != 0) return c;
 315 
 316             return 0;
 317         }
 318 
 319         /**
 320          * Tests this module dependence for equality with the given object.
 321          *
 322          * <p> If the given object is not a {@code Requires} then this method
 323          * returns {@code false}. Two module dependence objects are equal if
 324          * the module names are equal, set of modifiers are equal, and the
 325          * compiled version of both modules is equal or not recorded for
 326          * both modules. </p>
 327          *
 328          * <p> This method satisfies the general contract of the {@link
 329          * java.lang.Object#equals(Object) Object.equals} method. </p>
 330          *
 331          * @param   ob
 332          *          the object to which this object is to be compared
 333          *
 334          * @return  {@code true} if, and only if, the given object is a module
 335          *          dependence that is equal to this module dependence
 336          */
 337         @Override
 338         public boolean equals(Object ob) {
 339             return (ob instanceof Requires that)
 340                     && name.equals(that.name) && mods.equals(that.mods)
 341                     && Objects.equals(compiledVersion, that.compiledVersion)
 342                     && Objects.equals(rawCompiledVersion, that.rawCompiledVersion);
 343         }
 344 
 345         /**
 346          * Computes a hash code for this module dependence.
 347          *
 348          * <p> The hash code is based upon the module name, modifiers, and the
 349          * module version if recorded at compile time. It satisfies the general
 350          * contract of the {@link Object#hashCode Object.hashCode} method. </p>
 351          *
 352          * @return The hash-code value for this module dependence
 353          */
 354         @Override
 355         public int hashCode() {
 356             int hash = name.hashCode() * 43 + modsHashCode(mods);
 357             if (compiledVersion != null)
 358                 hash = hash * 43 + compiledVersion.hashCode();
 359             if (rawCompiledVersion != null)
 360                 hash = hash * 43 + rawCompiledVersion.hashCode();
 361             return hash;
 362         }
 363 
 364         /**
 365          * Returns a string describing this module dependence.
 366          *
 367          * @return A string describing this module dependence
 368          */
 369         @Override
 370         public String toString() {
 371             String what;
 372             if (compiledVersion != null) {
 373                 what = name() + " (@" + compiledVersion + ")";
 374             } else {
 375                 what = name();
 376             }
 377             return ModuleDescriptor.toString(mods, what);
 378         }
 379     }
 380 
 381 
 382     /**
 383      * <p> A package exported by a module, may be qualified or unqualified. </p>
 384      *
 385      * @see ModuleDescriptor#exports()
 386      * @since 9
 387      */
 388 
 389     public static final class Exports
 390         implements Comparable<Exports>
 391     {
 392 
 393         /**
 394          * A modifier on an exported package.
 395          *
 396          * @see Exports#modifiers()
 397          * @since 9
 398          */
 399         public enum Modifier {
 400 
 401             /**
 402              * The export was not explicitly or implicitly declared in the
 403              * source of the module declaration.
 404              */
 405             SYNTHETIC(AccessFlag.SYNTHETIC.mask()),
 406 
 407             /**
 408              * The export was implicitly declared in the source of the module
 409              * declaration.
 410              */
 411             MANDATED(AccessFlag.MANDATED.mask());
 412 
 413             private final int mask;
 414             private Modifier(int mask) {
 415                 this.mask = mask;
 416             }
 417             private int mask() {return mask;}
 418         }
 419 
 420         private final Set<Modifier> mods;
 421         private final String source;
 422         private final Set<String> targets;  // empty if unqualified export
 423 
 424         /**
 425          * Constructs an export
 426          */
 427         private Exports(Set<Modifier> ms, String source, Set<String> targets) {
 428             this.mods = Set.copyOf(ms);
 429             this.source = source;
 430             this.targets = Set.copyOf(targets);
 431         }
 432 
 433         private Exports(Set<Modifier> ms,
 434                         String source,
 435                         Set<String> targets,
 436                         boolean unused) {
 437             this.mods = ms;
 438             this.source = source;
 439             this.targets = targets;
 440         }
 441 
 442         /**
 443          * Returns the set of modifiers.
 444          *
 445          * @return A possibly-empty unmodifiable set of modifiers
 446          */
 447         public Set<Modifier> modifiers() {
 448             return mods;
 449         }
 450 
 451         /**
 452          * Returns the set of the module {@linkplain AccessFlag
 453          * export flags} for this module descriptor.
 454          *
 455          * @return A possibly-empty unmodifiable set of export flags
 456          * @see #modifiers()
 457          * @jvms 4.7.25 The Module Attribute
 458          * @since 20
 459          */
 460         public Set<AccessFlag> accessFlags() {
 461             int mask = 0;
 462             for (var modifier : mods) {
 463                 mask |= modifier.mask();
 464             }
 465             return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE_EXPORTS);
 466         }
 467 
 468         /**
 469          * Returns {@code true} if this is a qualified export.
 470          *
 471          * @return {@code true} if this is a qualified export
 472          */
 473         public boolean isQualified() {
 474             return !targets.isEmpty();
 475         }
 476 
 477         /**
 478          * Returns the package name.
 479          *
 480          * @return The package name
 481          */
 482         public String source() {
 483             return source;
 484         }
 485 
 486         /**
 487          * For a qualified export, returns the non-empty and immutable set
 488          * of the module names to which the package is exported. For an
 489          * unqualified export, returns an empty set.
 490          *
 491          * @return The set of target module names or for an unqualified
 492          *         export, an empty set
 493          */
 494         public Set<String> targets() {
 495             return targets;
 496         }
 497 
 498         /**
 499          * Compares this module export to another.
 500          *
 501          * <p> Two {@code Exports} objects are compared by comparing the package
 502          * names lexicographically. Where the packages names are equal then the
 503          * sets of modifiers are compared in the same way that module modifiers
 504          * are compared (see {@link ModuleDescriptor#compareTo
 505          * ModuleDescriptor.compareTo}). Where the package names are equal and
 506          * the set of modifiers are equal then the set of target modules are
 507          * compared. This is done by sorting the names of the target modules
 508          * in ascending order, and according to their natural ordering, and then
 509          * comparing the corresponding elements lexicographically. Where the
 510          * sets differ in size, and the larger set contains all elements of the
 511          * smaller set, then the larger set is considered to succeed the smaller
 512          * set. </p>
 513          *
 514          * @param  that
 515          *         The module export to compare
 516          *
 517          * @return A negative integer, zero, or a positive integer if this module
 518          *         export is less than, equal to, or greater than the given
 519          *         export dependence
 520          */
 521         @Override
 522         public int compareTo(Exports that) {
 523             if (this == that) return 0;
 524 
 525             int c = source.compareTo(that.source);
 526             if (c != 0)
 527                 return c;
 528 
 529             // modifiers
 530             long v1 = modsValue(this.modifiers());
 531             long v2 = modsValue(that.modifiers());
 532             c = Long.compare(v1, v2);
 533             if (c != 0)
 534                 return c;
 535 
 536             // targets
 537             c = compare(targets, that.targets);
 538             if (c != 0)
 539                 return c;
 540 
 541             return 0;
 542         }
 543 
 544         /**
 545          * Computes a hash code for this module export.
 546          *
 547          * <p> The hash code is based upon the modifiers, the package name,
 548          * and for a qualified export, the set of modules names to which the
 549          * package is exported. It satisfies the general contract of the
 550          * {@link Object#hashCode Object.hashCode} method.
 551          *
 552          * @return The hash-code value for this module export
 553          */
 554         @Override
 555         public int hashCode() {
 556             int hash = modsHashCode(mods);
 557             hash = hash * 43 + source.hashCode();
 558             return hash * 43 + targets.hashCode();
 559         }
 560 
 561         /**
 562          * Tests this module export for equality with the given object.
 563          *
 564          * <p> If the given object is not an {@code Exports} then this method
 565          * returns {@code false}. Two module exports objects are equal if their
 566          * set of modifiers is equal, the package names are equal and the set
 567          * of target module names is equal. </p>
 568          *
 569          * <p> This method satisfies the general contract of the {@link
 570          * java.lang.Object#equals(Object) Object.equals} method. </p>
 571          *
 572          * @param   ob
 573          *          the object to which this object is to be compared
 574          *
 575          * @return  {@code true} if, and only if, the given object is a module
 576          *          dependence that is equal to this module dependence
 577          */
 578         @Override
 579         public boolean equals(Object ob) {
 580             return (ob instanceof Exports other)
 581                     && Objects.equals(this.mods, other.mods)
 582                     && Objects.equals(this.source, other.source)
 583                     && Objects.equals(this.targets, other.targets);
 584         }
 585 
 586         /**
 587          * Returns a string describing the exported package.
 588          *
 589          * @return A string describing the exported package
 590          */
 591         @Override
 592         public String toString() {
 593             String s = ModuleDescriptor.toString(mods, source);
 594             if (targets.isEmpty())
 595                 return s;
 596             else
 597                 return s + " to " + targets;
 598         }
 599     }
 600 
 601 
 602     /**
 603      * <p> A package opened by a module, may be qualified or unqualified. </p>
 604      *
 605      * <p> The <em>opens</em> directive in a module declaration declares a
 606      * package to be open to allow all types in the package, and all their
 607      * members, not just public types and their public members to be reflected
 608      * on by APIs that support private access or a way to bypass or suppress
 609      * default Java language access control checks. </p>
 610      *
 611      * @see ModuleDescriptor#opens()
 612      * @since 9
 613      */
 614 
 615     public static final class Opens
 616         implements Comparable<Opens>
 617     {
 618         /**
 619          * A modifier on an open package.
 620          *
 621          * @see Opens#modifiers()
 622          * @since 9
 623          */
 624         public enum Modifier {
 625 
 626             /**
 627              * The open package was not explicitly or implicitly declared in
 628              * the source of the module declaration.
 629              */
 630             SYNTHETIC(AccessFlag.SYNTHETIC.mask()),
 631 
 632             /**
 633              * The open package was implicitly declared in the source of the
 634              * module declaration.
 635              */
 636             MANDATED(AccessFlag.MANDATED.mask());
 637             private final int mask;
 638             private Modifier(int mask) {
 639                 this.mask = mask;
 640             }
 641             private int mask() {return mask;}
 642         }
 643 
 644         private final Set<Modifier> mods;
 645         private final String source;
 646         private final Set<String> targets;  // empty if unqualified export
 647 
 648         /**
 649          * Constructs an {@code Opens}.
 650          */
 651         private Opens(Set<Modifier> ms, String source, Set<String> targets) {
 652             this.mods = Set.copyOf(ms);
 653             this.source = source;
 654             this.targets = Set.copyOf(targets);
 655         }
 656 
 657         private Opens(Set<Modifier> ms,
 658                       String source,
 659                       Set<String> targets,
 660                       boolean unused) {
 661             this.mods = ms;
 662             this.source = source;
 663             this.targets = targets;
 664         }
 665 
 666         /**
 667          * Returns the set of modifiers.
 668          *
 669          * @return A possibly-empty unmodifiable set of modifiers
 670          */
 671         public Set<Modifier> modifiers() {
 672             return mods;
 673         }
 674 
 675         /**
 676          * Returns the set of the module {@linkplain AccessFlag opens
 677          * flags}.
 678          *
 679          * @return A possibly-empty unmodifiable set of opens flags
 680          * @see #modifiers()
 681          * @jvms 4.7.25 The Module Attribute
 682          * @since 20
 683          */
 684         public Set<AccessFlag> accessFlags() {
 685             int mask = 0;
 686             for (var modifier : mods) {
 687                 mask |= modifier.mask();
 688             }
 689             return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE_OPENS);
 690         }
 691 
 692         /**
 693          * Returns {@code true} if this is a qualified {@code Opens}.
 694          *
 695          * @return {@code true} if this is a qualified {@code Opens}
 696          */
 697         public boolean isQualified() {
 698             return !targets.isEmpty();
 699         }
 700 
 701         /**
 702          * Returns the package name.
 703          *
 704          * @return The package name
 705          */
 706         public String source() {
 707             return source;
 708         }
 709 
 710         /**
 711          * For a qualified {@code Opens}, returns the non-empty and immutable set
 712          * of the module names to which the package is open. For an
 713          * unqualified {@code Opens}, returns an empty set.
 714          *
 715          * @return The set of target module names or for an unqualified
 716          *         {@code Opens}, an empty set
 717          */
 718         public Set<String> targets() {
 719             return targets;
 720         }
 721 
 722         /**
 723          * Compares this module {@code Opens} to another.
 724          *
 725          * <p> Two {@code Opens} objects are compared by comparing the package
 726          * names lexicographically. Where the packages names are equal then the
 727          * sets of modifiers are compared in the same way that module modifiers
 728          * are compared (see {@link ModuleDescriptor#compareTo
 729          * ModuleDescriptor.compareTo}). Where the package names are equal and
 730          * the set of modifiers are equal then the set of target modules are
 731          * compared. This is done by sorting the names of the target modules
 732          * in ascending order, and according to their natural ordering, and then
 733          * comparing the corresponding elements lexicographically. Where the
 734          * sets differ in size, and the larger set contains all elements of the
 735          * smaller set, then the larger set is considered to succeed the smaller
 736          * set. </p>
 737          *
 738          * @param  that
 739          *         The module {@code Opens} to compare
 740          *
 741          * @return A negative integer, zero, or a positive integer if this module
 742          *         {@code Opens} is less than, equal to, or greater than the given
 743          *         module {@code Opens}
 744          */
 745         @Override
 746         public int compareTo(Opens that) {
 747             if (this == that) return 0;
 748 
 749             int c = source.compareTo(that.source);
 750             if (c != 0)
 751                 return c;
 752 
 753             // modifiers
 754             long v1 = modsValue(this.modifiers());
 755             long v2 = modsValue(that.modifiers());
 756             c = Long.compare(v1, v2);
 757             if (c != 0)
 758                 return c;
 759 
 760             // targets
 761             c = compare(targets, that.targets);
 762             if (c != 0)
 763                 return c;
 764 
 765             return 0;
 766         }
 767 
 768         /**
 769          * Computes a hash code for this module {@code Opens}.
 770          *
 771          * <p> The hash code is based upon the modifiers, the package name,
 772          * and for a qualified {@code Opens}, the set of modules names to which the
 773          * package is opened. It satisfies the general contract of the
 774          * {@link Object#hashCode Object.hashCode} method.
 775          *
 776          * @return The hash-code value for this module {@code Opens}
 777          */
 778         @Override
 779         public int hashCode() {
 780             int hash = modsHashCode(mods);
 781             hash = hash * 43 + source.hashCode();
 782             return hash * 43 + targets.hashCode();
 783         }
 784 
 785         /**
 786          * Tests this module {@code Opens} for equality with the given object.
 787          *
 788          * <p> If the given object is not an {@code Opens} then this method
 789          * returns {@code false}. Two {@code Opens} objects are equal if their
 790          * set of modifiers is equal, the package names are equal and the set
 791          * of target module names is equal. </p>
 792          *
 793          * <p> This method satisfies the general contract of the {@link
 794          * java.lang.Object#equals(Object) Object.equals} method. </p>
 795          *
 796          * @param   ob
 797          *          the object to which this object is to be compared
 798          *
 799          * @return  {@code true} if, and only if, the given object is a module
 800          *          dependence that is equal to this module dependence
 801          */
 802         @Override
 803         public boolean equals(Object ob) {
 804            return (ob instanceof Opens other)
 805                    && Objects.equals(this.mods, other.mods)
 806                    && Objects.equals(this.source, other.source)
 807                    && Objects.equals(this.targets, other.targets);
 808         }
 809 
 810         /**
 811          * Returns a string describing the open package.
 812          *
 813          * @return A string describing the open package
 814          */
 815         @Override
 816         public String toString() {
 817             String s = ModuleDescriptor.toString(mods, source);
 818             if (targets.isEmpty())
 819                 return s;
 820             else
 821                 return s + " to " + targets;
 822         }
 823     }
 824 
 825 
 826     /**
 827      * <p> A service that a module provides one or more implementations of. </p>
 828      *
 829      * @see ModuleDescriptor#provides()
 830      * @since 9
 831      */
 832 
 833     public static final class Provides
 834         implements Comparable<Provides>
 835     {
 836         private final String service;
 837         private final List<String> providers;
 838 
 839         private Provides(String service, List<String> providers) {
 840             this.service = service;
 841             this.providers = List.copyOf(providers);
 842         }
 843 
 844         private Provides(String service, List<String> providers, boolean unused) {
 845             this.service = service;
 846             this.providers = providers;
 847         }
 848 
 849         /**
 850          * {@return the {@linkplain ClassLoader##binary-name binary name} of the service type}
 851          */
 852         public String service() { return service; }
 853 
 854         /**
 855          * Returns the list of the {@linkplain ClassLoader##binary-name binary names}
 856          * of the providers or provider factories.
 857          *
 858          * @return A non-empty and unmodifiable list of the {@linkplain ClassLoader##binary-name
 859          *         binary names} of the providers or provider factories
 860          */
 861         public List<String> providers() { return providers; }
 862 
 863         /**
 864          * Compares this {@code Provides} to another.
 865          *
 866          * <p> Two {@code Provides} objects are compared by comparing the
 867          * {@linkplain ClassLoader##binary-name binary name}
 868          * of the service type lexicographically. Where the
 869          * class names are equal then the list of the provider class names are
 870          * compared by comparing the corresponding elements of both lists
 871          * lexicographically and in sequence. Where the lists differ in size,
 872          * {@code N} is the size of the shorter list, and the first {@code N}
 873          * corresponding elements are equal, then the longer list is considered
 874          * to succeed the shorter list. </p>
 875          *
 876          * @param  that
 877          *         The {@code Provides} to compare
 878          *
 879          * @return A negative integer, zero, or a positive integer if this
 880          *         {@code Provides} is less than, equal to, or greater than
 881          *         the given {@code Provides}
 882          */
 883         public int compareTo(Provides that) {
 884             if (this == that) return 0;
 885 
 886             int c = service.compareTo(that.service);
 887             if (c != 0) return c;
 888 
 889             // compare provider class names in sequence
 890             int size1 = this.providers.size();
 891             int size2 = that.providers.size();
 892             for (int index=0; index<Math.min(size1, size2); index++) {
 893                 String e1 = this.providers.get(index);
 894                 String e2 = that.providers.get(index);
 895                 c = e1.compareTo(e2);
 896                 if (c != 0) return c;
 897             }
 898             if (size1 == size2) {
 899                 return 0;
 900             } else {
 901                 return (size1 > size2) ? 1 : -1;
 902             }
 903         }
 904 
 905         /**
 906          * Computes a hash code for this {@code Provides}.
 907          *
 908          * <p> The hash code is based upon the service type and the set of
 909          * providers. It satisfies the general contract of the {@link
 910          * Object#hashCode Object.hashCode} method. </p>
 911          *
 912          * @return The hash-code value for this module provides
 913          */
 914         @Override
 915         public int hashCode() {
 916             return service.hashCode() * 43 + providers.hashCode();
 917         }
 918 
 919         /**
 920          * Tests this {@code Provides} for equality with the given object.
 921          *
 922          * <p> If the given object is not a {@code Provides} then this method
 923          * returns {@code false}. Two {@code Provides} objects are equal if the
 924          * service type is equal and the list of providers is equal. </p>
 925          *
 926          * <p> This method satisfies the general contract of the {@link
 927          * java.lang.Object#equals(Object) Object.equals} method. </p>
 928          *
 929          * @param   ob
 930          *          the object to which this object is to be compared
 931          *
 932          * @return  {@code true} if, and only if, the given object is a
 933          *          {@code Provides} that is equal to this {@code Provides}
 934          */
 935         @Override
 936         public boolean equals(Object ob) {
 937             return (ob instanceof Provides other)
 938                     && Objects.equals(this.service, other.service)
 939                     && Objects.equals(this.providers, other.providers);
 940         }
 941 
 942         /**
 943          * Returns a string describing this {@code Provides}.
 944          *
 945          * @return A string describing this {@code Provides}
 946          */
 947         @Override
 948         public String toString() {
 949             return service + " with " + providers;
 950         }
 951 
 952     }
 953 
 954 
 955     /**
 956      * A module's version string.
 957      *
 958      * <p> A version string has three components: The version number itself, an
 959      * optional pre-release version, and an optional build version.  Each
 960      * component is a sequence of tokens; each token is either a non-negative
 961      * integer or a string.  Tokens are separated by the punctuation characters
 962      * {@code '.'}, {@code '-'}, or {@code '+'}, or by transitions from a
 963      * sequence of digits to a sequence of characters that are neither digits
 964      * nor punctuation characters, or vice versa.  Consecutive repeated
 965      * punctuation characters are treated as a single punctuation character.
 966      *
 967      * <ul>
 968      *
 969      *   <li> The <i>version number</i> is a sequence of tokens separated by
 970      *   {@code '.'} characters, terminated by the first {@code '-'} or {@code
 971      *   '+'} character. </li>
 972      *
 973      *   <li> The <i>pre-release version</i> is a sequence of tokens separated
 974      *   by {@code '.'} or {@code '-'} characters, terminated by the first
 975      *   {@code '+'} character. </li>
 976      *
 977      *   <li> The <i>build version</i> is a sequence of tokens separated by
 978      *   {@code '.'}, {@code '-'}, or {@code '+'} characters.
 979      *
 980      * </ul>
 981      *
 982      * <p> When comparing two version strings, the elements of their
 983      * corresponding components are compared in pointwise fashion.  If one
 984      * component is longer than the other, but otherwise equal to it, then the
 985      * first component is considered the greater of the two; otherwise, if two
 986      * corresponding elements are integers then they are compared as such;
 987      * otherwise, at least one of the elements is a string, so the other is
 988      * converted into a string if it is an integer and the two are compared
 989      * lexicographically.  Trailing integer elements with the value zero are
 990      * ignored.
 991      *
 992      * <p> Given two version strings, if their version numbers differ then the
 993      * result of comparing them is the result of comparing their version
 994      * numbers; otherwise, if one of them has a pre-release version but the
 995      * other does not then the first is considered to precede the second,
 996      * otherwise the result of comparing them is the result of comparing their
 997      * pre-release versions; otherwise, the result of comparing them is the
 998      * result of comparing their build versions.
 999      *
1000      * @see ModuleDescriptor#version()
1001      * @since 9
1002      */
1003 
1004     public static final class Version
1005         implements Comparable<Version>
1006     {
1007 
1008         private final String version;
1009 
1010         // If Java had disjunctive types then we'd write List<Integer|String> here
1011         //
1012         private final List<Object> sequence;
1013         private final List<Object> pre;
1014         private final List<Object> build;
1015 
1016         // Take a numeric token starting at position i
1017         // Append it to the given list
1018         // Return the index of the first character not taken
1019         // Requires: s.charAt(i) is (decimal) numeric
1020         //
1021         private static int takeNumber(String s, int i, List<Object> acc) {
1022             char c = s.charAt(i);
1023             int d = (c - '0');
1024             int n = s.length();
1025             while (++i < n) {
1026                 c = s.charAt(i);
1027                 if (c >= '0' && c <= '9') {
1028                     d = d * 10 + (c - '0');
1029                     continue;
1030                 }
1031                 break;
1032             }
1033             acc.add(d);
1034             return i;
1035         }
1036 
1037         // Take a string token starting at position i
1038         // Append it to the given list
1039         // Return the index of the first character not taken
1040         // Requires: s.charAt(i) is not '.'
1041         //
1042         private static int takeString(String s, int i, List<Object> acc) {
1043             int b = i;
1044             int n = s.length();
1045             while (++i < n) {
1046                 char c = s.charAt(i);
1047                 if (c != '.' && c != '-' && c != '+' && !(c >= '0' && c <= '9'))
1048                     continue;
1049                 break;
1050             }
1051             acc.add(s.substring(b, i));
1052             return i;
1053         }
1054 
1055         // Syntax: tok+ ( '-' tok+)? ( '+' tok+)?
1056         // First token string is sequence, second is pre, third is build
1057         // Tokens are separated by '.' or '-', or by changes between alpha & numeric
1058         // Numeric tokens are compared as decimal integers
1059         // Non-numeric tokens are compared lexicographically
1060         // A version with a non-empty pre is less than a version with same seq but no pre
1061         // Tokens in build may contain '-' and '+'
1062         //
1063         private Version(String v) {
1064 
1065             if (v == null)
1066                 throw new IllegalArgumentException("Null version string");
1067             int n = v.length();
1068             if (n == 0)
1069                 throw new IllegalArgumentException("Empty version string");
1070 
1071             int i = 0;
1072             char c = v.charAt(i);
1073             if (!(c >= '0' && c <= '9'))
1074                 throw new IllegalArgumentException(v
1075                                                    + ": Version string does not start"
1076                                                    + " with a number");
1077 
1078             List<Object> sequence = new ArrayList<>(4);
1079             List<Object> pre = new ArrayList<>(2);
1080             List<Object> build = new ArrayList<>(2);
1081 
1082             i = takeNumber(v, i, sequence);
1083 
1084             while (i < n) {
1085                 c = v.charAt(i);
1086                 if (c == '.') {
1087                     i++;
1088                     continue;
1089                 }
1090                 if (c == '-' || c == '+') {
1091                     i++;
1092                     break;
1093                 }
1094                 if (c >= '0' && c <= '9')
1095                     i = takeNumber(v, i, sequence);
1096                 else
1097                     i = takeString(v, i, sequence);
1098             }
1099 
1100             if (c == '-' && i >= n)
1101                 throw new IllegalArgumentException(v + ": Empty pre-release");
1102 
1103             while (i < n) {
1104                 c = v.charAt(i);
1105                 if (c == '.' || c == '-') {
1106                     i++;
1107                     continue;
1108                 }
1109                 if (c == '+') {
1110                     i++;
1111                     break;
1112                 }
1113                 if (c >= '0' && c <= '9')
1114                     i = takeNumber(v, i, pre);
1115                 else
1116                     i = takeString(v, i, pre);
1117             }
1118 
1119             if (c == '+' && i >= n)
1120                 throw new IllegalArgumentException(v + ": Empty pre-release");
1121 
1122             while (i < n) {
1123                 c = v.charAt(i);
1124                 if (c == '.' || c == '-' || c == '+') {
1125                     i++;
1126                     continue;
1127                 }
1128                 if (c >= '0' && c <= '9')
1129                     i = takeNumber(v, i, build);
1130                 else
1131                     i = takeString(v, i, build);
1132             }
1133 
1134             this.version = v;
1135             this.sequence = sequence;
1136             this.pre = pre;
1137             this.build = build;
1138         }
1139 
1140         /**
1141          * Parses the given string as a version string.
1142          *
1143          * @param  v
1144          *         The string to parse
1145          *
1146          * @return The resulting {@code Version}
1147          *
1148          * @throws IllegalArgumentException
1149          *         If {@code v} is {@code null}, an empty string, or cannot be
1150          *         parsed as a version string
1151          */
1152         public static Version parse(String v) {
1153             return new Version(v);
1154         }
1155 
1156         @SuppressWarnings("unchecked")
1157         private int cmp(Object o1, Object o2) {
1158             return ((Comparable)o1).compareTo(o2);
1159         }
1160 
1161         private int compareTokens(List<Object> ts1, List<Object> ts2) {
1162             int n = Math.min(ts1.size(), ts2.size());
1163             for (int i = 0; i < n; i++) {
1164                 Object o1 = ts1.get(i);
1165                 Object o2 = ts2.get(i);
1166                 if ((o1 instanceof Integer && o2 instanceof Integer)
1167                     || (o1 instanceof String && o2 instanceof String))
1168                 {
1169                     int c = cmp(o1, o2);
1170                     if (c == 0)
1171                         continue;
1172                     return c;
1173                 }
1174                 // Types differ, so convert number to string form
1175                 int c = o1.toString().compareTo(o2.toString());
1176                 if (c == 0)
1177                     continue;
1178                 return c;
1179             }
1180             List<Object> rest = ts1.size() > ts2.size() ? ts1 : ts2;
1181             int e = rest.size();
1182             for (int i = n; i < e; i++) {
1183                 Object o = rest.get(i);
1184                 if (o instanceof Integer && ((Integer)o) == 0)
1185                     continue;
1186                 return ts1.size() - ts2.size();
1187             }
1188             return 0;
1189         }
1190 
1191         /**
1192          * Compares this module version to another module version. Module
1193          * versions are compared as described in the class description.
1194          *
1195          * @param that
1196          *        The module version to compare
1197          *
1198          * @return A negative integer, zero, or a positive integer as this
1199          *         module version is less than, equal to, or greater than the
1200          *         given module version
1201          */
1202         @Override
1203         public int compareTo(Version that) {
1204             int c = compareTokens(this.sequence, that.sequence);
1205             if (c != 0) return c;
1206             if (this.pre.isEmpty()) {
1207                 if (!that.pre.isEmpty()) return +1;
1208             } else {
1209                 if (that.pre.isEmpty()) return -1;
1210             }
1211             c = compareTokens(this.pre, that.pre);
1212             if (c != 0) return c;
1213             return compareTokens(this.build, that.build);
1214         }
1215 
1216         /**
1217          * Tests this module version for equality with the given object.
1218          *
1219          * <p> If the given object is not a {@code Version} then this method
1220          * returns {@code false}. Two module version are equal if their
1221          * corresponding components are equal. </p>
1222          *
1223          * <p> This method satisfies the general contract of the {@link
1224          * java.lang.Object#equals(Object) Object.equals} method. </p>
1225          *
1226          * @param   ob
1227          *          the object to which this object is to be compared
1228          *
1229          * @return  {@code true} if, and only if, the given object is a module
1230          *          reference that is equal to this module reference
1231          */
1232         @Override
1233         public boolean equals(Object ob) {
1234             if (!(ob instanceof Version))
1235                 return false;
1236             return compareTo((Version)ob) == 0;
1237         }
1238 
1239         /**
1240          * Computes a hash code for this module version.
1241          *
1242          * <p> The hash code is based upon the components of the version and
1243          * satisfies the general contract of the {@link Object#hashCode
1244          * Object.hashCode} method. </p>
1245          *
1246          * @return The hash-code value for this module version
1247          */
1248         @Override
1249         public int hashCode() {
1250             return version.hashCode();
1251         }
1252 
1253         /**
1254          * Returns the string from which this version was parsed.
1255          *
1256          * @return The string from which this version was parsed.
1257          */
1258         @Override
1259         public String toString() {
1260             return version;
1261         }
1262 
1263     }
1264 
1265 
1266     private final String name;
1267     private final Version version;
1268     private final String rawVersionString;
1269     private final Set<Modifier> modifiers;
1270     private final boolean open;  // true if modifiers contains OPEN
1271     private final boolean automatic;  // true if modifiers contains AUTOMATIC
1272     private final Set<Requires> requires;
1273     private final Set<Exports> exports;
1274     private final Set<Opens> opens;
1275     private final Set<String> uses;
1276     private final Set<Provides> provides;
1277     private final Set<String> packages;
1278     private final String mainClass;
1279 
1280     private ModuleDescriptor(String name,
1281                              Version version,
1282                              String rawVersionString,
1283                              Set<Modifier> modifiers,
1284                              Set<Requires> requires,
1285                              Set<Exports> exports,
1286                              Set<Opens> opens,
1287                              Set<String> uses,
1288                              Set<Provides> provides,
1289                              Set<String> packages,
1290                              String mainClass)
1291     {
1292         assert version == null || rawVersionString == null;
1293         this.name = name;
1294         this.version = version;
1295         this.rawVersionString = rawVersionString;
1296         this.modifiers = Set.copyOf(modifiers);
1297         this.open = modifiers.contains(Modifier.OPEN);
1298         this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1299         assert (requires.stream().map(Requires::name).distinct().count()
1300                 == requires.size());
1301         this.requires = Set.copyOf(requires);
1302         this.exports = Set.copyOf(exports);
1303         this.opens = Set.copyOf(opens);
1304         this.uses = Set.copyOf(uses);
1305         this.provides = Set.copyOf(provides);
1306 
1307         this.packages = Set.copyOf(packages);
1308         this.mainClass = mainClass;
1309     }
1310 
1311     /**
1312      * Creates a module descriptor from its components.
1313      * The arguments are pre-validated and sets are unmodifiable sets.
1314      */
1315     ModuleDescriptor(String name,
1316                      Version version,
1317                      Set<Modifier> modifiers,
1318                      Set<Requires> requires,
1319                      Set<Exports> exports,
1320                      Set<Opens> opens,
1321                      Set<String> uses,
1322                      Set<Provides> provides,
1323                      Set<String> packages,
1324                      String mainClass,
1325                      int hashCode,
1326                      boolean unused) {
1327         this.name = name;
1328         this.version = version;
1329         this.rawVersionString = null;
1330         this.modifiers = modifiers;
1331         this.open = modifiers.contains(Modifier.OPEN);
1332         this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1333         this.requires = requires;
1334         this.exports = exports;
1335         this.opens = opens;
1336         this.uses = uses;
1337         this.provides = provides;
1338         this.packages = packages;
1339         this.mainClass = mainClass;
1340         this.hash = hashCode;
1341     }
1342 
1343     /**
1344      * <p> Returns the module name. </p>
1345      *
1346      * @return The module name
1347      */
1348     public String name() {
1349         return name;
1350     }
1351 
1352     /**
1353      * <p> Returns the set of module modifiers. </p>
1354      *
1355      * @return A possibly-empty unmodifiable set of modifiers
1356      */
1357     public Set<Modifier> modifiers() {
1358         return modifiers;
1359     }
1360 
1361     /**
1362      * Returns the set of the {@linkplain AccessFlag module flags}.
1363      *
1364      * @return A possibly-empty unmodifiable set of module flags
1365      * @see #modifiers()
1366      * @jvms 4.7.25 The Module Attribute
1367      * @since 20
1368      */
1369     public Set<AccessFlag> accessFlags() {
1370         int mask = 0;
1371         for (var modifier : modifiers) {
1372             mask |= modifier.mask();
1373         }
1374         return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE);
1375     }
1376 
1377     /**
1378      * <p> Returns {@code true} if this is an open module. </p>
1379      *
1380      * <p> This method is equivalent to testing if the set of {@link #modifiers()
1381      * modifiers} contains the {@link Modifier#OPEN OPEN} modifier. </p>
1382      *
1383      * @return  {@code true} if this is an open module
1384      */
1385     public boolean isOpen() {
1386         return open;
1387     }
1388 
1389     /**
1390      * <p> Returns {@code true} if this is an automatic module. </p>
1391      *
1392      * <p> This method is equivalent to testing if the set of {@link #modifiers()
1393      * modifiers} contains the {@link Modifier#AUTOMATIC AUTOMATIC} modifier. </p>
1394      *
1395      * @return  {@code true} if this is an automatic module
1396      */
1397     public boolean isAutomatic() {
1398         return automatic;
1399     }
1400 
1401     /**
1402      * <p> Returns the set of {@code Requires} objects representing the module
1403      * dependences. </p>
1404      *
1405      * <p> The set includes a dependency on "{@code java.base}" when this
1406      * module is not named "{@code java.base}". If this module is an automatic
1407      * module then it does not have a dependency on any module other than
1408      * "{@code java.base}". </p>
1409      *
1410      * @return  A possibly-empty unmodifiable set of {@link Requires} objects
1411      */
1412     public Set<Requires> requires() {
1413         return requires;
1414     }
1415 
1416     /**
1417      * <p> Returns the set of {@code Exports} objects representing the exported
1418      * packages. </p>
1419      *
1420      * <p> If this module is an automatic module then the set of exports
1421      * is empty. </p>
1422      *
1423      * @return  A possibly-empty unmodifiable set of exported packages
1424      */
1425     public Set<Exports> exports() {
1426         return exports;
1427     }
1428 
1429     /**
1430      * <p> Returns the set of {@code Opens} objects representing the open
1431      * packages. </p>
1432      *
1433      * <p> If this module is an open module or an automatic module then the
1434      * set of open packages is empty. </p>
1435      *
1436      * @return  A possibly-empty unmodifiable set of open packages
1437      */
1438     public Set<Opens> opens() {
1439         return opens;
1440     }
1441 
1442     /**
1443      * <p> Returns the set of service dependences. </p>
1444      *
1445      * <p> If this module is an automatic module then the set of service
1446      * dependences is empty. </p>
1447      *
1448      * @return  A possibly-empty unmodifiable set of the {@linkplain ClassLoader##binary-name
1449      *          binary names} of the service types used
1450      */
1451     public Set<String> uses() {
1452         return uses;
1453     }
1454 
1455     /**
1456      * <p> Returns the set of {@code Provides} objects representing the
1457      * services that the module provides. </p>
1458      *
1459      * @return The possibly-empty unmodifiable set of the services that this
1460      *         module provides
1461      */
1462     public Set<Provides> provides() {
1463         return provides;
1464     }
1465 
1466     /**
1467      * <p> Returns the module version. </p>
1468      *
1469      * @return This module's version, or an empty {@code Optional} if the
1470      *         module does not have a version or the version is
1471      *         {@linkplain Version#parse(String) unparseable}
1472      */
1473     public Optional<Version> version() {
1474         return Optional.ofNullable(version);
1475     }
1476 
1477     /**
1478      * <p> Returns the string with the possibly-unparseable version of the
1479      * module. </p>
1480      *
1481      * @return The string containing the version of the module or an empty
1482      *         {@code Optional} if the module does not have a version
1483      *
1484      * @see #version()
1485      */
1486     public Optional<String> rawVersion() {
1487         if (version != null) {
1488             return Optional.of(version.toString());
1489         } else {
1490             return Optional.ofNullable(rawVersionString);
1491         }
1492     }
1493 
1494     /**
1495      * <p> Returns a string containing the module name and, if present, its
1496      * version. </p>
1497      *
1498      * @return A string containing the module name and, if present, its
1499      *         version
1500      */
1501     public String toNameAndVersion() {
1502         if (version != null) {
1503             return name() + "@" + version;
1504         } else {
1505             return name();
1506         }
1507     }
1508 
1509     /**
1510      * <p> Returns the module main class. </p>
1511      *
1512      * @return The {@linkplain ClassLoader##binary-name binary name} of the module's main class
1513      */
1514     public Optional<String> mainClass() {
1515         return Optional.ofNullable(mainClass);
1516     }
1517 
1518     /**
1519      * Returns the set of packages in the module.
1520      *
1521      * <p> The set of packages includes all exported and open packages, as well
1522      * as the packages of any service providers, and the package for the main
1523      * class. </p>
1524      *
1525      * @return A possibly-empty unmodifiable set of the packages in the module
1526      */
1527     public Set<String> packages() {
1528         return packages;
1529     }
1530 
1531 
1532     /**
1533      * A builder for building {@link ModuleDescriptor} objects.
1534      *
1535      * <p> {@code ModuleDescriptor} defines the {@link #newModule newModule},
1536      * {@link #newOpenModule newOpenModule}, and {@link #newAutomaticModule
1537      * newAutomaticModule} methods to create builders for building
1538      * <em>normal</em>, open, and automatic modules. </p>
1539      *
1540      * <p> The set of packages in the module are accumulated by the {@code
1541      * Builder} as the {@link ModuleDescriptor.Builder#exports(String) exports},
1542      * {@link ModuleDescriptor.Builder#opens(String) opens},
1543      * {@link ModuleDescriptor.Builder#packages(Set) packages},
1544      * {@link ModuleDescriptor.Builder#provides(String,List) provides}, and
1545      * {@link ModuleDescriptor.Builder#mainClass(String) mainClass} methods are
1546      * invoked. </p>
1547      *
1548      * <p> The module names, package names, and class names that are parameters
1549      * specified to the builder methods are the module names, package names,
1550      * and qualified names of classes (in named packages) as defined in the
1551      * <cite>The Java Language Specification</cite>. </p>
1552      *
1553      * <p> Example usage: </p>
1554      * {@snippet :
1555      *     ModuleDescriptor descriptor = ModuleDescriptor.newModule("stats.core")
1556      *         .requires("java.base")
1557      *         .exports("org.acme.stats.core.clustering")
1558      *         .exports("org.acme.stats.core.regression")
1559      *         .packages(Set.of("org.acme.stats.core.internal"))
1560      *         .build();
1561      * }
1562      *
1563      * @apiNote A {@code Builder} checks the components and invariants as
1564      * components are added to the builder. The rationale for this is to detect
1565      * errors as early as possible and not defer all validation to the
1566      * {@link #build build} method.
1567      *
1568      * @since 9
1569      */
1570     public static final class Builder {
1571         final String name;
1572         final boolean strict;
1573         final Set<Modifier> modifiers;
1574         final boolean open;
1575         final boolean automatic;
1576         final Set<String> packages = new HashSet<>();
1577         final Map<String, Requires> requires = new HashMap<>();
1578         final Map<String, Exports> exports = new HashMap<>();
1579         final Map<String, Opens> opens = new HashMap<>();
1580         final Set<String> uses = new HashSet<>();
1581         final Map<String, Provides> provides = new HashMap<>();
1582         Version version;
1583         String rawVersionString;
1584         String mainClass;
1585 
1586         /**
1587          * Initializes a new builder with the given module name.
1588          *
1589          * If {@code strict} is {@code true} then module, package, and class
1590          * names are checked to ensure they are legal names. In addition, the
1591          * {@link #build build} method will add "{@code requires java.base}" if
1592          * the dependency is not declared.
1593          */
1594         Builder(String name, boolean strict, Set<Modifier> modifiers) {
1595             this.name = (strict) ? requireModuleName(name) : name;
1596             this.strict = strict;
1597             this.modifiers = modifiers;
1598             this.open = modifiers.contains(Modifier.OPEN);
1599             this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1600             assert !open || !automatic;
1601         }
1602 
1603         /**
1604          * Returns a snapshot of the packages in the module.
1605          */
1606         /* package */ Set<String> packages() {
1607             return Collections.unmodifiableSet(packages);
1608         }
1609 
1610         /**
1611          * Adds a dependence on a module.
1612          *
1613          * @param  req
1614          *         The dependence
1615          *
1616          * @return This builder
1617          *
1618          * @throws IllegalArgumentException
1619          *         If the dependence is on the module that this builder was
1620          *         initialized to build
1621          * @throws IllegalStateException
1622          *         If the dependence on the module has already been declared
1623          *         or this builder is for an automatic module
1624          */
1625         public Builder requires(Requires req) {
1626             if (automatic)
1627                 throw new IllegalStateException("Automatic modules cannot declare"
1628                                                 + " dependences");
1629             String mn = req.name();
1630             if (name.equals(mn))
1631                 throw new IllegalArgumentException("Dependence on self");
1632             if (requires.containsKey(mn))
1633                 throw new IllegalStateException("Dependence upon " + mn
1634                                                 + " already declared");
1635             requires.put(mn, req);
1636             return this;
1637         }
1638 
1639         /**
1640          * Adds a dependence on a module with the given (and possibly empty)
1641          * set of modifiers. The dependence includes the version of the
1642          * module that was recorded at compile-time.
1643          *
1644          * @param  ms
1645          *         The set of modifiers
1646          * @param  mn
1647          *         The module name
1648          * @param  compiledVersion
1649          *         The version of the module recorded at compile-time
1650          *
1651          * @return This builder
1652          *
1653          * @throws IllegalArgumentException
1654          *         If the module name is {@code null}, is not a legal module
1655          *         name, or is equal to the module name that this builder
1656          *         was initialized to build
1657          * @throws IllegalStateException
1658          *         If the dependence on the module has already been declared
1659          *         or this builder is for an automatic module
1660          */
1661         public Builder requires(Set<Requires.Modifier> ms,
1662                                 String mn,
1663                                 Version compiledVersion) {
1664             Objects.requireNonNull(compiledVersion);
1665             if (strict)
1666                 mn = requireModuleName(mn);
1667             return requires(new Requires(ms, mn, compiledVersion, null));
1668         }
1669 
1670         /* package */Builder requires(Set<Requires.Modifier> ms,
1671                                       String mn,
1672                                       String rawCompiledVersion) {
1673             Requires r;
1674             try {
1675                 Version v = Version.parse(rawCompiledVersion);
1676                 r = new Requires(ms, mn, v, null);
1677             } catch (IllegalArgumentException e) {
1678                 if (strict) throw e;
1679                 r = new Requires(ms, mn, null, rawCompiledVersion);
1680             }
1681             return requires(r);
1682         }
1683 
1684         /**
1685          * Adds a dependence on a module with the given (and possibly empty)
1686          * set of modifiers.
1687          *
1688          * @param  ms
1689          *         The set of modifiers
1690          * @param  mn
1691          *         The module name
1692          *
1693          * @return This builder
1694          *
1695          * @throws IllegalArgumentException
1696          *         If the module name is {@code null}, is not a legal module
1697          *         name, or is equal to the module name that this builder
1698          *         was initialized to build
1699          * @throws IllegalStateException
1700          *         If the dependence on the module has already been declared
1701          *         or this builder is for an automatic module
1702          */
1703         public Builder requires(Set<Requires.Modifier> ms, String mn) {
1704             if (strict)
1705                 mn = requireModuleName(mn);
1706             return requires(new Requires(ms, mn, null, null));
1707         }
1708 
1709         /**
1710          * Adds a dependence on a module with an empty set of modifiers.
1711          *
1712          * @param  mn
1713          *         The module name
1714          *
1715          * @return This builder
1716          *
1717          * @throws IllegalArgumentException
1718          *         If the module name is {@code null}, is not a legal module
1719          *         name, or is equal to the module name that this builder
1720          *         was initialized to build
1721          * @throws IllegalStateException
1722          *         If the dependence on the module has already been declared
1723          *         or this builder is for an automatic module
1724          */
1725         public Builder requires(String mn) {
1726             return requires(EnumSet.noneOf(Requires.Modifier.class), mn);
1727         }
1728 
1729         /**
1730          * Adds an exported package.
1731          *
1732          * @param  e
1733          *         The export
1734          *
1735          * @return This builder
1736          *
1737          * @throws IllegalStateException
1738          *         If the {@link Exports#source() package} is already declared as
1739          *         exported or this builder is for an automatic module
1740          */
1741         public Builder exports(Exports e) {
1742             if (automatic) {
1743                 throw new IllegalStateException("Automatic modules cannot declare"
1744                                                  + " exported packages");
1745             }
1746             String source = e.source();
1747             if (exports.containsKey(source)) {
1748                 throw new IllegalStateException("Exported package " + source
1749                                                  + " already declared");
1750             }
1751             exports.put(source, e);
1752             packages.add(source);
1753             return this;
1754         }
1755 
1756         /**
1757          * Adds an exported package with the given (and possibly empty) set of
1758          * modifiers. The package is exported to a set of target modules.
1759          *
1760          * @param  ms
1761          *         The set of modifiers
1762          * @param  pn
1763          *         The package name
1764          * @param  targets
1765          *         The set of target modules names
1766          *
1767          * @return This builder
1768          *
1769          * @throws IllegalArgumentException
1770          *         If the package name is {@code null} or is not a legal
1771          *         package name, the set of target modules is empty, or the set
1772          *         of target modules contains a name that is not a legal module
1773          *         name
1774          * @throws IllegalStateException
1775          *         If the package is already declared as exported
1776          *         or this builder is for an automatic module
1777          */
1778         public Builder exports(Set<Exports.Modifier> ms,
1779                                String pn,
1780                                Set<String> targets)
1781         {
1782             targets = new HashSet<>(targets);
1783             if (targets.isEmpty())
1784                 throw new IllegalArgumentException("Empty target set");
1785             if (strict) {
1786                 requirePackageName(pn);
1787                 targets.forEach(Checks::requireModuleName);
1788             }
1789             Exports e = new Exports(ms, pn, targets);
1790             return exports(e);
1791         }
1792 
1793         /**
1794          * Adds an exported package with the given (and possibly empty) set of
1795          * modifiers. The package is exported to all modules.
1796          *
1797          * @param  ms
1798          *         The set of modifiers
1799          * @param  pn
1800          *         The package name
1801          *
1802          * @return This builder
1803          *
1804          * @throws IllegalArgumentException
1805          *         If the package name is {@code null} or is not a legal
1806          *         package name
1807          * @throws IllegalStateException
1808          *         If the package is already declared as exported
1809          *         or this builder is for an automatic module
1810          */
1811         public Builder exports(Set<Exports.Modifier> ms, String pn) {
1812             if (strict) {
1813                 requirePackageName(pn);
1814             }
1815             Exports e = new Exports(ms, pn, Set.of());
1816             return exports(e);
1817         }
1818 
1819         /**
1820          * Adds an exported package. The package is exported to a set of target
1821          * modules.
1822          *
1823          * @param  pn
1824          *         The package name
1825          * @param  targets
1826          *         The set of target modules names
1827          *
1828          * @return This builder
1829          *
1830          * @throws IllegalArgumentException
1831          *         If the package name is {@code null} or is not a legal
1832          *         package name, the set of target modules is empty, or the set
1833          *         of target modules contains a name that is not a legal module
1834          *         name
1835          * @throws IllegalStateException
1836          *         If the package is already declared as exported
1837          *         or this builder is for an automatic module
1838          */
1839         public Builder exports(String pn, Set<String> targets) {
1840             return exports(Set.of(), pn, targets);
1841         }
1842 
1843         /**
1844          * Adds an exported package. The package is exported to all modules.
1845          *
1846          * @param  pn
1847          *         The package name
1848          *
1849          * @return This builder
1850          *
1851          * @throws IllegalArgumentException
1852          *         If the package name is {@code null} or is not a legal
1853          *         package name
1854          * @throws IllegalStateException
1855          *         If the package is already declared as exported
1856          *         or this builder is for an automatic module
1857          */
1858         public Builder exports(String pn) {
1859             return exports(Set.of(), pn);
1860         }
1861 
1862         /**
1863          * Adds an open package.
1864          *
1865          * @param  obj
1866          *         The {@code Opens} object
1867          *
1868          * @return This builder
1869          *
1870          * @throws IllegalStateException
1871          *         If the package is already declared as open, or this is a
1872          *         builder for an open module or automatic module
1873          */
1874         public Builder opens(Opens obj) {
1875             if (open || automatic) {
1876                 throw new IllegalStateException("Open or automatic modules cannot"
1877                                                 + " declare open packages");
1878             }
1879             String source = obj.source();
1880             if (opens.containsKey(source)) {
1881                 throw new IllegalStateException("Open package " + source
1882                                                 + " already declared");
1883             }
1884             opens.put(source, obj);
1885             packages.add(source);
1886             return this;
1887         }
1888 
1889 
1890         /**
1891          * Adds an open package with the given (and possibly empty) set of
1892          * modifiers. The package is open to a set of target modules.
1893          *
1894          * @param  ms
1895          *         The set of modifiers
1896          * @param  pn
1897          *         The package name
1898          * @param  targets
1899          *         The set of target modules names
1900          *
1901          * @return This builder
1902          *
1903          * @throws IllegalArgumentException
1904          *         If the package name is {@code null} or is not a legal
1905          *         package name, the set of target modules is empty, or the set
1906          *         of target modules contains a name that is not a legal module
1907          *         name
1908          * @throws IllegalStateException
1909          *         If the package is already declared as open, or this is a
1910          *         builder for an open module or automatic module
1911          */
1912         public Builder opens(Set<Opens.Modifier> ms,
1913                              String pn,
1914                              Set<String> targets)
1915         {
1916             targets = new HashSet<>(targets);
1917             if (targets.isEmpty())
1918                 throw new IllegalArgumentException("Empty target set");
1919             if (strict) {
1920                 requirePackageName(pn);
1921                 targets.forEach(Checks::requireModuleName);
1922             }
1923             Opens opens = new Opens(ms, pn, targets);
1924             return opens(opens);
1925         }
1926 
1927         /**
1928          * Adds an open package with the given (and possibly empty) set of
1929          * modifiers. The package is open to all modules.
1930          *
1931          * @param  ms
1932          *         The set of modifiers
1933          * @param  pn
1934          *         The package name
1935          *
1936          * @return This builder
1937          *
1938          * @throws IllegalArgumentException
1939          *         If the package name is {@code null} or is not a legal
1940          *         package name
1941          * @throws IllegalStateException
1942          *         If the package is already declared as open, or this is a
1943          *         builder for an open module or automatic module
1944          */
1945         public Builder opens(Set<Opens.Modifier> ms, String pn) {
1946             if (strict) {
1947                 requirePackageName(pn);
1948             }
1949             Opens e = new Opens(ms, pn, Set.of());
1950             return opens(e);
1951         }
1952 
1953         /**
1954          * Adds an open package. The package is open to a set of target modules.
1955          *
1956          * @param  pn
1957          *         The package name
1958          * @param  targets
1959          *         The set of target modules names
1960          *
1961          * @return This builder
1962          *
1963          * @throws IllegalArgumentException
1964          *         If the package name is {@code null} or is not a legal
1965          *         package name, the set of target modules is empty, or the set
1966          *         of target modules contains a name that is not a legal module
1967          *         name
1968          * @throws IllegalStateException
1969          *         If the package is already declared as open, or this is a
1970          *         builder for an open module or automatic module
1971          */
1972         public Builder opens(String pn, Set<String> targets) {
1973             return opens(Set.of(), pn, targets);
1974         }
1975 
1976         /**
1977          * Adds an open package. The package is open to all modules.
1978          *
1979          * @param  pn
1980          *         The package name
1981          *
1982          * @return This builder
1983          *
1984          * @throws IllegalArgumentException
1985          *         If the package name is {@code null} or is not a legal
1986          *         package name
1987          * @throws IllegalStateException
1988          *         If the package is already declared as open, or this is a
1989          *         builder for an open module or automatic module
1990          */
1991         public Builder opens(String pn) {
1992             return opens(Set.of(), pn);
1993         }
1994 
1995         /**
1996          * Adds a service dependence.
1997          *
1998          * @param  service
1999          *         The service type
2000          *
2001          * @return This builder
2002          *
2003          * @throws IllegalArgumentException
2004          *         If the service type is {@code null} or not a qualified name of
2005          *         a class in a named package
2006          * @throws IllegalStateException
2007          *         If a dependency on the service type has already been declared
2008          *         or this is a builder for an automatic module
2009          */
2010         public Builder uses(String service) {
2011             if (automatic)
2012                 throw new IllegalStateException("Automatic modules can not declare"
2013                                                 + " service dependences");
2014             if (uses.contains(requireServiceTypeName(service)))
2015                 throw new IllegalStateException("Dependence upon service "
2016                                                 + service + " already declared");
2017             uses.add(service);
2018             return this;
2019         }
2020 
2021         /**
2022          * Provides a service with one or more implementations. The package for
2023          * each {@link Provides#providers provider} (or provider factory) is
2024          * added to the module if not already added.
2025          *
2026          * @param  p
2027          *         The provides
2028          *
2029          * @return This builder
2030          *
2031          * @throws IllegalStateException
2032          *         If the providers for the service type have already been
2033          *         declared
2034          */
2035         public Builder provides(Provides p) {
2036             String service = p.service();
2037             if (provides.containsKey(service))
2038                 throw new IllegalStateException("Providers of service "
2039                                                 + service + " already declared");
2040             provides.put(service, p);
2041             p.providers().forEach(name -> packages.add(packageName(name)));
2042             return this;
2043         }
2044 
2045         /**
2046          * Provides implementations of a service. The package for each provider
2047          * (or provider factory) is added to the module if not already added.
2048          *
2049          * @param  service
2050          *         The service type
2051          * @param  providers
2052          *         The list of provider or provider factory class names
2053          *
2054          * @return This builder
2055          *
2056          * @throws IllegalArgumentException
2057          *         If the service type or any of the provider class names is
2058          *         {@code null} or not a qualified name of a class in a named
2059          *         package, or the list of provider class names is empty
2060          * @throws IllegalStateException
2061          *         If the providers for the service type have already been
2062          *         declared
2063          */
2064         public Builder provides(String service, List<String> providers) {
2065             providers = new ArrayList<>(providers);
2066             if (providers.isEmpty())
2067                 throw new IllegalArgumentException("Empty providers set");
2068             if (strict) {
2069                 requireServiceTypeName(service);
2070                 providers.forEach(Checks::requireServiceProviderName);
2071             } else {
2072                 // Disallow service/providers in unnamed package
2073                 String pn = packageName(service);
2074                 if (pn.isEmpty()) {
2075                     throw new IllegalArgumentException(service
2076                                                        + ": unnamed package");
2077                 }
2078                 for (String name : providers) {
2079                     pn = packageName(name);
2080                     if (pn.isEmpty()) {
2081                         throw new IllegalArgumentException(name
2082                                                            + ": unnamed package");
2083                     }
2084                 }
2085             }
2086             Provides p = new Provides(service, providers);
2087             return provides(p);
2088         }
2089 
2090         /**
2091          * Adds packages to the module. All packages in the set of package names
2092          * that are not in the module are added to module.
2093          *
2094          * @param  pns
2095          *         The (possibly empty) set of package names
2096          *
2097          * @return This builder
2098          *
2099          * @throws IllegalArgumentException
2100          *         If any of the package names is {@code null} or is not a
2101          *         legal package name
2102          */
2103         public Builder packages(Set<String> pns) {
2104             if (strict) {
2105                 pns = new HashSet<>(pns);
2106                 pns.forEach(Checks::requirePackageName);
2107             }
2108             this.packages.addAll(pns);
2109             return this;
2110         }
2111 
2112         /**
2113          * Sets the module version.
2114          *
2115          * @param  v
2116          *         The version
2117          *
2118          * @return This builder
2119          */
2120         public Builder version(Version v) {
2121             version = requireNonNull(v);
2122             rawVersionString = null;
2123             return this;
2124         }
2125 
2126         /**
2127          * Sets the module version.
2128          *
2129          * @param  vs
2130          *         The version string to parse
2131          *
2132          * @return This builder
2133          *
2134          * @throws IllegalArgumentException
2135          *         If {@code vs} is {@code null} or cannot be parsed as a
2136          *         version string
2137          *
2138          * @see Version#parse(String)
2139          */
2140         public Builder version(String vs) {
2141             try {
2142                 version = Version.parse(vs);
2143                 rawVersionString = null;
2144             } catch (IllegalArgumentException e) {
2145                 if (strict) throw e;
2146                 version = null;
2147                 rawVersionString = vs;
2148             }
2149             return this;
2150         }
2151 
2152         /**
2153          * Sets the module main class. The package for the main class is added
2154          * to the module if not already added. In other words, this method is
2155          * equivalent to first invoking this builder's {@link #packages(Set)
2156          * packages} method to add the package name of the main class.
2157          *
2158          * @param  mc
2159          *         The module main class
2160          *
2161          * @return This builder
2162          *
2163          * @throws IllegalArgumentException
2164          *         If {@code mainClass} is {@code null} or not a qualified
2165          *         name of a class in a named package
2166          */
2167         public Builder mainClass(String mc) {
2168             String pn;
2169             if (strict) {
2170                 mc = requireQualifiedClassName("main class name", mc);
2171                 pn = packageName(mc);
2172                 assert !pn.isEmpty();
2173             } else {
2174                 // Disallow main class in unnamed package
2175                 pn = packageName(mc);
2176                 if (pn.isEmpty()) {
2177                     throw new IllegalArgumentException(mc + ": unnamed package");
2178                 }
2179             }
2180             packages.add(pn);
2181             mainClass = mc;
2182             return this;
2183         }
2184 
2185         /**
2186          * Builds and returns a {@code ModuleDescriptor} from its components.
2187          *
2188          * <p> The module will require "{@code java.base}" even if the dependence
2189          * has not been declared (the exception is when building a module named
2190          * "{@code java.base}" as it cannot require itself). The dependence on
2191          * "{@code java.base}" will have the {@link
2192          * java.lang.module.ModuleDescriptor.Requires.Modifier#MANDATED MANDATED}
2193          * modifier if the dependence was not declared. </p>
2194          *
2195          * @return The module descriptor
2196          */
2197         public ModuleDescriptor build() {
2198             Set<Requires> requires = new HashSet<>(this.requires.values());
2199             Set<Exports> exports = new HashSet<>(this.exports.values());
2200             Set<Opens> opens = new HashSet<>(this.opens.values());
2201 
2202             // add dependency on java.base
2203             if (strict
2204                     && !name.equals("java.base")
2205                     && !this.requires.containsKey("java.base")) {
2206                 requires.add(new Requires(Set.of(Requires.Modifier.MANDATED),
2207                                           "java.base",
2208                                           null,
2209                                           null));
2210             }
2211 
2212             Set<Provides> provides = new HashSet<>(this.provides.values());
2213 
2214             return new ModuleDescriptor(name,
2215                                         version,
2216                                         rawVersionString,
2217                                         modifiers,
2218                                         requires,
2219                                         exports,
2220                                         opens,
2221                                         uses,
2222                                         provides,
2223                                         packages,
2224                                         mainClass);
2225         }
2226 
2227     }
2228 
2229     /**
2230      * Compares this module descriptor to another.
2231      *
2232      * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
2233      * module names lexicographically. Where the module names are equal then the
2234      * module versions are compared. When comparing the module versions then a
2235      * module descriptor with a version is considered to succeed a module
2236      * descriptor that does not have a version. If both versions are {@linkplain
2237      * Version#parse(String) unparseable} then the {@linkplain #rawVersion()
2238      * raw version strings} are compared lexicographically. Where the module names
2239      * are equal and the versions are equal (or not present in both), then the
2240      * set of modifiers are compared. Sets of modifiers are compared by comparing
2241      * a <em>binary value</em> computed for each set. If a modifier is present
2242      * in the set then the bit at the position of its ordinal is {@code 1}
2243      * in the binary value, otherwise {@code 0}. If the two set of modifiers
2244      * are also equal then the other components of the module descriptors are
2245      * compared in a manner that is consistent with {@code equals}. </p>
2246      *
2247      * @param  that
2248      *         The module descriptor to compare
2249      *
2250      * @return A negative integer, zero, or a positive integer if this module
2251      *         descriptor is less than, equal to, or greater than the given
2252      *         module descriptor
2253      */
2254     @Override
2255     public int compareTo(ModuleDescriptor that) {
2256         if (this == that) return 0;
2257 
2258         int c = this.name().compareTo(that.name());
2259         if (c != 0) return c;
2260 
2261         c = compare(this.version, that.version);
2262         if (c != 0) return c;
2263 
2264         c = compare(this.rawVersionString, that.rawVersionString);
2265         if (c != 0) return c;
2266 
2267         long v1 = modsValue(this.modifiers());
2268         long v2 = modsValue(that.modifiers());
2269         c = Long.compare(v1, v2);
2270         if (c != 0) return c;
2271 
2272         c = compare(this.requires, that.requires);
2273         if (c != 0) return c;
2274 
2275         c = compare(this.packages, that.packages);
2276         if (c != 0) return c;
2277 
2278         c = compare(this.exports, that.exports);
2279         if (c != 0) return c;
2280 
2281         c = compare(this.opens, that.opens);
2282         if (c != 0) return c;
2283 
2284         c = compare(this.uses, that.uses);
2285         if (c != 0) return c;
2286 
2287         c = compare(this.provides, that.provides);
2288         if (c != 0) return c;
2289 
2290         c = compare(this.mainClass, that.mainClass);
2291         if (c != 0) return c;
2292 
2293         return 0;
2294     }
2295 
2296     /**
2297      * Tests this module descriptor for equality with the given object.
2298      *
2299      * <p> If the given object is not a {@code ModuleDescriptor} then this
2300      * method returns {@code false}. Two module descriptors are equal if each
2301      * of their corresponding components is equal. </p>
2302      *
2303      * <p> This method satisfies the general contract of the {@link
2304      * java.lang.Object#equals(Object) Object.equals} method. </p>
2305      *
2306      * @param   ob
2307      *          the object to which this object is to be compared
2308      *
2309      * @return  {@code true} if, and only if, the given object is a module
2310      *          descriptor that is equal to this module descriptor
2311      */
2312     @Override
2313     public boolean equals(Object ob) {
2314         if (ob == this)
2315             return true;
2316         return (ob instanceof ModuleDescriptor that)
2317                 && (name.equals(that.name)
2318                 && modifiers.equals(that.modifiers)
2319                 && requires.equals(that.requires)
2320                 && Objects.equals(packages, that.packages)
2321                 && exports.equals(that.exports)
2322                 && opens.equals(that.opens)
2323                 && uses.equals(that.uses)
2324                 && provides.equals(that.provides)
2325                 && Objects.equals(version, that.version)
2326                 && Objects.equals(rawVersionString, that.rawVersionString)
2327                 && Objects.equals(mainClass, that.mainClass));
2328     }
2329 
2330     /**
2331      * Computes a hash code for this module descriptor.
2332      *
2333      * <p> The hash code is based upon the components of the module descriptor,
2334      * and satisfies the general contract of the {@link Object#hashCode
2335      * Object.hashCode} method. </p>
2336      *
2337      * @return The hash-code value for this module descriptor
2338      */
2339     @Override
2340     public int hashCode() {
2341         int hc = hash;
2342         if (hc == 0) {
2343             hc = name.hashCode();
2344             hc = hc * 43 + modsHashCode(modifiers);
2345             hc = hc * 43 + requires.hashCode();
2346             hc = hc * 43 + Objects.hashCode(packages);
2347             hc = hc * 43 + exports.hashCode();
2348             hc = hc * 43 + opens.hashCode();
2349             hc = hc * 43 + uses.hashCode();
2350             hc = hc * 43 + provides.hashCode();
2351             hc = hc * 43 + Objects.hashCode(version);
2352             hc = hc * 43 + Objects.hashCode(rawVersionString);
2353             hc = hc * 43 + Objects.hashCode(mainClass);
2354             if (hc == 0)
2355                 hc = -1;
2356             hash = hc;
2357         }
2358         return hc;
2359     }
2360     private transient int hash;  // cached hash code
2361 
2362     /**
2363      * <p> Returns a string describing the module. </p>
2364      *
2365      * @return A string describing the module
2366      */
2367     @Override
2368     public String toString() {
2369         StringBuilder sb = new StringBuilder();
2370 
2371         if (isOpen())
2372             sb.append("open ");
2373         sb.append("module { name: ").append(toNameAndVersion());
2374         if (!requires.isEmpty())
2375             sb.append(", ").append(requires);
2376         if (!uses.isEmpty())
2377             sb.append(", uses: ").append(uses);
2378         if (!exports.isEmpty())
2379             sb.append(", exports: ").append(exports);
2380         if (!opens.isEmpty())
2381             sb.append(", opens: ").append(opens);
2382         if (!provides.isEmpty()) {
2383             sb.append(", provides: ").append(provides);
2384         }
2385         sb.append(" }");
2386         return sb.toString();
2387     }
2388 
2389 
2390     /**
2391      * Instantiates a builder to build a module descriptor.
2392      *
2393      * @param  name
2394      *         The module name
2395      * @param  ms
2396      *         The set of module modifiers
2397      *
2398      * @return A new builder
2399      *
2400      * @throws IllegalArgumentException
2401      *         If the module name is {@code null} or is not a legal module
2402      *         name, or the set of modifiers contains {@link
2403      *         Modifier#AUTOMATIC AUTOMATIC} with other modifiers
2404      */
2405     public static Builder newModule(String name, Set<Modifier> ms) {
2406         Set<Modifier> mods = new HashSet<>(ms);
2407         if (mods.contains(Modifier.AUTOMATIC) && mods.size() > 1)
2408             throw new IllegalArgumentException("AUTOMATIC cannot be used with"
2409                                                + " other modifiers");
2410 
2411         return new Builder(name, true, mods);
2412     }
2413 
2414     /**
2415      * Instantiates a builder to build a module descriptor for a <em>normal</em>
2416      * module. This method is equivalent to invoking {@link #newModule(String,Set)
2417      * newModule} with an empty set of {@link ModuleDescriptor.Modifier modifiers}.
2418      *
2419      * @param  name
2420      *         The module name
2421      *
2422      * @return A new builder
2423      *
2424      * @throws IllegalArgumentException
2425      *         If the module name is {@code null} or is not a legal module
2426      *         name
2427      */
2428     public static Builder newModule(String name) {
2429         return new Builder(name, true, Set.of());
2430     }
2431 
2432     /**
2433      * Instantiates a builder to build a module descriptor for an open module.
2434      * This method is equivalent to invoking {@link #newModule(String,Set)
2435      * newModule} with the {@link ModuleDescriptor.Modifier#OPEN OPEN} modifier.
2436      *
2437      * <p> The builder for an open module cannot be used to declare any open
2438      * packages. </p>
2439      *
2440      * @param  name
2441      *         The module name
2442      *
2443      * @return A new builder that builds an open module
2444      *
2445      * @throws IllegalArgumentException
2446      *         If the module name is {@code null} or is not a legal module
2447      *         name
2448      */
2449     public static Builder newOpenModule(String name) {
2450         return new Builder(name, true, Set.of(Modifier.OPEN));
2451     }
2452 
2453     /**
2454      * Instantiates a builder to build a module descriptor for an automatic
2455      * module. This method is equivalent to invoking {@link #newModule(String,Set)
2456      * newModule} with the {@link ModuleDescriptor.Modifier#AUTOMATIC AUTOMATIC}
2457      * modifier.
2458      *
2459      * <p> The builder for an automatic module cannot be used to declare module
2460      * or service dependences. It also cannot be used to declare any exported
2461      * or open packages. </p>
2462      *
2463      * @param  name
2464      *         The module name
2465      *
2466      * @return A new builder that builds an automatic module
2467      *
2468      * @throws IllegalArgumentException
2469      *         If the module name is {@code null} or is not a legal module
2470      *         name
2471      *
2472      * @see ModuleFinder#of(Path[])
2473      */
2474     public static Builder newAutomaticModule(String name) {
2475         return new Builder(name, true, Set.of(Modifier.AUTOMATIC));
2476     }
2477 
2478 
2479     /**
2480      * Reads the binary form of a module declaration from an input stream
2481      * as a module descriptor.
2482      *
2483      * <p> If the descriptor encoded in the input stream does not indicate a
2484      * set of packages in the module then the {@code packageFinder} will be
2485      * invoked. The set of packages that the {@code packageFinder} returns
2486      * must include all the packages that the module exports, opens, as well
2487      * as the packages of the service implementations that the module provides,
2488      * and the package of the main class (if the module has a main class). If
2489      * the {@code packageFinder} throws an {@link UncheckedIOException} then
2490      * {@link IOException} cause will be re-thrown. </p>
2491      *
2492      * <p> If there are bytes following the module descriptor then it is
2493      * implementation specific as to whether those bytes are read, ignored,
2494      * or reported as an {@code InvalidModuleDescriptorException}. If this
2495      * method fails with an {@code InvalidModuleDescriptorException} or {@code
2496      * IOException} then it may do so after some, but not all, bytes have
2497      * been read from the input stream. It is strongly recommended that the
2498      * stream be promptly closed and discarded if an exception occurs. </p>
2499      *
2500      * @apiNote The {@code packageFinder} parameter is for use when reading
2501      * module descriptors from legacy module-artifact formats that do not
2502      * record the set of packages in the descriptor itself.
2503      *
2504      * @param  in
2505      *         The input stream
2506      * @param  packageFinder
2507      *         A supplier that can produce the set of packages
2508      *
2509      * @return The module descriptor
2510      *
2511      * @throws InvalidModuleDescriptorException
2512      *         If an invalid module descriptor is detected or the set of
2513      *         packages returned by the {@code packageFinder} does not include
2514      *         all of the packages obtained from the module descriptor
2515      * @throws IOException
2516      *         If an I/O error occurs reading from the input stream or {@code
2517      *         UncheckedIOException} is thrown by the package finder
2518      */
2519     public static ModuleDescriptor read(InputStream in,
2520                                         Supplier<Set<String>> packageFinder)
2521         throws IOException
2522     {
2523         return ModuleInfo.read(in, requireNonNull(packageFinder)).descriptor();
2524     }
2525 
2526     /**
2527      * Reads the binary form of a module declaration from an input stream as a
2528      * module descriptor. This method works exactly as specified by the 2-arg
2529      * {@link #read(InputStream,Supplier) read} method with the exception that
2530      * a package finder is not used to find additional packages when the
2531      * module descriptor read from the stream does not indicate the set of
2532      * packages.
2533      *
2534      * @param  in
2535      *         The input stream
2536      *
2537      * @return The module descriptor
2538      *
2539      * @throws InvalidModuleDescriptorException
2540      *         If an invalid module descriptor is detected
2541      * @throws IOException
2542      *         If an I/O error occurs reading from the input stream
2543      */
2544     public static ModuleDescriptor read(InputStream in) throws IOException {
2545         return ModuleInfo.read(in, null).descriptor();
2546     }
2547 
2548     /**
2549      * Reads the binary form of a module declaration from a byte buffer
2550      * as a module descriptor.
2551      *
2552      * <p> If the descriptor encoded in the byte buffer does not indicate a
2553      * set of packages in the module then the {@code packageFinder} will be
2554      * invoked. The set of packages that the {@code packageFinder} returns
2555      * must include all the packages that the module exports, opens, as well
2556      * as the packages of the service implementations that the module provides,
2557      * and the package of the main class (if the module has a main class). If
2558      * the {@code packageFinder} throws an {@link UncheckedIOException} then
2559      * {@link IOException} cause will be re-thrown. </p>
2560      *
2561      * <p> The module descriptor is read from the buffer starting at index
2562      * {@code p}, where {@code p} is the buffer's {@link ByteBuffer#position()
2563      * position} when this method is invoked. Upon return the buffer's position
2564      * will be equal to {@code p + n} where {@code n} is the number of bytes
2565      * read from the buffer. </p>
2566      *
2567      * <p> If there are bytes following the module descriptor then it is
2568      * implementation specific as to whether those bytes are read, ignored,
2569      * or reported as an {@code InvalidModuleDescriptorException}. If this
2570      * method fails with an {@code InvalidModuleDescriptorException} then it
2571      * may do so after some, but not all, bytes have been read. </p>
2572      *
2573      * @apiNote The {@code packageFinder} parameter is for use when reading
2574      * module descriptors from legacy module-artifact formats that do not
2575      * record the set of packages in the descriptor itself.
2576      *
2577      * @param  bb
2578      *         The byte buffer
2579      * @param  packageFinder
2580      *         A supplier that can produce the set of packages
2581      *
2582      * @return The module descriptor
2583      *
2584      * @throws InvalidModuleDescriptorException
2585      *         If an invalid module descriptor is detected or the set of
2586      *         packages returned by the {@code packageFinder} does not include
2587      *         all of the packages obtained from the module descriptor
2588      */
2589     public static ModuleDescriptor read(ByteBuffer bb,
2590                                         Supplier<Set<String>> packageFinder)
2591     {
2592         return ModuleInfo.read(bb, requireNonNull(packageFinder)).descriptor();
2593     }
2594 
2595     /**
2596      * Reads the binary form of a module declaration from a byte buffer as a
2597      * module descriptor. This method works exactly as specified by the 2-arg
2598      * {@link #read(ByteBuffer,Supplier) read} method with the exception that a
2599      * package finder is not used to find additional packages when the module
2600      * descriptor encoded in the buffer does not indicate the set of packages.
2601      *
2602      * @param  bb
2603      *         The byte buffer
2604      *
2605      * @return The module descriptor
2606      *
2607      * @throws InvalidModuleDescriptorException
2608      *         If an invalid module descriptor is detected
2609      */
2610     public static ModuleDescriptor read(ByteBuffer bb) {
2611         return ModuleInfo.read(bb, null).descriptor();
2612     }
2613 
2614     private static String packageName(String cn) {
2615         int index = cn.lastIndexOf('.');
2616         return (index == -1) ? "" : cn.substring(0, index);
2617     }
2618 
2619     /**
2620      * Returns a string containing the given set of modifiers and label.
2621      */
2622     private static <M> String toString(Set<M> mods, String what) {
2623         return (Stream.concat(mods.stream().map(e -> e.toString()
2624                                                       .toLowerCase(Locale.ROOT)),
2625                               Stream.of(what)))
2626                 .collect(Collectors.joining(" "));
2627     }
2628 
2629     /**
2630      * Generates and returns a hashcode for the enum instances. The returned hashcode
2631      * is a value based on the {@link Enum#name() name} of each enum instance.
2632      */
2633     private static int modsHashCode(Iterable<? extends Enum<?>> enums) {
2634         int h = 0;
2635         for (Enum<?> e : enums) {
2636             h += e.name().hashCode();
2637         }
2638         return h;
2639     }
2640 
2641     private static <T extends Object & Comparable<? super T>>
2642     int compare(T obj1, T obj2) {
2643         if (obj1 != null) {
2644             return (obj2 != null) ? obj1.compareTo(obj2) : 1;
2645         } else {
2646             return (obj2 == null) ? 0 : -1;
2647         }
2648     }
2649 
2650     /**
2651      * Compares two sets of {@code Comparable} objects.
2652      */
2653     @SuppressWarnings("unchecked")
2654     private static <T extends Object & Comparable<? super T>>
2655     int compare(Set<T> s1, Set<T> s2) {
2656         T[] a1 = (T[]) s1.toArray();
2657         T[] a2 = (T[]) s2.toArray();
2658         Arrays.sort(a1);
2659         Arrays.sort(a2);
2660         return Arrays.compare(a1, a2);
2661     }
2662 
2663     private static <E extends Enum<E>> long modsValue(Set<E> set) {
2664         long value = 0;
2665         for (Enum<E> e : set) {
2666             value += 1 << e.ordinal();
2667         }
2668         return value;
2669     }
2670 
2671     static {
2672         runtimeSetup();
2673     }
2674 
2675     // Called from JVM when loading an AOT cache
2676     private static void runtimeSetup() {
2677         /**
2678          * Setup the shared secret to allow code in other packages access
2679          * private package methods in java.lang.module.
2680          */
2681         jdk.internal.access.SharedSecrets
2682             .setJavaLangModuleAccess(new jdk.internal.access.JavaLangModuleAccess() {
2683                 @Override
2684                 public Builder newModuleBuilder(String mn,
2685                                                 boolean strict,
2686                                                 Set<ModuleDescriptor.Modifier> modifiers) {
2687                     return new Builder(mn, strict, modifiers);
2688                 }
2689 
2690                 @Override
2691                 public Set<String> packages(ModuleDescriptor.Builder builder) {
2692                     return builder.packages();
2693                 }
2694 
2695                 @Override
2696                 public void requires(ModuleDescriptor.Builder builder,
2697                                      Set<Requires.Modifier> ms,
2698                                      String mn,
2699                                      String rawCompiledVersion) {
2700                     builder.requires(ms, mn, rawCompiledVersion);
2701                 }
2702 
2703                 @Override
2704                 public Requires newRequires(Set<Requires.Modifier> ms, String mn, Version v) {
2705                     return new Requires(ms, mn, v, true);
2706                 }
2707 
2708                 @Override
2709                 public Exports newExports(Set<Exports.Modifier> ms, String source) {
2710                     return new Exports(ms, source, Set.of(), true);
2711                 }
2712 
2713                 @Override
2714                 public Exports newExports(Set<Exports.Modifier> ms,
2715                                           String source,
2716                                           Set<String> targets) {
2717                     return new Exports(ms, source, targets, true);
2718                 }
2719 
2720                 @Override
2721                 public Opens newOpens(Set<Opens.Modifier> ms,
2722                                       String source,
2723                                       Set<String> targets) {
2724                     return new Opens(ms, source, targets, true);
2725                 }
2726 
2727                 @Override
2728                 public Opens newOpens(Set<Opens.Modifier> ms, String source) {
2729                     return new Opens(ms, source, Set.of(), true);
2730                 }
2731 
2732                 @Override
2733                 public Provides newProvides(String service, List<String> providers) {
2734                     return new Provides(service, providers, true);
2735                 }
2736 
2737                 @Override
2738                 public ModuleDescriptor newModuleDescriptor(String name,
2739                                                             Version version,
2740                                                             Set<ModuleDescriptor.Modifier> modifiers,
2741                                                             Set<Requires> requires,
2742                                                             Set<Exports> exports,
2743                                                             Set<Opens> opens,
2744                                                             Set<String> uses,
2745                                                             Set<Provides> provides,
2746                                                             Set<String> packages,
2747                                                             String mainClass,
2748                                                             int hashCode) {
2749                     return new ModuleDescriptor(name,
2750                                                 version,
2751                                                 modifiers,
2752                                                 requires,
2753                                                 exports,
2754                                                 opens,
2755                                                 uses,
2756                                                 provides,
2757                                                 packages,
2758                                                 mainClass,
2759                                                 hashCode,
2760                                                 false);
2761                 }
2762 
2763                 @Override
2764                 public Configuration resolveAndBind(ModuleFinder finder,
2765                                                     Collection<String> roots,
2766                                                     PrintStream traceOutput)
2767                 {
2768                     return Configuration.resolveAndBind(finder, roots, traceOutput);
2769                 }
2770 
2771                 @Override
2772                 public Configuration newConfiguration(ModuleFinder finder,
2773                                                       Map<String, Set<String>> graph) {
2774                     return new Configuration(finder, graph);
2775                 }
2776             });
2777     }
2778 
2779 }