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