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